Exemplo n.º 1
0
Arquivo: cpp.c Projeto: rui314/8cc-old
/*
 * #undef
 * (C99 6.10.5 Scope of macro definisions, paragraph 2)
 */
static void read_undef(CppContext *ctx) {
    Token *name = read_cpp_token(ctx);
    if (!name || name->toktype != TOKTYPE_IDENT)
        error_token(name, "undef works only to an identifier, but got '%s'", token_to_string(name));
    expect_newline(ctx);
    dict_delete(ctx->defs, name->val.str);
}
Exemplo n.º 2
0
Arquivo: cpp.c Projeto: rui314/8cc-old
/*
 * Handles #if, #elif, #ifdef and #ifndef.  If condition does not meet, the
 * function calls skip_cond_include(), defined in lex.c, to skip all tokens
 * until the next #elif, #else of #endif.
 *
 * (C99 6.10.1 Conditional inclusion)
 */
static void handle_cond_incl(CppContext *ctx, CondInclType type) {
    bool cond;
    switch (type) {
    case COND_IF:
        cond = read_constant_expr(ctx);
        break;
    case COND_IFDEF:
        cond = read_ifdef(ctx);
        break;
    case COND_IFNDEF:
        cond = !read_ifdef(ctx);
        break;
    case COND_ELIF:
        error_cpp_ctx(ctx, "stray #elif");
    case COND_ELSE:
        expect_newline(ctx);
        if (LIST_IS_EMPTY(ctx->incl))
            error_cpp_ctx(ctx, "stray #else");
        bool in_else = (intptr)list_pop(ctx->incl);
        if (in_else)
            error_cpp_ctx(ctx, "#else appears twice");
        CondInclType type1 = skip_cond_incl(ctx);
        if (type1 == COND_ELIF)
            error_cpp_ctx(ctx, "stray #elif");
        if (type1 == COND_ELSE)
            error_cpp_ctx(ctx, "stray #else");
        return;
    case COND_ENDIF:
        expect_newline(ctx);
        if (LIST_IS_EMPTY(ctx->incl))
            error_cpp_ctx(ctx, "stray #endif");
        list_pop(ctx->incl);
        return;
    }
    if (cond) {
        list_push(ctx->incl, (void *)false);
        return;
    }
    // skip_cond_incl() returns one of COND_ELIF, COND_ELSE or COND_ENDIF.
    CondInclType type1 = skip_cond_incl(ctx);
    if (type1 == COND_ELIF)
        handle_cond_incl(ctx, COND_IF);
    else if (type1 == COND_ELSE)
        list_push(ctx->incl, (void *)true);
}
Exemplo n.º 3
0
Arquivo: cpp.c Projeto: rui314/8cc-old
/*
 * #include
 * (C99 6.10.2 Source file inclusion)
 */
static void handle_include(CppContext *ctx) {
    String *name;
    bool std;
    read_cpp_header_name(ctx, &name, &std);
    expect_newline(ctx);

    List *include_path = std
        ? ctx->include_path
        : make_list1(to_string(""));
    File *file = open_header(ctx, name, include_path);
    do_include(ctx, file);
}
Exemplo n.º 4
0
Arquivo: cpp.c Projeto: rui314/8cc-old
/*
 * #line
 * (C99 6.10.4 Line control)
 *
 * Line directive must be one of the following form in macro-expanded form:
 *
 *     #line digit-sequence
 *     #line digit-sequence "s-char-sequenceopt"
 */
static void handle_line_directive(CppContext *ctx) {
    Token *tok = expand_one(ctx);
    if (!tok || tok->toktype != TOKTYPE_CPPNUM)
        error_token(tok, "number expected, but got '%s'", token_to_string(tok));
    int line = cppnum_to_num(tok)->val.i;

    tok = expand_one(ctx);
    if (tok && tok->toktype == TOKTYPE_NEWLINE) {
        ctx->file->line = line;
        return;
    }
    if (tok && tok->toktype == TOKTYPE_STRING) {
        expect_newline(ctx);
        ctx->file->line = line;
        ctx->file->filename = tok->val.str;
        return;
    }
    error_token(tok, "filename expected, but got '%s'", token_to_string(tok));
}
Exemplo n.º 5
0
static int
parseit (void)
{
  int r;
  char *dot = NULL;

  if (!exports_seen)
    {
      if ((r = lexit2 ()) == -1)
	return 0;
      if (r == TK_EXPORTS)
	{
	  r = expect_newline ("EXPORTS");
	  return (r != -1 ? 1 : 0);
	}
      if (r == TK_LIBRARY)
	{
	  r = lexit2 ();
	  if (r != TK_STRING && r != TK_NAME)
	    {
	      fprintf (stderr, "Expect name/string after LIBRARY keyword.\n");
	      return (r != -1 ? 1 : 0);
	    }

	  cur_libname = unifyStr (t_buf);
	  if ((dot = strchr (t_buf, '.')) != NULL)
	    {
	      *dot = '\0';
	      cur_libbasename = unifyStr (t_buf);
	    }

	  fprintf (stderr, "Current library-name set to %s'\n", cur_libname);
	  cur_outlibbasename = unifyCat (cur_libbasename, SUFFIX);

	  r = expect_newline ("LIBRARY");
	  return (r != -1 ? 1 : 0);
	}
    }
  else
    {
      if ((r = lexit2 ()) == -1)
	return 0;
      if (r != TK_NAME)
	{
	  fprintf (stderr,
		   "Unexpected token ,%s'.  Would have expected a string/name.\n",
		   t_buf);
	  return (expect_newline ("UNKNOWN") == -1 ? 0 : 1);
	}
      cur_symbol = unifyStr (t_buf);
      cur_alias = "";
      cur_libsymbol = "";
      cur_srcfile = "";
      cur_data = 0;
      while ((r = lexit2 ()) != -1 && r != TK_NL)
	{
	  if (r == TK_DATA)
	    cur_data = 1;
	  else if (r == TK_EQUAL)
	    {
	      r = lexit2 ();
	      if (r != TK_NAME)
		{
		  fprintf (stderr, "Expected name after = expression.\n");
		  if (r != -1 && r != TK_NL)
		    r = expect_newline ("SYMBOL");
		  return (r == -1 ? 0 : 1);
		}
	      cur_libsymbol = unifyStr (t_buf);
	    }
	  else if (r == TK_EQUALEQUAL)
	    {
	      r = lexit2 ();
	      if (r != TK_NAME)
		{
		  fprintf (stderr, "Expected name after == expression.\n");
		  if (r != -1 && r != TK_NL)
		    r = expect_newline ("SYMBOL");
		  return (r == -1 ? 0 : 1);
		}
	      cur_alias = unifyStr (t_buf);
	    }
	  else if (r == TK_SOURCEFILENAME)
	    {
	      cur_srcfile = unifyStr (t_buf);
	    }
	  else
	    {
	      fprintf (stderr, "Unknown token ,%s'.\n", t_buf);
	    }
	}

      addSymbol (cur_symbol, cur_libsymbol, cur_alias, cur_srcfile, cur_data);
    }

  return (r != -1 ? 1 : 0);
}
Exemplo n.º 6
0
Arquivo: cpp.c Projeto: rui314/8cc-old
/*
 * #ifdef
 * (C99 6.10.1 Conditional inclusion, paragraph 5)
 */
static int read_ifdef(CppContext *ctx) {
    int r = is_defined(ctx, read_cpp_token(ctx));
    expect_newline(ctx);
    return r;
}