mojoshader_preprocessor.c
changeset 598 decc32dc03a7
parent 597 832dbfa63509
child 601 bb1484be4e1b
equal deleted inserted replaced
597:832dbfa63509 598:decc32dc03a7
    43 
    43 
    44 // Convenience functions for allocators...
    44 // Convenience functions for allocators...
    45 
    45 
    46 static inline void out_of_memory(Context *ctx)
    46 static inline void out_of_memory(Context *ctx)
    47 {
    47 {
    48     ctx->isfail = ctx->out_of_memory = 1;
    48     ctx->out_of_memory = 1;
    49 } // out_of_memory
    49 } // out_of_memory
    50 
    50 
    51 static inline void *Malloc(Context *ctx, const size_t len)
    51 static inline void *Malloc(Context *ctx, const size_t len)
    52 {
    52 {
    53     void *retval = ctx->malloc((int) len, ctx->malloc_data);
    53     void *retval = ctx->malloc((int) len, ctx->malloc_data);
    74 static void failf(Context *ctx, const char *fmt, ...)
    74 static void failf(Context *ctx, const char *fmt, ...)
    75 {
    75 {
    76     ctx->isfail = 1;
    76     ctx->isfail = 1;
    77     va_list ap;
    77     va_list ap;
    78     va_start(ap, fmt);
    78     va_start(ap, fmt);
    79     vsnprintf(ctx->failstr, sizeof (ctx->failstr), fmt, ap);  // rebuild it.
    79     vsnprintf(ctx->failstr, sizeof (ctx->failstr), fmt, ap);
    80     va_end(ap);
    80     va_end(ap);
    81 } // failf
    81 } // failf
    82 
    82 
    83 static inline void fail(Context *ctx, const char *reason)
    83 static inline void fail(Context *ctx, const char *reason)
    84 {
    84 {
   140         TOKENCASE(TOKEN_PP_ENDIF);
   140         TOKENCASE(TOKEN_PP_ENDIF);
   141         TOKENCASE(TOKEN_PP_ERROR);
   141         TOKENCASE(TOKEN_PP_ERROR);
   142         TOKENCASE(TOKEN_PP_INCOMPLETE_COMMENT);
   142         TOKENCASE(TOKEN_PP_INCOMPLETE_COMMENT);
   143         TOKENCASE(TOKEN_PP_BAD_CHARS);
   143         TOKENCASE(TOKEN_PP_BAD_CHARS);
   144         TOKENCASE(TOKEN_EOI);
   144         TOKENCASE(TOKEN_EOI);
       
   145         TOKENCASE(TOKEN_PREPROCESSING_ERROR);
   145         #undef TOKENCASE
   146         #undef TOKENCASE
   146 
   147 
   147         case ((Token) '\n'):
   148         case ((Token) '\n'):
   148             printf("'\\n'");
   149             printf("'\\n'");
   149             break;
   150             break;
   382 
   383 
   383     Free(ctx, ctx);
   384     Free(ctx, ctx);
   384 } // preprocessor_end
   385 } // preprocessor_end
   385 
   386 
   386 
   387 
   387 const char *preprocessor_error(Preprocessor *_ctx)
       
   388 {
       
   389     Context *ctx = (Context *) _ctx;
       
   390     if (ctx->isfail)
       
   391     {
       
   392         ctx->isfail = 0;
       
   393         return ctx->failstr;
       
   394     } // if
       
   395 
       
   396     return NULL;
       
   397 } // preprocessor_error
       
   398 
       
   399 
       
   400 int preprocessor_outofmemory(Preprocessor *_ctx)
   388 int preprocessor_outofmemory(Preprocessor *_ctx)
   401 {
   389 {
   402     Context *ctx = (Context *) _ctx;
   390     Context *ctx = (Context *) _ctx;
   403     return ctx->out_of_memory;
   391     return ctx->out_of_memory;
   404 } // preprocessor_outofmemory
   392 } // preprocessor_outofmemory
   409 {
   397 {
   410     Context *ctx = (Context *) _ctx;
   398     Context *ctx = (Context *) _ctx;
   411 
   399 
   412     while (1)
   400     while (1)
   413     {
   401     {
       
   402         if (ctx->isfail)
       
   403         {
       
   404             ctx->isfail = 0;
       
   405             *_token = TOKEN_PREPROCESSING_ERROR;
       
   406             *_len = strlen(ctx->failstr);
       
   407             return ctx->failstr;
       
   408         } // if
       
   409 
   414         IncludeState *state = ctx->include_stack;
   410         IncludeState *state = ctx->include_stack;
   415         if (state == NULL)
   411         if (state == NULL)
   416         {
   412         {
   417             *_token = TOKEN_EOI;
   413             *_token = TOKEN_EOI;
   418             *_len = 0;
   414             *_len = 0;
   428         } // if
   424         } // if
   429 
   425 
   430         else if (token == TOKEN_PP_INCOMPLETE_COMMENT)
   426         else if (token == TOKEN_PP_INCOMPLETE_COMMENT)
   431         {
   427         {
   432             fail(ctx, "Incomplete multiline comment");
   428             fail(ctx, "Incomplete multiline comment");
   433             continue;  // !!! FIXME: we should probably return TOKEN_ERROR or something.
   429             continue;  // will return at top of loop.
   434         } // else if
   430         } // else if
   435 
   431 
   436         *_token = token;
   432         *_token = token;
   437         *_len = (unsigned int) (state->source - state->token);
   433         *_len = (unsigned int) (state->source - state->token);
   438         return state->token;
   434         return state->token;
   655     if (pp == NULL)
   651     if (pp == NULL)
   656         return &out_of_mem_data_preprocessor;
   652         return &out_of_mem_data_preprocessor;
   657 
   653 
   658     Token token = TOKEN_UNKNOWN;
   654     Token token = TOKEN_UNKNOWN;
   659     const char *tokstr = NULL;
   655     const char *tokstr = NULL;
   660     const char *err = NULL;
       
   661 
   656 
   662     Buffer buffer;
   657     Buffer buffer;
   663     buffer_init(&buffer);
   658     buffer_init(&buffer);
   664 
   659 
   665     int nl = 1;
   660     int nl = 1;
   710                 indent++;
   705                 indent++;
   711                 isnewline = 1;
   706                 isnewline = 1;
   712             } // if
   707             } // if
   713         } // else if
   708         } // else if
   714 
   709 
       
   710         else if (token == TOKEN_PREPROCESSING_ERROR)
       
   711         {
       
   712             if (!out_of_memory)
       
   713             {
       
   714                 ErrorList *error = (ErrorList *) m(sizeof (ErrorList), d);
       
   715                 unsigned int pos = 0;
       
   716                 char *fname = NULL;
       
   717                 const char *str = preprocessor_sourcepos(pp, &pos);
       
   718                 if (str != NULL)
       
   719                 {
       
   720                     fname = (char *) m(strlen(str) + 1, d);
       
   721                     if (fname != NULL)
       
   722                         strcpy(fname, str);
       
   723                 } // if
       
   724 
       
   725                 // !!! FIXME: cut and paste with other error handlers.
       
   726                 char *errstr = (char *) m(len + 1, d);
       
   727                 if (errstr != NULL)
       
   728                     strcpy(errstr, tokstr);
       
   729 
       
   730                 out_of_memory = ((!error) || ((!fname) && (str)) || (!errstr));
       
   731                 if (out_of_memory)
       
   732                 {
       
   733                     if (errstr) f(errstr, d);
       
   734                     if (fname) f(fname, d);
       
   735                     if (error) f(error, d);
       
   736                 } // if
       
   737                 else
       
   738                 {
       
   739                     error->error.error = errstr;
       
   740                     error->error.filename = fname;
       
   741                     error->error.error_position = pos;
       
   742                     error->next = NULL;
       
   743 
       
   744                     ErrorList *prev = NULL;
       
   745                     ErrorList *item = errors;
       
   746                     while (item != NULL)
       
   747                     {
       
   748                         prev = item;
       
   749                         item = item->next;
       
   750                     } // while
       
   751 
       
   752                     if (prev == NULL)
       
   753                         errors = error;
       
   754                     else
       
   755                         prev->next = error;
       
   756 
       
   757                     error_count++;
       
   758                 } // else
       
   759             } // if
       
   760         } // else if
       
   761 
   715         else
   762         else
   716         {
   763         {
   717             if (!out_of_memory)
   764             if (!out_of_memory)
   718             {
   765             {
   719                 out_of_memory = (!indent_buffer(&buffer, indent, nl, m, d)) ||
   766                 out_of_memory = (!indent_buffer(&buffer, indent, nl, m, d)) ||
   721 
   768 
   722             } // if
   769             } // if
   723         } // else
   770         } // else
   724 
   771 
   725         nl = isnewline;
   772         nl = isnewline;
   726 
       
   727         if ((!out_of_memory) && ((err = preprocessor_error(pp)) != NULL))
       
   728         {
       
   729             ErrorList *error = (ErrorList *) m(sizeof (ErrorList), d);
       
   730             unsigned int pos = 0;
       
   731             char *fname = NULL;
       
   732             const char *str = preprocessor_sourcepos(pp, &pos);
       
   733             if (str != NULL)
       
   734             {
       
   735                 fname = (char *) m(strlen(str) + 1, d);
       
   736                 if (fname != NULL)
       
   737                     strcpy(fname, str);
       
   738             } // if
       
   739 
       
   740             // !!! FIXME: cut and paste with other error handlers.
       
   741             char *errstr = (char *) m(strlen(err) + 1, d);
       
   742             if (errstr != NULL)
       
   743                 strcpy(errstr, err);
       
   744 
       
   745             out_of_memory = ((!error) || ((!fname) && (str)) || (!errstr));
       
   746             if (out_of_memory)
       
   747             {
       
   748                 if (errstr) f(errstr, d);
       
   749                 if (fname) f(fname, d);
       
   750                 if (error) f(error, d);
       
   751             } // if
       
   752             else
       
   753             {
       
   754                 error->error.error = errstr;
       
   755                 error->error.filename = fname;
       
   756                 error->error.error_position = pos;
       
   757                 error->next = NULL;
       
   758 
       
   759                 ErrorList *prev = NULL;
       
   760                 ErrorList *item = errors;
       
   761                 while (item != NULL)
       
   762                 {
       
   763                     prev = item;
       
   764                     item = item->next;
       
   765                 } // while
       
   766 
       
   767                 if (prev == NULL)
       
   768                     errors = error;
       
   769                 else
       
   770                     prev->next = error;
       
   771 
       
   772                 error_count++;
       
   773             } // else
       
   774 
       
   775             continue;
       
   776         } // if
       
   777 
   773 
   778         if (out_of_memory)
   774         if (out_of_memory)
   779         {
   775         {
   780             preprocessor_end(pp);
   776             preprocessor_end(pp);
   781             free_buffer(&buffer, f, d);
   777             free_buffer(&buffer, f, d);