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/ddb/db_lex.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  * SPDX-License-Identifier: MIT-CMU
    3  *
    4  * Mach Operating System
    5  * Copyright (c) 1991,1990 Carnegie Mellon University
    6  * All Rights Reserved.
    7  *
    8  * Permission to use, copy, modify and distribute this software and its
    9  * documentation is hereby granted, provided that both the copyright
   10  * notice and this permission notice appear in all copies of the
   11  * software, derivative works or modified versions, and any portions
   12  * thereof, and that both notices appear in supporting documentation.
   13  *
   14  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
   15  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
   16  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   17  *
   18  * Carnegie Mellon requests users of this software to return to
   19  *
   20  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   21  *  School of Computer Science
   22  *  Carnegie Mellon University
   23  *  Pittsburgh PA 15213-3890
   24  *
   25  * any improvements or extensions that they make and grant Carnegie the
   26  * rights to redistribute these changes.
   27  */
   28 /*
   29  *      Author: David B. Golub, Carnegie Mellon University
   30  *      Date:   7/90
   31  */
   32 /*
   33  * Lexical analyzer.
   34  */
   35 
   36 #include <sys/cdefs.h>
   37 __FBSDID("$FreeBSD$");
   38 
   39 #include <sys/param.h>
   40 #include <sys/libkern.h>
   41 #include <sys/lock.h>
   42 
   43 #include <ddb/ddb.h>
   44 #include <ddb/db_lex.h>
   45 
   46 static char     db_line[DB_MAXLINE];
   47 static char *   db_lp, *db_endlp;
   48 
   49 static int      db_lex(int);
   50 static void     db_flush_line(void);
   51 static int      db_read_char(void);
   52 static void     db_unread_char(int);
   53 
   54 int
   55 db_read_line(void)
   56 {
   57         int     i;
   58 
   59         i = db_readline(db_line, sizeof(db_line));
   60         if (i == 0)
   61             return (0); /* EOI */
   62         db_lp = db_line;
   63         db_endlp = db_lp + i;
   64         return (i);
   65 }
   66 
   67 /*
   68  * Simulate a line of input into DDB.
   69  */
   70 void
   71 db_inject_line(const char *command)
   72 {
   73 
   74         strlcpy(db_line, command, sizeof(db_line));
   75         db_lp = db_line;
   76         db_endlp = db_lp + strlen(command);
   77 }
   78 
   79 /*
   80  * In rare cases, we may want to pull the remainder of the line input
   81  * verbatim, rather than lexing it.  For example, when assigning literal
   82  * values associated with scripts.  In that case, return a static pointer to
   83  * the current location in the input buffer.  The caller must be aware that
   84  * the contents are not stable if other lex/input calls are made.
   85  */
   86 char *
   87 db_get_line(void)
   88 {
   89 
   90         return (db_lp);
   91 }
   92 
   93 static void
   94 db_flush_line(void)
   95 {
   96         db_lp = db_line;
   97         db_endlp = db_line;
   98 }
   99 
  100 static int
  101 db_read_char(void)
  102 {
  103         int     c;
  104 
  105         if (db_lp >= db_endlp)
  106             c = -1;
  107         else
  108             c = *db_lp++;
  109         return (c);
  110 }
  111 
  112 static void
  113 db_unread_char(int c)
  114 {
  115 
  116         if (c == -1) {
  117                 /* Unread EOL at EOL is okay. */
  118                 if (db_lp < db_endlp)
  119                         db_error("db_unread_char(-1) before end of line\n");
  120         } else {
  121                 if (db_lp > db_line) {
  122                         db_lp--;
  123                         if (*db_lp != c)
  124                                 db_error("db_unread_char() wrong char\n");
  125                 } else {
  126                         db_error("db_unread_char() at beginning of line\n");
  127                 }
  128         }
  129 }
  130 
  131 static int      db_look_token = 0;
  132 
  133 void
  134 db_unread_token(int t)
  135 {
  136         db_look_token = t;
  137 }
  138 
  139 int
  140 db_read_token_flags(int flags)
  141 {
  142         int     t;
  143 
  144         MPASS((flags & ~(DRT_VALID_FLAGS_MASK)) == 0);
  145 
  146         if (db_look_token) {
  147             t = db_look_token;
  148             db_look_token = 0;
  149         }
  150         else
  151             t = db_lex(flags);
  152         return (t);
  153 }
  154 
  155 db_expr_t       db_tok_number;
  156 char    db_tok_string[TOK_STRING_SIZE];
  157 
  158 db_expr_t       db_radix = 16;
  159 
  160 void
  161 db_flush_lex(void)
  162 {
  163         db_flush_line();
  164         db_look_token = 0;
  165 }
  166 
  167 static int
  168 db_lex(int flags)
  169 {
  170         int     c, n, radix_mode;
  171         bool    lex_wspace, lex_hex_numbers;
  172 
  173         switch (flags & DRT_RADIX_MASK) {
  174         case DRT_DEFAULT_RADIX:
  175                 radix_mode = -1;
  176                 break;
  177         case DRT_OCTAL:
  178                 radix_mode = 8;
  179                 break;
  180         case DRT_DECIMAL:
  181                 radix_mode = 10;
  182                 break;
  183         case DRT_HEXADECIMAL:
  184                 radix_mode = 16;
  185                 break;
  186         }
  187 
  188         lex_wspace = ((flags & DRT_WSPACE) != 0);
  189         lex_hex_numbers = ((flags & DRT_HEX) != 0);
  190 
  191         c = db_read_char();
  192         for (n = 0; c <= ' ' || c > '~'; n++) {
  193             if (c == '\n' || c == -1)
  194                 return (tEOL);
  195             c = db_read_char();
  196         }
  197         if (lex_wspace && n != 0) {
  198             db_unread_char(c);
  199             return (tWSPACE);
  200         }
  201 
  202         if ((c >= '' && c <= '9') ||
  203            (lex_hex_numbers &&
  204            ((c >= 'a' && c <= 'f') ||
  205            (c >= 'A' && c <= 'F')))) {
  206             /* number */
  207             int r, digit = 0;
  208 
  209             if (radix_mode != -1)
  210                 r = radix_mode;
  211             else if (c != '')
  212                 r = db_radix;
  213             else {
  214                 c = db_read_char();
  215                 if (c == 'O' || c == 'o')
  216                     r = 8;
  217                 else if (c == 'T' || c == 't')
  218                     r = 10;
  219                 else if (c == 'X' || c == 'x')
  220                     r = 16;
  221                 else {
  222                     r = db_radix;
  223                     db_unread_char(c);
  224                 }
  225                 c = db_read_char();
  226             }
  227             db_tok_number = 0;
  228             for (;;) {
  229                 if (c >= '' && c <= ((r == 8) ? '7' : '9'))
  230                     digit = c - '';
  231                 else if (r == 16 && ((c >= 'A' && c <= 'F') ||
  232                                      (c >= 'a' && c <= 'f'))) {
  233                     if (c >= 'a')
  234                         digit = c - 'a' + 10;
  235                     else if (c >= 'A')
  236                         digit = c - 'A' + 10;
  237                 }
  238                 else
  239                     break;
  240                 db_tok_number = db_tok_number * r + digit;
  241                 c = db_read_char();
  242             }
  243             if ((c >= '' && c <= '9') ||
  244                 (c >= 'A' && c <= 'Z') ||
  245                 (c >= 'a' && c <= 'z') ||
  246                 (c == '_'))
  247             {
  248                 db_error("Bad character in number\n");
  249                 db_flush_lex();
  250                 return (tEOF);
  251             }
  252             db_unread_char(c);
  253             return (tNUMBER);
  254         }
  255         if ((c >= 'A' && c <= 'Z') ||
  256             (c >= 'a' && c <= 'z') ||
  257             c == '_' || c == '\\')
  258         {
  259             /* string */
  260             char *cp;
  261 
  262             cp = db_tok_string;
  263             if (c == '\\') {
  264                 c = db_read_char();
  265                 if (c == '\n' || c == -1)
  266                     db_error("Bad escape\n");
  267             }
  268             *cp++ = c;
  269             while (1) {
  270                 c = db_read_char();
  271                 if ((c >= 'A' && c <= 'Z') ||
  272                     (c >= 'a' && c <= 'z') ||
  273                     (c >= '' && c <= '9') ||
  274                     c == '_' || c == '\\' || c == ':' || c == '.')
  275                 {
  276                     if (c == '\\') {
  277                         c = db_read_char();
  278                         if (c == '\n' || c == -1)
  279                             db_error("Bad escape\n");
  280                     }
  281                     *cp++ = c;
  282                     if (cp == db_tok_string+sizeof(db_tok_string)) {
  283                         db_error("String too long\n");
  284                         db_flush_lex();
  285                         return (tEOF);
  286                     }
  287                     continue;
  288                 }
  289                 else {
  290                     *cp = '\0';
  291                     break;
  292                 }
  293             }
  294             db_unread_char(c);
  295             return (tIDENT);
  296         }
  297 
  298         switch (c) {
  299             case '+':
  300                 return (tPLUS);
  301             case '-':
  302                 return (tMINUS);
  303             case '.':
  304                 c = db_read_char();
  305                 if (c == '.')
  306                     return (tDOTDOT);
  307                 db_unread_char(c);
  308                 return (tDOT);
  309             case '*':
  310                 return (tSTAR);
  311             case '/':
  312                 return (tSLASH);
  313             case '=':
  314                 c = db_read_char();
  315                 if (c == '=')
  316                     return (tLOG_EQ);
  317                 db_unread_char(c);
  318                 return (tEQ);
  319             case '%':
  320                 return (tPCT);
  321             case '#':
  322                 return (tHASH);
  323             case '(':
  324                 return (tLPAREN);
  325             case ')':
  326                 return (tRPAREN);
  327             case ',':
  328                 return (tCOMMA);
  329             case '"':
  330                 return (tDITTO);
  331             case '$':
  332                 return (tDOLLAR);
  333             case '!':
  334                 c = db_read_char();
  335                 if (c == '='){
  336                         return (tLOG_NOT_EQ);
  337                 }
  338                 db_unread_char(c);
  339                 return (tEXCL);
  340             case ':':
  341                 c = db_read_char();
  342                 if (c == ':')
  343                         return (tCOLONCOLON);
  344                 db_unread_char(c);
  345                 return (tCOLON);
  346             case ';':
  347                 return (tSEMI);
  348             case '&':
  349                 c = db_read_char();
  350                 if (c == '&')
  351                     return (tLOG_AND);
  352                 db_unread_char(c);
  353                 return (tBIT_AND);
  354             case '|':
  355                 c = db_read_char();
  356                 if (c == '|')
  357                     return (tLOG_OR);
  358                 db_unread_char(c);
  359                 return (tBIT_OR);
  360             case '<':
  361                 c = db_read_char();
  362                 if (c == '<')
  363                     return (tSHIFT_L);
  364                 if (c == '=') 
  365                     return (tLESS_EQ);
  366                 db_unread_char(c);
  367                 return (tLESS);
  368             case '>':
  369                 c = db_read_char();
  370                 if (c == '>')
  371                     return (tSHIFT_R);
  372                 if (c == '=')
  373                     return (tGREATER_EQ);
  374                 db_unread_char(c);
  375                 return (tGREATER);
  376             case '?':
  377                 return (tQUESTION);
  378             case '~':
  379                 return (tBIT_NOT);
  380             case -1:
  381                 return (tEOF);
  382         }
  383         db_printf("Bad character\n");
  384         db_flush_lex();
  385         return (tEOF);
  386 }

Cache object: 9eef8cfc31b4d4786b44279e6fe0ff31


[ 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.