mojoshader_preprocessor.c
changeset 873 bdffabea8e40
parent 871 e72ec737ed74
child 875 dc28354d576e
equal deleted inserted replaced
872:5fde53b06a2e 873:bdffabea8e40
   522     memcpy(sym, state->token, state->tokenlen);
   522     memcpy(sym, state->token, state->tokenlen);
   523     sym[state->tokenlen] = '\0';
   523     sym[state->tokenlen] = '\0';
   524 
   524 
   525     for (def = state->defines; def != NULL; def = def->next)
   525     for (def = state->defines; def != NULL; def = def->next)
   526     {
   526     {
       
   527         assert(def->parameters == NULL);  // args can't have args!
   527         assert(def->paramcount == 0);  // args can't have args!
   528         assert(def->paramcount == 0);  // args can't have args!
   528         if (strcmp(def->identifier, sym) == 0)
   529         if (strcmp(def->identifier, sym) == 0)
   529             break;
   530             break;
   530     } // while
   531     } // while
   531 
   532 
  1269 
  1270 
  1270         is_macro = 1;
  1271         is_macro = 1;
  1271 
  1272 
  1272         if (def->paramcount != 0)
  1273         if (def->paramcount != 0)
  1273         {
  1274         {
       
  1275             MOJOSHADER_malloc m = ctx->malloc;
       
  1276             MOJOSHADER_free f = ctx->free;
       
  1277             void *d = ctx->malloc_data;
  1274             const int expected = (def->paramcount < 0) ? 0 : def->paramcount;
  1278             const int expected = (def->paramcount < 0) ? 0 : def->paramcount;
  1275             int saw_params = 0;
  1279             int saw_params = 0;
  1276             IncludeState saved;  // can't pushback, we need the original token.
  1280             IncludeState saved;  // can't pushback, we need the original token.
  1277             memcpy(&saved, state, sizeof (IncludeState));
  1281             memcpy(&saved, state, sizeof (IncludeState));
  1278             if (lexer(state) != ((Token) '('))
  1282             if (lexer(state) != ((Token) '('))
  1283 
  1287 
  1284             int void_call = 0;
  1288             int void_call = 0;
  1285             int paren = 1;
  1289             int paren = 1;
  1286             while (paren > 0)
  1290             while (paren > 0)
  1287             {
  1291             {
  1288                 const char *expr = NULL;
  1292                 Buffer buffer;
  1289                 const char *exprend = NULL;
       
  1290                 assert(!void_call);
  1293                 assert(!void_call);
       
  1294 
       
  1295                 init_buffer(&buffer);
       
  1296 
  1291                 while (1)
  1297                 while (1)
  1292                 {
  1298                 {
  1293                     exprend = state->source;
       
  1294                     const Token t = lexer(state);
  1299                     const Token t = lexer(state);
       
  1300                     const char *expr = state->token;
       
  1301                     unsigned int exprlen = state->tokenlen;
  1295                     if (t == '(')
  1302                     if (t == '(')
  1296                         paren++;
  1303                         paren++;
       
  1304 
  1297                     else if (t == ')')
  1305                     else if (t == ')')
  1298                     {
  1306                     {
  1299                         paren--;
  1307                         paren--;
  1300                         if (paren < 1)  // end of macro?
  1308                         if (paren < 1)  // end of macro?
  1301                             break;
  1309                             break;
  1302                     } // else if
  1310                     } // else if
       
  1311 
  1303                     else if (t == ',')
  1312                     else if (t == ',')
  1304                     {
  1313                     {
  1305                         if (paren == 1)  // new macro arg?
  1314                         if (paren == 1)  // new macro arg?
  1306                             break;
  1315                             break;
  1307                     } // else if
  1316                     } // else if
       
  1317 
       
  1318                     // is this an arg in the current macro?
       
  1319                     //  This is a special case, we need to replace here.
       
  1320                     else if ((state->is_macro) && (t == TOKEN_IDENTIFIER))
       
  1321                     {
       
  1322                         const Define *arg = find_macro_arg(state);
       
  1323                         if (arg)
       
  1324                         {
       
  1325                             expr = arg->definition;
       
  1326                             exprlen = strlen(arg->definition);
       
  1327                         } // if
       
  1328                     } // else if
       
  1329 
  1308                     else if ((t == TOKEN_INCOMPLETE_COMMENT) || (t == TOKEN_EOI))
  1330                     else if ((t == TOKEN_INCOMPLETE_COMMENT) || (t == TOKEN_EOI))
  1309                     {
  1331                     {
  1310                         pushback(state);
  1332                         pushback(state);
  1311                         fail(ctx, "Unterminated macro list");
  1333                         fail(ctx, "Unterminated macro list");
       
  1334                         free_buffer(&buffer, f, d);
  1312                         goto handle_pp_identifier_failed;
  1335                         goto handle_pp_identifier_failed;
  1313                     } // else if
  1336                     } // else if
  1314 
  1337 
  1315                     if (expr == NULL)
  1338                     assert(expr != NULL);
  1316                         expr = state->token;
  1339 
       
  1340                     if (!add_to_buffer(&buffer, expr, exprlen, m, d))
       
  1341                     {
       
  1342                         out_of_memory(ctx);
       
  1343                         free_buffer(&buffer, f, d);
       
  1344                         goto handle_pp_identifier_failed;
       
  1345                     } // if
  1317                 } // while
  1346                 } // while
  1318 
  1347 
  1319                 if (expr == NULL)
  1348                 if (buffer.total_bytes == 0)
  1320                 {
       
  1321                     expr = exprend = "";
       
  1322                     void_call = ((saw_params == 0) && (paren == 0));
  1349                     void_call = ((saw_params == 0) && (paren == 0));
  1323                 } // if
       
  1324 
  1350 
  1325                 if (saw_params < expected)
  1351                 if (saw_params < expected)
  1326                 {
  1352                 {
  1327                     Define *p = get_define(ctx);
  1353                     Define *p = get_define(ctx);
  1328                     if (p == NULL)
  1354                     if (p == NULL)
  1329                         goto handle_pp_identifier_failed;
  1355                         goto handle_pp_identifier_failed;
  1330 
  1356 
  1331                     p->next = params;
  1357                     p->next = params;
  1332                     params = p;
  1358                     params = p;
  1333 
  1359 
  1334                     const unsigned int exprlen = (unsigned int) (exprend - expr);
  1360                     char *definition = flatten_buffer(&buffer, m, d);
  1335                     char *definition = (char *) Malloc(ctx, exprlen + 1);
  1361                     free_buffer(&buffer, f, d);
  1336                     if (definition == NULL)
  1362                     if (definition == NULL)
       
  1363                     {
       
  1364                         out_of_memory(ctx);
  1337                         goto handle_pp_identifier_failed;
  1365                         goto handle_pp_identifier_failed;
  1338                     memcpy(definition, expr, exprlen);
  1366                     } // if
  1339                     definition[exprlen] = '\0';
       
  1340                     p->identifier = def->parameters[saw_params];
  1367                     p->identifier = def->parameters[saw_params];
  1341                     p->definition = definition;
  1368                     p->definition = definition;
  1342                 } // if
  1369                 } // if
  1343 
  1370 
  1344                 saw_params++;
  1371                 saw_params++;