⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 slang_preprocess.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 3 页
字号:
      *result = results[0];   }   else {      /* The directive is dead. */      *result = 0;   }   *pi += len + 1;   return GL_TRUE;}#define ESCAPE_TOKEN 0#define TOKEN_END       0#define TOKEN_DEFINE    1#define TOKEN_UNDEF     2#define TOKEN_IF        3#define TOKEN_ELSE      4#define TOKEN_ELIF      5#define TOKEN_ENDIF     6#define TOKEN_ERROR     7#define TOKEN_PRAGMA    8#define TOKEN_EXTENSION 9#define TOKEN_LINE      10#define PARAM_END       0#define PARAM_PARAMETER 1#define BEHAVIOR_REQUIRE 1#define BEHAVIOR_ENABLE  2#define BEHAVIOR_WARN    3#define BEHAVIOR_DISABLE 4static GLbooleanpreprocess_source (slang_string *output, const char *source, grammar pid, grammar eid,                   slang_info_log *elog){   static const char *predefined[] = {      "__FILE__",      "__LINE__",      "__VERSION__",#if FEATURE_es2_glsl      "GL_ES",      "GL_FRAGMENT_PRECISION_HIGH",#endif      NULL   };   byte *prod;   GLuint size, i;   pp_state state;   if (!grammar_fast_check (pid, (const byte *) (source), &prod, &size, 65536)) {      grammar_error_to_log (elog);      return GL_FALSE;   }   pp_state_init (&state, elog);   /* add the predefined symbols to the symbol table */   for (i = 0; predefined[i]; i++) {      pp_symbol *symbol = NULL;      symbol = pp_symbols_push(&state.symbols);      assert(symbol);      slang_string_pushs(&symbol->name,                         predefined[i], _mesa_strlen(predefined[i]));   }   i = 0;   while (i < size) {      if (prod[i] != ESCAPE_TOKEN) {         if (state.cond.top->effective) {            slang_string input;            expand_state es;            /* Eat only one line of source code to expand it.             * FIXME: This approach has one drawback. If a macro with parameters spans across             *        multiple lines, the preprocessor will raise an error. */            slang_string_init (&input);            while (prod[i] != '\0' && prod[i] != '\n')               slang_string_pushc (&input, prod[i++]);            if (prod[i] != '\0')               slang_string_pushc (&input, prod[i++]);            /* Increment line number. */            state.line++;            es.output = output;            es.input = slang_string_cstr (&input);            es.state = &state;            if (!expand (&es, &state.symbols))               goto error;            slang_string_free (&input);         }         else {            /* Condition stack is disabled - keep track on line numbers and output only newlines. */            if (prod[i] == '\n') {               state.line++;               /*pp_annotate (output, "%c", prod[i]);*/            }            else {               /*pp_annotate (output, "%c", prod[i]);*/            }            i++;         }      }      else {         const char *id;         GLuint idlen;         i++;         switch (prod[i++]) {         case TOKEN_END:            /* End of source string.               * Check if all #ifs have been terminated by matching #endifs.               * On condition stack there should be only the global condition context. */            if (state.cond.top->endif_required) {               slang_info_log_error (elog, "end of source without matching #endif.");               return GL_FALSE;            }            break;         case TOKEN_DEFINE:            {               pp_symbol *symbol = NULL;               /* Parse macro name. */               id = (const char *) (&prod[i]);               idlen = _mesa_strlen (id);               if (state.cond.top->effective) {                  pp_annotate (output, "// #define %s(", id);                  /* If the symbol is already defined, override it. */                  symbol = pp_symbols_find (&state.symbols, id);                  if (symbol == NULL) {                     symbol = pp_symbols_push (&state.symbols);                     if (symbol == NULL)                        goto error;                     slang_string_pushs (&symbol->name, id, idlen);                  }                  else {                     pp_symbol_reset (symbol);                  }               }               i += idlen + 1;               /* Parse optional macro parameters. */               while (prod[i++] != PARAM_END) {                  if (state.cond.top->effective) {                     pp_symbol *param;                     id = (const char *) (&prod[i]);                     idlen = _mesa_strlen (id);                     pp_annotate (output, "%s, ", id);                     param = pp_symbols_push (&symbol->parameters);                     if (param == NULL)                        goto error;                     slang_string_pushs (&param->name, id, idlen);                  }                  i += idlen + 1;               }               /* Parse macro replacement. */               id = (const char *) (&prod[i]);               idlen = _mesa_strlen (id);               if (state.cond.top->effective) {                  pp_annotate (output, ") %s", id);                  slang_string_pushs (&symbol->replacement, id, idlen);               }               i += idlen + 1;            }            break;         case TOKEN_UNDEF:            id = (const char *) (&prod[i]);            i += _mesa_strlen (id) + 1;            if (state.cond.top->effective) {               pp_symbol *symbol;               pp_annotate (output, "// #undef %s", id);               /* Try to find symbol with given name and remove it. */               symbol = pp_symbols_find (&state.symbols, id);               if (symbol != NULL)                  if (!pp_symbols_erase (&state.symbols, symbol))                     goto error;            }            break;         case TOKEN_IF:            {               GLint result;               /* Parse #if expression end execute it. */               pp_annotate (output, "// #if ");               if (!parse_if (output, prod, &i, &result, &state, eid))                  goto error;               /* Push new condition on the stack. */               if (!pp_cond_stack_push (&state.cond, state.elog))                  goto error;               state.cond.top->current = result ? GL_TRUE : GL_FALSE;               state.cond.top->else_allowed = GL_TRUE;               state.cond.top->endif_required = GL_TRUE;               pp_cond_stack_reevaluate (&state.cond);            }            break;         case TOKEN_ELSE:            /* Check if #else is alloved here. */            if (!state.cond.top->else_allowed) {               slang_info_log_error (elog, "#else without matching #if.");               goto error;            }            /* Negate current condition and reevaluate it. */            state.cond.top->current = !state.cond.top->current;            state.cond.top->else_allowed = GL_FALSE;            pp_cond_stack_reevaluate (&state.cond);            if (state.cond.top->effective)               pp_annotate (output, "// #else");            break;         case TOKEN_ELIF:            /* Check if #elif is alloved here. */            if (!state.cond.top->else_allowed) {               slang_info_log_error (elog, "#elif without matching #if.");               goto error;            }            /* Negate current condition and reevaluate it. */            state.cond.top->current = !state.cond.top->current;            pp_cond_stack_reevaluate (&state.cond);            if (state.cond.top->effective)               pp_annotate (output, "// #elif ");            {               GLint result;               /* Parse #elif expression end execute it. */               if (!parse_if (output, prod, &i, &result, &state, eid))                  goto error;               /* Update current condition and reevaluate it. */               state.cond.top->current = result ? GL_TRUE : GL_FALSE;               pp_cond_stack_reevaluate (&state.cond);            }            break;         case TOKEN_ENDIF:            /* Check if #endif is alloved here. */            if (!state.cond.top->endif_required) {               slang_info_log_error (elog, "#endif without matching #if.");               goto error;            }            /* Pop the condition off the stack. */            state.cond.top++;            if (state.cond.top->effective)               pp_annotate (output, "// #endif");            break;         case TOKEN_EXTENSION:            /* Parse the extension name. */            id = (const char *) (&prod[i]);            i += _mesa_strlen (id) + 1;            if (state.cond.top->effective)               pp_annotate (output, "// #extension %s: ", id);            /* Parse and apply extension behavior. */            if (state.cond.top->effective) {               switch (prod[i++]) {               case BEHAVIOR_REQUIRE:                  pp_annotate (output, "require");                  if (!pp_ext_set (&state.ext, id, GL_TRUE)) {                     if (_mesa_strcmp (id, "all") == 0) {                        slang_info_log_error (elog, "require: bad behavior for #extension all.");                        goto error;                     }                     else {                        slang_info_log_error (elog, "%s: required extension is not supported.", id);                        goto error;                     }                  }                  break;               case BEHAVIOR_ENABLE:                  pp_annotate (output, "enable");                  if (!pp_ext_set (&state.ext, id, GL_TRUE)) {                     if (_mesa_strcmp (id, "all") == 0) {                        slang_info_log_error (elog, "enable: bad behavior for #extension all.");                        goto error;                     }                     else {                        slang_info_log_warning (elog, "%s: enabled extension is not supported.", id);                     }                  }                  break;               case BEHAVIOR_WARN:                  pp_annotate (output, "warn");                  if (!pp_ext_set (&state.ext, id, GL_TRUE)) {                     if (_mesa_strcmp (id, "all") != 0) {                        slang_info_log_warning (elog, "%s: enabled extension is not supported.", id);                     }                  }                  break;               case BEHAVIOR_DISABLE:                  pp_annotate (output, "disable");                  if (!pp_ext_set (&state.ext, id, GL_FALSE)) {                     if (_mesa_strcmp (id, "all") == 0) {                        pp_ext_disable_all (&state.ext);                     }                     else {                        slang_info_log_warning (elog, "%s: disabled extension is not supported.", id);                     }                  }                  break;               default:                  assert (0);               }            }            break;         case TOKEN_LINE:            id = (const char *) (&prod[i]);            i += _mesa_strlen (id) + 1;            if (state.cond.top->effective) {               slang_string buffer;               GLuint count;               GLint results[2];               expand_state es;               slang_string_init (&buffer);               state.line++;               es.output = &buffer;               es.input = id;               es.state = &state;               if (!expand (&es, &state.symbols))                  goto error;               pp_annotate (output, "// #line ");               count = execute_expressions (output, eid,                                             (const byte *) (slang_string_cstr (&buffer)),                                             results, state.elog);               slang_string_free (&buffer);               if (count == 0)                  goto error;               state.line = results[0] - 1;               if (count == 2)                  state.file = results[1];            }            break;         }      }   }   /* Check for missing #endifs. */   if (state.cond.top->endif_required) {      slang_info_log_error (elog, "#endif expected but end of source found.");      goto error;   }   grammar_alloc_free(prod);   pp_state_free (&state);   return GL_TRUE;error:   grammar_alloc_free(prod);   pp_state_free (&state);   return GL_FALSE;}GLboolean_slang_preprocess_directives (slang_string *output, const char *input, slang_info_log *elog){   grammar pid, eid;   GLboolean success;   pid = grammar_load_from_text ((const byte *) (slang_pp_directives_syn));   if (pid == 0) {      grammar_error_to_log (elog);      return GL_FALSE;   }   eid = grammar_load_from_text ((const byte *) (slang_pp_expression_syn));   if (eid == 0) {      grammar_error_to_log (elog);      grammar_destroy (pid);      return GL_FALSE;   }   success = preprocess_source (output, input, pid, eid, elog);   grammar_destroy (eid);   grammar_destroy (pid);   return success;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -