예제 #1
0
char *filter_macros(char *line)
{
	if(*line == '#'){
		handle_macro(line);
		free(line);
		return NULL;
	}else{
		filter_macro(&line);
		return line;
	}
}
예제 #2
0
/*
 * handle_cl_macro
 *
 * handle for closing macro
 */
static BOOL handle_cl_macro(HSCPRC * hp, HSCTAG * tag)
{
    return (handle_macro(hp, tag, FALSE));
}
예제 #3
0
/*
 * handle_op_macro
 *
 * handle for opening macro
 */
static BOOL handle_op_macro(HSCPRC * hp, HSCTAG * tag)
{
    return (handle_macro(hp, tag, TRUE));
}
예제 #4
0
void handle_macro(preprocessor_state* preproc, int macro)
{
	FILE* input = preproc->input;
	FILE* output = preproc->output;
	lexer_state* lexer = &preproc->lexer;

	rsw_cstr expansion;
	init_cstr_str(&expansion, preproc->values.a[macro], strlen(preproc->values.a[macro]));

	macro_params* p = GET_PARAM(&preproc->params, macro);
	
	//do initial argument expansion
	if (p->num_params >= 0)
		parse_params(preproc, macro, &expansion);

	cvector_i valid_macros;
	cvec_i(&valid_macros, preproc->macros.size, preproc->macros.size);
	for (int i=0; i < preproc->macros.size; ++i) {
		valid_macros.a[i] = i;
	}

	rescan_expansion(preproc, &expansion, &valid_macros, macro);

	lexer_state save_lex;
	long fpos;
	token_lex t;

	save_lex = *lexer;
	if ((fpos = ftell(input)) == -1) {
		perror("ftell error in handle_macro");
		exit(0);
	}
	t = read_token(input, lexer, NULL);
	*lexer = save_lex;
	if (fseek(input, fpos, SEEK_SET)) {
		perror("fseek failure in handle_macro");
		exit(0);
	}
	
	if (t.tok.type == LPAREN) { 
		char* search, *found;
		search = expansion.a;

		int len;
		for (int i=0; i < preproc->macros.size; ++i) {
			if (i == macro)
				continue;

			len = strlen(preproc->macros.a[i]);
			search = expansion.a;
			while (1) {
				found = strstr(search, preproc->macros.a[i]);
				if (!found)
					break;
				if (found[len]) {
					search = found + len;
					continue;
				}

				if (found != expansion.a) {
					if (isalpha(found[-1]) || found[-1] == '_') {
						search = found + len;
						continue;
					}
				}
				//don't need to check the end because we already did
				
				p = GET_PARAM(&preproc->params, i);
				if (p->num_params != -1) {
					*found = 0; //cut off matched macro
					fprintf(output, "%s", expansion.a);
					handle_macro(preproc, i);

					goto exit;
				}

				search = found + len;
			}
		}
	} else if (t.tok.type == ID || t.tok.type == STR_LITERAL) {
		free(t.tok.v.id);
	}

	fprintf(output, "%s", expansion.a);

exit:

	free_cstr(&expansion);
	cvec_free_i(&valid_macros);
}
예제 #5
0
void preprocess_file(preprocessor_state* preproc)
{
	lexer_state save_lexer, *lexer = &preproc->lexer;
	long fpos;
	int c;

	token_lex tlex[10];

	FILE* input = preproc->input;
	FILE* output = preproc->output;

	// if not -P
	fprintf(output, "# 0 \"%s\"\n", lexer->cur_file);

	tlex[0] = read_token(input, lexer, output);
	for ( ; tlex[0].tok.type != END; tlex[0] = read_token(input, lexer, output)) {

		if (tlex[0].tok.type == ID) {
			int is_macro = look_up_macro_loc(preproc, tlex[0].tok.v.id);
			if (is_macro >= 0) {
				macro_params* p = GET_PARAM(&preproc->params, is_macro);
				//for a function style macro if the name isn't followed by a ( it's not an error
				//it's just not an invocation so just print it out
				if (p->num_params >= 0) {
					save_lexer = *lexer;
					if ((fpos = ftell(input)) == -1) {
						perror("ftell failure in preprocess_file");
						exit(0);
					}
					tlex[1] = read_token(input, lexer, NULL);
					if (tlex[1].tok.type != LPAREN) {
						*lexer = save_lexer;
						if (fseek(input, fpos, SEEK_SET)) {
							perror("fseek failure in preprocess_file");
							exit(0);
						}

						if (tlex[1].tok.type == ID || tlex[1].tok.type == STR_LITERAL)
							free(tlex[1].tok.v.id);

						print_token(&tlex[0].tok, output, 0);
						free(tlex[0].tok.v.id);
						continue;
					}
					//restore ( for symmetry in handle_macro
					*lexer = save_lexer;
					if (fseek(input, fpos, SEEK_SET)) {
						perror("fseek failure in preprocess_file");
						exit(0);
					}
				}

				handle_macro(preproc, is_macro);
			} else {
				print_token(&tlex[0].tok, output, 0);
			}
			free(tlex[0].tok.v.id);

		} else if (tlex[0].tok.type == POUND) {
			//has to be the first token
			if (lexer->cur_tok != 1) {
				preprocessor_error(NULL, lexer, "Error: stray # in program\n");
			}

			save_lexer = *lexer;
			if ((fpos = ftell(input)) == -1) {
				perror("ftell failure in preprocess_file");
				exit(0);
			}
			tlex[1] = read_token(input, lexer, NULL);
			if (tlex[0].line != tlex[1].line) { //null directive (EOF is always on it's own line)
				if (tlex[1].tok.type == POUND) {
					tlex[0] = tlex[1];
					continue;
				} else if (tlex[1].tok.type == ID || tlex[1].tok.type == STR_LITERAL) {
					free(tlex[1].tok.v.id);
				}
				*lexer = save_lexer;
				if (fseek(input, fpos, SEEK_SET)) {
					perror("fseek failure in preprocess_file");
					exit(0);
				}
				continue;
			}

			
			if (tlex[1].tok.type != ID) {
				preprocessor_error(&tlex[1], lexer, "expected ID as macro name,");
			}
			
			if (!strcmp(tlex[1].tok.v.id, "define")) {
				free(tlex[1].tok.v.id);

				handle_define(preproc);
				goto eat_newline;
			}

			if (!strcmp(tlex[1].tok.v.id, "undef")) {
				free(tlex[1].tok.v.id);
				save_lexer = *lexer;
				fpos = ftell(input);
				tlex[1] = read_token(input, lexer, NULL);
				if (tlex[1].line != tlex[0].line) {
					preprocessor_error(NULL, lexer, "macro name missing in undef directive\n");
				}

				if (tlex[1].tok.type != ID) {
					preprocessor_error(&tlex[1], lexer, "ID expected in undef directive,");
				}
			
				int exists = look_up_macro_loc(preproc, tlex[0].tok.v.id);
				if (exists >= 0) {
					cvec_erase_str(&preproc->macros, exists, exists);
					cvec_erase_str(&preproc->values, exists, exists);
					cvec_erase_void(&preproc->params, exists, exists);
				}
				free(tlex[1].tok.v.id);

				goto eat_newline;
			}

			if (!strcmp(tlex[1].tok.v.id, "include")) {
				free(tlex[1].tok.v.id);
				handle_include(preproc);
				goto eat_newline;
			}
			if (!strcmp(tlex[1].tok.v.id, "if")) {
				free(tlex[1].tok.v.id);
			}

			if (!strcmp(tlex[1].tok.v.id, "ifdef")) {
				free(tlex[1].tok.v.id);
				handle_ifdef(preproc);
				goto eat_newline;
			}

			if (!strcmp(tlex[1].tok.v.id, "ifndef")) {
				free(tlex[1].tok.v.id);
			}

			if (!strcmp(tlex[1].tok.v.id, "else")) {
			}
			if (!strcmp(tlex[1].tok.v.id, "endif")) {
			}
			if (!strcmp(tlex[1].tok.v.id, "elif")) {
			}

			if (!strcmp(tlex[1].tok.v.id, "defined")) {
			}
			if (!strcmp(tlex[1].tok.v.id, "pragma")) {
			}

			if (!strcmp(tlex[1].tok.v.id, "error")) {
				// check for string
				// preprocessor_error(NULL,
			}

eat_newline:
			//the newline should reset the position
			//but since the line of a directive should be
			//invisible to the final program it shouldn't affect line count
			do {
				c = getc(preproc->input);
				if (!isspace(c))
					preprocessor_error(NULL, lexer, "extra tokens in directive\n");
			} while (c != '\n');
			lexer->cur_pos = 1;
			lexer->cur_tok = 0;
		}
	}
}