mojoshader_preprocessor.c
changeset 896 7a7989b18117
parent 895 a2aacb5796bc
child 898 7f55db1ec3c1
equal deleted inserted replaced
895:a2aacb5796bc 896:7a7989b18117
    42     int isfail;
    42     int isfail;
    43     int out_of_memory;
    43     int out_of_memory;
    44     char failstr[256];
    44     char failstr[256];
    45     int recursion_count;
    45     int recursion_count;
    46     int asm_comments;
    46     int asm_comments;
    47     int file_macro_special;
       
    48     int line_macro_special;
       
    49     Conditional *conditional_pool;
    47     Conditional *conditional_pool;
    50     IncludeState *include_stack;
    48     IncludeState *include_stack;
    51     IncludeState *include_pool;
    49     IncludeState *include_pool;
    52     Define *define_hashtable[256];
    50     Define *define_hashtable[256];
    53     Define *define_pool;
    51     Define *define_pool;
       
    52     Define *file_macro;
       
    53     Define *line_macro;
    54     StringCache *filename_cache;
    54     StringCache *filename_cache;
    55     MOJOSHADER_includeOpen open_callback;
    55     MOJOSHADER_includeOpen open_callback;
    56     MOJOSHADER_includeClose close_callback;
    56     MOJOSHADER_includeClose close_callback;
    57     MOJOSHADER_malloc malloc;
    57     MOJOSHADER_malloc malloc;
    58     MOJOSHADER_free free;
    58     MOJOSHADER_free free;
   465 } // add_define
   465 } // add_define
   466 
   466 
   467 
   467 
   468 static void free_define(Context *ctx, Define *def)
   468 static void free_define(Context *ctx, Define *def)
   469 {
   469 {
   470     int i;
   470     if (def != NULL)
   471     for (i = 0; i < def->paramcount; i++)
   471     {
   472         Free(ctx, (void *) def->parameters[i]);
   472         int i;
   473     Free(ctx, (void *) def->parameters);
   473         for (i = 0; i < def->paramcount; i++)
   474     Free(ctx, (void *) def->identifier);
   474             Free(ctx, (void *) def->parameters[i]);
   475     Free(ctx, (void *) def->definition);
   475         Free(ctx, (void *) def->parameters);
   476     Free(ctx, (void *) def->original);
   476         Free(ctx, (void *) def->identifier);
   477     put_define(ctx, def);
   477         Free(ctx, (void *) def->definition);
       
   478         Free(ctx, (void *) def->original);
       
   479         put_define(ctx, def);
       
   480     } // if
   478 } // free_define
   481 } // free_define
   479 
   482 
   480 
   483 
   481 static int remove_define(Context *ctx, const char *sym)
   484 static int remove_define(Context *ctx, const char *sym)
   482 {
   485 {
   502 } // remove_define
   505 } // remove_define
   503 
   506 
   504 
   507 
   505 static const Define *find_define(Context *ctx, const char *sym)
   508 static const Define *find_define(Context *ctx, const char *sym)
   506 {
   509 {
       
   510     if ( (ctx->file_macro) && (strcmp(sym, "__FILE__") == 0) )
       
   511     {
       
   512         Free(ctx, (char *) ctx->file_macro->definition);
       
   513         const IncludeState *state = ctx->include_stack;
       
   514         const char *fname = state ? state->filename : "";
       
   515         const size_t len = strlen(fname) + 2;
       
   516         char *str = (char *) Malloc(ctx, len);
       
   517         if (!str)
       
   518             return NULL;
       
   519         str[0] = '\"';
       
   520         memcpy(str + 1, fname, len - 2);
       
   521         str[len - 1] = '\"';
       
   522         ctx->file_macro->definition = str;
       
   523         return ctx->file_macro;
       
   524     } // if
       
   525 
       
   526     else if ( (ctx->line_macro) && (strcmp(sym, "__LINE__") == 0) )
       
   527     {
       
   528         Free(ctx, (char *) ctx->line_macro->definition);
       
   529         const IncludeState *state = ctx->include_stack;
       
   530         const size_t bufsize = 32;
       
   531         char *str = (char *) Malloc(ctx, bufsize);
       
   532         if (!str)
       
   533             return 0;
       
   534 
       
   535         const size_t len = snprintf(str, bufsize, "%u", state->line);
       
   536         assert(len < bufsize);
       
   537         ctx->line_macro->definition = str;
       
   538         return ctx->line_macro;
       
   539     } // else
       
   540 
   507     const uint8 hash = hash_define(sym);
   541     const uint8 hash = hash_define(sym);
   508     Define *bucket = ctx->define_hashtable[hash];
   542     Define *bucket = ctx->define_hashtable[hash];
   509     while (bucket)
   543     while (bucket)
   510     {
   544     {
   511         if (strcmp(bucket->identifier, sym) == 0)
   545         if (strcmp(bucket->identifier, sym) == 0)
   666     ctx->free = f;
   700     ctx->free = f;
   667     ctx->malloc_data = d;
   701     ctx->malloc_data = d;
   668     ctx->open_callback = open_callback;
   702     ctx->open_callback = open_callback;
   669     ctx->close_callback = close_callback;
   703     ctx->close_callback = close_callback;
   670     ctx->asm_comments = asm_comments;
   704     ctx->asm_comments = asm_comments;
   671     ctx->file_macro_special = 1;
   705 
   672     ctx->line_macro_special = 1;
       
   673     ctx->filename_cache = stringcache_create(m, f, d);
   706     ctx->filename_cache = stringcache_create(m, f, d);
   674     if (ctx->filename_cache == 0)
   707     okay = ((okay) && (ctx->filename_cache != NULL));
   675     {
   708 
   676         f(ctx, d);
   709     ctx->file_macro = get_define(ctx);
   677         return NULL;
   710     okay = ((okay) && (ctx->file_macro != NULL));
   678     } // if
   711     if ((okay) && (ctx->file_macro))
       
   712         okay = ((ctx->file_macro->identifier = StrDup(ctx, "__FILE__")) != 0);
       
   713 
       
   714     ctx->line_macro = get_define(ctx);
       
   715     okay = ((okay) && (ctx->line_macro != NULL));
       
   716     if ((okay) && (ctx->line_macro))
       
   717         okay = ((ctx->line_macro->identifier = StrDup(ctx, "__LINE__")) != 0);
   679 
   718 
   680     // let the usual preprocessor parser sort these out.
   719     // let the usual preprocessor parser sort these out.
   681     char *define_include = NULL;
   720     char *define_include = NULL;
   682     unsigned int define_include_len = 0;
   721     unsigned int define_include_len = 0;
   683     if (define_count > 0)
   722     if ((okay) && (define_count > 0))
   684     {
   723     {
   685         for (i = 0; i < define_count; i++)
   724         for (i = 0; i < define_count; i++)
   686         {
   725         {
   687             define_include_len += strlen(defines[i].identifier);
   726             define_include_len += strlen(defines[i].identifier);
   688             define_include_len += strlen(defines[i].definition);
   727             define_include_len += strlen(defines[i].definition);
   735     put_all_defines(ctx);
   774     put_all_defines(ctx);
   736 
   775 
   737     if (ctx->filename_cache != NULL)
   776     if (ctx->filename_cache != NULL)
   738         stringcache_destroy(ctx->filename_cache);
   777         stringcache_destroy(ctx->filename_cache);
   739 
   778 
       
   779     free_define(ctx, ctx->file_macro);
       
   780     free_define(ctx, ctx->line_macro);
   740     free_define_pool(ctx);
   781     free_define_pool(ctx);
   741     free_conditional_pool(ctx);
   782     free_conditional_pool(ctx);
   742     free_include_pool(ctx);
   783     free_include_pool(ctx);
   743 
   784 
   744     Free(ctx, ctx);
   785     Free(ctx, ctx);
   992     } // if
  1033     } // if
   993 
  1034 
   994     // Don't treat these symbols as special anymore if they get (re)#defined.
  1035     // Don't treat these symbols as special anymore if they get (re)#defined.
   995     if (strcmp(sym, "__FILE__") == 0)
  1036     if (strcmp(sym, "__FILE__") == 0)
   996     {
  1037     {
   997         if (ctx->file_macro_special)
  1038         if (ctx->file_macro)
       
  1039         {
   998             failf(ctx, "'%s' already defined", sym); // !!! FIXME: warning?
  1040             failf(ctx, "'%s' already defined", sym); // !!! FIXME: warning?
   999         ctx->file_macro_special = 0;
  1041             free_define(ctx, ctx->file_macro);
       
  1042             ctx->file_macro = NULL;
       
  1043         } // if
  1000     } // if
  1044     } // if
  1001     else if (strcmp(sym, "__LINE__") == 0)
  1045     else if (strcmp(sym, "__LINE__") == 0)
  1002     {
  1046     {
  1003         if (ctx->line_macro_special)
  1047         if (ctx->line_macro)
       
  1048         {
  1004             failf(ctx, "'%s' already defined", sym); // !!! FIXME: warning?
  1049             failf(ctx, "'%s' already defined", sym); // !!! FIXME: warning?
  1005         ctx->line_macro_special = 0;
  1050             free_define(ctx, ctx->line_macro);
       
  1051             ctx->line_macro = NULL;
       
  1052         } // if
  1006     } // else if
  1053     } // else if
  1007 
  1054 
  1008     // #define a(b) is different than #define a (b)    :(
  1055     // #define a(b) is different than #define a (b)    :(
  1009     state->report_whitespace = 1;
  1056     state->report_whitespace = 1;
  1010     lexer(state);
  1057     lexer(state);
  1194         return;
  1241         return;
  1195     } // if
  1242     } // if
  1196 
  1243 
  1197     if (strcmp(sym, "__FILE__") == 0)
  1244     if (strcmp(sym, "__FILE__") == 0)
  1198     {
  1245     {
  1199         if ((ctx->file_macro_special) && (find_define(ctx, sym) == NULL))
  1246         if (ctx->file_macro)
       
  1247         {
  1200             failf(ctx, "undefining \"%s\"", sym);  // !!! FIXME: should be warning.
  1248             failf(ctx, "undefining \"%s\"", sym);  // !!! FIXME: should be warning.
  1201         ctx->file_macro_special = 0;
  1249             free_define(ctx, ctx->file_macro);
       
  1250             ctx->file_macro = NULL;
       
  1251         } // if
  1202     } // if
  1252     } // if
  1203     else if (strcmp(sym, "__LINE__") == 0)
  1253     else if (strcmp(sym, "__LINE__") == 0)
  1204     {
  1254     {
  1205         if ((ctx->line_macro_special) && (find_define(ctx, sym) == NULL))
  1255         if (ctx->line_macro)
       
  1256         {
  1206             failf(ctx, "undefining \"%s\"", sym);  // !!! FIXME: should be warning.
  1257             failf(ctx, "undefining \"%s\"", sym);  // !!! FIXME: should be warning.
  1207         ctx->line_macro_special = 0;
  1258             free_define(ctx, ctx->line_macro);
       
  1259             ctx->line_macro = NULL;
       
  1260         } // if
  1208     } // if
  1261     } // if
  1209 
  1262 
  1210     remove_define(ctx, sym);
  1263     remove_define(ctx, sym);
  1211 } // handle_pp_undef
  1264 } // handle_pp_undef
  1212 
  1265 
  1574     const char *fname = state->filename;
  1627     const char *fname = state->filename;
  1575     const unsigned int line = state->line;
  1628     const unsigned int line = state->line;
  1576     char *sym = (char *) alloca(state->tokenlen+1);
  1629     char *sym = (char *) alloca(state->tokenlen+1);
  1577     memcpy(sym, state->token, state->tokenlen);
  1630     memcpy(sym, state->token, state->tokenlen);
  1578     sym[state->tokenlen] = '\0';
  1631     sym[state->tokenlen] = '\0';
  1579 
       
  1580     if ( (ctx->file_macro_special) && (strcmp(sym, "__FILE__") == 0) )
       
  1581     {
       
  1582         const size_t len = strlen(fname) + 2;
       
  1583         char *str = (char *) Malloc(ctx, len);
       
  1584         if (!str)
       
  1585             return 0;
       
  1586         str[0] = '\"';
       
  1587         memcpy(str + 1, fname, len - 2);
       
  1588         str[len - 1] = '\"';
       
  1589         if (!push_source(ctx,fname,str,len,line,close_define_include))
       
  1590         {
       
  1591             Free(ctx, str);
       
  1592             return 0;
       
  1593         } // if
       
  1594         return 1;
       
  1595     } // if
       
  1596 
       
  1597     else if ( (ctx->line_macro_special) && (strcmp(sym, "__LINE__") == 0) )
       
  1598     {
       
  1599         const size_t bufsize = 32;
       
  1600         char *str = (char *) Malloc(ctx, bufsize);
       
  1601         if (!str)
       
  1602             return 0;
       
  1603 
       
  1604         const size_t len = snprintf(str, bufsize, "%u", line);
       
  1605         assert(len < bufsize);
       
  1606         if (!push_source(ctx,fname,str,len,line,close_define_include))
       
  1607         {
       
  1608             Free(ctx, str);
       
  1609             return 0;
       
  1610         } // if
       
  1611         return 1;
       
  1612     } // else
       
  1613 
  1632 
  1614     // Is this identifier #defined?
  1633     // Is this identifier #defined?
  1615     const Define *def = find_define(ctx, sym);
  1634     const Define *def = find_define(ctx, sym);
  1616     if (def == NULL)
  1635     if (def == NULL)
  1617         return 0;   // just send the token through unchanged.
  1636         return 0;   // just send the token through unchanged.