mojoshader_preprocessor.c
changeset 858 d51537335896
parent 841 05fa7ce0a202
child 861 760e1457ffc6
equal deleted inserted replaced
857:905ad877371b 858:d51537335896
    34         printf("NOW LEXING %s:%d ...\n", s->filename, s->line);
    34         printf("NOW LEXING %s:%d ...\n", s->filename, s->line);
    35 } // print_debug_lexing_position
    35 } // print_debug_lexing_position
    36 #else
    36 #else
    37 #define print_debug_lexing_position(s)
    37 #define print_debug_lexing_position(s)
    38 #endif
    38 #endif
    39 
       
    40 
       
    41 
       
    42 // Simple linked list to cache source filenames, so we don't have to copy
       
    43 //  the same string over and over for each opcode.
       
    44 typedef struct FilenameCache
       
    45 {
       
    46     char *filename;
       
    47     struct FilenameCache *next;
       
    48 } FilenameCache;
       
    49 
    39 
    50 typedef struct Context
    40 typedef struct Context
    51 {
    41 {
    52     int isfail;
    42     int isfail;
    53     int out_of_memory;
    43     int out_of_memory;
    57     Conditional *conditional_pool;
    47     Conditional *conditional_pool;
    58     IncludeState *include_stack;
    48     IncludeState *include_stack;
    59     IncludeState *include_pool;
    49     IncludeState *include_pool;
    60     Define *define_hashtable[256];
    50     Define *define_hashtable[256];
    61     Define *define_pool;
    51     Define *define_pool;
    62     FilenameCache *filename_cache;
    52     StringCache *filename_cache;
    63     MOJOSHADER_includeOpen open_callback;
    53     MOJOSHADER_includeOpen open_callback;
    64     MOJOSHADER_includeClose close_callback;
    54     MOJOSHADER_includeClose close_callback;
    65     MOJOSHADER_malloc malloc;
    55     MOJOSHADER_malloc malloc;
    66     MOJOSHADER_free free;
    56     MOJOSHADER_free free;
    67     void *malloc_data;
    57     void *malloc_data;
   505         } // while
   495         } // while
   506     } // for
   496     } // for
   507 } // put_all_defines
   497 } // put_all_defines
   508 
   498 
   509 
   499 
   510 // filename cache stuff...
       
   511 
       
   512 static const char *cache_filename(Context *ctx, const char *fname)
       
   513 {
       
   514     if (fname == NULL)
       
   515         return NULL;
       
   516 
       
   517     // !!! FIXME: this could be optimized into a hash table, but oh well.
       
   518     FilenameCache *item = ctx->filename_cache;
       
   519     while (item != NULL)
       
   520     {
       
   521         if (strcmp(item->filename, fname) == 0)
       
   522             return item->filename;
       
   523         item = item->next;
       
   524     } // while
       
   525 
       
   526     // new cache item.
       
   527     item = (FilenameCache *) Malloc(ctx, sizeof (FilenameCache));
       
   528     if (item == NULL)
       
   529         return NULL;
       
   530 
       
   531     item->filename = StrDup(ctx, fname);
       
   532     if (item->filename == NULL)
       
   533     {
       
   534         Free(ctx, item);
       
   535         return NULL;
       
   536     } // if
       
   537 
       
   538     item->next = ctx->filename_cache;
       
   539     ctx->filename_cache = item;
       
   540 
       
   541     return item->filename;
       
   542 } // cache_filename
       
   543 
       
   544 
       
   545 static void free_filename_cache(Context *ctx)
       
   546 {
       
   547     FilenameCache *item = ctx->filename_cache;
       
   548     while (item != NULL)
       
   549     {
       
   550         FilenameCache *next = item->next;
       
   551         Free(ctx, item->filename);
       
   552         Free(ctx, item);
       
   553         item = next;
       
   554     } // while
       
   555 } // free_filename_cache
       
   556 
       
   557 
       
   558 static int push_source(Context *ctx, const char *fname, const char *source,
   500 static int push_source(Context *ctx, const char *fname, const char *source,
   559                        unsigned int srclen, unsigned int linenum,
   501                        unsigned int srclen, unsigned int linenum,
   560                        MOJOSHADER_includeClose close_callback, Define *defs)
   502                        MOJOSHADER_includeClose close_callback, Define *defs)
   561 {
   503 {
   562     if (srclen == 0)
   504     if (srclen == 0)
   566     if (state == NULL)
   508     if (state == NULL)
   567         return 0;
   509         return 0;
   568 
   510 
   569     if (fname != NULL)
   511     if (fname != NULL)
   570     {
   512     {
   571         state->filename = cache_filename(ctx, fname);
   513         state->filename = stringcache(ctx->filename_cache, fname);
   572         if (state->filename == NULL)
   514         if (state->filename == NULL)
   573         {
   515         {
       
   516             out_of_memory(ctx);
   574             put_include(ctx, state);
   517             put_include(ctx, state);
   575             return 0;
   518             return 0;
   576         } // if
   519         } // if
   577     } // if
   520     } // if
   578 
   521 
   659     assert(m != NULL);
   602     assert(m != NULL);
   660     assert(f != NULL);
   603     assert(f != NULL);
   661 
   604 
   662     Context *ctx = (Context *) m(sizeof (Context), d);
   605     Context *ctx = (Context *) m(sizeof (Context), d);
   663     if (ctx == NULL)
   606     if (ctx == NULL)
   664         return 0;
   607         return NULL;
   665 
   608 
   666     memset(ctx, '\0', sizeof (Context));
   609     memset(ctx, '\0', sizeof (Context));
   667     ctx->malloc = m;
   610     ctx->malloc = m;
   668     ctx->free = f;
   611     ctx->free = f;
   669     ctx->malloc_data = d;
   612     ctx->malloc_data = d;
   670     ctx->open_callback = open_callback;
   613     ctx->open_callback = open_callback;
   671     ctx->close_callback = close_callback;
   614     ctx->close_callback = close_callback;
   672     ctx->asm_comments = asm_comments;
   615     ctx->asm_comments = asm_comments;
       
   616     ctx->filename_cache = stringcache_create(m, f, d);
       
   617     if (ctx->filename_cache == 0)
       
   618     {
       
   619         f(ctx, d);
       
   620         return NULL;
       
   621     } // if
   673 
   622 
   674     // let the usual preprocessor parser sort these out.
   623     // let the usual preprocessor parser sort these out.
   675     char *define_include = NULL;
   624     char *define_include = NULL;
   676     unsigned int define_include_len = 0;
   625     unsigned int define_include_len = 0;
   677     if (define_count > 0)
   626     if (define_count > 0)
   726     while (ctx->include_stack != NULL)
   675     while (ctx->include_stack != NULL)
   727         pop_source(ctx);
   676         pop_source(ctx);
   728 
   677 
   729     put_all_defines(ctx);
   678     put_all_defines(ctx);
   730 
   679 
   731     free_filename_cache(ctx);
   680     if (ctx->filename_cache != NULL)
       
   681         stringcache_destroy(ctx->filename_cache);
       
   682 
   732     free_define_pool(ctx);
   683     free_define_pool(ctx);
   733     free_conditional_pool(ctx);
   684     free_conditional_pool(ctx);
   734     free_include_pool(ctx);
   685     free_include_pool(ctx);
   735 
   686 
   736     Free(ctx, ctx);
   687     Free(ctx, ctx);
   888     {
   839     {
   889         fail(ctx, "Invalid #line directive");
   840         fail(ctx, "Invalid #line directive");
   890         return;
   841         return;
   891     } // if
   842     } // if
   892 
   843 
   893     const char *cached = cache_filename(ctx, filename);
   844     const char *cached = stringcache(ctx->filename_cache, filename);
   894     assert((cached != NULL) || (ctx->out_of_memory));
   845     if (cached == NULL)
       
   846         out_of_memory(ctx);
   895     state->filename = cached;
   847     state->filename = cached;
   896     state->line = linenum;
   848     state->line = linenum;
   897 } // handle_pp_line
   849 } // handle_pp_line
   898 
   850 
   899 
   851