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

Cache object: 769330452670691974e76dd66ecaba24


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