#define ULAS_CFG_FMT_BLUE "\x1B[34m"
#define ULAS_CFG_FMT_RESET "\x1B[0m"
+#define ULAS_PPSTR_DEF "#define"
+#define ULAS_PPSTR_MACRO "#macro"
+#define ULAS_PPSTR_IFDEF "#ifdef"
+#define ULAS_PPSTR_ENDIF "#endif"
+#define ULAS_PPSTR_IFNDEF "#ifndef"
+#define ULAS_PPSTR_ENDMACRO "#endmacro"
+
// configurable tokens
#define ULAS_TOK_COMMENT ';'
// start of as directives such as .org
/**
* Tokenize and apply the preprocessor
+ * returns 0: no error
+ * -1: error
*/
int ulas_preproc(FILE *dst, FILE *src);
+// reads the next line
+// returns 0 if no more data can be read
+// 1 if data was read
+// -1 on error
+int ulas_preprocnext(struct ulas_preproc *pp, FILE *dst, FILE *src, char *buf,
+ int n);
+
+// process a line of preproc
+// returns: 0 when a regular line was read
+// enum ulas_ppdirs id for preprocessor directive
+// -1 on error
+int ulas_preprocline(struct ulas_preproc *pp, FILE *dst, FILE *src,
+ const char *raw_line, size_t n);
+
// expand preproc into dst line
char *ulas_preprocexpand(struct ulas_preproc *pp, const char *raw_line,
size_t *n);
return 0;
}
-int ulas_preprocline(struct ulas_preproc *pp, FILE *dst, const char *raw_line,
- size_t n) {
+int ulas_preprocline(struct ulas_preproc *pp, FILE *dst, FILE *src,
+ const char *raw_line, size_t n) {
char *line = ulas_preprocexpand(pp, raw_line, &n);
const char *pline = line;
- const char *dirstrs[] = {"#define", "#macro", "#ifdef", "#ifndef",
- "#endif", "#endmacro", NULL};
+ const char *dirstrs[] = {ULAS_PPSTR_DEF,
+ ULAS_PPSTR_MACRO,
+ ULAS_PPSTR_IFDEF,
+ ULAS_PPSTR_IFNDEF,
+ ULAS_PPSTR_ENDIF,
+ ULAS_PPSTR_ENDMACRO,
+ NULL};
enum ulas_ppdirs dirs[] = {ULAS_PPDIR_DEF, ULAS_PPDIR_MACRO,
ULAS_PPDIR_IFDEF, ULAS_PPDIR_IFNDEF,
ULAS_PPDIR_ENDIF, ULAS_PPDIR_ENDMACRO};
ulas_preprocdef(pp, def);
// define short-circuits the rest of the logic
// because it just takes the entire rest of the line as a value!
- return 0;
+ goto dirdone;
}
case ULAS_PPDIR_MACRO:
case ULAS_PPDIR_ENDMACRO:
pp->tok.buf);
return -1;
}
-
+ dirdone:
+ return found_dir;
} else {
fwrite(line, 1, n, dst);
}
return 0;
}
+int ulas_preprocnext(struct ulas_preproc *pp, FILE *dst, FILE *src, char *buf,
+ int n) {
+ int rc = 1;
+ if (fgets(buf, n, src) != NULL) {
+ ulas.line++;
+ if (ulas_preprocline(pp, dst, src, buf, strlen(buf)) == -1) {
+ rc = -1;
+ }
+ } else {
+ rc = 0;
+ }
+
+ return rc;
+}
+
int ulas_preproc(FILE *dst, FILE *src) {
char buf[ULAS_LINEMAX];
memset(buf, 0, ULAS_LINEMAX);
struct ulas_preproc pp = {NULL, 0, ulas_str(1), ulas_str(1)};
- while (fgets(buf, ULAS_LINEMAX, src) != NULL) {
- ulas.line++;
- if (ulas_preprocline(&pp, dst, buf, strlen(buf)) == -1) {
- rc = -1;
- goto fail;
- }
+ while ((rc = ulas_preprocnext(&pp, dst, src, buf, ULAS_LINEMAX)) > 0) {
}
-fail:
ulas_strfree(&pp.line);
ulas_strfree(&pp.tok);