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  * Mach Operating System
    3  * Copyright (c) 1993,1992,1991,1990 Carnegie Mellon University
    4  * All Rights Reserved.
    5  * 
    6  * Permission to use, copy, modify and distribute this software and its
    7  * documentation is hereby granted, provided that both the copyright
    8  * notice and this permission notice appear in all copies of the
    9  * software, derivative works or modified versions, and any portions
   10  * thereof, and that both notices appear in supporting documentation.
   11  * 
   12  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   13  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
   14  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   15  * 
   16  * Carnegie Mellon requests users of this software to return to
   17  * 
   18  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   19  *  School of Computer Science
   20  *  Carnegie Mellon University
   21  *  Pittsburgh PA 15213-3890
   22  * 
   23  * any improvements or extensions that they make and grant Carnegie Mellon
   24  * the rights to redistribute these changes.
   25  */
   26 /*
   27  * HISTORY
   28  * $Log:        db_lex.c,v $
   29  * Revision 2.10  93/11/17  16:22:46  dbg
   30  *      Added prototypes.
   31  *      [93/10/06            dbg]
   32  * 
   33  * Revision 2.9  93/03/09  10:53:39  danner
   34  *      String protos.
   35  *      [93/03/07            af]
   36  * 
   37  * Revision 2.8  93/01/14  17:25:07  danner
   38  *      64bit cleanup.
   39  *      [92/11/30            af]
   40  * 
   41  * Revision 2.7  92/08/03  17:31:28  jfriedl
   42  *      removed silly prototypes
   43  *      [92/08/02            jfriedl]
   44  * 
   45  * Revision 2.6  92/05/21  17:07:10  jfriedl
   46  *      Cleanup to quiet gcc warnings.
   47  *      [92/05/18            jfriedl]
   48  * 
   49  * Revision 2.5  91/10/09  16:00:20  af
   50  *      Added relational operator tokens and string constant etc.
   51  *      Added input switching functions for macro and conditional command.
   52  *      Moved skip_to_eol() from db_command.c and added db_last_lp to print
   53  *        skipped input data as a warning message.
   54  *      Added last input repetition support to db_read_line.
   55  *      Changed db_lex() to always set db_tok_string for error message.
   56  *      [91/08/29            tak]
   57  * 
   58  * Revision 2.4  91/05/14  15:34:23  mrt
   59  *      Correcting copyright
   60  *
   61  * Revision 2.3  91/02/05  17:06:36  mrt
   62  *      Changed to new Mach copyright
   63  *      [91/01/31  16:18:20  mrt]
   64  * 
   65  * Revision 2.2  90/08/27  21:51:10  dbg
   66  *      Add 'dotdot' token.
   67  *      [90/08/22            dbg]
   68  * 
   69  *      Allow backslash to quote any character into an identifier.
   70  *      Allow colon in identifier for symbol table qualification.
   71  *      [90/08/16            dbg]
   72  *      Reduce lint.
   73  *      [90/08/07            dbg]
   74  *      Created.
   75  *      [90/07/25            dbg]
   76  * 
   77  */
   78 /*
   79  *      Author: David B. Golub, Carnegie Mellon University
   80  *      Date:   7/90
   81  */
   82 /*
   83  * Lexical analyzer.
   84  */
   85 #include <machine/db_machdep.h>
   86 #include <kern/strings.h>
   87 #include <ddb/db_command.h>     /* db_error */
   88 #include <ddb/db_lex.h>
   89 #include <ddb/db_input.h>
   90 #include <ddb/db_output.h>
   91 
   92 char    db_line[DB_LEX_LINE_SIZE];
   93 char    db_last_line[DB_LEX_LINE_SIZE];
   94 char    *db_lp, *db_endlp;
   95 char    *db_last_lp;
   96 int     db_look_char = 0;
   97 db_expr_t db_look_token = 0;
   98 
   99 int     db_lex(void);   /* forward */
  100 
  101 int
  102 db_read_line(
  103         char    *repeat_last)
  104 {
  105         int     i;
  106 
  107         i = db_readline(db_line, sizeof(db_line));
  108         if (i == 0)
  109             return 0;   /* EOI */
  110         if (repeat_last) {
  111             if (strncmp(db_line, repeat_last, strlen(repeat_last)) == 0) {
  112                 strcpy(db_line, db_last_line);
  113                 db_printf("%s", db_line);
  114                 i = strlen(db_line);
  115             } else if (db_line[0] != '\n' && db_line[0] != 0)
  116                 strcpy(db_last_line, db_line);
  117         }
  118         db_lp = db_line;
  119         db_endlp = db_lp + i;
  120         db_last_lp = db_lp;
  121         db_look_char = 0;
  122         db_look_token = 0;
  123         return i;
  124 }
  125 
  126 void
  127 db_flush_line(void)
  128 {
  129         db_lp = db_line;
  130         db_last_lp = db_lp;
  131         db_endlp = db_line;
  132 }
  133 
  134 void
  135 db_switch_input(
  136         char *buffer,
  137         int  size)
  138 {
  139         db_lp = buffer;
  140         db_last_lp = db_lp;
  141         db_endlp = buffer + size;
  142         db_look_char = 0;
  143         db_look_token = 0;
  144 }
  145 
  146 void
  147 db_save_lex_context(
  148         register struct db_lex_context *lp)
  149 {
  150         lp->l_ptr = db_lp;
  151         lp->l_eptr = db_endlp;
  152         lp->l_char = db_look_char;
  153         lp->l_token = db_look_token;
  154 }
  155 
  156 void
  157 db_restore_lex_context(
  158         register struct db_lex_context *lp)
  159 {
  160         db_lp = lp->l_ptr;
  161         db_last_lp = db_lp;
  162         db_endlp = lp->l_eptr;
  163         db_look_char = lp->l_char;
  164         db_look_token = lp->l_token;
  165 }
  166 
  167 int
  168 db_read_char(void)
  169 {
  170         int     c;
  171 
  172         if (db_look_char != 0) {
  173             c = db_look_char;
  174             db_look_char = 0;
  175         }
  176         else if (db_lp >= db_endlp)
  177             c = -1;
  178         else 
  179             c = *db_lp++;
  180         return c;
  181 }
  182 
  183 void
  184 db_unread_char(
  185         int c)
  186 {
  187         db_look_char = c;
  188 }
  189 
  190 void
  191 db_unread_token(
  192         int     t)
  193 {
  194         db_look_token = t;
  195 }
  196 
  197 int
  198 db_read_token(void)
  199 {
  200         int     t;
  201 
  202         if (db_look_token) {
  203             t = db_look_token;
  204             db_look_token = 0;
  205         }
  206         else {
  207             db_last_lp = db_lp;
  208             if (db_look_char)
  209                 db_last_lp--;
  210             t = db_lex();
  211         }
  212         return t;
  213 }
  214 
  215 db_expr_t       db_tok_number;
  216 char            db_tok_string[TOK_STRING_SIZE];
  217 db_expr_t       db_radix = 16;
  218 
  219 void
  220 db_flush_lex(void)
  221 {
  222         db_flush_line();
  223         db_look_char = 0;
  224         db_look_token = 0;
  225 }
  226 
  227 #define DB_DISP_SKIP    40              /* number of chars to display skip */
  228 
  229 void
  230 db_skip_to_eol(void)
  231 {
  232         register skip;
  233         register t;
  234         register n;
  235         register char *p;
  236 
  237         t = db_read_token();
  238         p = db_last_lp;
  239         for (skip = 0; t != tEOL && t != tSEMI_COLON && t != tEOF; skip++)
  240             t = db_read_token();
  241         if (t == tSEMI_COLON)
  242             db_unread_token(t);
  243         if (skip != 0) {
  244             while (p < db_last_lp && (*p == ' ' || *p == '\t'))
  245                 p++;
  246             db_printf("Warning: Skipped input data \"");
  247             for (n = 0; n < DB_DISP_SKIP && p < db_last_lp; n++)
  248                 db_printf("%c", *p++);
  249             if (n >= DB_DISP_SKIP)
  250                 db_printf("....");
  251             db_printf("\"\n");
  252         }
  253 }
  254 
  255 int
  256 db_lex(void)
  257 {
  258         register char *cp;
  259         register c;
  260 
  261         c = db_read_char();
  262         while (c <= ' ' || c > '~') {
  263             if (c == '\n' || c == -1)
  264                 return (tEOL);
  265             c = db_read_char();
  266         }
  267 
  268         cp = db_tok_string;
  269         *cp++ = c;
  270 
  271         if (c >= '' && c <= '9') {
  272             /* number */
  273             int r, digit;
  274 
  275             if (c > '')
  276                 r = db_radix;
  277             else {
  278                 c = db_read_char();
  279                 if (c == 'O' || c == 'o')
  280                     r = 8;
  281                 else if (c == 'T' || c == 't')
  282                     r = 10;
  283                 else if (c == 'X' || c == 'x')
  284                     r = 16;
  285                 else {
  286                     cp--;
  287                     r = db_radix;
  288                     db_unread_char(c);
  289                 }
  290                 c = db_read_char();
  291                 *cp++ = c;
  292             }
  293             db_tok_number = 0;
  294             for (;;) {
  295                 if (c >= '' && c <= ((r == 8) ? '7' : '9'))
  296                     digit = c - '';
  297                 else if (r == 16 && ((c >= 'A' && c <= 'F') ||
  298                                      (c >= 'a' && c <= 'f'))) {
  299                     if (c >= 'a')
  300                         digit = c - 'a' + 10;
  301                     else
  302                         digit = c - 'A' + 10;
  303                 }
  304                 else
  305                     break;
  306                 db_tok_number = db_tok_number * r + digit;
  307                 c = db_read_char();
  308                 if (cp < &db_tok_string[sizeof(db_tok_string)-1])
  309                         *cp++ = c;
  310             }
  311             cp[-1] = 0;
  312             if ((c >= '' && c <= '9') ||
  313                 (c >= 'A' && c <= 'Z') ||
  314                 (c >= 'a' && c <= 'z') ||
  315                 (c == '_'))
  316             {
  317                 db_printf("Bad character '%c' after number %s\n", 
  318                                 c, db_tok_string);
  319                 db_error(0);
  320                 db_flush_lex();
  321                 return tEOF;
  322             }
  323             db_unread_char(c);
  324             return tNUMBER;
  325         }
  326         if ((c >= 'A' && c <= 'Z') ||
  327             (c >= 'a' && c <= 'z') ||
  328             c == '_' || c == '\\' || c == ':')
  329         {
  330             /* identifier */
  331             if (c == '\\') {
  332                 c = db_read_char();
  333                 if (c == '\n' || c == -1)
  334                     db_error("Bad '\\' at the end of line\n");
  335                 cp[-1] = c;
  336             }
  337             while (1) {
  338                 c = db_read_char();
  339                 if ((c >= 'A' && c <= 'Z') ||
  340                     (c >= 'a' && c <= 'z') ||
  341                     (c >= '' && c <= '9') ||
  342                     c == '_' || c == '\\' || c == ':' || c == '.')
  343                 {
  344                     if (c == '\\') {
  345                         c = db_read_char();
  346                         if (c == '\n' || c == -1)
  347                             db_error("Bad '\\' at the end of line\n");
  348                     }
  349                     *cp++ = c;
  350                     if (cp == db_tok_string+sizeof(db_tok_string)) {
  351                         db_error("String too long\n");
  352                         db_flush_lex();
  353                         return tEOF;
  354                     }
  355                     continue;
  356                 }
  357                 else {
  358                     *cp = '\0';
  359                     break;
  360                 }
  361             }
  362             db_unread_char(c);
  363             return tIDENT;
  364         }
  365 
  366         *cp = 0;
  367         switch (c) {
  368             case '+':
  369                 return tPLUS;
  370             case '-':
  371                 return tMINUS;
  372             case '.':
  373                 c = db_read_char();
  374                 if (c == '.') {
  375                     *cp++ = c;
  376                     *cp = 0;
  377                     return tDOTDOT;
  378                 }
  379                 db_unread_char(c);
  380                 return tDOT;
  381             case '*':
  382                 return tSTAR;
  383             case '/':
  384                 return tSLASH;
  385             case '=':
  386                 c = db_read_char();
  387                 if (c == '=') {
  388                     *cp++ = c;
  389                     *cp = 0;
  390                     return tLOG_EQ;
  391                 }
  392                 db_unread_char(c);
  393                 return tEQ;
  394             case '%':
  395                 return tPCT;
  396             case '#':
  397                 return tHASH;
  398             case '(':
  399                 return tLPAREN;
  400             case ')':
  401                 return tRPAREN;
  402             case ',':
  403                 return tCOMMA;
  404             case '\'':
  405                 return tQUOTE;
  406             case '"':
  407                 /* string */
  408                 cp = db_tok_string;
  409                 c = db_read_char();
  410                 while (c != '"' && c > 0 && c != '\n') {
  411                     if (cp >= &db_tok_string[sizeof(db_tok_string)-1]) {
  412                         db_error("Too long string\n");
  413                         db_flush_lex();
  414                         return tEOF;
  415                     }
  416                     if (c == '\\') {
  417                         c = db_read_char();
  418                         switch(c) {
  419                         case 'n':
  420                             c = '\n'; break;
  421                         case 't':
  422                             c = '\t'; break;
  423                         case '\\':
  424                         case '"':
  425                             break;
  426                         default:
  427                             db_printf("Bad escape sequence '\\%c'\n", c);
  428                             db_error(0);
  429                             db_flush_lex();
  430                             return tEOF;
  431                         }
  432                     }
  433                     *cp++ = c;
  434                     c = db_read_char();
  435                 }
  436                 *cp = 0;
  437                 if (c != '"') {
  438                     db_error("Non terminated string constant\n");
  439                     db_flush_lex();
  440                     return tEOF;
  441                 }
  442                 return tSTRING;
  443             case '$':
  444                 return tDOLLAR;
  445             case '!':
  446                 c = db_read_char();
  447                 if (c == '=') {
  448                     *cp++ = c;
  449                     *cp = 0;
  450                     return tLOG_NOT_EQ;
  451                 }
  452                 db_unread_char(c);
  453                 return tEXCL;
  454             case '&':
  455                 c = db_read_char();
  456                 if (c == '&') {
  457                     *cp++ = c;
  458                     *cp = 0;
  459                     return tLOG_AND;
  460                 }
  461                 db_unread_char(c);
  462                 return tBIT_AND;
  463             case '|':
  464                 c = db_read_char();
  465                 if (c == '|') {
  466                     *cp++ = c;
  467                     *cp = 0;
  468                     return tLOG_OR;
  469                 }
  470                 db_unread_char(c);
  471                 return tBIT_OR;
  472             case '<':
  473                 c = db_read_char();
  474                 *cp++ = c;
  475                 *cp = 0;
  476                 if (c == '<')
  477                     return tSHIFT_L;
  478                 if (c == '=')
  479                     return tLESS_EQ;
  480                 cp[-1] = 0;
  481                 db_unread_char(c);
  482                 return tLESS;
  483                 break;
  484             case '>':
  485                 c = db_read_char();
  486                 *cp++ = c;
  487                 *cp = 0;
  488                 if (c == '>')
  489                     return tSHIFT_R;
  490                 if (c == '=')
  491                     return tGREATER_EQ;
  492                 cp[-1] = 0;
  493                 db_unread_char(c);
  494                 return tGREATER;
  495                 break;
  496             case ';':
  497                 return tSEMI_COLON;
  498             case '?':
  499                 return tQUESTION;
  500             case -1:
  501                 strcpy(db_tok_string, "<EOL>");
  502                 return tEOF;
  503         }
  504         db_printf("Bad character '%c'\n", c);
  505         db_flush_lex();
  506         return tEOF;
  507 }

Cache object: 99d16445e6806d678bdc6d54711a74da


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