The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/boot/ficl/prefix.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*******************************************************************
    2 ** p r e f i x . c
    3 ** Forth Inspired Command Language
    4 ** Parser extensions for Ficl
    5 ** Authors: Larry Hastings & John Sadler (john_sadler@alum.mit.edu)
    6 ** Created: April 2001
    7 ** $Id: prefix.c,v 1.6 2001/12/05 07:21:34 jsadler Exp $
    8 *******************************************************************/
    9 /*
   10 ** Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu)
   11 ** All rights reserved.
   12 **
   13 ** Get the latest Ficl release at http://ficl.sourceforge.net
   14 **
   15 ** I am interested in hearing from anyone who uses ficl. If you have
   16 ** a problem, a success story, a defect, an enhancement request, or
   17 ** if you would like to contribute to the ficl release, please
   18 ** contact me by email at the address above.
   19 **
   20 ** L I C E N S E  and  D I S C L A I M E R
   21 ** 
   22 ** Redistribution and use in source and binary forms, with or without
   23 ** modification, are permitted provided that the following conditions
   24 ** are met:
   25 ** 1. Redistributions of source code must retain the above copyright
   26 **    notice, this list of conditions and the following disclaimer.
   27 ** 2. Redistributions in binary form must reproduce the above copyright
   28 **    notice, this list of conditions and the following disclaimer in the
   29 **    documentation and/or other materials provided with the distribution.
   30 **
   31 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   32 ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   33 ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   34 ** ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   35 ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   36 ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   37 ** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   38 ** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   39 ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   40 ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   41 ** SUCH DAMAGE.
   42 */
   43 
   44 /* $FreeBSD$ */
   45 
   46 #include <string.h>
   47 #include <ctype.h>
   48 #include "ficl.h"
   49 #include "math64.h"
   50 
   51 /*
   52 ** (jws) revisions: 
   53 ** A prefix is a word in a dedicated wordlist (name stored in list_name below)
   54 ** that is searched in a special way by the prefix parse step. When a prefix
   55 ** matches the beginning of an incoming token, push the non-prefix part of the
   56 ** token back onto the input stream and execute the prefix code.
   57 **
   58 ** The parse step is called ficlParsePrefix. 
   59 ** Storing prefix entries in the dictionary greatly simplifies
   60 ** the process of matching and dispatching prefixes, avoids the
   61 ** need to clean up a dynamically allocated prefix list when the system
   62 ** goes away, but still allows prefixes to be allocated at runtime.
   63 */
   64 
   65 static char list_name[] = "<prefixes>";
   66 
   67 /**************************************************************************
   68                         f i c l P a r s e P r e f i x
   69 ** This is the parse step for prefixes - it checks an incoming word
   70 ** to see if it starts with a prefix, and if so runs the corrseponding
   71 ** code against the remainder of the word and returns true.
   72 **************************************************************************/
   73 int ficlParsePrefix(FICL_VM *pVM, STRINGINFO si)
   74 {
   75     int i;
   76     FICL_HASH *pHash;
   77     FICL_WORD *pFW = ficlLookup(pVM->pSys, list_name);
   78 
   79     /* 
   80     ** Make sure we found the prefix dictionary - otherwise silently fail
   81     ** If forth-wordlist is not in the search order, we won't find the prefixes.
   82     */
   83     if (!pFW)
   84         return FICL_FALSE;
   85 
   86     pHash = (FICL_HASH *)(pFW->param[0].p);
   87     /*
   88     ** Walk the list looking for a match with the beginning of the incoming token
   89     */
   90     for (i = 0; i < (int)pHash->size; i++)
   91     {
   92         pFW = pHash->table[i];
   93         while (pFW != NULL)
   94         {
   95             int n;
   96             n = pFW->nName;
   97             /*
   98             ** If we find a match, adjust the TIB to give back the non-prefix characters
   99             ** and execute the prefix word.
  100             */
  101             if (!strincmp(SI_PTR(si), pFW->name, (FICL_UNS)n))
  102             {
  103                 /* (sadler) fixed off-by-one error when the token has no trailing space in the TIB */
  104                                 vmSetTibIndex(pVM, si.cp + n - pVM->tib.cp );
  105                 vmExecute(pVM, pFW);
  106 
  107                 return (int)FICL_TRUE;
  108             }
  109             pFW = pFW->link;
  110         }
  111     }
  112 
  113     return FICL_FALSE;
  114 }
  115 
  116 
  117 static void tempBase(FICL_VM *pVM, int base)
  118 {
  119     int oldbase = pVM->base;
  120     STRINGINFO si = vmGetWord0(pVM);
  121 
  122     pVM->base = base;
  123     if (!ficlParseNumber(pVM, si)) 
  124     {
  125         int i = SI_COUNT(si);
  126         vmThrowErr(pVM, "%.*s not recognized", i, SI_PTR(si));
  127     }
  128 
  129     pVM->base = oldbase;
  130     return;
  131 }
  132 
  133 static void fTempBase(FICL_VM *pVM)
  134 {
  135     int base = stackPopINT(pVM->pStack);
  136     tempBase(pVM, base);
  137     return;
  138 }
  139 
  140 static void prefixHex(FICL_VM *pVM)
  141 {
  142     tempBase(pVM, 16);
  143 }
  144 
  145 static void prefixTen(FICL_VM *pVM)
  146 {
  147     tempBase(pVM, 10);
  148 }
  149 
  150 
  151 /**************************************************************************
  152                         f i c l C o m p i l e P r e f i x
  153 ** Build prefix support into the dictionary and the parser
  154 ** Note: since prefixes always execute, they are effectively IMMEDIATE.
  155 ** If they need to generate code in compile state you must add
  156 ** this code explicitly.
  157 **************************************************************************/
  158 void ficlCompilePrefix(FICL_SYSTEM *pSys)
  159 {
  160     FICL_DICT *dp = pSys->dp;
  161     FICL_HASH *pHash;
  162     FICL_HASH *pPrevCompile = dp->pCompile;
  163 #if (FICL_EXTENDED_PREFIX)
  164     FICL_WORD *pFW;
  165 #endif
  166     
  167     /*
  168     ** Create a named wordlist for prefixes to reside in...
  169     ** Since we're doing a special kind of search, make it
  170     ** a single bucket hashtable - hashing does not help here.
  171     */
  172     pHash = dictCreateWordlist(dp, 1);
  173     pHash->name = list_name;
  174     dictAppendWord(dp, list_name, constantParen, FW_DEFAULT);
  175     dictAppendCell(dp, LVALUEtoCELL(pHash));
  176 
  177         /*
  178         ** Put __tempbase in the forth-wordlist
  179         */
  180     dictAppendWord(dp, "__tempbase", fTempBase, FW_DEFAULT);
  181 
  182     /*
  183     ** Temporarily make the prefix list the compile wordlist so that
  184     ** we can create some precompiled prefixes.
  185     */
  186     dp->pCompile = pHash;
  187     dictAppendWord(dp, "0x", prefixHex, FW_DEFAULT);
  188     dictAppendWord(dp, "0d", prefixTen, FW_DEFAULT);
  189 #if (FICL_EXTENDED_PREFIX)
  190     pFW = ficlLookup(pSys, "\\");
  191     if (pFW)
  192     {
  193         dictAppendWord(dp, "//", pFW->code, FW_DEFAULT);
  194     }
  195 #endif
  196     dp->pCompile = pPrevCompile;
  197 
  198     return;
  199 }

Cache object: f178be3716cd1fa6963aca1cc2a69a23


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.