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 /*      $NetBSD: db_lex.c,v 1.20 2005/11/27 13:05:28 yamt Exp $ */
    2 
    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 "AS IS"
   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  *      Author: David B. Golub, Carnegie Mellon University
   29  *      Date:   7/90
   30  */
   31 
   32 /*
   33  * Lexical analyzer.
   34  */
   35 
   36 #include <sys/cdefs.h>
   37 __KERNEL_RCSID(0, "$NetBSD: db_lex.c,v 1.20 2005/11/27 13:05:28 yamt Exp $");
   38 
   39 #include <sys/param.h>
   40 #include <sys/systm.h>
   41 
   42 #include <machine/db_machdep.h>
   43 
   44 #include <ddb/db_lex.h>
   45 #include <ddb/db_output.h>
   46 #include <ddb/db_command.h>
   47 #include <ddb/db_sym.h>
   48 #include <ddb/db_extern.h>
   49 #include <ddb/db_interface.h>
   50 
   51 db_expr_t       db_tok_number;
   52 char            db_tok_string[TOK_STRING_SIZE];
   53 
   54 static char     db_line[DB_LINE_MAXLEN];
   55 static const char *db_lp;
   56 static const char *db_endlp;
   57 
   58 static int      db_look_char = 0;
   59 static int      db_look_token = 0;
   60 
   61 static void     db_flush_line(void);
   62 static int      db_read_char(void);
   63 static void     db_unread_char(int);
   64 static int      db_lex(void);
   65 
   66 int
   67 db_read_line(void)
   68 {
   69         int     i;
   70 
   71         i = db_readline(db_line, sizeof(db_line));
   72         if (i == 0)
   73                 return (0);     /* EOI */
   74         db_set_line(db_line, db_line + i);
   75         return (i);
   76 }
   77 
   78 void
   79 db_set_line(const char *sp, const char *ep)
   80 {
   81 
   82         db_lp = sp;
   83         db_endlp = ep;
   84 }
   85 
   86 static void
   87 db_flush_line(void)
   88 {
   89 
   90         db_lp = db_line;
   91         db_endlp = db_line;
   92 }
   93 
   94 static int
   95 db_read_char(void)
   96 {
   97         int     c;
   98 
   99         if (db_look_char != 0) {
  100                 c = db_look_char;
  101                 db_look_char = 0;
  102         }
  103         else if (db_lp >= db_endlp)
  104                 c = -1;
  105         else
  106                 c = *db_lp++;
  107         return (c);
  108 }
  109 
  110 static void
  111 db_unread_char(int c)
  112 {
  113 
  114         db_look_char = c;
  115 }
  116 
  117 void
  118 db_unread_token(int t)
  119 {
  120 
  121         db_look_token = t;
  122 }
  123 
  124 int
  125 db_read_token(void)
  126 {
  127         int     t;
  128 
  129         if (db_look_token) {
  130                 t = db_look_token;
  131                 db_look_token = 0;
  132         }
  133         else
  134                 t = db_lex();
  135         return (t);
  136 }
  137 
  138 int     db_radix = 16;
  139 
  140 /*
  141  * Convert the number to a string in the current radix.
  142  * This replaces the non-standard %n printf() format.
  143  */
  144 
  145 char *
  146 db_num_to_str(db_expr_t val)
  147 {
  148 
  149         /*
  150          * 2 chars for "0x", 1 for a sign ("-")
  151          * up to 21 chars for a 64-bit number:
  152          *   % echo 2^64 | bc | wc -c
  153          *   21
  154          * and 1 char for a terminal NUL
  155          * 2+1+21+1 => 25
  156          */
  157         static char buf[25];
  158 
  159         if (db_radix == 16)
  160                 snprintf(buf, sizeof(buf), DB_EXPR_T_IS_QUAD ? "%#qx" : "%#lx",
  161                     val);
  162         else if (db_radix == 8)
  163                 snprintf(buf, sizeof(buf), DB_EXPR_T_IS_QUAD ? "%#qo" : "%#lo",
  164                     val);
  165         else
  166                 snprintf(buf, sizeof(buf), DB_EXPR_T_IS_QUAD ? "%qu" : "%lu",
  167                     val);
  168 
  169         return (buf);
  170 }
  171 
  172 void
  173 db_flush_lex(void)
  174 {
  175 
  176         db_flush_line();
  177         db_look_char = 0;
  178         db_look_token = 0;
  179 }
  180 
  181 static int
  182 db_lex(void)
  183 {
  184         int     c;
  185 
  186         c = db_read_char();
  187         while (c <= ' ' || c > '~') {
  188                 if (c == '\n' || c == -1)
  189                         return (tEOL);
  190                 c = db_read_char();
  191         }
  192 
  193         if (c >= '' && c <= '9') {
  194                 /* number */
  195                 db_expr_t       r, digit = 0;
  196 
  197                 if (c > '')
  198                         r = db_radix;
  199                 else {
  200                         c = db_read_char();
  201                         if (c == 'O' || c == 'o')
  202                                 r = 8;
  203                         else if (c == 'T' || c == 't')
  204                                 r = 10;
  205                         else if (c == 'X' || c == 'x')
  206                                 r = 16;
  207                         else {
  208                                 r = db_radix;
  209                                 db_unread_char(c);
  210                         }
  211                         c = db_read_char();
  212                 }
  213                 db_tok_number = 0;
  214                 for (;;) {
  215                         if (c >= '' && c <= ((r == 8) ? '7' : '9'))
  216                                 digit = c - '';
  217                         else if (r == 16 && ((c >= 'A' && c <= 'F') ||
  218                                 (c >= 'a' && c <= 'f'))) {
  219                                 if (c >= 'a')
  220                                         digit = c - 'a' + 10;
  221                                 else if (c >= 'A')
  222                                         digit = c - 'A' + 10;
  223                         }
  224                         else
  225                                 break;
  226                         db_tok_number = db_tok_number * r + digit;
  227                         c = db_read_char();
  228                 }
  229                 if ((c >= '' && c <= '9') ||
  230                     (c >= 'A' && c <= 'Z') ||
  231                     (c >= 'a' && c <= 'z') ||
  232                     (c == '_')) {
  233                         db_error("Bad character in number\n");
  234                         /*NOTREACHED*/
  235                 }
  236                 db_unread_char(c);
  237                 return (tNUMBER);
  238         }
  239         if ((c >= 'A' && c <= 'Z') ||
  240             (c >= 'a' && c <= 'z') ||
  241             c == '_' || c == '\\') {
  242                 /* string */
  243                 char *cp;
  244 
  245                 cp = db_tok_string;
  246                 if (c == '\\') {
  247                         c = db_read_char();
  248                         if (c == '\n' || c == -1) {
  249                                 db_error("Bad escape\n");
  250                                 /*NOTREACHED*/
  251                         }
  252                 }
  253                 *cp++ = c;
  254                 while (1) {
  255                         c = db_read_char();
  256                         if ((c >= 'A' && c <= 'Z') ||
  257                             (c >= 'a' && c <= 'z') ||
  258                             (c >= '' && c <= '9') ||
  259                             c == '_' || c == '\\' || c == ':') {
  260                                 if (c == '\\') {
  261                                         c = db_read_char();
  262                                         if (c == '\n' || c == -1) {
  263                                                 db_error("Bad escape\n");
  264                                                 /*NOTREACHED*/
  265                                         }
  266                                 }
  267                                 *cp++ = c;
  268                                 if (cp == db_tok_string+sizeof(db_tok_string)) {
  269                                         db_error("String too long\n");
  270                                         /*NOTREACHED*/
  271                                 }
  272                                 continue;
  273                         } else {
  274                                 *cp = '\0';
  275                                 break;
  276                         }
  277                 }
  278                 db_unread_char(c);
  279                 return (tIDENT);
  280         }
  281 
  282         switch (c) {
  283         case '+':
  284                 return (tPLUS);
  285         case '-':
  286                 return (tMINUS);
  287         case '.':
  288                 c = db_read_char();
  289                 if (c == '.')
  290                         return (tDOTDOT);
  291                 db_unread_char(c);
  292                 return (tDOT);
  293         case '*':
  294                 return (tSTAR);
  295         case '/':
  296                 return (tSLASH);
  297         case '=':
  298                 return (tEQ);
  299         case '%':
  300                 return (tPCT);
  301         case '#':
  302                 return (tHASH);
  303         case '(':
  304                 return (tLPAREN);
  305         case ')':
  306                 return (tRPAREN);
  307         case ',':
  308                 return (tCOMMA);
  309         case '"':
  310                 return (tDITTO);
  311         case '$':
  312                 return (tDOLLAR);
  313         case '!':
  314                 return (tEXCL);
  315         case '<':
  316                 c = db_read_char();
  317                 if (c == '<')
  318                         return (tSHIFT_L);
  319                 db_unread_char(c);
  320                 break;
  321         case '>':
  322                 c = db_read_char();
  323                 if (c == '>')
  324                         return (tSHIFT_R);
  325                 db_unread_char(c);
  326                 break;
  327         case -1:
  328                 return (tEOF);
  329         }
  330         db_printf("Bad character\n");
  331         db_flush_lex();
  332         return (tEOF);
  333 }

Cache object: 8ff716d370861a4589c5052005376588


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