Example #1
0
extern void do_sharp (void)
{
   char *w;
   char c;

   w = read_ctrl();
   if (strcmp(w, "ifdef") == 0)
   {
      do_ifdef(1);
   }
   else if (strcmp(w, "ifndef") == 0)
   {
      do_ifndef(1);
   }
   else if (strcmp(w, "if") == 0)
   {
      do_if(1);
   }
   else if (strcmp(w, "else") == 0)
   {
      do_else(1);
   }
   else if (strcmp(w, "elif") == 0)
   {
      do_elif(1);
   }
   else if (strcmp(w, "endif") == 0)
   {
      do_endif(1);
   }
   else if (strcmp(w, "include") == 0)
   {
      do_include(1);
   }
   else if (strcmp(w, "define") == 0)
   {
      do_define(1, 0);
   }
   else if (strcmp(w, "undef") == 0)
   {
      do_undef(1);
   }
   else if (strcmp(w, "line") == 0)
   {
      do_line();
   }
   else if (strcmp(w, "pragma") == 0)
   {
      do_pragma();
   }
   else if (strcmp(w, "") == 0)
   {}
   else
   {
      int isnull;
      isnull = 0;
      if (strcmp(w, "") == 0)
      {
         c = Get();
         if (c != '\n')
         {
            Push(c);
         }
         else
         {
            isnull = 1;
         }
      }
      if (!isnull && !in_false_if())
      {
         err_head();
         fprintf(stderr, "unknown control `%s'\n", w);
         flush_sharp_line();
      }
   }
   maybe_print('\n');
   os_free(w);
}
Example #2
0
static Token next_token (void)
{
  Token token;
 restart:
  outbuffer_off();
  outbuffer_on();
  token.startindex = out.buffindex;
  {
    int c = next_char();
    switch (c) {
      case EOF:
        /* EOF */
        token.type = eof;
        goto done;
      case ' ': case '\v': case '\t': case '\n':
        /* whitespace, ignore */
        goto restart;
      case '\\':
        if (peek_char()=='\n') {
          /* backslash newline, ignore */
          next_char();
          goto restart;
        }
        goto separator;
      case '/':
        if (peek_char() == '*') {
          /* Comment */
          next_char();
          while (1) {
            c = next_char();
            if (c==EOF) {
              fprintf(stderr,"Unfinished comment\n");
              break;
            }
            if ((c=='*') && (peek_char()=='/')) {
              next_char();
              break;
            }
          }
          goto restart;
        }
        goto separator;
      case '*':
        if (peek_char() == '/')
          fprintf(stderr,"End of comment outside comment in line %lu\n",input_line);
        goto separator;
      case '#':
        /* preprocessor directive */
        {
          char* line = next_line();
          if (line) {
            char* old_line = line;
            line = concat2("#",line);
            xfree(old_line);
          } else
            line = concat1("#");
          while (line[strlen(line)-1] == '\\') {
            char* continuation_line = next_line();
            line[strlen(line)-1] = '\0';
            if (continuation_line) {
              char* old_line = line;
              line = concat2(line,continuation_line);
              xfree(old_line);
              xfree(continuation_line);
            }
          }
          {
            const char* condition;
            long line_directive;
            if ((condition = is_if(line)) != NULL) {
              do_if(condition);
            } else if (is_else(line)) {
              do_else();
              line_repeat_else();
            } else if ((condition = is_elif(line)) != NULL) {
              do_elif(condition);
              line_repeat_else();
            } else if (is_endif(line)) {
              do_endif();
              line_repeat_endif();
            } else if ((line_directive = decode_line_directive(line)) >= 0)
              input_line = line_directive;
#ifdef SPLIT_OBJECT_INITIALIZATIONS
            else {
              /* Replace "var object foo = ..." with "var object foo; foo = ..."
               in macros as well. */
              if (out.buffindex < MAXHEADERLEN) {
                uintB* p;
                out.buffer[out.buffindex] = '\0';
                for (p = &out.buffer[token.startindex]; ; p++) {
                  p = (uintB*) strstr((char*)p,"var ");
                  if (p == NULL)
                    break;
                  if ((strncmp((char*)p,"var object ",
                               strlen("var object "))==0
                       || strncmp((char*)p,"var chart ",
                                  strlen("var chart "))==0)
                      && (p[-1] == ' ' || p[-1] == '{')) {
                    if (strncmp((char*)p,"var object ",
                                strlen("var object "))==0)
                      p += strlen("var object ");
                    else if (strncmp((char*)p,"var chart ",
                                     strlen("var chart "))==0)
                      p += strlen("var chart ");
                    { uintB* q = p;
                      if ((*q >= 'A' && *q <= 'Z')
                          || (*q >= 'a' && *q <= 'z')
                          || *q == '_') {
                        do q++;
                        while ((*q >= 'A' && *q <= 'Z')
                               || (*q >= 'a' && *q <= 'z')
                               || (*q >= '0' && *q <= '9')
                               || *q == '_');
                        while (*q == ' ')
                          q++;
                        if (*q == '=') {
                          uintL insertlen = 2+(q-p);
                          if (out.buffindex + insertlen < MAXHEADERLEN) {
                            memmove(q+insertlen,q,
                                    &out.buffer[out.buffindex]-q+1);
                            q[0] = ';'; q[1] = ' ';
                            memcpy(q+2, p, q-p);
                            out.buffindex += insertlen;
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
#endif
          }
          xfree(line);
        }
        goto separator;
      case '.':
        c = peek_char();
        if (!(((c>='0') && (c<='9')) || (c=='.')))
          goto separator;
      case '0': case '1': case '2': case '3': case '4':
      case '5': case '6': case '7': case '8': case '9':
        /* Digit. Continue reading as long as alphanumeric or '.'. */
        while (1) {
          c = peek_char();
          if (((c>='0') && (c<='9')) || ((c>='A') && (c<='Z')) || ((c>='a') && (c<='z')) || (c=='.'))
            next_char();
          else
            break;
        }
        token.type = number;
        goto done;
      case '\'':
        /* Character constant */
        while (1) {
          c = next_char();
          if (c==EOF) {
            fprintf(stderr,"Unterminated character constant\n");
            break;
          }
          if (c=='\'')
            break;
          if (c=='\\')
            c = next_char();
        }
        token.type = charconst;
        goto done;
      case '\"':
        /* String constant */
        while (1) {
          c = next_char();
          if (c==EOF) {
            fprintf(stderr,"Unterminated string constant\n");
            break;
          }
          if (c=='\"')
            break;
          if (c=='\\')
            c = next_char();
        }
        token.type = stringconst;
        goto done;
      case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
      case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
      case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
      case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
      case 'Y': case 'Z':
      case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
      case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
      case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
      case 's': case 't': case 'u': case 'v': case 'w': case 'x':
      case 'y': case 'z':
      case '_':
        /* Identifier. */
        while (1) {
          c = peek_char();
          if (((c>='0') && (c<='9')) || ((c>='A') && (c<='Z')) || ((c>='a') && (c<='z')) || (c=='_'))
            next_char();
          else
            break;
        }
        token.type = ident;
        goto done;
      default:
      separator:
        token.type = sep;
        token.ch = c;
        goto done;
    }
  }
 done:
  token.endindex = out.buffindex;
  return token;
}