#define ULAS_VER "0.0.1"
// args without value
-#define ULAS_OPTS "hvV"
+#define ULAS_OPTS "hvVp"
// args with value
#define ULAS_OPTS_ARG "o:"
ULAS_HELP("h", "display this help and exit");
ULAS_HELP("V", "display version info and exit");
ULAS_HELP("v", "verbose output");
+ ULAS_HELP("p", "Stop after preprocessor");
ULAS_HELP("o=path", "Output file");
}
case 'o':
cfg->output_path = strndup(optarg, ULAS_PATHMAX);
break;
+ case 'p':
+ cfg->preproc_only = 1;
+ break;
case '?':
break;
default:
}
int ulas_main(struct ulas_config cfg) {
+ int rc = 0;
if (cfg.output_path) {
ulasout = fopen(cfg.output_path, "we");
if (!ulasout) {
}
}
+ if (cfg.argc > 0) {
+ ulasin = fopen(cfg.argv[0], "re");
+ if (!ulasin) {
+ fprintf(ulaserr, "%s: %s\n", cfg.argv[0], strerror(errno));
+ return -1;
+ }
+ }
+
ulas_init(cfg);
+ FILE *preprocdst = NULL;
+
+ if (cfg.preproc_only) {
+ preprocdst = ulasout;
+ } else {
+ preprocdst = tmpfile();
+ }
+
+ if (ulas_preproc(preprocdst, ulasin) == -1) {
+ rc = -1;
+ goto cleanup;
+ }
+
+ if (cfg.preproc_only) {
+ goto cleanup;
+ }
+
+ // TODO: rest of steps here
+
+cleanup:
+ if (!cfg.preproc_only) {
+ fclose(preprocdst);
+ }
+
if (cfg.output_path) {
fclose(ulasout);
free(cfg.output_path);
- return -1;
}
- return 0;
+ if (cfg.argc > 0) {
+ fclose(ulasin);
+ }
+
+ return rc;
}
int ulas_isname(const char *tok, size_t n) {
int ulas_preprocline(struct ulas_preproc *pp, FILE *dst, FILE *src,
const char *raw_line, size_t n) {
/**
+ * Footgun warning:
* We do use raw pointers to the line here... which is fine
* as long as it is never used after a recursive call to the preprocessor!
* never use this pointer after such a recursive call!