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);