From 2758f0af3e5008b18c777be76a75fb2d2598ac82 Mon Sep 17 00:00:00 2001 From: Lukas Krickl Date: Sun, 22 Mar 2026 15:41:58 +0100 Subject: [PATCH] porting codebase to c89 --- makefile | 2 +- src/archs.c | 67 ++-- src/archs.h | 29 +- src/main.c | 9 +- src/test.c | 143 ++++---- src/ulas.c | 984 ++++++++++++++++++++++++++++++++-------------------- src/ulas.h | 351 ++++++++++--------- src/uldas.c | 76 ++-- src/uldas.h | 2 +- 9 files changed, 973 insertions(+), 690 deletions(-) diff --git a/makefile b/makefile index 9a4b779..9c2c872 100644 --- a/makefile +++ b/makefile @@ -2,7 +2,7 @@ NAME=ulas TEST_NAME=test$(NAME) DBGCFLAGS=-g -fsanitize=address DBGLDFLAGS=-fsanitize=address -CFLAGS=-Wall -pedantic $(DBGCFLAGS) -std=gnu99 +CFLAGS=-Wall -pedantic $(DBGCFLAGS) -std=gnu89 LIBS= LDFLAGS=$(DBGLDFLAGS) $(LIBS) diff --git a/src/archs.c b/src/archs.c index d2e8f94..300d207 100644 --- a/src/archs.c +++ b/src/archs.c @@ -6,7 +6,7 @@ * for SM83 */ -// define r8, r8 +/* define r8, r8 */ #define ULAS_INSTRSM83_R8R8(name, base_op, reg_left, reg_right) \ { \ (name), {(reg_left), ',', (reg_right), 0}, { base_op, 0 } \ @@ -27,7 +27,7 @@ {(base_op) + 6, 0}}, \ ULAS_INSTRSM83_R8R8(name, (base_op) + 7, reg_left, ULAS_REGSM83_A) -// a, r8 +/* a, r8 */ #define ULAS_INSTRSM83_ALUR8D(name, base_op) \ ULAS_INSTRSM83_R8R8D(name, base_op, ULAS_REGSM83_A) @@ -36,13 +36,13 @@ (name), {(reg_left), ',', ULAS_E8, 0}, { (op), ULAS_E8, 0 } \ } -// r16, e16 +/* r16, e16 */ #define ULAS_INSTRSM83_R16E16(name, op, reg_left) \ { \ (name), {(reg_left), ',', ULAS_E16, 0}, { (op), ULAS_E16, 0 } \ } -// r16, a16 +/* r16, a16 */ #define ULAS_INSTRSM83_R16A16(name, op, reg_left) \ { \ (name), {(reg_left), ',', ULAS_A16, 0}, { (op), ULAS_A16, 0 } \ @@ -50,13 +50,13 @@ -// reg +/* reg */ #define ULAS_INSTRSM83_REG(name, op, reg) \ { \ (name), {(reg), 0}, { (op), 0x00 } \ } -// prefixed reg +/* prefixed reg */ #define ULAS_INSTRSM83_PRER8(name, base_op, reg_right) \ { \ (name), {(reg_right), 0}, { 0xCB, base_op, 0 } \ @@ -72,7 +72,7 @@ {(name), {'[', ULAS_REGSM83_HL, ']', 0}, {0xCB, (base_op) + 6, 0}}, \ ULAS_INSTRSM83_PRER8(name, (base_op) + 7, ULAS_REGSM83_A) -// prefixed , reg +/* prefixed , reg */ #define ULAS_INSTRSM83_PREBITR8(name, base_op, bit, reg_right) \ { \ (name), {(bit), ',', (reg_right), 0}, { 0xCB, base_op, 0 } \ @@ -90,31 +90,32 @@ {0xCB, (base_op) + 6, 0}}, \ ULAS_INSTRSM83_PREBITR8(name, (base_op) + 7, bit, ULAS_REGSM83_A) -// all instructions -// when name is NULL list ended -// FIXME: Add ULAS_A16 and make all absolute calls/jumps A16 instead of E16 +/* all instructions + * when name is NULL list ended + * FIXME: Add ULAS_A16 and make all absolute calls/jumps A16 instead of E16 + */ const struct ulas_instr ULASINSTRS_SM83[] = { - // control instructions + /* control instructions */ {"nop", {0}, {(short)ULAS_DATZERO, 0}}, {"halt", {0}, {0x76, 0}}, {"stop", {0}, {0x10, (short)ULAS_DATZERO, 0x00}}, {"di", {0}, {0xF3, 0x00}}, {"ei", {0}, {0xFB, 0x00}}, - // misc + /* misc */ {"daa", {0}, {0x27, 0x00}}, {"scf", {0}, {0x37, 0x00}}, {"cpl", {0}, {0x2F, 0x00}}, {"ccf", {0}, {0x3F, 0x00}}, - // shift / bits + /* shift / bits */ {"rlca", {0}, {0x07, 0x00}}, {"rls", {0}, {0x17, 0x00}}, {"rrca", {0}, {0x0F, 0x00}}, {"rra", {0}, {0x1F, 0x00}}, - // ld r8, r8 + /* ld r8, r8 */ ULAS_INSTRSM83_R8R8D("ld", 0x40, ULAS_REGSM83_B), ULAS_INSTRSM83_R8R8D("ld", 0x48, ULAS_REGSM83_C), ULAS_INSTRSM83_R8R8D("ld", 0x50, ULAS_REGSM83_D), @@ -123,7 +124,7 @@ const struct ulas_instr ULASINSTRS_SM83[] = { ULAS_INSTRSM83_R8R8D("ld", 0x68, ULAS_REGSM83_L), ULAS_INSTRSM83_R8R8D("ld", 0x78, ULAS_REGSM83_A), - // ld [r16], a + /* ld [r16], a */ {"ld", {'[', ULAS_REGSM83_BC, ']', ',', ULAS_REGSM83_A, 0}, {0x02, 0}}, {"ld", {'[', ULAS_REGSM83_DE, ']', ',', ULAS_REGSM83_A, 0}, {0x12, 0}}, {"ld", {'[', ULAS_REGSM83_HL, ']', ',', ULAS_REGSM83_A, 0}, {0x77, 0}}, @@ -131,7 +132,7 @@ const struct ulas_instr ULASINSTRS_SM83[] = { {"ld", {'[', ULAS_REGSM83_HL, '-', ']', ',', ULAS_REGSM83_A, 0}, {0x32, 0}}, {"ld", {'[', ULAS_REGSM83_HL, ']', ',', ULAS_E8, 0}, {0x36, ULAS_E8, 0x00}}, - // ld a, [r16] + /* ld a, [r16] */ {"ld", {ULAS_REGSM83_A, ',', '[', ULAS_REGSM83_BC, ']', 0}, {0x0A, 0}}, {"ld", {ULAS_REGSM83_A, ',', '[', ULAS_REGSM83_DE, ']', 0}, {0x1A, 0}}, {"ld", {ULAS_REGSM83_A, ',', '[', ULAS_REGSM83_HL, '+', ']', 0}, {0x2A, 0}}, @@ -152,7 +153,7 @@ const struct ulas_instr ULASINSTRS_SM83[] = { {"ldh", {'[', ULAS_A8, ']', ',', ULAS_REGSM83_A, 0}, {0xE0, ULAS_A8, 0}}, {"ldh", {ULAS_REGSM83_A, ',', '[', ULAS_A8, ']', 0}, {0xF0, ULAS_A8, 0}}, - // ld r8, e8 + /* ld r8, e8 */ ULAS_INSTRSM83_R8_EXPR8("ld", 0x06, ULAS_REGSM83_B), ULAS_INSTRSM83_R8_EXPR8("ld", 0x16, ULAS_REGSM83_D), ULAS_INSTRSM83_R8_EXPR8("ld", 0x26, ULAS_REGSM83_H), @@ -162,20 +163,20 @@ const struct ulas_instr ULASINSTRS_SM83[] = { ULAS_INSTRSM83_R8_EXPR8("ld", 0x2E, ULAS_REGSM83_L), ULAS_INSTRSM83_R8_EXPR8("ld", 0x3E, ULAS_REGSM83_A), - // ld r16, e16 + /* ld r16, e16 */ ULAS_INSTRSM83_R16E16("ld", 0x01, ULAS_REGSM83_BC), ULAS_INSTRSM83_R16E16("ld", 0x11, ULAS_REGSM83_DE), ULAS_INSTRSM83_R16E16("ld", 0x21, ULAS_REGSM83_HL), ULAS_INSTRSM83_R16E16("ld", 0x31, ULAS_REGSM83_SP), - // jr + /* jr */ ULAS_INSTRSM83_R8_EXPR8("jr", 0x20, ULAS_REGSM83_NOT_ZERO), ULAS_INSTRSM83_R8_EXPR8("jr", 0x30, ULAS_REGSM83_NOT_CARRY), ULAS_INSTRSM83_R8_EXPR8("jr", 0x28, ULAS_REGSM83_ZERO), ULAS_INSTRSM83_R8_EXPR8("jr", 0x38, ULAS_REGSM83_CARRY), {"jr", {ULAS_E8, 0}, {0x18, ULAS_E8, 0x00}}, - // ret + /* ret */ ULAS_INSTRSM83_REG("ret", 0xC0, ULAS_REGSM83_NOT_ZERO), ULAS_INSTRSM83_REG("ret", 0xD0, ULAS_REGSM83_NOT_CARRY), ULAS_INSTRSM83_REG("ret", 0xC8, ULAS_REGSM83_ZERO), @@ -183,7 +184,7 @@ const struct ulas_instr ULASINSTRS_SM83[] = { {"ret", {0}, {0xC9, 0x00}}, {"reti", {0}, {0xD9, 0x00}}, - // jp + /* jp */ ULAS_INSTRSM83_R16A16("jp", 0xC2, ULAS_REGSM83_NOT_ZERO), ULAS_INSTRSM83_R16A16("jp", 0xD2, ULAS_REGSM83_NOT_CARRY), ULAS_INSTRSM83_R16A16("jp", 0xCA, ULAS_REGSM83_ZERO), @@ -191,14 +192,14 @@ const struct ulas_instr ULASINSTRS_SM83[] = { {"jp", {ULAS_REGSM83_HL, 0}, {0xE9, 0x00}}, {"jp", {ULAS_A16, 0}, {0xC3, ULAS_A16, 0x00}}, - // call + /* call */ ULAS_INSTRSM83_R16A16("call", 0xC4, ULAS_REGSM83_NOT_ZERO), ULAS_INSTRSM83_R16A16("call", 0xD4, ULAS_REGSM83_NOT_CARRY), ULAS_INSTRSM83_R16A16("call", 0xCC, ULAS_REGSM83_ZERO), ULAS_INSTRSM83_R16A16("call", 0xDC, ULAS_REGSM83_CARRY), {"call", {ULAS_A16, 0}, {0xCD, ULAS_A16, 0x00}}, - // rst + /* rst */ ULAS_INSTRSM83_REG("rst", 0xC7, ULAS_VECSM83_00), ULAS_INSTRSM83_REG("rst", 0xD7, ULAS_VECSM83_10), ULAS_INSTRSM83_REG("rst", 0xE7, ULAS_VECSM83_20), @@ -208,7 +209,7 @@ const struct ulas_instr ULASINSTRS_SM83[] = { ULAS_INSTRSM83_REG("rst", 0xEF, ULAS_VECSM83_28), ULAS_INSTRSM83_REG("rst", 0xFF, ULAS_VECSM83_38), - // inc/dec + /* inc/dec */ ULAS_INSTRSM83_REG("inc", 0x03, ULAS_REGSM83_BC), ULAS_INSTRSM83_REG("inc", 0x13, ULAS_REGSM83_DE), ULAS_INSTRSM83_REG("inc", 0x23, ULAS_REGSM83_HL), @@ -239,7 +240,7 @@ const struct ulas_instr ULASINSTRS_SM83[] = { ULAS_INSTRSM83_REG("dec", 0x2D, ULAS_REGSM83_L), ULAS_INSTRSM83_REG("dec", 0x3D, ULAS_REGSM83_A), - // alu r8, r8 + /* alu r8, r8 */ ULAS_INSTRSM83_ALUR8D("add", 0x80), ULAS_INSTRSM83_ALUR8D("adc", 0x88), ULAS_INSTRSM83_ALUR8D("sub", 0x90), @@ -261,25 +262,25 @@ const struct ulas_instr ULASINSTRS_SM83[] = { ULAS_INSTRSM83_R8_EXPR8("add", 0xE8, ULAS_REGSM83_SP), - // alu r16, r16 + /* alu r16, r16 */ ULAS_INSTRSM83_R16R16("add", 0x09, ULAS_REGSM83_HL, ULAS_REGSM83_BC), ULAS_INSTRSM83_R16R16("add", 0x19, ULAS_REGSM83_HL, ULAS_REGSM83_DE), ULAS_INSTRSM83_R16R16("add", 0x29, ULAS_REGSM83_HL, ULAS_REGSM83_HL), ULAS_INSTRSM83_R16R16("add", 0x39, ULAS_REGSM83_HL, ULAS_REGSM83_SP), - // pop + /* pop */ ULAS_INSTRSM83_REG("pop", 0xC1, ULAS_REGSM83_BC), ULAS_INSTRSM83_REG("pop", 0xD1, ULAS_REGSM83_DE), ULAS_INSTRSM83_REG("pop", 0xE1, ULAS_REGSM83_HL), ULAS_INSTRSM83_REG("pop", 0xF1, ULAS_REGSM83_AF), - // push + /* push */ ULAS_INSTRSM83_REG("push", 0xC5, ULAS_REGSM83_BC), ULAS_INSTRSM83_REG("push", 0xD5, ULAS_REGSM83_DE), ULAS_INSTRSM83_REG("push", 0xE5, ULAS_REGSM83_HL), ULAS_INSTRSM83_REG("push", 0xF5, ULAS_REGSM83_AF), - // prefixed + /* prefixed */ ULAS_INSTRSM83_PRER8D("swap", 0x30), ULAS_INSTRSM83_PRER8D("rlc", 0x00), ULAS_INSTRSM83_PRER8D("rrc", 0x08), @@ -326,8 +327,12 @@ const char *ULAS_SM83_REGS[] = { void ulas_arch_set(enum ulas_archs arch) { switch (arch) { case ULAS_ARCH_SM83: - ulas.arch = (struct ulas_arch){arch, ULAS_SM83_REGS, ULAS_SM83_REGS_LEN, - ULASINSTRS_SM83, ULAS_LE}; + ulas.arch.type = arch; + ulas.arch.regs_names = ULAS_SM83_REGS; + ulas.arch.regs_len = ULAS_SM83_REGS_LEN; + ulas.arch.instrs = ULASINSTRS_SM83; + ulas.arch.endianess = ULAS_LE; + break; default: ULASPANIC("Unknown architecture\n"); diff --git a/src/archs.h b/src/archs.h index 822c0ae..86ee37b 100644 --- a/src/archs.h +++ b/src/archs.h @@ -16,7 +16,7 @@ enum ulas_endianess { */ enum ulas_asmregs_sm83 { - // r8 + /* r8 */ ULAS_REGSM83_B = 1, ULAS_REGSM83_C = 2, ULAS_REGSM83_D = 3, @@ -25,19 +25,19 @@ enum ulas_asmregs_sm83 { ULAS_REGSM83_L = 6, ULAS_REGSM83_A = 7, - // r16 + /* r16 */ ULAS_REGSM83_BC = 8, ULAS_REGSM83_DE = 9, ULAS_REGSM83_HL = 10, ULAS_REGSM83_AF = 16, - // flags + /* flags */ ULAS_REGSM83_NOT_ZERO = 11, ULAS_REGSM83_ZERO = 12, ULAS_REGSM83_NOT_CARRY = 13, ULAS_REGSM83_CARRY = 14, - // misc + /* misc */ ULAS_REGSM83_SP = 15, ULAS_VECSM83_00 = 17, ULAS_VECSM83_08 = 18, @@ -51,16 +51,18 @@ enum ulas_asmregs_sm83 { ULAS_SM83_REGS_LEN }; -// special asm tokens for instr enum -// TODO: add more expressions types such as e8, e16, e24, e32, e64 -// as well as the corresponding addresses -// Use ULAS_DATZERO if an actual byte is expected to appear in the assembly -// output (since 0 denotes the end of the list) +/* special asm tokens for instr enum + * TODO: add more expressions types such as e8, e16, e24, e32, e64 + * as well as the corresponding addresses + * Use ULAS_DATZERO if an actual byte is expected to appear in the assembly + * output (since 0 denotes the end of the list) + */ enum ulas_asmspetok { ULAS_E8 = -1, ULAS_E16 = -2, - // A8 is like E8, but it will not emit an overflow warning - // because it is commont to pass a 16-bit label as a value + /* A8 is like E8, but it will not emit an overflow warning + * because it is commont to pass a 16-bit label as a value + */ ULAS_A8 = -3, ULAS_A16 = -4, ULAS_DATZERO = 0xFF00 @@ -79,8 +81,9 @@ struct ulas_arch { void ulas_arch_set(enum ulas_archs arch); -// returns how many bytes of an instruction are occupied -// by the opcode based on its data +/* returns how many bytes of an instruction are occupied + * by the opcode based on its data + */ unsigned int ulas_arch_opcode_len(const char *buf, unsigned long read); #endif diff --git a/src/main.c b/src/main.c index 95ab531..66f8b5a 100644 --- a/src/main.c +++ b/src/main.c @@ -18,11 +18,11 @@ void ulas_getopt(int argc, char **argv, struct ulas_config *cfg) { int warnings[255]; + int c = 0; memset(warnings, 0, 255 * sizeof(int)); warnings['a'] = ULAS_WARN_ALL; warnings['o'] = ULAS_WARN_OVERFLOW; - int c = 0; while ((c = getopt(argc, argv, ULAS_OPTS ULAS_OPTS_ARG)) != -1) { switch (c) { case 'h': @@ -95,7 +95,8 @@ void ulas_getopt(int argc, char **argv, struct ulas_config *cfg) { } int main(int argc, char **argv) { - // map args to cfg here + int i, res; + /* map args to cfg here */ struct ulas_config cfg = ulas_cfg_from_env(); ulas_getopt(argc, argv, &cfg); @@ -104,7 +105,7 @@ int main(int argc, char **argv) { cfg.defs = defs; cfg.defslen = defslen; - int res = ulas_main(cfg); + res = ulas_main(cfg); if (cfg.output_path) { free(cfg.output_path); @@ -118,7 +119,7 @@ int main(int argc, char **argv) { free(cfg.lst_path); } - for (int i = 0; i < incpathslen; i++) { + for (i = 0; i < incpathslen; i++) { free(incpaths[i]); } diff --git a/src/test.c b/src/test.c index db99e24..6097973 100644 --- a/src/test.c +++ b/src/test.c @@ -11,43 +11,42 @@ #define ULAS_TEST_OPTS_ARG "" #define ULAS_TOKMAX 64 -#define TESTBEGIN(name) printf("[test %s]\n", (name)); -#define TESTEND(name) printf("[%s ok]\n", (name)); +#define TESTBEGIN(name) { printf("[test %s]\n", (name)); } +#define TESTEND(name) { printf("[%s ok]\n", (name)); } -#define assert_tok(line, ...) \ +#define assert_tok(line, expect) \ { \ - const char *expect[] = __VA_ARGS__; \ - unsigned long n = strlen(line); \ + unsigned long expect_n, n = strlen(line); \ struct ulas_str dst = ulas_str(n); \ - memset(dst.buf, 0, n); \ int i = 0; \ const char *pline = line; \ - while (ulas_tok(&dst, &pline, n)) { \ + memset(dst.buf, 0, n); \ + while (ulas_tok(&dst, &pline, n)) { \ assert(expect[i]); \ assert(strcmp(dst.buf, expect[i]) == 0); \ i++; \ } \ - unsigned long expect_n = 0; \ + expect_n = 0; \ for (expect_n = 0; expect[expect_n]; expect_n++) { \ } \ assert(i == expect_n); \ ulas_strfree(&dst); \ } -#define assert_tokuntil(line, c, ...) \ +#define assert_tokuntil(line, c, expect) \ { \ - const char *expect[] = __VA_ARGS__; \ - unsigned long n = strlen(line); \ + const char *pline; \ + unsigned long expect_n, n = strlen(line); \ struct ulas_str dst = ulas_str(n); \ - memset(dst.buf, 0, n); \ int i = 0; \ - const char *pline = line; \ + pline = line; \ + memset(dst.buf, 0, n); \ while (ulas_tokuntil(&dst, c, &pline, n)) { \ assert(expect[i]); \ assert(strcmp(dst.buf, expect[i]) == 0); \ i++; \ } \ - unsigned long expect_n = 0; \ + expect_n = 0; \ for (expect_n = 0; expect[expect_n]; expect_n++) { \ } \ assert(i == expect_n); \ @@ -55,23 +54,25 @@ } void test_tok(void) { + const char *expect1[] = {"test", "tokens", "with", ",", "line", "/", "*", + "+", "-", ",", ";", "$1", "$", "=", + "==", "!=", ">", "<", ">=", "<=", NULL}; + const char *expect2[] = {"this is a", "test for tok ", "until", NULL}; TESTBEGIN("tok"); assert_tok(" test tokens with, line / * + - , ; $1 $ = == != > < >= <=", - {"test", "tokens", "with", ",", "line", "/", "*", - "+", "-", ",", ";", "$1", "$", "=", - "==", "!=", ">", "<", ">=", "<=", NULL}); - - assert_tokuntil(" this is a, test for tok , until", ',', - {"this is a", "test for tok ", "until", NULL}); + expect1); + + assert_tokuntil(" this is a, test for tok , until", ',', expect2); TESTEND("tok"); } void test_strbuf(void) { + struct ulas_str s; TESTBEGIN("strbuf"); - - struct ulas_str s = ulas_str(5); + + s = ulas_str(5); assert(s.maxlen == 5); assert(s.buf); @@ -86,12 +87,13 @@ void test_strbuf(void) { #define assert_preproc(expect_dst, expect_ret, input) \ { \ + FILE *src, *dst; \ + char dstbuf[ULAS_LINEMAX]; \ ulas_preprocclear(&ulas.pp); \ ulas.pass = ULAS_PASS_RESOLVE; \ - char dstbuf[ULAS_LINEMAX]; \ memset(dstbuf, 0, ULAS_LINEMAX); \ - FILE *src = fmemopen((input), strlen((input)), "re"); \ - FILE *dst = fmemopen(dstbuf, ULAS_LINEMAX, "we"); \ + src = fmemopen((input), strlen((input)), "re"); \ + dst = fmemopen(dstbuf, ULAS_LINEMAX, "we"); \ assert(ulas_preproc(dst, src) == (expect_ret)); \ fclose(src); \ fclose(dst); \ @@ -102,26 +104,26 @@ void test_preproc(void) { ulascfg.preproc_only = 1; TESTBEGIN("preproc"); - // no directive + /* no directive */ assert_preproc(" test line", 0, " test line"); - // define + /* define */ assert_preproc("123", 0, " #define test 123\ntest"); assert_preproc("this is a ", 0, " #define test\nthis is a test"); assert_preproc("", -1, " #define 1test 123\n"); assert_preproc("", -1, " #define\n"); assert_preproc("this is a 123 for defs", 0, " #define test 123\nthis is a test for defs"); - // define used inside define + /* define used inside define */ assert_preproc( "this is a 123 for defs", 0, " #define ftest 123\n#define test ftest\nthis is a test for defs"); - // undefined + /* undefined */ assert_preproc("123\ntest", 0, "#define test 123\ntest\n#undefine test\ntest"); - // macro + /* macro */ assert_preproc( " line p1 1 label01,2 3\n line p2 2\n line p3 3 p1, p2, p3\n", 0, "#macro test\n line $1 1 label$$$$,$$ $$\n line $2 2\n line $3 3 " @@ -134,7 +136,7 @@ void test_preproc(void) { "#macro test\nmnested macro $1\n$1\n#macro " "mnested\ncontent $1\n#endmacro\nafter\nmnested n1\n#endmacro\ntest t1"); - // this macro caused a heap buffer overflow in production code + /* this macro caused a heap buffer overflow in production code */ assert_preproc("ld a, verylongmacroinput & 0xFF\nld [hl+], a\nld a, " "(verylongmacroinput >> 8) & 0xFF\nld [hl+], a\n", 0, @@ -142,7 +144,7 @@ void test_preproc(void) { "($1 >> 8) & 0xFF\nld [hl+], a\n#endmacro\ntestlonginput " "verylongmacroinput"); - // ifdef + /* ifdef */ assert_preproc( "before\nifdeftest defined!\nafter", 0, "before\n#define test\n#ifdef test\nifdeftest defined!\n#endif\nafter"); @@ -151,7 +153,7 @@ void test_preproc(void) { assert_preproc("ifdeftest defined!\n", -1, "#define test\n#ifdef test\nifdeftest defined!\n"); - // ifndef + /* ifndef */ assert_preproc("before\nifndeftest defined!\nafter", 0, "before\n#ifndef test\nifndeftest defined!\n#endif\nafter"); assert_preproc( @@ -212,37 +214,37 @@ void test_preproc(void) { void test_totok(void) { TESTBEGIN("totok"); - // regular ints + /* regular ints */ ASSERT_INT_TOTOK(10, 0, "10"); ASSERT_INT_TOTOK(0x1A, 0, "0x1A"); ASSERT_INT_TOTOK(5, 0, "0b101"); - // chars + /* chars */ ASSERT_INT_TOTOK('a', 0, "'a'"); ASSERT_INT_TOTOK('\n', 0, "'\\n'"); ASSERT_INT_TOTOK('\\', 0, "'\\\\'"); - // char - not terminated + /* char - not terminated */ ASSERT_INT_TOTOK('a', -1, "'a"); - // bad escape + /* bad escape */ ASSERT_INT_TOTOK(0, -1, "'\\z'"); - // unterminated escape + /* unterminated escape */ ASSERT_INT_TOTOK('\n', -1, "'\\n"); - // string token + /* string token */ ASSERT_STR_TOTOK("test", 0, "\"test\""); ASSERT_STR_TOTOK("test\n", 0, "\"test\\n\""); - // string with escape + /* string with escape */ ASSERT_STR_TOTOK("test\n\"123\"", 0, "\"test\\n\\\"123\\\"\""); - // unterminated string + /* unterminated string */ ASSERT_STR_TOTOK("test\n\"123\"", -1, "\"test\\n\\\"123\\\""); - // symbols + /* symbols */ ASSERT_SYMBOL_TOTOK("_symbol123", 0, "_symbol123"); ASSERT_SYMBOL_TOTOK("symbol123", 0, "symbol123"); ASSERT_UNEXPECTED_TOTOK(-1, "1symbol123"); - // generic tokens with no value + /* generic tokens with no value */ ASSERT_TOTOK(ULAS_EQ, 0, "=="); ASSERT_TOTOK(ULAS_NEQ, 0, "!="); ASSERT_TOTOK('=', 0, "="); @@ -254,10 +256,10 @@ void test_totok(void) { #define ASSERT_INTEXPR(expected_val, expected_rc, expr) \ { \ - int rc = 0; \ + int val, rc = 0; \ const char *oexpr = expr; \ ulas.pass = ULAS_PASS_FINAL; \ - int val = ulas_intexpr(&oexpr, strlen((expr)), &rc); \ + val = ulas_intexpr(&oexpr, strlen((expr)), &rc); \ assert(rc == (expected_rc)); \ assert(val == (expected_val)); \ } @@ -310,9 +312,10 @@ void test_intexpr(void) { #define ASSERT_STREXPR(expected_val, expected_rc, expr) \ { \ int rc = 0; \ + const char *val; \ const char *oexpr = expr; \ ulas.pass = ULAS_PASS_FINAL; \ - const char *val = ulas_strexpr(&oexpr, strlen((expr)), &rc); \ + val = ulas_strexpr(&oexpr, strlen((expr)), &rc); \ assert(rc == (expected_rc)); \ assert(val); \ assert(strcmp((expected_val), val) == 0); \ @@ -328,26 +331,29 @@ void test_strexpr(void) { TESTEND("strexpr"); } -#define ASSERT_ASMINSTR(expect_len, line, ...) \ +#define ASSERT_ASMINSTR(expect_len, line, expect_dst) \ { \ const char *l = line; \ - int n = strlen(l); \ + int i, n = strlen(l); \ char dst[64]; \ - unsigned char expect_dst[] = {__VA_ARGS__}; \ int res = ulas_asminstr(dst, 64, &l, n); \ assert(res == expect_len); \ - for (int i = 0; i < res; i++) { \ + for (i = 0; i < res; i++) { \ assert(expect_dst[i] == (unsigned char)dst[i]); \ } \ } void test_asminstr(void) { + unsigned char expect_dst1[] = {0x00}; + unsigned char expect_dst2[] = {0x76}; + unsigned char expect_dst3[] = {0x41}; + unsigned char expect_dst4[] = {0xF0, 0x03}; TESTBEGIN("asminstr"); - ASSERT_ASMINSTR(1, "nop", 0x00); - ASSERT_ASMINSTR(1, "halt", 0x76); - ASSERT_ASMINSTR(1, "ld b, c", 0x41); - ASSERT_ASMINSTR(2, "ldh a, [1 + 2]", 0xF0, 0x03); + ASSERT_ASMINSTR(1, "nop", expect_dst1); + ASSERT_ASMINSTR(1, "halt", expect_dst2); + ASSERT_ASMINSTR(1, "ld b, c", expect_dst3); + ASSERT_ASMINSTR(2, "ldh a, [1 + 2]", expect_dst4); TESTEND("asminstr"); } @@ -361,19 +367,19 @@ void test_asminstr(void) { void test_symscope(void) { TESTBEGIN("symscope"); - // auto-scope + /* auto-scope */ ASSERT_SYMSCOPE(0, "t1:", -1, 1); ASSERT_SYMSCOPE(-1, "t1:", -1, 1); ASSERT_SYMSCOPE(0, "@t1:", -1, 1); ASSERT_SYMSCOPE(-1, "@t1:", -1, 1); - // manual scoping + /* manual scoping */ ASSERT_SYMSCOPE(0, "t2:", 5, 1); ASSERT_SYMSCOPE(-1, "t2:", 5, 1); ASSERT_SYMSCOPE(0, "t2:", 6, 1); ASSERT_SYMSCOPE(-1, "t2:", 6, 1); - // set + /* set */ ASSERT_SYMSCOPE(0, "t3:", -1, 0); ASSERT_SYMSCOPE(0, "t3:", -1, 0); @@ -384,27 +390,28 @@ void test_symscope(void) { #define ASSERT_FULL(expect_rc, in_path, expect_path) \ { \ + char dstbuf[ULAS_FULLEN]; \ + char expect[ULAS_FULLEN]; \ + FILE *expectf = fopen(expect_path, "re"); \ + int i, expect_len; \ printf("[source: %s; expect: %s]\n", in_path, expect_path); \ ulaslstout = stdout; \ ulassymout = stdout; \ cfg.verbose = 1; \ - char dstbuf[ULAS_FULLEN]; \ - char expect[ULAS_FULLEN]; \ - FILE *expectf = fopen(expect_path, "re"); \ - int expect_len = fread(expect, 1, ULAS_FULLEN, expectf); \ + expect_len = fread(expect, 1, ULAS_FULLEN, expectf); \ fclose(expectf); \ memset(dstbuf, 0, ULAS_FULLEN); \ ulasout = fmemopen(dstbuf, ULAS_FULLEN, "we"); \ ulasin = fopen(in_path, "re"); \ assert(ulas_main(cfg) == (expect_rc)); \ fclose(ulasout); \ - for (int i = 0; i < expect_len; i++) { \ - assert(expect[i] == dstbuf[i]); \ + for (i = 0; i < expect_len; i++) { \ + assert(expect[i] == dstbuf[i]); \ if (cfg.disas) { \ putchar(dstbuf[i]); /* for easier debugging in disas mode */ \ } \ } \ - for (int i = expect_len; i < ULAS_FULLEN; i++) { \ + for (i = expect_len; i < ULAS_FULLEN; i++) { \ assert(dstbuf[i] == 0); \ } \ ulasin = stdin; \ @@ -420,7 +427,7 @@ void test_symscope(void) { ASSERT_FULL(expect_rc, in_path, expect_path) \ } -// tests the entire stack +/* tests the entire stack */ void test_full_asm(void) { TESTBEGIN("testfullasm"); @@ -432,12 +439,12 @@ void test_full_asm(void) { #define ASSERT_FULL_ASM_FAIL(expect_rc, in_path) \ { \ + char dstbuf[ULAS_FULLEN]; \ struct ulas_config cfg = ulas_cfg_from_env(); \ printf("[source: %s;]\n", in_path); \ ulaslstout = stdout; \ ulassymout = stdout; \ cfg.verbose = 1; \ - char dstbuf[ULAS_FULLEN]; \ memset(dstbuf, 0, ULAS_FULLEN); \ ulasout = fmemopen(dstbuf, ULAS_FULLEN, "we"); \ ulasin = fopen(in_path, "re"); \ @@ -521,8 +528,8 @@ int main(int argc, char **argv) { ulas_free(); - // this will re-init everything on its own, - // so call after free + /* this will re-init everything on its own, + so call after free */ test_full_dasm(); test_full_asm_fail(); test_full_asm(); diff --git a/src/ulas.c b/src/ulas.c index 3e14725..8f91af7 100644 --- a/src/ulas.c +++ b/src/ulas.c @@ -46,7 +46,8 @@ void ulas_help(void) { void ulas_version(void) { printf("%s version %s\n", ULAS_NAME, ULAS_VER); } void ulas_init(struct ulas_config cfg) { - // init global cfg + int i; + /* init global cfg */ if (ulasin == NULL) { ulasin = stdin; } @@ -59,7 +60,7 @@ void ulas_init(struct ulas_config cfg) { ulascfg = cfg; - // init assembly context + /* init assembly context */ memset(&ulas, 0, sizeof(ulas)); ulas.tok = ulas_str(8); @@ -76,23 +77,24 @@ void ulas_init(struct ulas_config cfg) { ulas.pp = ulas_preprocinit(); ulas.scope = 1; - for (int i = 0; i < ULAS_CHARCODEMAPLEN; i++) { + for (i = 0; i < ULAS_CHARCODEMAPLEN; i++) { ulas.charcodemap[i] = (char)i; } ulas_arch_set(ULAS_ARCH_SM83); } void ulas_nextpass(void) { + int i; ulas.scope = 1; ulas.line = 0; ulas.icntr = 0; ulas.address = ulascfg.org; ulas.chksm = 0; ulas.filename = ulas.initial_filename; - ulas.section[0] = '\0'; // reset section + ulas.section[0] = '\0'; /* reset section */ ulas.section_address = 0; - for (int i = 0; i < ULAS_CHARCODEMAPLEN; i++) { + for (i = 0; i < ULAS_CHARCODEMAPLEN; i++) { ulas.charcodemap[i] = (char)i; } } @@ -128,8 +130,9 @@ unsigned int ulas_strnlen(const char *s, unsigned int max) { unsigned int ulas_strlcat(char *dst, const char *src, unsigned int max) { unsigned int dst_len = ulas_strnlen(dst, max); unsigned int src_len = ulas_strnlen(src, max); + int i; - for (int i = 0; i < src_len; i++) { + for (i = 0; i < src_len; i++) { dst[dst_len+i] = src[i]; } @@ -140,14 +143,16 @@ unsigned int ulas_strlcat(char *dst, const char *src, unsigned int max) { FILE *ulas_incpathfopen(const char *path, const char *mode) { char pathbuf[ULAS_PATHMAX]; - memset(pathbuf, 0, ULAS_PATHMAX); + FILE *f; + int i; unsigned long baselen = strlen(path); + memset(pathbuf, 0, ULAS_PATHMAX); - // check all include paths - for (int i = 0; i < ulascfg.incpathslen; i++) { - pathbuf[0] = '\0'; + /* check all include paths */ + for (i = 0; i < ulascfg.incpathslen; i++) { char *ip = ulascfg.incpaths[i]; unsigned long len = strlen(ip); + pathbuf[0] = '\0'; if (len + baselen + 1 >= ULAS_PATHMAX) { continue; } @@ -158,14 +163,14 @@ FILE *ulas_incpathfopen(const char *path, const char *mode) { } ulas_strlcat(pathbuf, path, ULAS_PATHMAX); - FILE *f = fopen(pathbuf, mode); + f = fopen(pathbuf, mode); if (f != NULL) { return f; } } - // check the original path last - FILE *f = fopen(path, mode); + /* check the original path last */ + f = fopen(path, mode); if (f == NULL) { ULASERR("%s: %s\n", path, strerror(errno)); } @@ -185,10 +190,11 @@ struct ulas_config ulas_cfg_from_env(void) { } FILE *ulas_fopen(const char *path, const char *mode, FILE *stdfile) { + FILE *f; if (!path || strncmp(path, ULAS_STDFILEPATH, 1) == 0) { return stdfile; } - FILE *f = fopen(path, mode); + f = fopen(path, mode); if (!f) { ULASPANIC("%s: %s\n", path, strerror(errno)); @@ -205,15 +211,18 @@ void ulas_fclose(FILE *f) { fclose(f); } -long long ulas_timeusec(void) { +long ulas_timeusec(void) { struct timeval tv; gettimeofday(&tv, NULL); return 1000000 * tv.tv_sec + tv.tv_usec; } int ulas_main(struct ulas_config cfg) { - long long total_startusec = ulas_timeusec(); + long total_startusec = ulas_timeusec(); + long total_endusec; int rc = 0; + FILE *preprocdst; + ulas_init(cfg); if (cfg.output_path) { ULASDBG("output: %s\n", cfg.output_path); @@ -234,10 +243,11 @@ int ulas_main(struct ulas_config cfg) { ULASDBG("input: %s\n", cfg.argv[0]); ulasin = ulas_fopen(cfg.argv[0], "re", stdin); } - FILE *preprocdst = NULL; + preprocdst = NULL; - // only do 2 pass if we have a file as input - // because we cannot really rewind stdout + /* only do 2 pass if we have a file as input + * because we cannot really rewind stdout + */ if (!cfg.preproc_only && ulasin != stdin) { ulas.pass = ULAS_PASS_RESOLVE; } @@ -249,8 +259,9 @@ int ulas_main(struct ulas_config cfg) { ulas_nextpass(); - // FIXME: it would be nice if we could do the 2 pass by clearing the - // tmpfile instead of making an entierly new one + /* FIXME: it would be nice if we could do the 2 pass by clearing the + * tmpfile instead of making an entierly new one + */ if (cfg.preproc_only) { preprocdst = ulasout; } else { @@ -300,16 +311,17 @@ cleanup: ulas_free(); - long long total_endusec = ulas_timeusec(); + total_endusec = ulas_timeusec(); if (ulascfg.verbose) { - fprintf(ulaserr, "[Completed in %lld ms]\n", - (total_endusec - total_startusec) / 1000); + fprintf(ulaserr, "[Completed in %ld ms]\n", + (long int)((total_endusec - total_startusec) / 1000)); } return rc; } int ulas_isname(const char *tok, unsigned long n) { + unsigned long i; if (n == 0) { return 0; } @@ -318,7 +330,7 @@ int ulas_isname(const char *tok, unsigned long n) { return 0; } - for (unsigned long i = 0; i < n && tok[i]; i++) { + for (i = 0; i < n && tok[i]; i++) { char c = tok[i]; if (c != '_' && !isalnum(c) && !(i == 0 && c == ULAS_TOK_SCOPED_SYMBOL_BEGIN)) { @@ -334,9 +346,10 @@ int ulas_islabelname(const char *tok, unsigned long n) { } struct ulas_sym *ulas_symbolresolve(const char *name, int scope, int *rc) { - for (int i = 0; i < ulas.syms.len; i++) { + int i; + for (i = 0; i < ulas.syms.len; i++) { struct ulas_sym *sym = &ulas.syms.buf[i]; - // when scope is the same as the current one, or scope 0 (global) + /* when scope is the same as the current one, or scope 0 (global) */ if ((sym->scope == 0 || sym->scope == scope) && strcmp(name, sym->name) == 0) { return sym; @@ -348,20 +361,23 @@ struct ulas_sym *ulas_symbolresolve(const char *name, int scope, int *rc) { int ulas_symbolset(const char *cname, int scope, struct ulas_tok tok, int constant) { - // remove : from name + struct ulas_sym *existing; + int rc = 0; + int resolve_rc = 0; + unsigned long len; + + /* remove : from name */ char name[ULAS_SYMNAMEMAX]; memset(name, 0, ULAS_SYMNAMEMAX); - unsigned long len = strlen(cname); + len = strlen(cname); assert(len < ULAS_SYMNAMEMAX); strncpy(name, cname, len); if (name[len - 1] == ':') { name[len - 1] = '\0'; } - int rc = 0; - int resolve_rc = 0; - // auto-determine scope + /* auto-determine scope */ if (scope == -1) { if (name[0] == ULAS_TOK_SCOPED_SYMBOL_BEGIN) { scope = ulas.scope; @@ -370,21 +386,26 @@ int ulas_symbolset(const char *cname, int scope, struct ulas_tok tok, } } - struct ulas_sym *existing = ulas_symbolresolve(name, scope, &resolve_rc); - // inc scope when symbol is global + existing = ulas_symbolresolve(name, scope, &resolve_rc); + /* inc scope when symbol is global */ if (name[0] != ULAS_TOK_SCOPED_SYMBOL_BEGIN && cname[len - 1] == ':') { ulas.scope++; } if (!existing || (name[0] == '\0' && len == 1)) { - // def new symbol - struct ulas_sym new_sym = {ulas_strndup(name, len), tok, scope, ulas.pass, - constant}; + /* def new symbol */ + struct ulas_sym new_sym; + new_sym.name = ulas_strndup(name, len); + new_sym.tok = tok; + new_sym.scope = scope; + new_sym.lastdefin = ulas.pass, + new_sym.constant = constant; + ulas_symbufpush(&ulas.syms, new_sym); rc = ulas_symbolout(ulassymout, &new_sym); } else if (existing->lastdefin != ulas.pass || !existing->constant) { - // redefine if not defined this pass + /* redefine if not defined this pass */ existing->lastdefin = ulas.pass; ulas_tokfree(&existing->tok); existing->tok = tok; @@ -392,7 +413,7 @@ int ulas_symbolset(const char *cname, int scope, struct ulas_tok tok, rc = ulas_symbolout(ulassymout, existing); } else { - // exists.. cannot have duplicates! + /* exists.. cannot have duplicates! */ rc = -1; ULASERR("Redefenition of symbol '%s' in scope %d\n", name, scope); } @@ -409,7 +430,7 @@ int ulas_symbolout_mlbloc(FILE *dst, long addr) { if (ulas.section[0] != '\0') { const char *section = ulas.section; - // statically map some ulas section names to mlb sections + /* statically map some ulas section names to mlb sections */ if (strncmp(ULAS_MLB_SECTION_PRGROM, ulas.section, ULAS_SECTIONMAX) == 0) { section = "GbPrgRom"; } else if (strncmp(ULAS_MLB_SECTION_WORKRAM, ulas.section, @@ -426,9 +447,10 @@ int ulas_symbolout_mlbloc(FILE *dst, long addr) { return 0; } - // fallback - // if no previous section was declared we fall back to the - // old default output + /* fallback + * if no previous section was declared we fall back to the + * old default output + */ switch (ulas.arch.type) { case ULAS_ARCH_SM83: if (addr >= 0x0000 && addr <= 0x7FFF) { @@ -447,12 +469,11 @@ int ulas_symbolout_mlbloc(FILE *dst, long addr) { } int ulas_symbolout(FILE *dst, struct ulas_sym *s) { + int rc = 0; if (!dst || ulas.pass != ULAS_PASS_FINAL) { return 0; } - int rc = 0; - switch (ulascfg.sym_fmt) { case ULAS_SYM_FMT_DEFAULT: if (!s->name || s->name[0] == '\0') { @@ -528,8 +549,8 @@ int ulas_symbolout(FILE *dst, struct ulas_sym *s) { #define ULAS_TOKISTERM write #define ULAS_TOKCOND (i < n && write < n && line[i]) #define ULAS_QUOTED_TOKEN(quote_char) { \ - dst->buf[write++] = line[i++];\ int last_escape = 0;\ + dst->buf[write++] = line[i++];\ while (ULAS_TOKCOND && (line[i] != (quote_char) || last_escape)) {\ last_escape = line[i] == '\\';\ dst->buf[write++] = line[i];\ @@ -540,17 +561,17 @@ int ulas_symbolout(FILE *dst, struct ulas_sym *s) { int ulas_tok(struct ulas_str *dst, const char **out_line, unsigned long n) { const char *line = *out_line; - ulas_strensr(dst, n + 1); - int i = 0; int write = 0; - // always skip leading terminators + ulas_strensr(dst, n + 1); + + /* always skip leading terminators */ while (ULAS_TOKCOND && isspace(line[i])) { i++; } - // string token + /* string token */ if (line[i] == '"') { ULAS_QUOTED_TOKEN('\"'); } else if (line[i] == '\'') { @@ -578,17 +599,18 @@ int ulas_tok(struct ulas_str *dst, const char **out_line, unsigned long n) { if (ULAS_TOKISTERM) { goto tokdone; } - // single char tokens + /* single char tokens */ dst->buf[write++] = line[i++]; goto tokdone; case '$': if (ULAS_TOKISTERM) { goto tokdone; } - // special var for preprocessor - // make sure we have enough space in buffer + /* special var for preprocessor + * make sure we have enough space in buffer + */ ulas_strensr(dst, write + 2); - // escape char tokens + /* escape char tokens */ dst->buf[write++] = line[i++]; if (line[i] == '$') { dst->buf[write++] = line[i++]; @@ -630,19 +652,20 @@ tokdone: return i; } -// tokenize until the char c is seen -// this will also consume c and out_line will point to the next valid char -// this is useful if the next expected token is well defined and we want to -// capture everything between -// will remove leading white spaces +/* tokenize until the char c is seen + * this will also consume c and out_line will point to the next valid char + * this is useful if the next expected token is well defined and we want to + * capture everything between + * will remove leading white spaces + */ int ulas_tokuntil(struct ulas_str *dst, char c, const char **out_line, unsigned long n) { const char *line = *out_line; - ulas_strensr(dst, n + 1); - int i = 0; int write = 0; + ulas_strensr(dst, n + 1); + while (ULAS_TOKCOND && isspace(line[i])) { i++; } @@ -692,6 +715,8 @@ int ulas_unescape(char c, int *rc) { struct ulas_tok ulas_totok(char *buf, unsigned long n, int *rc) { struct ulas_tok tok; + long i = 0; + unsigned char first; memset(&tok, 0, sizeof(tok)); if (n == 0) { @@ -699,24 +724,25 @@ struct ulas_tok ulas_totok(char *buf, unsigned long n, int *rc) { goto end; } - unsigned char first = buf[0]; + first = buf[0]; buf++; if (n == 1 && !isalnum(first)) { - // single char tokens + /* single char tokens */ tok.type = first; } else { switch (first) { case '"': - // string + /* string */ tok.type = ULAS_STR; - // FIXME: this likely mallocs a few extra bytes - // but honestly its probably fine + /* FIXME: this likely mallocs a few extra bytes + * but honestly its probably fine + */ tok.val.strv = malloc(n * sizeof(char) + 1); memset(tok.val.strv, 0, n); - long i = 0; + i = 0; while (*buf && *buf != '\"') { if (*buf == '\\') { buf++; @@ -768,10 +794,10 @@ struct ulas_tok ulas_totok(char *buf, unsigned long n, int *rc) { break; default: if (isdigit(first)) { - // integer + /* integer */ tok.type = ULAS_INT; - // 0b prefix is not supported in strtol... so we implement it by hand + /* 0b prefix is not supported in strtol... so we implement it by hand */ if (*buf == 'b') { buf++; tok.val.intv = (int)strtol(buf, &buf, 2); @@ -795,8 +821,9 @@ struct ulas_tok ulas_totok(char *buf, unsigned long n, int *rc) { buf++; break; } else if (ulas_isname(buf - 1, n)) { - // literal token - // we resolve it later, will need to malloc here for now + /* literal token + * we resolve it later, will need to malloc here for now + */ tok.type = ULAS_SYMBOL; tok.val.strv = ulas_strndup(buf - 1, n); buf += n - 1; @@ -810,7 +837,7 @@ struct ulas_tok ulas_totok(char *buf, unsigned long n, int *rc) { } end: - // did we consume the entire token? + /* did we consume the entire token? */ if (buf[0] != '\0') { *rc = -1; } @@ -822,7 +849,9 @@ end: #undef ULAS_TOKISTERM struct ulas_str ulas_str(unsigned long n) { - struct ulas_str str = {malloc(n), n}; + struct ulas_str str; + str.buf = malloc(n); + str.maxlen = n; return str; } @@ -851,7 +880,8 @@ void ulas_strfree(struct ulas_str *s) { struct ulas_ppdef *ulas_preprocgetdef(struct ulas_preproc *pp, const char *name, unsigned long maxlen) { - for (unsigned long i = 0; i < pp->defslen; i++) { + unsigned long i; + for (i = 0; i < pp->defslen; i++) { struct ulas_ppdef *def = &pp->defs[i]; if (!def->undef && strncmp(def->name, name, maxlen) == 0) { return def; @@ -861,7 +891,7 @@ struct ulas_ppdef *ulas_preprocgetdef(struct ulas_preproc *pp, const char *name, return NULL; } -// inserts all leading white space from praw_line into linebuf +/* inserts all leading white space from praw_line into linebuf */ int ulas_preproclws(struct ulas_preproc *pp, const char *praw_line, unsigned long maxlen) { int i = 0; @@ -879,7 +909,7 @@ void ulas_trimend(char c, char *buf, unsigned long n) { if (buflen == 0) { return; } - // remove trailing new line if present + /* remove trailing new line if present */ while (buf[buflen - 1] == '\n') { buf[buflen - 1] = '\0'; buflen--; @@ -889,11 +919,13 @@ void ulas_trimend(char c, char *buf, unsigned long n) { char *ulas_preprocexpand2(struct ulas_preproc *pp, const char *raw_line, unsigned long *n, int recursive); void ulas_preprocexpand_rec(struct ulas_preproc *pp) { - // expand macro result again to allow - // defines to appear in the macro + unsigned long n; + /* expand macro result again to allow + * defines to appear in the macro + */ ulas_strensr(&pp->line2, strlen(pp->line.buf) + 1); sprintf(pp->line2.buf, "%s", pp->line.buf); - unsigned long n = strlen(pp->line.buf); + n = strlen(pp->line.buf); pp->exp_depth++; if (pp->exp_depth > ULAS_PREPROC_MAX_MACRO_DEPTH) { ULASERR("Max macro recursion depth reached\n"); @@ -910,58 +942,70 @@ char *ulas_preprocexpand(struct ulas_preproc *pp, const char *raw_line, char *ulas_preprocexpand2(struct ulas_preproc *pp, const char *raw_line, unsigned long *n, int recursive) { + const char *macro_argname[ULAS_MACROPARAMMAX] = { + "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", + "$9", "$10", "$11", "$12", "$13", "$14", "$15"}; const char *praw_line = raw_line; - memset(pp->line.buf, 0, pp->line.maxlen); int read = 0; int first_tok = 1; int skip_next_tok = 0; int comment_seen = 0; + unsigned long mi; + unsigned long i; + memset(pp->line.buf, 0, pp->line.maxlen); - // go through all tokens, see if a define matches the token, - // if so expand it - // only expand macros if they match toks[0] though! - // otherwise memcpy the read bytes 1:1 into the new string + /* go through all tokens, see if a define matches the token, + * if so expand it + * only expand macros if they match toks[0] though! + * otherwise memcpy the read bytes 1:1 into the new string + */ while ((read = ulas_tok(&pp->tok, &praw_line, *n))) { - // remove comment seen if raw line - // starts a new line - // this fixes expnasion in macros containing comments - // also make sure the next char is not 0 + struct ulas_ppdef *def; + /* remove comment seen if raw line + * starts a new line + * this fixes expnasion in macros containing comments + * also make sure the next char is not 0 + */ if (*praw_line == '\n' && praw_line[1]) { comment_seen = 0; } - struct ulas_ppdef *def = + def = ulas_preprocgetdef(pp, pp->tok.buf, pp->tok.maxlen); - // if it is the first token, and it begins with a # do not process at all! - // if the first token is a # preproc directive skip the second token at all - // times + /* if it is the first token, and it begins with a # do not process at all! + * if the first token is a # preproc directive skip the second token at all + * times + */ if ((first_tok && pp->tok.buf[0] == ULAS_TOK_PREPROC_BEGIN) || skip_next_tok) { def = NULL; skip_next_tok = !skip_next_tok; } else if (pp->tok.buf[0] == ULAS_TOK_COMMENT) { - // if its a comment at the end of a preproc statement - // just bail now + /* if its a comment at the end of a preproc statement + * just bail now + */ comment_seen = 1; } first_tok = 0; if (def && !comment_seen) { - // if so... expand now and leave + /* if so... expand now and leave */ switch (def->type) { case ULAS_PPDEF: { unsigned long val_len = strlen(def->value); int wsi = ulas_preproclws(pp, praw_line - read, *n); if (val_len) { - // make sure to include leading white space - // adjust total length + /* make sure to include leading white space + * adjust total length + */ *n -= strlen(pp->tok.buf); *n += val_len; ulas_strensr(&pp->line, (*n) + 1 + wsi); - // only remove the first white space char if the lenght of value - // is greater than 1, otherwise just leave it be... + /* only remove the first white space char if the lenght of value + * is greater than 1, otherwise just leave it be... + */ if (val_len > 1) { strncat(pp->line.buf, def->value + 1, val_len - 1); } else { @@ -972,50 +1016,57 @@ char *ulas_preprocexpand2(struct ulas_preproc *pp, const char *raw_line, break; } case ULAS_PPMACRO: { - // TODO: i am sure we can optimize the resize of line buffers here... - // TODO: allow recursive macro calls - - // get 9 comma separated values. - // $1-$9 will reference the respective arg - // $0 will reference the entire line after the macro name - // there can be more than 9 args, but anything after the 9th arg can - // only be accessed via $0 + const char *val; + unsigned long vallen; + unsigned long valread; + const char *tocat; + unsigned long tocatlen; + int paramc; + + /* TODO: i am sure we can optimize the resize of line buffers here... + * TODO: allow recursive macro calls + */ + + /* get 9 comma separated values. + * $1-$9 will reference the respective arg + * $0 will reference the entire line after the macro name + * there can be more than 9 args, but anything after the 9th arg can + * only be accessed via $0 + */ const char *line = praw_line; unsigned long linelen = strlen(praw_line); - // clear all params from previous attempt - for (unsigned long i = 0; i < ULAS_MACROPARAMMAX; i++) { + /* clear all params from previous attempt */ + for (i = 0; i < ULAS_MACROPARAMMAX; i++) { pp->macroparam[i].buf[0] = '\0'; } - // loop until 9 args are found or the line ends - int paramc = 0; + /* loop until 9 args are found or the line ends */ + paramc = 0; while (paramc < ULAS_MACROPARAMMAX && - // TODO: allow escaping , with \, + /* TODO: allow escaping , with \, */ ulas_tokuntil(&pp->macroparam[paramc], ',', &praw_line, *n) > 0) { - // trim new lines from the end of macro params + /* trim new lines from the end of macro params */ ulas_trimend('\n', pp->macroparam[paramc].buf, strlen(pp->macroparam[paramc].buf)); paramc++; } ulas_strensr(&pp->line, strlen(def->value) + 2); - const char *macro_argname[ULAS_MACROPARAMMAX] = { - "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", - "$9", "$10", "$11", "$12", "$13", "$14", "$15"}; - - const char *val = def->value; - unsigned long vallen = strlen(def->value); - unsigned long valread = 0; + val = def->value; + vallen = strlen(def->value); + valread = 0; - // the pointer to tocat will be the variable's value if any - // exists - const char *tocat = NULL; - unsigned long tocatlen = 0; + /* the pointer to tocat will be the variable's value if any + * exists + */ + tocat = NULL; + tocatlen = 0; - // always start an expanded macro with a new line - // to ensure expansion are separated if we are in a recursive call - // this fixes new lines in recursive macros being consumed + /* always start an expanded macro with a new line + * to ensure expansion are separated if we are in a recursive call + * this fixes new lines in recursive macros being consumed + */ if (recursive) { int len = ulas_strnlen(pp->line.buf, pp->line.maxlen) + 1; ulas_strensr(&pp->line, @@ -1024,15 +1075,16 @@ char *ulas_preprocexpand2(struct ulas_preproc *pp, const char *raw_line, } - // now tokenize the macro's value and look for $0-$9 - // and replace those instances - // eveyrthing else will just be copied as is + /* now tokenize the macro's value and look for $0-$9 + * and replace those instances + * eveyrthing else will just be copied as is + */ while ((valread = ulas_tok(&pp->macrobuf, &val, vallen)) > 0) { - tocat = NULL; char numbuf[128]; + tocat = NULL; - // decide what tocat should be - for (unsigned long mi = 0; mi < ULAS_MACROPARAMMAX; mi++) { + /* decide what tocat should be */ + for (mi = 0; mi < ULAS_MACROPARAMMAX; mi++) { const char *name = macro_argname[mi]; if (pp->macroparam[mi].buf[0] && strncmp((name), pp->macrobuf.buf, pp->macrobuf.maxlen) == 0) { @@ -1054,12 +1106,13 @@ char *ulas_preprocexpand2(struct ulas_preproc *pp, const char *raw_line, ulas_strnlen(pp->line.buf, pp->line.maxlen) + linelen + 1); if (linelen > 1) { - // this skips the separating token which is usually a space - // all further spaces are included though! + /* this skips the separating token which is usually a space + * all further spaces are included though! + */ tocat = line + 1; tocatlen = linelen - 1; } else { - // do not do this if the line is literally empty! + /* do not do this if the line is literally empty! */ tocat = line; tocatlen = linelen; } @@ -1076,7 +1129,7 @@ char *ulas_preprocexpand2(struct ulas_preproc *pp, const char *raw_line, ulas_strensr(&pp->line, strlen(pp->line.buf) + valread + 1); strncat(pp->line.buf, val - valread, valread); } else { - // make sure to include leading white space + /* make sure to include leading white space */ int wsi = ulas_preproclws(pp, val - valread, vallen); ulas_strensr(&pp->line, ulas_strnlen(pp->line.buf, pp->line.maxlen) + tocatlen + wsi + 1); @@ -1089,8 +1142,9 @@ char *ulas_preprocexpand2(struct ulas_preproc *pp, const char *raw_line, } } else { - // if not found: copy everythin from prev to the current raw_line point - - // tok lenght -> this keeps the line in-tact as is + /* if not found: copy everythin from prev to the current raw_line point - + * tok lenght -> this keeps the line in-tact as is + */ ulas_strensr(&pp->line, (*n) + 1); strncat(pp->line.buf, praw_line - read, read); } @@ -1102,8 +1156,9 @@ end: } int ulas_preprocdef(struct ulas_preproc *pp, struct ulas_ppdef def) { + void *defs; pp->defslen++; - void *defs = realloc(pp->defs, pp->defslen * sizeof(struct ulas_ppdef)); + defs = realloc(pp->defs, pp->defslen * sizeof(struct ulas_ppdef)); if (!defs) { ULASPANIC("%s\n", strerror(errno)); } @@ -1122,6 +1177,7 @@ int ulas_preprocline(struct ulas_preproc *pp, FILE *dst, FILE *src, */ char *line = ulas_preprocexpand(pp, raw_line, &n); const char *pline = line; + unsigned long i; const char *dirstrs[] = { ULAS_PPSTR_DEF, ULAS_PPSTR_MACRO, ULAS_PPSTR_IFDEF, @@ -1134,13 +1190,13 @@ int ulas_preprocline(struct ulas_preproc *pp, FILE *dst, FILE *src, enum ulas_ppdirs found_dir = ULAS_PPDIR_NONE; - // check if the first token is any of the valid preproc directives + /* check if the first token is any of the valid preproc directives */ if (ulas_tok(&pp->tok, &pline, n)) { - // not a preproc directive... + /* not a preproc directive... */ if (pp->tok.buf[0] != ULAS_TOK_PREPROC_BEGIN) { goto found; } - for (unsigned long i = 0; dirstrs[i]; i++) { + for (i = 0; dirstrs[i]; i++) { if (strncmp(dirstrs[i], pp->tok.buf, pp->tok.maxlen) == 0) { found_dir = dirs[i]; goto found; @@ -1156,8 +1212,10 @@ found: ulas_trimend('\n', line, strlen(line)); switch (found_dir) { case ULAS_PPDIR_DEF: { - // next token is a name - // and then the entire remainder of the line is a value + struct ulas_ppdef def; + /* next token is a name + * and then the entire remainder of the line is a value + */ if (ulas_tok(&pp->tok, &pline, n) == 0) { ULASERR("Expected name for #define\n"); return -1; @@ -1168,17 +1226,25 @@ found: return -1; } - struct ulas_ppdef def = {ULAS_PPDEF, ulas_strdup(pp->tok.buf), - ulas_strdup(pline), - 0}; + def.type = ULAS_PPDEF; + def.name = ulas_strdup(pp->tok.buf); + def.value = ulas_strdup(pline); + def.undef = 0; 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! + /* define short-circuits the rest of the logic + * because it just takes the entire rest of the line as a value! + */ goto dirdone; } case ULAS_PPDIR_MACRO: { - // get a name, ensure no more tokens come after - // and then consume lines until ENDMACRO is seen + struct ulas_ppdef def; + int rc; + char buf[ULAS_LINEMAX]; + char *name; + struct ulas_str val; + /* get a name, ensure no more tokens come after + * and then consume lines until ENDMACRO is seen + */ if (ulas_tok(&pp->tok, &pline, n) == 0) { ULASERR("Expected name for #macro\n"); return -1; @@ -1188,28 +1254,30 @@ found: ULASERR("'%s' is not a valid #macro name!\n", pp->tok.buf); return -1; } - char *name = ulas_strdup(pp->tok.buf); + name = ulas_strdup(pp->tok.buf); - struct ulas_str val = ulas_str(32); + val = ulas_str(32); memset(val.buf, 0, 32); - char buf[ULAS_LINEMAX]; memset(buf, 0, ULAS_LINEMAX); - // consume lines until #endmacro is read - // if reaching end of input without #endmacro we have an unterminated - // macro. pass NULL as dst to consume lines that are being read instead of - // echoing them back - int rc = 0; + /* consume lines until #endmacro is read + * if reaching end of input without #endmacro we have an unterminated + * macro. pass NULL as dst to consume lines that are being read instead of + * echoing them back + */ + rc = 0; while ((rc = ulas_preprocnext(pp, NULL, src, buf, ULAS_LINEMAX)) > 0) { + unsigned long len; if (rc == ULAS_PPDIR_ENDMACRO) { - // we need to clear the line buffer to now echo back - // the #endmacro directive + /* we need to clear the line buffer to now echo back + * the #endmacro directive + */ pp->line.buf[0] = '\0'; break; } - unsigned long len = ulas_strnlen(pp->line.buf, pp->line.maxlen); + len = ulas_strnlen(pp->line.buf, pp->line.maxlen); ulas_strensr(&val, ulas_strnlen(val.buf, val.maxlen) + len + 1); strncat(val.buf, pp->line.buf, val.maxlen); } @@ -1220,9 +1288,13 @@ found: free(name); return -1; } - // we leak the str's buffer into the def now - // this is ok because we call free for it later anyway - struct ulas_ppdef def = {ULAS_PPMACRO, name, val.buf, 0}; + /* we leak the str's buffer into the def now + * this is ok because we call free for it later anyway + */ + def.type = ULAS_PPMACRO; + def.name = name; + def.value = val.buf; + def.undef = 0; ulas_preprocdef(pp, def); goto dirdone; @@ -1232,30 +1304,35 @@ found: break; case ULAS_PPDIR_IFDEF: case ULAS_PPDIR_IFNDEF: { - // get the name - // get a name, ensure no more tokens come after - // and then consume lines until ENDMACRO is seen + FILE *defdst; + int rc; + struct ulas_ppdef *def; + char buf[ULAS_LINEMAX]; + /* get the name + * get a name, ensure no more tokens come after + * and then consume lines until ENDMACRO is seen + */ if (ulas_tok(&pp->tok, &pline, n) == 0) { ULASERR("Expected name for #if(n)def\n"); return -1; } - struct ulas_ppdef *def = + def = ulas_preprocgetdef(pp, pp->tok.buf, pp->tok.maxlen); - char buf[ULAS_LINEMAX]; memset(buf, 0, ULAS_LINEMAX); - FILE *defdst = NULL; + defdst = NULL; if ((def && found_dir == ULAS_PPDIR_IFDEF) || (!def && found_dir == ULAS_PPDIR_IFNDEF)) { defdst = dst; } - // loop until end of line or endif - int rc = 0; + /* loop until end of line or endif */ + rc = 0; while ((rc = ulas_preprocnext(pp, defdst, src, buf, ULAS_LINEMAX)) > 0) { if (rc == ULAS_PPDIR_ENDIF) { - // we need to clear the line buffer to now echo back - // the #endif directive + /* we need to clear the line buffer to now echo back + * the #endif directive + */ pp->line.buf[0] = '\0'; break; } @@ -1268,11 +1345,12 @@ found: goto dirdone; } case ULAS_PPDIR_UNDEF: { + struct ulas_ppdef *def; if (ulas_tok(&pp->tok, &pline, n) == 0) { ULASERR("Expected name for #undef\n"); return -1; } - struct ulas_ppdef *def = NULL; + def = NULL; while ((def = ulas_preprocgetdef(pp, pp->tok.buf, pp->tok.maxlen))) { def->undef = 1; } @@ -1280,24 +1358,27 @@ found: break; } case ULAS_PPDIR_INCLUDE: { + FILE *tmp, *f; int rc = found_dir; + unsigned long prev_lines; + char *prev_path; char *path = ulas_strexpr(&pline, strlen(pline), &rc); if (rc == -1 || !path) { return rc; } - FILE *f = ulas_incpathfopen(path, "re"); + f = ulas_incpathfopen(path, "re"); if (!f) { return -1; } - char *prev_path = ulas.filename; - unsigned long prev_lines = ulas.line; + prev_path = ulas.filename; + prev_lines = ulas.line; ulas.filename = ulas_strdup(path); ulas.line = 0; - FILE *tmp = tmpfile(); + tmp = tmpfile(); rc = ulas_preproc(tmp, f); - // only error if -1 + /* only error if -1 */ if (rc != -1) { rc = found_dir; } @@ -1311,7 +1392,7 @@ found: return rc; } default: - // this should not happen! + /* this should not happen! */ break; } @@ -1324,17 +1405,19 @@ found: return ULAS_PPDIR_NONE; } -// checks if the last printable char in a string is '\' -// side-effect: also replaced that what with \0 if it is found +/* checks if the last printable char in a string is '\' + * side-effect: also replaced that what with \0 if it is found + */ int ulas_last_print_is_escape(char *buf, int n) { int found_escape = 0; - // check if last printable char is an escape char + int i; + /* check if last printable char is an escape char */ unsigned int buf_len = ulas_strnlen(buf, n); if (buf_len == 0) { return 0; } - for (int i = buf_len - 1; i >= 0; i--) { + for (i = buf_len - 1; i >= 0; i--) { if (isprint(buf[i])) { found_escape = buf[i] == '\\'; if (found_escape) { @@ -1347,20 +1430,22 @@ int ulas_last_print_is_escape(char *buf, int n) { return found_escape; } -// call fgets and concats into buf until either buf is full (fatal error) -// or a non-escape character is *not* the last chracter of a line -// returns number of lines read +/* call fgets and concats into buf until either buf is full (fatal error) + * or a non-escape character is *not* the last chracter of a line + * returns number of lines read + */ int ulas_fgets(char *buf, int n, FILE *src) { char internal_buf[ULAS_LINEMAX+1]; + int lines_read; buf[0] = '\0'; internal_buf[ULAS_LINEMAX] = '\0'; - int lines_read = 0; + lines_read = 0; do { char *res = fgets(internal_buf, ULAS_LINEMAX, src); - // bail early + /* bail early */ if (res == NULL) { break; } @@ -1375,12 +1460,13 @@ int ulas_fgets(char *buf, int n, FILE *src) { int ulas_preprocnext(struct ulas_preproc *pp, FILE *dst, FILE *src, char *buf, int n) { + unsigned long buflen; int rc = 1; int lines_read = 0; if ((lines_read = ulas_fgets(buf, n, src)) != 0) { ulas.line += lines_read; - unsigned long buflen = strlen(buf); + buflen = strlen(buf); rc = ulas_preprocline(pp, dst, src, buf, buflen); } else { @@ -1391,18 +1477,26 @@ int ulas_preprocnext(struct ulas_preproc *pp, FILE *dst, FILE *src, char *buf, } struct ulas_preproc ulas_preprocinit(void) { - struct ulas_preproc pp = {NULL, 0, ulas_str(1), ulas_str(1), ulas_str(1)}; - for (unsigned long i = 0; i < ULAS_MACROPARAMMAX; i++) { + int i; + struct ulas_preproc pp; + pp.defs = NULL; + pp.defslen = 0; + pp.tok = ulas_str(1); + pp.line = ulas_str(1); + pp.line2 = ulas_str(1); + + for (i = 0; i < ULAS_MACROPARAMMAX; i++) { pp.macroparam[i] = ulas_str(8); } pp.macrobuf = ulas_str(8); - // set up initial defs - for (int i = 0; i < ulascfg.defslen; i++) { - - struct ulas_ppdef def = {ULAS_PPDEF, ulas_strdup(ulascfg.defs[i]), - ulas_strdup(""), - 0}; + /* set up initial defs */ + for (i = 0; i < ulascfg.defslen; i++) { + struct ulas_ppdef def; + def.type = ULAS_PPDEF; + def.name = ulas_strdup(ulascfg.defs[i]); + def.value = ulas_strdup(""); + def.undef = 0; ulas_preprocdef(&pp, def); } @@ -1410,7 +1504,8 @@ struct ulas_preproc ulas_preprocinit(void) { } void ulas_preprocclear(struct ulas_preproc *pp) { - for (unsigned long i = 0; i < pp->defslen; i++) { + unsigned long i; + for (i = 0; i < pp->defslen; i++) { if (pp->defs[i].name) { free(pp->defs[i].name); } @@ -1423,13 +1518,14 @@ void ulas_preprocclear(struct ulas_preproc *pp) { } void ulas_preprocfree(struct ulas_preproc *pp) { + unsigned long i; ulas_strfree(&pp->line); ulas_strfree(&pp->line2); ulas_strfree(&pp->tok); ulas_preprocclear(pp); - for (unsigned long i = 0; i < ULAS_MACROPARAMMAX; i++) { + for (i = 0; i < ULAS_MACROPARAMMAX; i++) { ulas_strfree(&pp->macroparam[i]); } ulas_strfree(&pp->macrobuf); @@ -1442,19 +1538,21 @@ void ulas_preprocfree(struct ulas_preproc *pp) { int ulas_preproc(FILE *dst, FILE *src) { FILE *asmsrc = dst; char buf[ULAS_LINEMAX]; - memset(buf, 0, ULAS_LINEMAX); int rc = 0; + long prevseek; + memset(buf, 0, ULAS_LINEMAX); - // init + /* init */ - long prevseek = ftell(asmsrc); - // preproc + prevseek = ftell(asmsrc); + /* preproc */ while ((rc = ulas_preprocnext(&ulas.pp, dst, src, buf, ULAS_LINEMAX)) > 0) { if (ulascfg.preproc_only) { continue; } - // after each preproc line we assembly it by reading it back - // from the temporary buffer + /* after each preproc line we assembly it by reading it back + * from the temporary buffer + */ fseek(asmsrc, prevseek, SEEK_SET); if (ulas_asm(ulasout, asmsrc) == -1) { rc = -1; @@ -1529,9 +1627,10 @@ struct ulas_tok *ulas_tokbufget(struct ulas_tokbuf *tb, int i) { } int ulas_tokbufpush(struct ulas_tokbuf *tb, struct ulas_tok tok) { + void *n; if (tb->len >= tb->maxlen) { tb->maxlen += 5; - void *n = realloc(tb->buf, tb->maxlen * sizeof(struct ulas_tok)); + n = realloc(tb->buf, tb->maxlen * sizeof(struct ulas_tok)); if (!n) { ULASPANIC("%s\n", strerror(errno)); } @@ -1550,7 +1649,8 @@ void ulas_tokfree(struct ulas_tok *t) { } void ulas_tokbufclear(struct ulas_tokbuf *tb) { - for (long i = 0; i < tb->len; i++) { + long i; + for (i = 0; i < tb->len; i++) { struct ulas_tok *t = &tb->buf[i]; ulas_tokfree(t); } @@ -1581,9 +1681,10 @@ struct ulas_expr *ulas_exprbufget(struct ulas_exprbuf *eb, int i) { } int ulas_exprbufpush(struct ulas_exprbuf *eb, struct ulas_expr expr) { + void *newbuf; if (eb->len >= eb->maxlen) { eb->maxlen *= 2; - void *newbuf = realloc(eb->buf, eb->maxlen * sizeof(struct ulas_expr)); + newbuf = realloc(eb->buf, eb->maxlen * sizeof(struct ulas_expr)); if (!newbuf) { ULASPANIC("%s\n", strerror(errno)); } @@ -1609,9 +1710,10 @@ struct ulas_symbuf ulas_symbuf(void) { } int ulas_symbufpush(struct ulas_symbuf *sb, struct ulas_sym sym) { + void *newbuf; if (sb->len >= sb->maxlen) { sb->maxlen *= 2; - void *newbuf = realloc(sb->buf, sb->maxlen * sizeof(struct ulas_sym)); + newbuf = realloc(sb->buf, sb->maxlen * sizeof(struct ulas_sym)); if (!newbuf) { ULASPANIC("%s\n", strerror(errno)); } @@ -1631,7 +1733,8 @@ struct ulas_sym *ulas_symbufget(struct ulas_symbuf *sb, int i) { } void ulas_symbufclear(struct ulas_symbuf *sb) { - for (long i = 0; i < sb->len; i++) { + long i; + for (i = 0; i < sb->len; i++) { struct ulas_sym *s = &sb->buf[i]; free(s->name); } @@ -1649,7 +1752,7 @@ void ulas_symbuffree(struct ulas_symbuf *sb) { int ulas_istokend(struct ulas_str *tok) { long len = (int)ulas_strnlen(tok->buf, tok->maxlen); - // skip comments though, they are not trailing tokens! + /* skip comments though, they are not trailing tokens! */ if (len > 0 && tok->buf[0] != ULAS_TOK_COMMENT) { return 0; } @@ -1657,38 +1760,40 @@ int ulas_istokend(struct ulas_str *tok) { return 1; } -// tokenize all until a terminator token or comment is reached +/* tokenize all until a terminator token or comment is reached */ int ulas_tokexpr(const char **line, unsigned long n) { + struct ulas_tok tok; + int tokrc = 0; ulas_tokbufclear(&ulas.toks); - int tokrc = 0; while ((tokrc = ulas_tok(&ulas.tok, line, n) > 0)) { if (tokrc == -1) { goto end; } - // empty tokens are going to be ignored + /* empty tokens are going to be ignored */ if (ulas_strnlen(ulas.tok.buf, ulas.tok.maxlen) == 0) { continue; } - // interpret the token - struct ulas_tok tok = ulas_totok( + /* interpret the token */ + tok = ulas_totok( ulas.tok.buf, ulas_strnlen(ulas.tok.buf, ulas.tok.maxlen), &tokrc); if (tokrc == -1) { goto end; } - // check for any expression terminators here + /* check for any expression terminators here */ if (tok.type == ',' || tok.type == ']' || tok.type == '=' || ulas_istokend(&ulas.tok)) { - // on terminator we roll back line so that the terminator token - // is not consumed now + /* on terminator we roll back line so that the terminator token + * is not consumed now + */ *line -= tokrc; goto end; } - // now we can loop token type, add all tokens to the token buffer + /* now we can loop token type, add all tokens to the token buffer */ ulas_tokbufpush(&ulas.toks, tok); } @@ -1710,6 +1815,13 @@ end: int ulas_parseexprat(int *i); int ulas_parseprim(int *i) { + struct ulas_expprim prim; + union ulas_expval val; + struct ulas_expr e; + struct ulas_expgrp grp; + int head; + struct ulas_tok *closing; + struct ulas_tok *t = ulas_tokbufget(&ulas.toks, *i); if (!t || (t->type != ULAS_INT && t->type != ULAS_STR && t->type != ULAS_SYMBOL && @@ -1720,13 +1832,14 @@ int ulas_parseprim(int *i) { if (t->type == '(') { *i += 1; - int head = ulas_parseexprat(i); + head = ulas_parseexprat(i); - struct ulas_expgrp grp = {head}; - union ulas_expval val = {.grp = grp}; - struct ulas_expr e = {ULAS_EXPGRP, val}; + grp.head = head; + val.grp = grp; + e.type = ULAS_EXPGRP; + e.val = val; - struct ulas_tok *closing = ulas_tokbufget(&ulas.toks, *i); + closing = ulas_tokbufget(&ulas.toks, *i); if (!closing || closing->type != ')') { ULASERR("Unterminated group expression\n"); return -1; @@ -1734,9 +1847,11 @@ int ulas_parseprim(int *i) { *i += 1; return ulas_exprbufpush(&ulas.exprs, e); } else { - struct ulas_expprim prim = {*i}; - union ulas_expval val = {.prim = prim}; - struct ulas_expr e = {ULAS_EXPPRIM, val}; + prim.tok = *i; + val.prim = prim; + e.type = ULAS_EXPPRIM; + e.val = val; + *i += 1; return ulas_exprbufpush(&ulas.exprs, e); } @@ -1746,16 +1861,22 @@ int ulas_parsecmp(int *i); int ulas_parseun(int *i) { struct ulas_tok *t = ulas_tokbufget(&ulas.toks, *i); + struct ulas_expun un; + union ulas_expval val; + struct ulas_expr e; + int op, right; if (t && (t->type == '!' || t->type == '-' || t->type == '~' || t->type == '+')) { - int op = *i; + op = *i; *i += 1; - int right = ulas_parseun(i); + right = ulas_parseun(i); - struct ulas_expun un = {right, op}; - union ulas_expval val = {.un = un}; - struct ulas_expr e = {ULAS_EXPUN, val}; + un.right = right; + un.op = op; + val.un = un; + e.type = ULAS_EXPUN; + e.val = val; return ulas_exprbufpush(&ulas.exprs, e); } @@ -1765,16 +1886,26 @@ int ulas_parseun(int *i) { int ulas_parsefact(int *i) { int expr = ulas_parseun(i); struct ulas_tok *t = NULL; + struct ulas_expbin bin; + union ulas_expval val; + struct ulas_expr e; + int op, right; while ((t = ulas_tokbufget(&ulas.toks, *i)) && (t->type == '*' || t->type == '/' || t->type == '%')) { - int op = *i; + op = *i; *i += 1; - int right = ulas_parseun(i); + right = ulas_parseun(i); + + bin.left = expr; + bin.right = right; + bin.op = op; + + val.bin = bin; + + e.type = ULAS_EXPBIN; + e.val = val; - struct ulas_expbin bin = {expr, right, op}; - union ulas_expval val = {.bin = bin}; - struct ulas_expr e = {ULAS_EXPBIN, val}; expr = ulas_exprbufpush(&ulas.exprs, e); } @@ -1784,16 +1915,25 @@ int ulas_parsefact(int *i) { int ulas_parseterm(int *i) { int expr = ulas_parsefact(i); struct ulas_tok *t = NULL; + struct ulas_expbin bin; + union ulas_expval val; + struct ulas_expr e; + int op, right; while ((t = ulas_tokbufget(&ulas.toks, *i)) && (t->type == '+' || t->type == '-')) { - int op = *i; + op = *i; *i += 1; - int right = ulas_parsefact(i); + right = ulas_parsefact(i); + + bin.left = expr; + bin.right = right; + bin.op = op; + + val.bin = bin; + e.type = ULAS_EXPBIN; + e.val = val; - struct ulas_expbin bin = {expr, right, op}; - union ulas_expval val = {.bin = bin}; - struct ulas_expr e = {ULAS_EXPBIN, val}; expr = ulas_exprbufpush(&ulas.exprs, e); } @@ -1803,16 +1943,25 @@ int ulas_parseterm(int *i) { int ulas_parseshift(int *i) { int expr = ulas_parseterm(i); struct ulas_tok *t = NULL; + struct ulas_expbin bin; + union ulas_expval val; + struct ulas_expr e; + int op, right; while ((t = ulas_tokbufget(&ulas.toks, *i)) && (t->type == ULAS_RSHIFT || t->type == ULAS_LSHIFT)) { - int op = *i; + op = *i; *i += 1; - int right = ulas_parseterm(i); + right = ulas_parseterm(i); + + bin.left = expr; + bin.right = right; + bin.op = op; + + val.bin = bin; + e.type = ULAS_EXPBIN; + e.val = val; - struct ulas_expbin bin = {expr, right, op}; - union ulas_expval val = {.bin = bin}; - struct ulas_expr e = {ULAS_EXPBIN, val}; expr = ulas_exprbufpush(&ulas.exprs, e); } @@ -1822,17 +1971,26 @@ int ulas_parseshift(int *i) { int ulas_parsecmp(int *i) { int expr = ulas_parseshift(i); struct ulas_tok *t = NULL; + struct ulas_expbin bin; + union ulas_expval val; + struct ulas_expr e; + int right, op; while ((t = ulas_tokbufget(&ulas.toks, *i)) && (t->type == ULAS_LTEQ || t->type == ULAS_GTEQ || t->type == '>' || t->type == '<')) { - int op = *i; + op = *i; *i += 1; - int right = ulas_parseshift(i); + right = ulas_parseshift(i); + + bin.left = expr; + bin.right = right; + bin.op = op; + + val.bin = bin; + e.type = ULAS_EXPBIN; + e.val = val; - struct ulas_expbin bin = {expr, right, op}; - union ulas_expval val = {.bin = bin}; - struct ulas_expr e = {ULAS_EXPBIN, val}; expr = ulas_exprbufpush(&ulas.exprs, e); } @@ -1842,15 +2000,25 @@ int ulas_parsecmp(int *i) { int ulas_parseeq(int *i) { int expr = ulas_parsecmp(i); struct ulas_tok *t = NULL; + struct ulas_expbin bin; + union ulas_expval val; + struct ulas_expr e; + int right, op; + while ((t = ulas_tokbufget(&ulas.toks, *i)) && (t->type == ULAS_EQ || t->type == ULAS_NEQ)) { - int op = *i; + op = *i; *i += 1; - int right = ulas_parsecmp(i); + right = ulas_parsecmp(i); + + bin.left = expr; + bin.right = right; + bin.op = op; + + val.bin = bin; + e.type = ULAS_EXPBIN; + e.val = val; - struct ulas_expbin bin = {expr, right, op}; - union ulas_expval val = {.bin = bin}; - struct ulas_expr e = {ULAS_EXPBIN, val}; expr = ulas_exprbufpush(&ulas.exprs, e); } @@ -1860,16 +2028,23 @@ int ulas_parseeq(int *i) { int ulas_parsebit(int *i) { int expr = ulas_parseeq(i); struct ulas_tok *t = NULL; + struct ulas_expbin bin; + union ulas_expval val; + struct ulas_expr e; while ((t = ulas_tokbufget(&ulas.toks, *i)) && (t->type == '&' || t->type == '|' || t->type == '^')) { - int op = *i; + int right, op = *i; *i += 1; - int right = ulas_parseeq(i); + right = ulas_parseeq(i); + + bin.left = expr; + bin.right = right; + bin.op = op; - struct ulas_expbin bin = {expr, right, op}; - union ulas_expval val = {.bin = bin}; - struct ulas_expr e = {ULAS_EXPBIN, val}; + val.bin = bin; + e.type = ULAS_EXPBIN; + e.val = val; expr = ulas_exprbufpush(&ulas.exprs, e); } @@ -1878,19 +2053,21 @@ int ulas_parsebit(int *i) { int ulas_parseexprat(int *i) { return ulas_parsebit(i); } -// parses tokens to expression tree -// returns head expression index +/* parses tokens to expression tree + * returns head expression index */ int ulas_parseexpr(void) { + int i, rc; + struct ulas_tokbuf *toks; ulas_exprbufclear(&ulas.exprs); - struct ulas_tokbuf *toks = &ulas.toks; + toks = &ulas.toks; if (toks->len == 0) { ULASERR("Expected expression\n"); return -1; } - int i = 0; - int rc = ulas_parseexprat(&i); + i = 0; + rc = ulas_parseexprat(&i); if (i < toks->len) { ULASERR("Trailing token at index %d\n", i); @@ -1902,6 +2079,9 @@ int ulas_parseexpr(void) { int ulas_intexpreval(int i, int *rc) { struct ulas_expr *e = ulas_exprbufget(&ulas.exprs, i); + int right, left; + struct ulas_tok *op; + struct ulas_tok *t; if (!e) { ULASERR("unable to evaluate expression\n"); *rc = -1; @@ -1910,12 +2090,12 @@ int ulas_intexpreval(int i, int *rc) { switch ((int)e->type) { case ULAS_EXPBIN: { - struct ulas_tok *op = ulas_tokbufget(&ulas.toks, (int)e->val.bin.op); + op = ulas_tokbufget(&ulas.toks, (int)e->val.bin.op); if (!op) { ULASPANIC("Binary operator was NULL\n"); } - int left = ulas_intexpreval((int)e->val.bin.left, rc); - int right = ulas_intexpreval((int)e->val.bin.right, rc); + left = ulas_intexpreval((int)e->val.bin.left, rc); + right = ulas_intexpreval((int)e->val.bin.right, rc); switch ((int)op->type) { case ULAS_EQ: return left == right; @@ -1972,11 +2152,11 @@ int ulas_intexpreval(int i, int *rc) { break; } case ULAS_EXPUN: { - struct ulas_tok *op = ulas_tokbufget(&ulas.toks, (int)e->val.un.op); + op = ulas_tokbufget(&ulas.toks, (int)e->val.un.op); if (!op) { ULASPANIC("Unary operator was NULL\n"); } - int right = ulas_intexpreval((int)e->val.un.right, rc); + right = ulas_intexpreval((int)e->val.un.right, rc); switch ((int)op->type) { case '!': return !right; @@ -1996,7 +2176,7 @@ int ulas_intexpreval(int i, int *rc) { return ulas_intexpreval((int)e->val.grp.head, rc); } case ULAS_EXPPRIM: { - struct ulas_tok *t = ulas_tokbufget(&ulas.toks, (int)e->val.prim.tok); + t = ulas_tokbufget(&ulas.toks, (int)e->val.prim.tok); return ulas_valint(t, rc); } } @@ -2005,34 +2185,37 @@ int ulas_intexpreval(int i, int *rc) { } int ulas_intexpr(const char **line, unsigned long n, int *rc) { + int expr; if (ulas_tokexpr(line, n) == -1) { *rc = -1; return -1; } - int expr = ulas_parseexpr(); + expr = ulas_parseexpr(); if (expr == -1) { *rc = -1; return -1; } - // execute the tree of expressions + /* execute the tree of expressions */ return ulas_intexpreval(expr, rc); } char *ulas_strexpr(const char **line, unsigned long n, int *rc) { + struct ulas_expr *e; + int expr; if (ulas_tokexpr(line, n) == -1) { *rc = -1; return NULL; } - int expr = ulas_parseexpr(); + expr = ulas_parseexpr(); if (expr == -1) { *rc = -1; return NULL; } - struct ulas_expr *e = ulas_exprbufget(&ulas.exprs, expr); + e = ulas_exprbufget(&ulas.exprs, expr); if (!e) { ULASERR("unable to evaluate expression\n"); *rc = -1; @@ -2065,39 +2248,48 @@ const char *ulas_asmregstr(unsigned int reg) { int ulas_asminstr(char *dst, unsigned long max, const char **line, unsigned long n) { const char *start = *line; + int datread, rc = 0, i, res; + const short *dat; + char c[2]; + const short *tok; + const char *regstr; + const struct ulas_instr *instrs; + int written; + if (max < ULAS_INSTRBUF_MIN) { ULASPANIC("Instruction buffer is too small!"); return -1; } - const struct ulas_instr *instrs = ulas.arch.instrs; + instrs = ulas.arch.instrs; - int written = 0; + written = 0; while (instrs->name && written == 0) { + int exprres[ULAS_INSTRDATMAX]; + int expridx = 0; *line = start; if (ulas_tok(&ulas.tok, line, n) == -1) { ULASERR("Expected instruction\n"); return -1; } - // check for instruction name first + /* check for instruction name first */ if (strncmp(ulas.tok.buf, instrs->name, ulas.tok.maxlen) != 0) { goto skip; } - // expression results in order they appear - // TODO: this should probably become a union of sort to allow float - // expressions - int exprres[ULAS_INSTRDATMAX]; - int expridx = 0; + /* expression results in order they appear + * TODO: this should probably become a union of sort to allow float + * expressions + */ memset(&exprres, 0, sizeof(int) * ULAS_INSTRDATMAX); - // then check for each single token... - const short *tok = instrs->tokens; - int i = 0; + /* then check for each single token... */ + tok = instrs->tokens; + i = 0; while (tok[i]) { assert(i < ULAS_INSTRTOKMAX); - const char *regstr = ulas_asmregstr(tok[i]); + regstr = ulas_asmregstr(tok[i]); if (regstr) { if (ulas_tok(&ulas.tok, line, n) == -1) { goto skip; @@ -2109,8 +2301,8 @@ int ulas_asminstr(char *dst, unsigned long max, const char **line, } else if (tok[i] == ULAS_E8 || tok[i] == ULAS_E16 || tok[i] == ULAS_A8 || tok[i] == ULAS_A16) { assert(expridx < ULAS_INSTRDATMAX); - int rc = 0; - int res = ulas_intexpr(line, n, &rc); + rc = 0; + res = ulas_intexpr(line, n, &rc); exprres[expridx++] = res; if (rc == -1) { return -1; @@ -2132,7 +2324,8 @@ int ulas_asminstr(char *dst, unsigned long max, const char **line, goto skip; } - char c[2] = {(char)tok[i], '\0'}; + c[0] = (char)tok[i]; + c[1] = '\0'; if (strncmp(ulas.tok.buf, c, ulas.tok.maxlen) != 0) { goto skip; } @@ -2141,10 +2334,10 @@ int ulas_asminstr(char *dst, unsigned long max, const char **line, i++; } - // we are good to go! - int datread = 0; + /* we are good to go! */ + datread = 0; expridx = 0; - const short *dat = instrs->data; + dat = instrs->data; while (dat[datread]) { assert(datread < ULAS_INSTRDATMAX); assert(expridx < ULAS_INSTRDATMAX); @@ -2157,7 +2350,7 @@ int ulas_asminstr(char *dst, unsigned long max, const char **line, dst[written++] = (char)(val >> 8); dst[written] = (char)(val & 0xFF); } else { - // write 16-bit le values + /* write 16-bit le values */ dst[written++] = (char)(val & 0xFF); dst[written] = (char)(val >> 8); } @@ -2182,20 +2375,22 @@ int ulas_asminstr(char *dst, unsigned long max, const char **line, } void ulas_asmlst(const char *line, const char *outbuf, unsigned long n) { - // only write to dst on final pass + long i; + int outwrt; + const int pad = 10; + /* only write to dst on final pass */ if (ulaslstout && ulas.pass == ULAS_PASS_FINAL) { fprintf(ulaslstout, "%08X", ulas.address); - // always pad at least n bytes + /* always pad at least n bytes */ fputs(" ", ulaslstout); - const int pad = 10; - int outwrt = 0; + outwrt = 0; - for (long i = 0; i < n; i++) { + for (i = 0; i < n; i++) { outwrt += fprintf(ulaslstout, "%02x ", outbuf[i] & 0xFF); } - for (long i = outwrt; i < pad; i++) { + for (i = outwrt; i < pad; i++) { fputs(".", ulaslstout); } @@ -2204,20 +2399,21 @@ void ulas_asmlst(const char *line, const char *outbuf, unsigned long n) { } void ulas_asmout(FILE *dst, const char *outbuf, unsigned long n) { - // only write to dst on final pass + int i; + /* only write to dst on final pass */ if (ulas.pass == ULAS_PASS_FINAL) { fwrite(outbuf, 1, n, dst); } if (ulas.address < 0x14C) { - for (int i = 0; i < n; i++) { + for (i = 0; i < n; i++) { ulas.chksm = (char)(ulas.chksm - outbuf[i] - 1); } } } int ulas_asmdirbyte(FILE *dst, const char **line, unsigned long n, int *rc) { - // .db expr, expr, expr + /* .db expr, expr, expr */ struct ulas_tok t; int written = 0; memset(&t, 0, sizeof(t)); @@ -2235,7 +2431,7 @@ int ulas_asmdirbyte(FILE *dst, const char **line, unsigned long n, int *rc) { } } while (*rc != -1 && t.type == ','); - // go back one byte if the token was a comment + /* go back one byte if the token was a comment */ if (t.type == ULAS_TOK_COMMENT) { *line = *line - strlen(ulas.tok.buf); } @@ -2245,6 +2441,8 @@ int ulas_asmdirbyte(FILE *dst, const char **line, unsigned long n, int *rc) { int ulas_asmdirset(const char **line, unsigned long n, enum ulas_type t) { char name[ULAS_SYMNAMEMAX]; + struct ulas_tok tok; + int rc; ulas_tok(&ulas.tok, line, n); if (!ulas_isname(ulas.tok.buf, ulas.tok.maxlen)) { ULASERR("Unexpected token '%s'\n", ulas.tok.buf); @@ -2252,25 +2450,24 @@ int ulas_asmdirset(const char **line, unsigned long n, enum ulas_type t) { } strncpy(name, ulas.tok.buf, ULAS_SYMNAMEMAX); - // consume = + /* consume = */ ulas_tok(&ulas.tok, line, n); if (strncmp(ulas.tok.buf, "=", ulas.tok.maxlen) != 0) { ULASERR("Unexpected token '%s'. Expected '='\n", ulas.tok.buf); return -1; } - int rc = 0; + rc = 0; - union ulas_val val = {0}; switch (t) { case ULAS_INT: - val.intv = ulas_intexpr(line, n, &rc); + tok.val.intv = ulas_intexpr(line, n, &rc); if (rc == -1) { goto fail; } break; case ULAS_STR: - val.strv = ulas_strexpr(line, n, &rc); + tok.val.strv = ulas_strexpr(line, n, &rc); if (rc == -1) { goto fail; } @@ -2279,10 +2476,10 @@ int ulas_asmdirset(const char **line, unsigned long n, enum ulas_type t) { ULASERR("Unexpected type\n"); return -1; } - struct ulas_tok tok = {t, val}; + tok.type = t; if (ulas.pass == ULAS_PASS_FINAL) { - // only really define in final pass + /* only really define in final pass */ ulas_symbolset(name, -1, tok, 0); } fail: @@ -2290,22 +2487,27 @@ fail: } int ulas_asmdirset_lookup(const char **line, unsigned long n) { + enum ulas_type t; + int rc; + struct ulas_sym *found; + const char *start; + if (ulas.pass != ULAS_PASS_FINAL) { *line += strlen(*line); return 0; } - const char *start = *line; + start = *line; ulas_tok(&ulas.tok, line, n); - int rc = 0; - struct ulas_sym *found = ulas_symbolresolve(ulas.tok.buf, -1, &rc); + rc = 0; + found = ulas_symbolresolve(ulas.tok.buf, -1, &rc); if (rc == -1 || !found) { ULASERR("Unable to set symbol '%s'\n", ulas.tok.buf); return -1; } - enum ulas_type t = found->tok.type; + t = found->tok.type; *line = start; @@ -2313,10 +2515,10 @@ int ulas_asmdirset_lookup(const char **line, unsigned long n) { } int ulas_asmdirdef(const char **line, unsigned long n) { - // .set = name expr + /* .set = name expr */ - ulas_tok(&ulas.tok, line, n); enum ulas_type t = ULAS_INT; + ulas_tok(&ulas.tok, line, n); if (strncmp(ulas.tok.buf, "int", ulas.tok.maxlen) == 0) { t = ULAS_INT; } else if (strncmp(ulas.tok.buf, "str", ulas.tok.maxlen) == 0) { @@ -2331,6 +2533,9 @@ int ulas_asmdirdef(const char **line, unsigned long n) { int ulas_asmdirdefenum(const char **line, unsigned long n) { char name[ULAS_SYMNAMEMAX]; + struct ulas_tok tok; + int rc; + ulas_tok(&ulas.tok, line, n); if (!ulas_isname(ulas.tok.buf, ulas.tok.maxlen)) { ULASERR("Unexpected token '%s'\n", ulas.tok.buf); @@ -2338,48 +2543,48 @@ int ulas_asmdirdefenum(const char **line, unsigned long n) { } strncpy(name, ulas.tok.buf, ULAS_SYMNAMEMAX); - // consume , + /* consume , */ ulas_tok(&ulas.tok, line, n); if (strncmp(ulas.tok.buf, ",", ulas.tok.maxlen) != 0) { ULASERR("Unexpected token '%s'. Expected ','\n", ulas.tok.buf); return -1; } - union ulas_val val = {0}; - val.intv = ulas.enumv; + tok.val.intv = ulas.enumv; - int rc = 0; + rc = 0; ULAS_EVALEXPRS(ulas.enumv += ulas_intexpr(line, n, &rc)); if (rc == -1) { goto fail; } - struct ulas_tok tok = {ULAS_INT, val}; + tok.type = ULAS_INT; - // only really define in final pass + /* only really define in final pass */ ulas_symbolset(name, -1, tok, 1); fail: return rc; } int ulas_asmdirfill(FILE *dst, const char **line, unsigned long n, int *rc) { - // fill , - int written = 0; - + /* fill , */ + int written = 0, i, count; int ival = ulas_intexpr(line, n, rc); char val = (char)ival; + struct ulas_tok t; + if (*rc == -1) { return 0; } ulas_tok(&ulas.tok, line, n); - struct ulas_tok t = + t = ulas_totok(ulas.tok.buf, ulas_strnlen(ulas.tok.buf, ulas.tok.maxlen), rc); if (*rc == -1 || t.type != ',') { ULASERR("Expected ,\n"); return 0; } - int count = 0; + count = 0; ULAS_EVALEXPRS(count = ulas_intexpr(line, n, rc)); if (count < 0) { @@ -2391,7 +2596,7 @@ int ulas_asmdirfill(FILE *dst, const char **line, unsigned long n, int *rc) { return 0; } - for (int i = 0; i < count; i++) { + for (i = 0; i < count; i++) { ulas_asmout(dst, &val, 1); written++; } @@ -2400,9 +2605,11 @@ int ulas_asmdirfill(FILE *dst, const char **line, unsigned long n, int *rc) { } int ulas_asmdirstr(FILE *dst, const char **line, unsigned long n, int *rc) { - // .str expr, expr, expr + /* .str expr, expr, expr */ struct ulas_tok t; + int i; unsigned long written = 0; + unsigned long len; memset(&t, 0, sizeof(t)); do { @@ -2411,10 +2618,10 @@ int ulas_asmdirstr(FILE *dst, const char **line, unsigned long n, int *rc) { *rc = -1; return 0; } - unsigned long len = strlen(s); + len = strlen(s); - // apply char code map - for (int i = 0; i < len; i++) { + /* apply char code map */ + for (i = 0; i < len; i++) { s[i] = ulas.charcodemap[(int)s[i]]; } @@ -2434,16 +2641,17 @@ int ulas_asmdirstr(FILE *dst, const char **line, unsigned long n, int *rc) { int ulas_asmdirincbin(FILE *dst, const char **line, unsigned long n, int *rc) { char *path = ulas_strexpr(line, n, rc); char buf[256]; - memset(buf, 0, 256); unsigned long written = 0; + unsigned long read = 0; FILE *f = ulas_incpathfopen(path, "re"); + memset(buf, 0, 256); + if (!f) { *rc = -1; return 0; } - unsigned long read = 0; while ((read = fread(buf, 1, 256, f))) { ulas_asmout(dst, buf, read); written += read; @@ -2468,11 +2676,12 @@ int ulas_asmdirsetcharcode(const char **line, unsigned long n) { int rc = 0; int charcode = 0; int setto = 0; + struct ulas_tok t; ULAS_EVALEXPRS(charcode = ulas_intexpr(line, n, &rc)); charcode = charcode & 0xFF; ulas_tok(&ulas.tok, line, n); - struct ulas_tok t = + t = ulas_totok(ulas.tok.buf, ulas_strnlen(ulas.tok.buf, ulas.tok.maxlen), &rc); if (rc == -1 || t.type != '=') { @@ -2491,32 +2700,35 @@ int ulas_asmdirsetcharcode(const char **line, unsigned long n) { int ulas_asmdirchr(FILE *dst, const char **line, unsigned long n, int *rc) { unsigned char b[2] = {0, 0}; struct ulas_tok t; - memset(&t, 0, sizeof(t)); + int i, written; + unsigned long len; int bit = 7; + + memset(&t, 0, sizeof(t)); ulas_tok(&ulas.tok, line, n); - unsigned long len = strlen(ulas.tok.buf); + len = strlen(ulas.tok.buf); if (len > 8) { *rc = -1; ULASERR("chr input exceeds 8 pixels\n"); return 0; } - for (int i = 0; i < len; i++, bit--) { + for (i = 0; i < len; i++, bit--) { switch (ulas.tok.buf[i]) { case '0': - // 0 sets no bit + /* 0 sets no bit */ break; case '1': - // 1 sets 01 + /* 1 sets 01 */ b[1] |= (char)(1 << bit); break; case '2': - // 2 sets 10 + /* 2 sets 10 */ b[0] |= (char)(1 << bit); break; case '3': - // 3 sets 11 + /* 3 sets 11 */ b[0] |= (char)(1 << bit); b[1] |= (char)(1 << bit); break; @@ -2526,15 +2738,20 @@ int ulas_asmdirchr(FILE *dst, const char **line, unsigned long n, int *rc) { } } - int written = 2; + written = 2; ulas_asmout(dst, (char *)b, written); - // this always writes 2 bytes + /* this always writes 2 bytes */ return written; } int ulas_asmdirrep(FILE *dst, FILE *src, const char **line, unsigned long n) { char name[ULAS_SYMNAMEMAX]; + int i, step, repval, rc; + struct ulas_tok t; + unsigned long argline_len; + struct ulas_tok tok; + ulas_tok(&ulas.tok, line, n); if (!ulas_isname(ulas.tok.buf, ulas.tok.maxlen)) { ULASERR("Unexpected token '%s'\n", ulas.tok.buf); @@ -2542,31 +2759,31 @@ int ulas_asmdirrep(FILE *dst, FILE *src, const char **line, unsigned long n) { } strncpy(name, ulas.tok.buf, ULAS_SYMNAMEMAX); - // consume , + /* consume , */ ulas_tok(&ulas.tok, line, n); if (strncmp(ulas.tok.buf, ",", ulas.tok.maxlen) != 0) { ULASERR("Unexpected token '%s'. Expected ','\n", ulas.tok.buf); return -1; } - union ulas_val val = {0}; - val.intv = 0; - struct ulas_tok tok = {ULAS_INT, val}; + tok.type = ULAS_INT; + tok.val.intv = 0; + ulas_symbolset(name, ulas.scope, tok, 0); - int repval = 0; - int rc = 0; + repval = 0; + rc = 0; ULAS_EVALEXPRS(repval = ulas_intexpr(line, n, &rc)); ulas_tok(&ulas.tok, line, n); - struct ulas_tok t = + t = ulas_totok(ulas.tok.buf, ulas_strnlen(ulas.tok.buf, ulas.tok.maxlen), &rc); if (rc == -1 || t.type != ',') { ULASERR("Expected ,\n"); return 0; } - int step = 0; + step = 0; ULAS_EVALEXPRS(step = ulas_intexpr(line, n, &rc)); ulas_tok(&ulas.tok, line, n); t = ulas_totok(ulas.tok.buf, ulas_strnlen(ulas.tok.buf, ulas.tok.maxlen), &rc); @@ -2575,9 +2792,9 @@ int ulas_asmdirrep(FILE *dst, FILE *src, const char **line, unsigned long n) { return 0; } - unsigned long argline_len = strlen(*line); + argline_len = strlen(*line); - for (int i = 0; i < repval; i += step) { + for (i = 0; i < repval; i += step) { tok.val.intv = i; ulas_symbolset(name, ulas.scope, tok, 0); rc = ulas_asmline(dst, src, *line, argline_len); @@ -2609,34 +2826,39 @@ int ulas_asmdirbank(FILE *dst, FILE *src, const char **line, unsigned long n, } int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) { - // this buffer is written both to dst and to verbose output + /* this buffer is written both to dst and to verbose output */ char outbuf[ULAS_OUTBUFMAX]; - memset(outbuf, 0, ULAS_OUTBUFMAX); long towrite = 0; long other_writes = 0; - + long i; + int nextwrite; + struct ulas_tok label_tok; const char *start = line; const char *instr_start = start; int rc = 0; + + memset(outbuf, 0, ULAS_OUTBUFMAX); - // read the first token and decide + /* read the first token and decide */ ulas_tok(&ulas.tok, &line, n); - // we ignore empty lines or all comments lines + /* we ignore empty lines or all comments lines */ if (ulas_istokend(&ulas.tok)) { ulas_asmlst(start, outbuf, towrite); return 0; } - // is it a label? + /* is it a label? */ if (ulas_islabelname(ulas.tok.buf, strlen(ulas.tok.buf))) { instr_start = line; - struct ulas_tok label_tok = {ULAS_INT, {(int)ulas.address}}; + label_tok.type = ULAS_INT; + label_tok.val.intv = (int)ulas.address; + if (ulas_symbolset(ulas.tok.buf, -1, label_tok, 1) == -1) { return -1; } ulas_tok(&ulas.tok, &line, n); - // is next token empty? + /* is next token empty? */ if (ulas_istokend(&ulas.tok)) { ulas_asmlst(start, outbuf, towrite); return 0; @@ -2668,7 +2890,7 @@ int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) { enum ulas_asmdir dir = ULAS_ASMDIR_NONE; - for (long i = 0; dirstrs[i]; i++) { + for (i = 0; dirstrs[i]; i++) { if (strncmp(ulas.tok.buf, dirstrs[i], n) == 0) { dir = dirs[i]; break; @@ -2688,7 +2910,7 @@ int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) { break; } case ULAS_ASMDIR_DEF: - // only do this in the final pass + /* only do this in the final pass */ rc = ulas_asmdirdef(&line, n); break; case ULAS_ASMDIR_SET: @@ -2751,18 +2973,19 @@ int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) { ulas.prev_scope = 0; break; case ULAS_ASMDIR_PAD: - // TODO: pad is the same as .fill n, $ - n + /* TODO: pad is the same as .fill n, $ - n */ case ULAS_ASMDIR_NONE: ULASPANIC("asmdir not implemented\n"); break; } } else { - // is regular line in form of [label:] instruction ; comment - // start over for the next step... + /* is regular line in form of [label:] instruction ; comment + * start over for the next step... + */ line = instr_start; - int nextwrite = ulas_asminstr(outbuf, ULAS_OUTBUFMAX, &line, n); + nextwrite = ulas_asminstr(outbuf, ULAS_OUTBUFMAX, &line, n); if (nextwrite == -1) { ULASERR("Unable to assemble instruction\n"); rc = -1; @@ -2771,8 +2994,9 @@ int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) { towrite += nextwrite; } - // check for trailing - // but only if its not a comment + /* check for trailing + * but only if its not a comment + */ if (ulas_tok(&ulas.tok, &line, n) > 0) { if (!ulas_istokend(&ulas.tok)) { ULASERR("Trailing token '%s'\n", ulas.tok.buf); @@ -2805,10 +3029,10 @@ int ulas_asmnext(FILE *dst, FILE *src, char *buf, int n) { int ulas_asm(FILE *dst, FILE *src) { char buf[ULAS_LINEMAX]; - memset(buf, 0, ULAS_LINEMAX); int rc = 0; + memset(buf, 0, ULAS_LINEMAX); - // preproc + /* preproc */ while ((rc = ulas_asmnext(dst, src, buf, ULAS_LINEMAX)) > 0) { } diff --git a/src/ulas.h b/src/ulas.h index c0bd764..1460e9b 100644 --- a/src/ulas.h +++ b/src/ulas.h @@ -9,10 +9,10 @@ #define ULAS_NAME "ulas" #define ULAS_VER "0.0.1" -// args without value +/* args without value */ #define ULAS_OPTS "hvVpdA" -// args with value +/* args with value */ #define ULAS_OPTS_ARG "o:l:s:I:w:a:S:D:" #define ULAS_HELP(a, desc) printf("\t-%s\t%s\n", (a), desc); @@ -26,7 +26,7 @@ extern unsigned long incpathslen; extern char *defs[ULAS_DEFSMAX]; extern unsigned long defslen; -// if this is used as a path use stdin or stdout instead +/* if this is used as a path use stdin or stdout instead */ #define ULAS_STDFILEPATH "-" #define ULAS_PATHSEP "/" @@ -43,7 +43,7 @@ extern unsigned long defslen; #define MAX(x, y) (((x) > (y)) ? (x) : (y)) #define MIN(x, y) (((x) < (y)) ? (x) : (y)) -// Config variables +/* Config variables */ #define ULAS_CFG_FMT_GREEN "\x1B[32m" #define ULAS_CFG_FMT_YELLOW "\x1B[33m" #define ULAS_CFG_FMT_RED "\x1B[31m" @@ -69,7 +69,7 @@ extern unsigned long defslen; #define ULAS_ASMSTR_PAD ".pad" #define ULAS_ASMSTR_INCBIN ".incbin" #define ULAS_ASMSTR_DEF ".def" -// TODO: chksm should only work on sm83 +/* TODO: chksm should only work on sm83 */ #define ULAS_ASMSTR_CHKSM ".chksm" #define ULAS_ASMSTR_ADV ".adv" #define ULAS_ASMSTR_SET_ENUM_DEF ".se" @@ -82,11 +82,11 @@ extern unsigned long defslen; #define ULAS_ASMSTR_BEGIN_SCOPE ".beginscope" #define ULAS_ASMSTR_END_SCOPE ".endscope" -// configurable tokens +/* configurable tokens */ #define ULAS_TOK_COMMENT ';' -// start of as directives such as .org +/* start of as directives such as .org */ #define ULAS_TOK_ASMDIR_BEGIN '.' -// start of preprocessor directives such as #define or #include +/* start of preprocessor directives such as #define or #include */ #define ULAS_TOK_PREPROC_BEGIN '#' #define ULAS_TOK_SCOPED_SYMBOL_BEGIN '@' #define ULAS_TOK_CURRENT_ADDR '$' @@ -106,17 +106,18 @@ extern unsigned long defslen; } #define ULASWARNLEVEL(level) (ulascfg.warn_level & (level)) -// format macros +/* format macros */ #define ULAS_FMT(f, fmt) \ if (isatty(fileno(f)) && ulascfg.color) { \ fprintf((f), "%s", (fmt)); \ } -// this is a bit of a hack to get the int expression to evaluate anyway -// because expressions only work in the final pass -// Beware that this can cause unforseen writes to the file and should really -// only be uesd to evalulate an expression that needs to be evaled during -// all passes and nothing else! +/* this is a bit of a hack to get the int expression to evaluate anyway + * because expressions only work in the final pass + * Beware that this can cause unforseen writes to the file and should really + * only be uesd to evalulate an expression that needs to be evaled during + * all passes and nothing else! + */ #define ULAS_EVALEXPRS(...) \ { \ int pass = ulas.pass; \ @@ -129,15 +130,15 @@ extern unsigned long defslen; * Output target files */ -// input file for source reader +/* input file for source reader */ extern FILE *ulasin; -// source code output target +/* source code output target */ extern FILE *ulasout; -// error output target +/* error output target */ extern FILE *ulaserr; -// assembly listing output +/* assembly listing output */ extern FILE *ulaslstout; -// symbol list output +/* symbol list output */ extern FILE *ulassymout; struct ulas_expr; @@ -148,7 +149,7 @@ enum ulas_warm { ULAS_WARN_OVERFLOW = 1, ULAS_WARN_ALL = 0x7FFFFFFF }; enum ulas_symfmt { ULAS_SYM_FMT_DEFAULT, ULAS_SYM_FMT_SYM, ULAS_SYM_FMT_MLB }; struct ulas_config { - // argv represents file names + /* argv represents file names */ char **argv; int argc; @@ -166,13 +167,13 @@ struct ulas_config { unsigned int print_addrs; - // all include search paths + /* all include search paths */ char **incpaths; unsigned int incpathslen; enum ulas_warm warn_level; - // initial defs for preproc + /* initial defs for preproc */ char **defs; unsigned int defslen; }; @@ -189,10 +190,11 @@ struct ulas_str { * Tokens */ -// any token before 256 is just the literal char value -// primitive data types -// FIXME: split up types and operators -// TODO:add float expressions +/* any token before 256 is just the literal char value + * primitive data types + * FIXME: split up types and operators + * TODO:add float expressions + */ enum ulas_type { ULAS_SYMBOL = 256, ULAS_INT, @@ -202,10 +204,10 @@ enum ulas_type { ULAS_GTEQ, ULAS_LTEQ, ULAS_RSHIFT, - ULAS_LSHIFT, + ULAS_LSHIFT }; -// data type value +/* data type value */ union ulas_val { int intv; char *strv; @@ -216,14 +218,14 @@ struct ulas_tok { union ulas_val val; }; -// the token buffer is a dynamically allocated token store +/* the token buffer is a dynamically allocated token store */ struct ulas_tokbuf { struct ulas_tok *buf; long len; long maxlen; }; -// the expression buffer hold expression buffers +/* the expression buffer hold expression buffers */ struct ulas_exprbuf { struct ulas_expr *buf; unsigned long len; @@ -240,7 +242,7 @@ struct ulas_exprbuf { */ enum ulas_pass { ULAS_PASS_FINAL = 0, - ULAS_PASS_RESOLVE = 1, + ULAS_PASS_RESOLVE = 1 }; /** @@ -250,15 +252,16 @@ enum ulas_pass { struct ulas_sym { char *name; struct ulas_tok tok; - // this label's scope index + /* this label's scope index */ int scope; - // last pass this was defined in... - // a symbol may only be defined once per pass/scope + /* last pass this was defined in... + * a symbol may only be defined once per pass/scope + */ enum ulas_pass lastdefin; int constant; }; -// holds all currently defned symbols +/* holds all currently defned symbols */ struct ulas_symbuf { struct ulas_sym *buf; unsigned long len; @@ -281,9 +284,9 @@ struct ulas_preproc { int exp_depth; - // macro parameter buffers + /* macro parameter buffers */ struct ulas_str macroparam[ULAS_MACROPARAMMAX]; - // macro expansion buffer + /* macro expansion buffer */ struct ulas_str macrobuf; }; @@ -293,13 +296,13 @@ struct ulas { char *initial_filename; unsigned long line; - // count how many passes we have completed so far + /* count how many passes we have completed so far */ int pass; - // holds the current token + /* holds the current token */ struct ulas_str tok; - // current token stream + /* current token stream */ struct ulas_tokbuf toks; struct ulas_exprbuf exprs; struct ulas_symbuf syms; @@ -307,28 +310,32 @@ struct ulas { unsigned int address; int enumv; - // current scope index - // each global-label increments the scope + /* current scope index + * each global-label increments the scope + */ int scope; - // temporary storage for .beginscope - // and .endscope + /* temporary storage for .beginscope + * and .endscope + */ int prev_scope; - // internal counter - // used whenever a new unique number might be needed + /* internal counter + * used whenever a new unique number might be needed + */ int icntr; char chksm; - // character code map - // defaults to just x=x mapping - // but cna be set with a directive + /* character code map + * defaults to just x=x mapping + * but cna be set with a directive + */ char charcodemap[ULAS_CHARCODEMAPLEN]; char section[ULAS_SECTIONMAX]; - // where was the section defined? + /* where was the section defined? */ unsigned int section_address; - // active bank + /* active bank */ unsigned int bank; struct ulas_arch arch; @@ -338,8 +345,9 @@ extern struct ulas ulas; int ulas_icntr(void); -// init the next pass -// by resetting some values +/* init the next pass + * by resetting some values + */ void ulas_nextpass(void); /** @@ -348,29 +356,30 @@ void ulas_nextpass(void); enum ulas_ppdirs { ULAS_PPDIR_NONE = 1, - // #define name value + /* #define name value */ ULAS_PPDIR_DEF, - // #undefine name + /* #undefine name */ ULAS_PPDIR_UNDEF, - // #macro name - // value - // value + /* #macro name + * value + * value + */ ULAS_PPDIR_MACRO, - // #endmacro + /* #endmacro */ ULAS_PPDIR_ENDMACRO, - // ifdef name + /* ifdef name */ ULAS_PPDIR_IFDEF, - // ifndef name + /* ifndef name */ ULAS_PPDIR_IFNDEF, - // endif + /* endif */ ULAS_PPDIR_ENDIF, - // include "filename" - ULAS_PPDIR_INCLUDE, + /* include "filename" */ + ULAS_PPDIR_INCLUDE }; enum ulas_ppdefs { ULAS_PPDEF, - ULAS_PPMACRO, + ULAS_PPMACRO }; struct ulas_ppdef { @@ -408,8 +417,9 @@ struct ulas_expprim { }; struct ulas_expgrp { - // points to the first expression - // in this group + /* points to the first expression + * in this group + */ long head; }; @@ -430,76 +440,87 @@ struct ulas_expr { */ enum ulas_asmdir { ULAS_ASMDIR_NONE = 0, - // .org
+ /* .org
*/ ULAS_ASMDIR_ORG, - // .set name = + /* .set name = */ ULAS_ASMDIR_SET, - // .byte , , , ... + /* .byte , , , ... */ ULAS_ASMDIR_BYTE, - // .str "String value" + /* .str "String value" */ ULAS_ASMDIR_STR, - // .fill , n + /* .fill , n */ ULAS_ASMDIR_FILL, - // .pad , + /* .pad , */ ULAS_ASMDIR_PAD, - // .incbin + /* .incbin */ ULAS_ASMDIR_INCBIN, - // .def name = value + /* .def name = value */ ULAS_ASMDIR_DEF, - // inserts checksum into rom + /* inserts checksum into rom */ ULAS_ASMDIR_CHKSM, - // .adv - // advance .org by n bytes without writing to rom + /* .adv + * advance .org by n bytes without writing to rom + */ ULAS_ASMDIR_ADV, - // .setenum - // sets the internal _ENUM counter + /* .setenum + * sets the internal _ENUM counter + */ ULAS_ASMDIR_SET_ENUM_DEF, - // .de - // acts like .def but sets the value to the current _ENUM counter - // and increments it by size + /* .de + * acts like .def but sets the value to the current _ENUM counter + * and increments it by size + */ ULAS_ASMDIR_DEFINE_ENUM, - // .scc ''= - // allows to set custom encoding for char codes - // when using .str + /* .scc ''= + * allows to set custom encoding for char codes + * when using .str + */ ULAS_ASMDIR_SETCHRCODE, - // .chr 01230123 - // allows defining - // chr (tile) data from 0-3 - // for each possible color - // it requires up to 8 integer expressions between 0 and 3 + /* .chr 01230123 + * allows defining + * chr (tile) data from 0-3 + * for each possible color + * it requires up to 8 integer expressions between 0 and 3 + */ ULAS_ASMDIR_CHR, - // .rep , , - // repeats a line n times + /* .rep , , + * repeats a line n times + */ ULAS_ASMDIR_REP, - // .section - // set the current section + /* .section + * set the current section + */ ULAS_ASMDIR_SECTION, - // .bank - // sets the current bank number + /* .bank + * sets the current bank number + */ ULAS_ASMDIR_BANK, - // .beginscope - // incements scope index by 1 + /* .beginscope + * incements scope index by 1 + */ ULAS_ASMDIR_BEGIN_SCOPE, - // .endscope - // decrements scope index by 1 - ULAS_ASMDIR_END_SCOPE, + /* .endscope + * decrements scope index by 1 + */ + ULAS_ASMDIR_END_SCOPE }; #define ULAS_INSTRTOKMAX 16 #define ULAS_INSTRDATMAX 16 -// entry for lut instruction parser -// in the form of: name token token token token -// tokens can either be literal chars, or any of the special tokens like an -// asmreg or e8, e16 -// if toks value is 0 the list ends -// if data value is 0 the list ends -// if toks is E8 or E16 an expression is evaluated -// id data is E8 or E16 the previous expression is inserted +/* entry for lut instruction parser + * in the form of: name token token token token + * tokens can either be literal chars, or any of the special tokens like an + * asmreg or e8, e16 + * if toks value is 0 the list ends + * if data value is 0 the list ends + * if toks is E8 or E16 an expression is evaluated + * id data is E8 or E16 the previous expression is inserted + */ struct ulas_instr { char *name; short tokens[ULAS_INSTRTOKMAX]; @@ -516,37 +537,41 @@ FILE *ulas_incpathfopen(const char *path, const char *mode); int ulas_main(struct ulas_config cfg); -// resolve a symbol until an actual literal token (str, int) is found -// returns NULL if the symbol cannot be resolved -// returns -1 if any flagged symbol was not found -// if flagged symbols remain unresolved (e.g. global or locals) rc is set to the -// respective flag value +/* resolve a symbol until an actual literal token (str, int) is found + * returns NULL if the symbol cannot be resolved + * returns -1 if any flagged symbol was not found + * if flagged symbols remain unresolved (e.g. global or locals) rc is set to the + * respective flag value + */ struct ulas_sym *ulas_symbolresolve(const char *name, int scope, int *rc); -// define a new symbol -// scope 0 indicates global scope. a scope of -1 instructs -// the function to auto-detect the scope -// if a label starts with @ the current scope is used, otherwise 0 is used -// if the symbol already exists -1 is returned +/* define a new symbol + * scope 0 indicates global scope. a scope of -1 instructs + * the function to auto-detect the scope + * if a label starts with @ the current scope is used, otherwise 0 is used + * if the symbol already exists -1 is returned + */ int ulas_symbolset(const char *cname, int scope, struct ulas_tok tok, int constant); int ulas_symbolout(FILE *dst, struct ulas_sym *s); -// tokenisze according to pre-defined rules -// returns the amount of bytes of line that were -// consumed or -1 on error -// returns 0 when no more tokens can be read -// writes the token to dst string buffer +/* tokenisze according to pre-defined rules + * returns the amount of bytes of line that were + * consumed or -1 on error + * returns 0 when no more tokens can be read + * writes the token to dst string buffer + */ int ulas_tok(struct ulas_str *dst, const char **out_line, unsigned long n); -// converts a token string to a token struct -// this is only useful if we do not require the token literal -// but rather can be used to store a slimmer list of token types -// and literal values +/* converts a token string to a token struct + * this is only useful if we do not require the token literal + * but rather can be used to store a slimmer list of token types + * and literal values + */ struct ulas_tok ulas_totok(char *buf, unsigned long n, int *rc); -// tokenize until a terminator char is reached +/* tokenize until a terminator char is reached */ int ulas_tokuntil(struct ulas_str *dst, char c, const char **out_line, unsigned long n); @@ -554,13 +579,13 @@ int ulas_tokuntil(struct ulas_str *dst, char c, const char **out_line, * str */ -// create a string buffer +/* create a string buffer */ struct ulas_str ulas_str(unsigned long n); -// ensure the string buffer is at least n bytes long, if not realloc +/* ensure the string buffer is at least n bytes long, if not realloc */ struct ulas_str ulas_strensr(struct ulas_str *s, unsigned long maxlen); -// require at least n bytes + the current strlen +/* require at least n bytes + the current strlen */ struct ulas_str ulas_strreq(struct ulas_str *s, unsigned long n); void ulas_strfree(struct ulas_str *s); @@ -580,27 +605,29 @@ void ulas_preprocfree(struct ulas_preproc *pp); */ int ulas_preproc(FILE *dst, FILE *src); -// reads the next line -// returns 0 if no more data can be read -// > 0 if data was read (enum ulas_ppdirs id) -// -1 on error -// it also places the processed line into pp->line.buf -// note that this is overwritten by every call! +/* reads the next line + * returns 0 if no more data can be read + * > 0 if data was read (enum ulas_ppdirs id) + * -1 on error + * it also places the processed line into pp->line.buf + * note that this is overwritten by every call! + */ 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 -// Warning: calling this recursively may clobber pp buffers and those should -// not be used in the caller after recursvion finishes! -// or initialize a new preproc object if the old state is important! -// (preprocinit and preprocfree) +/* process a line of preproc + * returns: 0 when a regular line was read + * enum ulas_ppdirs id for preprocessor directive + * -1 on error + * Warning: calling this recursively may clobber pp buffers and those should + * not be used in the caller after recursvion finishes! + * or initialize a new preproc object if the old state is important! + * (preprocinit and preprocfree) + */ int ulas_preprocline(struct ulas_preproc *pp, FILE *dst, FILE *src, const char *raw_line, unsigned long n); -// expand preproc into dst line +/* expand preproc into dst line */ char *ulas_preprocexpand(struct ulas_preproc *pp, const char *raw_line, unsigned long *n); @@ -608,18 +635,20 @@ char *ulas_preprocexpand(struct ulas_preproc *pp, const char *raw_line, * Literals, tokens and expressions */ -// convert literal to its int value -// retunrs -1 on error, 0 on success and 1 if there is an unresolved symbol +/* convert literal to its int value + * retunrs -1 on error, 0 on success and 1 if there is an unresolved symbol + */ int ulas_valint(struct ulas_tok *lit, int *rc); -// convert literal to its char value +/* convert literal to its char value */ char *ulas_valstr(struct ulas_tok *lit, int *rc); struct ulas_tokbuf ulas_tokbuf(void); -// TODO: maybe we could macro all those buf functions into a single more -// "geneirc" thing... +/* TODO: maybe we could macro all those buf functions into a single more + * "geneirc" thing... + */ -// pushes new token, returns newly added index +/* pushes new token, returns newly added index */ int ulas_tokbufpush(struct ulas_tokbuf *tb, struct ulas_tok tok); struct ulas_tok *ulas_tokbufget(struct ulas_tokbuf *tb, int i); void ulas_tokbufclear(struct ulas_tokbuf *tb); @@ -628,7 +657,7 @@ void ulas_tokfree(struct ulas_tok *t); struct ulas_exprbuf ulas_exprbuf(void); -// pushes new expression, returns newly added index +/* pushes new expression, returns newly added index */ int ulas_exprbufpush(struct ulas_exprbuf *eb, struct ulas_expr expr); struct ulas_expr *ulas_exprbufget(struct ulas_exprbuf *eb, int i); void ulas_exprbufclear(struct ulas_exprbuf *eb); @@ -644,14 +673,16 @@ void ulas_symbuffree(struct ulas_symbuf *sb); * Assembly step */ -// assembles an instruction, writes bytes into dst -// returns bytes written or -1 on error +/* assembles an instruction, writes bytes into dst + * returns bytes written or -1 on error + */ int ulas_asminstr(char *dst, unsigned long max, const char **line, unsigned long n); -// returns 0 if no more data can be read -// > 0 if data was read -// -1 on error +/* returns 0 if no more data can be read + * > 0 if data was read + * -1 on error + */ int ulas_asmnext(FILE *dst, FILE *src, char *buf, int n); int ulas_asm(FILE *dst, FILE *src); int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n); diff --git a/src/uldas.c b/src/uldas.c index d526dc5..6f76c5e 100644 --- a/src/uldas.c +++ b/src/uldas.c @@ -15,10 +15,14 @@ void ulas_dasm_print_header(FILE *dst) { fprintf(dst, ".org 0x%x\n", ulas.address); } -// this function assumes the bounds checks -// for buf have already been done and will not check anymore! +/* + * this function assumes the bounds checks + * for buf have already been done and will not check anymore! +*/ void ulas_dasm_instr_fout(FILE *src, FILE *dst, const struct ulas_instr *instr, const char *buf, unsigned long read) { + int i; + unsigned int bi; if (ulas.pass != ULAS_PASS_FINAL) { return; } @@ -26,8 +30,8 @@ void ulas_dasm_instr_fout(FILE *src, FILE *dst, const struct ulas_instr *instr, ulas_dasm_print_addr(dst); fprintf(dst, " %s ", instr->name); - unsigned int bi = ulas_arch_opcode_len(buf, read); - for (int i = 0; instr->tokens[i]; i++) { + bi = ulas_arch_opcode_len(buf, read); + for (i = 0; instr->tokens[i]; i++) { int dat = instr->tokens[i]; switch (dat) { case ULAS_E8: @@ -52,7 +56,7 @@ void ulas_dasm_instr_fout(FILE *src, FILE *dst, const struct ulas_instr *instr, fprintf(dst, "%s", reg); } else { fprintf(dst, "%c", dat); - // just for formatting purposes + /* just for formatting purposes */ if (dat == ',') { fprintf(dst, " "); } @@ -65,7 +69,7 @@ void ulas_dasm_instr_fout(FILE *src, FILE *dst, const struct ulas_instr *instr, fprintf(dst, "\n"); } -// fallback if no instruction was found +/* fallback if no instruction was found */ void ulas_dasm_db_fout(FILE *src, FILE *dst, const char *buf, unsigned long read) { ulas.address++; @@ -77,21 +81,24 @@ void ulas_dasm_db_fout(FILE *src, FILE *dst, const char *buf, fprintf(dst, ".db 0x%x\n", buf[0] & 0xFF); } -// returns > 1 if instruction was found, and 0 if not -// the integer returned is the amount of bytes this instruction consumed +/* + * returns > 1 if instruction was found, and 0 if not + * the integer returned is the amount of bytes this instruction consumed + */ int ulas_dasm_instr_check(FILE *src, FILE *dst, const struct ulas_instr *instr, const char *buf, unsigned long read) { int i = 0; - int bi = 0; // current buffer index - // test all instruction's contents + int bi = 0; /* current buffer index */ + /* test all instruction's contents */ for (i = 0; instr->data[i]; i++) { unsigned int dat = instr->data[i]; if (dat == ULAS_DATZERO) { dat = 0; } - // do we even have enough data? - // this is a general check for 1 byte + /* do we even have enough data? + * this is a general check for 1 byte + */ if (bi + 1 >= read) { goto fail; } @@ -99,12 +106,12 @@ int ulas_dasm_instr_check(FILE *src, FILE *dst, const struct ulas_instr *instr, switch (dat) { case ULAS_E8: case ULAS_A8: - // just ignore it + /* just ignore it */ bi++; break; case ULAS_E16: case ULAS_A16: - // need 2 bytes here + /* need 2 bytes here */ bi += 2; if (bi > read) { goto fail; @@ -128,30 +135,34 @@ fail: #define ULAS_DASM_BUFMAX 4 -// dasm the next instruction -// if there are no more bytes to be read, return 0 -// on error return -1 -// otherwise return 1 +/* dasm the next instruction + * if there are no more bytes to be read, return 0 + * on error return -1 + * otherwise return 1 + */ int ulas_dasm_next(FILE *src, FILE *dst) { + int i; long srctell = ftell(src); - // read n bytes (as many as in instruction) + /* read n bytes (as many as in instruction) */ char buf[ULAS_DASM_BUFMAX]; - memset(buf, 0, ULAS_DASM_BUFMAX); unsigned long read = 0; + memset(buf, 0, ULAS_DASM_BUFMAX); - // find the correct instructions - // needs to match every byte! - // first read max outbuf + /* find the correct instructions + * needs to match every byte! + * first read max outbuf + */ read = fread(buf, 1, ULAS_DASM_BUFMAX, src); if (read == 0) { return 0; } - // now find the instruction that matches all - // read bytes - // -> then reset src's read buffer to the srctell + actual instruction's - // length if nothing matches simply output a .db for the first byte and return - for (int i = 0; ulas.arch.instrs[i].name; i++) { + /* now find the instruction that matches all + * read bytes + * -> then reset src's read buffer to the srctell + actual instruction's + * length if nothing matches simply output a .db for the first byte and return + */ + for (i = 0; ulas.arch.instrs[i].name; i++) { const struct ulas_instr *instr = &ulas.arch.instrs[i]; int consumed = ulas_dasm_instr_check(src, dst, instr, buf, read); @@ -166,14 +177,15 @@ int ulas_dasm_next(FILE *src, FILE *dst) { return 1; } -// TODO: implement label generation +/* TODO: implement label generation */ int ulas_dasm(FILE *src, FILE *dst) { - // pass 1: run and collect labels - // pass 2: run and output to file + /* pass 1: run and collect labels + * pass 2: run and output to file + */ + int rc = 0; ulas_dasm_print_header(dst); - int rc = 0; while ((rc = ulas_dasm_next(src, dst)) > 0) { if (rc == -1) { return -1; diff --git a/src/uldas.h b/src/uldas.h index 0e9ed00..4948e8e 100644 --- a/src/uldas.h +++ b/src/uldas.h @@ -7,7 +7,7 @@ #include "ulas.h" #include "archs.h" -// Disassemble a file based on the current arch +/* Disassemble a file based on the current arch */ int ulas_dasm(FILE *src, FILE *dst); #endif -- 2.30.2