Esempio n. 1
0
extern void do_sharp (void)
{
   char *w;
   char c;

   w = read_ctrl();
   if (strcmp(w, "ifdef") == 0)
   {
      do_ifdef(1);
   }
   else if (strcmp(w, "ifndef") == 0)
   {
      do_ifndef(1);
   }
   else if (strcmp(w, "if") == 0)
   {
      do_if(1);
   }
   else if (strcmp(w, "else") == 0)
   {
      do_else(1);
   }
   else if (strcmp(w, "elif") == 0)
   {
      do_elif(1);
   }
   else if (strcmp(w, "endif") == 0)
   {
      do_endif(1);
   }
   else if (strcmp(w, "include") == 0)
   {
      do_include(1);
   }
   else if (strcmp(w, "define") == 0)
   {
      do_define(1, 0);
   }
   else if (strcmp(w, "undef") == 0)
   {
      do_undef(1);
   }
   else if (strcmp(w, "line") == 0)
   {
      do_line();
   }
   else if (strcmp(w, "pragma") == 0)
   {
      do_pragma();
   }
   else if (strcmp(w, "") == 0)
   {}
   else
   {
      int isnull;
      isnull = 0;
      if (strcmp(w, "") == 0)
      {
         c = Get();
         if (c != '\n')
         {
            Push(c);
         }
         else
         {
            isnull = 1;
         }
      }
      if (!isnull && !in_false_if())
      {
         err_head();
         fprintf(stderr, "unknown control `%s'\n", w);
         flush_sharp_line();
      }
   }
   maybe_print('\n');
   os_free(w);
}
Esempio n. 2
0
bool Parser::SM_Run()
{
	FILE *out_fp = included_files.top()->ofile;
	const char *pos;
	TRI_STATE result = TSV_0;
	const char *output = pline.from.c_str();
	sym_t preprocessor;
	CC_STRING expanded_line;

	do {
		pos = pline.parsed.c_str();
		preprocessor = GetPreprocessor(pos, &pos);
		if(preprocessor != pline.pp_id || (pline.content != -1 && pline.content + pline.parsed.c_str() != pos) ) {
			fprintf(stderr, "%s:%zu\n", dv_current_file, dv_current_line);
			fprintf(stderr, "  (%d) %s\n", pline.content, pline.parsed.c_str());
			fprintf(stderr, "  %d vs %d\n", preprocessor, pline.pp_id);
			exit(1);
		}
	} while(0);

	pos = pline.parsed.c_str() + pline.content;

	dv_current_file = GetCurrentFileName().c_str();
	dv_current_line = GetCurrentLineNumber();

//	GDB_TRAP2(strstr(dv_current_file,"makeint.h"), (dv_current_line==30));
//	GDB_TRAP2(strstr(dv_current_file,"/usr/include/features.h"), dv_current_line==131);
	switch(pline.pp_id) {
	case SSID_SHARP_IF:
		if( superior_conditional_value(true) != TSV_0 )
			result = (TRI_STATE) Compute(pos);
		goto handle_if_branch;

	case SSID_SHARP_IFNDEF:
		if( superior_conditional_value(true) != TSV_0 )
			result = (TRI_STATE) CheckSymbolDefined(pos, true, NULL);
		goto handle_if_branch;

	case SSID_SHARP_IFDEF:
		if( superior_conditional_value(true) != TSV_0 )
			result = (TRI_STATE) CheckSymbolDefined(pos, false, NULL);

handle_if_branch:
		if( result == TSV_X ) {
			if( gvar_preprocess_mode ) {
				if(errmsg.isnull())
					errmsg = "Error on processing conditional";
				goto done;
			}
		}

		conditionals.push(new CConditionalChain());

		upper_chain()->enter_if(result);
		upper_chain()->filename = dv_current_file;
		upper_chain()->line = dv_current_line;
		if(eval_current_conditional() != TSV_X)
			output = NULL;
		included_files.top()->add_if(result);
		break;

	case SSID_SHARP_ELIF:
		if( superior_conditional_value(false) == TSV_0 ) {
			included_files.top()->add_elif(false);
			goto done;
		}
		if( upper_chain()->has_true() ) {
			upper_chain()->enter_elif(TSV_0);
			included_files.top()->add_elif(false);
			goto done;
		}
		result = (TRI_STATE) Compute(pos);
		if( gvar_preprocess_mode && result == TSV_X)
			goto done;

		/*
		 *  Transformation on the condition of:
		 *
		 *  1) #if   0
		 *     #elif X --> #if   X
		 *
		 *  2) #elif X
		 *     #elif 1 --> #else
		 */
		if( eval_current_conditional() == TSV_0 ) {
			if(result == TSV_X) {
				pline.to = do_elif(1);
				output = pline.to.c_str();
			} else
				output = NULL;
		} else {
			if(result == TSV_1) {
				pline.to = do_elif(2);
				output = pline.to.c_str();
			} else if(result == TSV_0)
				output = NULL;
		}
		upper_chain()->enter_elif(result);
		included_files.top()->add_elif(result);
		break;

	case SSID_SHARP_ELSE:
		if( superior_conditional_value(false) == TSV_0 ) {
			included_files.top()->add_else(false);
			goto done;
		}
		result = upper_chain()->enter_else();
		included_files.top()->add_else(result);
		if( eval_current_conditional() != TSV_X )
			output = NULL;
		break;

	case SSID_SHARP_ENDIF:
		included_files.top()->add_endif();
		CConditionalChain *c;
		if( ! upper_chain()->keep_endif() )
			output = NULL;
		if( conditionals.size() == 0 ) {
			errmsg = "Unmatched #endif";
			goto done;
		}
		conditionals.pop(c);
		delete c;
		break;

	default:
		if(eval_current_conditional() == TSV_0)
			goto done;
		if(eval_current_conditional() == TSV_X)
			goto print_and_exit;

		switch(pline.pp_id) {
		  case SSID_SHARP_DEFINE:
			if(!do_define(pos))
				goto error_out;
			break;
		  case SSID_SHARP_UNDEF:
			handle_undef(intab, pos);
			break;
		  case SSID_SHARP_INCLUDE:
		  case SSID_SHARP_INCLUDE_NEXT:
			if( gvar_preprocess_mode )
				do_include(pline.pp_id, pos, &output);
			break;
		  default:
			if(gvar_expand_macros) {
				pos = pline.parsed.c_str();
				expanded_line = ExpandLine(intab, false, pos, errmsg);
				if(!errmsg.isnull())
					goto error_out;
				if(included_files.size() == 1) {
					expanded_line += '\n';
					output = expanded_line.c_str();
				}
			}
		}
	}

print_and_exit:
	if( out_fp != NULL && output != NULL )
		fprintf(out_fp, "%s", output);
done:
	pline.comment_start = -1;
	if(gvar_preprocess_mode && GetError()) {
		IncludedFile *tmp;
		CC_STRING pmsg, ts;
		while(included_files.size() > 0) {
			included_files.pop(tmp);
			ts.Format("  %s:%u\n", tmp->ifile->name.c_str(), tmp->ifile->line);
			pmsg += ts;
		}
		if( !pmsg.isnull() ) {
			errmsg = pmsg + errmsg;
		}
	}
	return gvar_preprocess_mode ? (GetError() == NULL) : true;

error_out:
	return false;
}
Esempio n. 3
0
static Token next_token (void)
{
  Token token;
 restart:
  outbuffer_off();
  outbuffer_on();
  token.startindex = out.buffindex;
  {
    int c = next_char();
    switch (c) {
      case EOF:
        /* EOF */
        token.type = eof;
        goto done;
      case ' ': case '\v': case '\t': case '\n':
        /* whitespace, ignore */
        goto restart;
      case '\\':
        if (peek_char()=='\n') {
          /* backslash newline, ignore */
          next_char();
          goto restart;
        }
        goto separator;
      case '/':
        if (peek_char() == '*') {
          /* Comment */
          next_char();
          while (1) {
            c = next_char();
            if (c==EOF) {
              fprintf(stderr,"Unfinished comment\n");
              break;
            }
            if ((c=='*') && (peek_char()=='/')) {
              next_char();
              break;
            }
          }
          goto restart;
        }
        goto separator;
      case '*':
        if (peek_char() == '/')
          fprintf(stderr,"End of comment outside comment in line %lu\n",input_line);
        goto separator;
      case '#':
        /* preprocessor directive */
        {
          char* line = next_line();
          if (line) {
            char* old_line = line;
            line = concat2("#",line);
            xfree(old_line);
          } else
            line = concat1("#");
          while (line[strlen(line)-1] == '\\') {
            char* continuation_line = next_line();
            line[strlen(line)-1] = '\0';
            if (continuation_line) {
              char* old_line = line;
              line = concat2(line,continuation_line);
              xfree(old_line);
              xfree(continuation_line);
            }
          }
          {
            const char* condition;
            long line_directive;
            if ((condition = is_if(line)) != NULL) {
              do_if(condition);
            } else if (is_else(line)) {
              do_else();
              line_repeat_else();
            } else if ((condition = is_elif(line)) != NULL) {
              do_elif(condition);
              line_repeat_else();
            } else if (is_endif(line)) {
              do_endif();
              line_repeat_endif();
            } else if ((line_directive = decode_line_directive(line)) >= 0)
              input_line = line_directive;
#ifdef SPLIT_OBJECT_INITIALIZATIONS
            else {
              /* Replace "var object foo = ..." with "var object foo; foo = ..."
               in macros as well. */
              if (out.buffindex < MAXHEADERLEN) {
                uintB* p;
                out.buffer[out.buffindex] = '\0';
                for (p = &out.buffer[token.startindex]; ; p++) {
                  p = (uintB*) strstr((char*)p,"var ");
                  if (p == NULL)
                    break;
                  if ((strncmp((char*)p,"var object ",
                               strlen("var object "))==0
                       || strncmp((char*)p,"var chart ",
                                  strlen("var chart "))==0)
                      && (p[-1] == ' ' || p[-1] == '{')) {
                    if (strncmp((char*)p,"var object ",
                                strlen("var object "))==0)
                      p += strlen("var object ");
                    else if (strncmp((char*)p,"var chart ",
                                     strlen("var chart "))==0)
                      p += strlen("var chart ");
                    { uintB* q = p;
                      if ((*q >= 'A' && *q <= 'Z')
                          || (*q >= 'a' && *q <= 'z')
                          || *q == '_') {
                        do q++;
                        while ((*q >= 'A' && *q <= 'Z')
                               || (*q >= 'a' && *q <= 'z')
                               || (*q >= '0' && *q <= '9')
                               || *q == '_');
                        while (*q == ' ')
                          q++;
                        if (*q == '=') {
                          uintL insertlen = 2+(q-p);
                          if (out.buffindex + insertlen < MAXHEADERLEN) {
                            memmove(q+insertlen,q,
                                    &out.buffer[out.buffindex]-q+1);
                            q[0] = ';'; q[1] = ' ';
                            memcpy(q+2, p, q-p);
                            out.buffindex += insertlen;
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
#endif
          }
          xfree(line);
        }
        goto separator;
      case '.':
        c = peek_char();
        if (!(((c>='0') && (c<='9')) || (c=='.')))
          goto separator;
      case '0': case '1': case '2': case '3': case '4':
      case '5': case '6': case '7': case '8': case '9':
        /* Digit. Continue reading as long as alphanumeric or '.'. */
        while (1) {
          c = peek_char();
          if (((c>='0') && (c<='9')) || ((c>='A') && (c<='Z')) || ((c>='a') && (c<='z')) || (c=='.'))
            next_char();
          else
            break;
        }
        token.type = number;
        goto done;
      case '\'':
        /* Character constant */
        while (1) {
          c = next_char();
          if (c==EOF) {
            fprintf(stderr,"Unterminated character constant\n");
            break;
          }
          if (c=='\'')
            break;
          if (c=='\\')
            c = next_char();
        }
        token.type = charconst;
        goto done;
      case '\"':
        /* String constant */
        while (1) {
          c = next_char();
          if (c==EOF) {
            fprintf(stderr,"Unterminated string constant\n");
            break;
          }
          if (c=='\"')
            break;
          if (c=='\\')
            c = next_char();
        }
        token.type = stringconst;
        goto done;
      case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
      case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
      case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
      case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
      case 'Y': case 'Z':
      case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
      case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
      case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
      case 's': case 't': case 'u': case 'v': case 'w': case 'x':
      case 'y': case 'z':
      case '_':
        /* Identifier. */
        while (1) {
          c = peek_char();
          if (((c>='0') && (c<='9')) || ((c>='A') && (c<='Z')) || ((c>='a') && (c<='z')) || (c=='_'))
            next_char();
          else
            break;
        }
        token.type = ident;
        goto done;
      default:
      separator:
        token.type = sep;
        token.ch = c;
        goto done;
    }
  }
 done:
  token.endindex = out.buffindex;
  return token;
}