boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

129-extern-libp1pp.c (2223B)


      1 /* Calls into libp1pp routines via plain C `extern` declarations. The
      2  * libp1pp side already provides `:memcpy`, `:memcmp`, and `:memset`
      3  * as bare-name labels (see P1/P1pp.P1pp). For these to link,
      4  * cc.scm must NOT prefix `extern`-but-not-defined-here symbols with
      5  * its `cc__` namespace — bare-name extern decls should pass through.
      6  *
      7  * This is the linkage rule that lets the tcc-boot2 path resolve all
      8  * the low-level memory symbols (memcpy/memcmp/memset/etc.) tcc.c calls.
      9  * Do not test stdio/libc string APIs here; plain tests/cc fixtures should
     10  * stay freestanding.
     11  */
     12 
     13 extern void          *memcpy(void *, const void *, unsigned long);
     14 extern int            memcmp(const void *, const void *, unsigned long);
     15 extern void          *memset(void *, int, unsigned long);
     16 
     17 int test_memcpy(void) {
     18     char buf[8];
     19     memcpy(buf, "abcdefg", 8);
     20     if (buf[0] != 'a') return 1;
     21     if (buf[3] != 'd') return 2;
     22     if (buf[6] != 'g') return 3;
     23     if (buf[7] != 0)   return 4;
     24     return 0;
     25 }
     26 
     27 int test_memcmp(void) {
     28     if (memcmp("hello", "hello", 5) != 0) return 1;
     29     if (memcmp("hello", "help!", 5) == 0) return 2;
     30     if (memcmp("a", "b", 1) == 0) return 3;
     31     return 0;
     32 }
     33 
     34 int test_memset(void) {
     35     char buf[6];
     36     memset(buf, 'X', 5);
     37     buf[5] = 0;
     38     if (buf[0] != 'X') return 1;
     39     if (buf[2] != 'X') return 2;
     40     if (buf[4] != 'X') return 3;
     41     if (buf[5] != 0)   return 4;
     42     return 0;
     43 }
     44 
     45 int test_extern_then_define(void) {
     46     /* If a function is declared extern AND later defined here in the
     47      * same TU, the definition's `cc__` prefix takes precedence — the
     48      * scope-bind! merge sets defined?=#t, the call resolves to the
     49      * local definition rather than the bare libp1pp symbol. */
     50     extern int helper_local(int);   /* declared local */
     51     return helper_local(7);          /* should call the cc__helper_local below */
     52 }
     53 
     54 int helper_local(int x) {
     55     return x == 7 ? 0 : 99;
     56 }
     57 
     58 int main(int argc, char **argv) {
     59     int r;
     60     if ((r = test_memcpy()))             return 20 + r;
     61     if ((r = test_memcmp()))             return 30 + r;
     62     if ((r = test_memset()))             return 40 + r;
     63     if ((r = test_extern_then_define())) return 50 + r;
     64     return 0;
     65 }