/* CPP */ static TAG_CALLBACK(cpp_default) { out_printf (out, "DEFAULT: (%s)\n", buf); return 0; } static TAG_CALLBACK(cpp_error) { out_printf (out, "\n"); if (state->echo[state->ifl] && buf) { out_printf (out, "ERROR: %s (line=%d)\n", buf, state->lineno); return -1; } return 0; } static TAG_CALLBACK(cpp_warning) { out_printf (out,"\n"); if (state->echo[state->ifl] && buf != NULL) { out_printf (out, "WARNING: line %d: %s\n", state->lineno, buf); } return 0; } static TAG_CALLBACK(cpp_if) { char *var = getenv (buf + ((*buf == '!') ? 1 : 0)); if (var && *var == '1') { state->echo[state->ifl + 1] = 1; } else { state->echo[state->ifl + 1] = 0; } if (*buf == '!') { state->echo[state->ifl + 1] = !!!state->echo[state->ifl + 1]; } return 1; } static TAG_CALLBACK(cpp_ifdef) { char *var = getenv (buf); state->echo[state->ifl + 1] = var? 1: 0; return 1; } static TAG_CALLBACK(cpp_else) { state->echo[state->ifl] = state->echo[state->ifl]? 0: 1; return 0; } static TAG_CALLBACK(cpp_ifndef) { cpp_ifdef (state, out, buf); cpp_else (state, out, buf); return 1; } static struct cpp_macro_t { char *name; char *args; char *body; } cpp_macros[10]; static int cpp_macros_n = 0; static void cpp_macro_add(char *name, char *args, char *body) { char *ptr; cpp_macros[cpp_macros_n].args = strdup(args); cpp_macros[cpp_macros_n].body = strdup(body); ptr = strchr (name, '('); if (ptr) { ptr[1] = '\0'; } cpp_macros[cpp_macros_n].name = strdup(name); cpp_macros_n++; } static PUT_CALLBACK(cpp_fputs) { int i; for (i = 0; i < cpp_macros_n; i++) { if (strstr(buf, cpp_macros[i].name)) { fprintf (stderr, "MACRO (%s) HIT\n", cpp_macros[i].name); } } out_printf (out, "%s", buf); return 0; } static TAG_CALLBACK(cpp_define) { char *eq = strchr (buf, ' '); if (eq) { char *ptr = eq + 1; char *macro = strchr(buf, '('); *eq = '\0'; if (macro) { /*macro[0]='\0'; */ ptr = strchr (macro + 1, ')'); if (!ptr) { fprintf(stderr, "Invalid syntax\n"); return 1; } ptr = ptr + 1; fprintf(stderr, "REGISTER MACRO:\n"); fprintf(stderr, " name: %s\n", buf); fprintf(stderr, " args: %s\n", macro); fprintf(stderr, " body: %s\n", ptr+1); cpp_macro_add(buf,macro,ptr+1); /* TODO: Name is "BUF(". for funny strstr */ } rz_sys_setenv (buf, ptr); } else rz_sys_setenv (buf, ""); return 0; } static TAG_CALLBACK(cpp_endif) { return -1; } static TAG_CALLBACK(cpp_include) { if (state->echo[state->ifl]) { spp_file (buf, out); } return 0; } DLL_LOCAL struct Tag cpp_tags[] = { { "ifdef", cpp_ifdef }, { "ifndef", cpp_ifndef }, { "endif", cpp_endif }, { "if", cpp_if }, { "else", cpp_else }, { "include", cpp_include }, { "define", cpp_define }, { "error", cpp_error }, { "warning", cpp_warning }, { NULL, cpp_default }, { NULL } }; /* arguments */ static ARG_CALLBACK(cpp_arg_i) { printf("INCLUDEDIR(%s)\n", arg); return 0; } static ARG_CALLBACK(cpp_arg_d) { // TODO: handle rz_sys_setenv==-1 char *eq = strchr (arg, '='); if (eq) { *eq = '\0'; rz_sys_setenv (arg, eq + 1); } else { rz_sys_setenv (arg, ""); } return 0; } static struct Arg cpp_args[] = { { "-I", "add include directory", 1, cpp_arg_i }, { "-D", "define value of variable", 1, cpp_arg_d }, { NULL } }; DLL_LOCAL struct Proc cpp_proc = { .name = "cpp", .tags = (struct Tag **)cpp_tags, .args = (struct Arg **)cpp_args, .token = " ", .eof = NULL, .tag_pre = "#", .tag_post = "\n", .multiline = "\\\n", .default_echo = 1, .fputs = cpp_fputs, .chop = 0, .tag_begin = 1, };