#ifndef PREPROC_H_
#define PREPROC_H_
+#include <stdbool.h>
#include <stdio.h>
/*
struct ulas_ppdef {
enum ulas_ppdefs type;
+ bool undef;
+};
+
+struct ulas_preproc {
+ struct ulas_ppdef *defs;
+ size_t defslen;
+
+ const char *srcname;
+ const char *dstname;
};
/**
* Tokenize and apply the preprocessor
*/
-int ulas_preproc(FILE *dst, FILE *src);
+int ulas_preproc(FILE *dst, const char *dstname, FILE *src, const char *srcname);
#endif
#define ULAS_PATHMAX 4096
#define ULAS_LINEMAX 4096
+#define ULAS_TOKMAX 512
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
// returns 0 when no more tokens can be read
int ulas_tok(char *dst, const char *line, size_t n, ulas_tokrule rule);
+// tokenizes an entire line
+char **ulas_tokline(const char *line, size_t *n, ulas_tokrule rule);
+
+void ulas_toklinefree(char **data, size_t n);
+
#endif
#include "preproc.h"
#include "ulas.h"
+#include <stdio.h>
+#include <assert.h>
-int ulas_preproc(FILE *dst, FILE *src) {
+
+int ulas_preprocline(struct ulas_preproc *pp, FILE *dst, const char *line,
+ size_t n) {
+
+ // check if the first token is any of the valid preproc directives
+
+ assert(fwrite(line, 1, n, dst) == n);
+
+ return 0;
+}
+
+int ulas_preproc(FILE *dst, const char *dstname, FILE *src,
+ const char *srcname) {
char buf[ULAS_LINEMAX];
memset(buf, 0, ULAS_LINEMAX);
+ int rc = 0;
if (!dst || !src) {
- ULASERR("[preproc] Unable to read from dst or write to src!\n");
+ ULASERR("[%s] Unable to read from dst or write to src!\n", srcname);
return -1;
}
- while (fgets(buf, ULAS_LINEMAX, src) == NULL) {
+ struct ulas_preproc pp = {NULL, 0, srcname, dstname};
+
+ while (fgets(buf, ULAS_LINEMAX, src) != NULL) {
+ if (ulas_preprocline(&pp, dst, buf, strlen(buf)) == -1) {
+ rc = -1;
+ goto fail;
+ }
}
- return 0;
+fail:
+ return rc;
}
#define assert_tok(expected_tok, expected_ret, line, rule) \
{ \
- char buf[256]; \
- memset(buf, 0, 256); \
- assert(ulas_tok(buf, (line), 256, (rule)) == (expected_ret)); \
+ char buf[ULAS_TOKMAX]; \
+ memset(buf, 0, ULAS_TOKMAX); \
+ assert(ulas_tok(buf, (line), ULAS_TOKMAX, (rule)) == (expected_ret)); \
assert(strcmp(buf, expected_tok) == 0); \
}
+#define assert_tokline(expected_toks, expected_n, line, rule) \
+ {}
+
void test_tok(void) {
TESTBEGIN("tok");
assert_tok("", 0, "", ulas_tokrulespace);
assert_tok("", -1, NULL, ulas_tokrulespace);
+ assert_tokline(({"test", "tokens", "with", "line"}), 4,
+ " test tokens with line", ulas_tokrulespace);
+
TESTEND("tok");
}
{ \
char dstbuf[ULAS_LINEMAX]; \
memset(dstbuf, 0, ULAS_LINEMAX); \
- FILE *src = fmemopen((input), strlen((input)), "r"); \
- FILE *dst = fmemopen(dstbuf, ULAS_LINEMAX, "w"); \
- assert(ulas_preproc(dst, src) == (expect_ret)); \
- assert(strcmp(dstbuf, (expect_dst)) == 0); \
+ FILE *src = fmemopen((input), strlen((input)), "re"); \
+ FILE *dst = fmemopen(dstbuf, ULAS_LINEMAX, "we"); \
+ assert(ulas_preproc(dst, "testdst", src, "testsrc") == (expect_ret)); \
fclose(src); \
fclose(dst); \
+ assert(strcmp(dstbuf, (expect_dst)) == 0); \
}
void test_preproc(void) {
TESTBEGIN("preproc");
- assert_preproc("", 0, "test");
+ assert_preproc("test", 0, "test");
TESTEND("preproc");
}
dst[write + 1] = '\0';
return i;
}
+
+char **ulas_tokline(const char *line, size_t *n, ulas_tokrule rule) {
+ char buf[ULAS_TOKMAX];
+
+ char **dst = NULL;
+ *n = 0;
+
+ int tokrc = 0;
+ int read = 0;
+ while ((tokrc = ulas_tok(buf, line + read, ULAS_TOKMAX, rule)) > 0) {
+ if (tokrc == -1) {
+ goto fail;
+ }
+ read += tokrc;
+
+ *n = *n + 1;
+ char **newdst = realloc(dst, sizeof(char *) * (*n));
+ if (!newdst) {
+ goto fail;
+ }
+ dst = newdst;
+
+ dst[*n - 1] = strndup(buf, ULAS_TOKMAX);
+ }
+
+ return dst;
+fail:
+ ulas_toklinefree(dst, *n);
+ return NULL;
+}
+
+void ulas_toklinefree(char **data, size_t n) {
+ if (!data) {
+ return;
+ }
+ for (size_t i = 0; i < n; i++) {
+ free(data[n]);
+ }
+
+ free(data);
+}