Mercurial > hg > index.cgi
diff lwasm/pseudo.c @ 564:87f904e2b304
Add offset and length operands (optional) to includebin
This addition is based on a patch from Tim Lindner <tlindner@macmess.org>.
While the original logic of the patch was not quite correct, the basic idea
is. So with some edits to the logic, the feature goes in.
author | William Astle <lost@l-w.ca> |
---|---|
date | Thu, 21 Dec 2023 22:14:25 -0700 |
parents | a6a9d46f071f |
children | d746a52e00db |
line wrap: on
line diff
--- a/lwasm/pseudo.c Fri Dec 01 21:16:54 2023 -0700 +++ b/lwasm/pseudo.c Thu Dec 21 22:14:25 2023 -0700 @@ -1482,7 +1482,8 @@ FILE *fp; long flen; char *rfn; - + lw_expr_t e, e1; + if (!**p) { lwasm_register_error(as, l, E_FILENAME_MISSING); @@ -1522,12 +1523,94 @@ fclose(fp); l -> len = flen; + + if (**p == ',') + { + (*p)++; + e = lwasm_parse_expr(as, p); + + if (e) + lwasm_save_expr(l, 0, e); + + if (**p == ',') + { + (*p)++; + e1 = lwasm_parse_expr(as, p); + + if (e1) + lwasm_save_expr(l, 1, e1); + } + } +} + +RESOLVEFUNC(pseudo_resolve_includebin) +{ + lw_expr_t e, e1, n; + int i = 0, i1; + + e = lwasm_fetch_expr(l, 0); + e1 = lwasm_fetch_expr(l, 1); + + // if offset and/or length specified, make sure they've resolved + // before we do anything + if (e && !lw_expr_istype(e, lw_expr_type_int)) + return; + if (e1 && !lwexpr_istype(e, lw_expr_type_int)) + return; + if (e != NULL) + { + i = lw_expr_intval(e); + + if (i < 0) + i = l -> len + i; + } + + i1 = l -> len - i; + + e1 = lwasm_fetch_expr(l, 1); + + if (e1 != NULL) + { + i1 = lw_expr_intval(e1); + } + + if( i < 0 ) + { + /* starting before file */ + lwasm_register_error(as, l, E_INCLUDEBIN_ILL_START); + return; + } + + if (i > l -> len) + { + /* starts past end of file */ + lwasm_register_error(as, l, E_INCLUDEBIN_ILL_START); + return; + } + + if (i1 < 0) + { + /* length is negative */ + lwasm_register_error(as, l, E_INCLUDEBIN_ILL_LENGTH); + return; + } + + if (i + i1 > l -> len) + { + /* read past end of file */ + lwasm_register_error(as, l, E_INCLUDEBIN_ILL_LENGTH); + return; + } + + + l -> lint = i; // pass forward offset + l -> len = i1; } EMITFUNC(pseudo_emit_includebin) { FILE *fp; - int c; + int c, i; fp = fopen(l -> lstr, "rb"); if (!fp) @@ -1536,7 +1619,10 @@ return; } - for (;;) + // apply the specified offset + fseek(fp, l -> lint, SEEK_SET); + + for (i=0; i < l -> len; i++) { c = fgetc(fp); if (c == EOF)