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 }