Mercurial > hg > index.cgi
comparison 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 |
comparison
equal
deleted
inserted
replaced
563:8c6c3363e18e | 564:87f904e2b304 |
---|---|
1480 char *fn, *p2; | 1480 char *fn, *p2; |
1481 int delim = 0; | 1481 int delim = 0; |
1482 FILE *fp; | 1482 FILE *fp; |
1483 long flen; | 1483 long flen; |
1484 char *rfn; | 1484 char *rfn; |
1485 | 1485 lw_expr_t e, e1; |
1486 | |
1486 if (!**p) | 1487 if (!**p) |
1487 { | 1488 { |
1488 lwasm_register_error(as, l, E_FILENAME_MISSING); | 1489 lwasm_register_error(as, l, E_FILENAME_MISSING); |
1489 return; | 1490 return; |
1490 } | 1491 } |
1520 fseek(fp, 0, SEEK_END); | 1521 fseek(fp, 0, SEEK_END); |
1521 flen = ftell(fp); | 1522 flen = ftell(fp); |
1522 fclose(fp); | 1523 fclose(fp); |
1523 | 1524 |
1524 l -> len = flen; | 1525 l -> len = flen; |
1526 | |
1527 if (**p == ',') | |
1528 { | |
1529 (*p)++; | |
1530 e = lwasm_parse_expr(as, p); | |
1531 | |
1532 if (e) | |
1533 lwasm_save_expr(l, 0, e); | |
1534 | |
1535 if (**p == ',') | |
1536 { | |
1537 (*p)++; | |
1538 e1 = lwasm_parse_expr(as, p); | |
1539 | |
1540 if (e1) | |
1541 lwasm_save_expr(l, 1, e1); | |
1542 } | |
1543 } | |
1544 } | |
1545 | |
1546 RESOLVEFUNC(pseudo_resolve_includebin) | |
1547 { | |
1548 lw_expr_t e, e1, n; | |
1549 int i = 0, i1; | |
1550 | |
1551 e = lwasm_fetch_expr(l, 0); | |
1552 e1 = lwasm_fetch_expr(l, 1); | |
1553 | |
1554 // if offset and/or length specified, make sure they've resolved | |
1555 // before we do anything | |
1556 if (e && !lw_expr_istype(e, lw_expr_type_int)) | |
1557 return; | |
1558 if (e1 && !lwexpr_istype(e, lw_expr_type_int)) | |
1559 return; | |
1560 if (e != NULL) | |
1561 { | |
1562 i = lw_expr_intval(e); | |
1563 | |
1564 if (i < 0) | |
1565 i = l -> len + i; | |
1566 } | |
1567 | |
1568 i1 = l -> len - i; | |
1569 | |
1570 e1 = lwasm_fetch_expr(l, 1); | |
1571 | |
1572 if (e1 != NULL) | |
1573 { | |
1574 i1 = lw_expr_intval(e1); | |
1575 } | |
1576 | |
1577 if( i < 0 ) | |
1578 { | |
1579 /* starting before file */ | |
1580 lwasm_register_error(as, l, E_INCLUDEBIN_ILL_START); | |
1581 return; | |
1582 } | |
1583 | |
1584 if (i > l -> len) | |
1585 { | |
1586 /* starts past end of file */ | |
1587 lwasm_register_error(as, l, E_INCLUDEBIN_ILL_START); | |
1588 return; | |
1589 } | |
1590 | |
1591 if (i1 < 0) | |
1592 { | |
1593 /* length is negative */ | |
1594 lwasm_register_error(as, l, E_INCLUDEBIN_ILL_LENGTH); | |
1595 return; | |
1596 } | |
1597 | |
1598 if (i + i1 > l -> len) | |
1599 { | |
1600 /* read past end of file */ | |
1601 lwasm_register_error(as, l, E_INCLUDEBIN_ILL_LENGTH); | |
1602 return; | |
1603 } | |
1604 | |
1605 | |
1606 l -> lint = i; // pass forward offset | |
1607 l -> len = i1; | |
1525 } | 1608 } |
1526 | 1609 |
1527 EMITFUNC(pseudo_emit_includebin) | 1610 EMITFUNC(pseudo_emit_includebin) |
1528 { | 1611 { |
1529 FILE *fp; | 1612 FILE *fp; |
1530 int c; | 1613 int c, i; |
1531 | 1614 |
1532 fp = fopen(l -> lstr, "rb"); | 1615 fp = fopen(l -> lstr, "rb"); |
1533 if (!fp) | 1616 if (!fp) |
1534 { | 1617 { |
1535 lwasm_register_error2(as, l, E_FILE_OPEN, "%s", "(emit)!"); | 1618 lwasm_register_error2(as, l, E_FILE_OPEN, "%s", "(emit)!"); |
1536 return; | 1619 return; |
1537 } | 1620 } |
1538 | 1621 |
1539 for (;;) | 1622 // apply the specified offset |
1623 fseek(fp, l -> lint, SEEK_SET); | |
1624 | |
1625 for (i=0; i < l -> len; i++) | |
1540 { | 1626 { |
1541 c = fgetc(fp); | 1627 c = fgetc(fp); |
1542 if (c == EOF) | 1628 if (c == EOF) |
1543 { | 1629 { |
1544 fclose(fp); | 1630 fclose(fp); |