live-bootstrap

This page is produced by the version of the program keam_parser.cpp listed at the bottom of this page. The program parsers the contents of GitHub repositories oriansj/stage0 and fosslinux/live-bootstrap (the commit 493ddfa) in order to find all the dependencies and list relevant input sources. The parsing stops at the execution of run.sh. (This is still work in progress.)

The code displayed on this page is not copyrighted by me but by the owners of respective repositories as also mentioned in the headers of the various files.

Binary seeds files

../git/live-bootstrap/sysa/stage0-posix/src/bootstrap-seeds/POSIX/x86/kaem-optional-seed

Source: https://github.com/oriansj/bootstrap-seeds/blob/main/POSIX/x86/kaem-optional-seed

Executable seed!

../git/live-bootstrap/sysa/stage0-posix/src/bootstrap-seeds/POSIX/x86/hex0-seed

Source: https://github.com/oriansj/bootstrap-seeds/blob/main/POSIX/x86/hex0-seed

Executable seed!

Input source files

../git/live-bootstrap/sysa/stage0-posix/src/x86/hex0_x86.hex0

Source: https://github.com/oriansj/stage0-posix-x86/blob/main/hex0_x86.hex0

../git/live-bootstrap/sysa/stage0-posix/src/x86/kaem-minimal.hex0

Source: https://github.com/oriansj/stage0-posix-x86/blob/main/kaem-minimal.hex0

../git/live-bootstrap/sysa/stage0-posix/src/x86/hex1_x86.hex0

Source: https://github.com/oriansj/stage0-posix-x86/blob/main/hex1_x86.hex0

../git/live-bootstrap/sysa/stage0-posix/src/x86/hex2_x86.hex1

Source: https://github.com/oriansj/stage0-posix-x86/blob/main/hex2_x86.hex1

../git/live-bootstrap/sysa/stage0-posix/src/x86/catm_x86.hex2

Source: https://github.com/oriansj/stage0-posix-x86/blob/main/catm_x86.hex2

../git/live-bootstrap/sysa/stage0-posix/src/x86/ELF-i386.hex2

Source: https://github.com/oriansj/stage0-posix-x86/blob/main/ELF-i386.hex2

../git/live-bootstrap/sysa/stage0-posix/src/x86/M0_x86.hex2

Source: https://github.com/oriansj/stage0-posix-x86/blob/main/M0_x86.hex2

../git/live-bootstrap/sysa/stage0-posix/src/x86/cc_x86.M1

Source: https://github.com/oriansj/stage0-posix-x86/blob/main/cc_x86.M1

../git/live-bootstrap/sysa/stage0-posix/src/M2libc/x86/linux/bootstrap.c

Source: https://github.com/oriansj/M2libc/blob/main/x86/linux/bootstrap.c

../git/live-bootstrap/sysa/stage0-posix/src/M2-Planet/cc.h

Source: https://github.com/oriansj/M2-Planet/blob/main/cc.h

../git/live-bootstrap/sysa/stage0-posix/src/M2libc/bootstrappable.c

Source: https://github.com/oriansj/M2libc/blob/main/bootstrappable.c

../git/live-bootstrap/sysa/stage0-posix/src/M2-Planet/cc_globals.c

Source: https://github.com/oriansj/M2-Planet/blob/main/cc_globals.c

../git/live-bootstrap/sysa/stage0-posix/src/M2-Planet/cc_reader.c

Source: https://github.com/oriansj/M2-Planet/blob/main/cc_reader.c

../git/live-bootstrap/sysa/stage0-posix/src/M2-Planet/cc_strings.c

Source: https://github.com/oriansj/M2-Planet/blob/main/cc_strings.c

../git/live-bootstrap/sysa/stage0-posix/src/M2-Planet/cc_types.c

Source: https://github.com/oriansj/M2-Planet/blob/main/cc_types.c

../git/live-bootstrap/sysa/stage0-posix/src/M2-Planet/cc_core.c

Source: https://github.com/oriansj/M2-Planet/blob/main/cc_core.c

../git/live-bootstrap/sysa/stage0-posix/src/M2-Planet/cc_macro.c

Source: https://github.com/oriansj/M2-Planet/blob/main/cc_macro.c

../git/live-bootstrap/sysa/stage0-posix/src/M2-Planet/cc.c

Source: https://github.com/oriansj/M2-Planet/blob/main/cc.c

../git/live-bootstrap/sysa/stage0-posix/src/x86/x86_defs.M1

Source: https://github.com/oriansj/stage0-posix-x86/blob/main/x86_defs.M1

../git/live-bootstrap/sysa/stage0-posix/src/x86/libc-core.M1

Source: https://github.com/oriansj/stage0-posix-x86/blob/main/libc-core.M1

../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools/stringify.c

Source: https://git.savannah.nongnu.org/gitweb/?p=mescc-tools.git;a=blob;f=stringify.c

../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools/blood-elf.c

Source: https://git.savannah.nongnu.org/gitweb/?p=mescc-tools.git;a=blob;f=blood-elf.c

../git/live-bootstrap/sysa/stage0-posix/src/M2libc/x86/x86_defs.M1

Source: https://github.com/oriansj/M2libc/blob/main/x86/x86_defs.M1

../git/live-bootstrap/sysa/stage0-posix/src/M2libc/x86/libc-core.M1

Source: https://github.com/oriansj/M2libc/blob/main/x86/libc-core.M1

../git/live-bootstrap/sysa/stage0-posix/src/M2libc/x86/ELF-x86.hex2

Source: https://github.com/oriansj/M2libc/blob/main/x86/ELF-x86.hex2

../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools/M1-macro.c

Source: https://git.savannah.nongnu.org/gitweb/?p=mescc-tools.git;a=blob;f=M1-macro.c

../git/live-bootstrap/sysa/stage0-posix/src/M2libc/x86/ELF-x86-debug.hex2

Source: https://github.com/oriansj/M2libc/blob/main/x86/ELF-x86-debug.hex2

../git/live-bootstrap/sysa/stage0-posix/src/M2libc/sys/types.h

Source: https://github.com/oriansj/M2libc/blob/main/sys/types.h

../git/live-bootstrap/sysa/stage0-posix/src/M2libc/stddef.h

Source: https://github.com/oriansj/M2libc/blob/main/stddef.h

../git/live-bootstrap/sysa/stage0-posix/src/M2libc/x86/linux/unistd.c

Source: https://github.com/oriansj/M2libc/blob/main/x86/linux/unistd.c

../git/live-bootstrap/sysa/stage0-posix/src/M2libc/x86/linux/fcntl.c

Source: https://github.com/oriansj/M2libc/blob/main/x86/linux/fcntl.c

../git/live-bootstrap/sysa/stage0-posix/src/M2libc/fcntl.c

Source: https://github.com/oriansj/M2libc/blob/main/fcntl.c

../git/live-bootstrap/sysa/stage0-posix/src/M2libc/x86/linux/sys/stat.c

Source: https://github.com/oriansj/M2libc/blob/main/x86/linux/sys/stat.c

../git/live-bootstrap/sysa/stage0-posix/src/M2libc/stdlib.c

Source: https://github.com/oriansj/M2libc/blob/main/stdlib.c

../git/live-bootstrap/sysa/stage0-posix/src/M2libc/stdio.h

Source: https://github.com/oriansj/M2libc/blob/main/stdio.h

../git/live-bootstrap/sysa/stage0-posix/src/M2libc/stdio.c

Source: https://github.com/oriansj/M2libc/blob/main/stdio.c

../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools/hex2.h

Source: https://git.savannah.nongnu.org/gitweb/?p=mescc-tools.git;a=blob;f=hex2.h

../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools/hex2_linker.c

Source: https://git.savannah.nongnu.org/gitweb/?p=mescc-tools.git;a=blob;f=hex2_linker.c

../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools/hex2_word.c

Source: https://git.savannah.nongnu.org/gitweb/?p=mescc-tools.git;a=blob;f=hex2_word.c

../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools/hex2.c

Source: https://git.savannah.nongnu.org/gitweb/?p=mescc-tools.git;a=blob;f=hex2.c

../git/live-bootstrap/sysa/stage0-posix/src/M2libc/x86/libc-full.M1

Source: https://github.com/oriansj/M2libc/blob/main/x86/libc-full.M1

../git/live-bootstrap/sysa/stage0-posix/src/M2libc/string.c

Source: https://github.com/oriansj/M2libc/blob/main/string.c

../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools/Kaem/kaem.h

Source: https://git.savannah.nongnu.org/gitweb/?p=mescc-tools.git;a=blob;f=Kaem/kaem.h

../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools/Kaem/variable.c

Source: https://git.savannah.nongnu.org/gitweb/?p=mescc-tools.git;a=blob;f=Kaem/variable.c

../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools/Kaem/kaem_globals.c

Source: https://git.savannah.nongnu.org/gitweb/?p=mescc-tools.git;a=blob;f=Kaem/kaem_globals.c

../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools/Kaem/kaem.c

Source: https://git.savannah.nongnu.org/gitweb/?p=mescc-tools.git;a=blob;f=Kaem/kaem.c

../git/live-bootstrap/sysa/stage0-posix/src/M2-Mesoplanet/cc.h

Source: https://github.com/oriansj/M2-Mesoplanet/blob/main/cc.h

../git/live-bootstrap/sysa/stage0-posix/src/M2-Mesoplanet/cc_globals.c

Source: https://github.com/oriansj/M2-Mesoplanet/blob/main/cc_globals.c

../git/live-bootstrap/sysa/stage0-posix/src/M2-Mesoplanet/cc_env.c

Source: https://github.com/oriansj/M2-Mesoplanet/blob/main/cc_env.c

../git/live-bootstrap/sysa/stage0-posix/src/M2-Mesoplanet/cc_reader.c

Source: https://github.com/oriansj/M2-Mesoplanet/blob/main/cc_reader.c

../git/live-bootstrap/sysa/stage0-posix/src/M2-Mesoplanet/cc_spawn.c

Source: https://github.com/oriansj/M2-Mesoplanet/blob/main/cc_spawn.c

../git/live-bootstrap/sysa/stage0-posix/src/M2-Mesoplanet/cc_core.c

Source: https://github.com/oriansj/M2-Mesoplanet/blob/main/cc_core.c

../git/live-bootstrap/sysa/stage0-posix/src/M2-Mesoplanet/cc_macro.c

Source: https://github.com/oriansj/M2-Mesoplanet/blob/main/cc_macro.c

../git/live-bootstrap/sysa/stage0-posix/src/M2-Mesoplanet/cc.c

Source: https://github.com/oriansj/M2-Mesoplanet/blob/main/cc.c

../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools/get_machine.c

Source: https://git.savannah.nongnu.org/gitweb/?p=mescc-tools.git;a=blob;f=get_machine.c

../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools-extra/sha256sum.c

Source: https://github.com/oriansj/mescc-tools-extra/blob/main/sha256sum.c

../git/live-bootstrap/sysa/stage0-posix/src/M2libc/string.h

Source: https://github.com/oriansj/M2libc/blob/main/string.h

../git/live-bootstrap/sysa/stage0-posix/src/M2libc/sys/stat.h

Source: https://github.com/oriansj/M2libc/blob/main/sys/stat.h

../git/live-bootstrap/sysa/stage0-posix/src/M2libc/fcntl.h

Source: https://github.com/oriansj/M2libc/blob/main/fcntl.h

../git/live-bootstrap/sysa/stage0-posix/src/M2libc/unistd.h

Source: https://github.com/oriansj/M2libc/blob/main/unistd.h

../git/live-bootstrap/sysa/stage0-posix/src/M2libc/stdlib.h

Source: https://github.com/oriansj/M2libc/blob/main/stdlib.h

../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools-extra/M2libc/bootstrappable.h

Source: https://github.com/oriansj/M2libc/blob/main/bootstrappable.h

../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools-extra/match.c

Source: https://github.com/oriansj/mescc-tools-extra/blob/main/match.c

../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools-extra/mkdir.c

Source: https://github.com/oriansj/mescc-tools-extra/blob/main/mkdir.c

../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools-extra/untar.c

Source: https://github.com/oriansj/mescc-tools-extra/blob/main/untar.c

../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools-extra/ungz.c

Source: https://github.com/oriansj/mescc-tools-extra/blob/main/ungz.c

../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools-extra/unbz2.c

Source: https://github.com/oriansj/mescc-tools-extra/blob/main/unbz2.c

../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools-extra/catm.c

Source: https://github.com/oriansj/mescc-tools-extra/blob/main/catm.c

../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools-extra/cp.c

Source: https://github.com/oriansj/mescc-tools-extra/blob/main/cp.c

../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools-extra/chmod.c

Source: https://github.com/oriansj/mescc-tools-extra/blob/main/chmod.c

../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools-extra/rm.c

Source: https://github.com/oriansj/mescc-tools-extra/blob/main/rm.c

../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools-extra/replace.c

Source: https://github.com/oriansj/mescc-tools-extra/blob/main/replace.c

../git/live-bootstrap/sysa/stage0-posix/src/x86.answers

Source: https://github.com/oriansj/stage0-posix/blob/main/x86.answers

/M2libc/x86/linux/sys/stat.c

Source: https://github.com/oriansj/M2libc/blob/main/x86/linux/sys/stat.c

/M2libc/stdlib.c

Source: https://github.com/oriansj/M2libc/blob/main/stdlib.c

/M2libc/stdio.h

Source: https://github.com/oriansj/M2libc/blob/main/stdio.h

/M2libc/stdio.c

Source: https://github.com/oriansj/M2libc/blob/main/stdio.c

/M2libc/x86/libc-full.M1

Source: https://github.com/oriansj/M2libc/blob/main/x86/libc-full.M1

/M2libc/string.c

Source: https://github.com/oriansj/M2libc/blob/main/string.c

/M2libc/string.h

Source: https://github.com/oriansj/M2libc/blob/main/string.h

../git/live-bootstrap/sysa/stage0-posix/src/M2libc/bootstrappable.h

Source: https://github.com/oriansj/M2libc/blob/main/bootstrappable.h

../git/live-bootstrap/sysa/checksum-transcriber.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/checksum-transcriber.c

../git/live-bootstrap/sysa/checksum-transcriber.x86.SHA256SUM

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/checksum-transcriber.x86.SHA256SUM

../git/live-bootstrap/sysa/simple-patch.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/simple-patch.c

../git/live-bootstrap/sysa/mes-0.24.2/sources

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/mes-0.24.2/sources

/sysa/distfiles/mes-0.24.2.tar.gz

Source: https://mirrors.kernel.org/gnu/mes/mes-0.24.2.tar.gz

/sysa/distfiles/nyacc-1.00.2.tar.gz

Source: https://download.savannah.gnu.org/releases/nyacc/nyacc-1.00.2.tar.gz

../git/live-bootstrap/sysa/mes-0.24.2/files/config.h

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/mes-0.24.2/files/config.h

/sysa/mes-0.24.2/build/mes-0.24.2/include/linux/x86/syscall.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/linux/x86/syscall.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/linux/x86/kernel-stat.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/linux/x86/kernel-stat.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/mes/module/mes/psyntax.pp

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/mes/module/mes/psyntax.pp?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/mes/module/mes/psyntax.pp.header

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/mes/module/mes/psyntax.pp.header?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/mes/module/srfi/srfi-9-struct.mes

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/mes/module/srfi/srfi-9-struct.mes?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/mes/module/srfi/srfi-9/gnu-struct.mes

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/mes/module/srfi/srfi-9/gnu-struct.mes?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/m2/lib.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/m2/lib.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/x86-mes-m2/crt1.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-m2/crt1.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/x86-mes-m2/_exit.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-m2/_exit.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/x86-mes-m2/_write.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-m2/_write.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/mes/globals.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/globals.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/m2/cast.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/m2/cast.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/m2/exit.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/m2/exit.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/mes/mini-write.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/mini-write.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/x86-mes-m2/syscall.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-m2/syscall.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stub/__raise.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/__raise.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/brk.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/brk.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/m2/malloc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/m2/malloc.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/string/memset.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/memset.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/m2/read.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/m2/read.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/mes/fdgetc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/fdgetc.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdio/getchar.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/getchar.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdio/putchar.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/putchar.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/m2/open.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/m2/open.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/m2/mes_open.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/m2/mes_open.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/string/strlen.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strlen.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/mes/eputs.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/eputs.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/mes/fdputc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/fdputc.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/mes/eputc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/eputc.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/m2/types.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/m2/types.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/mes/mes.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/mes/mes.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/mes/builtins.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/mes/builtins.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/mes/constants.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/mes/constants.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/mes/symbols.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/mes/symbols.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/mes/__assert_fail.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/__assert_fail.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/mes/assert_msg.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/assert_msg.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/string/strncmp.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strncmp.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/posix/getenv.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/getenv.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/mes/fdputs.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/fdputs.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/mes/ntoab.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/ntoab.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/ctype/isdigit.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isdigit.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/ctype/isxdigit.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isxdigit.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/ctype/isspace.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isspace.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/ctype/isnumber.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isnumber.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/mes/abtol.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/abtol.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdlib/atoi.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/atoi.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/string/memcpy.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/memcpy.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdlib/free.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/free.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdlib/realloc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/realloc.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/string/strcpy.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strcpy.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/mes/itoa.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/itoa.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/mes/ltoa.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/ltoa.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/mes/fdungetc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/fdungetc.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/posix/setenv.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/setenv.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/access.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/access.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/linux/m2/kernel-stat.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/linux/m2/kernel-stat.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/sys/stat.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/stat.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/m2/chmod.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/m2/chmod.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/ioctl3.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/ioctl3.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/m2/isatty.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/m2/isatty.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/fork.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/fork.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/m2/execve.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/m2/execve.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/m2/execv.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/m2/execv.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/m2/waitpid.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/m2/waitpid.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/gettimeofday.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/gettimeofday.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/m2/clock_gettime.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/m2/clock_gettime.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/m2/time.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/m2/time.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/_getcwd.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/_getcwd.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/m2/getcwd.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/m2/getcwd.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/dup.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/dup.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/dup2.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/dup2.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/string/strcmp.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strcmp.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/string/memcmp.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/memcmp.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/unlink.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/unlink.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/src/builtins.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/src/builtins.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/src/core.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/src/core.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/src/display.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/src/display.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/src/eval-apply.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/src/eval-apply.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/src/gc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/src/gc.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/src/hash.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/src/hash.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/src/lib.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/src/lib.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/src/m2.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/src/m2.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/src/math.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/src/math.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/src/mes.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/src/mes.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/src/module.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/src/module.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/src/posix.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/src/posix.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/src/reader.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/src/reader.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/src/stack.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/src/stack.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/src/string.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/src/string.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/src/struct.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/src/struct.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/src/symbol.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/src/symbol.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/src/vector.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/src/vector.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/x86-mes/x86.M1

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/x86-mes/x86.M1?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/x86-mes-m2/crt1.M1

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-m2/crt1.M1?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/m2/x86/ELF-x86.hex2

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/m2/x86/ELF-x86.hex2?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/x86-mes-mescc/crt1.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-mescc/crt1.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/mes/lib-mini.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/mes/lib-mini.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/string.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/string.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/mes/oputs.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/oputs.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdlib/exit.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/exit.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/mes/lib.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/mes/lib.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/x86-mes-mescc/_exit.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-mescc/_exit.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/x86-mes-mescc/_write.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-mescc/_write.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdlib/puts.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/puts.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/errno.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/errno.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/x86-mes-mescc/syscall-internal.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-mescc/syscall-internal.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/ctype.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/ctype.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/mes/cast.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/cast.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/limits.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/limits.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/stdlib.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/stdlib.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/sys/resource.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/resource.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/unistd.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/unistd.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/mes/ltoab.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/ltoab.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/mes/mes_open.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/mes_open.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/assert.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/assert.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/mes/oputc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/oputc.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/mes/ultoa.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/ultoa.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/mes/utoa.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/utoa.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/posix/write.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/write.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/stdio.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/stdio.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/lseek.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/lseek.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/linux/syscall.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/linux/syscall.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/sys/types.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/types.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/mes/__buffered_read.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/__buffered_read.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/mes/__mes_debug.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/__mes_debug.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/posix/execv.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/execv.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/posix/getcwd.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/getcwd.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/posix/isatty.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/isatty.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/sys/ioctl.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/ioctl.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/termio.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/termio.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/posix/open.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/open.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/fcntl.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/fcntl.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/stdarg.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/stdarg.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/posix/buffered-read.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/buffered-read.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/posix/wait.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/wait.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/sys/wait.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/wait.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdio/fgetc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fgetc.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdio/fputc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fputc.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdio/fputs.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fputs.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdio/getc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/getc.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdio/putc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/putc.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdio/ungetc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/ungetc.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/string/memchr.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/memchr.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/string/memmove.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/memmove.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/posix/raise.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/raise.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/signal.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/signal.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/chmod.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/chmod.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/clock_gettime.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/clock_gettime.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/time.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/time.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/execve.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/execve.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/fsync.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/fsync.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/sys/time.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/time.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/malloc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/malloc.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/stddef.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/stddef.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/stdint.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/stdint.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/_open3.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/_open3.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/_read.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/_read.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/time.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/time.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/waitpid.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/waitpid.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/x86-mes-mescc/syscall.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-mescc/syscall.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/getpid.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/getpid.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/kill.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/kill.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/mes/cc.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/mes/cc.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/src/cc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/src/cc.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/src/globals.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/src/globals.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/ctype/islower.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/islower.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/ctype/isupper.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isupper.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/ctype/tolower.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/tolower.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/ctype/toupper.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/toupper.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/mes/abtod.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/abtod.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/mes/dtoab.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/dtoab.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/mes/search-path.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/search-path.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/posix/execvp.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/execvp.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdio/fclose.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fclose.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdio/fdopen.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fdopen.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdio/ferror.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/ferror.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdio/fflush.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fflush.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdio/fopen.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fopen.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdio/fprintf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fprintf.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdio/fread.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fread.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdio/fseek.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fseek.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdio/ftell.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/ftell.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdio/fwrite.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fwrite.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdio/printf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/printf.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdio/remove.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/remove.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdio/snprintf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/snprintf.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdio/sprintf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/sprintf.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdio/sscanf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/sscanf.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdio/vfprintf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/vfprintf.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdio/vprintf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/vprintf.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdio/vsnprintf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/vsnprintf.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdio/vsprintf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/vsprintf.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdio/vsscanf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/vsscanf.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdlib/calloc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/calloc.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdlib/qsort.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/qsort.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdlib/strtod.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/strtod.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdlib/strtof.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/strtof.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdlib/strtol.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/strtol.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdlib/strtold.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/strtold.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdlib/strtoll.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/strtoll.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdlib/strtoul.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/strtoul.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stdlib/strtoull.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/strtoull.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/string/memmem.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/memmem.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/string/strcat.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strcat.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/string/strchr.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strchr.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/string/strlwr.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strlwr.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/string/strncpy.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strncpy.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/string/strrchr.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strrchr.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/string/strstr.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strstr.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/sys/mman.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/mman.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/string/strupr.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strupr.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stub/sigaction.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/sigaction.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stub/ldexp.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/ldexp.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/math.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/math.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stub/mprotect.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/mprotect.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stub/localtime.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/localtime.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/stub/sigemptyset.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/sigemptyset.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/x86-mes-mescc/setjmp.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/x86-mes-mescc/setjmp.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/setjmp.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/setjmp.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/close.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/close.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/rmdir.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/rmdir.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/stat.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/stat.c?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/x86-mes/crt1.s

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/x86-mes/crt1.s?h=v0.24.2

NoInput

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/x86-mes/elf32-footer-single-main.hex2

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes/elf32-footer-single-main.hex2?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/x86-mes/elf32-header.hex2

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes/elf32-header.hex2?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/alloca.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/alloca.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/argz.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/argz.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/ar.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/ar.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/dirent.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/dirent.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/dirstream.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/dirstream.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/dlfcn.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/dlfcn.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/endian.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/endian.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/features.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/features.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/float.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/float.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/getopt.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/getopt.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/grp.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/grp.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/inttypes.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/inttypes.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/libgen.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/libgen.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/locale.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/locale.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/memory.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/memory.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/pwd.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/pwd.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/stdbool.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/stdbool.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/stdnoreturn.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/stdnoreturn.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/strings.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/strings.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/sys/cdefs.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/cdefs.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/sys/dir.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/dir.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/sys/file.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/file.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/sys/param.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/param.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/sys/select.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/select.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/sys/timeb.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/timeb.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/sys/times.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/times.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/sys/ucontext.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/ucontext.h?h=v0.24.2

/sysa/mes-0.24.2/build/mes-0.24.2/include/sys/user.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/user.h?h=v0.24.2

/sysa/mes-0.24.2/mes-0.24.2.checksums

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/mes-0.24.2/mes-0.24.2.checksums

../git/live-bootstrap/sysa/tcc-0.9.26/sources

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/tcc-0.9.26/sources

/sysa/distfiles/tcc-0.9.26.tar.gz

Source: https://lilypond.org/janneke/tcc/tcc-0.9.26-1136-g5bba73cc.tar.gz

../git/live-bootstrap/sysa/tcc-0.9.26/build/tcc-0.9.26-1136-g5bba73cc/tcctools.c

Source: https://gitlab.com/janneke/tinycc/-/blob/ff2210b308321f27ee07476d07f24b5095602b17/tcctools.c

../git/live-bootstrap/sysa/tcc-0.9.26/simple-patches/remove-fileopen.before

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/tcc-0.9.26/simple-patches/remove-fileopen.before

../git/live-bootstrap/sysa/tcc-0.9.26/simple-patches/remove-fileopen.after

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/tcc-0.9.26/simple-patches/remove-fileopen.after

../git/live-bootstrap/sysa/tcc-0.9.26/simple-patches/addback-fileopen.before

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/tcc-0.9.26/simple-patches/addback-fileopen.before

../git/live-bootstrap/sysa/tcc-0.9.26/simple-patches/addback-fileopen.after

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/tcc-0.9.26/simple-patches/addback-fileopen.after

../git/live-bootstrap/sysa/tcc-0.9.26/build/tcc-0.9.26-1136-g5bba73cc/tcc.c

Source: https://gitlab.com/janneke/tinycc/-/blob/ff2210b308321f27ee07476d07f24b5095602b17/tcc.c

../git/live-bootstrap/sysa/tcc-0.9.26/build/tcc-0.9.26-1136-g5bba73cc/libtcc.c

Source: https://gitlab.com/janneke/tinycc/-/blob/ff2210b308321f27ee07476d07f24b5095602b17/libtcc.c

../git/live-bootstrap/sysa/tcc-0.9.26/build/tcc-0.9.26-1136-g5bba73cc/tcc.h

Source: https://gitlab.com/janneke/tinycc/-/blob/ff2210b308321f27ee07476d07f24b5095602b17/tcc.h

../git/live-bootstrap/sysa/tcc-0.9.26/build/tcc-0.9.26-1136-g5bba73cc/tccpp.c

Source: https://gitlab.com/janneke/tinycc/-/blob/ff2210b308321f27ee07476d07f24b5095602b17/tccpp.c

../git/live-bootstrap/sysa/tcc-0.9.26/build/tcc-0.9.26-1136-g5bba73cc/tccgen.c

Source: https://gitlab.com/janneke/tinycc/-/blob/ff2210b308321f27ee07476d07f24b5095602b17/tccgen.c

../git/live-bootstrap/sysa/tcc-0.9.26/build/tcc-0.9.26-1136-g5bba73cc/tccelf.c

Source: https://gitlab.com/janneke/tinycc/-/blob/ff2210b308321f27ee07476d07f24b5095602b17/tccelf.c

../git/live-bootstrap/sysa/tcc-0.9.26/build/tcc-0.9.26-1136-g5bba73cc/tccrun.c

Source: https://gitlab.com/janneke/tinycc/-/blob/ff2210b308321f27ee07476d07f24b5095602b17/tccrun.c

../git/live-bootstrap/sysa/tcc-0.9.26/build/tcc-0.9.26-1136-g5bba73cc/i386-gen.c

Source: https://gitlab.com/janneke/tinycc/-/blob/ff2210b308321f27ee07476d07f24b5095602b17/i386-gen.c

../git/live-bootstrap/sysa/tcc-0.9.26/build/tcc-0.9.26-1136-g5bba73cc/i386-link.c

Source: https://gitlab.com/janneke/tinycc/-/blob/ff2210b308321f27ee07476d07f24b5095602b17/i386-link.c

../git/live-bootstrap/sysa/tcc-0.9.26/build/tcc-0.9.26-1136-g5bba73cc/i386-asm.c

Source: https://gitlab.com/janneke/tinycc/-/blob/ff2210b308321f27ee07476d07f24b5095602b17/i386-asm.c

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/ctype/isalnum.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isalnum.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/ctype/isalpha.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isalpha.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/ctype/isascii.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isascii.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/ctype/iscntrl.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/iscntrl.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/ctype/isdigit.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isdigit.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/ctype/isgraph.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isgraph.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/ctype/islower.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/islower.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/ctype/isnumber.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isnumber.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/ctype/isprint.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isprint.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/ctype/ispunct.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/ispunct.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/ctype/isspace.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isspace.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/ctype/isupper.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isupper.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/ctype/isxdigit.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isxdigit.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/ctype/tolower.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/tolower.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/ctype/toupper.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/toupper.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/dirent/closedir.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/dirent/closedir.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/dirent/__getdirentries.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/dirent/__getdirentries.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/dirent/opendir.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/dirent/opendir.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/dirent/readdir.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/dirent/readdir.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/access.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/access.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/brk.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/brk.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/chdir.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/chdir.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/chmod.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/chmod.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/clock_gettime.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/clock_gettime.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/close.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/close.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/dup2.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/dup2.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/dup.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/dup.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/execve.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/execve.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/fcntl.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/fcntl.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/fork.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/fork.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/fsync.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/fsync.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/fstat.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/fstat.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/_getcwd.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/_getcwd.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/getdents.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/getdents.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/getegid.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/getegid.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/geteuid.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/geteuid.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/getgid.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/getgid.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/getpid.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/getpid.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/getppid.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/getppid.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/getrusage.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/getrusage.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/gettimeofday.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/gettimeofday.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/getuid.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/getuid.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/ioctl.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/ioctl.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/ioctl3.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/ioctl3.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/kill.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/kill.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/link.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/link.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/lseek.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/lseek.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/lstat.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/lstat.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/malloc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/malloc.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/mkdir.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/mkdir.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/mknod.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/mknod.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/nanosleep.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/nanosleep.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/_open3.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/_open3.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/pipe.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/pipe.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/_read.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/_read.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/readlink.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/readlink.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/rename.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/rename.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/rmdir.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/rmdir.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/setgid.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/setgid.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/settimer.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/settimer.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/setuid.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/setuid.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/signal.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/signal.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/sigprogmask.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/sigprogmask.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/symlink.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/symlink.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/stat.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/stat.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/time.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/time.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/unlink.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/unlink.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/waitpid.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/waitpid.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/x86-mes-gcc/_exit.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-gcc/_exit.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/x86-mes-gcc/syscall.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-gcc/syscall.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/x86-mes-gcc/_write.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-gcc/_write.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/math/ceil.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/math/ceil.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/math/fabs.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/math/fabs.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/math/floor.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/math/floor.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/mes/abtod.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/abtod.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/mes/abtol.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/abtol.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/mes/__assert_fail.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/__assert_fail.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/mes/assert_msg.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/assert_msg.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/mes/__buffered_read.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/__buffered_read.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/mes/cast.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/cast.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/mes/dtoab.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/dtoab.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/mes/eputc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/eputc.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/mes/eputs.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/eputs.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/mes/fdgetc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/fdgetc.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/mes/fdgets.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/fdgets.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/mes/fdputc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/fdputc.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/mes/fdputs.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/fdputs.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/mes/fdungetc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/fdungetc.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/mes/globals.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/globals.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/mes/itoa.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/itoa.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/mes/ltoab.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/ltoab.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/mes/ltoa.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/ltoa.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/mes/__mes_debug.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/__mes_debug.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/mes/mes_open.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/mes_open.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/mes/ntoab.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/ntoab.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/mes/oputc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/oputc.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/mes/oputs.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/oputs.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/mes/search-path.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/search-path.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/mes/ultoa.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/ultoa.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/mes/utoa.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/utoa.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/posix/alarm.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/alarm.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/posix/buffered-read.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/buffered-read.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/posix/execl.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/execl.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/posix/execlp.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/execlp.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/posix/execv.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/execv.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/posix/execvp.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/execvp.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/posix/getcwd.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/getcwd.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/posix/getenv.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/getenv.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/posix/isatty.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/isatty.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/posix/mktemp.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/mktemp.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/posix/open.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/open.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/posix/raise.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/raise.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/posix/sbrk.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/sbrk.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/posix/setenv.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/setenv.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/posix/sleep.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/sleep.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/posix/unsetenv.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/unsetenv.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/posix/wait.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/wait.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/posix/write.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/write.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/clearerr.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/clearerr.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/fclose.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fclose.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/fdopen.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fdopen.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/feof.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/feof.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/ferror.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/ferror.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/fflush.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fflush.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/fgetc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fgetc.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/fgets.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fgets.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/fileno.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fileno.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/fopen.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fopen.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/fprintf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fprintf.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/fputc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fputc.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/fputs.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fputs.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/fread.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fread.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/freopen.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/freopen.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/fscanf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fscanf.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/fseek.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fseek.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/ftell.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/ftell.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/fwrite.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fwrite.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/getc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/getc.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/getchar.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/getchar.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/perror.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/perror.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/printf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/printf.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/putc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/putc.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/putchar.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/putchar.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/remove.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/remove.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/snprintf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/snprintf.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/sprintf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/sprintf.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/sscanf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/sscanf.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/ungetc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/ungetc.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/vfprintf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/vfprintf.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/vfscanf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/vfscanf.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/vprintf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/vprintf.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/vsnprintf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/vsnprintf.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/vsprintf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/vsprintf.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdio/vsscanf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/vsscanf.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdlib/abort.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/abort.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdlib/abs.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/abs.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdlib/alloca.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/alloca.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdlib/atexit.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/atexit.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdlib/atof.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/atof.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdlib/atoi.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/atoi.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdlib/atol.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/atol.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdlib/calloc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/calloc.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdlib/__exit.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/__exit.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdlib/exit.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/exit.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdlib/free.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/free.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdlib/mbstowcs.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/mbstowcs.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdlib/puts.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/puts.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdlib/qsort.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/qsort.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdlib/realloc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/realloc.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdlib/strtod.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/strtod.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdlib/strtof.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/strtof.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdlib/strtol.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/strtol.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdlib/strtold.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/strtold.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdlib/strtoll.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/strtoll.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdlib/strtoul.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/strtoul.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stdlib/strtoull.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/strtoull.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/string/bcmp.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/bcmp.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/string/bcopy.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/bcopy.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/string/bzero.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/bzero.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/string/index.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/index.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/string/memchr.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/memchr.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/string/memcmp.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/memcmp.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/string/memcpy.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/memcpy.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/string/memmem.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/memmem.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/string/memmove.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/memmove.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/string/memset.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/memset.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/string/rindex.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/rindex.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/string/strcat.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strcat.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/string/strchr.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strchr.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/string/strcmp.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strcmp.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/string/strcpy.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strcpy.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/string/strcspn.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strcspn.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/string/strdup.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strdup.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/string/strerror.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strerror.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/string/strlen.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strlen.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/string/strlwr.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strlwr.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/string/strncat.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strncat.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/string/strncmp.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strncmp.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/string/strncpy.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strncpy.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/string/strpbrk.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strpbrk.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/string/strrchr.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strrchr.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/string/strspn.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strspn.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/string/strstr.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strstr.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/string/strupr.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strupr.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/atan2.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/atan2.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/bsearch.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/bsearch.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/chown.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/chown.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/__cleanup.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/__cleanup.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/cos.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/cos.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/ctime.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/ctime.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/exp.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/exp.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/fpurge.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/fpurge.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/freadahead.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/freadahead.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/frexp.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/frexp.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/getgrgid.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/getgrgid.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/getgrnam.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/getgrnam.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/getlogin.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/getlogin.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/getpgid.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/getpgid.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/getpgrp.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/getpgrp.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/getpwnam.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/getpwnam.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/getpwuid.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/getpwuid.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/gmtime.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/gmtime.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/ldexp.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/ldexp.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/localtime.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/localtime.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/log.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/log.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/mktime.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/mktime.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/modf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/modf.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/mprotect.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/mprotect.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/pclose.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/pclose.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/popen.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/popen.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/pow.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/pow.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/rand.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/rand.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/rewind.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/rewind.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/setbuf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/setbuf.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/setgrent.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/setgrent.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/setlocale.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/setlocale.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/setvbuf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/setvbuf.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/sigaction.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/sigaction.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/sigaddset.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/sigaddset.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/sigblock.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/sigblock.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/sigdelset.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/sigdelset.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/sigemptyset.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/sigemptyset.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/sigsetmask.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/sigsetmask.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/sin.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/sin.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/sys_siglist.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/sys_siglist.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/system.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/system.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/sqrt.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/sqrt.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/strftime.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/strftime.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/times.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/times.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/ttyname.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/ttyname.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/umask.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/umask.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/stub/utime.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/utime.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/x86-mes-gcc/setjmp.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/x86-mes-gcc/setjmp.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/x86-mes-gcc/crt1.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-gcc/crt1.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/mes/lib-mini.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/mes/lib-mini.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/x86-mes-gcc/crtn.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-gcc/crtn.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/linux/x86-mes-gcc/crti.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-gcc/crti.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/ctype.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/ctype.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/mes/lib.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/mes/lib.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/errno.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/errno.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/stddef.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/stddef.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/stdlib.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/stdlib.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/dirent.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/dirent.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/unistd.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/unistd.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/dirstream.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/dirstream.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/stdio.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/stdio.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/limits.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/limits.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/fcntl.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/fcntl.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/sys/types.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/types.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/sys/stat.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/stat.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/string.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/string.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/assert.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/assert.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/linux/syscall.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/linux/syscall.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/time.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/time.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/stdarg.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/stdarg.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/sys/resource.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/resource.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/sys/time.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/time.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/sys/ioctl.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/ioctl.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/stdint.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/stdint.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/signal.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/signal.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/linux/x86/syscall.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/linux/x86/syscall.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/math.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/math.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/termio.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/termio.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/sys/wait.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/wait.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/sys/mman.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/mman.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/grp.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/grp.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/pwd.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/pwd.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/locale.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/locale.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/sys/times.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/times.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/setjmp.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/setjmp.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/libtcc1.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/libtcc1.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/posix/getopt.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/getopt.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/include/getopt.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/getopt.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.26/build/tcc-0.9.26-1136-g5bba73cc/lib/libtcc1.c

Source: https://gitlab.com/janneke/tinycc/-/blob/ff2210b308321f27ee07476d07f24b5095602b17/lib/libtcc1.c

../git/live-bootstrap/sysa/tcc-0.9.26/tcc-0.9.26.checksums

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/tcc-0.9.26/tcc-0.9.26.checksums

../git/live-bootstrap/sysa/tcc-0.9.27/sources

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/tcc-0.9.27/sources

/sysa/distfiles/tcc-0.9.27.tar.bz2

Source: https://download.savannah.gnu.org/releases/tinycc/tcc-0.9.27.tar.bz2

/sysa/tcc-0.9.27/simple-patches/remove-fileopen.before

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/tcc-0.9.27/simple-patches/remove-fileopen.before

/sysa/tcc-0.9.27/simple-patches/remove-fileopen.after

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/tcc-0.9.27/simple-patches/remove-fileopen.after

/sysa/tcc-0.9.27/simple-patches/addback-fileopen.before

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/tcc-0.9.27/simple-patches/addback-fileopen.before

/sysa/tcc-0.9.27/simple-patches/addback-fileopen.after

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/tcc-0.9.27/simple-patches/addback-fileopen.after

/sysa/tcc-0.9.27/build/tcc-0.9.27/tccelf.c

Source: https://gitlab.com/janneke/tinycc/-/tree/release_0_9_27/tccelf.c

/sysa/tcc-0.9.27/simple-patches/fiwix-paddr.before

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/tcc-0.9.27/simple-patches/fiwix-paddr.before

/sysa/tcc-0.9.27/simple-patches/fiwix-paddr.after

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/tcc-0.9.27/simple-patches/fiwix-paddr.after

/sysa/tcc-0.9.27/simple-patches/check-reloc-null.before

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/tcc-0.9.27/simple-patches/check-reloc-null.before

/sysa/tcc-0.9.27/simple-patches/check-reloc-null.after

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/tcc-0.9.27/simple-patches/check-reloc-null.after

../git/live-bootstrap/sysa/tcc-0.9.27/build/tcc-0.9.27/tcc.c

Source: https://gitlab.com/janneke/tinycc/-/tree/release_0_9_27/tcc.c

../git/live-bootstrap/sysa/tcc-0.9.27/build/tcc-0.9.27/tcc.h

Source: https://gitlab.com/janneke/tinycc/-/tree/release_0_9_27/tcc.h

../git/live-bootstrap/sysa/tcc-0.9.27/build/tcc-0.9.27/libtcc.c

Source: https://gitlab.com/janneke/tinycc/-/tree/release_0_9_27/libtcc.c

../git/live-bootstrap/sysa/tcc-0.9.27/build/tcc-0.9.27/tccpp.c

Source: https://gitlab.com/janneke/tinycc/-/tree/release_0_9_27/tccpp.c

../git/live-bootstrap/sysa/tcc-0.9.27/build/tcc-0.9.27/tcctok.h

Source: https://gitlab.com/janneke/tinycc/-/tree/release_0_9_27/tcctok.h

../git/live-bootstrap/sysa/tcc-0.9.27/build/tcc-0.9.27/tccgen.c

Source: https://gitlab.com/janneke/tinycc/-/tree/release_0_9_27/tccgen.c

../git/live-bootstrap/sysa/tcc-0.9.27/build/tcc-0.9.27/tccelf.c

Source: https://gitlab.com/janneke/tinycc/-/tree/release_0_9_27/tccelf.c

../git/live-bootstrap/sysa/tcc-0.9.27/build/tcc-0.9.27/tccrun.c

Source: https://gitlab.com/janneke/tinycc/-/tree/release_0_9_27/tccrun.c

../git/live-bootstrap/sysa/tcc-0.9.27/build/tcc-0.9.27/i386-gen.c

Source: https://gitlab.com/janneke/tinycc/-/tree/release_0_9_27/i386-gen.c

../git/live-bootstrap/sysa/tcc-0.9.27/build/tcc-0.9.27/i386-link.c

Source: https://gitlab.com/janneke/tinycc/-/tree/release_0_9_27/i386-link.c

../git/live-bootstrap/sysa/tcc-0.9.27/build/tcc-0.9.27/i386-asm.c

Source: https://gitlab.com/janneke/tinycc/-/tree/release_0_9_27/i386-asm.c

../git/live-bootstrap/sysa/tcc-0.9.27/build/tcc-0.9.27/tcctools.c

Source: https://gitlab.com/janneke/tinycc/-/tree/release_0_9_27/tcctools.c

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/ctype/isalnum.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isalnum.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/ctype/isalpha.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isalpha.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/ctype/isascii.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isascii.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/ctype/iscntrl.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/iscntrl.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/ctype/isdigit.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isdigit.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/ctype/isgraph.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isgraph.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/ctype/islower.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/islower.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/ctype/isnumber.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isnumber.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/ctype/isprint.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isprint.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/ctype/ispunct.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/ispunct.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/ctype/isspace.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isspace.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/ctype/isupper.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isupper.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/ctype/isxdigit.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isxdigit.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/ctype/tolower.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/tolower.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/ctype/toupper.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/toupper.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/dirent/closedir.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/dirent/closedir.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/dirent/__getdirentries.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/dirent/__getdirentries.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/dirent/opendir.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/dirent/opendir.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/dirent/readdir.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/dirent/readdir.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/access.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/access.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/brk.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/brk.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/chdir.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/chdir.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/chmod.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/chmod.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/clock_gettime.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/clock_gettime.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/close.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/close.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/dup2.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/dup2.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/dup.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/dup.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/execve.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/execve.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/fcntl.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/fcntl.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/fork.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/fork.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/fsync.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/fsync.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/fstat.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/fstat.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/_getcwd.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/_getcwd.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/getdents.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/getdents.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/getegid.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/getegid.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/geteuid.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/geteuid.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/getgid.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/getgid.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/getpid.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/getpid.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/getppid.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/getppid.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/getrusage.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/getrusage.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/gettimeofday.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/gettimeofday.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/getuid.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/getuid.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/ioctl.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/ioctl.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/ioctl3.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/ioctl3.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/kill.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/kill.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/link.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/link.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/lseek.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/lseek.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/lstat.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/lstat.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/malloc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/malloc.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/mkdir.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/mkdir.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/mknod.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/mknod.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/nanosleep.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/nanosleep.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/_open3.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/_open3.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/pipe.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/pipe.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/_read.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/_read.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/readlink.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/readlink.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/rename.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/rename.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/rmdir.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/rmdir.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/setgid.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/setgid.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/settimer.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/settimer.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/setuid.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/setuid.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/signal.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/signal.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/sigprogmask.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/sigprogmask.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/symlink.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/symlink.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/stat.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/stat.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/time.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/time.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/unlink.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/unlink.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/waitpid.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/waitpid.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/x86-mes-gcc/_exit.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-gcc/_exit.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/x86-mes-gcc/syscall.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-gcc/syscall.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/x86-mes-gcc/_write.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-gcc/_write.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/math/ceil.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/math/ceil.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/math/fabs.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/math/fabs.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/math/floor.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/math/floor.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/mes/abtod.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/abtod.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/mes/abtol.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/abtol.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/mes/__assert_fail.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/__assert_fail.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/mes/assert_msg.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/assert_msg.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/mes/__buffered_read.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/__buffered_read.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/mes/cast.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/cast.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/mes/dtoab.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/dtoab.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/mes/eputc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/eputc.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/mes/eputs.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/eputs.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/mes/fdgetc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/fdgetc.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/mes/fdgets.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/fdgets.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/mes/fdputc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/fdputc.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/mes/fdputs.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/fdputs.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/mes/fdungetc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/fdungetc.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/mes/globals.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/globals.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/mes/itoa.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/itoa.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/mes/ltoab.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/ltoab.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/mes/ltoa.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/ltoa.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/mes/__mes_debug.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/__mes_debug.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/mes/mes_open.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/mes_open.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/mes/ntoab.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/ntoab.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/mes/oputc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/oputc.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/mes/oputs.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/oputs.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/mes/search-path.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/search-path.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/mes/ultoa.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/ultoa.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/mes/utoa.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/utoa.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/posix/alarm.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/alarm.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/posix/buffered-read.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/buffered-read.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/posix/execl.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/execl.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/posix/execlp.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/execlp.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/posix/execv.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/execv.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/posix/execvp.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/execvp.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/posix/getcwd.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/getcwd.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/posix/getenv.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/getenv.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/posix/isatty.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/isatty.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/posix/mktemp.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/mktemp.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/posix/open.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/open.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/posix/raise.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/raise.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/posix/sbrk.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/sbrk.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/posix/setenv.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/setenv.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/posix/sleep.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/sleep.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/posix/unsetenv.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/unsetenv.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/posix/wait.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/wait.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/posix/write.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/write.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/clearerr.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/clearerr.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/fclose.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fclose.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/fdopen.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fdopen.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/feof.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/feof.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/ferror.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/ferror.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/fflush.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fflush.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/fgetc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fgetc.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/fgets.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fgets.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/fileno.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fileno.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/fopen.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fopen.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/fprintf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fprintf.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/fputc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fputc.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/fputs.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fputs.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/fread.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fread.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/freopen.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/freopen.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/fscanf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fscanf.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/fseek.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fseek.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/ftell.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/ftell.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/fwrite.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fwrite.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/getc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/getc.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/getchar.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/getchar.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/perror.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/perror.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/printf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/printf.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/putc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/putc.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/putchar.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/putchar.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/remove.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/remove.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/snprintf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/snprintf.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/sprintf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/sprintf.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/sscanf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/sscanf.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/ungetc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/ungetc.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/vfprintf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/vfprintf.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/vfscanf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/vfscanf.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/vprintf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/vprintf.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/vsnprintf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/vsnprintf.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/vsprintf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/vsprintf.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdio/vsscanf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/vsscanf.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdlib/abort.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/abort.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdlib/abs.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/abs.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdlib/alloca.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/alloca.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdlib/atexit.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/atexit.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdlib/atof.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/atof.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdlib/atoi.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/atoi.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdlib/atol.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/atol.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdlib/calloc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/calloc.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdlib/__exit.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/__exit.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdlib/exit.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/exit.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdlib/free.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/free.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdlib/mbstowcs.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/mbstowcs.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdlib/puts.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/puts.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdlib/qsort.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/qsort.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdlib/realloc.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/realloc.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdlib/strtod.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/strtod.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdlib/strtof.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/strtof.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdlib/strtol.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/strtol.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdlib/strtold.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/strtold.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdlib/strtoll.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/strtoll.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdlib/strtoul.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/strtoul.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stdlib/strtoull.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/strtoull.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/string/bcmp.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/bcmp.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/string/bcopy.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/bcopy.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/string/bzero.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/bzero.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/string/index.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/index.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/string/memchr.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/memchr.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/string/memcmp.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/memcmp.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/string/memcpy.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/memcpy.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/string/memmem.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/memmem.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/string/memmove.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/memmove.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/string/memset.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/memset.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/string/rindex.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/rindex.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/string/strcat.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strcat.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/string/strchr.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strchr.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/string/strcmp.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strcmp.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/string/strcpy.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strcpy.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/string/strcspn.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strcspn.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/string/strdup.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strdup.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/string/strerror.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strerror.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/string/strlen.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strlen.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/string/strlwr.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strlwr.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/string/strncat.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strncat.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/string/strncmp.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strncmp.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/string/strncpy.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strncpy.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/string/strpbrk.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strpbrk.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/string/strrchr.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strrchr.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/string/strspn.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strspn.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/string/strstr.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strstr.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/string/strupr.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strupr.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/atan2.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/atan2.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/bsearch.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/bsearch.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/chown.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/chown.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/__cleanup.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/__cleanup.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/cos.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/cos.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/ctime.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/ctime.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/exp.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/exp.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/fpurge.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/fpurge.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/freadahead.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/freadahead.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/frexp.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/frexp.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/getgrgid.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/getgrgid.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/getgrnam.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/getgrnam.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/getlogin.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/getlogin.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/getpgid.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/getpgid.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/getpgrp.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/getpgrp.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/getpwnam.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/getpwnam.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/getpwuid.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/getpwuid.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/gmtime.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/gmtime.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/ldexp.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/ldexp.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/localtime.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/localtime.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/log.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/log.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/mktime.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/mktime.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/modf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/modf.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/mprotect.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/mprotect.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/pclose.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/pclose.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/popen.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/popen.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/pow.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/pow.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/rand.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/rand.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/rewind.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/rewind.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/setbuf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/setbuf.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/setgrent.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/setgrent.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/setlocale.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/setlocale.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/setvbuf.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/setvbuf.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/sigaction.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/sigaction.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/sigaddset.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/sigaddset.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/sigblock.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/sigblock.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/sigdelset.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/sigdelset.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/sigemptyset.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/sigemptyset.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/sigsetmask.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/sigsetmask.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/sin.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/sin.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/sys_siglist.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/sys_siglist.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/system.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/system.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/sqrt.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/sqrt.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/strftime.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/strftime.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/times.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/times.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/ttyname.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/ttyname.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/umask.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/umask.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/stub/utime.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/utime.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/x86-mes-gcc/setjmp.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/x86-mes-gcc/setjmp.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/x86-mes-gcc/crt1.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-gcc/crt1.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/mes/lib-mini.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/mes/lib-mini.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/x86-mes-gcc/crtn.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-gcc/crtn.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/linux/x86-mes-gcc/crti.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-gcc/crti.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/lib/libtcc1.c

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/lib/libtcc1.c?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/mes/lib.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/mes/lib.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/tcc-0.9.27/lib/libtcc1.c

Source: https://gitlab.com/janneke/tinycc/-/tree/release_0_9_27/lib/libtcc1.c

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/ctype.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/ctype.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/errno.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/errno.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/stddef.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/stddef.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/stdlib.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/stdlib.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/dirent.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/dirent.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/unistd.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/unistd.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/dirstream.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/dirstream.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/stdio.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/stdio.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/limits.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/limits.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/fcntl.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/fcntl.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/sys/types.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/types.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/sys/stat.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/stat.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/string.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/string.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/assert.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/assert.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/linux/syscall.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/linux/syscall.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/time.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/time.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/stdarg.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/stdarg.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/sys/resource.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/resource.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/sys/time.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/time.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/sys/ioctl.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/ioctl.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/stdint.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/stdint.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/signal.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/signal.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/linux/x86/syscall.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/linux/x86/syscall.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/math.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/math.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/termio.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/termio.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/sys/wait.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/wait.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/sys/mman.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/mman.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/grp.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/grp.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/pwd.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/pwd.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/locale.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/locale.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/sys/times.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/times.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/build/mes-0.24.2/include/setjmp.h

Source: https://git.savannah.gnu.org/cgit/mes.git/tree/include/setjmp.h?h=v0.24.2

../git/live-bootstrap/sysa/tcc-0.9.27/tcc-0.9.27.checksums

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/tcc-0.9.27/tcc-0.9.27.checksums

../git/live-bootstrap/sysa/make-3.82/sources

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/make-3.82/sources

/sysa/distfiles/make-3.82.tar.bz2

Source: https://mirrors.kernel.org/gnu/make/make-3.82.tar.bz2

../git/live-bootstrap/sysa/make-3.82/files/putenv_stub.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/make-3.82/files/putenv_stub.c

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/getopt.c

Source: https://git.savannah.gnu.org/cgit/make.git/tree/getopt.c?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/getopt1.c

Source: https://git.savannah.gnu.org/cgit/make.git/tree/getopt1.c?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/ar.c

Source: https://git.savannah.gnu.org/cgit/make.git/tree/ar.c?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/make.h

Source: https://git.savannah.gnu.org/cgit/make.git/tree/make.h?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/filedef.h

Source: https://git.savannah.gnu.org/cgit/make.git/tree/filedef.h?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/hash.h

Source: https://git.savannah.gnu.org/cgit/make.git/tree/hash.h?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/dep.h

Source: https://git.savannah.gnu.org/cgit/make.git/tree/dep.h?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/glob/fnmatch.h

Source: https://git.savannah.gnu.org/cgit/make.git/tree/glob/fnmatch.h?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/arscan.c

Source: https://git.savannah.gnu.org/cgit/make.git/tree/arscan.c?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/commands.c

Source: https://git.savannah.gnu.org/cgit/make.git/tree/commands.c?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/variable.h

Source: https://git.savannah.gnu.org/cgit/make.git/tree/variable.h?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/job.h

Source: https://git.savannah.gnu.org/cgit/make.git/tree/job.h?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/commands.h

Source: https://git.savannah.gnu.org/cgit/make.git/tree/commands.h?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/default.c

Source: https://git.savannah.gnu.org/cgit/make.git/tree/default.c?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/rule.h

Source: https://git.savannah.gnu.org/cgit/make.git/tree/rule.h?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/dir.c

Source: https://git.savannah.gnu.org/cgit/make.git/tree/dir.c?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/expand.c

Source: https://git.savannah.gnu.org/cgit/make.git/tree/expand.c?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/file.c

Source: https://git.savannah.gnu.org/cgit/make.git/tree/file.c?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/debug.h

Source: https://git.savannah.gnu.org/cgit/make.git/tree/debug.h?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/function.c

Source: https://git.savannah.gnu.org/cgit/make.git/tree/function.c?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/implicit.c

Source: https://git.savannah.gnu.org/cgit/make.git/tree/implicit.c?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/job.c

Source: https://git.savannah.gnu.org/cgit/make.git/tree/job.c?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/main.c

Source: https://git.savannah.gnu.org/cgit/make.git/tree/main.c?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/getopt.h

Source: https://git.savannah.gnu.org/cgit/make.git/tree/getopt.h?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/misc.c

Source: https://git.savannah.gnu.org/cgit/make.git/tree/misc.c?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/read.c

Source: https://git.savannah.gnu.org/cgit/make.git/tree/read.c?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/glob/glob.h

Source: https://git.savannah.gnu.org/cgit/make.git/tree/glob/glob.h?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/remake.c

Source: https://git.savannah.gnu.org/cgit/make.git/tree/remake.c?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/rule.c

Source: https://git.savannah.gnu.org/cgit/make.git/tree/rule.c?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/signame.c

Source: https://git.savannah.gnu.org/cgit/make.git/tree/signame.c?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/strcache.c

Source: https://git.savannah.gnu.org/cgit/make.git/tree/strcache.c?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/variable.c

Source: https://git.savannah.gnu.org/cgit/make.git/tree/variable.c?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/version.c

Source: https://git.savannah.gnu.org/cgit/make.git/tree/version.c?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/vpath.c

Source: https://git.savannah.gnu.org/cgit/make.git/tree/vpath.c?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/hash.c

Source: https://git.savannah.gnu.org/cgit/make.git/tree/hash.c?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/remote-stub.c

Source: https://git.savannah.gnu.org/cgit/make.git/tree/remote-stub.c?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/getloadavg.c

Source: https://git.savannah.gnu.org/cgit/make.git/tree/getloadavg.c?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/glob/fnmatch.c

Source: https://git.savannah.gnu.org/cgit/make.git/tree/glob/fnmatch.c?h=3.82

../git/live-bootstrap/sysa/make-3.82/build/make-3.82/glob/glob.c

Source: https://git.savannah.gnu.org/cgit/make.git/tree/glob/glob.c?h=3.82

../git/live-bootstrap/sysa/make-3.82/make-3.82.checksums

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/make-3.82/make-3.82.checksums

../git/live-bootstrap/sysa/patch-2.5.9/sources

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/sources

/sysa/distfiles/patch-2.5.9.tar.gz

Source: https://mirrors.kernel.org/gnu/patch/patch-2.5.9.tar.gz

../git/live-bootstrap/sysa/patch-2.5.9/mk/main.mk

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/mk/main.mk

../git/live-bootstrap/sysa/patch-2.5.9/build/patch-2.5.9/error.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/build/patch-2.5.9/error.c

../git/live-bootstrap/sysa/patch-2.5.9/build/patch-2.5.9/getopt.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/build/patch-2.5.9/getopt.c

../git/live-bootstrap/sysa/patch-2.5.9/build/patch-2.5.9/getopt1.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/build/patch-2.5.9/getopt1.c

../git/live-bootstrap/sysa/patch-2.5.9/build/patch-2.5.9/addext.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/build/patch-2.5.9/addext.c

../git/live-bootstrap/sysa/patch-2.5.9/build/patch-2.5.9/argmatch.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/build/patch-2.5.9/argmatch.c

../git/live-bootstrap/sysa/patch-2.5.9/build/patch-2.5.9/backupfile.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/build/patch-2.5.9/backupfile.c

../git/live-bootstrap/sysa/patch-2.5.9/build/patch-2.5.9/basename.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/build/patch-2.5.9/basename.c

../git/live-bootstrap/sysa/patch-2.5.9/build/patch-2.5.9/dirname.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/build/patch-2.5.9/dirname.c

../git/live-bootstrap/sysa/patch-2.5.9/build/patch-2.5.9/inp.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/build/patch-2.5.9/inp.c

../git/live-bootstrap/sysa/patch-2.5.9/build/patch-2.5.9/common.h

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/build/patch-2.5.9/common.h

../git/live-bootstrap/sysa/patch-2.5.9/build/patch-2.5.9/backupfile.h

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/build/patch-2.5.9/backupfile.h

../git/live-bootstrap/sysa/patch-2.5.9/build/patch-2.5.9/pch.h

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/build/patch-2.5.9/pch.h

../git/live-bootstrap/sysa/patch-2.5.9/build/patch-2.5.9/quotearg.h

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/build/patch-2.5.9/quotearg.h

../git/live-bootstrap/sysa/patch-2.5.9/build/patch-2.5.9/util.h

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/build/patch-2.5.9/util.h

../git/live-bootstrap/sysa/patch-2.5.9/build/patch-2.5.9/xalloc.h

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/build/patch-2.5.9/xalloc.h

../git/live-bootstrap/sysa/patch-2.5.9/build/patch-2.5.9/inp.h

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/build/patch-2.5.9/inp.h

../git/live-bootstrap/sysa/patch-2.5.9/build/patch-2.5.9/maketime.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/build/patch-2.5.9/maketime.c

../git/live-bootstrap/sysa/patch-2.5.9/build/patch-2.5.9/partime.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/build/patch-2.5.9/partime.c

../git/live-bootstrap/sysa/patch-2.5.9/build/patch-2.5.9/patch.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/build/patch-2.5.9/patch.c

../git/live-bootstrap/sysa/patch-2.5.9/build/patch-2.5.9/argmatch.h

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/build/patch-2.5.9/argmatch.h

../git/live-bootstrap/sysa/patch-2.5.9/build/patch-2.5.9/getopt.h

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/build/patch-2.5.9/getopt.h

../git/live-bootstrap/sysa/patch-2.5.9/build/patch-2.5.9/version.h

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/build/patch-2.5.9/version.h

../git/live-bootstrap/sysa/patch-2.5.9/build/patch-2.5.9/pch.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/build/patch-2.5.9/pch.c

../git/live-bootstrap/sysa/patch-2.5.9/build/patch-2.5.9/dirname.h

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/build/patch-2.5.9/dirname.h

../git/live-bootstrap/sysa/patch-2.5.9/build/patch-2.5.9/quote.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/build/patch-2.5.9/quote.c

../git/live-bootstrap/sysa/patch-2.5.9/build/patch-2.5.9/quotearg.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/build/patch-2.5.9/quotearg.c

../git/live-bootstrap/sysa/patch-2.5.9/build/patch-2.5.9/quotesys.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/build/patch-2.5.9/quotesys.c

../git/live-bootstrap/sysa/patch-2.5.9/build/patch-2.5.9/util.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/build/patch-2.5.9/util.c

../git/live-bootstrap/sysa/patch-2.5.9/build/patch-2.5.9/quotesys.h

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/build/patch-2.5.9/quotesys.h

../git/live-bootstrap/sysa/patch-2.5.9/build/patch-2.5.9/maketime.h

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/build/patch-2.5.9/maketime.h

../git/live-bootstrap/sysa/patch-2.5.9/build/patch-2.5.9/partime.h

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/build/patch-2.5.9/partime.h

../git/live-bootstrap/sysa/patch-2.5.9/build/patch-2.5.9/version.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/build/patch-2.5.9/version.c

../git/live-bootstrap/sysa/patch-2.5.9/build/patch-2.5.9/xmalloc.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/build/patch-2.5.9/xmalloc.c

../git/live-bootstrap/sysa/patch-2.5.9/patch-2.5.9.checksums

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/patch-2.5.9/patch-2.5.9.checksums

../git/live-bootstrap/sysa/gzip-1.2.4/sources

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/gzip-1.2.4/sources

/sysa/distfiles/gzip-1.2.4.tar.gz

Source: https://mirrors.kernel.org/gnu/gzip/gzip-1.2.4.tar.gz

../git/live-bootstrap/sysa/gzip-1.2.4/mk/main.mk

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/gzip-1.2.4/mk/main.mk

../git/live-bootstrap/sysa/gzip-1.2.4/files/stat_override.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/gzip-1.2.4/files/stat_override.c

../git/live-bootstrap/sysa/gzip-1.2.4/patches/removecrc.patch

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/gzip-1.2.4/patches/removecrc.patch

../git/live-bootstrap/sysa/gzip-1.2.4/patches/makecrc-write-to-file.patch

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/gzip-1.2.4/patches/makecrc-write-to-file.patch

../git/live-bootstrap/sysa/gzip-1.2.4/build/gzip-1.2.4/sample/makecrc.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/gzip-1.2.4/build/gzip-1.2.4/sample/makecrc.c

../git/live-bootstrap/sysa/gzip-1.2.4/build/gzip-1.2.4/crc.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/gzip-1.2.4/build/gzip-1.2.4/crc.c

NoInput

../git/live-bootstrap/sysa/gzip-1.2.4/build/gzip-1.2.4/bits.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/gzip-1.2.4/build/gzip-1.2.4/bits.c

../git/live-bootstrap/sysa/gzip-1.2.4/build/gzip-1.2.4/tailor.h

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/gzip-1.2.4/build/gzip-1.2.4/tailor.h

../git/live-bootstrap/sysa/gzip-1.2.4/build/gzip-1.2.4/gzip.h

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/gzip-1.2.4/build/gzip-1.2.4/gzip.h

../git/live-bootstrap/sysa/gzip-1.2.4/build/gzip-1.2.4/crypt.h

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/gzip-1.2.4/build/gzip-1.2.4/crypt.h

../git/live-bootstrap/sysa/gzip-1.2.4/build/gzip-1.2.4/crypt.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/gzip-1.2.4/build/gzip-1.2.4/crypt.c

../git/live-bootstrap/sysa/gzip-1.2.4/build/gzip-1.2.4/deflate.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/gzip-1.2.4/build/gzip-1.2.4/deflate.c

../git/live-bootstrap/sysa/gzip-1.2.4/build/gzip-1.2.4/lzw.h

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/gzip-1.2.4/build/gzip-1.2.4/lzw.h

../git/live-bootstrap/sysa/gzip-1.2.4/build/gzip-1.2.4/getopt.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/gzip-1.2.4/build/gzip-1.2.4/getopt.c

../git/live-bootstrap/sysa/gzip-1.2.4/build/gzip-1.2.4/inflate.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/gzip-1.2.4/build/gzip-1.2.4/inflate.c

../git/live-bootstrap/sysa/gzip-1.2.4/build/gzip-1.2.4/lzw.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/gzip-1.2.4/build/gzip-1.2.4/lzw.c

../git/live-bootstrap/sysa/gzip-1.2.4/build/gzip-1.2.4/trees.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/gzip-1.2.4/build/gzip-1.2.4/trees.c

../git/live-bootstrap/sysa/gzip-1.2.4/build/gzip-1.2.4/unlzh.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/gzip-1.2.4/build/gzip-1.2.4/unlzh.c

../git/live-bootstrap/sysa/gzip-1.2.4/build/gzip-1.2.4/unlzw.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/gzip-1.2.4/build/gzip-1.2.4/unlzw.c

../git/live-bootstrap/sysa/gzip-1.2.4/build/gzip-1.2.4/unpack.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/gzip-1.2.4/build/gzip-1.2.4/unpack.c

../git/live-bootstrap/sysa/gzip-1.2.4/build/gzip-1.2.4/unzip.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/gzip-1.2.4/build/gzip-1.2.4/unzip.c

../git/live-bootstrap/sysa/gzip-1.2.4/build/gzip-1.2.4/zip.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/gzip-1.2.4/build/gzip-1.2.4/zip.c

../git/live-bootstrap/sysa/gzip-1.2.4/gzip-1.2.4.checksums

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/gzip-1.2.4/gzip-1.2.4.checksums

../git/live-bootstrap/sysa/tar-1.12/sources

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/tar-1.12/sources

/sysa/distfiles/tar-1.12.tar.gz

Source: https://mirrors.kernel.org/gnu/tar/tar-1.12.tar.gz

../git/live-bootstrap/sysa/tar-1.12/mk/main.mk

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/tar-1.12/mk/main.mk

../git/live-bootstrap/sysa/tar-1.12/files/getdate_stub.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/tar-1.12/files/getdate_stub.c

../git/live-bootstrap/sysa/tar-1.12/files/stat_override.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/tar-1.12/files/stat_override.c

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/lib/argmatch.c

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//lib/argmatch.c?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/lib/backupfile.c

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//lib/backupfile.c?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/lib/error.c

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//lib/error.c?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/lib/fnmatch.c

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//lib/fnmatch.c?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/lib/ftruncate.c

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//lib/ftruncate.c?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/lib/getdate.h

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//lib/getdate.h?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/lib/getopt.c

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//lib/getopt.c?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/lib/getopt1.c

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//lib/getopt1.c?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/lib/getversion.c

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//lib/getversion.c?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/lib/modechange.c

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//lib/modechange.c?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/lib/msleep.c

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//lib/msleep.c?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/lib/xgetcwd.c

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//lib/xgetcwd.c?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/lib/xmalloc.c

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//lib/xmalloc.c?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/lib/xstrdup.c

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//lib/xstrdup.c?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/src/arith.c

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//src/arith.c?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/src/system.h

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//src/system.h?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/src/common.h

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//src/common.h?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/src/tar.h

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//src/tar.h?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/src/buffer.c

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//src/buffer.c?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/src/compare.c

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//src/compare.c?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/src/delete.c

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//src/delete.c?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/src/rmt.h

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//src/rmt.h?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/src/extract.c

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//src/extract.c?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/src/incremen.c

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//src/incremen.c?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/src/list.c

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//src/list.c?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/src/mangle.c

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//src/mangle.c?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/src/misc.c

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//src/misc.c?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/lib/backupfile.h

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//lib/backupfile.h?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/src/names.c

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//src/names.c?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/lib/fnmatch.h

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//lib/fnmatch.h?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/src/open3.c

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//src/open3.c?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/src/rtapelib.c

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//src/rtapelib.c?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/src/tar.c

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//src/tar.c?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/lib/getopt.h

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//lib/getopt.h?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/build/tar-1.12/src/update.c

Source: https://git.savannah.gnu.org/cgit/tar.git/tree//src/update.c?id=e9da8d1a8020ad4dfe92416f3c77a33e6906b55e

../git/live-bootstrap/sysa/tar-1.12/tar-1.12.checksums

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/tar-1.12/tar-1.12.checksums

../git/live-bootstrap/sysa/sed-4.0.9/sources

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/sed-4.0.9/sources

/sysa/distfiles/sed-4.0.9.tar.gz

Source: https://mirrors.kernel.org/gnu/sed/sed-4.0.9.tar.gz

../git/live-bootstrap/sysa/sed-4.0.9/mk/main.mk

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/sed-4.0.9/mk/main.mk

../git/live-bootstrap/sysa/sed-4.0.9/build/sed-4.0.9/lib/alloca.c

Source: https://git.savannah.gnu.org/cgit/sed.git/tree/lib/alloca.c?id=9c9919efe2166efd32409054005619062624226c

../git/live-bootstrap/sysa/sed-4.0.9/build/sed-4.0.9/lib/getopt1.c

Source: https://git.savannah.gnu.org/cgit/sed.git/tree/lib/getopt1.c?id=9c9919efe2166efd32409054005619062624226c

../git/live-bootstrap/sysa/sed-4.0.9/build/sed-4.0.9/lib/getopt.c

Source: https://git.savannah.gnu.org/cgit/sed.git/tree/lib/getopt.c?id=9c9919efe2166efd32409054005619062624226c

../git/live-bootstrap/sysa/sed-4.0.9/build/sed-4.0.9/lib/utils.c

Source: https://git.savannah.gnu.org/cgit/sed.git/tree/lib/utils.c?id=9c9919efe2166efd32409054005619062624226c

../git/live-bootstrap/sysa/sed-4.0.9/build/sed-4.0.9/lib/regex_.h

Source: https://git.savannah.gnu.org/cgit/sed.git/tree/lib/regex_.h?id=9c9919efe2166efd32409054005619062624226c

../git/live-bootstrap/sysa/sed-4.0.9/build/sed-4.0.9/lib/regex.c

Source: https://git.savannah.gnu.org/cgit/sed.git/tree/lib/regex.c?id=9c9919efe2166efd32409054005619062624226c

../git/live-bootstrap/sysa/sed-4.0.9/build/sed-4.0.9/lib/obstack.c

Source: https://git.savannah.gnu.org/cgit/sed.git/tree/lib/obstack.c?id=9c9919efe2166efd32409054005619062624226c

../git/live-bootstrap/sysa/sed-4.0.9/build/sed-4.0.9/lib/obstack.h

Source: https://git.savannah.gnu.org/cgit/sed.git/tree/lib/obstack.h?id=9c9919efe2166efd32409054005619062624226c

../git/live-bootstrap/sysa/sed-4.0.9/build/sed-4.0.9/lib/strverscmp.c

Source: https://git.savannah.gnu.org/cgit/sed.git/tree/lib/strverscmp.c?id=9c9919efe2166efd32409054005619062624226c

../git/live-bootstrap/sysa/sed-4.0.9/build/sed-4.0.9/lib/mkstemp.c

Source: https://git.savannah.gnu.org/cgit/sed.git/tree/lib/mkstemp.c?id=9c9919efe2166efd32409054005619062624226c

../git/live-bootstrap/sysa/sed-4.0.9/build/sed-4.0.9/sed/compile.c

Source: https://git.savannah.gnu.org/cgit/sed.git/tree/sed/compile.c?id=9c9919efe2166efd32409054005619062624226c

../git/live-bootstrap/sysa/sed-4.0.9/build/sed-4.0.9/sed/sed.h

Source: https://git.savannah.gnu.org/cgit/sed.git/tree/sed/sed.h?id=9c9919efe2166efd32409054005619062624226c

../git/live-bootstrap/sysa/sed-4.0.9/build/sed-4.0.9/lib/strverscmp.h

Source: https://git.savannah.gnu.org/cgit/sed.git/tree/lib/strverscmp.h?id=9c9919efe2166efd32409054005619062624226c

../git/live-bootstrap/sysa/sed-4.0.9/build/sed-4.0.9/sed/execute.c

Source: https://git.savannah.gnu.org/cgit/sed.git/tree/sed/execute.c?id=9c9919efe2166efd32409054005619062624226c

../git/live-bootstrap/sysa/sed-4.0.9/build/sed-4.0.9/sed/regexp.c

Source: https://git.savannah.gnu.org/cgit/sed.git/tree/sed/regexp.c?id=9c9919efe2166efd32409054005619062624226c

../git/live-bootstrap/sysa/sed-4.0.9/build/sed-4.0.9/sed/fmt.c

Source: https://git.savannah.gnu.org/cgit/sed.git/tree/sed/fmt.c?id=9c9919efe2166efd32409054005619062624226c

../git/live-bootstrap/sysa/sed-4.0.9/build/sed-4.0.9/sed/sed.c

Source: https://git.savannah.gnu.org/cgit/sed.git/tree/sed/sed.c?id=9c9919efe2166efd32409054005619062624226c

../git/live-bootstrap/sysa/sed-4.0.9/sed-4.0.9.checksums

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/sed-4.0.9/sed-4.0.9.checksums

../git/live-bootstrap/sysa/bzip2-1.0.8/sources

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/bzip2-1.0.8/sources

/sysa/distfiles/bzip2-1.0.8.tar.gz

Source: https://sourceware.org/pub/bzip2/bzip2-1.0.8.tar.gz

../git/live-bootstrap/sysa/bzip2-1.0.8/patches/mes-libc.patch

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/bzip2-1.0.8/patches/mes-libc.patch

../git/live-bootstrap/sysa/bzip2-1.0.8/build/bzip2-1.0.8/bzip2.c

Source: https://github.com/libarchive/bzip2/blob/6a8690fc8d26c815e798c588f796eabe9d684cf0/bzip2.c

../git/live-bootstrap/sysa/bzip2-1.0.8/patches/coreutils.patch

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/bzip2-1.0.8/patches/coreutils.patch

../git/live-bootstrap/sysa/bzip2-1.0.8/build/bzip2-1.0.8/Makefile

Source: https://github.com/libarchive/bzip2/blob/6a8690fc8d26c815e798c588f796eabe9d684cf0/Makefile

../git/live-bootstrap/sysa/bzip2-1.0.8/build/bzip2-1.0.8/blocksort.c

Source: https://github.com/libarchive/bzip2/blob/6a8690fc8d26c815e798c588f796eabe9d684cf0/blocksort.c

../git/live-bootstrap/sysa/bzip2-1.0.8/build/bzip2-1.0.8/bzlib_private.h

Source: https://github.com/libarchive/bzip2/blob/6a8690fc8d26c815e798c588f796eabe9d684cf0/bzlib_private.h

../git/live-bootstrap/sysa/bzip2-1.0.8/build/bzip2-1.0.8/bzlib.h

Source: https://github.com/libarchive/bzip2/blob/6a8690fc8d26c815e798c588f796eabe9d684cf0/bzlib.h

../git/live-bootstrap/sysa/bzip2-1.0.8/build/bzip2-1.0.8/huffman.c

Source: https://github.com/libarchive/bzip2/blob/6a8690fc8d26c815e798c588f796eabe9d684cf0/huffman.c

../git/live-bootstrap/sysa/bzip2-1.0.8/build/bzip2-1.0.8/crctable.c

Source: https://github.com/libarchive/bzip2/blob/6a8690fc8d26c815e798c588f796eabe9d684cf0/crctable.c

../git/live-bootstrap/sysa/bzip2-1.0.8/build/bzip2-1.0.8/randtable.c

Source: https://github.com/libarchive/bzip2/blob/6a8690fc8d26c815e798c588f796eabe9d684cf0/randtable.c

../git/live-bootstrap/sysa/bzip2-1.0.8/build/bzip2-1.0.8/compress.c

Source: https://github.com/libarchive/bzip2/blob/6a8690fc8d26c815e798c588f796eabe9d684cf0/compress.c

../git/live-bootstrap/sysa/bzip2-1.0.8/build/bzip2-1.0.8/decompress.c

Source: https://github.com/libarchive/bzip2/blob/6a8690fc8d26c815e798c588f796eabe9d684cf0/decompress.c

../git/live-bootstrap/sysa/bzip2-1.0.8/build/bzip2-1.0.8/bzlib.c

Source: https://github.com/libarchive/bzip2/blob/6a8690fc8d26c815e798c588f796eabe9d684cf0/bzlib.c

../git/live-bootstrap/sysa/bzip2-1.0.8/bzip2-1.0.8.checksums

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/bzip2-1.0.8/bzip2-1.0.8.checksums

../git/live-bootstrap/sysa/coreutils-5.0/sources

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/coreutils-5.0/sources

/sysa/distfiles/coreutils-5.0.tar.bz2

Source: https://mirrors.kernel.org/gnu/coreutils/coreutils-5.0.tar.bz2

../git/live-bootstrap/sysa/coreutils-5.0/mk/main.mk

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/coreutils-5.0/mk/main.mk

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/fnmatch_.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/fnmatch_.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/ftw_.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/ftw_.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/search_.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/search_.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/patches/modechange.patch

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/coreutils-5.0/patches/modechange.patch

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/modechange.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/modechange.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/patches/mbstate.patch

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/coreutils-5.0/patches/mbstate.patch

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/quotearg.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/quotearg.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/patches/ls-strcmp.patch

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/coreutils-5.0/patches/ls-strcmp.patch

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/ls.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/ls.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/patches/touch-getdate.patch

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/coreutils-5.0/patches/touch-getdate.patch

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/touch.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/touch.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/patches/touch-dereference.patch

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/coreutils-5.0/patches/touch-dereference.patch

../git/live-bootstrap/sysa/coreutils-5.0/patches/tac-uint64.patch

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/coreutils-5.0/patches/tac-uint64.patch

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/tempname.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/tempname.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/patches/expr-strcmp.patch

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/coreutils-5.0/patches/expr-strcmp.patch

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/expr.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/expr.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/patches/sort-locale.patch

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/coreutils-5.0/patches/sort-locale.patch

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/memcoll.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/memcoll.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/sort.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/sort.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/patches/uniq-fopen.patch

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/coreutils-5.0/patches/uniq-fopen.patch

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/uniq.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/uniq.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/basename.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/basename.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/system.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/system.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/long-options.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/long-options.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/dirname.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/dirname.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/error.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/error.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/closeout.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/closeout.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/acl.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/acl.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/posixtm.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/posixtm.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/posixver.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/posixver.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/strftime.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/strftime.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/getopt.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/getopt.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/getopt1.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/getopt1.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/hash.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/hash.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/hash-pjw.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/hash-pjw.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/addext.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/addext.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/argmatch.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/argmatch.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/backupfile.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/backupfile.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/basename.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/basename.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/canon-host.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/canon-host.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/closeout.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/closeout.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/cycle-check.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/cycle-check.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/diacrit.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/diacrit.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/dirname.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/dirname.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/dup-safer.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/dup-safer.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/error.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/error.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/exclude.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/exclude.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/exitfail.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/exitfail.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/filemode.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/filemode.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/__fpending.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/__fpending.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/file-type.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/file-type.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/fnmatch.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/fnmatch.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/fopen-safer.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/fopen-safer.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/full-read.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/full-read.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/full-write.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/full-write.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/gethostname.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/gethostname.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/getline.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/getline.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/getstr.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/getstr.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/gettime.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/gettime.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/hard-locale.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/hard-locale.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/human.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/human.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/idcache.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/idcache.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/isdir.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/isdir.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/imaxtostr.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/imaxtostr.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/inttostr.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/inttostr.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/inttostr.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/inttostr.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/linebuffer.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/linebuffer.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/localcharset.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/localcharset.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/long-options.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/long-options.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/makepath.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/makepath.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/mbswidth.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/mbswidth.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/md5.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/md5.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/memcasecmp.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/memcasecmp.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/offtostr.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/offtostr.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/path-concat.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/path-concat.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/physmem.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/physmem.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/quote.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/quote.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/readtokens.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/readtokens.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/rpmatch.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/rpmatch.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/safe-read.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/safe-read.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/safe-write.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/safe-write.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/same.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/same.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/save-cwd.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/save-cwd.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/savedir.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/savedir.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/settime.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/settime.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/sha.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/sha.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/stpcpy.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/stpcpy.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/stripslash.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/stripslash.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/strtoimax.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/strtoimax.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/strtoumax.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/strtoumax.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/umaxtostr.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/umaxtostr.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/unicodeio.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/unicodeio.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/userspec.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/userspec.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/version-etc.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/version-etc.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/xgetcwd.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/xgetcwd.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/xgethostname.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/xgethostname.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/xmalloc.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/xmalloc.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/xmemcoll.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/xmemcoll.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/xnanosleep.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/xnanosleep.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/xreadlink.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/xreadlink.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/xstrdup.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/xstrdup.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/xstrtod.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/xstrtod.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/xstrtol.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/xstrtol.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/xstrtoul.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/xstrtoul.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/xstrtoimax.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/xstrtoimax.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/xstrtoumax.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/xstrtoumax.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/yesno.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/yesno.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/strnlen.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/strnlen.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/getcwd.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/getcwd.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/pathmax.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/pathmax.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/same.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/same.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/sig2str.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/sig2str.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/mountlist.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/mountlist.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/regex.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/regex.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/canonicalize.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/canonicalize.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/mkstemp.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/mkstemp.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/memrchr.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/memrchr.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/euidaccess.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/euidaccess.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/ftw.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/ftw.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/dirfd.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/dirfd.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/obstack.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/obstack.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/strverscmp.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/strverscmp.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/tsearch.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/tsearch.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/cat.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/cat.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/getopt.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/getopt.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/full-write.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/full-write.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/safe-read.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/safe-read.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/chmod.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/chmod.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/filemode.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/filemode.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/modechange.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/modechange.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/quote.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/quote.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/savedir.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/savedir.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/cksum.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/cksum.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/csplit.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/csplit.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/regex.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/regex.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/xstrtol.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/xstrtol.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/cut.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/cut.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/getstr.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/getstr.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/dirname.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/dirname.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/echo.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/echo.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/expand.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/expand.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/posixver.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/posixver.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/factor.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/factor.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/readtokens.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/readtokens.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/wheel-size.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/wheel-size.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/wheel.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/wheel.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/true.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/true.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/version-etc.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/version-etc.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/fmt.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/fmt.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/fold.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/fold.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/head.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/head.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/hostname.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/hostname.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/id.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/id.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/join.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/join.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/hard-locale.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/hard-locale.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/linebuffer.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/linebuffer.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/memcasecmp.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/memcasecmp.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/xmemcoll.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/xmemcoll.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/kill.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/kill.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/link.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/link.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/ln.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/ln.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/logname.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/logname.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/mkfifo.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/mkfifo.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/mkdir.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/mkdir.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/makepath.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/makepath.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/mknod.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/mknod.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/nl.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/nl.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/od.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/od.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/paste.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/paste.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/pathchk.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/pathchk.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/pr.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/pr.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/mbswidth.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/mbswidth.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/printf.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/printf.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/unicodeio.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/unicodeio.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/ptx.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/ptx.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/argmatch.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/argmatch.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/bumpalloc.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/bumpalloc.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/diacrit.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/diacrit.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/pwd.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/pwd.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/xgetcwd.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/xgetcwd.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/readlink.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/readlink.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/canonicalize.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/canonicalize.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/xreadlink.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/xreadlink.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/rmdir.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/rmdir.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/seq.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/seq.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/xstrtod.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/xstrtod.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/sleep.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/sleep.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/xnanosleep.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/xnanosleep.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/physmem.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/physmem.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/stdio-safer.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/stdio-safer.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/split.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/split.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/full-read.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/full-read.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/sum.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/sum.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/human.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/human.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/tail.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/tail.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/tee.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/tee.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/tr.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/tr.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/tsort.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/tsort.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/unexpand.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/unexpand.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/unlink.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/unlink.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/wc.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/wc.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/whoami.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/whoami.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/tac.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/tac.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/test.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/test.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/getdate.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/getdate.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/posixtm.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/posixtm.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/yes.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/yes.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/cp.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/cp.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/copy.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/copy.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/cp-hash.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/cp-hash.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/hash.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/hash.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/cp-hash.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/cp-hash.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/ls-ls.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/ls-ls.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/ls.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/ls.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/install.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/install.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/md5.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/md5.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/checksum.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/checksum.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/md5sum.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/md5sum.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/md5.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/md5.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/sha.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/sha.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/getline.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/getline.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/mv.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/mv.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/remove.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/remove.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/rm.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/rm.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/remove.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/remove.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/lib/save-cwd.h

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/lib/save-cwd.h?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/build/coreutils-5.0/src/sha1sum.c

Source: https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/sha1sum.c?h=COREUTILS-5_0

../git/live-bootstrap/sysa/coreutils-5.0/coreutils-5.0.checksums

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/coreutils-5.0/coreutils-5.0.checksums

../git/live-bootstrap/sysa/heirloom-devtools-070527/sources

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/sources

/sysa/distfiles/heirloom-devtools-070527.tar.bz2

Source: http://downloads.sourceforge.net/project/heirloom/heirloom-devtools/070527/heirloom-devtools-070527.tar.bz2

../git/live-bootstrap/sysa/heirloom-devtools-070527/patches/yacc_remove_wchar.patch

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/patches/yacc_remove_wchar.patch

../git/live-bootstrap/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/yacc/dextern

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/yacc/dextern

../git/live-bootstrap/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/yacc/y1.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/yacc/y1.c

../git/live-bootstrap/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/yacc/y2.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/yacc/y2.c

../git/live-bootstrap/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/yacc/y3.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/yacc/y3.c

../git/live-bootstrap/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/yacc/y4.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/yacc/y4.c

../git/live-bootstrap/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/yacc/Makefile.mk

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/yacc/Makefile.mk

../git/live-bootstrap/sysa/heirloom-devtools-070527/patches/lex_remove_wchar.patch

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/patches/lex_remove_wchar.patch

../git/live-bootstrap/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/Makefile.mk

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/Makefile.mk

../git/live-bootstrap/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/allprint.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/allprint.c

../git/live-bootstrap/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/ldefs.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/ldefs.c

../git/live-bootstrap/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/main.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/main.c

../git/live-bootstrap/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/parser.y

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/parser.y

../git/live-bootstrap/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/reject.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/reject.c

../git/live-bootstrap/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/sub1.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/sub1.c

../git/live-bootstrap/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/sub3.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/sub3.c

../git/live-bootstrap/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/yacc/sgs.h

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/yacc/sgs.h

../git/live-bootstrap/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/yacc/getopt.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/yacc/getopt.c

../git/live-bootstrap/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/yacc/libmai.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/yacc/libmai.c

../git/live-bootstrap/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/yacc/libzer.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/yacc/libzer.c

../git/live-bootstrap/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/yacc/yaccpar

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/yacc/yaccpar

../git/live-bootstrap/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/once.h

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/once.h

../git/live-bootstrap/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/sgs.h

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/sgs.h

../git/live-bootstrap/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/sub2.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/sub2.c

../git/live-bootstrap/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/header.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/header.c

../git/live-bootstrap/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/getopt.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/getopt.c

../git/live-bootstrap/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/lsearch.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/lsearch.c

../git/live-bootstrap/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/search.h

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/search.h

../git/live-bootstrap/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/libmain.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/libmain.c

../git/live-bootstrap/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/yyless.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/yyless.c

../git/live-bootstrap/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/yywrap.c

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/yywrap.c

../git/live-bootstrap/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/ncform

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/build/heirloom-devtools-070527/lex/ncform

../git/live-bootstrap/sysa/heirloom-devtools-070527/heirloom-devtools-070527.checksums

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/heirloom-devtools-070527/heirloom-devtools-070527.checksums

../git/live-bootstrap/sysa/bash-2.05b/sources

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/bash-2.05b/sources

/sysa/distfiles/bash-2.05b.tar.gz

Source: https://mirrors.kernel.org/gnu/bash/bash-2.05b.tar.gz

../git/live-bootstrap/sysa/bash-2.05b/mk/main.mk

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/bash-2.05b/mk/main.mk

../git/live-bootstrap/sysa/bash-2.05b/mk/builtins.mk

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/bash-2.05b/mk/builtins.mk

../git/live-bootstrap/sysa/bash-2.05b/mk/common.mk

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/bash-2.05b/mk/common.mk

../git/live-bootstrap/sysa/bash-2.05b/patches/mes-libc.patch

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/bash-2.05b/patches/mes-libc.patch

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/snprintf.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/snprintf.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/patches/tinycc.patch

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/bash-2.05b/patches/tinycc.patch

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/oslib.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/oslib.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/patches/missing-defines.patch

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/bash-2.05b/patches/missing-defines.patch

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/execute_cmd.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/execute_cmd.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/patches/locale.patch

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/bash-2.05b/patches/locale.patch

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/locale.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/locale.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/patches/dev-tty.patch

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/bash-2.05b/patches/dev-tty.patch

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/shell.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/shell.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/mkbuiltins.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/mkbuiltins.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/alias.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/alias.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/bind.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/bind.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/break.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/break.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/builtin.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/builtin.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/cd.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/cd.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/colon.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/colon.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/command.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/command.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/complete.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/complete.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/declare.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/declare.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/echo.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/echo.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/enable.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/enable.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/eval.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/eval.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/exec.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/exec.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/exit.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/exit.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/fc.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/fc.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/fg_bg.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/fg_bg.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/hash.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/hash.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/history.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/history.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/jobs.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/jobs.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/kill.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/kill.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/let.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/let.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/read.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/read.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/return.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/return.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/set.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/set.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/setattr.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/setattr.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/shift.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/shift.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/source.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/source.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/suspend.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/suspend.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/test.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/test.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/times.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/times.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/trap.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/trap.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/type.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/type.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/ulimit.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/ulimit.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/umask.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/umask.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/wait.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/wait.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/getopts.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/getopts.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/pushd.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/pushd.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/shopt.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/shopt.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/printf.def

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/printf.def?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/bashtypes.h

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/bashtypes.h?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/include/posixstat.h

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/include/posixstat.h?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/include/filecntl.h

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/include/filecntl.h?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/include/chartypes.h

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/include/chartypes.h?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/bashansi.h

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/bashansi.h?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/shell.h

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/shell.h?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/include/stdc.h

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/include/stdc.h?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/bashgetopt.h

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/bashgetopt.h?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/common.h

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/common.h?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/common.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/common.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/evalstring.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/evalstring.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/evalfile.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/evalfile.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/getopt.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/getopt.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/builtins/bashgetopt.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/builtins/bashgetopt.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/clktck.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/clktck.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/getcwd.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/getcwd.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/getenv.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/getenv.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/setlinebuf.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/setlinebuf.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/xmalloc.h

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/xmalloc.h?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/strcasecmp.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/strcasecmp.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/strerror.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/strerror.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/strtod.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/strtod.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/vprint.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/vprint.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/itos.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/itos.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/rename.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/rename.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/zread.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/zread.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/zwrite.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/zwrite.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/shtty.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/shtty.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/inet_aton.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/inet_aton.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/netopen.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/netopen.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/strpbrk.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/strpbrk.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/timeval.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/timeval.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/clock.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/clock.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/makepath.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/makepath.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/pathcanon.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/pathcanon.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/pathphys.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/pathphys.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/stringlist.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/stringlist.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/stringvec.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/stringvec.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/tmpfile.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/tmpfile.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/include/posixtime.h

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/include/posixtime.h?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/spell.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/spell.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/strtrans.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/strtrans.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/strindex.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/strindex.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/shquote.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/shquote.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/mailstat.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/mailstat.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/include/posixdir.h

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/include/posixdir.h?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/include/maxpath.h

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/include/maxpath.h?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/fmtulong.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/fmtulong.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/fmtullong.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/fmtullong.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/strtoll.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/strtoll.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/strtoull.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/strtoull.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/strtoimax.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/strtoimax.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/strtoumax.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/strtoumax.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/fmtumax.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/fmtumax.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/netconn.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/netconn.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/mktime.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/mktime.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/strftime.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/strftime.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/xstrchr.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/xstrchr.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/sh/zcatfd.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/sh/zcatfd.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/glob/glob.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/glob/glob.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/glob/strmatch.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/glob/strmatch.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/glob/strmatch.h

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/glob/strmatch.h?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/glob/smatch.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/glob/smatch.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/include/shmbutil.h

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/include/shmbutil.h?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/glob/xmbsrtowcs.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/glob/xmbsrtowcs.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/lib/tilde/tilde.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/lib/tilde/tilde.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/eval.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/eval.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/parse.y

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/parse.y?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/general.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/general.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/make_cmd.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/make_cmd.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/print_cmd.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/print_cmd.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/dispose_cmd.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/dispose_cmd.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/variables.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/variables.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/copy_cmd.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/copy_cmd.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/error.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/error.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/expr.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/expr.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/flags.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/flags.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/nojobs.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/nojobs.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/subst.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/subst.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/hashcmd.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/hashcmd.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/hashlib.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/hashlib.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/mailcheck.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/mailcheck.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/support/mksignames.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/support/mksignames.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/trap.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/trap.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/input.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/input.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/unwind_prot.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/unwind_prot.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/pathexp.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/pathexp.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/sig.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/sig.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/test.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/test.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/version.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/version.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/patchlevel.h

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/patchlevel.h?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/conftypes.h

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/conftypes.h?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/alias.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/alias.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/array.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/array.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/arrayfunc.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/arrayfunc.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/braces.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/braces.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/bracecomp.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/bracecomp.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/bashhist.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/bashhist.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/bashline.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/bashline.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/list.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/list.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/stringlib.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/stringlib.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/findcmd.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/findcmd.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/redir.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/redir.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/pcomplete.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/pcomplete.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/pcomplib.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/pcomplib.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/mksyntax.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/mksyntax.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/syntax.h

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/syntax.h?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/xmalloc.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/xmalloc.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/build/bash-2.05b/siglist.c

Source: https://git.savannah.gnu.org/cgit/bash.git/tree/siglist.c?id=7117c2d221b2aed4ede8600f6a36b7c1454b4f55

../git/live-bootstrap/sysa/bash-2.05b/bash-2.05b.checksums

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/bash-2.05b/bash-2.05b.checksums

../git/live-bootstrap/sysa/run.sh

Source: https://github.com/fosslinux/live-bootstrap/blob/master/sysa/run.sh

Steps

Step 1

Step 2

Step 3

Step 4

Step 5

Step 6

Step 7

Step 8

Step 9

Step 10

Step 11

Step 12

Step 13

Step 14

Step 15

Step 16

Step 17

Step 18

Step 19

Step 20

Step 21

Step 22

Step 23

Step 24

Step 25

Step 26

Step 27

Step 28

Step 29

Step 30

Step 31

Step 32

Step 33

Step 34

Step 35

Step 36

Step 37

Step 38

Step 39

Step 40

Step 41

Step 42

Step 43

Step 44

Step 45

Step 46

Step 47

Step 48

Step 49

Step 50

Step 51

Step 52

Step 53

Step 54

Step 55

Step 56

Step 57

Step 58

Step 59

Step 60

Step 61

Step 62

Step 63

Step 64

Step 65

Step 66

Step 67

Step 68

Step 69

Step 70

Step 71

Step 72

Step 73

Step 74

Step 75

Step 76

Step 77

Step 78

Step 79

Step 80

Step 81

Step 82

Step 83

Step 84

Step 85

Step 86

Step 87

Step 88

Step 89

Step 90

Step 91

Step 92

Step 93

Step 94

Step 95

Step 96

Step 97

Step 98

Step 99

Step 100

Step 101

Step 102

Step 103

Step 104

Step 105

Step 106

Step 107

Step 108

Step 109

Step 110

Step 111

Step 112

Step 113

Step 114

Step 115

Step 116

Step 117

Step 118

Step 119

Step 120

Step 121

Step 122

Step 123

Step 124

Step 125

Step 126

Step 127

Step 128

Step 129

Step 130

Step 131

Step 132

Step 133

Step 134

Step 135

Step 136

Step 137

Step 138

Step 139

Step 140

Step 141

Step 142

Step 143

Step 144

Step 145

Step 146

Step 147

Step 148

Step 149

Step 150

Step 151

Step 152

Step 153

Step 154

Step 155

Step 156

Step 157

Step 158

Step 159

Step 160

Step 161

Step 162

Step 163

Step 164

Step 165

Step 166

Step 167

Step 168

Step 169

Step 170

Step 171

Step 172

Step 173

Step 174

Step 175

Step 176

Step 177

Step 178

Step 179

Step 180

Step 181

Step 182

Step 183

Step 184

Step 185

Step 186

Step 187

Step 188

Step 189

Step 190

Step 191

Step 192

Step 193

Step 194

Step 195

Step 196

Step 197

Step 198

Step 199

Step 200

Step 201

Step 202

Step 203

Step 204

Step 205

Step 206

Step 207

Step 208

Step 209

Step 210

Step 211

Step 212

Step 213

Step 214

Step 215

Step 216

Step 217

Step 218

Step 219

Step 220

Step 221

Step 222

Step 223

Step 224

Step 225

Step 226

Step 227

Step 228

Step 229

Step 230

Step 231

Step 232

Step 233

Step 234

Step 235

Step 236

Step 237

Step 238

Step 239

Step 240

Step 241

Step 242

Step 243

Step 244

Step 245

Step 246

Step 247

Step 248

Step 249

Step 250

Step 251

Step 252

Step 253

Step 254

Step 255

Step 256

Step 257

Step 258

Step 259

Step 260

Step 261

Step 262

Step 263

Step 264

Step 265

Step 266

Step 267

Step 268

Step 269

Step 270

Step 271

Step 272

Step 273

Step 274

Step 275

Step 276

Step 277

Step 278

Step 279

Step 280

Step 281

Step 282

Step 283

Step 284

Step 285

Step 286

Step 287

Step 288

Step 289

Step 290

Step 291

Step 292

Step 293

Step 294

Step 295

Step 296

Step 297

Step 298

Step 299

Step 300

Step 301

Step 302

Step 303

Step 304

Step 305

Step 306

Step 307

Step 308

Step 309

Step 310

Step 311

Step 312

Step 313

Step 314

Step 315

Step 316

Step 317

Step 318

Step 319

Step 320

Step 321

Step 322

Step 323

Step 324

Step 325

Step 326

Step 327

Step 328

Step 329

Step 330

Step 331

Step 332

Step 333

Step 334

Step 335

Step 336

Step 337

Step 338

Step 339

Step 340

Step 341

Step 342

Step 343

Step 344

Step 345

Step 346

Step 347

Step 348

Step 349

Step 350

Step 351

Step 352

Step 353

Step 354

Step 355

Step 356

Step 357

Step 358

Step 359

Step 360

Step 361

Step 362

Step 363

Step 364

Step 365

Step 366

Step 367

Step 368

Step 369

Step 370

Step 371

Step 372

Step 373

Step 374

Step 375

Step 376

Step 377

Step 378

Step 379

Step 380

Step 381

Step 382

Step 383

Step 384

Step 385

Step 386

Step 387

Step 388

Step 389

Step 390

Step 391

Step 392

Step 393

Step 394

Step 395

Step 396

Step 397

Step 398

Step 399

Step 400

Step 401

Step 402

Step 403

Step 404

Step 405

Step 406

Step 407

Step 408

Step 409

Step 410

Step 411

Step 412

Step 413

Step 414

Step 415

Step 416

Step 417

Step 418

Step 419

Step 420

Step 421

Step 422

Step 423

Step 424

Step 425

Step 426

Step 427

Step 428

Step 429

Step 430

Step 431

Step 432

Step 433

Step 434

Step 435

Step 436

Step 437

Step 438

Step 439

Step 440

Step 441

Step 442

Step 443

Step 444

Step 445

Step 446

Step 447

Step 448

Step 449

Step 450

Step 451

Step 452

Step 453

Step 454

Step 455

Step 456

Step 457

Step 458

Step 459

Step 460

Step 461

Step 462

Step 463

Step 464

Step 465

Step 466

Step 467

Step 468

Step 469

Step 470

Step 471

Step 472

Step 473

Step 474

Step 475

Step 476

Step 477

Step 478

Step 479

Step 480

Step 481

Step 482

Step 483

Step 484

Step 485

Step 486

Step 487

Step 488

Step 489

Step 490

Step 491

Step 492

Step 493

Step 494

Step 495

Step 496

Step 497

Step 498

Step 499

Step 500

Step 501

Step 502

Step 503

Step 504

Step 505

Step 506

Step 507

Step 508

Step 509

Step 510

Step 511

Step 512

Step 513

Step 514

Step 515

Step 516

Step 517

Step 518

Step 519

Step 520

Step 521

Step 522

Step 523

Step 524

Step 525

Step 526

Step 527

Step 528

Step 529

Step 530

Step 531

Step 532

Step 533

Step 534

Step 535

Step 536

Step 537

Step 538

Step 539

Step 540

Step 541

Step 542

Step 543

Step 544

Step 545

Step 546

Step 547

Step 548

Step 549

Step 550

Step 551

Step 552

Step 553

Step 554

Step 555

Step 556

Step 557

Step 558

Step 559

Step 560

Step 561

Step 562

Step 563

Step 564

Step 565

Step 566

Step 567

Step 568

Step 569

Step 570

Step 571

Step 572

Step 573

Step 574

Step 575

Step 576

Step 577

Step 578

Step 579

Step 580

Step 581

Step 582

Step 583

Step 584

Step 585

Step 586

Step 587

Step 588

Step 589

Step 590

Step 591

Step 592

Step 593

Step 594

Step 595

Step 596

Step 597

Step 598

Step 599

Step 600

Step 601

Step 602

Step 603

Step 604

Step 605

Step 606

Step 607

Step 608

Step 609

Step 610

Step 611

Step 612

Step 613

Step 614

Step 615

Step 616

Step 617

Step 618

Step 619

Step 620

Step 621

Step 622

Step 623

Step 624

Step 625

Step 626

Step 627

Step 628

Step 629

Step 630

Step 631

Step 632

Step 633

Step 634

Step 635

Step 636

Step 637

Step 638

Step 639

Step 640

Step 641

Step 642

Step 643

Step 644

Step 645

Step 646

Step 647

Step 648

Step 649

Step 650

Step 651

Step 652

Step 653

Step 654

Step 655

Step 656

Step 657

Step 658

Step 659

Step 660

Step 661

Step 662

Step 663

Step 664

Step 665

Step 666

Step 667

Step 668

Step 669

Step 670

Step 671

Step 672

Step 673

Step 674

Step 675

Step 676

Step 677

Step 678

Step 679

Step 680

Step 681

Step 682

Step 683

Step 684

Step 685

Step 686

Step 687

Step 688

Step 689

Step 690

Step 691

Step 692

Step 693

Step 694

Step 695

Step 696

Step 697

Step 698

Step 699

Step 700

Step 701

Step 702

Step 703

Step 704

Step 705

Step 706

Step 707

Step 708

Step 709

Step 710

Step 711

Step 712

Step 713

Step 714

Step 715

Step 716

Step 717

Step 718

Step 719

Step 720

Step 721

Step 722

Step 723

Step 724

Step 725

Step 726

Step 727

Step 728

Step 729

Step 730

Step 731

Step 732

Step 733

Step 734

Step 735

Step 736

Step 737

Step 738

Step 739

Step 740

Step 741

Step 742

Step 743

Step 744

Step 745

Step 746

Step 747

Step 748

Step 749

Step 750

Step 751

Step 752

Step 753

Step 754

Step 755

Step 756

Step 757

Step 758

Step 759

Step 760

Step 761

Step 762

Step 763

Step 764

Step 765

Step 766

Step 767

Step 768

Step 769

Step 770

Step 771

Step 772

Step 773

Step 774

Step 775

Step 776

Step 777

Step 778

Step 779

Step 780

Step 781

Step 782

Step 783

Step 784

Step 785

Step 786

Step 787

Step 788

Step 789

Step 790

Step 791

Step 792

Step 793

Step 794

Step 795

Step 796

Step 797

Step 798

Step 799

Step 800

Step 801

Step 802

Step 803

Step 804

Step 805

Step 806

Step 807

Step 808

Step 809

Step 810

Step 811

Step 812

Step 813

Step 814

Step 815

Step 816

Step 817

Step 818

Step 819

Step 820

Step 821

Step 822

Step 823

Step 824

Step 825

Step 826

Step 827

Step 828

Step 829

Step 830

Step 831

Step 832

Step 833

Step 834

Step 835

Step 836

Step 837

Step 838

Step 839

Step 840

Step 841

Step 842

Step 843

Step 844

Step 845

Step 846

Step 847

Step 848

Step 849

Step 850

Step 851

Step 852

Step 853

Step 854

Step 855

Step 856

Step 857

Step 858

Step 859

Step 860

Step 861

Step 862

Step 863

Step 864

Step 865

Step 866

Step 867

Step 868

Step 869

Step 870

Step 871

Step 872

Step 873

Step 874

Step 875

Step 876

Step 877

Step 878

Step 879

Step 880

Step 881

Step 882

Step 883

Step 884

Step 885

Step 886

Step 887

Step 888

Step 889

Step 890

Step 891

Step 892

Step 893

Step 894

Step 895

Step 896

Step 897

Step 898

Step 899

Step 900

Step 901

Step 902

Step 903

Step 904

Step 905

Step 906

Step 907

Step 908

Step 909

Step 910

Step 911

Step 912

Step 913

Step 914

Step 915

Step 916

Step 917

Step 918

Step 919

Step 920

Step 921

Step 922

Step 923

Step 924

Step 925

Step 926

Step 927

Step 928

Step 929

Step 930

Step 931

Step 932

Step 933

Step 934

Step 935

Step 936

Step 937

Step 938

Step 939

Step 940

Step 941

Step 942

Step 943

Step 944

Step 945

Step 946

Step 947

Step 948

Step 949

Step 950

Step 951

Step 952

Step 953

Step 954

Step 955

Step 956

Step 957

Step 958

Step 959

Step 960

Step 961

Step 962

Step 963

Step 964

Step 965

Step 966

Step 967

Step 968

Step 969

Step 970

Step 971

Step 972

Step 973

Step 974

Step 975

Step 976

Step 977

Step 978

Step 979

Step 980

Step 981

Step 982

Step 983

Step 984

Step 985

Step 986

Step 987

Step 988

Step 989

Step 990

Step 991

Step 992

Step 993

Step 994

Step 995

Step 996

Step 997

Step 998

Step 999

Step 1000

Step 1001

Step 1002

Step 1003

Step 1004

Step 1005

Step 1006

Step 1007

Step 1008

Step 1009

Step 1010

Step 1011

Step 1012

Step 1013

Step 1014

Step 1015

Step 1016

Step 1017

Step 1018

Step 1019

Step 1020

Step 1021

Step 1022

Step 1023

Step 1024

Step 1025

Step 1026

Step 1027

Step 1028

Step 1029

Step 1030

Step 1031

Step 1032

Step 1033

Step 1034

Step 1035

Step 1036

Step 1037

Step 1038

Step 1039

Step 1040

Step 1041

Step 1042

Step 1043

Step 1044

Step 1045

Step 1046

Step 1047

Step 1048

Step 1049

Step 1050

Step 1051

Step 1052

Step 1053

Step 1054

Step 1055

Step 1056

Step 1057

Step 1058

Step 1059

Step 1060

Step 1061

Step 1062

Step 1063

Step 1064

Step 1065

Step 1066

Step 1067

Step 1068

Step 1069

Step 1070

Step 1071

Step 1072

Step 1073

Step 1074

Step 1075

Step 1076

Step 1077

Step 1078

Step 1079

Step 1080

Step 1081

Step 1082

Step 1083

Step 1084

Step 1085

Step 1086

Step 1087

Step 1088

Step 1089

Step 1090

Step 1091

Step 1092

Step 1093

Step 1094

Step 1095

Step 1096

Step 1097

Step 1098

Step 1099

Step 1100

Step 1101

Step 1102

Step 1103

Step 1104

Step 1105

Step 1106

Step 1107

Step 1108

Step 1109

Step 1110

Step 1111

Step 1112

Step 1113

Step 1114

Step 1115

Step 1116

Step 1117

Step 1118

Step 1119

Step 1120

Step 1121

Step 1122

Step 1123

Step 1124

Step 1125

Step 1126

Step 1127

Step 1128

Step 1129

Step 1130

Step 1131

Step 1132

Step 1133

Step 1134

Step 1135

Step 1136

Step 1137

Step 1138

Step 1139

Step 1140

Step 1141

Step 1142

Step 1143

Step 1144

Step 1145

Step 1146

Step 1147

Step 1148

Step 1149

Step 1150

Step 1151

Step 1152

Step 1153

Step 1154

Step 1155

Step 1156

Step 1157

Step 1158

Step 1159

Step 1160

Step 1161

Step 1162

Step 1163

Step 1164

Step 1165

Step 1166

Step 1167

Step 1168

Step 1169

Step 1170

Step 1171

Step 1172

Step 1173

Step 1174

Step 1175

Step 1176

Step 1177

Step 1178

Step 1179

Step 1180

Step 1181

Step 1182

Step 1183

Step 1184

Step 1185

Step 1186

Step 1187

Step 1188

Step 1189

Step 1190

Step 1191

Step 1192

Step 1193

Step 1194

Step 1195

Step 1196

Step 1197

Step 1198

Step 1199

Step 1200

Step 1201

Step 1202

Step 1203

Step 1204

Step 1205

Step 1206

Step 1207

Step 1208

Step 1209

Step 1210

Step 1211

Step 1212

Step 1213

Step 1214

Step 1215

Step 1216

Step 1217

Step 1218

Step 1219

Step 1220

Step 1221

Step 1222

Step 1223

Step 1224

Step 1225

Step 1226

Step 1227

Step 1228

Step 1229

Step 1230

Step 1231

Step 1232

Step 1233

Step 1234

Step 1235

Step 1236

Step 1237

Step 1238

Step 1239

Step 1240

Step 1241

Step 1242

Step 1243

Step 1244

Step 1245

Step 1246

Step 1247

Step 1248

Step 1249

Step 1250

Step 1251

Step 1252

Step 1253

Step 1254

Step 1255

Step 1256

Step 1257

Step 1258

Step 1259

Output files

Sources

https://mirrors.kernel.org/gnu/mes/mes-0.24.2.tar.gz

File: /sysa/distfiles/mes-0.24.2.tar.gz used in: Step 89, Step 372, Step 480

https://download.savannah.gnu.org/releases/nyacc/nyacc-1.00.2.tar.gz

File: /sysa/distfiles/nyacc-1.00.2.tar.gz used in: Step 88

https://lilypond.org/janneke/tcc/tcc-0.9.26-1136-g5bba73cc.tar.gz

File: /sysa/distfiles/tcc-0.9.26.tar.gz used in: Step 371

https://download.savannah.gnu.org/releases/tinycc/tcc-0.9.27.tar.bz2

File: /sysa/distfiles/tcc-0.9.27.tar.bz2 used in: Step 479

https://mirrors.kernel.org/gnu/make/make-3.82.tar.bz2

File: /sysa/distfiles/make-3.82.tar.bz2 used in: Step 510

https://mirrors.kernel.org/gnu/patch/patch-2.5.9.tar.gz

File: /sysa/distfiles/patch-2.5.9.tar.gz used in: Step 551

https://mirrors.kernel.org/gnu/gzip/gzip-1.2.4.tar.gz

File: /sysa/distfiles/gzip-1.2.4.tar.gz used in: Step 586

https://mirrors.kernel.org/gnu/tar/tar-1.12.tar.gz

File: /sysa/distfiles/tar-1.12.tar.gz used in: Step 624

https://mirrors.kernel.org/gnu/sed/sed-4.0.9.tar.gz

File: /sysa/distfiles/sed-4.0.9.tar.gz used in: Step 672

https://sourceware.org/pub/bzip2/bzip2-1.0.8.tar.gz

File: /sysa/distfiles/bzip2-1.0.8.tar.gz used in: Step 702

https://mirrors.kernel.org/gnu/coreutils/coreutils-5.0.tar.bz2

File: /sysa/distfiles/coreutils-5.0.tar.bz2 used in: Step 730

http://downloads.sourceforge.net/project/heirloom/heirloom-devtools/070527/heirloom-devtools-070527.tar.bz2

File: /sysa/distfiles/heirloom-devtools-070527.tar.bz2 used in: Step 985

https://mirrors.kernel.org/gnu/bash/bash-2.05b.tar.gz

File: /sysa/distfiles/bash-2.05b.tar.gz used in: Step 1038

https://github.com/oriansj/bootstrap-seeds/blob/main/POSIX/x86/kaem-optional-seed

File: ../git/live-bootstrap/sysa/stage0-posix/src/bootstrap-seeds/POSIX/x86/kaem-optional-seed used in:
 7F 45 4C 46 01 01 01 03 00 00
 00 00 00 00 00 00 02 00 03 00
 01 00 00 00 54 80 04 08 34 00
 00 00 00 00 00 00 00 00 00 00
 34 00 20 00 01 00 00 00 00 00
 00 00 01 00 00 00 00 00 00 00
 00 80 04 08 00 80 04 08 80 02
 00 00 80 02 00 00 07 00 00 00
 01 00 00 00 58 5B 5B 85 DB 75
 06 50 BB 3A 82 04 08 31 C9 6A
 05 58 CD 80 85 C0 7E 6C A3 68
 82 04 08 58 89 E5 6A 2D 58 31
 DB CD 80 A3 78 82 04 08 A1 70
 82 04 08 E8 3F 01 00 00 89 C3
 89 D9 31 C0 A3 7C 82 04 08 A3
 6C 82 04 08 E8 95 00 00 00 85
 C0 74 05 89 01 83 C1 04 A1 6C
 82 04 08 85 C0 74 E9 39 CB 74
 CB E8 4F 00 00 00 8B 03 85 C0
 74 18 53 6A 02 58 CD 80 5B 85
 C0 7C 0D 75 12 6A 0B 58 89 EA
 89 D9 8B 1B CD 80 6A 01 5B 89
 D8 CD 80 89 C3 B9 7C 82 04 08
 31 D2 6A 07 58 CD 80 A1 7C 82
 04 08 85 C0 74 8A B8 48 82 04
 08 E8 07 01 00 00 EB D6 31 DB
 6A 01 58 CD 80 53 B8 43 82 04
 08 E8 F3 00 00 00 8B 03 E8 EC
 00 00 00 83 C3 04 6A 20 58 E8
 FE 00 00 00 39 CB 75 EA 6A 0A
 58 E8 F2 00 00 00 5B C3 53 51
 A1 74 82 04 08 E8 89 00 00 00
 89 C3 89 C1 E8 9F 00 00 00 3C
 FC 74 B5 3C 20 74 42 3C 09 74
 3E 3C 0A 75 0A 6A 01 58 A3 6C
 82 04 08 EB 30 3C 22 75 07 E8
 32 00 00 00 EB 25 3C 23 75 0F
 E8 40 00 00 00 6A 01 58 A3 6C
 82 04 08 EB 12 3C 5C 75 07 E8
 5E 00 00 00 EB 07 88 01 83 C1
 01 EB B1 39 CB 75 02 31 DB 89
 D8 59 5B C3 E8 45 00 00 00 3C
 FC 0F 84 2D FF FF FF 3C 22 74
 07 88 01 83 C1 01 EB E8 C3 E8
 2C 00 00 00 3C FC 0F 84 14 FF
 FF FF 3C 0A 75 EF C3 53 51 52
 8B 1D 78 82 04 08 01 C3 6A 2D
 58 CD 80 A1 78 82 04 08 89 1D
 78 82 04 08 5A 59 5B C3 53 51
 52 6A FC 58 50 8D 0C 24 8B 1D
 68 82 04 08 6A 03 58 6A 01 5A
 CD 80 58 3C FC 5A 59 5B C3 53
 51 89 C3 85 C0 74 12 31 C0 8A
 03 85 C0 74 0A E8 08 00 00 00
 83 C3 01 EB EE 59 5B C3 53 51
 52 50 8D 0C 24 6A 01 5B 6A 04
 58 89 DA CD 80 58 5A 59 5B C3
 6B 61 65 6D 2E 78 38 36 00 20
 2B 3E 20 00 53 75 62 70 72 6F
 63 65 73 73 20 65 72 72 6F 72
 0A 41 42 4F 52 54 49 4E 47 20
 48 41 52 44 0A 00 00 00 00 00
 00 00 00 00 00 04 00 00 00 10
 00 00 00 00 00 00 00 00 00 00

https://github.com/oriansj/bootstrap-seeds/blob/main/POSIX/x86/hex0-seed

File: ../git/live-bootstrap/sysa/stage0-posix/src/bootstrap-seeds/POSIX/x86/hex0-seed used in:
 7F 45 4C 46 01 01 01 03 00 00
 00 00 00 00 00 00 02 00 03 00
 01 00 00 00 54 80 04 08 34 00
 00 00 00 00 00 00 00 00 00 00
 34 00 20 00 01 00 00 00 00 00
 00 00 01 00 00 00 00 00 00 00
 00 80 04 08 00 80 04 08 00 01
 00 00 00 01 00 00 07 00 00 00
 01 00 00 00 58 5B 5B 31 C9 31
 D2 6A 05 58 CD 80 89 C6 5B 66
 B9 41 02 66 BA C0 01 6A 05 58
 CD 80 89 C2 6A FF 5D 31 FF E8
 68 00 00 00 E8 1B 00 00 00 85
 C0 7C F2 85 ED 7D 06 89 C7 31
 ED EB E8 C1 E7 04 01 F8 4D E8
 39 00 00 00 EB DB 3C 23 74 1E
 3C 3B 74 1A 3C 30 7C 1F 3C 3A
 7C 1F 3C 41 7C 17 3C 47 7C 1C
 3C 61 7C 0F 3C 67 7C 12 EB 09
 E8 21 00 00 00 3C 0A 75 F7 6A
 FF 58 C3 2C 30 C3 2C 20 2C 37
 C3 89 D3 52 6A 01 5A 50 89 E1
 6A 04 58 CD 80 5B 5A C3 52 6A
 01 5A 53 89 E1 89 F3 6A 03 58
 CD 80 85 C0 74 03 58 5A C3 31
 DB 6A 01 58 CD 80

https://github.com/oriansj/stage0-posix-x86/blob/main/hex0_x86.hex0

File: ../git/live-bootstrap/sysa/stage0-posix/src/x86/hex0_x86.hex0 used in: Step 2
## Copyright (C) 2019 Jeremiah Orians
## Copyright (C) 2022 Andrius Å tikonas
#
# SPDX-License-Identifier: GPL-3.0-or-later

## ELF Header
#:ELF_base
7F 45 4C 46                     # e_ident[EI_MAG0-3] ELF's magic number

01                              # e_ident[EI_CLASS] Indicating 32 bit
01                              # e_ident[EI_DATA] Indicating little endianness
01                              # e_ident[EI_VERSION] Indicating original elf

03                              # e_ident[EI_OSABI] Set at 3 because FreeBSD is strict
00                              # e_ident[EI_ABIVERSION] Set at 0 because no one cares

00 00 00 00 00 00 00            # e_ident[EI_PAD]

02 00                           # e_type Indicating Executable
03 00                           # e_machine Indicating x86
01 00 00 00                     # e_version Indicating original elf

54 80 04 08                     # e_entry Address of the entry point
34 00 00 00                     # e_phoff Address of program header table
00 00 00 00                     # e_shoff Address of section header table

00 00 00 00                     # e_flags

34 00                           # e_ehsize Indicating our 52 Byte header

20 00                           # e_phentsize size of a program header table
01 00                           # e_phnum number of entries in program table

00 00                           # e_shentsize size of a section header table
00 00                           # e_shnum number of entries in section table

00 00                           # e_shstrndx index of the section names

## Program Header
#:ELF_program_headers
#:ELF_program_header__text
01 00 00 00                     # ph_type: PT-LOAD = 1
00 00 00 00                     # ph_offset

00 80 04 08                     # ph_vaddr
00 80 04 08                     # ph_physaddr

00 01 00 00                     # ph_filesz
00 01 00 00                     # ph_memsz

07 00 00 00                     # ph_flags: PF-X|PF-W|PF-R = 7
01 00 00 00                     # ph_align

#:ELF_text

# Where the ELF Header is going to hit
# Simply jump to _start
# Our main function
# :_start ; (0x8048054)
    58                          ; pop_eax                     # Get the number of arguments
    5B                          ; pop_ebx                     # Get the program name
    5B                          ; pop_ebx                     # Get the actual input name
    31C9                        ; xor_ecx,ecx                 # prepare read_only, ecx = 0
    31D2                        ; xor_edx,edx                 # Extra sure, edx = 0
    6A 05                       ; push !5                     # prepare to set eax to 5
    58                          ; pop_eax                     # the syscall number for open()
    CD 80                       ; int !0x80                   # Now open that damn file
    89C6                        ; mov_esi,eax                 # Preserve the file pointer we were given

    5B                          ; pop_ebx                     # Get the actual output name
    66B9 4102                   ; mov_cx, @577                # Prepare file as O_WRONLY|O_CREAT|O_TRUNC
    66BA C001                   ; mov_dx, @448                # Prepare file as RWX for owner only (700 in octal)
    6A 05                       ; push !5                     # prepare to set eax to 5
    58                          ; pop_eax                     # the syscall number for open()
    CD 80                       ; int !0x80                   # Now open that damn file
    89C2                        ; mov_edx,eax                 # Preserve the file pointer we were given

    # Our flag for byte processing
    6A FF                       ; push !-1
    5D                          ; pop_ebp                     # ebp = -1

    # temp storage for the sum
    31FF                        ; xor_edi,edi                 # edi = 0

#:loop ; (0x8048077)
    # Read a byte
    E8 68000000                 ; call %Read_byte

    # process byte
    E8 1B000000                 ; call %hex

    # Deal with -1 values
    85C0                        ; test_eax,eax
    7C F2                       ; jl !loop

    # deal with toggle
    85ED                        ; test_ebp,ebp                # jump if ebp >= 0
    7D 06                       ; jge !print

    # process first byte of pair
    89C7                        ; mov_edi,eax
    31ED                        ; xor_ebp,ebp                 # ebp = 0
    EB E8                       ; jmp !loop

# process second byte of pair
#:print ; (0x804808F)
    # update the sum and store in output
    C1E7 04                     ; shl_edi, !4
    01F8                        ; add_eax,edi

    # flip the toggle
    4D                          ; DEC_EBP                     # ebp = -1

    E8 39000000                 ; call %write_byte

    EB DB                       ; jmp !loop

#:hex ; (0x804809C)
    # Purge Comment Lines (#)
    3C 23                       ; cmp_al, !35
    74 1E                       ; je !purge_comment

    # Purge Comment Lines (;)
    3C 3B                       ; cmp_al, !59
    74 1A                       ; je !purge_comment

    # deal all ascii less than 0
    3C 30                       ; cmp_al, !48
    7C 1F                       ; jl !ascii_other

    # deal with 0-9
    3C 3A                       ; cmp_al, !58
    7C 1F                       ; jl !ascii_num

    # deal with all ascii less than A
    3C 41                       ; cmp_al, !65
    7C 17                       ; jl !ascii_other

    # deal with A-F
    3C 47                       ; cmp_al, !71
    7C 1C                       ; jl !ascii_high

    # deal with all ascii less than a
    3C 61                       ; cmp_al, !97
    7C 0F                       ; jl !ascii_other

    # deal with a-f
    3C 67                       ; cmp_al, !103
    7C 12                       ; jl !ascii_low

    # The rest that remains needs to be ignored
    EB 09                       ; jmp !ascii_other

#:purge_comment ; (0x80480BE)
    # Read a byte
    E8 21000000                 ; call %Read_byte

    # Loop if not LF
    3C 0A                       ; cmp_al, !10
    75 F7                       ; jne !purge_comment

    # Otherwise return -1

#:ascii_other ; (0x80480C7)
    6A FF                       ; push !-1
    58                          ; pop_eax                     # return -1
    C3                          ; ret

#:ascii_num ; (0x80480CB)
    2C 30                       ; sub_al, !48
    C3                          ; ret

#:ascii_low ; (0x80480CE)
    2C 20                       ; sub_al, !32                 # convert to uppercase

#:ascii_high ; (0x80480D0)
    2C 37                       ; sub_al, !55
    C3                          ; ret

# Writes byte stored in al
#:write_byte ; (0x80480D3)
    # Print our Hex
    89D3                        ; mov_ebx,edx                 # Where are we writing to
    52                          ; push_edx                    # protect fout
    6A 01                       ; push !1                     # prepare to set edx to 1
    5A                          ; pop_edx                     # set the size of chars we want
    50                          ; push_eax                    # Move output to stack
    89E1                        ; mov_ecx,esp                 # What we are writing
    6A 04                       ; push !4                     # prepare to set eax to 4
    58                          ; pop_eax                     # the syscall number for write
    CD 80                       ; int !0x80                   # call the Kernel
    5B                          ; pop_ebx                     # deallocate stack
    5A                          ; pop_edx                     # restore fout
    C3                          ; ret

#:Read_byte ; (0x80480E4)
    # Attempt to read 1 byte from Input file
    52                          ; push_edx                    # protect fout
    6A 01                       ; push !1                     # prepare to set edx to 1
    5A                          ; pop_edx                     # set the size of chars we want
    53                          ; push_ebx                    # allocate stack
    89E1                        ; mov_ecx,esp                 # Where to put it
    89F3                        ; mov_ebx,esi                 # Where are we reading from
    6A 03                       ; push !3                     # prepare to set eax to 3
    58                          ; pop_eax                     # the syscall number for read
    CD 80                       ; int !0x80                   # call the Kernel

    85C0                        ; test_eax,eax                # check what we got
    74 03                       ; je !Done                    # Got EOF call it done

    # load byte
    58                          ; pop_eax                     # load char
    5A                          ; pop_edx                     # restore fout
    C3                          ; ret

#:Done ; (0x80480F9)
    # program completed Successfully
    31DB                        ; xor_ebx,ebx                 # All is well, ebx = 0
    6A 01                       ; push !1
    58                          ; pop_eax                     # put the exit syscall number in eax
    CD 80                       ; int !0x80                   # Call it a good day

#:ELF_end

https://github.com/oriansj/stage0-posix-x86/blob/main/kaem-minimal.hex0

File: ../git/live-bootstrap/sysa/stage0-posix/src/x86/kaem-minimal.hex0 used in: Step 3
# SPDX-FileCopyrightText: 2020 Jeremiah Orians
# SPDX-FileCopyrightText: 2022 Andrius Å tikonas
#
# SPDX-License-Identifier: GPL-3.0-or-later

## ELF Header
# :ELF_base ; (0x8048000)
    7F 45 4C 46                     # e_ident[EI_MAG0-3] ELF's magic number

    01                              # e_ident[EI_CLASS] Indicating 32 bit
    01                              # e_ident[EI_DATA] Indicating little endianness
    01                              # e_ident[EI_VERSION] Indicating original elf

    03                              # e_ident[EI_OSABI] Set at 3 because FreeBSD is strict
    00                              # e_ident[EI_ABIVERSION] Set at 0 because none cares

    00 00 00 00 00 00 00            # e_ident[EI_PAD]

    02 00                           # e_type Indicating Executable
    03 00                           # e_machine Indicating x86
    01 00 00 00                     # e_version Indicating original elf

    54 80 04 08                     # e_entry Address of the entry point
    34 00 00 00                     # e_phoff Address of program header table
    00 00 00 00                     # e_shoff Address of section header table

    00 00 00 00                     # e_flags

    34 00                           # e_ehsize Indicating our 52 Byte header

    20 00                           # e_phentsize size of a program header table
    01 00                           # e_phnum number of entries in program table

    00 00                           # e_shentsize size of a section header table
    00 00                           # e_shnum number of entries in section table

    00 00                           # e_shstrndx index of the section names

## Program Header
# :ELF_program_headers
# :ELF_program_header__text
    01 00 00 00                     # ph_type: PT-LOAD = 1
    00 00 00 00                     # ph_offset

    00 80 04 08                     # ph_vaddr
    00 80 04 08                     # ph_physaddr

    80 02 00 00                     # ph_filesz
    80 02 00 00                     # ph_memsz

    07 00 00 00                     # ph_flags: PF-X|PF-W|PF-R = 7
    01 00 00 00                     # ph_align

# :ELF_text

# :_start ; (0x8048054)
    58                              ; pop_eax                           # Get the number of arguments
    5B                              ; pop_ebx                           # Get the program name
    5B                              ; pop_ebx                           # Get the actual input name
    85DB                            ; test_ebx,ebx                      # Check for missing output
    75 06                           ; jne !_start_out                   # Have real input
    50                              ; push_eax                          # Need to adjust stack
    BB 3A820408                     ; mov_ebx, &default_file            # Use "kaem.x86"

# :_start_out ; (0x8048061)
    31C9                            ; xor_ecx,ecx                       # prepare read_only
    6A 05                           ; push !5
    58                              ; pop_eax                           # the syscall number for open()
    CD80                            ; int !0x80                         # Now open that damn file

    85C0                            ; test_eax,eax                      # IF NULL We couldn't open the file
    7E 6C                           ; jle !Exit_Failure                 # Abort hard
    A3 68820408                     ; mov_[DWORD],eax &script           # Set input pointer

    58                              ; pop_eax                           # Get start of envp
    89E5                            ; mov_ebp,esp                       # Protect envp

    6A 2D                           ; push !45
    58                              ; pop_eax                           # the Syscall # for SYS_BRK
    31DB                            ; xor_ebx,ebx                       # Get current brk
    CD80                            ; int !0x80                         # Let the kernel do the work
    A3 78820408                     ; mov_[DWORD],eax &MALLOC           # Set our malloc pointer

    # Where the main work gets done
    # Using EBX for tokens and ECX for tokens[i]
# :main_loop ; (0x8048080)
    A1 70820408                     ; mov_eax,[DWORD] &max_args         # Using 256 char* of space
    E8 3F010000                     ; call %malloc                      # get it
    89C3                            ; mov_ebx,eax                       # set tokens

    89D9                            ; mov_ecx,ebx                       # I = 0
    31C0                            ; xor_eax,eax                       # Using 0
    A3 7C820408                     ; mov_[DWORD],eax &status           # status = 0
    A3 6C820408                     ; mov_[DWORD],eax &command_done     # command_done = 0

    # Using EAX for result and EBX for tokens[i]
# :collect_command ; (0x804809A)
    E8 95000000                     ; call %collect_token               # Get another token
    85C0                            ; test_eax,eax                      # if NULL == result
    74 05                           ; je !collect_command_comment       # It is a comment, don't store

    8901                            ; mov_[ecx],eax                     # tokens[i] = result
    83C1 04                         ; add_ecx, !4                       # i = i + 1 (adjusted for char* size)

# :collect_command_comment ; (0x80480A8)
    A1 6C820408                     ; mov_eax,[DWORD] &command_done     # Using command_done
    85C0                            ; test_eax,eax                      # IF 0 == command_done
    74 E9                           ; je !collect_command               # keep looping

    # Deal with line comments
    39CB                            ; cmp_ebx,ecx                       # if 0 < i
    74 CB                           ; je !main_loop                     # It was a comment

    E8 4F000000                     ; call %print_command               # print the command
    8B03                            ; mov_eax,[ebx]                     # program = tokens[0]
    85C0                            ; test_eax,eax                      # IF NULL == program
    74 18                           ; je !Exit_Failure                  # Some shit went down, abort

    53                              ; push_ebx                          # Protect Tokens
    6A 02                           ; push !2
    58                              ; pop_eax                           # FORKing
    CD 80                           ; int !0x80                         # int f = FORK()
    5B                              ; pop_ebx                           # Restore Tokens

    85C0                            ; test_eax,eax                      # Check fork
    7C 0D                           ; jl !Exit_Failure                  # IF f == -1 abort hard
    75 12                           ; jne !collect_command_parent       # IF f == 0 it is child

    # Deal with child case
    6A 0B                           ; push !11
    58                              ; pop_eax                           # EXECVE
    89EA                            ; mov_edx,ebp                       # third arg = envp
    89D9                            ; mov_ecx,ebx                       # second arg = tokens
    8B1B                            ; mov_ebx,[ebx]                     # program = tokens[0]
    CD 80                           ; int !0x80                         # execve(program, tokens, envp)
                                                                        # return error

# Exit_Failure function
# Receives nothing
# And aborts hard
# Does NOT return
# :Exit_Failure ; (0x80480D8)
    6A 01                           ; push !1
    5B                              ; pop_ebx                           # All is wrong
    89D8                            ; mov_eax,ebx                       # put the exit syscall number in eax
    CD 80                           ; int !0x80                         # Call it a bad day

# :collect_command_parent ; (0x80480DF)
    89C3                            ; mov_ebx,eax                       # first arg = f
    B9 7C820408                     ; mov_ecx, &status                  # second arg = &status
    31D2                            ; xor_edx,edx                       # third arg = NULL
    6A 07                           ; push !7
    58                              ; pop_eax                           # WAITPID
    CD 80                           ; int !0x80                         # waitpid(f, &status, 0)

    A1 7C820408                     ; mov_eax,[DWORD] &status           # Using status
    85C0                            ; test_eax,eax                      # IF 0 == status
    74 8A                           ; je !main_loop                     # Loop forever

    # Deal with very unhappy case
    B8 48820408                     ; mov_eax, &hard                    # Using "Subprocess error\nABORTING HARD\n"
    E8 07010000                     ; call %File_Print                  # Print it
    EB D6                           ; jmp !Exit_Failure                 # return error

# :Done ; (0x8048102)
    # program completed Successfully
    31DB                            ; xor_ebx,ebx                       # All is well
    6A 01                           ; push !1
    58                              ; pop_eax                           # put the exit syscall number in eax
    CD 80                           ; int !0x80                         # Call it a good day

# print_command function
# Receives tokens[j] in EBX and tokens[i] in ECX
# Modifies EAX
# :print_command ; (0x8048109)
    53                              ; push_ebx                          # Protect EBX
    B8 43820408                     ; mov_eax, &prefix                  # using " +> "
    E8 F3000000                     ; call %File_Print                  # print it
# :print_command_loop ; (0x8048114)
    8B03                            ; mov_eax,[ebx]                     # using tokens[j]
    E8 EC000000                     ; call %File_Print                  # print it
    83C3 04                         ; add_ebx, !4                       # j = j + 1
    6A 20                           ; push !32
    58                              ; pop_eax                           # using ' '
    E8 FE000000                     ; call %fputc                       # print it
    39CB                            ; cmp_ebx,ecx                       # IF j < i
    75 EA                           ; jne !print_command_loop           # otherwise keep looping

    6A 0A                           ; push !10
    58                              ; pop_eax                           # using '\n'
    E8 F2000000                     ; call %fputc                       # print it
    5B                              ; pop_ebx                           # Restore EBX
    C3                              ; ret


# collect_token function
# Receives nothing
# Overwrites EAX
# Uses EAX as C, EBX as token and ECX as token[i]
# :collect_token ; (0x8048134)
    53                              ; push_ebx                          # Protect EBX
    51                              ; push_ecx                          # Protect ECX
    A1 74820408                     ; mov_eax,[DWORD] &max_string       # Using max_string
    E8 89000000                     ; call %malloc                      # allocate space
    89C3                            ; mov_ebx,eax                       # token = malloc(max_string)
    89C1                            ; mov_ecx,eax                       # i = 0; set token[i]

# :collect_token_loop ; (0x8048144)
    E8 9F000000                     ; call %fgetc                       # c = fgetc(input)
    3C FC                           ; cmp_al, !-4                       # if C == EOF
    74 B5                           ; je !Done                          # We are done

    3C 20                           ; cmp_al, !32                       # IF C == ' '
    74 42                           ; je !collect_token_done            # Space terminates token

    3C 09                           ; cmp_al, !9                        # IF C == '\t'
    74 3E                           ; je !collect_token_done            # tab terminates token

    3C 0A                           ; cmp_al, !10                       # IF C == '\n'
    75 0A                           ; jne !collect_token_string         # otherwise check next

    # It is a newline
    6A 01                           ; push !1
    58                              ; pop_eax                           # Using 1
    A3 6C820408                     ; mov_[DWORD],eax &command_done     # Set command_done = TRUE
    EB 30                           ; jmp !collect_token_done           # Be done

# :collect_token_string ; (0x8048163)
    3C 22                           ; cmp_al, !34                       # IF C == '\"'
    75 07                           ; jne !collect_token_comment        # otherwise check next

    # It is a RAW STRING
    E8 32000000                     ; call %collect_string              # Get the rest of the string
    EB 25                           ; jmp !collect_token_done           # Be done

# :collect_token_comment ; (0x804816E)
    3C 23                           ; cmp_al, !35                       # IF C == '#'
    75 0F                           ; jne !collect_token_escape         # otherwise check next

    # It is a line comment
    E8 40000000                     ; call %collect_comment             # Read it all
    6A 01                           ; push !1
    58                              ; pop_eax                           # Using 1
    A3 6C820408                     ; mov_[DWORD],eax &command_done     # Set command_done = TRUE
    EB 12                           ; jmp !collect_token_done           # Be done

# :collect_token_escape ; (0x8048181)
    3C 5C                           ; cmp_al, !92                       # IF C == '\\'
    75 07                           ; jne !collect_token_other          # otherwise just store it

    # It is an escape char
    E8 5E000000                     ; call %fgetc                       # Read the char to drop
    EB 07                           ; jmp !collect_token_done           # Be done

# :collect_token_other ; (0x804818C)
    8801                            ; mov_[ecx],al                      # token[i] = C
    83C1 01                         ; add_ecx, !1                       # i = i + 1
    EB B1                           ; jmp !collect_token_loop           # Keep going

# :collect_token_done ; (0x8048193)
    39CB                            ; cmp_ebx,ecx                       # IF i == 0
    75 02                           ; jne !collect_token_good           # otherwise return the token
    31DB                            ; xor_ebx,ebx                       # token = NULL

# :collect_token_good ; (0x8048199)
    89D8                            ; mov_eax,ebx                       # Return token
    59                              ; pop_ecx                           # Restore ECX
    5B                              ; pop_ebx                           # Restore EBX
    C3                              ; ret


# collect_string function
# Receives target[index] in ECX
# Modifies EAX
# Uses EAX as C
# :collect_string ; (0x804819E)
    E8 45000000                     ; call %fgetc                       # C = fgetc(input)
    3C FC                           ; cmp_al, !-4                       # if C == EOF
    0F84 2DFFFFFF                   ; je32 %Exit_Failure                # Something went horribly wrong

    3C 22                           ; cmp_al, !34                       # IF C == '\"'
    74 07                           ; je !collect_string_done           # be done

    # deal with inside of string
    8801                            ; mov_[ecx],al                      # target[index] = C
    83C1 01                         ; add_ecx, !1                       # index = index + 1
    EB E8                           ; jmp !collect_string               # Keep going

# :collect_string_done ; (0x80481B6)
    C3                              ; ret


# collect_comment function
# Receives nothing
# Modifies EAX
# uses EAX as Int C
# Just throws away everything it reads
# :collect_comment ; (0x80481B7)
    E8 2C000000                     ; call %fgetc                       # C = fgetc(input)
    3C FC                           ; cmp_al, !-4                       # IF C == EOF
    0F84 14FFFFFF                   ; je32 %Exit_Failure                # abort hard

    3C 0A                           ; cmp_al, !10                       # IF C == '\n'
    75 EF                           ; jne !collect_comment              # otherwise keep looping
    C3                              ; ret


;; Malloc isn't actually required if the program being built fits in the initial memory
;; However, it doesn't take much to add it.
;; Requires [MALLOC] to be initialized and EAX to have the number of desired bytes
# :malloc ; (0x80481C9)
    53                              ; push_ebx                          # Protect EBX
    51                              ; push_ecx                          # Protect ECX
    52                              ; push_edx                          # Protect EDX
    8B1D 78820408                   ; mov_ebx,[DWORD] &MALLOC           # Using the current pointer
    01C3                            ; add_ebx,eax                       # Request the number of desired bytes
    6A 2D                           ; push !45
    58                              ; pop_eax                           # the Syscall # for SYS_BRK
    CD 80                           ; int !0x80                         # call the Kernel
    A1 78820408                     ; mov_eax,[DWORD] &MALLOC           # Return pointer
    891D 78820408                   ; mov_[DWORD],ebx &MALLOC           # Update pointer
    5A                              ; pop_edx                           # Restore EDX
    59                              ; pop_ecx                           # Restore ECX
    5B                              ; pop_ebx                           # Restore EBX
    C3                              ; ret


# fgetc function
# Loads FILE* from [script]
# Returns -4 (EOF) or char in AL
# :fgetc ; (0x80481E8)
    53                              ; push_ebx                          # Protect EBX
    51                              ; push_ecx                          # Protect ECX
    52                              ; push_edx                          # Protect EDX
    6A FC                           ; push !-4
    58                              ; pop_eax                           # Put EOF in eax
    50                              ; push_eax                          # Assume bad (If nothing read, value will remain EOF)
    8D0C24                          ; lea_ecx,[esp]                     # Get stack address
    8B1D 68820408                   ; mov_ebx,[DWORD] &script           # Where are we reading from
    6A 03                           ; push !3
    58                              ; pop_eax                           # the syscall number for read
    6A 01                           ; push !1
    5A                              ; pop_edx                           # set the size of chars we want
    CD 80                           ; int !0x80                         # call the Kernel
    58                              ; pop_eax                           # Get either char or EOF
    3C FC                           ; cmp_al, !-4                       # Check for EOF
# :fgetc_done ; (0x8048203)
    5A                              ; pop_edx                           # Restore EDX
    59                              ; pop_ecx                           # Restore ECX
    5B                              ; pop_ebx                           # Restore EBX
    C3                              ; ret


# File_Print function
# Receives CHAR* in EAX
# calls fputc for every non-null char
# :File_Print ; (0x8048207)
    53                              ; push_ebx                          # Protect EBX
    51                              ; push_ecx                          # Protect ECX
    89C3                            ; mov_ebx,eax                       # Protect S
    85C0                            ; test_eax,eax                      # Protect against nulls
    74 12                           ; je !File_Print_Done               # Simply don't try to print them
# :File_Print_Loop ; (0x804820F)
    31C0                            ; xor_eax,eax                       # Zero eax
    8A03                            ; mov_al,[ebx]                      # Read byte
    85C0                            ; test_eax,eax                      # Check for NULL
    74 0A                           ; je !File_Print_Done               # Stop at NULL

    E8 08000000                     ; call %fputc                       # write it
    83C3 01                         ; add_ebx, !1                       # S = S + 1
    EB EE                           ; jmp !File_Print_Loop              # Keep going

# :File_Print_Done ; (0x8048221)
    59                              ; pop_ecx                           # Restore ECX
    5B                              ; pop_ebx                           # Restore EBX
    C3                              ; ret


# fputc function
# receives CHAR in EAX and load FILE* from stdout
# writes char and returns
# :fputc ; (0x8048224)
    53                              ; push_ebx                          # Protect EBX
    51                              ; push_ecx                          # Protect ECX
    52                              ; push_edx                          # Protect EDX
    50                              ; push_eax                          # We are writing eax
    8D0C24                          ; lea_ecx,[esp]                     # Get stack address
    6A 01                           ; push !1
    5B                              ; pop_ebx                           # Write to target file
    6A 04                           ; push !4
    58                              ; pop_eax                           # the syscall number for write
    89DA                            ; mov_edx,ebx                       # set the size of chars we want
    CD 80                           ; int !0x80                         # call the Kernel
    58                              ; pop_eax                           # Restore stack
    5A                              ; pop_edx                           # Restore EDX
    59                              ; pop_ecx                           # Restore ECX
    5B                              ; pop_ebx                           # Restore EBX
    C3                              ; ret


# :default_file ; (0x804823A)
    6B61656D2E78383600              # "kaem.x86"
# :prefix ; (0x8048243)
    202B3E2000                      # " +> "
# :hard ; (0x8048248)
    53756270726F63657373206572726F720A41424F5254494E4720484152440A00 # "Subprocess error\nABORTING HARD\n"
# :script ; (0x8048268)
    00000000
# :command_done ; (0x804826C)
    00000000
# :max_args ; (0x8048270)
    00040000
# :max_string ; (0x8048274)
    00100000
# :MALLOC ; (0x8048278)
    00000000
# :status ; (0x804827C)
    00000000
# :ELF_end ; (0x8048280)

https://github.com/oriansj/stage0-posix-x86/blob/main/hex1_x86.hex0

File: ../git/live-bootstrap/sysa/stage0-posix/src/x86/hex1_x86.hex0 used in: Step 5
### Copyright (C) 2016 Jeremiah Orians
### This file is part of stage0.
###
### stage0 is free software: you can redistribute it and/or modify
### it under the terms of the GNU General Public License as published by
### the Free Software Foundation, either version 3 of the License, or
### (at your option) any later version.
###
### stage0 is distributed in the hope that it will be useful,
### but WITHOUT ANY WARRANTY; without even the implied warranty of
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
### GNU General Public License for more details.
###
### You should have received a copy of the GNU General Public License
### along with stage0.  If not, see <http://www.gnu.org/licenses/>.

## ELF Header
#:ELF_base
7F 45 4C 46                     # e_ident[EI_MAG0-3] ELF's magic number

01                              # e_ident[EI_CLASS] Indicating 32 bit
01                              # e_ident[EI_DATA] Indicating little endianness
01                              # e_ident[EI_VERSION] Indicating original elf

03                              # e_ident[EI_OSABI] Set at 3 because FreeBSD is strict
00                              # e_ident[EI_ABIVERSION] Set at 0 because none cares

00 00 00 00 00 00 00            # e_ident[EI_PAD]

02 00                           # e_type Indicating Executable
03 00                           # e_machine Indicating x86
01 00 00 00                     # e_version Indicating original elf

54 80 04 08                     # e_entry Address of the entry point
34 00 00 00                     # e_phoff Address of program header table
00 00 00 00                     # e_shoff Address of section header table

00 00 00 00                     # e_flags

34 00                           # e_ehsize Indicating our 52 Byte header

20 00                           # e_phentsize size of a program header table
01 00                           # e_phnum number of entries in program table

00 00                           # e_shentsize size of a section header table
00 00                           # e_shnum number of entries in section table

00 00                           # e_shstrndx index of the section names

## Program Header
#:ELF_program_headers
#:ELF_program_header__text
01 00 00 00                     # ph_type: PT-LOAD = 1
00 00 00 00                     # ph_offset

00 80 04 08                     # ph_vaddr
00 80 04 08                     # ph_physaddr

B1 02 00 00                     # ph_filesz
B1 02 00 00                     # ph_memsz

07 00 00 00                     # ph_flags: PF-X|PF-W|PF-R = 7
01 00 00 00                     # ph_align

#:ELF_text

#:_start ; (0x8048054)
    58                          # POP_EAX                     ; Get the number of arguments
    5B                          # POP_EBX                     ; Get the program name
    5B                          # POP_EBX                     ; Get the actual input name
    B9 00000000                 # LOADI32_ECX %0              ; prepare read_only
    BA 00000000                 # LOADI32_EDX %0              ; extra sure
    B8 05000000                 # LOADI32_EAX %5              ; the syscall number for open()
    CD80                        # INT_80                      ; Now open that damn file
    A3 A9820408                 # STORE32_Absolute32_eax &fin ; Preserve the file pointer we were given

    5B                          # POP_EBX                     ; Get the actual output name
    B9 41020000                 # LOADI32_ECX %577            ; Prepare file as O_WRONLY|O_CREAT|O_TRUNC
    BA C0010000                 # LOADI32_EDX %448            ; Prepare file as RWX for owner only (700 in octal)
    B8 05000000                 # LOADI32_EAX %5              ; the syscall number for open()
    CD80                        # INT_80                      ; Now open that damn file
    A3 AD820408                 # STORE32_Absolute32_eax &fout ; Preserve the file pointer we were given

    BD FFFFFFFF                 # LOADI32_EBP %-1             ; Our flag for byte processing
    BE 00000000                 # LOADI32_ESI %0              ; temp storage for the sum
    BF 00000000                 # LOADI32_EDI %0              ; Our starting IP
    E8 30000000                 # CALLI32 %First_pass         ; Process it

    ; rewind input file
    8B1D A9820408               # LOAD32_Absolute32_ebx &fin  ; Using our input file
    B9 00000000                 # LOADI32_ECX %0              ; Offset Zero
    BA 00000000                 # LOADI32_EDX %0              ; Whence Zero
    B8 13000000                 # LOADI32_EAX %19             ; lseek
    CD80                        # INT_80

    BD FFFFFFFF                 # LOADI32_EBP %-1             ; Our flag for byte processing
    BE 00000000                 # LOADI32_ESI %0              ; temp storage for the sum
    BF 00000000                 # LOADI32_EDI %0              ; Our starting IP
    E8 B8000000                 # CALLI32 %Second_pass        ; Process it

    E9 62010000                 # JMP32 %Done

#:First_pass ; (0x80480C8)
    E8 69010000                 # CALLI32 %Read_byte

    ; Deal with EOF
    83F8 FC                     # CMPI8_EAX !-4
    0F84 4E000000               # JE32 %First_pass_done

    ; Check for :
    83F8 3A                     # CMPI8_EAX !58
    0F85 05000000               # JNE32 %First_pass_0

    ; Deal with label
    E8 A1010000                 # CALLI32 %StoreLabel

#:First_pass_0 ; (0x80480E4)
    ; Check for %
    83F8 25                     # CMPI8_EAX !37
    0F84 2A000000               # JE32 %First_pass_pointer

    ; Deal with everything else
    E8 33000000                 # CALLI32 %hex                ; Process our char

    ; Deal with EOF
    83F8 FC                     # CMPI8_EAX !-4
    0F84 29000000               # JE32 %First_pass_done

    ; deal with -1 values
    83F8 00                     # CMPI8_EAX !0
    0F8C C4FFFFFF               # JL32 %First_pass

    ; deal with toggle
    83FD 00                     # CMPI8_EBP !0
    0F84 03000000               # JE32 %First_pass_1
    83C7 01                     # ADDI8_EDI !1                ; Increment IP

#:First_pass_1 ; (0x8048110)
    F7D5                        # NOT_EBP
    E9 B1FFFFFF                 # JMP32 %First_pass

#:First_pass_pointer ; (0x8048117)
    ; Deal with Pointer to label
    E8 1A010000                 # CALLI32 %Read_byte          ; Drop the char
    83C7 04                     # ADDI8_EDI !4                ; Increment IP
    E9 A4FFFFFF                 # JMP32 %First_pass           ; Loop again

#:First_pass_done ; (0x8048124)
    C3                          # RET

#:hex ; (0x8048125)
    ; deal with EOF
    83F8 FC                     # CMPI8_EAX !-4
    0F84 AE000000               # JE32 %EOF
    ; deal with line comments starting with #
    83F8 23                     # CMPI8_EAX !35
    0F84 B8000000               # JE32 %ascii_comment
    ; deal with line comments starting with ;
    83F8 3B                     # CMPI8_EAX !59
    0F84 AF000000               # JE32 %ascii_comment
    ; deal all ascii less than 0
    83F8 30                     # CMPI8_EAX !48
    0F8C A0000000               # JL32 %ascii_other
    ; deal with 0-9
    83F8 3A                     # CMPI8_EAX !58
    0F8C 8B000000               # JL32 %ascii_num
    ; deal with all ascii less than A
    83F8 41                     # CMPI8_EAX !65
    0F8C 8E000000               # JL32 %ascii_other
    ; deal with A-F
    83F8 47                     # CMPI8_EAX !71
    0F8C 81000000               # JL32 %ascii_high
    ;deal with all ascii less than a
    83F8 61                     # CMPI8_EAX !97
    0F8C 7C000000               # JL32 %ascii_other
    ;deal with a-f
    83F8 67                     # CMPI8_EAX !103
    0F8C 6B000000               # JL32 %ascii_low
    ; The rest that remains needs to be ignored
    E9 6E000000                 # JMP32 %ascii_other

#:Second_pass ; (0x804817B)
    E8 B6000000                 # CALLI32 %Read_byte

    ; Deal with EOF
    83F8 FC                     # CMPI8_EAX !-4
    0F84 52000000               # JE32 %Second_pass_done

    ; Simply drop the label
    83F8 3A                     # CMPI8_EAX !58
    0F85 0A000000               # JNE32 %Second_pass_0

    E8 9F000000                 # CALLI32 %Read_byte
    E9 DFFFFFFF                 # JMP32 %Second_pass

#:Second_pass_0 ; (0x804819C)
    ; Deal with  pointer
    83F8 25                     # CMPI8_EAX !37
    0F85 0A000000               # JNE32 %Second_pass_1

    E8 E3000000                 # CALLI32 %StorePointer
    E9 CCFFFFFF                 # JMP32 %Second_pass

#:Second_pass_1 ; (0x80481AF)
    ; Deal with everything else
    E8 71FFFFFF                 # CALLI32 %hex                ; Process our char

    ; Deal with EOF
    83F8 FC                     # CMPI8_EAX !-4
    0F84 1E000000               # JE32 %Second_pass_done

    ; deal with -1 values
    83F8 00                     # CMPI8_EAX !0
    0F8C B5FFFFFF               # JL32 %Second_pass

    ; deal with toggle
    83FD 00                     # CMPI8_EBP !0
    0F84 3D000000               # JE32 %print

    ; process first byte of pair
    89C6                        # COPY_EAX_to_ESI
    BD 00000000                 # LOADI32_EBP %0
    E9 A0FFFFFF                 # JMP32 %Second_pass

#:Second_pass_done ; (0x80481DB)
    C3                          # RET

#:EOF ; (0x80481DC)
    C3                          # RET
#:ascii_num ; (0x80481DD)
    83E8 30                     # SUBI8_EAX !48
    C3                          # RET
#:ascii_low ; (0x80481E1)
    83E8 57                     # SUBI8_EAX !87
    C3                          # RET
#:ascii_high ; (0x80481E5)
    83E8 37                     # SUBI8_EAX !55
    C3                          # RET
#:ascii_other ; (0x80481E9)
    B8 FFFFFFFF                 # LOADI32_EAX %-1
    C3                          # RET
#:ascii_comment ; (0x80481EF)
    E8 42000000                 # CALLI32 %Read_byte
    83F8 0D                     # CMPI8_EAX !13
    0F84 09000000               # JE32 %ascii_comment_cr
    83F8 0A                     # CMPI8_EAX !10
    0F85 E9FFFFFF               # JNE32 %ascii_comment
#:ascii_comment_cr ; (0x8048206)
    B8 FFFFFFFF                 # LOADI32_EAX %-1
    C3                          # RET

; process second byte of pair
#:print ; (0x804820C)
    ; update the sum and store in output
    C1E6 04                     # SHLI8_ESI !4
    01F0                        # ADD_ESI_to_EAX
    A2 B1820408                 # STORE8_Absolute32_al &table

    ; flip the toggle
    F7D5                        # NOT_EBP

    ; Print our first Hex
    BA 01000000                 # LOADI32_EDX %1              ; set the size of chars we want
    E8 42000000                 # CALLI32 %print_chars

    83C7 01                     # ADDI8_EDI !1                ; Increment IP
    E9 51FFFFFF                 # JMP32 %Second_pass

#:Done ; (0x804822A)
    ; program completed Successfully
    BB 00000000                 # LOADI32_EBX %0              ; All is well
    B8 01000000                 # LOADI32_EAX %1              ; put the exit syscall number in eax
    CD80                        # INT_80                      ; Call it a good day

#:Read_byte ; (0x8048236)
    ; Attempt to read 1 byte from STDIN
    BA 01000000                 # LOADI32_EDX %1              ; set the size of chars we want
    B9 B1820408                 # LOADI32_ECX &table          ; Where to put it
    8B1D A9820408               # LOAD32_Absolute32_ebx &fin  ; Where are we reading from
    B8 03000000                 # LOADI32_EAX %3              ; the syscall number for read
    CD80                        # INT_80                      ; call the Kernel

    85C0                        # TEST                        ; check what we got
    0F84 09000000               # JE32 %Read_byte_1           ; Got EOF call it done

    ; load byte
    A0 B1820408                 # LOAD8_Absolute32_al &table  ; load char
    0FB6C0                      # MOVZX                       ; We have to zero extend it to use it
    C3                          # RET

; Deal with EOF
#:Read_byte_1 ; (0x804825E)
    B8 FCFFFFFF                 # LOADI32_EAX %-4             ; Put EOF in eax
    C3                          # RET

#:print_chars ; (0x8048264)
    B9 B1820408                 # LOADI32_ECX &table          ; What we are writing
    8B1D AD820408               # LOAD32_Absolute32_ebx &fout ; Write to target file
    B8 04000000                 # LOADI32_EAX %4              ; the syscall number for write
    CD80                        # INT_80                      ; call the Kernel
    C3                          # RET

#:Get_table_target ; (0x8048277)
    E8 BAFFFFFF                 # CALLI32 %Read_byte          ; Get single char label
    C1E0 02                     # SHLI8_EAX !2                ; Each label in table takes 4 bytes to store
    05 B1820408                 # ADDI32_EAX &table           ; Calculate offset
    C3                          # RET

#:StoreLabel ; (0x8048285)
    E8 EDFFFFFF                 # CALLI32 %Get_table_target
    8938                        # STORE32_EDI_into_Address_EAX ; Write out pointer to table
    C3                          # RET

#:StorePointer ; (0x804828D)
    83C7 04                     # ADDI8_EDI !4                ; Increment IP
    E8 E2FFFFFF                 # CALLI32 %Get_table_target   ; Get address of pointer
    8B00                        # LOAD32_Address_EAX_into_EAX ; Get pointer
    29F8                        # SUB_EDI_from_EAX            ; target - ip
    A3 B1820408                 # STORE32_Absolute32_eax &table ; put value in output
    BA 04000000                 # LOADI32_EDX %4              ; set the size of chars we want
    E8 BCFFFFFF                 # CALLI32 %print_chars
    C3                          # RET

#:fin ; (0x80482A9)
    00000000                    # NULL
#:fout ; (0x80482AD)
    00000000                    # NULL
#:table ; (0x80482B1)
#:ELF_end

https://github.com/oriansj/stage0-posix-x86/blob/main/hex2_x86.hex1

File: ../git/live-bootstrap/sysa/stage0-posix/src/x86/hex2_x86.hex1 used in: Step 6
;; Copyright (C) 2017 Jeremiah Orians
;; This file is part of stage0.
;;
;; stage0 is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;;
;; stage0 is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with stage0.  If not, see <http://www.gnu.org/licenses/>.

## ELF Header
7F 45 4C 46                     # e_ident[EI_MAG0-3] ELF's magic number

01                              # e_ident[EI_CLASS] Indicating 32 bit
01                              # e_ident[EI_DATA] Indicating little endianness
01                              # e_ident[EI_VERSION] Indicating original elf

03                              # e_ident[EI_OSABI] Set at 3 because FreeBSD is strict
00                              # e_ident[EI_ABIVERSION] Set at 0 because none cares

00 00 00 00 00 00 00            # e_ident[EI_PAD]

02 00                           # e_type Indicating Executable
03 00                           # e_machine Indicating x86
01 00 00 00                     # e_version Indicating original elf

54 80 04 08                     # e_entry Address of the entry point
34 00 00 00                     # e_phoff Address of program header table
00 00 00 00                     # e_shoff Address of section header table

00 00 00 00                     # e_flags

34 00                           # e_ehsize Indicating our 52 Byte header

20 00                           # e_phentsize size of a program header table
01 00                           # e_phnum number of entries in program table

00 00                           # e_shentsize size of a section header table
00 00                           # e_shnum number of entries in section table

00 00                           # e_shstrndx index of the section names

## Program Header
01 00 00 00                     # ph_type: PT-LOAD = 1
00 00 00 00                     # ph_offset

00 80 04 08                     # ph_vaddr
00 80 04 08                     # ph_physaddr

7E 05 00 00                     # ph_filesz
7E 05 00 00                     # ph_memsz

07 00 00 00                    # ph_flags: PF-X|PF-W|PF-R = 7
01 00 00 00                    # ph_align

    ;; Register usage:
    ;; EAX, EDX, ECX, EBX => Temps
    ;; EDI => IP
    ;; EBP => MALLOC
    ;; ESI => HEAD

    ;; Struct format: (size 24)
    ;; NEXT => 0
    ;; TARGET => 8
    ;; NAME => 16

; Where the ELF Header is going to hit
; Simply jump to _start
; Our main function

#:_start
    BB 00000000                 ; LOADI32_EBX %0              ; Get current pointer
    E8 %x                       ; CALL32 %malloc              ; Get current HEAP
    89C3                        ; COPY_EAX_to_EBX             ; Using current
    89C5                        ; COPY_EAX_to_EBP             ; Setup MALLOC
    81C3 0000C000               ; ADDI32_EBX %12582912        ; Create space for temp [12M]
    E8 %x                       ; CALL32 %malloc              ; Give ourselves 8192000 bytes to work with

    58                          ; POP_EAX                     ; Get the number of arguments
    5B                          ; POP_EBX                     ; Get the program name
    5B                          ; POP_EBX                     ; Get the actual input name
    B9 00000000                 ; LOADI32_ECX %0              ; prepare read_only
    BA 00000000                 ; LOADI32_EDX %0              ; Really sure
    B8 05000000                 ; LOADI32_EAX %5              ; the syscall number for open()
    CD80                        ; INT_80                      ; Now open that damn file
    A3 6E850408                 ; STORE32_Absolute32_eax &Input ; Preserve the file pointer we were given

    5B                          ; POP_EBX                     ; Get the actual output name
    B9 41020000                 ; LOADI32_ECX %577            ; Prepare file as O_WRONLY|O_CREAT|O_TRUNC
    BA C0010000                 ; LOADI32_EDX %448            ; Prepare file as RWX for owner only (700 in octal)
    B8 05000000                 ; LOADI32_EAX %5              ; the syscall number for open()
    CD80                        ; INT_80                      ; Now open that damn file
    83F8 00                     ; CMPI8_EAX !0                ; Check for missing output
    0F8F %a                     ; JG32 %_start_out            ; Have real input
    B8 01000000                 ; LOADI32_EAX %1              ; Use stdout

:a #:_start_out
    A3 72850408                 ; STORE32_Absolute32_eax &Output ; Preserve the file pointer we were given


    E8 %I                       ; CALL32 %ClearScratch        ; Zero scratch
    B8 FFFFFFFF                 ; LOADI32_EAX %-1             ; Our flag for byte processing
    A3 6A850408                 ; STORE32_Absolute32_eax &Flag ; Set
    B8 00000000                 ; LOADI32_EAX %0              ; temp storage for the sum
    A3 66850408                 ; STORE32_Absolute32_eax &High ; Set
    BF 00800408                 ; LOADI32_EDI %0x8048000      ; Our starting IP
    BE 00000000                 ; LOADI32_ESI %0              ; HEAD = NULL
    E8 %b                       ; CALL32 %First_pass          ; Process it

    ; rewind input file
    8B1D 6E850408               ; LOAD32_Absolute32_ebx &Input ; Using our input file
    B9 00000000                 ; LOADI32_ECX %0              ; Offset Zero
    BA 00000000                 ; LOADI32_EDX %0              ; Whence Zero
    B8 13000000                 ; LOADI32_EAX %19             ; lseek
    56                          ; PUSH_ESI                    ; Protect HEAD
    CD80                        ; INT_80
    5E                          ; POP_ESI                     ; Restore HEAD

    B8 FFFFFFFF                 ; LOADI32_EAX %-1             ; Our flag for byte processing
    A3 6A850408                 ; STORE32_Absolute32_eax &Flag ; Set
    B8 00000000                 ; LOADI32_EAX %0              ; temp storage for the sum
    A3 66850408                 ; STORE32_Absolute32_eax &High ; Set
    BF 00800408                 ; LOADI32_EDI %0x8048000      ; Our starting IP
    E8 %l                       ; CALL32 %Second_pass         ; Process it

    E9 %w                       ; JMP32 %Done

:b #:First_pass
    E8 %y                       ; CALL32 %Read_byte

    ; Deal with EOF
    83F8 FC                     ; CMPI8_EAX !-4
    0F84 %j                     ; JE32 %First_pass_done

    ; Check for :
    83F8 3A                     ; CMPI8_EAX !0x3A
    0F85 %c                     ; JNE32 %First_pass_0

    ; Deal with label
    E9 %D                       ; JMP32 %StoreLabel

:c #:First_pass_0
    ; Check for !
    83F8 21                     ; CMPI8_EAX !0x21
    0F84 %i                     ; JE32 %First_pass_pointer

    ; Check for @
    83F8 40                     ; CMPI8_EAX !0x40
    0F84 %i                     ; JE32 %First_pass_pointer

    ; Check for $
    83F8 24                     ; CMPI8_EAX !0x24
    0F84 %i                     ; JE32 %First_pass_pointer

    ; Check for %
    83F8 25                     ; CMPI8_EAX !0x25
    0F84 %i                     ; JE32 %First_pass_pointer

    ; Check for &
    83F8 26                     ; CMPI8_EAX !0x26
    0F84 %i                     ; JE32 %First_pass_pointer

    ; Deal with everything else
    E8 %k                       ; CALL32 %hex                 ; Process our char

    ; Deal with EOF
    83F8 FC                     ; CMPI8_EAX !-4
    0F84 %j                     ; JE32 %First_pass_done

    ; deal with -1 values
    83F8 00                     ; CMPI8_EAX !0
    0F8C %b                     ; JL32 %First_pass

    ; deal with toggle
    A1 6A850408                 ; LOAD32_Absolute32_eax &Flag
    83F8 00                     ; CMPI8_EAX !0
    0F84 %d                     ; JE32 %First_pass_1
    83C7 01                     ; ADDI8_EDI !1                ; Increment IP

:d #:First_pass_1
    F7D0                        ; NOT_EAX
    A3 6A850408                 ; STORE32_Absolute32_eax &Flag
    E9 %b                       ; JMP32 %First_pass

:e #:Update_Pointer
    ; Check for !
    83F8 21                     ; CMPI8_EAX !0x21
    0F84 %h                     ; JE32 %Update_Pointer_1

    ; Check for @
    83F8 40                     ; CMPI8_EAX !0x40
    0F84 %g                     ; JE32 %Update_Pointer_2

    ; Check for $
    83F8 24                     ; CMPI8_EAX !0x24
    0F84 %g                     ; JE32 %Update_Pointer_2

    ; Check for %
    83F8 25                     ; CMPI8_EAX !0x25
    0F84 %f                     ; JE32 %Update_Pointer_4

    ; Check for &
    83F8 26                     ; CMPI8_EAX !0x26
    0F84 %f                     ; JE32 %Update_Pointer_4

    ;; deal with bad input
    E8 %R                       ; CALL32 %fail

:f #:Update_Pointer_4
    83C7 02                     ; ADDI8_EDI !2                ; Increment IP
:g #:Update_Pointer_2
    83C7 01                     ; ADDI8_EDI !1                ; Increment IP
:h #:Update_Pointer_1
    83C7 01                     ; ADDI8_EDI !1                ; Increment IP
    C3                          ; RET

:i #:First_pass_pointer
    ; Deal with Pointer to label
    E8 %e                       ; CALL32 %Update_Pointer      ; Increment IP
    BB 7A850408                 ; LOADI32_EBX &table          ; Using scratch
    E8 %B                       ; CALL32 %consume_token       ; Read token
    E8 %I                       ; CALL32 %ClearScratch        ; Throw away token
    83F8 3E                     ; CMPI8_EAX !0x3E             ; check for '>'
    0F85 %b                     ; JNE32 %First_pass           ; Loop again

    ;; Deal with %label>label case
    BB 7A850408                 ; LOADI32_EBX &table          ; Write to scratch
    E8 %B                       ; CALL32 %consume_token       ; get token
    E8 %I                       ; CALL32 %ClearScratch        ; Clean up after ourselves
    E9 %b                       ; JMP32 %First_pass           ; Loop again

:j # :First_pass_done
    C3                          ; RET

:k #:hex
    ; deal with EOF
    83F8 FC                     ; CMPI8_EAX !-4
    0F84 %o                     ; JE32 %EOF
    ; deal with line comments starting with #
    83F8 23                     ; CMPI8_EAX !0x23
    0F84 %t                     ; JE32 %ascii_comment
    ; deal with line comments starting with ;
    83F8 3B                     ; CMPI8_EAX !0x3B
    0F84 %t                     ; JE32 %ascii_comment
    ; deal all ascii less than 0
    83F8 30                     ; CMPI8_EAX !0x30
    0F8C %s                     ; JL32 %ascii_other
    ; deal with 0-9
    83F8 3A                     ; CMPI8_EAX !0x3A
    0F8C %p                     ; JL32 %ascii_num
    ; deal with all ascii less than A
    83F8 41                     ; CMPI8_EAX !0x41
    0F8C %s                     ; JL32 %ascii_other
    ; deal with A-F
    83F8 47                     ; CMPI8_EAX !0x47
    0F8C %r                     ; JL32 %ascii_high
    ;deal with all ascii less than a
    83F8 61                     ; CMPI8_EAX !0x61
    0F8C %s                     ; JL32 %ascii_other
    ;deal with a-f
    83F8 67                     ; CMPI8_EAX !0x67
    0F8C %q                     ; JL32 %ascii_low
    ; The rest that remains needs to be ignored
    E9 %s                       ; JMP32 %ascii_other

:l #:Second_pass
    E8 %y                       ; CALL32 %Read_byte

    ; Deal with EOF
    83F8 FC                     ; CMPI8_EAX !-4
    0F84 %n                     ; JE32 %Second_pass_done

    ; Simply drop the label
    83F8 3A                     ; CMPI8_EAX !0x3A
    0F85 %m                     ; JNE32 %Second_pass_0

    BB 7A850408                 ; LOADI32_EBX &table          ; Using scratch
    E8 %B                       ; CALL32 %consume_token       ; Read token
    E8 %I                       ; CALL32 %ClearScratch        ; Throw away token

    E9 %l                       ; JMP32 %Second_pass

:m #:Second_pass_0
    ; Deal with % pointer
    83F8 25                     ; CMPI8_EAX !0x25
    0F84 %M                     ; JE32 %StorePointer_rel4

    ; Deal with @ pointer
    83F8 40                     ; CMPI8_EAX !0x40
    0F84 %N                     ; JE32 %StorePointer_rel2

    ; Deal with ! pointer
    83F8 21                     ; CMPI8_EAX !0x21
    0F84 %O                     ; JE32 %StorePointer_rel1

    ; Deal with & pointer
    83F8 26                     ; CMPI8_EAX !0x26
    0F84 %P                     ; JE32 %StorePointer_abs4

    ; Deal with $ pointer
    83F8 24                     ; CMPI8_EAX !0x24
    0F84 %Q                     ; JE32 %StorePointer_abs2

#:Second_pass_1
    ; Deal with everything else
    E8 %k                       ; CALL32 %hex                 ; Process our char

    ; Deal with EOF
    83F8 FC                     ; CMPI8_EAX !-4
    0F84 %n                     ; JE32 %Second_pass_done

    ; deal with -1 values
    83F8 00                     ; CMPI8_EAX !0
    0F8C %l                     ; JL32 %Second_pass

    ; deal with toggle
    8B1D 6A850408               ; LOAD32_Absolute32_ebx &Flag
    83FB 00                     ; CMPI8_EBX !0
    0F84 %v                     ; JE32 %print

    ; process first byte of pair
    C1E0 04                     ; SHLI8_EAX !4
    A3 66850408                 ; STORE32_Absolute32_eax &High
    B8 00000000                 ; LOADI32_EAX %0
    A3 6A850408                 ; STORE32_Absolute32_eax &Flag
    E9 %l                       ; JMP32 %Second_pass

:n #:Second_pass_done
    C3                          ; RET

:o #:EOF
    C3                          ; RET
:p #:ascii_num
    83E8 30                     ; SUBI8_EAX !0x30
    C3                          ; RET
:q #:ascii_low
    83E8 57                     ; SUBI8_EAX !0x57
    C3                          ; RET
:r #:ascii_high
    83E8 37                     ; SUBI8_EAX !0x37
    C3                          ; RET
:s #:ascii_other
    B8 FFFFFFFF                 ; LOADI32_EAX %-1
    C3                          ; RET
:t #:ascii_comment
    E8 %y                       ; CALL32 %Read_byte
    83F8 0D                     ; CMPI8_EAX !0x0D
    0F84 %u                     ; JE32 %ascii_comment_cr
    83F8 0A                     ; CMPI8_EAX !0x0A
    0F85 %t                     ; JNE32 %ascii_comment
:u #:ascii_comment_cr
    B8 FFFFFFFF                 ; LOADI32_EAX %-1
    C3                          ; RET

; process second byte of pair
:v #:print
    ; update the sum and store in output
    0305 66850408               ; ADD32_Absolute32_eax &High

    ; Print our first Hex
    BA 01000000                 ; LOADI32_EDX %1              ; set the size of chars we want
    E8 %A                       ; CALL32 %print_chars

    ; flip the toggle
    A1 6A850408                 ; LOAD32_Absolute32_eax &Flag
    F7D0                        ; NOT_EAX
    A3 6A850408                 ; STORE32_Absolute32_eax &Flag

    83C7 01                     ; ADDI8_EDI !1                ; Increment IP
    E9 %l                       ; JMP32 %Second_pass

:w #:Done
    ; program completed Successfully
    BB 00000000                 ; LOADI32_EBX %0              ; All is well
    B8 01000000                 ; LOADI32_EAX %1              ; put the exit syscall number in eax
    CD80                        ; INT_80                      ; Call it a good day


;; Malloc isn't actually required if the program being built fits in the initial memory
;; However, it doesn't take much to add it.
;; Requires a value in EBX
:x #:malloc
    B8 2D000000                 ; LOADI32_EAX %45             ; the Syscall # for SYS_BRK
    56                          ; PUSH_ESI                    ; Protect esi
    57                          ; PUSH_EDI                    ; Protect edi
    CD80                        ; INT_80                      ; call the Kernel
    5F                          ; POP_EDI                     ; Restore edi
    5E                          ; POP_ESI                     ; Restore esi
    C3                          ; RET


:y #:Read_byte
    52                          ; PUSH_EDX                    ; Protect EDX
    51                          ; PUSH_ECX                    ; Protect ECX
    53                          ; PUSH_EBX                    ; Protect EBX
    B8 FCFFFFFF                 ; LOADI32_EAX %-4             ; Put EOF in eax
    50                          ; PUSH_EAX                    ; Assume bad (If nothing read, value will remain EOF)
    8D0C24                      ; LEA32_ECX_from_esp          ; Get stack address
    8B1D 6E850408               ; LOAD32_Absolute32_ebx &Input ; Where are we reading from
    B8 03000000                 ; LOADI32_EAX %3              ; the syscall number for read
    BA 01000000                 ; LOADI32_EDX %1              ; set the size of chars we want
    CD80                        ; INT_80                      ; call the Kernel
    85C0                        ; TEST                        ; check what we got
    58                          ; POP_EAX                     ; Get either char or EOF
    0F84 %z                     ; JE32 %Read_byte_1           ; Got EOF call it done
    0FB6C0                      ; MOVZX_al                    ; We have to zero extend it to use it
    5B                          ; POP_EBX                     ; Restore EBX
    59                          ; POP_ECX                     ; Restore ECX
    5A                          ; POP_EDX                     ; Restore EDX
    C3                          ; RET

; Deal with EOF
:z #:Read_byte_1
    5B
    59
    5A
    C3                          ; RET

:A #:print_chars
    52                          ; PUSH_EDX                    ; Protect EDX
    51                          ; PUSH_ECX                    ; protect ECX
    53                          ; PUSH_EBX                    ; protect EBX
    50                          ; PUSH_EAX                    ; We are writing eax
    8D0C24                      ; LEA32_ECX_from_esp          ; Get stack address
    8B1D 72850408               ; LOAD32_Absolute32_ebx &Output ; Write to target file
    B8 04000000                 ; LOADI32_EAX %4              ; the syscall number for write
    ;; EDX contains the number of bytes to write
    CD80                        ; INT_80                      ; call the Kernel
    58                          ; POP_EAX                     ; Restore stack
    5B                          ; POP_EBX                     ; Restore EBX
    59                          ; POP_ECX                     ; Restore ECX
    5A                          ; POP_EDX                     ; Restore EDX
    C3                          ; RET

;; Receives pointer in EBX
;; Writes out char and updates EBX
:B #:consume_token
    E8 %y                       ; CALL32 %Read_byte           ; Consume_token

    ; Check for \t
    83F8 09                     ; CMPI8_EAX !0x09
    0F84 %C                     ; JE32 %consume_token_done

    ; Check for \n
    83F8 0A                     ; CMPI8_EAX !0x0A
    0F84 %C                     ; JE32 %consume_token_done

    ; Check for ' '
    83F8 20                     ; CMPI8_EAX !0x20
    0F84 %C                     ; JE32 %consume_token_done

    ; Check for '>'
    83F8 3E                     ; CMPI8_EAX !0x3E
    0F84 %C                     ; JE32 %consume_token_done

    ;; Looks like we are still reading token
    8803                        ; STORE8_al_into_Address_EBX  ; Store char
    83C3 01                     ; ADDI8_EBX !1                ; Point to next spot
    E9 %B                       ; JMP32 %consume_token        ; loop until done

:C #:consume_token_done
    B9 00000000                 ; LOADI32_ECX %0              ; Pad with nulls
    890B                        ; STORE32_ECX_into_Address_EBX
    83C3 04                     ; ADDI8_EBX !4
    C3                          ; RET

:D #:StoreLabel
    89E8                        ; COPY_EBP_to_EAX             ; ENTRY
    83C5 18                     ; ADDI8_EBP !24               ; CALLOC
    8978 08                     ; STORE32_EDI_into_Address_EAX_Immediate8 !8 ; ENTRY->TARGET = IP
    8930                        ; STORE32_ESI_into_Address_EAX ; ENTRY->NEXT = JUMP_TABLE
    89C6                        ; COPY_EAX_to_ESI             ; JUMP_TABLE = ENTRY
    896E 10                     ; STORE32_EBP_into_Address_ESI_Immediate8 !16 ; ENTRY->NAME = TOKEN
    89EB                        ; COPY_EBP_to_EBX             ; Write Starting after struct
    E8 %B                       ; CALL32 %consume_token       ; Collect whole string
    89DD                        ; COPY_EBX_to_EBP             ; Update HEAP
    E9 %b                       ; JMP32 %First_pass

:E #:GetTarget
    53                          ; PUSH_EBX                    ; protect ebx
    51                          ; PUSH_ECX                    ; protect ecx
    52                          ; PUSH_EDX                    ; protect edx
    56                          ; PUSH_ESI                    ; protect JUMP_TABLE
    B9 7A850408                 ; LOADI32_ECX &table          ; Reset scratch
    8B56 10                     ; LOAD32_EDX_from_ESI_Immediate8 !16 ; I->NAME
:F #:GetTarget_loop
    8A01                        ; LOAD8_al_from_ECX           ; I->NAME[0]
    8A1A                        ; LOAD8_bl_from_EDX           ; scratch[0]
    0FB6DB                      ; MOVZX_bl                    ; Zero extend
    0FB6C0                      ; MOVZX_al                    ; Zero extend
    38D8                        ; CMP_al_bl                   ; IF TOKEN == I->NAME
    0F85 %G                     ; JNE32 %GetTarget_miss       ; Oops

    83C1 01                     ; ADDI8_ECX !1
    83C2 01                     ; ADDI8_EDX !1
    3C 00                       ; CMPI8_al !0
    0F85 %F                     ; JNE32 %GetTarget_loop       ; Loop until
    E9 %H                       ; JMP32 %GetTarget_done       ; Match

    ;; Miss
:G #:GetTarget_miss
    8B36                        ; LOAD32_ESI_from_ESI         ; I = I->NEXT
    83FE 00                     ; CMPI8_ESI !0                ; IF NULL == I
    0F84 %R                     ; JE32 %fail                  ; Abort hard

    8B56 10                     ; LOAD32_EDX_from_ESI_Immediate8 !16 ; I->NAME
    B9 7A850408                 ; LOADI32_ECX &table          ; Reset scratch
    E9 %F                       ; JMP32 %GetTarget_loop

:H #:GetTarget_done
    8B46 08                     ; LOAD32_EAX_from_ESI_Immediate8 !8 ; Get address
    5E                          ; POP_ESI                     ; Restore JUMP_TABLE
    5A                          ; POP_EDX                     ; Restore EDX
    59                          ; POP_ECX                     ; Restore ECX
    5B                          ; POP_EBX                     ; Restore EBX
    C3                          ; RET

:I #:ClearScratch
    50                          ; PUSH_EAX                    ; Protect against changes
    53                          ; PUSH_EBX                    ; And overwrites
    51                          ; PUSH_ECX                    ; While we work
    BB 7A850408                 ; LOADI32_EBX &table          ; Where our table is
    B8 00000000                 ; LOADI32_EAX %0              ; Using null

:J #:ClearScratch_loop
    8B0B                        ; LOAD32_ECX_from_EBX         ; Get current value
    8803                        ; STORE8_al_into_Address_EBX  ; Because we want null
    83C3 01                     ; ADDI8_EBX !1                ; Increment
    83F9 00                     ; CMPI8_ECX !0                ; Check if we hit null
    0F85 %J                     ; JNE32 %ClearScratch_loop    ; Keep looping

    59                          ; POP_ECX                     ; Restore
    5B                          ; POP_EBX                     ; Damage
    58                          ; POP_EAX                     ; Entirely
    C3                          ; RET

:K #:StorePointer
    E8 %e                       ; CALL32 %Update_Pointer      ; Increment IP
    BB 7A850408                 ; LOADI32_EBX &table          ; Write to scratch
    E8 %B                       ; CALL32 %consume_token       ; get token
    50                          ; PUSH_EAX                    ; Protect base_sep_p
    B8 7A850408                 ; LOADI32_EAX &table          ; Pointer to scratch
    E8 %E                       ; CALL32 %GetTarget           ; Get address of pointer
    E8 %I                       ; CALL32 %ClearScratch        ; Clean up after ourselves
    89FA                        ; COPY_EDI_to_EDX             ; base = IP
    5B                          ; POP_EBX                     ; Restore base_sep_p
    83FB 3E                     ; CMPI8_EBX !0x3E             ; If base_sep_p == '>'
    0F85 %L                     ; JNE32 %StorePointer_done    ; If not

    ;; Deal with %label>label case
    50                          ; PUSH_EAX                    ; We need to preserve main target
    BB 7A850408                 ; LOADI32_EBX &table          ; Write to scratch
    E8 %B                       ; CALL32 %consume_token       ; get token
    B8 7A850408                 ; LOADI32_EAX &table          ; Pointer to scratch
    E8 %E                       ; CALL32 %GetTarget           ; Get address of pointer
    E8 %I                       ; CALL32 %ClearScratch        ; Clean up after ourselves
    89C2                        ; COPY_EAX_to_EDX             ; Use our new base
    58                          ; POP_EAX                     ; Restore main target

:L #:StorePointer_done
    C3                          ; RET

:M #:StorePointer_rel4
    E8 %K                       ; CALL32 %StorePointer        ; Do Common
    29D0                        ; SUB_EDX_from_EAX            ; target - ip
    BA 04000000                 ; LOADI32_EDX %4              ; set the size of chars we want
    E8 %A                       ; CALL32 %print_chars
    E8 %I                       ; CALL32 %ClearScratch        ; Clean up after ourselves
    E9 %l                       ; JMP32 %Second_pass

:N #:StorePointer_rel2
    E8 %K                       ; CALL32 %StorePointer        ; Do Common
    29D0                        ; SUB_EDX_from_EAX            ; target - ip
    BA 02000000                 ; LOADI32_EDX %2              ; set the size of chars we want
    E8 %A                       ; CALL32 %print_chars
    E8 %I                       ; CALL32 %ClearScratch        ; Clean up after ourselves
    E9 %l                       ; JMP32 %Second_pass

:O #:StorePointer_rel1
    E8 %K                       ; CALL32 %StorePointer        ; Do Common
    29D0                        ; SUB_EDX_from_EAX            ; target - ip
    BA 01000000                 ; LOADI32_EDX %1              ; set the size of chars we want
    E8 %A                       ; CALL32 %print_chars
    E8 %I                       ; CALL32 %ClearScratch        ; Clean up after ourselves
    E9 %l                       ; JMP32 %Second_pass

:P #:StorePointer_abs4
    E8 %K                       ; CALL32 %StorePointer        ; Do Common
    BA 04000000                 ; LOADI32_EDX %4              ; set the size of chars we want
    E8 %A                       ; CALL32 %print_chars
    E8 %I                       ; CALL32 %ClearScratch        ; Clean up after ourselves
    E9 %l                       ; JMP32 %Second_pass

:Q #:StorePointer_abs2
    E8 %K                       ; CALL32 %StorePointer        ; Do Common
    BA 02000000                 ; LOADI32_EDX %2              ; set the size of chars we want
    E8 %A                       ; CALL32 %print_chars
    E8 %I                       ; CALL32 %ClearScratch        ; Clean up after ourselves
    E9 %l                       ; JMP32 %Second_pass

:R #:fail
    ; Some shit went wrong
    BB 01000000                 ; LOADI32_EBX %1              ; All is wrong
    B8 01000000                 ; LOADI32_EAX %1              ; put the exit syscall number in eax
    CD80                        ; INT_80                      ; Call it a good day


#:High (0x8048566)
    00000000                    ; NULL
#:Flag (0x804856A)
    00000000                    ; NULL
#:Input (0x804856E)
    00000000                    ; NULL
#:Output (0x8048572)
    00000000                    ; NULL
#:write (0x8048576)
    00000000                    ; NULL
#:table (0x804857A)
    00000000                    ; NULL
#:ELF_end

https://github.com/oriansj/stage0-posix-x86/blob/main/catm_x86.hex2

File: ../git/live-bootstrap/sysa/stage0-posix/src/x86/catm_x86.hex2 used in: Step 7
;; Copyright (C) 2019 Jeremiah Orians
;; This file is part of mescc-tools.
;;
;; mescc-tools is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;;
;; mescc-tools is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with mescc-tools. If not, see <http://www.gnu.org/licenses/>.

    ;; Register usage:
    ;; EBP => OUTPUT
    ;; EDI => Buffer
    ;; ESI => INPUT

## ELF Header
:ELF_base
7F 45 4C 46                    # e_ident[EI_MAG0-3] ELF's magic number

01                             # e_ident[EI_CLASS] Indicating 32 bit
01                             # e_ident[EI_DATA] Indicating little endianness
01                             # e_ident[EI_VERSION] Indicating original elf

03                             # e_ident[EI_OSABI] Set at 3 because FreeBSD is strict
00                             # e_ident[EI_ABIVERSION] Set at 0 because none cares

00 00 00 00 00 00 00           # e_ident[EI_PAD]

02 00                          # e_type Indicating Executable
03 00                          # e_machine Indicating x86
01 00 00 00                    # e_version Indicating original elf

&_start                        # e_entry Address of the entry point
%ELF_program_headers>ELF_base  # e_phoff Address of program header table
00 00 00 00                    # e_shoff Address of section header table

00 00 00 00                    # e_flags

34 00                          # e_ehsize Indicating our 52 Byte header

20 00                          # e_phentsize size of a program header table
01 00                          # e_phnum number of entries in program table

00 00                          # e_shentsize size of a section header table
00 00                          # e_shnum number of entries in section table

00 00                          # e_shstrndx index of the section names

## Program Header
:ELF_program_headers
:ELF_program_header__text
01 00 00 00                    # ph_type: PT-LOAD = 1
00 00 00 00                    # ph_offset

&ELF_base                      # ph_vaddr
&ELF_base                      # ph_physaddr

%ELF_end>ELF_base              # ph_filesz
%ELF_end>ELF_base              # ph_memsz

07 00 00 00                    # ph_flags: PF-X|PF-W|PF-R = 7
01 00 00 00                    # ph_align

:ELF_text


; Where the ELF Header is going to hit
; Simply jump to _start
; Our main function
:_start
    58                          # POP_EAX                     ; Get the number of arguments
    5B                          # POP_EBX                     ; Get the program name
    5B                          # POP_EBX                     ; Get the actual output name
    66B9 4102                   # LOADI16_CX @577             ; Prepare file as O_WRONLY|O_CREAT|O_TRUNC
    66BA 8001                   # LOADI16_DX @384             ; Prepare file as RW for owner only (600 in octal)
    6A 05                       # PUSH !5                     ; prepare to set eax to 5
    58                          # POP_EAX                     ; the syscall number for open()
    CD80                        # INT_80                      ; Now open that file
    89C5                        # COPY_EAX_to_EBP             ; Preserve the file pointer we were given

    6A 2D                       # PUSH !45
    58                          # POP_EAX                     ; the Syscall # for SYS_BRK
    31DB                        # XOR_EBX_EBX                 ; Get current brk
    CD80                        # INT_80                      ; Let the kernel do the work
    89C7                        # COPY_EAX_to_EDI             ; Set our malloc pointer

    6A 2D                       # PUSH !45
    58                          # POP_EAX                     ; the Syscall # for SYS_BRK
    89FB                        # COPY_EDI_to_EBX             ; Using current pointer
    81C3 00001000               # ADDI32_EBX %0x100000        ; Allocate 1MB
    CD80                        # INT_80                      ; Let the kernel do the work

:core
    5B                          # POP_EBX                     ; Get the actual input name
    85DB                        # TEST_EBX_EBX                ; Check for null string
    74 !done                    # JE8 !done                   ; Hit null be done

    31C9                        # XOR_ECX_ECX                 ; prepare read_only
    31D2                        # XOR_EDX_EDX                 ; prevent any interactions
    6A 05                       # PUSH !5
    58                          # POP_EAX                     ; the syscall number for open()
    CD80                        # INT_80                      ; Now open that damn file
    89C6                        # COPY_EAX_to_ESI             ; Protect INPUT
:keep
    BA 00001000                 # LOADI32_EDX %0x100000       ; set the size of chars we want
    89F9                        # COPY_EDI_to_ECX             ; Where to put it
    89F3                        # COPY_ESI_to_EBX             ; Where are we reading from
    6A03                        # PUSH !3
    58                          # POP_EAX                     ; the syscall number for read
    CD80                        # INT_80                      ; call the Kernel
    50                          # PUSH_EAX                    ; Protect the number of bytes read

    89C2                        # COPY_EAX_to_EDX             ; Number of bytes to write
    89F9                        # COPY_EDI_to_ECX             ; What we are writing
    89EB                        # COPY_EBP_to_EBX             ; Write to target file
    6A 04                       # PUSH !4
    58                          # POP_EAX                     ; the syscall number for write
    CD80                        # INT_80                      ; call the Kernel

    58                          # POP_EAX                     ; Get bytes read
    3D 00001000                 # CMPI32_EAX %0x100000        ; Check if buffer was fully used
    74 !keep                    # JE8 !keep                   ; Keep looping if was full
    EB !core                    # JMP8 !core                  ; Otherwise move to next file

:done
    ; program completed Successfully
    31DB                        # XOR_EBX_EBX                 ; All is well
    6A 01                       # PUSH !1
    58                          # POP_EAX                     ; put the exit syscall number in eax
    CD80                        # INT_80                      ; Call it a good day

:ELF_end

https://github.com/oriansj/stage0-posix-x86/blob/main/ELF-i386.hex2

File: ../git/live-bootstrap/sysa/stage0-posix/src/x86/ELF-i386.hex2 used in: Step 8, Step 11, Step 17
### Copyright (C) 2016 Jeremiah Orians
### Copyright (C) 2017 Jan Nieuwenhuizen <janneke@gnu.org>
### This file is part of stage0.
###
### stage0 is free software: you can redistribute it and/or modify
### it under the terms of the GNU General Public License as published by
### the Free Software Foundation, either version 3 of the License, or
### (at your option) any later version.
###
### stage0 is distributed in the hope that it will be useful,
### but WITHOUT ANY WARRANTY; without even the implied warranty of
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
### GNU General Public License for more details.
###
### You should have received a copy of the GNU General Public License
### along with stage0.  If not, see <http://www.gnu.org/licenses/>.

### stage0's hex2 format
###    !<label>          1 byte relative
###    $<label>          2 byte address
###    @<label>          2 byte relative
###    &<label>          4 byte address
###    %<label>          4 byte relative

### elf32.hex2: 32 bit elf header in hex2
### if you wish to use this header, you need to add :ELF_end to the end of your
### M1 or hex2 files.

## ELF Header
:ELF_base
7F 45 4C 46                    # e_ident[EI_MAG0-3] ELF's magic number

01                             # e_ident[EI_CLASS] Indicating 32 bit
01                             # e_ident[EI_DATA] Indicating little endianness
01                             # e_ident[EI_VERSION] Indicating original elf

03                             # e_ident[EI_OSABI] Set at 3 because FreeBSD is strict
00                             # e_ident[EI_ABIVERSION] Set at 0 because none cares

00 00 00 00 00 00 00           # e_ident[EI_PAD]

02 00                          # e_type Indicating Executable
03 00                          # e_machine Indicating x86
01 00 00 00                    # e_version Indicating original elf

&_start                        # e_entry Address of the entry point
%ELF_program_headers>ELF_base  # e_phoff Address of program header table
00 00 00 00                    # e_shoff Address of section header table

00 00 00 00                    # e_flags

34 00                          # e_ehsize Indicating our 52 Byte header

20 00                          # e_phentsize size of a program header table
01 00                          # e_phnum number of entries in program table

00 00                          # e_shentsize size of a section header table
00 00                          # e_shnum number of entries in section table

00 00                          # e_shstrndx index of the section names

## Program Header
:ELF_program_headers
:ELF_program_header__text
01 00 00 00                    # ph_type: PT-LOAD = 1
00 00 00 00                    # ph_offset

&ELF_base                      # ph_vaddr
&ELF_base                      # ph_physaddr

%ELF_end>ELF_base              # ph_filesz
%ELF_end>ELF_base              # ph_memsz

07 00 00 00                    # ph_flags: PF-X|PF-W|PF-R = 7
01 00 00 00                    # ph_align

:ELF_text

https://github.com/oriansj/stage0-posix-x86/blob/main/M0_x86.hex2

File: ../git/live-bootstrap/sysa/stage0-posix/src/x86/M0_x86.hex2 used in: Step 8
;; Copyright (C) 2017 Jeremiah Orians
;; This file is part of stage0.
;;
;; stage0 is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;;
;; stage0 is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with stage0.  If not, see <http://www.gnu.org/licenses/>.

    ;; Register usage:
    ;; EAX, ECX, EBX => Temps
    ;; EDI => MALLOC
    ;; EBP => HEAD
    ;; [Output] => Output_file
    ;; [Input] => Input_file

    ;; Struct format: (size 32)
    ;; NEXT => 0
    ;; TYPE => 8
    ;; TEXT => 16
    ;; EXPRESSION => 24

    ;; Types
    ;; None => 0
    ;; MACRO => 1
    ;; STRING => 2

; Where the ELF Header is going to hit
; Simply jump to _start
; Our main function
:_start
    58                          ; POP_EAX                     ; Get the number of arguments
    5B                          ; POP_EBX                     ; Get the program name
    5B                          ; POP_EBX                     ; Get the actual input name
    B9 00000000                 ; LOADI32_ECX %0              ; prepare read_only
    B8 05000000                 ; LOADI32_EAX %5              ; the syscall number for open()
    CD80                        ; INT_80                      ; Now open that damn file
    A3 &Input                   ; STORE32_Absolute32_eax &Input ; Preserve the file pointer we were given

    5B                          ; POP_EBX                     ; Get the actual output name
    B9 41020000                 ; LOADI32_ECX %577            ; Prepare file as O_WRONLY|O_CREAT|O_TRUNC
    BA 80010000                 ; LOADI32_EDX %384            ; Prepare file as RW for owner only (600 in octal)
    B8 05000000                 ; LOADI32_EAX %5              ; the syscall number for open()
    CD80                        ; INT_80                      ; Now open that damn file
    83F8 00                     ; CMPI8_EAX !0                ; Check for missing output
    0F8F %_start_out            ; JG32 %_start_out            ; Have real input
    B8 01000000                 ; LOADI32_EAX %1              ; Use stdout

:_start_out
    A3 &Output                  ; STORE32_Absolute32_eax &Output ; Preserve the file pointer we were given

    B8 2D000000                 ; LOADI32_EAX %45             ; the Syscall # for SYS_BRK
    BB 00000000                 ; LOADI32_EBX %0              ; Get current brk
    CD80                        ; INT_80                      ; Let the kernel do the work
    89C7                        ; COPY_EAX_to_EDI             ; Set our malloc pointer

    E8 %Tokenize_Line           ; CALL32 %Tokenize_Line       ; Get all lines
    89E8                        ; COPY_EBP_to_EAX             ; prepare for Reverse_List
    E8 %Reverse_List            ; CALL32 %Reverse_List        ; Correct order
    89C5                        ; COPY_EAX_to_EBP             ; Update HEAD
    E8 %Identify_Macros         ; CALL32 %Identify_Macros     ; Find the DEFINEs
    E8 %Line_Macro              ; CALL32 %Line_Macro          ; Apply the DEFINEs
    E8 %Process_String          ; CALL32 %Process_String      ; Handle strings
    E8 %Eval_Immediates         ; CALL32 %Eval_Immediates     ; Handle Numbers
    E8 %Preserve_Other          ; CALL32 %Preserve_Other      ; Collect the remaining
    E8 %Print_Hex               ; CALL32 %Print_Hex           ; Output our results

:Done
    ; program completed Successfully
    BB 00000000                 ; LOADI32_EBX %0              ; All is well
    B8 01000000                 ; LOADI32_EAX %1              ; put the exit syscall number in eax
    CD80                        ; INT_80                      ; Call it a good day


;; Tokenize_Line Function
;; Using input file [Input] and Head EBP
;; Creates a linked list of structs
;; Uses EBX for in_set strings, ECX for Int C and EDX for Struct Token* p
:Tokenize_Line
    53                          ; PUSH_EBX                    ; Protect EBX
    51                          ; PUSH_ECX                    ; Protect ECX
    52                          ; PUSH_EDX                    ; Protect EDX
:restart
    E8 %fgetc                   ; CALL32 %fgetc               ; Read a char
    83F8 FC                     ; CMPI8_EAX !-4               ; Check for EOF
    0F84 %done                  ; JE32 %done                  ; File is collected

    0FB6C0                      ; MOVZX_al                    ; We have to zero extend it to use it
    89C1                        ; COPY_EAX_to_ECX             ; Protect C

    BB &comments                ; LOADI32_EBX &comments       ; Get pointer to "#;"
    E8 %In_Set                  ; CALL32 %In_Set              ; Check for comments
    83F8 01                     ; CMPI8_EAX !1                ; If comments
    0F84 %Purge_LineComment     ; JE32 %Purge_LineComment     ; try again

    89C8                        ; COPY_ECX_to_EAX             ; put C in place for check
    BB &terminators             ; LOADI32_EBX &terminators    ; Get pointer to "\n\t "
    E8 %In_Set                  ; CALL32 %In_Set              ; Check for terminators
    83F8 01                     ; CMPI8_EAX !1                ; If terminator
    0F84 %restart               ; JE32 %restart               ; try again

    B8 20000000                 ; LOADI32_EAX %32             ; Malloc the struct P
    E8 %malloc                  ; CALL32 %malloc              ; Get pointer to P
    89C2                        ; COPY_EAX_to_EDX             ; Protect P
    892A                        ; STORE32_EBP_into_Address_EDX ; P->NEXT = HEAD
    89D5                        ; COPY_EDX_to_EBP             ; HEAD = P

    89C8                        ; COPY_ECX_to_EAX             ; put C in place for check
    BB &string_char             ; LOADI32_EBX &string_char    ; Get pointer to "\"'"
    E8 %In_Set                  ; CALL32 %In_Set              ; Check for string chars
    83F8 01                     ; CMPI8_EAX !1                ; If string char
    0F84 %Store_String          ; JE32 %Store_String          ; Get string

    E8 %Store_Atom              ; CALL32 %Store_Atom          ; Get whole token
    E9 %restart                 ; JMP32 %restart

:done
    5A                          ; POP_EDX                     ; Restore EDX
    59                          ; POP_ECX                     ; Restore ECX
    5B                          ; POP_EBX                     ; Restore EBX
    C3                          ; RET


;; fgetc function
;; Receives FILE* in [Input]
;; Returns -4 (EOF) or char in EAX
:fgetc
    52                          ; PUSH_EDX                    ; Protect EDX
    51                          ; PUSH_ECX                    ; Protect ECX
    53                          ; PUSH_EBX                    ; Protect EBX
    B8 FCFFFFFF                 ; LOADI32_EAX %-4             ; Put EOF in eax
    50                          ; PUSH_EAX                    ; Assume bad (If nothing read, value will remain EOF)
    8D0C24                      ; LEA32_ECX_from_esp          ; Get stack address
    8B1D &Input                 ; LOAD32_Absolute32_ebx &Input ; Where are we reading from
    B8 03000000                 ; LOADI32_EAX %3              ; the syscall number for read
    BA 01000000                 ; LOADI32_EDX %1              ; set the size of chars we want
    CD80                        ; INT_80                      ; call the Kernel
    58                          ; POP_EAX                     ; Get either char or EOF
    5B                          ; POP_EBX                     ; Restore EBX
    59                          ; POP_ECX                     ; Restore ECX
    5A                          ; POP_EDX                     ; Restore EDX
    C3                          ; RET


;; Malloc isn't actually required if the program being built fits in the initial memory
;; However, it doesn't take much to add it.
;; Requires EDI to be initialized and EAX to have the number of desired bytes
:malloc
    52                          ; PUSH_EDX                    ; Protect EDX
    51                          ; PUSH_ECX                    ; Protect ECX
    53                          ; PUSH_EBX                    ; Protect EBX

    89FB                        ; COPY_EDI_to_EBX             ; Using the current pointer
    01C3                        ; ADD_EAX_to_EBX              ; Request the number of desired bytes
    B8 2D000000                 ; LOADI32_EAX %45             ; the Syscall # for SYS_BRK
    CD80                        ; INT_80                      ; call the Kernel
    89F8                        ; COPY_EDI_to_EAX             ; Return pointer
    89DF                        ; COPY_EBX_to_EDI             ; Update pointer

    5B                          ; POP_EBX                     ; Restore EBX
    59                          ; POP_ECX                     ; Restore ECX
    5A                          ; POP_EDX                     ; Restore EDX
    C3                          ; RET


;; Purge_LineComment function
;; Reads chars until LF and jumps to restart
:Purge_LineComment
    E8 %fgetc                   ; CALL32 %fgetc               ; Get a char
    0FB6C0                      ; MOVZX_al                    ; Zero extend
    83F8 0A                     ; CMPI8_EAX !10               ; While not LF
    0F85 %Purge_LineComment     ; JNE32 %Purge_LineComment    ; Keep reading
    E9 %restart                 ; JMP32 %restart


;; Store_String Function
;; Receives C in ECX, HEAD in EDX and Input file in [Output]
;; Uses EBX for terminator, ECX for C and EDX for string
:Store_String
    53                          ; PUSH_EBX                    ; Protect EBX
    51                          ; PUSH_ECX                    ; Protect ECX
    52                          ; PUSH_EDX                    ; Protect EDX

    B8 02000000                 ; LOADI32_EAX %2              ; Using TYPE STRING
    8942 08                     ; STORE32_EAX_into_Address_EDX_Immediate8 !8 ; HEAD->TYPE = STRING
    B8 00010000                 ; LOADI32_EAX %256            ; Malloc the string
    E8 %malloc                  ; CALL32 %malloc              ; Get pointer to P
    8942 10                     ; STORE32_EAX_into_Address_EDX_Immediate8 !16 ; HEAD->TEXT = STRING
    89CB                        ; COPY_ECX_to_EBX             ; Protect terminator
    89C2                        ; COPY_EAX_to_EDX             ; Protect string pointer
:Store_String_Loop
    880A                        ; STORE8_cl_into_Address_EDX  ; write byte
    E8 %fgetc                   ; CALL32 %fgetc               ; read next char
    0FB6C0                      ; MOVZX_al                    ; Zero extend it
    89C1                        ; COPY_EAX_to_ECX             ; Update C
    83C2 01                     ; ADDI8_EDX !1                ; STRING = STRING + 1
    39D9                        ; CMP_EBX_ECX                 ; See if we hit terminator
    0F85 %Store_String_Loop     ; JNE32 %Store_String_Loop    ; Otherwise keep looping

    5A                          ; POP_EDX                     ; Restore EDX
    59                          ; POP_ECX                     ; Restore ECX
    5B                          ; POP_EBX                     ; Restore EBX
    89D0                        ; COPY_EDX_to_EAX             ; return HEAD
    E9 %restart                 ; JMP32 %restart


;; Store_Atom Function
;; Receives C in ECX, HEAD in EDX and Input file in [Input]
;; Uses EBX for in_set strings, ECX for C and EDX for string
:Store_Atom
    53                          ; PUSH_EBX                    ; Protect EBX
    51                          ; PUSH_ECX                    ; Protect ECX
    52                          ; PUSH_EDX                    ; Protect EDX

    B8 00010000                 ; LOADI32_EAX %256            ; Malloc the string
    E8 %malloc                  ; CALL32 %malloc              ; Get pointer to P
    8942 10                     ; STORE32_EAX_into_Address_EDX_Immediate8 !16 ; HEAD->TEXT = STRING
    BB &terminators             ; LOADI32_EBX &terminators    ; Get pointer to "\n\t "
    89C2                        ; COPY_EAX_to_EDX             ; Protect string pointer
:Store_Atom_loop
    880A                        ; STORE8_cl_into_Address_EDX  ; write byte
    E8 %fgetc                   ; CALL32 %fgetc               ; read next char
    0FB6C0                      ; MOVZX_al                    ; Zero extend it
    89C1                        ; COPY_EAX_to_ECX             ; Update C
    83C2 01                     ; ADDI8_EDX !1                ; STRING = STRING + 1
    E8 %In_Set                  ; CALL32 %In_Set              ; Check for terminators
    83F8 00                     ; CMPI8_EAX !0                ; Check for "\n\t "
    0F84 %Store_Atom_loop       ; JE32 %Store_Atom_loop       ; Loop otherwise

    5A                          ; POP_EDX                     ; Restore EDX
    59                          ; POP_ECX                     ; Restore ECX
    5B                          ; POP_EBX                     ; Restore EBX
    89D0                        ; COPY_EDX_to_EAX             ; return HEAD
    C3                          ; RET


;; In_Set function
;; Receives Char C in EAX and CHAR* in EBX
;; Returns 1 if true, zero if false in EAX
:In_Set
    53                          ; PUSH_EBX                    ; Protect EBX
    51                          ; PUSH_ECX                    ; Protect ECX
:In_Set_loop
    8A0B                        ; LOAD8_cl_from_EBX           ; Read char
    0FB6C9                      ; MOVZX_cl                    ; Zero extend it

    39C8                        ; CMP_EAX_ECX                 ; See if they match
    0F84 %In_Set_True           ; JE32 %In_Set_True           ; return true

    83F9 00                     ; CMPI8_ECX !0                ; Check for NULL
    0F84 %In_Set_False          ; JE32 %In_Set_False          ; return false

    83C3 01                     ; ADDI8_EBX !1                ; s = s + 1
    E9 %In_Set_loop             ; JMP32 %In_Set_loop          ; Keep looping

:In_Set_True
    B8 01000000                 ; LOADI32_EAX %1              ; Set True
    59                          ; POP_ECX                     ; Restore ECX
    5B                          ; POP_EBX                     ; Restore EBX
    C3                          ; RET

:In_Set_False
    B8 00000000                 ; LOADI32_EAX %0              ; Set FALSE
    59                          ; POP_ECX                     ; Restore ECX
    5B                          ; POP_EBX                     ; Restore EBX
    C3                          ; RET

;; Char sets
:terminators
0A092000                        ; "\n\t "

:comments
3B2300                          ; ";#"

:string_char
22 27 00                        ; "\"\'"


;; Reverse_List function
;; Receives List in EAX
;; Returns the list reversed in EAX
:Reverse_List
    53                          ; PUSH_EBX                    ; Protect EBX
    51                          ; PUSH_ECX                    ; Protect ECX
    89C3                        ; COPY_EAX_to_EBX             ; Set HEAD
    B8 00000000                 ; LOADI32_EAX %0              ; ROOT = NULL
:Reverse_List_Loop
    83FB 00                     ; CMPI8_EBX !0                ; WHILE HEAD != NULL
    0F84 %Reverse_List_Done     ; JE32 %Reverse_List_Done     ; Stop otherwise

    8B0B                        ; LOAD32_ECX_from_EBX         ; NEXT = HEAD->NEXT
    8903                        ; STORE32_EAX_into_Address_EBX ; HEAD->NEXT = ROOT
    89D8                        ; COPY_EBX_to_EAX             ; ROOT = HEAD
    89CB                        ; COPY_ECX_to_EBX             ; HEAD = NEXT
    E9 %Reverse_List_Loop       ; JMP32 %Reverse_List_Loop    ; Keep Going

:Reverse_List_Done
    59                          ; POP_ECX                     ; Restore ECX
    5B                          ; POP_EBX                     ; Restore EBX
    C3                          ; RET


;; Identify_Macros function
;; Receives List in EAX
;; Updates the list in place; does not modify registers
;; Uses EBX for DEFINE, ECX for I
:Identify_Macros
    50                          ; PUSH_EAX                    ; Protect EAX
    53                          ; PUSH_EBX                    ; Protect EBX
    51                          ; PUSH_ECX                    ; Protect ECX
    52                          ; PUSH_EDX                    ; Protect EDX
    BB &DEFINE_str              ; LOADI32_EBX &DEFINE_str     ; Setup define string
    89C1                        ; COPY_EAX_to_ECX             ; I = HEAD
:Identify_Macros_Loop
    8B41 10                     ; LOAD32_EAX_from_ECX_Immediate8 !16 ; I->TEXT
    E8 %match                   ; CALL32 %match               ; IF "DEFINE" == I->TEXT
    83F8 00                     ; CMPI8_EAX !0                ; Check if match
    0F85 %Identify_Macros_Next  ; JNE32 %Identify_Macros_Next ; Skip the work

    ;; Deal with MACRO
    B8 01000000                 ; LOADI32_EAX %1              ; Using MACRO
    8941 08                     ; STORE32_EAX_into_Address_ECX_Immediate8 !8 ; I->TYPE = MACRO

    8B01                        ; LOAD32_EAX_from_ECX         ; I->NEXT
    8B40 10                     ; LOAD32_EAX_from_EAX_Immediate8 !16 ; I->NEXT->TEXT
    8941 10                     ; STORE32_EAX_into_Address_ECX_Immediate8 !16 ; I->TEXT = I->NEXT->TEXT

    8B01                        ; LOAD32_EAX_from_ECX         ; I->NEXT
    8B00                        ; LOAD32_EAX_from_EAX         ; I->NEXT->NEXT
    8B40 10                     ; LOAD32_EAX_from_EAX_Immediate8 !16 ; I->NEXT->NEXT->TEXT
    8941 18                     ; STORE32_EAX_into_Address_ECX_Immediate8 !24 ; I->EXPRESSION = I->NEXT->NEXT->TEXT

    8B01                        ; LOAD32_EAX_from_ECX         ; I->NEXT
    8B00                        ; LOAD32_EAX_from_EAX         ; I->NEXT->NEXT
    8B00                        ; LOAD32_EAX_from_EAX         ; I->NEXT->NEXT->NEXT
    8901                        ; STORE32_EAX_into_Address_ECX ; I->NEXT = I->NEXT->NEXT->NEXT

:Identify_Macros_Next
    8B09                        ; LOAD32_ECX_from_ECX         ; I = I->NEXT
    83F9 00                     ; CMPI8_ECX !0                ; Check for NULL
    0F85 %Identify_Macros_Loop  ; JNE32 %Identify_Macros_Loop ; Keep looping otherwise

    5A                          ; POP_EDX                     ; Restore EDX
    59                          ; POP_ECX                     ; Restore ECX
    5B                          ; POP_EBX                     ; Restore EBX
    58                          ; POP_EAX                     ; Restore EAX
    C3                          ; RET

:DEFINE_str
444546494E4500                  ; "DEFINE"


;; match function
;; Receives CHAR* in EAX and CHAR* in EBX
;; Returns 0 (TRUE) or 1 (FALSE) in EAX
:match
    53                          ; PUSH_EBX                    ; Protect EBX
    51                          ; PUSH_ECX                    ; Protect ECX
    52                          ; PUSH_EDX                    ; Protect EDX
    89C1                        ; COPY_EAX_to_ECX             ; S1 in place
    89DA                        ; COPY_EBX_to_EDX             ; S2 in place
:match_Loop
    8A01                        ; LOAD8_al_from_ECX           ; S1[0]
    0FB6C0                      ; MOVZX_al                    ; Make it useful
    8A1A                        ; LOAD8_bl_from_EDX           ; S2[0]
    0FB6DB                      ; MOVZX_bl                    ; Make it useful
    39D8                        ; CMP_EAX_EBX                 ; See if they match
    0F85 %match_False           ; JNE32 %match_False          ; If not

    83C1 01                     ; ADDI8_ECX !1                ; S1 = S1 + 1
    83C2 01                     ; ADDI8_EDX !1                ; S2 = S2 + 1
    83F8 00                     ; CMPI8_EAX !0                ; If reached end of string
    0F84 %match_Done            ; JE32 %match_Done            ; Perfect match
    E9 %match_Loop              ; JMP32 %match_Loop           ; Otherwise keep looping

:match_False
    B8 01000000                 ; LOADI32_EAX %1              ; Return false
:match_Done
    5A                          ; POP_EDX                     ; Restore EDX
    59                          ; POP_ECX                     ; Restore ECX
    5B                          ; POP_EBX                     ; Restore EBX
    C3                          ; RET


;; Line_Macro function
;; Receives List in EAX
;; Updates the list in place; does not modify registers
;; Uses EAX for I, EBX for I->TEXT, ECX for I->EXPRESSION
:Line_Macro
    50                          ; PUSH_EAX                    ; Protect EAX
    53                          ; PUSH_EBX                    ; Protect EBX
    51                          ; PUSH_ECX                    ; Protect ECX
    52                          ; PUSH_EDX                    ; Protect EDX
:Line_Macro_Loop
    8B58 08                     ; LOAD32_EBX_from_EAX_Immediate8 !8 ; I->TYPE
    83FB 01                     ; CMPI8_EBX !1                ; IF MACRO == I->TYPE
    0F85 %Line_Macro_Next       ; JNE32 %Line_Macro_Next      ; Otherwise move on

    ;; Is a macro apply
    8B58 10                     ; LOAD32_EBX_from_EAX_Immediate8 !16 ; I->TEXT
    8B48 18                     ; LOAD32_ECX_from_EAX_Immediate8 !24 ; I->EXPRESSION
    8B00                        ; LOAD32_EAX_from_EAX         ; I->NEXT
    E8 %Set_Expression          ; CALL32 %Set_Expression      ; Apply it
    E9 %Line_Macro_Loop         ; JMP32 %Line_Macro_Loop      ; Move on to next

:Line_Macro_Next
    8B00                        ; LOAD32_EAX_from_EAX         ; I->NEXT
    83F8 00                     ; CMPI8_EAX !0                ; Check for NULL
    0F85 %Line_Macro_Loop       ; JNE32 %Line_Macro_Loop      ; Keep going

    5A                          ; POP_EDX                     ; Restore EDX
    59                          ; POP_ECX                     ; Restore ECX
    5B                          ; POP_EBX                     ; Restore EBX
    58                          ; POP_EAX                     ; Restore EAX
    C3                          ; RET


;; Set_Expression function
;; Receives List in EAX, CHAR* in EBX and CHAR* in ECX
;; Updates the list in place; does not modify registers
;; Uses EBX for C, ECX for EXP and EDX for I
:Set_Expression
    50                          ; PUSH_EAX                    ; Protect EAX
    53                          ; PUSH_EBX                    ; Protect EBX
    51                          ; PUSH_ECX                    ; Protect ECX
    52                          ; PUSH_EDX                    ; Protect EDX
    89C2                        ; COPY_EAX_to_EDX             ; Set I
:Set_Expression_Loop
    8B42 08                     ; LOAD32_EAX_from_EDX_Immediate8 !8 ; I->TYPE
    83F8 01                     ; CMPI8_EAX !1                ; IF MACRO == I->TYPE
    0F84 %Set_Expression_Next   ; JE32 %Set_Expression_Next   ; Ignore and move on

    8B42 10                     ; LOAD32_EAX_from_EDX_Immediate8 !16 ; I->TEXT
    E8 %match                   ; CALL32 %match               ; Check for match
    83F8 00                     ; CMPI8_EAX !0                ; If match
    0F85 %Set_Expression_Next   ; JNE32 %Set_Expression_Next  ; Otherwise next

    ;; We have a non-macro match
    894A 18                     ; STORE32_ECX_into_Address_EDX_Immediate8 !24 ; I->EXPRESSION = EXP

:Set_Expression_Next
    8B12                        ; LOAD32_EDX_from_EDX         ; I = I->NEXT
    83FA 00                     ; CMPI8_EDX !0                ; IF NULL == I
    0F85 %Set_Expression_Loop   ; JNE32 %Set_Expression_Loop  ; Otherwise keep looping

    5A                          ; POP_EDX                     ; Restore EDX
    59                          ; POP_ECX                     ; Restore ECX
    5B                          ; POP_EBX                     ; Restore EBX
    58                          ; POP_EAX                     ; Restore EAX
    C3                          ; RET


;; Process_String function
;; Receives List in EAX
;; Update the list in place; does not modify registers
;; Uses EBX for I->TEXT, ECX for I and EDX for S
:Process_String
    50                          ; PUSH_EAX                    ; Protect EAX
    53                          ; PUSH_EBX                    ; Protect EBX
    51                          ; PUSH_ECX                    ; Protect ECX
    52                          ; PUSH_EDX                    ; Protect EDX
    89C1                        ; COPY_EAX_to_ECX             ; I = HEAD
:Process_String_loop
    8B41 08                     ; LOAD32_EAX_from_ECX_Immediate8 !8 ; I->TYPE
    83F8 02                     ; CMPI8_EAX !2                ; IF STRING == I->TYPE
    0F85 %Process_String_Next   ; JNE32 %Process_String_Next  ; Skip to next

    8B59 10                     ; LOAD32_EBX_from_ECX_Immediate8 !16 ; I->TEXT
    8A03                        ; LOAD8_al_from_EBX           ; I->TEXT[0]
    0FB6C0                      ; MOVZX_al                    ; make it useful
    83F8 27                     ; CMPI8_EAX !39               ; IF '\'' == I->TEXT[0]
    0F85 %Process_String_Raw    ; JNE32 %Process_String_Raw   ; Deal with '\"'

    ;; Deal with '\''
    83C3 01                     ; ADDI8_EBX !1                ; I->TEXT + 1
    8959 18                     ; STORE32_EBX_into_Address_ECX_Immediate8 !24 ; I->EXPRESSION = I->TEXT + 1
    E9 %Process_String_Next     ; JMP32 %Process_String_Next  ; Move on to next

:Process_String_Raw
    89D8                        ; COPY_EBX_to_EAX             ; Get length of I->TEXT
    E8 %string_length           ; CALL32 %string_length       ; Do it
    C1E8 02                     ; SHRI8_EAX !2                ; LENGTH = LENGTH >> 2
    83C0 01                     ; ADDI8_EAX !1                ; LENGTH = LENGTH + 1
    C1E0 03                     ; SHLI8_EAX !3                ; LENGTH = LENGTH << 3
    E8 %malloc                  ; CALL32 %malloc              ; Get string
    89DA                        ; COPY_EBX_to_EDX             ; S = I->TEXT
    83C2 01                     ; ADDI8_EDX !1                ; S = S + 1
    8941 18                     ; STORE32_EAX_into_Address_ECX_Immediate8 !24 ; I->EXPRESSION = hexify
    89C3                        ; COPY_EAX_to_EBX             ; Put hexify buffer in ebx

:Process_String_Raw_Loop
    8A02                        ; LOAD8_al_from_EDX           ; Read 1 chars
    0FB6C0                      ; MOVZX_al                    ; Make it useful
    83C2 01                     ; ADDI8_EDX !1                ; S = S + 1
    3C 00                       ; CMPI8_AL !0                 ; Check for NULL
    9C                          ; PUSH_FLAGS                  ; Protect condition
    E8 %hex8                    ; CALL32 %hex8                ; write them all
    9D                          ; POP_FLAGS                   ; restore condition
    0F85 %Process_String_Raw_Loop ; JNE32 %Process_String_Raw_Loop ; Keep looping

:Process_String_Next
    8B09                        ; LOAD32_ECX_from_ECX         ; I = I->NEXT
    83F9 00                     ; CMPI8_ECX !0                ; IF NULL == I
    0F85 %Process_String_loop   ; JNE32 %Process_String_loop  ; Otherwise keep looping

    5A                          ; POP_EDX                     ; Restore EDX
    59                          ; POP_ECX                     ; Restore ECX
    5B                          ; POP_EBX                     ; Restore EBX
    58                          ; POP_EAX                     ; Restore EAX
    C3                          ; RET


;; string_length function
;; Receives CHAR* in EAX
;; Returns INT in EAX
;; Uses EAX for CH, EBX for S and ECX for INDEX
:string_length
    53                          ; PUSH_EBX                    ; Protect EBX
    51                          ; PUSH_ECX                    ; Protect ECX
    89C3                        ; COPY_EAX_to_EBX             ; Set S
    B9 00000000                 ; LOADI32_ECX %0              ; INDEX = 0
:string_length_loop
    8A040B                      ; LOAD8_al_from_EBX_indexed_ECX ; S[0]
    0FB6C0                      ; MOVZX_al                    ; make it useful
    83F8 00                     ; CMPI8_EAX !0                ; IF NULL == S[0]
    0F84 %string_length_done    ; JE32 %string_length_done    ; Stop

    83C1 01                     ; ADDI8_ECX !1                ; INDEX = INDEX + 1
    E9 %string_length_loop      ; JMP32 %string_length_loop   ; Keep going

:string_length_done
    89C8                        ; COPY_ECX_to_EAX             ; RETURN INDEX
    59                          ; POP_ECX                     ; Restore ECX
    5B                          ; POP_EBX                     ; Restore EBX
    C3                          ; RET


;; Eval_Immediates function
;; Receives List in EAX
;; Updates the list in place; does not modify registers
;; Uses EBX for I->TEXT[0], ECX for I->TEXT[1] and EDX for I
:Eval_Immediates
    50                          ; PUSH_EAX                    ; Protect EAX
    53                          ; PUSH_EBX                    ; Protect EBX
    51                          ; PUSH_ECX                    ; Protect ECX
    52                          ; PUSH_EDX                    ; Protect EDX
    89C2                        ; COPY_EAX_to_EDX             ; I = HEAD
:Eval_Immediates_Loop
    ;; Check for MACRO
    8B42 08                     ; LOAD32_EAX_from_EDX_Immediate8 !8 ; I->TYPE
    83F8 01                     ; CMPI8_EAX !1                ; IF MACRO == I-TYPE
    0F84 %Eval_Immediates_Next  ; JE32 %Eval_Immediates_Next  ; Skip to next

    ;; Check for NULL EXPRESSION
    8B42 18                     ; LOAD32_EAX_from_EDX_Immediate8 !24 ; I->EXPRESSION
    83F8 00                     ; CMPI8_EAX !0                ; IF NULL == I->EXPRESSION
    0F85 %Eval_Immediates_Next  ; JNE32 %Eval_Immediates_Next ; Skip to next

    ;; Check if number
    8B42 10                     ; LOAD32_EAX_from_EDX_Immediate8 !16 ; I->TEXT
    8A18                        ; LOAD8_bl_from_EAX           ; I->TEXT[0]
    0FB6DB                      ; MOVZX_bl                    ; Extend to use
    83C0 01                     ; ADDI8_EAX !1                ; I->TEXT + 1
    8A08                        ; LOAD8_cl_from_EAX           ; I->TEXT[1]
    0FB6C9                      ; MOVZX_cl                    ; Extend to use
    E8 %numerate_string         ; CALL32 %numerate_string     ; Convert string to INT
    83F8 00                     ; CMPI8_EAX !0                ; IF 0 == numerate_number(I->TEXT + 1)
    0F85 %Eval_Immediates_value ; JNE32 %Eval_Immediates_value ; Has a value

    ;; Last chance for Immediate
    83F9 30                     ; CMPI8_ECX !48               ; If '0' == I->TEXT[1]
    0F85 %Eval_Immediates_Next  ; JNE32 %Eval_Immediates_Next ; Skip to next

:Eval_Immediates_value
    E8 %express_number          ; CALL32 %express_number      ; Convert value to hex string
    8942 18                     ; STORE32_EAX_into_Address_EDX_Immediate8 !24 ; I->EXPRESSION = express_number(value, I-TEXT[0])

:Eval_Immediates_Next
    8B12                        ; LOAD32_EDX_from_EDX         ; I = I->NEXT
    83FA 00                     ; CMPI8_EDX !0                ; IF NULL == I
    0F85 %Eval_Immediates_Loop  ; JNE32 %Eval_Immediates_Loop ; Otherwise keep looping

    5A                          ; POP_EDX                     ; Restore EDX
    59                          ; POP_ECX                     ; Restore ECX
    5B                          ; POP_EBX                     ; Restore EBX
    58                          ; POP_EAX                     ; Restore EAX
    C3                          ; RET


;; numerate_string function
;; Receives CHAR* in EAX
;; Returns value of CHAR* in EAX
;; Uses EAX for VALUE, EBX for S, ECX for CH and EDI for NEGATIVE?
:numerate_string
    53                          ; PUSH_EBX                    ; Protect EBX
    51                          ; PUSH_ECX                    ; Protect ECX
    52                          ; PUSH_EDX                    ; Protect EDX
    57                          ; PUSH_EDI                    ; Protect EDI
    89C3                        ; COPY_EAX_to_EBX             ; put S in correct place
    B8 00000000                 ; LOADI32_EAX %0              ; Initialize to Zero
:numerate_string_loop
    8A4B 01                     ; LOAD8_cl_from_EBX_Immediate8 !1 ; S[1]
    0FB6C9                      ; MOVZX_cl                    ; make it useful
    83F9 78                     ; CMPI8_ECX !120              ; IF 'x' == S[1]
    0F84 %numerate_hex          ; JE32 %numerate_hex          ; Deal with hex input

    ;; Assume decimal input
    B9 00000000                 ; LOADI32_ECX %0              ; Assume no negation
    8A0B                        ; LOAD8_cl_from_EBX           ; S[0]
    0FB6C9                      ; MOVZX_cl                    ; make it useful
    83F9 2D                     ; CMPI8_ECX !45               ; IF '-' == S[0]
    0F85 %numerate_decimal      ; JNE32 %numerate_decimal     ; Skip negation

    BF 01000000                 ; LOADI32_EDI %1              ; Set FLAG
    83C3 01                     ; ADDI8_EBX !1                ; S = S + 1

:numerate_decimal
    8A0B                        ; LOAD8_cl_from_EBX           ; S[0]
    0FB6C9                      ; MOVZX_cl                    ; make it useful
    83F9 00                     ; CMPI8_ECX !0                ; IF NULL == S[0]
    0F84 %numerate_decimal_done ; JE32 %numerate_decimal_done ; We are done

    6BC0 0A                     ; IMULI8_EAX !10              ; VALUE = VALUE * 10
    83E9 30                     ; SUBI8_ECX !48               ; CH = CH - '0'
    83F9 09                     ; CMPI8_ECX !9                ; Check for illegal
    0F8F %numerate_string_fail  ; JG32 %numerate_string_fail  ; If CH > '9'
    83F9 00                     ; CMPI8_ECX !0                ; Check for illegal
    0F8C %numerate_string_fail  ; JL32 %numerate_string_fail  ; IF CH < 0
    01C8                        ; ADD_ECX_to_EAX              ; VALUE = VALUE + CH
    83C3 01                     ; ADDI8_EBX !1                ; S = S + 1
    E9 %numerate_decimal        ; JMP32 %numerate_decimal     ; Keep looping

:numerate_decimal_done
    83FF 01                     ; CMPI8_EDI !1                ; Check if need to negate
    0F85 %numerate_string_done  ; JNE32 %numerate_string_done ; Nope

    6BC0 FF                     ; IMULI8_EAX !-1              ; VALUE = VALUE * -1
    E9 %numerate_string_done    ; JMP32 %numerate_string_done ; Done

:numerate_hex
    83C3 02                     ; ADDI8_EBX !2                ; S = S + 2
:numerate_hex_loop
    8A0B                        ; LOAD8_cl_from_EBX           ; S[0]
    0FB6C9                      ; MOVZX_cl                    ; make it useful
    83F9 00                     ; CMPI8_ECX !0                ; IF NULL == S[0]
    0F84 %numerate_string_done  ; JE32 %numerate_string_done  ; We are done

    C1E0 04                     ; SHLI8_EAX !4                ; VALUE = VALUE << 4
    83E9 30                     ; SUBI8_ECX !48               ; CH = CH - '0'
    83F9 0A                     ; CMPI8_ECX !10               ; IF 10 >= CH
    0F8C %numerate_hex_digit    ; JL32 %numerate_hex_digit    ; NO
    83E9 07                     ; SUBI8_ECX !7                ; Push A-F into range
:numerate_hex_digit
    83F9 0F                     ; CMPI8_ECX !15               ; Check for illegal
    0F8F %numerate_string_fail  ; JG32 %numerate_string_fail  ; If CH > 'F'
    83F9 00                     ; CMPI8_ECX !0                ; Check for illegal
    0F8C %numerate_string_fail  ; JL32 %numerate_string_fail  ; IF CH < 0
    01C8                        ; ADD_ECX_to_EAX              ; VALUE = VALUE + CH
    83C3 01                     ; ADDI8_EBX !1                ; S = S + 1
    E9 %numerate_hex_loop       ; JMP32 %numerate_hex_loop    ; Keep looping

:numerate_string_fail
    B8 00000000                 ; LOADI32_EAX %0              ; return ZERO

:numerate_string_done
    5F                          ; POP_EDI                     ; Restore EDI
    5A                          ; POP_EDX                     ; Restore EDX
    59                          ; POP_ECX                     ; Restore ECX
    5B                          ; POP_EBX                     ; Restore EBX
    C3                          ; RET


;; express_number function
;; Receives INT in EAX and CHAR in EBX
;; Allocates a string and expresses the value in hex
;; Returns string in EAX
;; Uses EAX for VALUE, EBX for S and ECX for CH
:express_number
    53                          ; PUSH_EBX                    ; Protect EBX
    51                          ; PUSH_ECX                    ; Protect ECX
    52                          ; PUSH_EDX                    ; Protect EDX
    89D9                        ; COPY_EBX_to_ECX             ; Put CH in right place
    89C3                        ; COPY_EAX_to_EBX             ; Protect VALUE
    83F9 25                     ; CMPI8_ECX !37               ; IF '%' == CH
    0F85 %express_number2       ; JNE32 %express_number2      ; Otherwise try @

    B8 09000000                 ; LOADI32_EAX %9              ; We need 3bytes
    E8 %malloc                  ; CALL32 %malloc              ; Get S pointer
    93                          ; XCHG_EAX_EBX                ; Put S and VALUE in place
    53                          ; PUSH_EBX                    ; Protect S
    E8 %hex32l                  ; CALL32 %hex32l              ; Store 32bits
    E9 %express_number_done     ; JMP32 %express_number_done  ; done

:express_number2
    83F9 40                     ; CMPI8_ECX !64               ; IF '@' == CH
    0F85 %express_number1       ; JNE32 %express_number1      ; Othrewise try !

    B8 05000000                 ; LOADI32_EAX %5              ; We need 3bytes
    E8 %malloc                  ; CALL32 %malloc              ; Get S pointer
    93                          ; XCHG_EAX_EBX                ; Put S and VALUE in place
    53                          ; PUSH_EBX                    ; Protect S
    E8 %hex16l                  ; CALL32 %hex16l              ; Store 16bits
    E9 %express_number_done     ; JMP32 %express_number_done  ; done

:express_number1
    B8 03000000                 ; LOADI32_EAX %3              ; We need 3bytes
    E8 %malloc                  ; CALL32 %malloc              ; Get S pointer
    93                          ; XCHG_EAX_EBX                ; Put S and VALUE in place
    53                          ; PUSH_EBX                    ; Protect S
    E8 %hex8                    ; CALL32 %hex8                ; Store 8bit

:express_number_done
    58                          ; POP_EAX                     ; Restore S
    5A                          ; POP_EDX                     ; Restore EDX
    59                          ; POP_ECX                     ; Restore ECX
    5B                          ; POP_EBX                     ; Restore EBX
    C3                          ; RET


;; HEX to ascii routine
;; Receives INT in EAX and CHAR* in EBX
;; Stores ascii of INT in CHAR*
;; Returns only modifying EAX
:hex64l
    50                          ; PUSH_EAX                    ; Protect top 32
    E8 %hex32l                  ; CALL32 %hex32l              ; Store it
    58                          ; POP_EAX                     ; do top 32
    C1E8 20                     ; SHRI8_EAX !32               ; do bottom 32 first
:hex32l
    50                          ; PUSH_EAX                    ; Protect top 16
    E8 %hex16l                  ; CALL32 %hex16l              ; Store it
    58                          ; POP_EAX                     ; do top 16
    C1E8 10                     ; SHRI8_EAX !16               ; do bottom 16 first
:hex16l
    50                          ; PUSH_EAX                    ; Protect top byte
    E8 %hex8                    ; CALL32 %hex8                ; Store it
    58                          ; POP_EAX                     ; do high byte
    C1E8 08                     ; SHRI8_EAX !8                ; do bottom byte first
:hex8
    50                          ; PUSH_EAX                    ; Protect bottom nibble
    C1E8 04                     ; SHRI8_EAX !4                ; do high nibble first
    E8 %hex4                    ; CALL32 %hex4                ; Store it
    58                          ; POP_EAX                     ; do low nibble
:hex4
    83E0 0F                     ; ANDI8_EAX !0xF              ; isolate nibble
    04 30                       ; ADDI8_AL !48                ; convert to ascii
    3C 39                       ; CMPI8_AL !57                ; valid digit?
    0F86 %hex1                  ; JBE32 %hex1                 ; yes
    04 07                       ; ADDI8_AL !7                 ; use alpha range
:hex1
    8803                        ; STORE8_al_into_Address_EBX  ; store result
    83C3 01                     ; ADDI8_EBX !1                ; next position
    C3                          ; RET


;; Preserve_Other function
;; Receives List in EAX
;; Updates the list in place; does not modify registers
;; Uses EAX for I, EBX for I->TEXT
:Preserve_Other
    50                          ; PUSH_EAX                    ; Protect EAX
    53                          ; PUSH_EBX                    ; Protect EBX
    51                          ; PUSH_ECX                    ; Protect ECX
    52                          ; PUSH_EDX                    ; Protect EDX
:Preserve_Other_Loop
    8B58 18                     ; LOAD32_EBX_from_EAX_Immediate8 !24 ; I->EXPRESSION
    83FB 00                     ; CMPI8_EBX !0                ; IF NULL == I->EXPRESSION
    0F85 %Preserve_Other_Next   ; JNE32 %Preserve_Other_Next  ; Otherwise next

    ;; Needs preserving
    8B58 10                     ; LOAD32_EBX_from_EAX_Immediate8 !16 ; I->TEXT
    8958 18                     ; STORE32_EBX_into_Address_EAX_Immediate8 !24 ; I->EXPRESSION = I->TEXT

:Preserve_Other_Next
    8B00                        ; LOAD32_EAX_from_EAX         ; I = I->NEXT
    83F8 00                     ; CMPI8_EAX !0                ; IF NULL == I
    0F85 %Preserve_Other_Loop   ; JNE32 %Preserve_Other_Loop  ; Otherwise keep looping

    5A                          ; POP_EDX                     ; Restore EDX
    59                          ; POP_ECX                     ; Restore ECX
    5B                          ; POP_EBX                     ; Restore EBX
    58                          ; POP_EAX                     ; Restore EAX
    C3                          ; RET


;; Print_Hex function
;; Receives list in EAX
;; walks the list and prints the I->EXPRESSION for all nodes followed by newline
;; Uses EBX for I
:Print_Hex
    53                          ; PUSH_EBX                    ; Protect EBX
    51                          ; PUSH_ECX                    ; Protect ECX
    89EB                        ; COPY_EBP_to_EBX             ; I = Head
:Print_Hex_Loop
    8B43 08                     ; LOAD32_EAX_from_EBX_Immediate8 !8 ; I->TYPE
    83F8 01                     ; CMPI8_EAX !1                ; IF MACRO == I->TYPE
    0F84 %Print_Hex_Next        ; JE32 %Print_Hex_Next        ; Skip

    8B43 18                     ; LOAD32_EAX_from_EBX_Immediate8 !24 ; Using EXPRESSION
    E8 %File_Print              ; CALL32 %File_Print          ; Print it
    B8 0A000000                 ; LOADI32_EAX %10             ; NEWLINE
    E8 %fputc                   ; CALL32 %fputc               ; Append it

:Print_Hex_Next
    8B1B                        ; LOAD32_EBX_from_EBX         ; Iterate to next Token
    83FB 00                     ; CMPI8_EBX !0                ; Check for NULL
    0F85 %Print_Hex_Loop        ; JNE32 %Print_Hex_Loop       ; Otherwise keep looping

    59                          ; POP_ECX                     ; Restore ECX
    5B                          ; POP_EBX                     ; Restore EBX
    C3                          ; RET


;; File_Print function
;; Receives CHAR* in EAX
;; calls fputc for every non-null char
:File_Print
    53                          ; PUSH_EBX                    ; Protect EBX
    51                          ; PUSH_ECX                    ; Protect ECX
    89C3                        ; COPY_EAX_to_EBX             ; Protect S
    83F8 00                     ; CMPI8_EAX !0                ; Protect against nulls
    0F84 %File_Print_Done       ; JE32 %File_Print_Done       ; Simply don't try to print them
:File_Print_Loop
    8A03                        ; LOAD8_al_from_EBX           ; Read byte
    0FB6C0                      ; MOVZX_al                    ; zero extend
    83F8 00                     ; CMPI8_EAX !0                ; Check for NULL
    0F84 %File_Print_Done       ; JE32 %File_Print_Done       ; Stop at NULL

    E8 %fputc                   ; CALL32 %fputc               ; write it
    83C3 01                     ; ADDI8_EBX !1                ; S = S + 1
    E9 %File_Print_Loop         ; JMP32 %File_Print_Loop      ; Keep going

:File_Print_Done
    59                          ; POP_ECX                     ; Restore ECX
    5B                          ; POP_EBX                     ; Restore EBX
    C3                          ; RET


;; fputc function
;; receives CHAR in EAX and FILE* in [Output]
;; writes char and returns
:fputc
    52                          ; PUSH_EDX                    ; Protect EDX
    51                          ; PUSH_ECX                    ; protect ECX
    53                          ; PUSH_EBX                    ; protect EBX
    50                          ; PUSH_EAX                    ; We are writing eax
    8D0C24                      ; LEA32_ECX_from_esp          ; Get stack address
    8B1D &Output                ; LOAD32_Absolute32_ebx &Output ; Write to target file
    B8 04000000                 ; LOADI32_EAX %4              ; the syscall number for write
    BA 01000000                 ; LOADI32_EDX %1              ; set the size of chars we want
    CD80                        ; INT_80                      ; call the Kernel
    58                          ; POP_EAX                     ; Restore stack
    5B                          ; POP_EBX                     ; Restore EBX
    59                          ; POP_ECX                     ; Restore ECX
    5A                          ; POP_EDX                     ; Restore EDX
    C3                          ; RET

:Output
    00000000                    ; NULL
:Input
    00000000                    ; NULL
:ELF_end

https://github.com/oriansj/stage0-posix-x86/blob/main/cc_x86.M1

File: ../git/live-bootstrap/sysa/stage0-posix/src/x86/cc_x86.M1 used in: Step 10
;; Copyright (C) 2017 Jeremiah Orians
;; This file is part of stage0.
;;
;; stage0 is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;;
;; stage0 is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with stage0.  If not, see <http://www.gnu.org/licenses/>.

DEFINE ADDI8_EAX 83C0
DEFINE ADDI8_EBX 83C3
DEFINE ADDI8_ECX 83C1
DEFINE ADDI8_EDX 83C2
DEFINE ADDI8_ESI 83C6
DEFINE ADD_eax_into_ebx 01C3
DEFINE ADD_ebx_into_eax 01D8
DEFINE ADD_ecx_into_eax 01C8
DEFINE ADD_edi_into_ecx 01F9
DEFINE AND_EAX_EBX 21D8
DEFINE ANDI32_EAX 25
DEFINE CALL_EAX FFD0
DEFINE CALL32 E8
DEFINE CMPI8_EAX 83F8
DEFINE CMPI8_EBP 83fd
DEFINE CMPI8_EBX 83FB
DEFINE CMPI8_ECX 83F9
DEFINE CMPI8_EDX 83FA
DEFINE CMPI8_ESI 83FE
DEFINE CMP_EAX_EBX 39D8
DEFINE CMP_EAX_ECX 39C8
DEFINE CMP_EBX_ECX 39D9
DEFINE CMP_ECX_EBX 39CB
DEFINE CMP_EDI_ESI 39FE
DEFINE CMP_EBX_EDX 39D3
DEFINE COPY_EAX_to_EBP 89C5
DEFINE COPY_EAX_to_EBX 89C3
DEFINE COPY_EAX_to_ECX 89C1
DEFINE COPY_EAX_to_EDX 89C2
DEFINE COPY_EAX_to_ESI 89C6
DEFINE COPY_EBP_to_EAX 89E8
DEFINE COPY_EBX_to_EAX 89D8
DEFINE COPY_EBX_to_ECX 89D9
DEFINE COPY_EBX_to_EDX 89DA
DEFINE COPY_ECX_to_EAX 89C8
DEFINE COPY_ECX_to_EBX 89CB
DEFINE COPY_EDI_to_ESI 89FE
DEFINE COPY_EDX_to_EAX 89D0
DEFINE COPY_EDX_to_EBP 89D5
DEFINE COPY_EDX_to_EBX 89D3
DEFINE COPY_ESI_to_EAX 89F0
DEFINE COPY_ESI_to_EDI 89F7
DEFINE IDIV_EBX F7FB
DEFINE IMUL_EAX_by_EBX 0FAFC3
DEFINE IMULI8_EAX 6BC0
DEFINE IMULI8_EBP 6BED
DEFINE INT_80 CD80
DEFINE JBE8 76
DEFINE JE32 0F84
DEFINE JG32 0F8F
DEFINE JG8 7F
DEFINE JL32 0F8C
DEFINE JLE32 0F8E
DEFINE JMP32 E9
DEFINE JNE32 0F85
DEFINE LEA32_ECX_from_esp 8D0C24
DEFINE LOAD32_Absolute32_eax A1
DEFINE LOAD32_Absolute32_ebx 8B1D
DEFINE LOAD32_Absolute32_ecx 8B0D
DEFINE LOAD32_EAX_from_EAX 8B00
DEFINE LOAD32_EAX_from_EAX_Immediate8 8B40
DEFINE LOAD32_EAX_from_EBP_Immediate8 8B45
DEFINE LOAD32_EAX_from_EBX 8B03
DEFINE LOAD32_EAX_from_EBX_Immediate8 8B43
DEFINE LOAD32_EAX_from_ECX_Immediate8 8B41
DEFINE LOAD32_EAX_from_EDX_Immediate8 8B42
DEFINE LOAD32_EBP_from_EBP 8B6D00
DEFINE LOAD32_EBX_from_EAX_Immediate8 8B58
DEFINE LOAD32_EBX_from_EBX 8B1B
DEFINE LOAD32_EBX_from_EBX_Immediate8 8B5B
DEFINE LOAD32_EBX_from_ECX_Immediate8 8B59
DEFINE LOAD32_ECX_from_EAX_Immediate8 8B48
DEFINE LOAD32_ECX_from_EBX 8B0B
DEFINE LOAD32_ECX_from_ECX 8B09
DEFINE LOAD32_ECX_from_ECX_Immediate8 8B49
DEFINE LOAD32_ECX_from_EDX_Immediate8 8B4A
DEFINE LOAD32_EDI_from_EDX_Immediate8 8B7A
DEFINE LOAD32_EDX_from_EDX_Immediate8 8B52
DEFINE LOAD8_al_from_EAX 8A00
DEFINE LOAD8_al_from_EBX 8A03
DEFINE LOAD8_al_from_ECX 8A01
DEFINE LOAD8_al_from_EDX 8A02
DEFINE LOAD8_bl_from_EBX 8A1B
DEFINE LOAD8_bl_from_ECX 8A19
DEFINE LOAD8_bl_from_EDX 8A1A
DEFINE LOAD8_cl_from_EBX 8A0B
DEFINE LOAD8_cl_from_EBX_Immediate8 8A4B
DEFINE LOADI32_EAX B8
DEFINE LOADI32_EBX BB
DEFINE LOADI32_ECX B9
DEFINE LOADI32_EDI BF
DEFINE LOADI32_EDX BA
DEFINE LOADI32_ESI BE
DEFINE MOVZX_al 0FB6C0
DEFINE MOVZX_bl 0FB6DB
DEFINE MOVZX_cl 0FB6C9
DEFINE NULL 00000000
DEFINE POP_EAX 58
DEFINE POP_EBP 5D
DEFINE POP_EBX 5B
DEFINE POP_ECX 59
DEFINE POP_EDI 5F
DEFINE POP_EDX 5A
DEFINE POP_ESI 5E
DEFINE PUSH_EAX 50
DEFINE PUSH_EBP 55
DEFINE PUSH_EBX 53
DEFINE PUSH_ECX 51
DEFINE PUSH_EDI 57
DEFINE PUSH_EDX 52
DEFINE PUSH_ESI 56
DEFINE RETURN C3
DEFINE SALI8_EAX C1E0
DEFINE SHRI8_EAX C1E8
DEFINE SHRI8_EBX C1EB
DEFINE STORE32_Absolute32_eax A3
DEFINE STORE32_Absolute32_ebx 891D
DEFINE STORE32_Absolute32_ecx 890D
DEFINE STORE32_Absolute32_edx 8915
DEFINE STORE32_EAX_into_EBP_Immediate8 8945
DEFINE STORE32_EAX_into_EBX 8903
DEFINE STORE32_EAX_into_ECX_Immediate8 8941
DEFINE STORE32_EAX_into_EDX 8902
DEFINE STORE32_EAX_into_EDX_Immediate8 8942
DEFINE STORE32_EBP_into_EDX_Immediate8 896A
DEFINE STORE32_EBX_into_EAX 8918
DEFINE STORE32_EBX_into_EAX_Immediate8 8958
DEFINE STORE32_EBX_into_EDX_Immediate8 895A
DEFINE STORE32_ECX_into_EAX 8908
DEFINE STORE32_ECX_into_EAX_Immediate8 8948
DEFINE STORE32_ECX_into_EDX_Immediate8 894A
DEFINE STORE32_EDX_into_EAX_Immediate8 8950
DEFINE STORE32_EDX_into_EBP_Immediate8 8955
DEFINE STORE32_ESI_into_EBP_Immedate8 8975
DEFINE STORE32_ESI_into_EDX_Immedate8 8972
DEFINE STORE8_al_into_Address_EBX 8803
DEFINE STORE8_al_into_Address_ECX 8801
DEFINE STORE8_al_into_Address_ESI 8806
DEFINE STORE8_bl_into_Address_ECX 8819
DEFINE SUBI8_EAX 83E8
DEFINE SUBI8_ECX 83E9
DEFINE SUBI8_ESI 83EE
DEFINE SWAP_EAX_EBX 93


    ;; Register usage:
    ;; EAX => Temps

    ;; Struct TYPE format: (size 28)
    ;; NEXT => 0
    ;; SIZE => 4
    ;; OFFSET => 8
    ;; INDIRECT => 12
    ;; MEMBERS => 16
    ;; TYPE => 20
    ;; NAME => 24

    ;; Struct TOKEN_LIST format: (size 20)
    ;; NEXT => 0
    ;; LOCALS/PREV => 4
    ;; S => 8
    ;; TYPE => 12
    ;; ARGS/DEPTH => 16

; Where the ELF Header is going to hit
; Simply jump to _start
; Our main function
:_start
    POP_EAX                                     ; Get the number of arguments
    POP_EBX                                     ; Get the program name
    POP_EBX                                     ; Get the actual input name
    LOADI32_ECX %0                              ; prepare read_only
    LOADI32_EAX %5                              ; the syscall number for open()
    INT_80                                      ; Now open that damn file
    STORE32_Absolute32_eax &Input_file          ; Preserve the file pointer we were given

    POP_EBX                                     ; Get the actual output name
    LOADI32_ECX %577                            ; Prepare file as O_WRONLY|O_CREAT|O_TRUNC
    LOADI32_EDX %384                            ; Prepare file as RW for owner only (600 in octal)
    LOADI32_EAX %5                              ; the syscall number for open()
    INT_80                                      ; Now open that damn file
    CMPI8_EAX !0                                ; Check for missing output
    JG32 %_start_out                            ; Have real input
    LOADI32_EAX %1                              ; Use stdout

:_start_out
    STORE32_Absolute32_eax &Output_file         ; Preserve the file pointer we were given

    LOADI32_EAX %45                             ; the Syscall # for SYS_BRK
    LOADI32_EBX %0                              ; Get current brk
    INT_80                                      ; Let the kernel do the work
    STORE32_Absolute32_eax &MALLOC              ; Set our malloc pointer
    LOADI32_EAX %0                              ; HEAD = NULL
    CALL32 %read_all_tokens                     ; Read all tokens
    CALL32 %Reverse_List                        ; Reverse order
;   CALL32 %debug_list                          ; Try to figure out what is wrong
    STORE32_Absolute32_eax &global_token        ; Set global_token
    CALL32 %program                             ; Convert into program
    LOADI32_EAX &header_string1                 ; Our header string
    CALL32 %File_Print                          ; Print it
    LOAD32_Absolute32_eax &output_list          ; Our output_list
    CALL32 %recursive_output                    ; Print core program
;   LOADI32_EAX &header_string2                 ; Our Enable debug
;   CALL32 %File_Print                          ; Print it
    LOADI32_EAX &header_string3                 ; Our second label
    CALL32 %File_Print                          ; Print it
    LOAD32_Absolute32_eax &globals_list         ; Our globals
    CALL32 %recursive_output                    ; Get them
    LOADI32_EAX &header_string4                 ; Our final header
    CALL32 %File_Print                          ; Print it
    LOAD32_Absolute32_eax &strings_list         ; Our strings
    CALL32 %recursive_output                    ; Get them
    LOADI32_EAX &header_string5                 ; Make this a bare assembly
    CALL32 %File_Print                          ; Print it

:Done
    ; program completed Successfully
    LOADI32_EBX %0                              ; All is well
    LOADI32_EAX %1                              ; put the exit syscall number in eax
    INT_80                                      ; Call it a good day

:header_string1  "
# Core program
"
:header_string2  "
:ELF_data
"
:header_string3  "
# Program global variables
"
:header_string4  "
# Program strings
"
:header_string5  "
:ELF_end
"


;; read_all_tokens function
;; Receives Token_List* in EAX
;; Tokenizes all input and returns updated list in EAX
;; Returns TOKEN in EAX
;; Uses EAX for C
:read_all_tokens
    STORE32_Absolute32_eax &Token
    CALL32 %fgetc
:read_all_tokens_loop
    CMPI8_EAX !-4                               ; Check for EOF
    JE32 %read_all_tokens_done                  ; Stop if found
    CALL32 %get_token                           ; Read all tokens
    JMP32 %read_all_tokens_loop                 ; Loop
:read_all_tokens_done
    LOAD32_Absolute32_eax &Token
    RETURN


;; get_token function
;; Receives INT in EAX
;; Makes a list of TOKEN_LIST
;; C and STRING_INDEX are stored in memory, ECX is used for S and EDX is used for current
;; Returns C in EAX
:get_token
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    PUSH_EDX                                    ; Protect EDX

    STORE32_Absolute32_eax &C                   ; Set C

    LOADI32_EAX %20                             ; Malloc CURRENT
    CALL32 %malloc                              ; Get Pointer
    COPY_EAX_to_EDX                             ; Set CURRENT

    LOADI32_EAX %256                            ; Malloc the string
    CALL32 %malloc                              ; Get pointer to S
    COPY_EAX_to_ECX                             ; Set S
    STORE32_ECX_into_EDX_Immediate8 !8          ; CURRENT->S = S
:reset
    STORE32_Absolute32_ecx &string_index        ; S[0]
    LOAD32_Absolute32_eax &C                    ; Using C

    CALL32 %clear_white_space                   ; Clear WhiteSpace
    STORE32_Absolute32_eax &C                   ; Set C

    CMPI8_EAX !-4                               ; Check for EOF
    JE32 %get_token_abort                       ; if EOF abort

    CMPI8_EAX !35                               ; Check for '#'
    JNE32 %get_token_alpha                      ; Nope

    ;; Deal with # line comments
    CALL32 %purge_macro                         ; Let it handle it
    STORE32_Absolute32_eax &C                   ; Set C
    JMP32 %reset                                ; Try again

:get_token_alpha
    LOAD32_Absolute32_eax &C                    ; Send C
    LOADI32_EBX &alphas                         ; Get alphanumerics
    CALL32 %In_Set                              ; See if in set
    CMPI8_EAX !1                                ; IF TRUE
    JNE32 %get_token_symbol                     ; Otherwise

    ;; Store keywords
    LOAD32_Absolute32_eax &C                    ; Send C
    CALL32 %preserve_keyword                    ; Store
    STORE32_Absolute32_eax &C                   ; Set C
    JMP32 %get_token_done                       ; Be done with this token

:get_token_symbol
    LOAD32_Absolute32_eax &C                    ; Send C
    LOADI32_EBX &symbols                        ; Get symbols
    CALL32 %In_Set                              ; See if in set
    CMPI8_EAX !1                                ; IF TRUE
    JNE32 %get_token_strings                    ; Otherwise

    ;; Store symbols
    LOAD32_Absolute32_eax &C                    ; Send C
    CALL32 %preserve_symbol                     ; Store
    STORE32_Absolute32_eax &C                   ; Set C
    JMP32 %get_token_done                       ; Be done with this token

:get_token_strings
    LOAD32_Absolute32_eax &C                    ; Send C
    LOADI32_EBX &strings                        ; Get strings
    CALL32 %In_Set                              ; See if in set
    CMPI8_EAX !1                                ; IF TRUE
    JNE32 %get_token_comment                    ; Otherwise

    ;; Store String
    LOAD32_Absolute32_eax &C                    ; Send C
    CALL32 %consume_word                        ; Store
    STORE32_Absolute32_eax &C                   ; Set C
    JMP32 %get_token_done                       ; Be done with this token

:get_token_comment
    LOAD32_Absolute32_eax &C                    ; Send C
    CMPI8_EAX !47                               ; IF '/' == C
    JNE32 %get_token_else                       ; Otherwise

    CALL32 %consume_byte                        ; Hope it just is '/'
    STORE32_Absolute32_eax &C                   ; Set C

    CMPI8_EAX !42                               ; IF '*' we have '/*'
    JNE32 %get_token_comment_line               ; Check for '//'

    ;; Deal with /* block comments */
    CALL32 %fgetc                               ; get next C
    STORE32_Absolute32_eax &C                   ; Set C
:get_token_comment_block_outer
    LOAD32_Absolute32_eax &C                    ; Using C
    CMPI8_EAX !47                               ; IF '/' != C
    JE32 %get_token_comment_block_done          ; be done

:get_token_comment_block_inner
    LOAD32_Absolute32_eax &C                    ; Using C
    CMPI8_EAX !42                               ; IF '*' != C
    JE32 %get_token_comment_block_iter          ; jump over

    ;; Deal with inner loop
    CALL32 %fgetc                               ; get next C
    STORE32_Absolute32_eax &C                   ; Set C
    JMP32 %get_token_comment_block_inner        ; keep going

:get_token_comment_block_iter
    CALL32 %fgetc                               ; get next C
    STORE32_Absolute32_eax &C                   ; Set C
    JMP32 %get_token_comment_block_outer

:get_token_comment_block_done
    CALL32 %fgetc                               ; get next C
    STORE32_Absolute32_eax &C                   ; Set C
    JMP32 %reset                                ; throw away, try again

:get_token_comment_line
    CMPI8_EAX !47                               ; IF '/' we have //
    JNE32 %get_token_done                       ; keep if just '/'

    ;; Deal with // line comment
    CALL32 %fgetc                               ; drop to match
    STORE32_Absolute32_eax &C                   ; Set C
    JMP32 %reset                                ; throw away, try again

:get_token_else
    LOAD32_Absolute32_eax &C                    ; Send C
    CALL32 %consume_byte
    STORE32_Absolute32_eax &C                   ; Set C

:get_token_done
    LOAD32_Absolute32_eax &Token                ; TOKEN
    STORE32_EAX_into_EDX_Immediate8 !4          ; CURRENT->PREV = TOKEN
    STORE32_EAX_into_EDX                        ; CURRENT->NEXT = TOKEN
    STORE32_Absolute32_edx &Token               ; TOKEN = CURRENT

:get_token_abort
    POP_EDX                                     ; Restore EDX
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    LOAD32_Absolute32_eax &C                    ; Return C
    RETURN


;; Malloc isn't actually required if the program being built fits in the initial memory
;; However, it doesn't take much to add it.
;; Requires [MALLOC] to be initialized and EAX to have the number of desired bytes
:malloc
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    PUSH_EDX                                    ; Protect EDX
    LOAD32_Absolute32_ebx &MALLOC               ; Using the current pointer
    ADD_eax_into_ebx                            ; Request the number of desired bytes
    LOADI32_EAX %45                             ; the Syscall # for SYS_BRK
    INT_80                                      ; call the Kernel
    LOAD32_Absolute32_eax &MALLOC               ; Return pointer
    STORE32_Absolute32_ebx &MALLOC              ; Update pointer
    POP_EDX                                     ; Restore EDX
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN


;; clear_white_space function
;; Receives INT C in EAX
;; Returns first non-whitespace char in EAX
:clear_white_space
    CMPI8_EAX !32                               ; Check for ' '
    JE32 %clear_white_space_wipe                ; wipe it out

    CMPI8_EAX !10                               ; Check for '\n'
    JE32 %clear_white_space_wipe                ; wipe it output

    CMPI8_EAX !9                                ; Check for '\t'
    JNE32 %clear_white_space_done               ; looks like non-whitespace

:clear_white_space_wipe
    CALL32 %fgetc                               ; Read a new byte
    CMPI8_EAX !-4                               ; Check for EOF
    JE32 %clear_white_space_done                ; Short circuit
    JMP32 %clear_white_space                    ; iterate

:clear_white_space_done
    RETURN


;; In_Set function
;; Receives Char C in EAX and CHAR* in EBX
;; Returns 1 if true, zero if false in EAX
:In_Set
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
:In_Set_loop
    LOAD8_cl_from_EBX                           ; Read char
    MOVZX_cl                                    ; Zero extend it

    CMP_EAX_ECX                                 ; See if they match
    JE32 %In_Set_True                           ; return true

    CMPI8_ECX !0                                ; Check for NULL
    JE32 %In_Set_False                          ; return false

    ADDI8_EBX !1                                ; s = s + 1
    JMP32 %In_Set_loop                          ; Keep looping

:In_Set_True
    LOADI32_EAX %1                              ; Set True
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

:In_Set_False
    LOADI32_EAX %0                              ; Set FALSE
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

:alphas  "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"
:symbols  "<=>|&!-"
:strings  '22 27 00'


;; purge_macro function
;; Receives CH in EAX
;; Reads chars until Line feed is read
;; returns line feed
:purge_macro
    CALL32 %fgetc                               ; read next char
    CMPI8_EAX !10                               ; Check for '\n'
    JNE32 %purge_macro                          ; Keep going
    RETURN


;; preserve_keyword function
;; Receives INT C in EAX
;; collects all chars in keyword
;; Returns C in EAX
;; Uses ECX for INT C
:preserve_keyword
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    COPY_EAX_to_ECX                             ; Setup C
    LOADI32_EBX &alphas                         ; Concerning ourselves with "abc.."
:preserve_keyword_loop
    CALL32 %In_Set                              ; Check if alphanumerics
    CMPI8_EAX !1                                ; IF TRUE
    JNE32 %preserve_keyword_label               ; Otherwise check for label

    COPY_ECX_to_EAX                             ; Pass C
    CALL32 %consume_byte                        ; consume that byte
    COPY_EAX_to_ECX                             ; Update C
    JMP32 %preserve_keyword_loop                ; keep looping

:preserve_keyword_label
    COPY_ECX_to_EAX                             ; Fix return
    CMPI8_EAX !58                               ; Check for ':'
    JNE32 %preserve_keyword_done                ; be done

    ;; Fix our goto label
    CALL32 %fixup_label                         ; Fix the label
    LOADI32_EAX %32                             ; Return Whitespace

:preserve_keyword_done
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN


;; preserve_symbol function
;; Receives INT C in EAX
;; collects all chars in symbol
;; Returns C in EAX
;; Uses ECX for INT C
:preserve_symbol
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    COPY_EAX_to_ECX                             ; Setup C
    LOADI32_EBX &symbols                        ; Concerning ourselves with "<=>.."
:preserve_symbol_loop
    CALL32 %In_Set                              ; Check if symbol
    CMPI8_EAX !1                                ; IF TRUE
    JNE32 %preserve_symbol_done                 ; Otherwise be done

    COPY_ECX_to_EAX                             ; Pass C
    CALL32 %consume_byte                        ; consume that byte
    COPY_EAX_to_ECX                             ; Update C
    JMP32 %preserve_symbol_loop                 ; keep looping

:preserve_symbol_done
    COPY_ECX_to_EAX                             ; Fix return
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN


;; consume_word function
;; receives INT C in EAX
;; returns INT C in EAX
;; Uses EAX for C, EBX for FREQ and ECX for ESCAPE
:consume_word
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    COPY_EAX_to_EBX                             ; FREQ = C
    LOADI32_ECX %0                              ; ESCAPE = FALSE
:consume_word_loop
    CMPI8_ECX !0                                ; IF !ESCAPE
    JNE32 %consume_word_escape                  ; Enable escape

    CMPI8_EAX !92                               ; if '\\'
    JNE32 %consume_word_iter                    ; keep state

    LOADI32_ECX %1                              ; ESCAPE = TRUE
    JMP32 %consume_word_iter                    ; keep going

:consume_word_escape
    LOADI32_ECX %0                              ; ESCAPE = FALSE

:consume_word_iter
    CALL32 %consume_byte                        ; read next char

    CMPI8_ECX !0                                ; IF ESCAPE
    JNE32 %consume_word_loop                    ; keep looping

    CMP_EAX_EBX                                 ; IF C != FREQ
    JNE32 %consume_word_loop                    ; keep going

    CALL32 %fgetc                               ; return next char
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN


;; consume_byte function
;; Receives INT C in EAX
;; Inserts C into string S, updates String S
;; Returns Next char in EAX
:consume_byte
    PUSH_EBX                                    ; Protect EBX
    LOAD32_Absolute32_ebx &string_index         ; S[0]
    STORE8_al_into_Address_EBX                  ; S[0] = C
    ADDI8_EBX !1                                ; S = S + 1
    STORE32_Absolute32_ebx &string_index        ; Update S
    CALL32 %fgetc
    POP_EBX                                     ; Restore EBX
    RETURN


;; fixup_label function
;; Receives S in ECX
;; prepends ':' to string and returns registers unchanged
;; Uses EAX for HOLD, EBX for PREV and ECX for S[0]
:fixup_label
    PUSH_EAX                                    ; Protect EAX
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    LOADI32_EAX %58                             ; HOLD = ':'
    LOAD32_ECX_from_EDX_Immediate8 !8           ; HOLD_STRING[0]
:fixup_label_loop
    COPY_EAX_to_EBX                             ; PREV = HOLD
    LOAD8_al_from_ECX                           ; HOLD = HOLD_STRING[I]
    MOVZX_al                                    ; make useful
    STORE8_bl_into_Address_ECX                  ; HOLD_STRING[I] = PREV
    ADDI8_ECX !1                                ; I = I + 1
    CMPI8_EAX !0                                ; IF NULL == HOLD
    JNE32 %fixup_label_loop                     ; Keep looping

    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    POP_EAX                                     ; Restore EAX
    RETURN


;; fgetc function
;; Loads FILE* from [INPUT_FILE]
;; Returns -4 (EOF) or char in EAX
:fgetc
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    PUSH_EDX                                    ; Protect EDX
    LOADI32_EAX %-4                             ; Put EOF in eax
    PUSH_EAX                                    ; Assume bad (If nothing read, value will remain EOF)
    LEA32_ECX_from_esp                          ; Get stack address
    LOAD32_Absolute32_ebx &Input_file           ; Where are we reading from
    LOADI32_EAX %3                              ; the syscall number for read
    LOADI32_EDX %1                              ; set the size of chars we want
    INT_80                                      ; call the Kernel
    POP_EAX                                     ; Get either char or EOF
    CMPI8_EAX !-4                               ; Check for EOF
    JE32 %fgetc_done                            ; Return as is
    MOVZX_al                                    ; Make it useful
:fgetc_done
    POP_EDX                                     ; Restore EDX
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN


;; Reverse_List function
;; Receives List in EAX
;; Returns the list reversed in EAX
:Reverse_List
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    COPY_EAX_to_EBX                             ; Set HEAD
    LOADI32_EAX %0                              ; ROOT = NULL
:Reverse_List_Loop
    CMPI8_EBX !0                                ; WHILE HEAD != NULL
    JE32 %Reverse_List_Done                     ; Stop otherwise

    LOAD32_ECX_from_EBX                         ; NEXT = HEAD->NEXT
    STORE32_EAX_into_EBX                        ; HEAD->NEXT = ROOT
    COPY_EBX_to_EAX                             ; ROOT = HEAD
    COPY_ECX_to_EBX                             ; HEAD = NEXT
    JMP32 %Reverse_List_Loop                    ; Keep Going

:Reverse_List_Done
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN


;; recursive_output function
;; Receives list in EAX
;; walks the list and prints the I->S for all nodes backwards
;; Uses EBX for I
:recursive_output
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    CMPI8_EAX !0                                ; Check for NULL
    JE32 %recursive_output_done                 ; Skip the work
    COPY_EAX_to_EBX                             ; I = Head

    LOAD32_EAX_from_EBX                         ; Iterate to next Token
    CALL32 %recursive_output                    ; Recurse

    LOAD32_EAX_from_EBX_Immediate8 !8           ; Using S
    CALL32 %File_Print                          ; Print it

:recursive_output_done
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN


;; File_Print function
;; Receives CHAR* in EAX
;; calls fputc for every non-null char
:File_Print
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    COPY_EAX_to_EBX                             ; Protect S
    CMPI8_EAX !0                                ; Protect against nulls
    JE32 %File_Print_Done                       ; Simply don't try to print them
:File_Print_Loop
    LOAD8_al_from_EBX                           ; Read byte
    MOVZX_al                                    ; zero extend
    CMPI8_EAX !0                                ; Check for NULL
    JE32 %File_Print_Done                       ; Stop at NULL

    CALL32 %fputc                               ; write it
    ADDI8_EBX !1                                ; S = S + 1
    JMP32 %File_Print_Loop                      ; Keep going

:File_Print_Done
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN


;; fputc function
;; receives CHAR in EAX and load FILE* from [OUTPUT_FILE]
;; writes char and returns
:fputc
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    PUSH_EDX                                    ; Protect EDX
    PUSH_EAX                                    ; We are writing eax
    LEA32_ECX_from_esp                          ; Get stack address
    LOAD32_Absolute32_ebx &Output_file          ; Write to target file
    LOADI32_EAX %4                              ; the syscall number for write
    LOADI32_EDX %1                              ; set the size of chars we want
    INT_80                                      ; call the Kernel
    POP_EAX                                     ; Restore stack
    POP_EDX                                     ; Restore EDX
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN


;; program function
;; receives nothing, returns nothing
;; Uses EAX for type_size
:program
    ;; The binary initialized the globals to null, so we can skip those steps
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX

:new_type
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    CMPI8_EAX !0                                ; Check if NULL
    JE32 %program_done                          ; Be done if null

    LOAD32_EBX_from_EAX_Immediate8 !8           ; GLOBAL_TOKEN->S
    LOADI32_EAX &constant                       ; "CONSTANT"
    CALL32 %match                               ; IF GLOBAL_TOKEN->S == "CONSTANT"
    CMPI8_EAX !0                                ; If true
    JNE32 %program_else                         ; Looks like not a constant

    ;; Deal with minimal constant case
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->next
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->next

    LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
    LOADI32_EBX %0                              ; NULL
    LOAD32_Absolute32_ecx &global_constant_list ; global_constant_list
    CALL32 %sym_declare                         ; Declare that constant
    STORE32_Absolute32_eax &global_constant_list ; global_constant_list = sym_declare(global_token->s, NULL, global_constant_list);

    LOAD32_Absolute32_ebx &global_token         ; Using global_token
    LOAD32_EBX_from_EBX                         ; global_token->next
    STORE32_EBX_into_EAX_Immediate8 !16         ; global_constant_list->arguments = global_token->next

    LOAD32_EBX_from_EBX                         ; global_token->next->next
    STORE32_Absolute32_ebx &global_token        ; global_token = global_token->next->next
    JMP32 %new_type                             ; go around again

:program_else
    CALL32 %type_name                           ; Figure out the type_size
    CMPI8_EAX !0                                ; IF NULL == type_size
    JE32 %new_type                              ; it was a new type

    ;; Add to global symbol table
    COPY_EAX_to_EBX                             ; put type_size in the right spot
    LOAD32_Absolute32_eax &global_token         ; Using global token
    LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
    LOAD32_Absolute32_ecx &global_symbol_list   ; Using global_symbol_list
    CALL32 %sym_declare                         ; Declare symbol
    STORE32_Absolute32_eax &global_symbol_list  ; global_symbol_list = sym_declare(global_token->s, type_size, global_symbol_list);
    LOAD32_Absolute32_ebx &global_token         ; Using global token
    LOAD32_EBX_from_EBX                         ; global_token->next
    STORE32_Absolute32_ebx &global_token        ; global_token = global_token->next

    LOAD32_Absolute32_ebx &global_token         ; Using global token
    LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
    LOADI32_EAX &semicolon                      ; ";"
    CALL32 %match                               ; if(match(";", global_token->s))
    CMPI8_EAX !0                                ; If true
    JNE32 %program_function                     ; looks like not a match

    ;; Deal with the global variable
    LOAD32_Absolute32_ebx &globals_list         ; Using globals_list
    LOADI32_EAX &program_string_0               ; ":GLOBAL_"
    CALL32 %emit                                ; Emit it
    COPY_EAX_to_EBX                             ; update globals_list

    LOAD32_Absolute32_eax &global_token         ; Using global token
    LOAD32_EAX_from_EAX_Immediate8 !4           ; global token->prev
    LOAD32_EAX_from_EAX_Immediate8 !8           ; global token->prev->s
    CALL32 %emit                                ; Emit it

    COPY_EAX_to_EBX                             ; update globals_list
    LOADI32_EAX &program_string_1               ; "\nNULL\n"
    CALL32 %emit                                ; Emit it
    STORE32_Absolute32_eax &globals_list        ; update globals_list

    LOAD32_Absolute32_eax &global_token         ; Using global token
    LOAD32_EAX_from_EAX                         ; global_token->next
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->next
    JMP32 %new_type                             ; go around again

:program_function
    LOAD32_Absolute32_ebx &global_token         ; Using global token
    LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
    LOADI32_EAX &open_paren                     ; "("
    CALL32 %match                               ; if(match(";", global_token->s))
    CMPI8_EAX !0                                ; If true
    JNE32 %program_error                        ; Otherwise deal with error case

    ;; Deal with function definition
    CALL32 %declare_function                    ; Lets get the parsing rolling
    JMP32 %new_type                             ; Keep looping through functions

:program_error
    ;; Deal with the case of something we don't support
    ;; NOT IMPLEMENTED

:program_done
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

;; Strings needed by the program function
:program_string_0  ":GLOBAL_"
:program_string_1  "
NULL
"


;; declare_function function
;; Receives nothing and returns nothing
;; Sets current function and adds it to the global function list
:declare_function
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    LOADI32_EAX %0                              ; Using NULL
    STORE32_Absolute32_eax &current_count       ; current_count = 0

    LOAD32_Absolute32_eax &global_token         ; Using global token
    LOAD32_EAX_from_EAX_Immediate8 !4           ; global token->prev
    LOAD32_EAX_from_EAX_Immediate8 !8           ; global token->prev->s
    LOADI32_EBX %0                              ; NULL
    LOAD32_Absolute32_ecx &global_function_list ; global_function_list
    CALL32 %sym_declare                         ; sym_declare(global_token->prev->s, NULL, global_function_list);
    STORE32_Absolute32_eax &function            ; function = sym_declare(global_token->prev->s, NULL, global_function_list);
    STORE32_Absolute32_eax &global_function_list ; global_function_list = function

    CALL32 %collect_arguments                   ; collect all of the function arguments

    LOAD32_Absolute32_eax &global_token         ; Using global token
    LOAD32_EAX_from_EAX_Immediate8 !8           ; global token->s
    LOADI32_EBX &semicolon                      ; ";"
    CALL32 %match                               ; IF global token->s == ";"
    CMPI8_EAX !0                                ; If true
    JNE32 %declare_function_full                ; It was a prototype

    ;; Deal with prototypes
    LOAD32_Absolute32_eax &global_token         ; Using global token
    LOAD32_EAX_from_EAX                         ; global token->next
    STORE32_Absolute32_eax &global_token        ; global token = global token->next
    JMP32 %declare_function_done                ; Move on

:declare_function_full
    ;; Deal with full function definitions
    LOADI32_EAX &declare_function_string_0      ; "# Defining function "
    CALL32 %emit_out                            ; emit it

    LOAD32_Absolute32_eax &function             ; function
    LOAD32_EAX_from_EAX_Immediate8 !8           ; function->s
    CALL32 %emit_out                            ; emit it

    LOADI32_EAX &declare_function_string_1      ; "\n:FUNCTION_"
    CALL32 %emit_out                            ; emit it

    LOAD32_Absolute32_eax &function             ; function
    LOAD32_EAX_from_EAX_Immediate8 !8           ; function->s
    CALL32 %emit_out                            ; emit it

    LOADI32_EAX &declare_function_string_3      ; "\n"
    CALL32 %emit_out                            ; emit it

    CALL32 %statement                           ; Recursively get the function pieces

    LOAD32_Absolute32_eax &output_list          ; output
    LOAD32_EAX_from_EAX_Immediate8 !8           ; output->s
    LOADI32_EBX &declare_function_string_2      ; "ret\n"
    CALL32 %match                               ; IF output->s == "ret\n"
    CMPI8_EAX !0                                ; If true we can skip adding it
    JE32 %declare_function_done                 ; otherwise we need to add it

    ;; Add the return to the end of a function lacking a return;
    LOADI32_EAX &declare_function_string_2      ; "ret\n"
    CALL32 %emit_out                            ; emit it

:declare_function_done
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

:declare_function_string_0  "# Defining function "
:declare_function_string_1  "
:FUNCTION_"
:declare_function_string_2  "ret
"
:declare_function_string_3  "
"


;; collect_arguments function
;; Receives nothing
;; Returns Nothing
;; Adds arguments to the function definition
;; holds struct type* type_size in ECX, then replace with struct token_list* a in ECX when type_size is used
:collect_arguments
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->next
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->next
:collect_arguments_loop
    LOAD32_Absolute32_ebx &global_token         ; Using global_token
    LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
    LOADI32_EAX &close_paren                    ; ")"
    CALL32 %match                               ; IF global_token->S == ")"
    CMPI8_EAX !0                                ; we reached the end
    JE32 %collect_arguments_done                ; be done

    ;; deal with the case of there are arguments
    CALL32 %type_name                           ; Get the type
    COPY_EAX_to_ECX                             ; put type_size safely out of the way

    LOAD32_Absolute32_ebx &global_token         ; Using global_token
    LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
    LOADI32_EAX &close_paren                    ; ")"
    CALL32 %match                               ; IF global_token->S == ")"
    CMPI8_EAX !0                                ; is a foo(int, char,void) case
    JE32 %collect_arguments_common              ; deal with commas

    ;; Trying second else
    LOAD32_Absolute32_ebx &global_token         ; Using global_token
    LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
    LOADI32_EAX &comma                          ; ","
    CALL32 %match                               ; IF global_token->S == ","
    CMPI8_EAX !0                                ; then deal with the common
    JE32 %collect_arguments_common              ; case of commas between arguments

    ;; deal with foo(int a, char b)
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
    COPY_ECX_to_EBX                             ; put type_size in the right place
    LOAD32_Absolute32_ecx &function             ; Using function
    LOAD32_ECX_from_ECX_Immediate8 !16          ; function->args
    CALL32 %sym_declare                         ; sym_declare(global_token->s, type_size, function->arguments);
    COPY_EAX_to_ECX                             ; put a in a safe place

    LOAD32_Absolute32_eax &function             ; Using function
    LOAD32_EAX_from_EAX_Immediate8 !16          ; function->args
    CMPI8_EAX !0                                ; IF function->args == NULL
    JNE32 %collect_arguments_another            ; otherwise it isn't the first

    ;; Deal with the case of first argument in the function
    LOADI32_EAX %-4                             ; -4
    STORE32_EAX_into_ECX_Immediate8 !16         ; a->depth = -4
    JMP32 %collect_arguments_next               ; get to next

:collect_arguments_another
    ;; deal with the case of non-first arguments
    LOAD32_Absolute32_eax &function             ; Using function
    LOAD32_EAX_from_EAX_Immediate8 !16          ; function->args
    LOAD32_EAX_from_EAX_Immediate8 !16          ; function->args->depth
    SUBI8_EAX !4                                ; function->args->depth - 4
    STORE32_EAX_into_ECX_Immediate8 !16         ; a->depth = function->args->depth - 4

:collect_arguments_next
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->next
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->next

    LOAD32_Absolute32_eax &function             ; Using function
    STORE32_ECX_into_EAX_Immediate8 !16         ; function->args = a

:collect_arguments_common
    LOAD32_Absolute32_ebx &global_token         ; Using global_token
    LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
    LOADI32_EAX &comma                          ; ","
    CALL32 %match                               ; IF global_token->S == ","
    CMPI8_EAX !0                                ; then deal with the comma
    JNE32 %collect_arguments_loop               ; otherwise loop

    ;; keep foo(bar(), 1) expressions working
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->next
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->next
    JMP32 %collect_arguments_loop               ; keep going

:collect_arguments_done
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->next
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->next
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN


;; statement function
;; Receives nothing
;; Returns nothing
;; Walks down global_token recursively to collect the contents of the function
:statement
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX

    LOAD32_Absolute32_ebx &global_token         ; Using global_token
    LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
    LOADI32_EAX &open_curly_brace               ; "{"
    CALL32 %match                               ; IF global_token->S == "{"
    JNE32 %statement_label                      ; otherwise try label

    ;; deal with { statement }
    CALL32 %recursive_statement                 ; Statements inside of statements for days
    JMP32 %statement_done                       ; Be done

:statement_label
    LOAD8_al_from_EBX                           ; global_token->S[0]
    MOVZX_al                                    ; make it useful
    CMPI8_EAX !58                               ; IF global_token->S == ':'
    JNE32 %statement_local                      ; otherwise try locals

    ;; deal with labels
    COPY_EBX_to_EAX                             ; put global_token->S in the right spot
    CALL32 %emit_out                            ; emit it

    LOADI32_EAX &statement_string_0             ; Using "\t#C goto label\n"
    CALL32 %emit_out                            ; emit it

    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->next
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->next
    JMP32 %statement_done                       ; be done

:statement_local
    COPY_EBX_to_EAX                             ; put global_token->S in the right place
    LOADI32_EBX &prim_types                     ; pointer to primative types
    CALL32 %lookup_type                         ; See if found
    CMPI8_EAX !0                                ; IF NULL == lookup_type(global_token->S, prim_types)
    JNE32 %statement_local_success              ; Sweet a new local

    ;; Second chance
    LOAD32_Absolute32_ebx &global_token         ; Using global_token
    LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
    LOADI32_EAX &struct                         ; "struct"
    CALL32 %match                               ; IF global_token->S == "struct"
    CMPI8_EAX !0                                ; then we are a local
    JNE32 %statement_if                         ; otherwise try IF

:statement_local_success
    CALL32 %collect_local                       ; Grab those locals
    JMP32 %statement_done                       ; be done

:statement_if
    LOADI32_EAX &if_string                      ; Using "if"
    CALL32 %match                               ; IF global_token->S == "if"
    CMPI8_EAX !0                                ; then we have an if statement
    JNE32 %statement_do                         ; otherwise try DO

    ;; Deal with IF statement
    CALL32 %process_if                          ; DO IT
    JMP32 %statement_done                       ; be done

:statement_do
    LOADI32_EAX &do_string                      ; Using "do"
    CALL32 %match                               ; IF global_token->S == "do"
    CMPI8_EAX !0                                ; then we have a do statement
    JNE32 %statement_while                      ; otherwise try WHILE

    ;; Deal with DO statement
    CALL32 %process_do                          ; DO IT
    JMP32 %statement_done                       ; be done

:statement_while
    LOADI32_EAX &while_string                   ; Using "while"
    CALL32 %match                               ; IF global_token->S == "while"
    CMPI8_EAX !0                                ; then we have a while statement
    JNE32 %statement_for                        ; otherwise try FOR

    ;; Deal with WHILE statement
    CALL32 %process_while                       ; DO IT
    JMP32 %statement_done                       ; be done

:statement_for
    LOADI32_EAX &for_string                     ; Using "for"
    CALL32 %match                               ; IF global_token->S == "for"
    CMPI8_EAX !0                                ; then we have a for statement
    JNE32 %statement_asm                        ; otherwise try ASM

    ;; Deal with FOR statement
    CALL32 %process_for                         ; DO IT
    JMP32 %statement_done                       ; be done

:statement_asm
    LOADI32_EAX &asm_string                     ; Using "asm"
    CALL32 %match                               ; IF global_token->S == "asm"
    CMPI8_EAX !0                                ; then we have an asm statement
    JNE32 %statement_goto                       ; otherwise try GOTO

    ;; Deal with ASM statement
    CALL32 %process_asm                         ; Hit it
    JMP32 %statement_done                       ; be done

:statement_goto
    LOADI32_EAX &goto_string                    ; Using "goto"
    CALL32 %match                               ; IF global_token->S == "goto"
    CMPI8_EAX !0                                ; then we have a goto statement
    JNE32 %statement_return                     ; Otherwise try RETURN

    ;; Deal with GOTO statement
    LOADI32_EAX &statement_string_1             ; Using "jmp %"
    CALL32 %emit_out                            ; emit it

    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->next
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->next

    LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
    CALL32 %emit_out                            ; emit it

    LOADI32_EAX &statement_string_2             ; Using "\n"
    CALL32 %emit_out                            ; emit it

    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->next
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->next

    LOADI32_EAX &statement_string_4             ; Using "ERROR in statement\nMissing ;\n"
    LOADI32_EBX &semicolon                      ; Using ";"
    CALL32 %require_match                       ; Make sure it has the required
    JMP32 %statement_done                       ; Be done

:statement_return
    LOADI32_EAX &return_string                  ; Using "return"
    CALL32 %match                               ; IF global_token->S == "return"
    CMPI8_EAX !0                                ; then we have a return statement
    JNE32 %statement_break                      ; Otherwise try BREAK

    ;; Deal with RETURN Statement
    CALL32 %return_result                       ; Return anything they want
    JMP32 %statement_done                       ; be done

:statement_break
    LOADI32_EAX &break_string                   ; Using "break"
    CALL32 %match                               ; IF global_token->S == "break"
    CMPI8_EAX !0                                ; then we have a break statement
    JNE32 %statement_continue                   ; Otherwise try CONTINUE

    ;; Deal with BREAK statement
    CALL32 %process_break                       ; Lets do some damage
    JMP32 %statement_done                       ; be done

:statement_continue
    LOADI32_EAX &continue_string                ; Using "continue"
    CALL32 %match                               ; IF global_token->S == "continue"
    CMPI8_EAX !0                                ; then we have a continue statement
    JNE32 %statement_else                       ; Otherwise we are punting to an expression

    ;; Deal with CONTINUE statement
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->next
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->next

    LOADI32_EAX &statement_string_3             ; Using "\n#continue statement\n"
    CALL32 %emit_out                            ; emit it

    LOADI32_EAX &statement_string_4             ; Using "ERROR in statement\nMissing ;\n"
    LOADI32_EBX &semicolon                      ; Using ";"
    CALL32 %require_match                       ; Don't forget the ";"
    JMP32 %statement_done                       ; Be done

:statement_else
    CALL32 %expression                          ; Collect expression
    LOADI32_EAX &statement_string_4             ; Using "ERROR in statement\nMissing ;\n"
    LOADI32_EBX &semicolon                      ; Using ";"
    CALL32 %require_match                       ; make sure we have it

:statement_done
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

:statement_string_0  "  #C goto label
"
:statement_string_1  "jmp %"
:statement_string_2  "
"
:statement_string_3  "
#continue statement
"
:statement_string_4  "ERROR in statement
Missing ;
"


;; recursive_statement function
;; Receives nothing
;; Returns nothing
;; Walks the global_token list to build the contents of statements
;; Uses struct token_list* frame in ECX
:recursive_statement
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX

    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->next
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->next

    LOAD32_Absolute32_ecx &function             ; Using function
    LOAD32_ECX_from_ECX_Immediate8 !4           ; frame = function->locals

:recursive_statement_loop
    LOAD32_Absolute32_ebx &global_token         ; Using global_token
    LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
    LOADI32_EAX &close_curly_brace              ; Using "}"
    CALL32 %match                               ; IF global_token->S == "}"
    CMPI8_EAX !0                                ; Then we are done recursing
    JE32 %recursive_statement_cleanup           ; and then we clean up

    ;; Deal with the recursive calls
    CALL32 %statement                           ; Deal with another statement
    JMP32 %recursive_statement_loop             ; loop some more

:recursive_statement_cleanup
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->next
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->next

    LOADI32_EAX &recursive_statement_string_0   ; Using "ret\n"
    LOAD32_Absolute32_ebx &output_list          ; Using output
    LOAD32_EBX_from_EBX_Immediate8 !8           ; output->S
    CALL32 %match                               ; IF output->S == "ret\n"
    CMPI8_EAX !0                                ; Then we can skip the clean up
    JE32 %recursive_statement_done              ; and be done

    ;; Deal with cleanup
    LOAD32_Absolute32_ebx &function             ; Using function
    LOAD32_EBX_from_EBX_Immediate8 !4           ; i = function->locals
    LOADI32_EAX &recursive_statement_string_1   ; Using "pop_ebx\t# _recursive_statement_locals\n"

:recursive_statement_locals
    CMP_ECX_EBX                                 ; IF frame != i
    JE32 %recursive_statement_done              ; Otherwise be done

    ;; Lets emit
    CALL32 %emit_out                            ; emit it
    LOAD32_EBX_from_EBX                         ; i = i->next
    JMP32 %recursive_statement_locals           ; keep going

:recursive_statement_done
    LOAD32_Absolute32_eax &function             ; Using function
    STORE32_ECX_into_EAX_Immediate8 !4          ; function->locals = frame
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

:recursive_statement_string_0  "ret
"
:recursive_statement_string_1  "pop_ebx # _recursive_statement_locals
"


;; return_result function
;; Receives nothing
;; Returns nothing
;; Cleans up function and generates return
;; Also handles returning expressions
:return_result
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->next
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->next

    LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
    LOAD8_al_from_EAX                           ; global_token->S[0]
    MOVZX_al                                    ; make it useful
    CMPI8_EAX !59                               ; If global_token->S[0] == ';'
    JE32 %return_result_cleanup                 ; Go straight to cleanup

    CALL32 %expression                          ; get the expression we are returning

:return_result_cleanup
    LOADI32_EAX &return_result_string_0         ; Using "ERROR in return_result\nMISSING ;\n"
    LOADI32_EBX &semicolon                      ; Using ";"
    CALL32 %require_match                       ; Make sure we have it

    LOAD32_Absolute32_ebx &function             ; Using function
    LOAD32_EBX_from_EBX_Immediate8 !4           ; function->locals
    LOADI32_EAX &return_result_string_1         ; Using "pop_ebx\t# _return_result_locals\n"
:return_result_locals
    CMPI8_EBX !0                                ; IF NULL == i
    JE32 %return_result_done                    ; Be done

    CALL32 %emit_out                            ; Emit out pop
    LOAD32_EBX_from_EBX                         ; i = i->NEXT
    JMP32 %return_result_locals                 ; Keep going

:return_result_done
    LOADI32_EAX &return_result_string_2         ; Using "ret\n"
    CALL32 %emit_out                            ; Emit it
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

:return_result_string_0  "ERROR in return_result
MISSING ;
"
:return_result_string_1  "pop_ebx   # _return_result_locals
"
:return_result_string_2  "ret
"


;; collect_local function
;; Receives nothing
;; Returns nothing
;; Walks global_token list to create function locals
;; Uses ECX for struct token_list* A
:collect_local
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    CALL32 %type_name                           ; Get the local's type

    COPY_EAX_to_EBX                             ; Put struct type* type_size in the right place
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
    LOAD32_Absolute32_ecx &function             ; Using function
    LOAD32_ECX_from_ECX_Immediate8 !4           ; function->locals
    CALL32 %sym_declare                         ; Declare it
    COPY_EAX_to_ECX                             ; put it away safely

    ;; Try for main
    LOADI32_EAX &main_string                    ; Using "main"
    LOAD32_Absolute32_ebx &function             ; Using function
    LOAD32_EBX_from_EBX_Immediate8 !8           ; function->S
    CALL32 %match                               ; IF match("main", function->s)
    CMPI8_EAX !0                                ; possible
    JNE32 %collect_local_fresh                  ; try to see if fresh function

    ;; Ok we are in main, now to see if main is fresh
    LOAD32_Absolute32_eax &function             ; Using function
    LOAD32_EAX_from_EAX_Immediate8 !4           ; function->locals
    CMPI8_EAX !0                                ; IF NULL == function->locals
    JNE32 %collect_local_fresh                  ; try to see if fresh function

    ;; Sweet we are in a fresh main
    LOADI32_EAX %-20                            ; We start at -20
    STORE32_EAX_into_ECX_Immediate8 !16         ; a->DEPTH = -20
    JMP32 %collect_local_common                 ; Go to the commons

:collect_local_fresh
    LOAD32_Absolute32_eax &function             ; Using function
    LOAD32_EAX_from_EAX_Immediate8 !16          ; function->args
    CMPI8_EAX !0                                ; IF NULL == function->args
    JNE32 %collect_local_first                  ; Otherwise see if first

    LOAD32_Absolute32_eax &function             ; Using function
    LOAD32_EAX_from_EAX_Immediate8 !4           ; function->locals
    CMPI8_EAX !0                                ; IF NULL == function->locals
    JNE32 %collect_local_first                  ; Otherwise try first

    ;; Sweet we are in a fresh function
    LOADI32_EAX %-8                             ; We start at -8
    STORE32_EAX_into_ECX_Immediate8 !16         ; a->DEPTH = -8
    JMP32 %collect_local_common                 ; Go to the commons

:collect_local_first
    LOAD32_Absolute32_eax &function             ; Using function
    LOAD32_EAX_from_EAX_Immediate8 !4           ; function->locals
    CMPI8_EAX !0                                ; IF NULL == function->locals
    JNE32 %collect_local_else                   ; Looks like we are just another local

    ;; Ok we are the first local
    LOAD32_Absolute32_eax &function             ; Using function
    LOAD32_EAX_from_EAX_Immediate8 !16          ; function->args
    LOAD32_EAX_from_EAX_Immediate8 !16          ; function->args->depth
    SUBI8_EAX !8                                ; function->arguments->depth - 8
    STORE32_EAX_into_ECX_Immediate8 !16         ; a->DEPTH = function->arguments->depth - 8
    JMP32 %collect_local_common                 ; Go to the commons

:collect_local_else
    ;; Always the last to know
    LOAD32_Absolute32_eax &function             ; Using function
    LOAD32_EAX_from_EAX_Immediate8 !4           ; function->locals
    LOAD32_EAX_from_EAX_Immediate8 !16          ; function->locals->depth
    SUBI8_EAX !4                                ; function->locals->depth - 4
    STORE32_EAX_into_ECX_Immediate8 !16         ; a->DEPTH = function->locals->depth - 4

:collect_local_common
    LOAD32_Absolute32_eax &function             ; Using function

    STORE32_ECX_into_EAX_Immediate8 !4          ; function->locals = a
    LOAD32_ECX_from_ECX_Immediate8 !8           ; a->S

    LOADI32_EAX &collect_local_string_0         ; Using "# Defining local "
    CALL32 %emit_out                            ; emit it

    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
    CALL32 %emit_out                            ; emit it

    LOADI32_EAX &collect_local_string_1         ; Using "\n"
    CALL32 %emit_out                            ; emit it

    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->NEXT
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT

    LOAD32_EBX_from_EAX_Immediate8 !8           ; global_token->S
    LOADI32_EAX &equal                          ; Using "="
    CALL32 %match                               ; IF match("=", global_token->s)
    CMPI8_EAX !0                                ; Deal with assignment
    JNE32 %collect_local_done                   ; Otherwise finish it

    ;; Deal with assignment
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->NEXT
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT

    CALL32 %expression                          ; Recurse

:collect_local_done
    LOADI32_EAX &collect_local_string_2         ; Using "ERROR in collect_local\nMissing ;\n"
    LOADI32_EBX &semicolon                      ; Using ";"
    CALL32 %require_match                       ; Make sure we have it

    LOADI32_EAX &collect_local_string_3         ; Using "push_eax\t#"
    CALL32 %emit_out                            ; emit it

    COPY_ECX_to_EAX                             ; put A->S where it belongs
    CALL32 %emit_out                            ; emit it

    LOADI32_EAX &collect_local_string_1         ; Using "\n"
    CALL32 %emit_out                            ; emit it

    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

:collect_local_string_0  "# Defining local "
:collect_local_string_1  "
"
:collect_local_string_2  "ERROR in collect_local
Missing ;
"
:collect_local_string_3  "push_eax  #"


;; process_asm function
;; Receives nothing
;; Returns nothing
;; Simply inlines the asm statements
;; Uses EBX for global_token temp storage
:process_asm
    PUSH_EBX                                    ; Protect EBX
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->NEXT
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT

    LOADI32_EAX &process_asm_string_0           ; Using "ERROR in process_asm\nMISSING (\n"
    LOADI32_EBX &open_paren                     ; Using "("
    CALL32 %require_match                       ; Make sure we have it

    LOAD32_Absolute32_ebx &global_token         ; Using global_token
:process_asm_iter
    LOAD32_EAX_from_EBX_Immediate8 !8           ; global_token->S
    LOAD8_al_from_EAX                           ; global_token->S[0]
    MOVZX_al                                    ; Make it useful
    CMPI8_EAX !34                               ; IF global_token->S[0] == '\"'
    JNE32 %process_asm_done                     ; Otherwise be done

    LOAD32_EAX_from_EBX_Immediate8 !8           ; global_token->S
    ADDI8_EAX !1                                ; global_token->S + 1
    CALL32 %emit_out                            ; Emit it

    LOADI32_EAX &process_asm_string_1           ; Using "\n"
    CALL32 %emit_out                            ; Emit it

    LOAD32_EBX_from_EBX                         ; global_token->NEXT
    STORE32_Absolute32_ebx &global_token        ; global_token = global_token->NEXT
    JMP32 %process_asm_iter                     ; keep going

:process_asm_done
    LOADI32_EAX &process_asm_string_2           ; Using "ERROR in process_asm\nMISSING )\n"
    LOADI32_EBX &close_paren                    ; Using ")"
    CALL32 %require_match                       ; Make sure we have it

    LOADI32_EAX &process_asm_string_3           ; Using "ERROR in process_asm\nMISSING ;\n"
    LOADI32_EBX &semicolon                      ; Using ";"
    CALL32 %require_match                       ; Make sure we have it

    POP_EBX                                     ; Restore EBX
    RETURN

:process_asm_string_0  "ERROR in process_asm
MISSING (
"
:process_asm_string_1  "
"
:process_asm_string_2  "ERROR in process_asm
MISSING )
"
:process_asm_string_3  "ERROR in process_asm
MISSING ;
"


;; process_if function
;; Receives nothing
;; Returns Nothing
;; Increments current_count recurses into expression + statement
;; Uses ECX for char* NUMBER_STRING
:process_if
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    LOAD32_Absolute32_eax &current_count        ; Using current count
    COPY_EAX_to_EBX                             ; Preparing for update
    ADDI8_EBX !1                                ; current_count + 1
    STORE32_Absolute32_ebx &current_count       ; current_count = current_count + 1
    CALL32 %numerate_number                     ; convert to string
    COPY_EAX_to_ECX                             ; put NUMBER_STRING in place

    LOADI32_EAX &process_if_string_0            ; Using "# IF_"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &function             ; Using function
    LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
    COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
    CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)

    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->NEXT
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT

    LOADI32_EAX &process_if_string_1            ; Using "ERROR in process_if\nMISSING (\n"
    LOADI32_EBX &open_paren                     ; Using "("
    CALL32 %require_match                       ; Make sure we have it

    CALL32 %expression                          ; Recurse to get the IF(...) part

    LOADI32_EAX &process_if_string_2            ; Using "test_eax,eax\nje %ELSE_"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &function             ; Using function
    LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
    COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
    CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)

    LOADI32_EAX &process_if_string_3            ; Using "ERROR in process_if\nMISSING )\n"
    LOADI32_EBX &close_paren                    ; Using ")"
    CALL32 %require_match                       ; Make sure we have it

    CALL32 %statement                           ; Recursive to get the IF(){...} part

    LOADI32_EAX &process_if_string_4            ; Using "jmp %_END_IF_"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &function             ; Using function
    LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
    COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
    CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)

    LOADI32_EAX &process_if_string_5            ; Using ":ELSE_"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &function             ; Using function
    LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
    CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)

    LOAD32_Absolute32_ebx &global_token         ; Using global_token
    LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
    LOADI32_EAX &else_string                    ; Using "else"
    CALL32 %match                               ; IF global_token->S == "else"
    CMPI8_EAX !0                                ; Then we need to collect the else too
    JNE32 %process_if_done                      ; Otherwise finish up

    ;; deal with else statement
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->NEXT
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT

    CALL32 %statement                           ; Recurse to get the ELSE {...} part

:process_if_done
    LOADI32_EAX &process_if_string_6            ; Using ":_END_IF_"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &function             ; Using function
    LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
    COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
    CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)

    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

:process_if_string_0  "# IF_"
:process_if_string_1  "ERROR in process_if
MISSING (
"
:process_if_string_2  "test_eax,eax
je %ELSE_"
:process_if_string_3  "ERROR in process_if
MISSING )
"
:process_if_string_4  "jmp %_END_IF_"
:process_if_string_5  ":ELSE_"
:process_if_string_6  ":_END_IF_"


;; save_break_frame microfunction
;; Overwrites EAX and EBX
;; Saves break frame on stack
;; Returns to caller
:save_break_frame
    POP_EBX                                     ; Save return Address
    LOAD32_Absolute32_eax &break_frame          ; Get break_frame
    PUSH_EAX                                    ; Store as nested_locals
    LOAD32_Absolute32_eax &break_target_head    ; Get break_target_head
    PUSH_EAX                                    ; Store as nested_break_head
    LOAD32_Absolute32_eax &break_target_func    ; Get break_target_func
    PUSH_EAX                                    ; Store as nested_break_func
    LOAD32_Absolute32_eax &break_target_num     ; Get break_target_num
    PUSH_EAX                                    ; Store as nested_break_num
    PUSH_EBX                                    ; Put return back in place
    RETURN                                      ; Return to caller


;; restore_break_frame microfunction
;; Overwrites EAX and EBX
;; Restores break frame from stack
;; Returns to caller
:restore_break_frame
    POP_EBX                                     ; Save return Address
    POP_EAX                                     ; Get nested_break_num
    STORE32_Absolute32_eax &break_target_num    ; Restore break_target_num
    POP_EAX                                     ; Get nested_break_func
    STORE32_Absolute32_eax &break_target_func   ; Restore break_target_func
    POP_EAX                                     ; Get nested_break_head
    STORE32_Absolute32_eax &break_target_head   ; Restore break_target_head
    POP_EAX                                     ; Get nested_locals
    STORE32_Absolute32_eax &break_frame         ; Restore break_frame
    PUSH_EBX                                    ; Put return back in place
    RETURN                                      ; Return to caller


;; set_break_frame microfunction
;; Receives char* head in EAX and char* num in EBX
;; Overwrites EAX and EBX
;; Returns to calling function
:set_break_frame
    STORE32_Absolute32_eax &break_target_head   ; update break_target_head
    STORE32_Absolute32_ebx &break_target_num    ; update break_target_num
    LOAD32_Absolute32_ebx &function             ; Using function
    LOAD32_EAX_from_EBX_Immediate8 !4           ; function->LOCALS
    STORE32_Absolute32_eax &break_frame         ; break_frame = function->LOCALS
    LOAD32_EAX_from_EBX_Immediate8 !8           ; function->S
    STORE32_Absolute32_eax &break_target_func   ; break_target_func = function->S
    RETURN                                      ; Return to sender


;; process_do function
;; Receives Nothing
;; Returns Nothing
;; Increments current_count and leverages save/restore_break_frame pieces
;; Uses ECX for char* NUMBER_STRING
:process_do
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    CALL32 %save_break_frame                    ; Save the frame

    LOAD32_Absolute32_eax &current_count        ; Using current count
    COPY_EAX_to_EBX                             ; Preparing for update
    ADDI8_EBX !1                                ; current_count + 1
    STORE32_Absolute32_ebx &current_count       ; current_count = current_count + 1
    CALL32 %numerate_number                     ; convert to string
    COPY_EAX_to_ECX                             ; put NUMBER_STRING in place

    LOADI32_EAX &process_do_string_0            ; Using "DO_END_"
    COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
    CALL32 %set_break_frame                     ; Set the frame

    LOADI32_EAX &process_do_string_1            ; Using ":DO_"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &function             ; Using function
    LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
    COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
    CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)

    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->NEXT
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT

    CALL32 %statement                           ; Do the DO {...} part

    LOADI32_EAX &process_do_string_2            ; Using "ERROR in process_do\nMISSING while\n"
    LOADI32_EBX &while_string                   ; Using "while"
    CALL32 %require_match                       ; Make sure we have it

    LOADI32_EAX &process_do_string_3            ; Using "ERROR in process_do\nMISSING (\n"
    LOADI32_EBX &open_paren                     ; Using "("
    CALL32 %require_match                       ; Make sure we have it

    CALL32 %expression                          ; Do the WHILE (...) part

    LOADI32_EAX &process_do_string_4            ; Using "ERROR in process_do\nMISSING )\n"
    LOADI32_EBX &close_paren                    ; Using ")"
    CALL32 %require_match                       ; Make sure we have it

    LOADI32_EAX &process_do_string_5            ; Using "ERROR in process_do\nMISSING ;\n"
    LOADI32_EBX &semicolon                      ; Using ";"
    CALL32 %require_match                       ; Make sure we have it

    LOADI32_EAX &process_do_string_6            ; Using "test_eax,eax\njne %DO_"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &function             ; Using function
    LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
    COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
    CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)

    LOADI32_EAX &process_do_string_7            ; Using ":DO_END_"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &function             ; Using function
    LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
    CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)

    CALL32 %restore_break_frame                 ; Restore the old break frame

    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

:process_do_string_0  "DO_END_"
:process_do_string_1  ":DO_"
:process_do_string_2  "ERROR in process_do
MISSING while
"
:process_do_string_3  "ERROR in process_do
MISSING (
"
:process_do_string_4  "ERROR in process_do
MISSING )
"
:process_do_string_5  "ERROR in process_do
MISSING ;
"
:process_do_string_6  "test_eax,eax
jne %DO_"
:process_do_string_7  ":DO_END_"


;; process_while function
;; Receives nothing
;; Returns nothing
;; Increments current_count and leverages save/restore_break_frame pieces
;; Uses ECX for char* NUMBER_STRING
:process_while
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    CALL32 %save_break_frame                    ; Save break_frame

    LOAD32_Absolute32_eax &current_count        ; Using current count
    COPY_EAX_to_EBX                             ; Preparing for update
    ADDI8_EBX !1                                ; current_count + 1
    STORE32_Absolute32_ebx &current_count       ; current_count = current_count + 1
    CALL32 %numerate_number                     ; convert to string
    COPY_EAX_to_ECX                             ; put NUMBER_STRING in place

    LOADI32_EAX &process_while_string_0         ; Using "END_WHILE_"
    COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
    CALL32 %set_break_frame                     ; Set it and forget it

    LOADI32_EAX &process_while_string_1         ; Using ":WHILE_"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &function             ; Using function
    LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
    COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
    CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)

    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->NEXT
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT

    LOADI32_EAX &process_while_string_2         ; Using "ERROR in process_while\nMISSING (\n"
    LOADI32_EBX &open_paren                     ; Using "("
    CALL32 %require_match                       ; Make sure we have it

    CALL32 %expression                          ; Deal with the WHILE (...) part

    LOADI32_EAX &process_while_string_3         ; Using "test_eax,eax\nje %END_WHILE_"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &function             ; Using function
    LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
    COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
    CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)

    LOADI32_EAX &process_while_string_4         ; Using "# THEN_while_"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &function             ; Using function
    LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
    CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)

    LOADI32_EAX &process_while_string_5         ; Using "ERROR in process_while\nMISSING )\n"
    LOADI32_EBX &close_paren                    ; Using ")"
    CALL32 %require_match                       ; Make sure we have it

    CALL32 %statement                           ; Deal with the {....} part

    LOADI32_EAX &process_while_string_6         ; Using "jmp %WHILE_"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &function             ; Using function
    LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
    COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
    CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)

    LOADI32_EAX &process_while_string_7         ; Using ":END_WHILE_"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &function             ; Using function
    LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
    CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)

    CALL32 %restore_break_frame                 ; Restore the old break frame

    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

:process_while_string_0  "END_WHILE_"
:process_while_string_1  ":WHILE_"
:process_while_string_2  "ERROR in process_while
MISSING (
"
:process_while_string_3  "test_eax,eax
je %END_WHILE_"
:process_while_string_4  "# THEN_while_"
:process_while_string_5  "ERROR in process_while
MISSING )
"
:process_while_string_6  "jmp %WHILE_"
:process_while_string_7  ":END_WHILE_"


;; process_for function
;; Receives Nothing
;; Returns Nothing
;; Increments current_count and leverages save/restore_break_frame pieces
;; Uses ECX for char* NUMBER_STRING
:process_for
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    CALL32 %save_break_frame                    ; Save the frame

    LOAD32_Absolute32_eax &current_count        ; Using current count
    COPY_EAX_to_EBX                             ; Preparing for update
    ADDI8_EBX !1                                ; current_count + 1
    STORE32_Absolute32_ebx &current_count       ; current_count = current_count + 1
    CALL32 %numerate_number                     ; convert to string
    COPY_EAX_to_ECX                             ; put NUMBER_STRING in place

    LOADI32_EAX &process_for_string_0           ; Using "FOR_END_"
    COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
    CALL32 %set_break_frame                     ; Set it and forget it

    LOADI32_EAX &process_for_string_1           ; Using "# FOR_initialization_"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &function             ; Using function
    LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
    COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
    CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)

    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->NEXT
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT

    LOADI32_EAX &process_for_string_2           ; Using "ERROR in process_for\nMISSING (\n"
    LOADI32_EBX &open_paren                     ; Using "("
    CALL32 %require_match                       ; Make Sure we have it

    LOAD32_Absolute32_ebx &global_token         ; Using global_token
    LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
    LOADI32_EAX &semicolon                      ; Using ";"
    CALL32 %match                               ; IF global_token->S == ";"
    CMPI8_EAX !0                                ; Then no initializer
    JE32 %process_for_terminator                ; And skip getting the expression

    ;; Deal with FOR (...; case
    CALL32 %expression                          ; Get the FOR ( ... ; part

:process_for_terminator
    LOADI32_EAX &process_for_string_3           ; Using ":FOR_"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &function             ; Using function
    LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
    COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
    CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)

    LOADI32_EAX &process_for_string_4           ; Using "ERROR in process_for\nMISSING ;1\n"
    LOADI32_EBX &semicolon                      ; Using ";"
    CALL32 %require_match                       ; Make sure we have it

    CALL32 %expression                          ; Get the FOR ( ; ... ; Part

    LOADI32_EAX &process_for_string_5           ; Using "test_eax,eax\nje %FOR_END_"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &function             ; Using function
    LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
    COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
    CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)

    LOADI32_EAX &process_for_string_6           ; Using "jmp %FOR_THEN_"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &function             ; Using function
    LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
    CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)

    LOADI32_EAX &process_for_string_7           ; Using ":FOR_ITER_"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &function             ; Using function
    LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
    CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)

    LOADI32_EAX &process_for_string_8           ; Using "ERROR in process_for\nMISSING ;2\n"
    LOADI32_EBX &semicolon                      ; Using ";"
    CALL32 %require_match                       ; Make sure we have it

    CALL32 %expression                          ; Get the FOR (;;...) part

    LOADI32_EAX &process_for_string_9           ; Using "jmp %FOR_"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &function             ; Using function
    LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
    COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
    CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)

    LOADI32_EAX &process_for_string_10          ; Using ":FOR_THEN_"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &function             ; Using function
    LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
    CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)

    LOADI32_EAX &process_for_string_11          ; Using "ERROR in process_for\nMISSING )\n"
    LOADI32_EBX &close_paren                    ; Using ")"
    CALL32 %require_match                       ; Make sure we have it

    CALL32 %statement                           ; Get FOR (;;) {...} part

    LOADI32_EAX &process_for_string_12          ; Using "jmp %FOR_ITER_"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &function             ; Using function
    LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
    COPY_ECX_to_EBX                             ; Passing NUMBER_STRING
    CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)

    LOADI32_EAX &process_for_string_13          ; Using ":FOR_END_"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &function             ; Using function
    LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
    CALL32 %uniqueID_out                        ; uniqueID_out(function->s, number_string)

    CALL32 %restore_break_frame                 ; Restore the old break frame

    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

:process_for_string_0  "FOR_END_"
:process_for_string_1  "# FOR_initialization_"
:process_for_string_2  "ERROR in process_for
MISSING (
"
:process_for_string_3  ":FOR_"
:process_for_string_4  "ERROR in process_for
MISSING ;1
"
:process_for_string_5  "test_eax,eax
je %FOR_END_"
:process_for_string_6  "jmp %FOR_THEN_"
:process_for_string_7  ":FOR_ITER_"
:process_for_string_8  "ERROR in process_for
MISSING ;2
"
:process_for_string_9  "jmp %FOR_"
:process_for_string_10 ":FOR_THEN_"
:process_for_string_11 "ERROR in process_for
MISSING )
"
:process_for_string_12 "jmp %FOR_ITER_"
:process_for_string_13 ":FOR_END_"


;; process_break function
;; Receives nothing
;; Returns nothing
;; Handles the break out of loops case
;; Uses EBX for struct token_list* break_frame and ECX for struct token_list* I
:process_break
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    LOAD32_Absolute32_eax &break_target_head    ; Catch big error
    CMPI8_EAX !0                                ; IF(NULL == break_target_head)
    JE32 %process_break_bad                     ; I'm sorry Mr White but you have stage-3 lung cancer

    LOAD32_Absolute32_eax &function             ; Using function
    LOAD32_ECX_from_EAX_Immediate8 !4           ; I = function->LOCALS
    LOAD32_Absolute32_ebx &break_frame          ; Put break_frame in the right spot
    LOADI32_EAX &process_break_string_1         ; Using "pop_ebx\t# break_cleanup_locals\n"

:process_break_iter
    CMPI8_ECX !0                                ; IF (NULL == I)
    JE32 %process_break_cleaned                 ; We are done

    CMP_EBX_ECX                                 ; IF I != break_frame
    JE32 %process_break_cleaned                 ; We are done

    CALL32 %emit_out                            ; Emit it
    LOAD32_ECX_from_ECX                         ; I = I->NEXT
    JMP32 %process_break_iter                   ; Keep looping

:process_break_cleaned
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->NEXT
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT

    LOADI32_EAX &process_break_string_2         ; Using "jmp %"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &break_target_head    ; Get what we are in
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &break_target_func    ; Get what function we are in
    CALL32 %emit_out                            ; Emit it

    LOADI32_EAX &underline                      ; Using "_"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &break_target_num     ; Get dem digits
    CALL32 %emit_out                            ; Emit it

    LOADI32_EAX &process_break_string_3         ; Using "\n"
    CALL32 %emit_out                            ; Emit it

    LOADI32_EAX &process_break_string_4         ; Using "ERROR in break statement\nMissing ;\n"
    LOADI32_EBX &semicolon                      ; Using ";"
    CALL32 %require_match                       ; Make sure we have it

    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

:process_break_bad
    ;; Breaking badly
    LOADI32_EAX %2                              ; Using standard error
    STORE32_Absolute32_eax &Output_file         ; write to standard error
;   CALL32 %line_error                          ; Write useful debug info
    COPY_ECX_to_EAX                             ; put S in the right place
    CALL32 %File_Print                          ; print it

    LOADI32_EAX &process_break_string_0         ; Ending string
    CALL32 %File_Print                          ; print it
    JMP32 %Exit_Failure                         ; Abort Hard

:process_break_string_0  "Not inside of a loop or case statement"
:process_break_string_1  "pop_ebx   # break_cleanup_locals
"
:process_break_string_2  "jmp %"
:process_break_string_3  "
"
:process_break_string_4  "ERROR in break statement
Missing ;
"


;; expression function
;; Receives Nothing
;; Returns Nothing
;; Walks global_token and updates output_list
;; Uses EAX and EBX for match and ECX for char* store
:expression
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    CALL32 %bitwise_expr                        ; Collect bitwise expressions

    LOAD32_Absolute32_ebx &global_token         ; Using global_token
    LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
    LOADI32_EAX &equal                          ; "="
    CALL32 %match                               ; IF global_token->S == "="
    CMPI8_EAX !0                                ; We have to deal with assignment
    JNE32 %expression_done                      ; Looks like nope

    ;; Deal with possible assignment
    LOADI32_ECX &expression_string_1            ; Assume "mov_[ebx],al\n" by default
    LOAD32_Absolute32_ebx &global_token         ; Using global_token
    LOAD32_EBX_from_EBX_Immediate8 !4           ; global_token->PREV
    LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->PREV->S
    LOADI32_EAX &close_bracket                  ; Using "]"
    CALL32 %match                               ; IF global_token->S == "]"
    CMPI8_EAX !0                                ; Then we might have a char
    JNE32 %expression_int                       ; Otherwise INT

    LOAD32_Absolute32_ebx &current_target       ; Using current_target
    LOAD32_EBX_from_EBX_Immediate8 !24          ; current_target->NAME
    LOADI32_EAX &type_char_indirect_name        ; Using "char*"
    CALL32 %match                               ; Intentional inefficiency because I feel like it
    CMPI8_EAX !0                                ; IF current_target->NAME == "char*"
    JNE32 %expression_int                       ; Do char anyway

    JMP32 %expression_common                    ; Looks like we have to use "mov_[ebx],al\n"

:expression_int
    LOADI32_ECX &expression_string_0            ; Use "mov_[ebx],eax\n"

:expression_common
    LOADI32_EAX &expression                     ; Passing expression
    CALL32 %common_recursion                    ; Recurse
    COPY_ECX_to_EAX                             ; Using Store
    CALL32 %emit_out                            ; Emit it
    LOADI32_EAX %0                              ; Using NULL
    STORE32_Absolute32_eax &current_target      ; current_target = NULL

:expression_done
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

:expression_string_0  "mov_[ebx],eax
"
:expression_string_1  "mov_[ebx],al
"


;; bitwise_expr function
;; Receives nothing
;; Returns nothing
;; Walks global_token list and updates output list
;; Just calls other functions
:bitwise_expr
    CALL32 %relational_expr                     ; Walk up the tree
    CALL32 %bitwise_expr_stub                   ; Let general recursion do the work
    RETURN


;; bitwise_expr_stub function
;; Receives nothing
;; Returns Nothing
;; Just calls general_recursion a bunch
;; Uses EAX, EBX, ECX and EDX for passing constants to general recursion
:bitwise_expr_stub
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    PUSH_EDX                                    ; Protect EDX

    LOADI32_EAX &relational_expr                ; Using relational_expr
    LOADI32_EBX &bitwise_expr_stub_string_0     ; Using "and_eax,ebx\n"
    LOADI32_ECX &bitwise_and                    ; Using "&"
    LOADI32_EDX &bitwise_expr_stub              ; And recurse
    CALL32 %general_recursion                   ; Hit it

    LOADI32_EAX &relational_expr                ; Using relational_expr
    LOADI32_EBX &bitwise_expr_stub_string_0     ; Using "and_eax,ebx\n"
    LOADI32_ECX &logical_and                    ; Using "&&"
    LOADI32_EDX &bitwise_expr_stub              ; And recurse
    CALL32 %general_recursion                   ; Hit it

    LOADI32_EAX &relational_expr                ; Using relational_expr
    LOADI32_EBX &bitwise_expr_stub_string_1     ; Using "or_eax,ebx\n"
    LOADI32_ECX &bitwise_or                     ; Using "|"
    LOADI32_EDX &bitwise_expr_stub              ; And recurse
    CALL32 %general_recursion                   ; Hit it

    LOADI32_EAX &relational_expr                ; Using relational_expr
    LOADI32_EBX &bitwise_expr_stub_string_1     ; Using "or_eax,ebx\n"
    LOADI32_ECX &logical_or                     ; Using "||"
    LOADI32_EDX &bitwise_expr_stub              ; And recurse
    CALL32 %general_recursion                   ; Hit it

    LOADI32_EAX &relational_expr                ; Using relational_expr
    LOADI32_EBX &bitwise_expr_stub_string_2     ; Using "xor_eax,ebx\n"
    LOADI32_ECX &bitwise_xor                    ; Using "^"
    LOADI32_EDX &bitwise_expr_stub              ; And recurse
    CALL32 %general_recursion                   ; Hit it

    POP_EDX                                     ; Restore EDX
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

:bitwise_expr_stub_string_0  "and_eax,ebx
"
:bitwise_expr_stub_string_1  "or_eax,ebx
"
:bitwise_expr_stub_string_2  "xor_eax,ebx
"


;; relational_expr function
;; Receives nothing
;; Returns Nothing
;; Walks global_token list and updates output list
;; just calls other function
:relational_expr
    CALL32 %additive_expr                       ; Walk up the tree
    CALL32 %relational_expr_stub                ; Recurse
    RETURN


;; relational_expr_stub function
;; Receives nothing
;; Returns Nothing
;; Just calls general_recursion a bunch
;; Uses EAX, EBX, ECX and EDX for passing constants to general recursion
:relational_expr_stub
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    PUSH_EDX                                    ; Protect EDX

    LOADI32_EAX &additive_expr                  ; Using additive_expr
    LOADI32_EBX &relational_expr_stub_string_0  ; Using "cmp\nsetl_al\nmovzx_eax,al\n"
    LOADI32_ECX &less_than_string               ; Using "<"
    LOADI32_EDX &relational_expr_stub           ; And recurse
    CALL32 %general_recursion                   ; Hit it

    LOADI32_EAX &additive_expr                  ; Using additive_expr
    LOADI32_EBX &relational_expr_stub_string_1  ; Using "cmp\nsetle_al\nmovzx_eax,al\n"
    LOADI32_ECX &less_than_equal_string         ; Using "<="
    LOADI32_EDX &relational_expr_stub           ; And recurse
    CALL32 %general_recursion                   ; Hit it

    LOADI32_EAX &additive_expr                  ; Using additive_expr
    LOADI32_EBX &relational_expr_stub_string_2  ; Using "cmp\nsetge_al\nmovzx_eax,al\n"
    LOADI32_ECX &greater_than_equal_string      ; Using ">="
    LOADI32_EDX &relational_expr_stub           ; And recurse
    CALL32 %general_recursion                   ; Hit it

    LOADI32_EAX &additive_expr                  ; Using additive_expr
    LOADI32_EBX &relational_expr_stub_string_3  ; Using "cmp\nsetg_al\nmovzx_eax,al\n"
    LOADI32_ECX &greater_than_string            ; Using ">"
    LOADI32_EDX &relational_expr_stub           ; And recurse
    CALL32 %general_recursion                   ; Hit it

    LOADI32_EAX &additive_expr                  ; Using additive_expr
    LOADI32_EBX &relational_expr_stub_string_4  ; Using "cmp\nsete_al\nmovzx_eax,al\n"
    LOADI32_ECX &equal_to_string                ; Using "=="
    LOADI32_EDX &relational_expr_stub           ; And recurse
    CALL32 %general_recursion                   ; Hit it

    LOADI32_EAX &additive_expr                  ; Using additive_expr
    LOADI32_EBX &relational_expr_stub_string_5  ; Using "cmp\nsetne_al\nmovzx_eax,al\n"
    LOADI32_ECX &not_equal_string               ; Using "!="
    LOADI32_EDX &relational_expr_stub           ; And recurse
    CALL32 %general_recursion                   ; Hit it

    POP_EDX                                     ; Restore EDX
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

:relational_expr_stub_string_0  "cmp
setl_al
movzx_eax,al
"
:relational_expr_stub_string_1  "cmp
setle_al
movzx_eax,al
"
:relational_expr_stub_string_2  "cmp
setge_al
movzx_eax,al
"
:relational_expr_stub_string_3  "cmp
setg_al
movzx_eax,al
"
:relational_expr_stub_string_4  "cmp
sete_al
movzx_eax,al
"
:relational_expr_stub_string_5  "cmp
setne_al
movzx_eax,al
"


;; additive_expr function
;; Receives nothing
;; Returns Nothing
;; Walks global_token list and updates output list
;; just calls other function
:additive_expr
    CALL32 %postfix_expr                        ; Walk up the tree
    CALL32 %additive_expr_stub                  ; Recurse
    RETURN


;; additive_expr_stub function
;; Receives nothing
;; Returns Nothing
;; Just calls general_recursion a bunch
;; Uses EAX, EBX, ECX and EDX for passing constants to general recursion
:additive_expr_stub
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    PUSH_EDX                                    ; Protect EDX

    LOADI32_EAX &postfix_expr                   ; Using postfix_expr
    LOADI32_EBX &additive_expr_stub_string_0    ; Using "add_eax,ebx\n"
    LOADI32_ECX &plus_string                    ; Using "+"
    LOADI32_EDX &additive_expr_stub             ; And recurse
    CALL32 %general_recursion                   ; Hit it

    LOADI32_EAX &postfix_expr                   ; Using postfix_expr
    LOADI32_EBX &additive_expr_stub_string_1    ; Using "sub_ebx,eax\nmov_eax,ebx\n"
    LOADI32_ECX &minus_string                   ; Using "-"
    LOADI32_EDX &additive_expr_stub             ; And recurse
    CALL32 %general_recursion                   ; Hit it

    LOADI32_EAX &postfix_expr                   ; Using postfix_expr
    LOADI32_EBX &additive_expr_stub_string_2    ; Using "mul_ebx\n"
    LOADI32_ECX &multiply_string                ; Using "*"
    LOADI32_EDX &additive_expr_stub             ; And recurse
    CALL32 %general_recursion                   ; Hit it

    LOADI32_EAX &postfix_expr                   ; Using postfix_expr
    LOADI32_EBX &additive_expr_stub_string_3    ; Using "xchg_ebx,eax\nmov_edx, %0\ndiv_ebx\n"
    LOADI32_ECX &divide_string                  ; Using "/"
    LOADI32_EDX &additive_expr_stub             ; And recurse
    CALL32 %general_recursion                   ; Hit it

    LOADI32_EAX &postfix_expr                   ; Using postfix_expr
    LOADI32_EBX &additive_expr_stub_string_4    ; Using "xchg_ebx,eax\nmov_edx, %0\ndiv_ebx\nmov_eax,edx\n"
    LOADI32_ECX &modulus_string                 ; Using "%"
    LOADI32_EDX &additive_expr_stub             ; And recurse
    CALL32 %general_recursion                   ; Hit it

    LOADI32_EAX &postfix_expr                   ; Using postfix_expr
    LOADI32_EBX &additive_expr_stub_string_5    ; Using "mov_ecx,eax\nmov_eax,ebx\nsal_eax,cl\n"
    LOADI32_ECX &left_shift_string              ; Using "<<"
    LOADI32_EDX &additive_expr_stub             ; And recurse
    CALL32 %general_recursion                   ; Hit it

    LOADI32_EAX &postfix_expr                   ; Using postfix_expr
    LOADI32_EBX &additive_expr_stub_string_6    ; Using "mov_ecx,eax\nmov_eax,ebx\nsar_eax,cl\n"
    LOADI32_ECX &right_shift_string             ; Using ">>"
    LOADI32_EDX &additive_expr_stub             ; And recurse
    CALL32 %general_recursion                   ; Hit it

    POP_EDX                                     ; Restore EDX
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

:additive_expr_stub_string_0  "add_eax,ebx
"
:additive_expr_stub_string_1  "sub_ebx,eax
mov_eax,ebx
"
:additive_expr_stub_string_2  "mul_ebx
"
:additive_expr_stub_string_3  "xchg_ebx,eax
mov_edx, %0
div_ebx
"
:additive_expr_stub_string_4  "xchg_ebx,eax
mov_edx, %0
div_ebx
mov_eax,edx
"
:additive_expr_stub_string_5  "mov_ecx,eax
mov_eax,ebx
sal_eax,cl
"
:additive_expr_stub_string_6  "mov_ecx,eax
mov_eax,ebx
sar_eax,cl
"


;; postfix_expr function
;; Receives nothing
;; Returns Nothing
;; Walks global_token list and updates output list
;; just calls other function
:postfix_expr
    CALL32 %primary_expr                        ; Walk up the tree
    CALL32 %postfix_expr_stub                   ; Recurse
    RETURN


;; postfix_expr_stub function
;; Receives nothing
;; Returns Nothing
;; Checks for "[" and "->" and deals with them otherwise does nothing
;; Uses EAX, EBX, ECX and EDX for passing constants to general recursion
:postfix_expr_stub
    PUSH_EBX                                    ; Protect EBX
    LOAD32_Absolute32_ebx &global_token         ; Using global_token
    LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
    LOADI32_EAX &open_bracket                   ; Using "["
    CALL32 %match                               ; IF global_token->S == "["
    CMPI8_EAX !0                                ; then we have an array
    JNE32 %postfix_expr_stub_arrow              ; Otherwise try arrow

    ;; Deal with array
    CALL32 %postfix_expr_array                  ; Get it
    CALL32 %postfix_expr_stub                   ; Recurse

:postfix_expr_stub_arrow
    LOADI32_EAX &arrow_string                   ; Using "->"
    CALL32 %match                               ; IF global_token->S == "->"
    CMPI8_EAX !0                                ; Then we need to deal with struct offsets
    JNE32 %postfix_expr_stub_done               ; Otherwise be done

    ;; Deal with arrow
    CALL32 %postfix_expr_arrow                  ; Get it
    CALL32 %postfix_expr_stub                   ; Recurse

:postfix_expr_stub_done
    POP_EBX                                     ; Restore EBX
    RETURN


;; unary_expr_sizeof function
;; Receives nothing
;; Returns nothing
;; Uses ECX for A->SIZE
:unary_expr_sizeof
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->NEXT
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT

    LOADI32_EAX &unary_expr_sizeof_string_0     ; Using "ERROR in unary_expr\nMissing (\n"
    LOADI32_EBX &open_paren                     ; Using "("
    CALL32 %require_match                       ; Make sure we have it

    CALL32 %type_name                           ; Get the type
    LOAD32_ECX_from_EAX_Immediate8 !4           ; Set A->TYPE

    LOADI32_EAX &unary_expr_sizeof_string_1     ; Using "ERROR in unary_expr\nMissing )\n"
    LOADI32_EBX &close_paren                    ; Using ")"
    CALL32 %require_match                       ; Make sure we have it

    LOADI32_EAX &unary_expr_sizeof_string_2     ; Using "mov_eax, %"
    CALL32 %emit_out                            ; Emit it

    COPY_ECX_to_EAX                             ; Put A->SIZE in the right place
    CALL32 %numerate_number                     ; Turn into string
    CALL32 %emit_out                            ; Emit it

    LOADI32_EAX &unary_expr_sizeof_string_3     ; Using "\n"
    CALL32 %emit_out                            ; Emit it

    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

:unary_expr_sizeof_string_0  "ERROR in unary_expr
Missing (
"
:unary_expr_sizeof_string_1  "ERROR in unary_expr
Missing )
"
:unary_expr_sizeof_string_2  "mov_eax, %"
:unary_expr_sizeof_string_3  "
"


;; postfix_expr_array function
;; Receives Nothing
;; Returns Nothing
;; Uses EBX for struct type* ARRAY and ECX for char* ASSIGN
:postfix_expr_array
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    LOAD32_Absolute32_eax &current_target       ; ARRAY = current_target
    PUSH_EAX                                    ; Protect it

    LOADI32_EAX &expression                     ; Using expression
    CALL32 %common_recursion                    ; Recurse

    POP_EBX                                     ; Restore array
    STORE32_Absolute32_ebx &current_target      ; current_target = ARRAY

    LOADI32_ECX &postfix_expr_array_string_0    ; ASSIGN = "mov_eax,[eax]\n"

    LOADI32_EAX &type_char_indirect_name        ; Using "char*"
    LOAD32_EBX_from_EBX_Immediate8 !24          ; current_target->NAME
    CALL32 %match                               ; IF current_target->NAME == "char*"
    CMPI8_EAX !0                                ; load a byte
    JNE32 %postfix_expr_array_large             ; Otherwise adjust

    ;; Deal with loading byte
    LOADI32_ECX &postfix_expr_array_string_1    ; ASSIGN = "movsx_eax,BYTE_PTR_[eax]\n"
    JMP32 %postfix_expr_array_common            ; Do the next bit

:postfix_expr_array_large
    ;; deal with arrays made of things other than chars
    LOADI32_EAX &postfix_expr_array_string_2    ; Using "sal_eax, !"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &current_target       ; Using current_target
    LOAD32_EAX_from_EAX_Immediate8 !12          ; current_target->INDIRECT
    LOAD32_EAX_from_EAX_Immediate8 !4           ; current_target->INDIRECT->SIZE
    CALL32 %ceil_log2                           ; ceil_log2(current_target->indirect->size)
    CALL32 %numerate_number                     ; numerate_number(ceil_log2(current_target->indirect->size))
    CALL32 %emit_out                            ; Emit it

    LOADI32_EAX &postfix_expr_array_string_3    ; Using "\n"
    CALL32 %emit_out                            ; Emit it

:postfix_expr_array_common
    LOADI32_EAX &postfix_expr_array_string_4    ; Using "add_eax,ebx\n"
    CALL32 %emit_out                            ; Emit it

    LOADI32_EAX &postfix_expr_array_string_5    ; Using "ERROR in postfix_expr\nMissing ]\n"
    LOADI32_EBX &close_bracket                  ; Using "]"
    CALL32 %require_match                       ; Make sure we have it

    LOAD32_Absolute32_ebx &global_token         ; Using global_token
    LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
    LOADI32_EAX &equal                          ; Using "="
    CALL32 %match                               ; IF global_token->S == "="
    CMPI8_EAX !0                                ; We need to preserve address
    JNE32 %postfix_expr_array_done              ; Otherwise be done

    ;; Clearing out assign
    LOADI32_ECX &postfix_expr_array_string_6    ; ASSIGN = ""

:postfix_expr_array_done
    COPY_ECX_to_EAX                             ; Using ASSIGN
    CALL32 %emit_out                            ; Emit it

    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

:postfix_expr_array_string_0  "mov_eax,[eax]
"
:postfix_expr_array_string_1  "movsx_eax,BYTE_PTR_[eax]
"
:postfix_expr_array_string_2  "sal_eax, !"
:postfix_expr_array_string_3  "
"
:postfix_expr_array_string_4  "add_eax,ebx
"
:postfix_expr_array_string_5  "ERROR in postfix_expr
Missing ]
"
:postfix_expr_array_string_6  ""


;; ceil_log2 function
;; Receives int a in EAX
;; Performs log2 on A and
;; Returns result in EAX
;; Uses EBX for INT A and ECX for INT RESULT
:ceil_log2
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    LOADI32_ECX %0                              ; RESULT = 0

    COPY_EAX_to_EBX                             ; put A in right place
    SUBI8_EAX !1                                ; (A - 1)
    AND_EAX_EBX                                 ; A & (A - 1)
    CMPI8_EAX !0                                ; IF 0 == (A & (A - 1))
    JNE32 %ceil_log2_iter                       ; Starting from -1

    LOADI32_ECX %-1                             ; RESULT = -1

:ceil_log2_iter
    CMPI8_EBX !0                                ; IF A > 0
    JLE32 %ceil_log2_done                       ; Otherwise be done

    ADDI8_ECX !1                                ; RESULT = RESULT + 1
    SHRI8_EBX !1                                ; A = A >> 1
    JMP32 %ceil_log2_iter                       ; Keep looping

:ceil_log2_done
    COPY_ECX_to_EAX                             ; Return RESULT
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN


;; postfix_expr_arrow function
;; Receives nothing
;; Returns nothing
;; Emits a bunch and updates current_target
;; Uses EBX for struct type* I
:postfix_expr_arrow
    PUSH_EBX                                    ; Protect EBX
    LOADI32_EAX &postfix_expr_arrow_string_0    ; Using "# looking up offset\n"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->NEXT
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT

    LOAD32_EBX_from_EAX_Immediate8 !8           ; Using global_token->S
    LOAD32_Absolute32_eax &current_target       ; Using current_target
    CALL32 %lookup_member                       ; lookup_member(current_target, global_token->s)
    COPY_EAX_to_EBX                             ; struct type* I = lookup_member(current_target, global_token->s)

    LOAD32_EAX_from_EAX_Immediate8 !20          ; I->TYPE
    STORE32_Absolute32_eax &current_target      ; current_target = I->TYPE

    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->NEXT
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT

    LOAD32_EAX_from_EBX_Immediate8 !8           ; I->OFFSET
    CMPI8_EAX !0                                ; IF 0 != I->OFFSET
    JE32 %postfix_expr_arrow_first              ; Then we don't need to do an offset

    ;; Deal with needing an offset
    LOADI32_EAX &postfix_expr_arrow_string_1    ; Using "# -> offset calculation\nmov_ebx, %"
    CALL32 %emit_out                            ; Emit it

    LOAD32_EAX_from_EBX_Immediate8 !8           ; I->OFFSET
    CALL32 %numerate_number                     ; Convert to string
    CALL32 %emit_out                            ; Emit it

    LOADI32_EAX &postfix_expr_arrow_string_2    ; Using "\nadd_eax,ebx\n"
    CALL32 %emit_out                            ; Emit it

:postfix_expr_arrow_first
    LOAD32_EAX_from_EBX_Immediate8 !4           ; I->SIZE
    CMPI8_EAX !4                                ; IF I->SIZE >= 4
    JL32 %postfix_expr_arrow_done               ; Otherwise be done

    ;; Last chance for load
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EBX_from_EAX_Immediate8 !8           ; global_token->S
    LOADI32_EAX &equal                          ; Using "="
    CALL32 %match                               ; IF global_token->S == "="
    CMPI8_EAX !0                                ; Then we have assignment and should not load
    JE32 %postfix_expr_arrow_done               ; Be done

    ;; Deal with load case
    LOADI32_EAX &postfix_expr_arrow_string_3    ; Using "mov_eax,[eax]\n"
    CALL32 %emit_out                            ; Emit it

:postfix_expr_arrow_done
    POP_EBX                                     ; Restore EBX
    RETURN

:postfix_expr_arrow_string_0  "# looking up offset
"
:postfix_expr_arrow_string_1  "# -> offset calculation
mov_ebx, %"
:postfix_expr_arrow_string_2  "
add_eax,ebx
"
:postfix_expr_arrow_string_3  "mov_eax,[eax]
"


;; primary_expr function
;; Receives nothing
;; Returns nothing
:primary_expr
    PUSH_EBX                                    ; Protect EBX

    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EBX_from_EAX_Immediate8 !8           ; global_token->S
    LOADI32_EAX &sizeof_string                  ; Using "sizeof"
    CALL32 %match                               ; See if match
    CMPI8_EAX !0                                ; IF match
    JNE32 %primary_expr_neg                     ; Otherwise try negatives

    ;; Deal with sizeof
    CALL32 %unary_expr_sizeof                   ; Lets do this
    JMP32 %primary_expr_done                    ; Be done

:primary_expr_neg
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
    LOAD8_al_from_EAX                           ; global_token->S[0]
    MOVZX_al                                    ; Make it useful
    CMPI8_EAX !45                               ; IF global_token->S[0] == "-"
    JNE32 %primary_expr_not                     ; Otherwise try logical NOT

    ;; Deal with negative numbers
    LOADI32_EAX &primary_expr_string_0          ; Using "mov_eax, %0\n"
    CALL32 %emit_out                            ; Emit it

    LOADI32_EAX &postfix_expr                   ; Passing postfix_expr
    CALL32 %common_recursion                    ; Get what it is notting

    LOADI32_EAX &primary_expr_string_1          ; Using "sub_ebx,eax\nmov_eax,ebx\n"
    CALL32 %emit_out                            ; Emit it
    JMP32 %primary_expr_done                    ; Be done

:primary_expr_not
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
    LOAD8_al_from_EAX                           ; global_token->S[0]
    MOVZX_al                                    ; Make it useful
    CMPI8_EAX !33                               ; IF global_token->S[0] == "!"
    JNE32 %primary_expr_bin                     ; Otherwise try '~'

    ;; Deal with logical not
    LOADI32_EAX &primary_expr_string_2          ; Using "mov_eax, %1\n"
    CALL32 %emit_out                            ; Emit it

    LOADI32_EAX &postfix_expr                   ; Passing postfix_expr
    CALL32 %common_recursion                    ; Get what it is notting

    LOADI32_EAX &primary_expr_string_3          ; Using "xor_eax,ebx\n"
    CALL32 %emit_out                            ; Emit it
    JMP32 %primary_expr_done                    ; Be done

:primary_expr_bin
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
    LOAD8_al_from_EAX                           ; global_token->S[0]
    MOVZX_al                                    ; Make it useful
    CMPI8_EAX !126                              ; IF global_token->S[0] == "~"
    JNE32 %primary_expr_paren                   ; Otherwise try paren

    ;; Deal with binary NOT
    LOADI32_EAX &postfix_expr                   ; Passing postfix_expr
    CALL32 %common_recursion                    ; Get what it is notting
    LOADI32_EAX &primary_expr_string_4          ; Using "not_eax\n"
    CALL32 %emit_out                            ; Emit it
    JMP32 %primary_expr_done                    ; Be done

:primary_expr_paren
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
    LOAD8_al_from_EAX                           ; global_token->S[0]
    MOVZX_al                                    ; Make it useful
    CMPI8_EAX !40                               ; IF global_token->S[0] == "("
    JNE32 %primary_expr_ch                      ; Otherwise try char

    ;; deal with nesting
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->NEXT
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT
    CALL32 %expression                          ; Lets recurse
    LOADI32_EAX &primary_expr_string_5          ; Using "Error in Primary expression\nDidn't get )\n"
    LOADI32_EBX &close_paren                    ; Using ")"
    CALL32 %require_match                       ; Make sure we have it
    JMP32 %primary_expr_done                    ; Be done

:primary_expr_ch
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
    LOAD8_al_from_EAX                           ; global_token->S[0]
    MOVZX_al                                    ; Make it useful
    CMPI8_EAX !39                               ; Using "'"
    JNE32 %primary_expr_str                     ; Otherwise try string

    ;; Deal with chars
    CALL32 %primary_expr_char                   ; Handle that char
    JMP32 %primary_expr_done                    ; Be done

:primary_expr_str
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
    LOAD8_al_from_EAX                           ; global_token->S[0]
    MOVZX_al                                    ; Make it useful
    CMPI8_EAX !34                               ; Using '\"'
    JNE32 %primary_expr_var                     ; Otherwise try a variable

    ;; Deal with strings
    CALL32 %primary_expr_string                 ; Handle that string
    JMP32 %primary_expr_done                    ; Be done

:primary_expr_var
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
    LOAD8_al_from_EAX                           ; global_token->S[0]
    MOVZX_al                                    ; Make it useful
    LOADI32_EBX &primary_expr_string_6          ; Using "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_"
    CALL32 %In_Set                              ; See if we have a match
    CMPI8_EAX !1                                ; IF match
    JNE32 %primary_expr_num                     ; otherwise try number

    ;; Deal with variables
    CALL32 %primary_expr_variable               ; Deal with variable
    JMP32 %primary_expr_done                    ; Be done

:primary_expr_num
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
    LOAD8_al_from_EAX                           ; global_token->S[0]
    MOVZX_al                                    ; Make it useful
    LOADI32_EBX &primary_expr_string_7          ; Using "0123456789"
    CALL32 %In_Set                              ; See if we have a match
    CMPI8_EAX !1                                ; IF match
    JNE32 %primary_expr_fail                    ; otherwise we failed hard

    ;; Deal with numbers
    CALL32 %primary_expr_number                 ; Collect the number
    JMP32 %primary_expr_done                    ; Be done

:primary_expr_fail
    ;; looks like we hit bad input
    ;; abort before it gets bad
    CALL32 %primary_expr_failure                ; No match means failure
:primary_expr_done
    POP_EBX                                     ; Restore EBX
    RETURN

:primary_expr_string_0  "mov_eax, %0
"
:primary_expr_string_1  "sub_ebx,eax
mov_eax,ebx
"
:primary_expr_string_2  "mov_eax, %1
"
:primary_expr_string_3  "xor_eax,ebx
"
:primary_expr_string_4  "not_eax
"
:primary_expr_string_5  "Error in Primary expression
Didn't get )
"
:primary_expr_string_6  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_"
:primary_expr_string_7  "0123456789"


;; primary_expr_variable function
;; Receives nothing
;; Returns nothing
;; Walks global and updates output
;; Uses EAX for struct token_list* a and ECX for char* S
:primary_expr_variable
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_ECX_from_EAX_Immediate8 !8           ; S = global_token->S
    LOAD32_EAX_from_EAX                         ; global_token->NEXT
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT

    COPY_ECX_to_EAX                             ; Using S
    LOAD32_Absolute32_ebx &global_constant_list ; Using global_constant_list
    CALL32 %sym_lookup                          ; sym_lookup(s, global_constant_list)
    CMPI8_EAX !0                                ; IF NULL == sym_lookup(s, global_constant_list)
    JE32 %primary_expr_variable_local           ; Try locals next

    ;; Deal with constant load
    LOAD32_EBX_from_EAX_Immediate8 !16          ; a->ARGS
    LOADI32_EAX &primary_expr_variable_string_2 ; Using "mov_eax, %"
    CALL32 %emit_out                            ; Emit it

    LOAD32_EAX_from_EBX_Immediate8 !8           ; a->ARGS->S
    CALL32 %emit_out                            ; Emit it

    LOADI32_EAX &primary_expr_variable_string_1 ; Using "\n"
    CALL32 %emit_out                            ; Emit it
    JMP32 %primary_expr_variable_done           ; Be done

:primary_expr_variable_local
    COPY_ECX_to_EAX                             ; Using S
    LOAD32_Absolute32_ebx &function             ; Using function
    LOAD32_EBX_from_EBX_Immediate8 !4           ; function->locals
    CALL32 %sym_lookup                          ; sym_lookup(s, function->locals)
    CMPI8_EAX !0                                ; IF NULL == sym_lookup(s, function->locals)
    JE32 %primary_expr_variable_arguments       ; try arguments next

    ;; Deal with local load
    CALL32 %variable_load                       ; Collect it
    JMP32 %primary_expr_variable_done           ; Be done

:primary_expr_variable_arguments
    COPY_ECX_to_EAX                             ; Using S
    LOAD32_Absolute32_ebx &function             ; Using function
    LOAD32_EBX_from_EBX_Immediate8 !16          ; function->args
    CALL32 %sym_lookup                          ; sym_lookup(s, function->args)
    CMPI8_EAX !0                                ; IF NULL == sym_lookup(s, global_constant_list)
    JE32 %primary_expr_variable_function        ; try functions next

    ;; Deal with argument load
    CALL32 %variable_load                       ; Collect it
    JMP32 %primary_expr_variable_done           ; Be done

:primary_expr_variable_function
    COPY_ECX_to_EAX                             ; Using S
    LOAD32_Absolute32_ebx &global_function_list ; Using global_function_list
    CALL32 %sym_lookup                          ; sym_lookup(s, global_function_list)
    CMPI8_EAX !0                                ; IF NULL == sym_lookup(s, global_function_list)
    JE32 %primary_expr_variable_global          ; try globals next

    ;; Deal with functions
    CALL32 %function_load                       ; Deal with the function
    JMP32 %primary_expr_variable_done           ; Be done

:primary_expr_variable_global
    COPY_ECX_to_EAX                             ; Using S
    LOAD32_Absolute32_ebx &global_symbol_list   ; Using global_symbol_list
    CALL32 %sym_lookup                          ; sym_lookup(s, global_symbol_list)
    CMPI8_EAX !0                                ; IF NULL == sym_lookup(s, global_symbol_list)
    JE32 %primary_expr_variable_error           ; Give up

    ;; Deal with globals
    CALL32 %global_load                         ; Collect that global
    JMP32 %primary_expr_variable_done           ; Be done

:primary_expr_variable_error
    LOADI32_EAX %2                              ; Using standard error
    STORE32_Absolute32_eax &Output_file         ; write to standard error
;   CALL32 %line_error                          ; Write useful debug info
    COPY_ECX_to_EAX                             ; put S in the right place
    CALL32 %File_Print                          ; print it

    LOADI32_EAX &primary_expr_variable_string_0 ; Ending string
    CALL32 %File_Print                          ; print it
    JMP32 %Exit_Failure                         ; Abort Hard

:primary_expr_variable_done
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

:primary_expr_variable_string_0  " is not a defined symbol
"
:primary_expr_variable_string_1  "
"
:primary_expr_variable_string_2  "mov_eax, %"


;; function_call function
;; Receives char* S in EAX and int BOOL in EBX
;; Builds stack frames before and tears them down after function calls
;; Uses ECX for char* S, EDX for int BOOL, ESI for PASSED
:function_call
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    PUSH_EDX                                    ; Protect EDX
    PUSH_ESI                                    ; Protect ESI
    COPY_EAX_to_ECX                             ; Put S in place
    COPY_EBX_to_EDX                             ; Put BOOL in place
    LOADI32_ESI %0                              ; PASSED = 0

    LOADI32_EAX &function_call_string_0         ; Using "ERROR in process_expression_list\nNo ( was found\n"
    LOADI32_EBX &open_paren                     ; Using "("
    CALL32 %require_match                       ; Make sure we have it

    LOADI32_EAX &function_call_string_1         ; Using "push_edi\t# Prevent overwriting in recursion\n"
    CALL32 %emit_out                            ; Emit it

    LOADI32_EAX &function_call_string_2         ; Using "push_ebp\t# Protect the old base pointer\n"
    CALL32 %emit_out                            ; Emit it

    LOADI32_EAX &function_call_string_3         ; Using "mov_edi,esp\t# Copy new base pointer\n"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
    LOAD8_al_from_EAX                           ; global_token->S[0]
    MOVZX_al                                    ; Make it useful
    CMPI8_EAX !41                               ; IF global_token->S[0] == ")"
    JE32 %function_call_gen_done                ; Then no arguments to send

    ;; looks like we have arguments to collect
    CALL32 %expression                          ; Collect the argument

    LOADI32_EAX &function_call_string_4         ; Using "push_eax\t#_process_expression1\n"
    CALL32 %emit_out                            ; Emit it
    LOADI32_ESI %1                              ; PASSED = 1

:function_call_gen_iter
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
    LOAD8_al_from_EAX                           ; global_token->S[0]
    MOVZX_al                                    ; Make it useful
    CMPI8_EAX !44                               ; IF global_token->S[0] == ","
    JNE32 %function_call_gen_done               ; Otherwise we are done

    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->NEXT
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT

    CALL32 %expression                          ; Collect the argument

    LOADI32_EAX &function_call_string_5         ; Using "push_eax\t#_process_expression2\n"
    CALL32 %emit_out                            ; Emit it
    ADDI8_ESI !1                                ; PASSED = PASSED + 1
    JMP32 %function_call_gen_iter               ; Keep trying

:function_call_gen_done
    ;; All is collected
    LOADI32_EAX &function_call_string_6         ; Using "ERROR in process_expression_list\nNo ) was found\n"
    LOADI32_EBX &close_paren                    ; Using ")"
    CALL32 %require_match                       ; Make sure we have it

    CMPI8_EDX !0                                ; IF(BOOL == TRUE)
    JNE32 %function_call_static                 ; Otherwise it is a static call

    ;; Deal with a passed function pointer
    LOADI32_EAX &function_call_string_7         ; Using "lea_eax,[ebp+DWORD] %"
    CALL32 %emit_out                            ; Emit it

    COPY_ECX_to_EAX                             ; Using S
    CALL32 %emit_out                            ; Emit it

    LOADI32_EAX &function_call_string_8         ; Using "\nmov_eax,[eax]\n"
    CALL32 %emit_out                            ; Emit it

    LOADI32_EAX &function_call_string_9         ; Using "mov_ebp,edi\n"
    CALL32 %emit_out                            ; Emit it

    LOADI32_EAX &function_call_string_10        ; Using "call_eax\n"
    CALL32 %emit_out                            ; Emit it

    LOADI32_EAX &function_call_string_13        ; Using "pop_ebx\t# _process_expression_locals\n"
    JMP32 %function_call_cleanup                ; Clean up

:function_call_static
    ;; Deal with fixed function name
    LOADI32_EAX &function_call_string_9         ; Using "mov_ebp,edi\n"
    CALL32 %emit_out                            ; Emit it

    LOADI32_EAX &function_call_string_11        ; Using "call %FUNCTION_"
    CALL32 %emit_out                            ; Emit it

    COPY_ECX_to_EAX                             ; Using S
    CALL32 %emit_out                            ; Emit it

    LOADI32_EAX &function_call_string_12        ; Using "\n"
    CALL32 %emit_out                            ; Emit it

    LOADI32_EAX &function_call_string_13        ; Using "pop_ebx\t# _process_expression_locals\n"

:function_call_cleanup
    CMPI8_ESI !0                                ; IF PASSED > 0
    JLE32 %function_call_done                   ; Otherwise be done

    ;; The desired string is already in EAX
    CALL32 %emit_out                            ; Emit it

    SUBI8_ESI !1                                ; PASSED = PASSED - 1
    JMP32 %function_call_cleanup                ; Keep going

:function_call_done
    LOADI32_EAX &function_call_string_14        ; Using "pop_ebp\t# Restore old base pointer\n"
    CALL32 %emit_out                            ; Emit it

    LOADI32_EAX &function_call_string_15        ; Using "pop_edi\t# Prevent overwrite\n"
    CALL32 %emit_out                            ; Emit it

    POP_ESI                                     ; Restore ESI
    POP_EDX                                     ; Restore EDX
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

:function_call_string_0  "ERROR in process_expression_list
No ( was found
"
:function_call_string_1  "push_edi  # Prevent overwriting in recursion
"
:function_call_string_2  "push_ebp  # Protect the old base pointer
"
:function_call_string_3  "mov_edi,esp   # Copy new base pointer
"
:function_call_string_4  "push_eax  #_process_expression1
"
:function_call_string_5  "push_eax  #_process_expression2
"
:function_call_string_6  "ERROR in process_expression_list
No ) was found
"
:function_call_string_7  "lea_eax,[ebp+DWORD] %"
:function_call_string_8  "
mov_eax,[eax]
"
:function_call_string_9  "mov_ebp,edi
"
:function_call_string_10 "call_eax
"
:function_call_string_11 "call %FUNCTION_"
:function_call_string_12 "
"
:function_call_string_13 "pop_ebx   # _process_expression_locals
"
:function_call_string_14 "pop_ebp   # Restore old base pointer
"
:function_call_string_15 "pop_edi   # Prevent overwrite
"


;; variable_load function
;; Receives struct token_list* A in EAX
;; Returns nothing
;; Updates output and current_target
;; Uses ECX for A
:variable_load
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    COPY_EAX_to_ECX                             ; Protect A

    LOAD32_Absolute32_ebx &global_token         ; Using global_token
    LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
    LOADI32_EAX &open_paren                     ; Using "("
    CALL32 %match                               ; IF global_token->S == "("
    CMPI8_EAX !0                                ; Then it might be a function
    JNE32 %variable_load_regular                ; Otherwise it is regular

    LOAD32_EBX_from_ECX_Immediate8 !12          ; A->TYPE
    LOAD32_EBX_from_EBX_Immediate8 !24          ; A->TYPE->NAME
    LOADI32_EAX &type_function_name             ; Using "FUNCTION"
    CALL32 %match                               ; IF A->TYPE->NAME == "FUNCTION"
    CMPI8_EAX !0                                ; Then it must be a function
    JNE32 %variable_load_regular                ; otherwise just another regular

    ;; deal with function
    LOAD32_EAX_from_ECX_Immediate8 !16          ; A->DEPTH
    CALL32 %numerate_number                     ; Convert to string
    LOADI32_EBX %0                              ; pass 0 for true
    CALL32 %function_call                       ; Create the function call
    JMP32 %variable_load_done                   ; Be done

:variable_load_regular
    LOAD32_EAX_from_ECX_Immediate8 !12          ; A->TYPE
    STORE32_Absolute32_eax &current_target      ; current_target = A->TYPE

    LOADI32_EAX &variable_load_string_0         ; Using "lea_eax,[ebp+DWORD] %"
    CALL32 %emit_out                            ; Emit it

    LOAD32_EAX_from_ECX_Immediate8 !16          ; A->DEPTH
    CALL32 %numerate_number                     ; Convert to string
    CALL32 %emit_out                            ; Emit it

    LOADI32_EAX &variable_load_string_1         ; Using "\n"
    CALL32 %emit_out                            ; Emit it

    ;; Check for special case of assignment
    LOAD32_Absolute32_ebx &global_token         ; Using global_token
    LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
    LOADI32_EAX &equal                          ; Using "="
    CALL32 %match                               ; IF global_token->S == "="
    CMPI8_EAX !0                                ; Then we skip loading
    JE32 %variable_load_done                    ; And be done

    ;; Deal with common case
    LOADI32_EAX &variable_load_string_2         ; Using "mov_eax,[eax]\n"
    CALL32 %emit_out                            ; Emit it

:variable_load_done
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

:variable_load_string_0  "lea_eax,[ebp+DWORD] %"
:variable_load_string_1  "
"
:variable_load_string_2  "mov_eax,[eax]
"


;; function_load function
;; Receives struct token_list* a in EAX
;; Returns nothing
;; Uses ECX to hold A->S
:function_load
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    LOAD32_EAX_from_EAX_Immediate8 !8           ; A->S
    COPY_EAX_to_ECX                             ; Protect A->S
    LOAD32_Absolute32_ebx &global_token         ; Using global_token
    LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
    LOADI32_EAX &open_paren                     ; Using "("
    CALL32 %match                               ; IF global_token->S == "("
    CMPI8_EAX !0                                ; The we need to do a function call
    JNE32 %function_load_regular                ; Otherwise just load it's address

    ;; Deal with function call
    COPY_ECX_to_EAX                             ; Using A->S
    LOADI32_EBX %1                              ; Using FALSE
    CALL32 %function_call                       ; Deal with it
    JMP32 %function_load_done                   ; Be done

:function_load_regular
    LOADI32_EAX &function_load_string_0         ; Using "mov_eax, &FUNCTION_"
    CALL32 %emit_out                            ; Emit it

    COPY_ECX_to_EAX                             ; Using A->S
    CALL32 %emit_out                            ; Emit it

    LOADI32_EAX &function_load_string_1         ; Using "\n"
    CALL32 %emit_out                            ; Emit it

:function_load_done
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

:function_load_string_0  "mov_eax, &FUNCTION_"
:function_load_string_1  "
"


;; global_load function
;; Receives struct token_list* A in EAX
;; Returns nothing
;; Uses EBX to hold A->S
:global_load
    PUSH_EBX                                    ; Protect EBX
    COPY_EAX_to_EBX                             ; Set as A
    LOAD32_EBX_from_EBX_Immediate8 !8           ; Set as A->S

    LOAD32_EAX_from_EAX_Immediate8 !12          ; A->TYPE
    STORE32_Absolute32_eax &current_target      ; current_target = A->TYPE

    LOADI32_EAX &global_load_string_0           ; Using "mov_eax, &GLOBAL_"
    CALL32 %emit_out                            ; Emit it

    COPY_EBX_to_EAX                             ; Using A->S
    CALL32 %emit_out                            ; Emit it

    LOADI32_EAX &global_load_string_1           ; Using "\n"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_ebx &global_token         ; Using global_token
    LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
    LOADI32_EAX &equal                          ; "="
    CALL32 %match                               ; IF global_token->S == "="
    CMPI8_EAX !0                                ; We need to skip for assignment
    JE32 %global_load_done                      ; and be done

    ;; Otherwise we are loading the contents
    LOADI32_EAX &global_load_string_2           ; Using "mov_eax,[eax]\n"
    CALL32 %emit_out                            ; Emit it

:global_load_done
    POP_EBX                                     ; Restore EBX
    RETURN

:global_load_string_0  "mov_eax, &GLOBAL_"
:global_load_string_1  "
"
:global_load_string_2  "mov_eax,[eax]
"


;; sym_lookup function
;; Receives char* S in EAX and struct token_list* symbol_list in EBX
;; Uses I->S in EAX, S in EBX and I in ECX
;; Returns match or NULL
:sym_lookup
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    COPY_EBX_to_ECX                             ; I = symbol_list
    COPY_EAX_to_EBX                             ; Put S in the right place
:sym_lookup_iter
    CMPI8_ECX !0                                ; IF NULL == I
    JE32 %sym_lookup_done                       ; We failed to find match

    LOAD32_EAX_from_ECX_Immediate8 !8           ; Using I->S
    CALL32 %match                               ; IF I->S == S
    CMPI8_EAX !0                                ; then be done
    JE32 %sym_lookup_done                       ; Failed

    LOAD32_ECX_from_ECX                         ; I = I->NEXT
    JMP32 %sym_lookup_iter                      ; otherwise keep looping

:sym_lookup_done
    COPY_ECX_to_EAX                             ; Return I
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN


;; primary_expr_number function
;; Receives nothing
;; Returns nothing
;; Simply uses current global token to update output and then steps to next global_token
:primary_expr_number
    LOADI32_EAX &primary_expr_number_string_0   ; Using "mov_eax, %"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
    CALL32 %emit_out                            ; Emit it

    LOADI32_EAX &primary_expr_number_string_1   ; Using "\n"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->NEXT
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT
    RETURN

:primary_expr_number_string_0  "mov_eax, %"
:primary_expr_number_string_1  "
"


;; primary_expr_string function
;; receives nothing
;; Returns nothing
;; creates entries for string and calls to generate string output
;; uses ECX for char* number_string
:primary_expr_string
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    LOAD32_Absolute32_ebx &current_count        ; Using current_count
    COPY_EBX_to_EAX                             ; And putting it in the right place
    CALL32 %numerate_number                     ; Get the string
    COPY_EAX_to_ECX                             ; protect number_string

    ADDI8_EBX !1                                ; current_count + 1
    STORE32_Absolute32_ebx &current_count       ; current_count = current_count + 1

    LOADI32_EAX &primary_expr_string_string_0   ; Using "mov_eax, &STRING_"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &function             ; Using function
    LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
    COPY_ECX_to_EBX                             ; Put number_string in the right place
    CALL32 %uniqueID_out                        ; Make it unique

    ;; Generate the target
    LOADI32_EAX &primary_expr_string_string_1   ; Using ":STRING_"
    LOAD32_Absolute32_ebx &strings_list         ; Using strings_list
    CALL32 %emit                                ; Emit it
    COPY_EAX_to_EBX                             ; put new strings_list in place

    LOAD32_Absolute32_eax &function             ; Using function
    LOAD32_EAX_from_EAX_Immediate8 !8           ; function->S
    CALL32 %uniqueID                            ; Make it unique
    COPY_EAX_to_EBX                             ; put new strings_list in place

    ;; Parse the string
    LOAD32_Absolute32_eax &global_token         ; Using global token
    LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
    CALL32 %parse_string                        ; convert to useful form
    CALL32 %emit                                ; Emit it
    STORE32_Absolute32_eax &strings_list        ; Update Strings _list

    LOAD32_Absolute32_eax &global_token         ; Using global token
    LOAD32_EAX_from_EAX                         ; global_token->NEXT
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT

    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

:primary_expr_string_string_0  "mov_eax, &STRING_"
:primary_expr_string_string_1  ":STRING_"


;; primary_expr_char function
;; Receives nothing
;; Returns nothing
;; Updates output_list using global_token
:primary_expr_char
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    LOADI32_EAX &primary_expr_char_string_0     ; Using "mov_eax, %"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &global_token         ; Using global token
    LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
    ADDI8_EAX !1                                ; global_token->S + 1
    CALL32 %escape_lookup                       ; Get the char
    CALL32 %numerate_number                     ; Convert to string
    CALL32 %emit_out                            ; emit it

    LOADI32_EAX &primary_expr_char_string_1     ; Using "\n"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &global_token         ; Using global token
    LOAD32_EAX_from_EAX                         ; global_token->NEXT
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

:primary_expr_char_string_0  "mov_eax, %"
:primary_expr_char_string_1  "
"


;; primary_expr_failure function
;; Receives nothing
;; Does not return but aborts hard
;; Complains about the bad input
:primary_expr_failure
;   CALL32 %line_error                          ; Get line of issue
    LOADI32_EAX %2                              ; Using Standard error
    STORE32_Absolute32_eax &Output_file         ; write to standard error
    LOADI32_EAX &primary_expr_failure_string_0  ; Using "Received "
    CALL32 %File_Print                          ; Print it

    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
    CALL32 %File_Print                          ; Print it

    LOADI32_EAX &primary_expr_failure_string_1  ; Using " in primary_expr\n"
    CALL32 %File_Print                          ; Print it
    JMP32 %Exit_Failure                         ; Abort Hard

:primary_expr_failure_string_0  "Received "
:primary_expr_failure_string_1  " in primary_expr
"


;; general_recursion function
;; Receives FUNCTION F in EAX, char* S in EBX, char* name in ECX and FUNCTION iterate in EDX
;; Returns nothing
;; Uses ECX for char* S, EDX for FUNCTION iterate and EBP for FUNCTION F
;; But generally recurses a shitload
:general_recursion
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    PUSH_EDX                                    ; Protect EDX
    PUSH_EBP                                    ; Protect EBP
    COPY_EAX_to_EBP                             ; Protect F
    COPY_ECX_to_EAX                             ; Put name in the right place
    COPY_EBX_to_ECX                             ; Protect S

    LOAD32_Absolute32_ebx &global_token         ; Using global_token
    LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
    CALL32 %match                               ; IF match(name, global_token->s)
    CMPI8_EAX !0                                ; If true we do
    JNE32 %general_recursion_done               ; Otherwise skip it

    ;; Deal with the recursion
    COPY_EBP_to_EAX                             ; Put F in the right place
    CALL32 %common_recursion                    ; Recurse

    COPY_ECX_to_EAX                             ; Put S in the right place
    CALL32 %emit_out                            ; Emit it

    COPY_EDX_to_EAX                             ; Put iterate in the right place
    CALL_EAX                                    ; Down the rabbit hole

:general_recursion_done
    POP_EBP                                     ; Restore EBP
    POP_EDX                                     ; Restore EDX
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN


;; promote_type function
;; Receives struct type* a in EAX and struct type* b in EBX
;; Returns the most recent type in EAX
;; Uses EAX for struct type* I, ECX for struct type* A and EDX for struct type* B
:promote_type
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    PUSH_EDX                                    ; Protect EDX
    CMPI8_EBX !0                                ; IF NULL == B
    JE32 %promote_type_done                     ; Just return A

    COPY_EAX_to_ECX                             ; Put A in place
    COPY_EBX_to_EDX                             ; Put B in place
    COPY_EBX_to_EAX                             ; IF NULL == A
    CMPI8_ECX !0                                ; Then we just return B
    JE32 %promote_type_done                     ; Be done

    ;; Looks like we need to walk the list
    LOAD32_ECX_from_ECX_Immediate8 !24          ; A->NAME
    LOAD32_EDX_from_EDX_Immediate8 !24          ; B->NAME
    LOAD32_Absolute32_eax &global_types         ; I = global_types
:promote_type_iter
    CMPI8_EAX !0                                ; IF NULL == I
    JE32 %promote_type_done                     ; Just be done

    LOAD32_EBX_from_EAX_Immediate8 !24          ; I->NAME
    CMP_ECX_EBX                                 ; IF(A->NAME == I->NAME)
    JE32 %promote_type_done                     ; Be done

    CMP_EBX_EDX                                 ; IF(B->NAME == I->NAME)
    JE32 %promote_type_done                     ; Be done

    LOAD32_EBX_from_EAX_Immediate8 !12          ; I->INDIRECT
    LOAD32_EBX_from_EBX_Immediate8 !24          ; I->INDIRECT->NAME

    CMP_ECX_EBX                                 ; IF(A->NAME == I->INDIRECT->NAME)
    JE32 %promote_type_done                     ; Be done

    CMP_EBX_EDX                                 ; IF(B->NAME == I->INDIRECT->NAME)
    JE32 %promote_type_done                     ; Be done

    LOAD32_EAX_from_EAX                         ; I = I->NEXT
    JMP32 %promote_type_iter                    ; Keep going

:promote_type_done
    POP_EDX                                     ; Restore EDX
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN


;; common_recursion function
;; Receives FUNCTION F in EAX
;; Returns Nothing
;; Walks global_token list and update output_list
;; Updates current_target
;; Uses EBX to hold FUNCTION F and struct type* last_type
:common_recursion
    PUSH_EBX                                    ; Protect EBX
    COPY_EAX_to_EBX                             ; Put FUNCTION F safely out of the way
    LOADI32_EAX &common_recursion_string_0      ; Using "push_eax\t#_common_recursion\n"
    CALL32 %emit_out                            ; Emit it

    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->NEXT
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT

    COPY_EBX_to_EAX                             ; Prepare for function call
    LOAD32_Absolute32_ebx &current_target       ; Get last type
    CALL_EAX                                    ; F();
    LOAD32_Absolute32_eax &current_target       ; Get current_target
    CALL32 %promote_type                        ; get the right type
    STORE32_Absolute32_eax &current_target      ; Set new current_target

    LOADI32_EAX &common_recursion_string_1      ; Using "pop_ebx\t# _common_recursion\n"
    CALL32 %emit_out                            ; Emit it
    POP_EBX                                     ; Restore EBX
    RETURN

:common_recursion_string_0  "push_eax   #_common_recursion
"
:common_recursion_string_1  "pop_ebx    # _common_recursion
"


;; require_match function
;; Receives char* message in EAX and char* required in EBX
;; Returns nothing
;; Uses ECX to hold message and updates global_token
:require_match
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    COPY_EAX_to_ECX                             ; put the message somewhere safe
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
    CALL32 %match                               ; IF required == global_token->S
    CMPI8_EAX !0                                ; we are fine
    JE32 %require_match_good                    ; otherwise pain

    ;; Deal will bad times
;   CALL32 %line_error                          ; Tell user what went wrong
    LOADI32_EAX %2                              ; Using standard error
    STORE32_Absolute32_eax &Output_file         ; write to standard error
    COPY_ECX_to_EAX                             ; using our message
    CALL32 %File_Print                          ; Print it
    JMP32 %Exit_Failure                         ; Abort HARD

:require_match_good
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->next
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->next
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN


;; uniqueID Function
;; Receives char *S in EAX, struct token_list* l in EBX and char* num in ECX
;; Returns updated struct token_list* L in EAX
:uniqueID
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    CALL32 %emit                                ; emit(s, l)
    COPY_EAX_to_EBX                             ; Put L in correct place
    LOADI32_EAX &underline                      ; Using "_"
    CALL32 %emit                                ; emit("_", l)
    COPY_EAX_to_EBX                             ; Put L in correct place
    COPY_ECX_to_EAX                             ; Put num in correct place
    CALL32 %emit                                ; emit(num, l)
    COPY_EAX_to_EBX                             ; Put L in correct place
    LOADI32_EAX &uniqueID_string_0              ; Using "\n"
    CALL32 %emit                                ; emit("\n", l)
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

:uniqueID_string_0  "
"


;; uniqueID_out function
;; Receives char* S in EAX and char* num in EBX
;; Returns nothing
:uniqueID_out
    PUSH_EAX                                    ; Protect EAX
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    COPY_EBX_to_ECX                             ; Put num in right spot
    LOAD32_Absolute32_ebx &output_list          ; Using output_list
    CALL32 %uniqueID                            ; Get updated list
    STORE32_Absolute32_eax &output_list         ; output_list = uniqueID(s, output_list, num)
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    POP_EAX                                     ; Restore EAX
    RETURN


;; emit_out function
;; Receives char* S in EAX
;; Returns nothing
;; Updates output_list
;; MUST NOT ALTER REGISTERS
:emit_out
    PUSH_EAX                                    ; Protect EAX
    PUSH_EBX                                    ; Protect EBX
    LOAD32_Absolute32_ebx &output_list          ; Using output_list
    CALL32 %emit                                ; emit it
    STORE32_Absolute32_eax &output_list         ; update it
    POP_EBX                                     ; Restore EBX
    POP_EAX                                     ; Restore EAX
    RETURN


;; emit function
;; Receives char *s in EAX and struct token_list* head in EBX
;; Returns struct token_list* T in EAX
:emit
    PUSH_ECX                                    ; Protect ECX
    COPY_EAX_to_ECX                             ; put S out of the way
    LOADI32_EAX %20                             ; sizeof(struct token_list)
    CALL32 %malloc                              ; get T
    STORE32_EBX_into_EAX                        ; t->next = head;
    STORE32_ECX_into_EAX_Immediate8 !8          ; t->s = s;
    POP_ECX                                     ; Restore ECX
    RETURN


;; escape_lookup function
;; Receives char* c in EAX
;; Returns integer value of char in EAX
;; Aborts hard if unknown escape is received
;; Uses ECX to hold char* C
:escape_lookup
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    COPY_EAX_to_ECX                             ; Put char* C in safe place
    LOAD8_al_from_ECX                           ; Load c[0]
    MOVZX_al                                    ; make it useful
    CMPI8_EAX !92                               ; If '\\' != c[0]
    JNE32 %escape_lookup_done                   ; Be done

    COPY_ECX_to_EBX                             ; Prepare for walk
    ADDI8_EBX !1                                ; increment
    LOAD8_bl_from_EBX                           ; load c[1]
    MOVZX_bl                                    ; make it useful

    CMPI8_EBX !120                              ; Check if \x??
    JE32 %escape_lookup_hex                     ; Deal with hex

    ;; Deal with \? escapes
    LOADI32_EAX %10                             ; Guess "\n"
    CMPI8_EBX !110                              ; If n
    JE32 %escape_lookup_done                    ; Be done

    LOADI32_EAX %9                              ; Guess "\t"
    CMPI8_EBX !116                              ; If t
    JE32 %escape_lookup_done                    ; Be done

    COPY_EBX_to_EAX                             ; "\\", "'" and '\"' all encode as themselves
    CMPI8_EBX !92                               ; If "\\"
    JE32 %escape_lookup_done                    ; Be done
    CMPI8_EBX !39                               ; IF "'"
    JE32 %escape_lookup_done                    ; Be done
    CMPI8_EBX !34                               ; IF '\"'
    JE32 %escape_lookup_done                    ; Be done

    LOADI32_EAX %13                             ; Guess "\r"
    CMPI8_EBX !114                              ; IF r
    JE32 %escape_lookup_done                    ; Be done

    ;; Looks like we have no clue what we are doing
    ;; Aborting hard
    LOADI32_EAX %2                              ; Using Standard error
    STORE32_Absolute32_eax &Output_file         ; write to standard error
    LOADI32_EAX &escape_lookup_string_0         ; Using "Unknown escape received: "
    CALL32 %File_Print                          ; Print it
    COPY_ECX_to_EAX                             ; Using C
    CALL32 %File_Print                          ; Print it
    LOADI32_EAX &escape_lookup_string_1         ; Using " Unable to process\n"
    CALL32 %File_Print                          ; Print it
    JMP32 %Exit_Failure                         ; Abort Hard

:escape_lookup_done
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

:escape_lookup_hex
    ;; Give up on C and just assume they know what they are doing
    ADDI8_ECX !2                                ; increment
    LOAD8_al_from_ECX                           ; c[2]
    MOVZX_al                                    ; make it useful
    ADDI8_ECX !1                                ; increment
    CALL32 %char2hex                            ; Get the hex value
    SALI8_EAX !4                                ; c << 4
    LOAD8_bl_from_ECX                           ; c[3]
    MOVZX_bl                                    ; make it useful
    SWAP_EAX_EBX                                ; protect c << 4
    CALL32 %char2hex                            ; Get the hex value
    ADD_ebx_into_eax                            ; hex(c[2]) << 4 + hex(c[3])
    JMP32 %escape_lookup_done                   ; Be done

:escape_lookup_string_0  "Unknown escape received: "
:escape_lookup_string_1  " Unable to process
"


;; char2hex function
;; Receives char in EAX
;; Returns hex or aborts hard
:char2hex
    SUBI8_EAX !48                               ; Try 0-9
    CMPI8_EAX !10                               ; Otherwise fun times
    JL32 %char2hex_done                         ; Be done

    ;; Deal with A-F
    ANDI32_EAX %0xDF                            ; Unset High bit turning a-f into A-F
    SUBI8_EAX !7                                ; Shift down into position
    CMPI8_EAX !10                               ; Everything below A is bad
    JL32 %char2hex_fail                         ; And should fail
    CMPI8_EAX !16                               ; Make sure we are below F
    JL32 %char2hex_done                         ; If so be done

:char2hex_fail
    ;; Time to fail hard
    LOADI32_EAX %2                              ; Using Standard error
    STORE32_Absolute32_eax &Output_file         ; write to standard error
    LOADI32_EAX &char2hex_string_0              ; Using "Tried to print non-hex number\n"
    CALL32 %File_Print                          ; Print it
    JMP32 %Exit_Failure                         ; Abort Hard

:char2hex_done
    RETURN

:char2hex_string_0  "Tried to print non-hex number
"


;; parse_string function
;; Receives char* string in EAX
;; Returns cleaned up string
;; Protects char* string in EBX
:parse_string
    PUSH_EBX                                    ; Protect EBX
    COPY_EAX_to_EBX                             ; Protect char* string
    CALL32 %weird                               ; Determine if we have a weird string
    CMPI8_EAX !0                                ; If weird
    JE32 %parse_string_weird                    ; Deal with it

    ;; Dealing with regular string
    COPY_EBX_to_EAX                             ; Passing Char* string
    CALL32 %collect_regular_string              ; Collect it
    JMP32 %parse_string_done                    ; Be done

:parse_string_weird
    COPY_EBX_to_EAX                             ; Passing Char* string
    CALL32 %collect_weird_string                ; Collect it

:parse_string_done
    POP_EBX                                     ; Restore EBX
    RETURN


;; weird function
;; Receives char* string in EAX
;; Returns true(0) or false(1) in EAX
;; Uses ECX to hold char* string
:weird
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    COPY_EAX_to_ECX                             ; Place string in safe place
    ADDI8_ECX !1                                ; increment past the '\"'
:weird_reset
    LOAD8_al_from_ECX                           ; Load a char
    MOVZX_al                                    ; Make it useful
    CMPI8_EAX !0                                ; IF NULL == C
    JE32 %weird_false                           ; Nothing weird found

    CMPI8_EAX !92                               ; IF '\\'
    JNE32 %weird_escaped                        ; Deal with escaping

    ;; Deal with escape
    COPY_ECX_to_EAX                             ; We are passing the string
    CALL32 %escape_lookup                       ; to look it up

    ADDI8_ECX !1                                ; string = string + 1
    LOAD8_bl_from_ECX                           ; get string[1]
    MOVZX_bl                                    ; make it useful
    CMPI8_EBX !120                              ; IF 'x' == string[1]
    JNE32 %weird_escaped                        ; otherwise skip the gap

    ADDI8_ECX !2                                ; string = string + 2

:weird_escaped
    PUSH_EAX                                    ; Protect C in case we need it
    LOADI32_EBX &weird_string_0                 ; Use "\t\n !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
    CALL32 %In_Set                              ; To find if weird
    CMPI8_EAX !1                                ; IF TRUE
    POP_EAX                                     ; Restore C
    JNE32 %weird_true                           ; Then not weird

    ADDI8_ECX !1                                ; string = string + 1

    ;; Last chance for weird
    LOADI32_EBX &weird_string_1                 ; Use "\t\n\r "
    CALL32 %In_Set                              ; Check for special case
    CMPI8_EAX !1                                ; IF TRUE
    JNE32 %weird_reset                          ; Otherwise not in the special case

    ;; Deal with possible special case
    LOAD8_al_from_ECX                           ; Load string[1]
    MOVZX_al                                    ; Make it useful
    CMPI8_EAX !58                               ; IF string[1] == ":"
    JE32 %weird_true                            ; Then we hit the special case
    JMP32 %weird_reset                          ; Keep trying

:weird_done
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

:weird_true
    LOADI32_EAX %0                              ; Return true
    JMP32 %weird_done                           ; Be done

:weird_false
    LOADI32_EAX %1                              ; Return false
    JMP32 %weird_done                           ; Be done

:weird_string_0  "  
 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
:weird_string_1  '09 0A 0D 20' ; "\t\n\r "


;; collect_regular_string function
;; Receives char* string in EAX
;; Malloc and creates new string to return in EAX
;; Uses ECX for return string and EDX for passed string
:collect_regular_string
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    PUSH_EDX                                    ; Protect EDX
    COPY_EAX_to_EDX                             ; Protect our passed string
    LOADI32_EAX %256                            ; We need 256bytes of storage
    CALL32 %malloc                              ; Get our new pointer
    COPY_EAX_to_ECX                             ; put it in place
    PUSH_EAX                                    ; protect until done
:collect_regular_string_reset
    LOAD8_al_from_EDX                           ; string[0]
    MOVZX_al                                    ; Make it useful
    CMPI8_EAX !0                                ; See if we hit the end
    JE32 %collect_regular_string_done           ; And be done

    CMPI8_EAX !92                               ; IF string[0] == '\\'
    JE32 %collect_regular_string_escaped        ; Deal with that mess

    ;; deal with boring char
    STORE8_al_into_Address_ECX                  ; hold_string[index] = string[0]
    ADDI8_ECX !1                                ; Increment it
    ADDI8_EDX !1                                ; Increment it
    JMP32 %collect_regular_string_reset         ; And keep going

:collect_regular_string_escaped
    COPY_EDX_to_EAX                             ; Using string
    CALL32 %escape_lookup                       ; Get the char
    STORE8_al_into_Address_ECX                  ; hold_string[index] = escape_lookup(string)
    ADDI8_EDX !1                                ; Increment it
    ADDI8_ECX !1                                ; Increment it
    LOAD8_al_from_EDX                           ; string[0]
    MOVZX_al                                    ; Make it useful
    ADDI8_EDX !1                                ; Increment it
    CMPI8_EAX !120                              ; IF 'x' == string[1]
    JNE32 %collect_regular_string_reset         ; Otherwise keep going

    ADDI8_EDX !2                                ; Increment it
    JMP32 %collect_regular_string_reset         ; Keep going

:collect_regular_string_done
    LOADI32_EAX %34                             ; Using '\"'
    STORE8_al_into_Address_ECX                  ; hold_string[index] = '\"'
    ADDI8_ECX !1                                ; Increment it
    LOADI32_EAX %10                             ; Using "\n"
    STORE8_al_into_Address_ECX                  ; hold_string[index] = '\n'
    POP_EAX                                     ; Return our new string
    POP_EDX                                     ; Restore EDX
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN


;; collect_weird_string function
;; Receives char* string in EAX
;; Mallocs and returns char* hold in EAX
;; Uses ECX for char* hold and EDX for char* string
:collect_weird_string
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    PUSH_EDX                                    ; Protect EDX
    COPY_EAX_to_EDX                             ; Protect our passed string
    LOADI32_EAX %512                            ; We need 512bytes of storage
    CALL32 %malloc                              ; Get our new pointer
    COPY_EAX_to_ECX                             ; put it in place
    PUSH_EAX                                    ; protect until done

    LOADI32_EAX %39                             ; Using "'"
    STORE8_al_into_Address_ECX                  ; hold_string[index] = "'"
    ADDI8_ECX !1                                ; Increment it
    ADDI8_EDX !1                                ; Increment it
:collect_weird_string_reset
    LOAD8_al_from_EDX                           ; Read a byte
    MOVZX_al                                    ; Make it useful
    CMPI8_EAX !0                                ; IF NULL == string[0]
    JE32 %collect_weird_string_done             ; Be done

    LOADI32_EAX %32                             ; Using ' '
    STORE8_al_into_Address_ECX                  ; hold_string[index] = ' '
    ADDI8_ECX !1                                ; Increment it

    COPY_EDX_to_EAX                             ; Using string
    CALL32 %escape_lookup                       ; Get the char
    CALL32 %hex8                                ; Update ECX

    LOAD8_al_from_EDX                           ; Read a byte
    MOVZX_al                                    ; Make it useful
    ADDI8_EDX !1                                ; Increment it
    CMPI8_EAX !92                               ; IF string[0] == '\\'
    JNE32 %collect_weird_string_reset           ; Otherwise keep going

    LOAD8_al_from_EDX                           ; Read a byte
    MOVZX_al                                    ; Make it useful
    ADDI8_EDX !1                                ; Increment it
    CMPI8_EAX !120                              ; IF 'x' == string[1]
    JNE32 %collect_weird_string_reset           ; Otherwise keep going

    ADDI8_EDX !2                                ; Increment it
    JMP32 %collect_weird_string_reset           ; Keep going

:collect_weird_string_done
    LOADI32_EAX %32                             ; Using ' '
    STORE8_al_into_Address_ECX                  ; hold_string[index] = ' '
    ADDI8_ECX !1                                ; Increment it
    LOADI32_EAX %48                             ; Using '0'
    STORE8_al_into_Address_ECX                  ; hold_string[index] = '0'
    ADDI8_ECX !1                                ; Increment it
    STORE8_al_into_Address_ECX                  ; hold_string[index] = '0'
    ADDI8_ECX !1                                ; Increment it
    LOADI32_EAX %39                             ; Using "'"
    STORE8_al_into_Address_ECX                  ; hold_string[index] = "'"
    ADDI8_ECX !1                                ; Increment it
    LOADI32_EAX %10                             ; Using "\n"
    STORE8_al_into_Address_ECX                  ; hold_string[index] = '\n'
    POP_EAX                                     ; Return our new string
    POP_EDX                                     ; Restore EDX
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN


;; HEX to ascii routine
;; Receives INT in EAX and CHAR* in ECX
;; Stores ascii of INT in CHAR*
;; Returns only modifying EAX and ECX
:hex8
    PUSH_EAX                                    ; Protect bottom nibble
    SHRI8_EAX !4                                ; do high nibble first
    CALL32 %hex4                                ; Store it
    POP_EAX                                     ; do low nibble
:hex4
    ANDI32_EAX %0xF                             ; isolate nibble
    ADDI8_EAX !48                               ; convert to ascii
    CMPI8_EAX !57                               ; valid digit?
    JBE8 !hex1                                  ; yes
    ADDI8_EAX !7                                ; use alpha range
:hex1
    STORE8_al_into_Address_ECX                  ; store result
    ADDI8_ECX !1                                ; next position
    RETURN


;; type_name function
;; Receives nothing
;; Returns type_size in EAX
;; Uses ECX for STRUCT TYPE* RET
:type_name
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    LOAD32_Absolute32_ebx &global_token         ; Using global_token
    LOAD32_EBX_from_EBX_Immediate8 !8           ; global_token->S
    LOADI32_EAX &struct                         ; Using "struct"
    CALL32 %match                               ; IF global_token->S == "struct"
    COPY_EAX_to_ECX                             ; Protect structure
    CMPI8_EAX !0                                ; need to skip over "struct"
    JNE32 %type_name_native                     ; otherwise keep going

    ;; Deal with possible STRUCTs
    LOAD32_Absolute32_ebx &global_token         ; Using global_token
    LOAD32_EBX_from_EBX                         ; global_token->next
    STORE32_Absolute32_ebx &global_token        ; global_token = global_token->next
    LOAD32_EAX_from_EBX_Immediate8 !8           ; global_token->S
    LOAD32_Absolute32_ebx &global_types         ; get all known types
    CALL32 %lookup_type                         ; Find type if possible
    COPY_EAX_to_ECX                             ; Set ret

    CMPI8_EAX !0                                ; IF NULL == ret
    JNE32 %type_name_common                     ; We have to create struct

    ;; Create a struct
    CALL32 %create_struct                       ; Create a new struct
    LOADI32_ECX %0                              ; We wish to return NULL
    JMP32 %type_name_done                       ; be done

:type_name_native
    ;; Deal only with native types
    COPY_EBX_to_EAX                             ; Put global_token->S in the right place
    LOAD32_Absolute32_ebx &global_types         ; get all known types
    CALL32 %lookup_type                         ; Find the type if possible
    COPY_EAX_to_ECX                             ; Set ret

    CMPI8_EAX !0                                ; IF NULL == ret
    JNE32 %type_name_common                     ; We need to abort hard

    ;; Aborting hard
    LOADI32_EAX %2                              ; Using Standard error
    STORE32_Absolute32_eax &Output_file         ; write to standard error
    LOADI32_EAX &type_name_string_0             ; Print header
    CALL32 %File_Print                          ; Print it

    LOAD32_Absolute32_eax &global_token         ; Using global token
    LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
    CALL32 %File_Print                          ; Print it

    LOADI32_EAX &type_name_string_1             ; Print footer
    CALL32 %File_Print                          ; Print it

;   CALL32 %line_error                          ; Give details
    JMP32 %Exit_Failure                         ; Abort

:type_name_common
    LOAD32_Absolute32_ebx &global_token         ; Using global_token
    LOAD32_EBX_from_EBX                         ; global_token->next
    STORE32_Absolute32_ebx &global_token        ; global_token = global_token->next

:type_name_iter
    LOAD32_EAX_from_EBX_Immediate8 !8           ; global_token->S
    LOAD8_al_from_EAX                           ; global_token->S[0]
    MOVZX_al                                    ; make it useful
    CMPI8_EAX !42                               ; IF global_token->S[0] == '*'
    JNE32 %type_name_done                       ; recurse

    ;; Deal with char**
    LOAD32_ECX_from_ECX_Immediate8 !12          ; ret = ret->indirect
    LOAD32_Absolute32_ebx &global_token         ; Using global_token
    LOAD32_EBX_from_EBX                         ; global_token->next
    STORE32_Absolute32_ebx &global_token        ; global_token = global_token->next
    JMP32 %type_name_iter                       ; keep looping

:type_name_done
    COPY_ECX_to_EAX                             ; put ret in the right place
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

:type_name_string_0  "Unknown type "
:type_name_string_1  "
"


;; lookup_type function
;; Receives char* s in EAX and struct type* start in EBX
;; Returns struct type* in EAX
;; Uses EBX for S and ECX for I
:lookup_type
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    COPY_EBX_to_ECX                             ; I = Start
    COPY_EAX_to_EBX                             ; Put S in place
:lookup_type_iter
    CMPI8_ECX !0                                ; Check if I == NULL
    JE32 %lookup_type_done                      ; return NULL

    LOAD32_EAX_from_ECX_Immediate8 !24          ; I->NAME
    CALL32 %match                               ; Check if matching
    CMPI8_EAX !0                                ; IF I->NAME == S
    JE32 %lookup_type_done                      ; return it

    LOAD32_ECX_from_ECX                         ; Otherwise I = I->NEXT
    JMP32 %lookup_type_iter                     ; And keep looping

:lookup_type_done
    COPY_ECX_to_EAX                             ; return either I or NULL
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN


;; create_struct function
;; Receives nothing
;; Returns nothing
;; Uses global_token to malloc a struct's definition
;; Uses ECX for int OFFSET, EDX for struct type* head, EBP for struct type* I,
;; EDI for member_size (Which is passed) and ESI for LAST
;; EAX and EBX are used for scratch
:create_struct
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    PUSH_EDX                                    ; Protect EDX
    PUSH_EBP                                    ; Protect EBP
    PUSH_EDI                                    ; Protect EDI
    PUSH_ESI                                    ; Protect ESI
    LOADI32_ECX %0                              ; OFFSET = 0
    LOADI32_EDI %0                              ; member_size = 0

    LOADI32_EAX %28                             ; sizeof(struct type)
    CALL32 %malloc                              ; malloc(sizeof(struct type))
    COPY_EAX_to_EDX                             ; Set HEAD

    LOADI32_EAX %28                             ; sizeof(struct type)
    CALL32 %malloc                              ; malloc(sizeof(struct type))
    COPY_EAX_to_EBP                             ; Set I

    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
    STORE32_EAX_into_EDX_Immediate8 !24         ; HEAD->NAME = global_token->S
    STORE32_EAX_into_EBP_Immediate8 !24         ; I->NAME = global_token->S

    STORE32_EBP_into_EDX_Immediate8 !12         ; HEAD->INDIRECT = I
    STORE32_EDX_into_EBP_Immediate8 !12         ; I->INDIRECT = HEAD

    LOAD32_Absolute32_eax &global_types         ; Using global_types
    STORE32_EAX_into_EDX                        ; HEAD->NEXT = global_types
    STORE32_Absolute32_edx &global_types        ; global_types = HEAD

    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->NEXT
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT

    LOADI32_EAX %4                              ; Using register size
    STORE32_EAX_into_EBP_Immediate8 !4          ; I->SIZE = register size

    LOADI32_EAX &create_struct_string_0         ; Using "ERROR in create_struct\n Missing {\n"
    LOADI32_EBX &open_curly_brace               ; Using "{"
    CALL32 %require_match                       ; Make sure we have it

    LOADI32_ESI %0                              ; LAST = NULL

:create_struct_iter
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
    LOAD8_al_from_EAX                           ; global_token->S[0]
    MOVZX_al                                    ; Make it useful
    CMPI8_EAX !125                              ; IF global_token->S[0] == "}"
    JE32 %create_struct_done                    ; be done

    ;; Looks like we are adding members
    ;; Lets see if it is a union
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
    LOADI32_EBX &union                          ; Using "union"
    CALL32 %match                               ; IF match(global_token->s, "union")
    CMPI8_EAX !0                                ; Deal with union
    JNE32 %create_struct_single                 ; Otherwise deal with singles

    ;; Deal with union
    COPY_ESI_to_EAX                             ; Put last in right place
    COPY_ECX_to_EBX                             ; put offset in right place
    CALL32 %build_union                         ; ASSEMBLE
    COPY_EAX_to_ESI                             ; last = build_union(last, offset)
    ADD_edi_into_ecx                            ; offset = offset + member_size

    LOADI32_EAX &create_struct_string_1         ; Using "ERROR in create_struct\n Missing ;\n"
    LOADI32_EBX &semicolon                      ; Using ";"
    CALL32 %require_match                       ; Make sure we have it
    JMP32 %create_struct_iter                   ; keep going

:create_struct_single
    ;; deal with singles
    COPY_ESI_to_EAX                             ; Put last in right place
    COPY_ECX_to_EBX                             ; put offset in right place
    CALL32 %build_member                        ; ASSEMBLE
    COPY_EAX_to_ESI                             ; last = build_union(last, offset)
    ADD_edi_into_ecx                            ; offset = offset + member_size

    LOADI32_EAX &create_struct_string_1         ; Using "ERROR in create_struct\n Missing ;\n"
    LOADI32_EBX &semicolon                      ; Using ";"
    CALL32 %require_match                       ; Make sure we have it
    JMP32 %create_struct_iter                   ; keep going

:create_struct_done
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->NEXT
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT

    LOADI32_EAX &create_struct_string_1         ; Using "ERROR in create_struct\n Missing ;\n"
    LOADI32_EBX &semicolon                      ; Using ";"
    CALL32 %require_match                       ; Make sure we have it

    STORE32_ECX_into_EDX_Immediate8 !4          ; HEAD->SIZE = OFFSET
    STORE32_ESI_into_EDX_Immedate8 !16          ; HEAD->MEMBERS = LAST
    STORE32_ESI_into_EBP_Immedate8 !16          ; I->MEMBERS = LAST

    POP_ESI                                     ; Restore ESI
    POP_EDI                                     ; Restore EDI
    POP_EBP                                     ; Restore EBP
    POP_EDX                                     ; Restore EDX
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

:create_struct_string_0  "ERROR in create_struct
 Missing {
"
:create_struct_string_1  "ERROR in create_struct
 Missing ;
"


;; lookup_member function
;; Receives struct type* parent in EAX and char* name in EBX
;; Returns struct type* I in EAX
;; Uses char* NAME in EBX, ECX for struct type* I and EDX to hold parent for errors
;; Aborts hard if not found
:lookup_member
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    PUSH_EDX                                    ; Protect EDX
    COPY_EAX_to_EDX                             ; Protect Parent
    LOAD32_ECX_from_EAX_Immediate8 !16          ; struct type* I = parent->MEMBERS
:lookup_member_iter
    CMPI8_ECX !0                                ; IF I == NULL
    JE32 %lookup_member_fail                    ; Abort HARD

    LOAD32_EAX_from_ECX_Immediate8 !24          ; Using I->NAME
    CALL32 %match                               ; IF I->NAME == NAME
    CMPI8_EAX !0                                ; Then we have found the member
    COPY_ECX_to_EAX                             ; Prepare for return
    LOAD32_ECX_from_ECX_Immediate8 !16          ; Prepare for loop I = I->MEMBERS
    JNE32 %lookup_member_iter                   ; Looks like we are looping

    ;; I is already in EAX
    POP_EDX                                     ; Restore EDX
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

:lookup_member_fail
    LOADI32_EAX %2                              ; Using Standard error
    STORE32_Absolute32_eax &Output_file         ; write to standard error
    LOADI32_EAX &lookup_member_string_0         ; Using "ERROR in lookup_member "
    CALL32 %File_Print                          ; print it

    LOAD32_EAX_from_EDX_Immediate8 !24          ; PARENT->NAME
    CALL32 %File_Print                          ; print it

    LOADI32_EAX &arrow_string                   ; Using "->"
    CALL32 %File_Print                          ; print it

    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
    CALL32 %File_Print                          ; print it

    LOADI32_EAX &lookup_member_string_1         ; Using " does not exist\n"
    CALL32 %File_Print                          ; print it

;   CALL32 %line_error                          ; Write useful debug info

    LOADI32_EAX &lookup_member_string_2         ; Using "\n"
    CALL32 %File_Print                          ; print it
    JMP32 %Exit_Failure                         ; Abort Hard

:lookup_member_string_0  "ERROR in lookup_member "
:lookup_member_string_1  " does not exist
"
:lookup_member_string_2  "
"


;; build_member function
;; Receives struct type* last in EAX, int offset in EBX and global member_size in EDI
;; Updates member_size in EDI and returns struct type* I in EAX
;; Uses ECX for struct type* member_type and EDX for struct type* I
:build_member
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    PUSH_EDX                                    ; Protect EDX
    COPY_EAX_to_EDX                             ; Put last out of the way
    LOADI32_EAX %28                             ; Allocate type
    CALL32 %malloc                              ; Get I
    STORE32_EDX_into_EAX_Immediate8 !16         ; I->MEMBERS = LAST
    STORE32_EBX_into_EAX_Immediate8 !8          ; I->OFFSET = OFFSET
    COPY_EAX_to_EDX                             ; Put I in place

    CALL32 %type_name                           ; Get member_type
    COPY_EAX_to_ECX                             ; Put in place
    STORE32_ECX_into_EDX_Immediate8 !20         ; I->TYPE = MEMBER_TYPE
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EBX_from_EAX_Immediate8 !8           ; global_token->S
    STORE32_EBX_into_EDX_Immediate8 !24         ; I->NAME = global_token->S
    LOAD32_EAX_from_EAX                         ; global_token->NEXT
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT

    ;; Check if we have an array
    LOAD32_EBX_from_EAX_Immediate8 !8           ; global_token->S
    LOADI32_EAX &open_bracket                   ; Using "["
    CALL32 %match                               ; IF global_token->S == "["
    CMPI8_EAX !0                                ; Then we have to deal with arrays in our structs
    JE32 %build_member_array                    ; So deal with that pain

    ;; Deal with non-array case
    LOAD32_EAX_from_ECX_Immediate8 !4           ; member_type->SIZE
    STORE32_EAX_into_EDX_Immediate8 !4          ; I->SIZE = member_type->SIZE
    JMP32 %build_member_done                    ; Be done

:build_member_array
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->NEXT
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT

    LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
    CALL32 %numerate_string                     ; convert number
    LOAD32_EBX_from_ECX_Immediate8 !20          ; member_type->TYPE
    LOAD32_EBX_from_EBX_Immediate8 !4           ; member_type->TYPE->SIZE
    IMUL_EAX_by_EBX                             ; member_type->type->size * numerate_string(global_token->s)
    STORE32_EAX_into_EDX_Immediate8 !4          ; I->SIZE = member_type->type->size * numerate_string(global_token->s)

    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->NEXT
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT

    LOADI32_EAX &build_member_string_0          ; Using "Struct only supports [num] form\n"
    LOADI32_EBX &close_bracket                  ; Using "]"
    CALL32 %require_match                       ; Make sure we have it

:build_member_done
    LOAD32_EDI_from_EDX_Immediate8 !4           ; MEMBER_SIZE = I->SIZE
    STORE32_ECX_into_EDX_Immediate8 !20         ; I->TYPE = MEMBER_TYPE
    COPY_EDX_to_EAX                             ; Return I

    POP_EDX                                     ; Restore EDX
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

:build_member_string_0  "Struct only supports [num] form
"


;; build_union function
;; Receives struct type* last in EAX, int offset in EBX and global member_size in EDI
;; Updates member_size in EDI and returns struct type* LAST in EAX
;; Uses ECX for struct type* last, EDX for int offset, ESI for int size and EDI for int member_size
:build_union
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    PUSH_EDX                                    ; Protect EDX
    PUSH_ESI                                    ; Protect ESI
    COPY_EAX_to_ECX                             ; Put LAST in right spot
    COPY_EBX_to_EDX                             ; Put OFFSET in right spot
    LOADI32_ESI %0                              ; SIZE = 0

    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->NEXT
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT

    LOADI32_EAX &build_union_string_0           ; Using "ERROR in build_union\nMissing {\n"
    LOADI32_EBX &open_curly_brace               ; Using "{"
    CALL32 %require_match                       ; Make sure we have it

:build_union_iter
    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX_Immediate8 !8           ; global_token->S
    LOAD8_al_from_EAX                           ; global_token->S[0]
    MOVZX_al                                    ; make it useful
    CMPI8_EAX !125                              ; IF global_token->S[0] == "}"
    JE32 %build_union_done                      ; Be done

    ;; Collect union member
    COPY_ECX_to_EAX                             ; Passing LAST
    COPY_EDX_to_EBX                             ; Passing offset
    CALL32 %build_member                        ; build_member(last, offset)
    COPY_EAX_to_ECX                             ; last = build_member(last, offset)

    CMP_EDI_ESI                                 ; IF member_size > size
    JG32 %build_union_size                      ; Then update size

    ;; deal with member_size > size
    COPY_EDI_to_ESI                             ; SIZE = MEMBER_SIZE

:build_union_size
    LOADI32_EAX &build_union_string_1           ; Using "ERROR in build_union\nMissing ;\n"
    LOADI32_EBX &semicolon                      ; Using ";"
    CALL32 %require_match                       ; Make sure we have it
    JMP32 %build_union_iter                     ; Keep going

:build_union_done
    COPY_ESI_to_EDI                             ; MEMBER_SIZE = SIZE

    LOAD32_Absolute32_eax &global_token         ; Using global_token
    LOAD32_EAX_from_EAX                         ; global_token->NEXT
    STORE32_Absolute32_eax &global_token        ; global_token = global_token->NEXT

    COPY_ECX_to_EAX                             ; Return last

    POP_ESI                                     ; Restore ESI
    POP_EDX                                     ; Restore EDX
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

:build_union_string_0  "ERROR in build_union
Missing {
"
:build_union_string_1  "ERROR in build_union
Missing ;
"


;; sym_declare function
;; Receives char *s in EAX, struct type* t in EBX, and struct token_list* list in ECX
;; Returns struct token_list* in EAX
;; Uses EAX for A
:sym_declare
    PUSH_EDX                                    ; Protect EDX
    COPY_EAX_to_EDX                             ; Get char *S safely out of the way
    LOADI32_EAX %20                             ; Using sizeof(struct token_list)
    CALL32 %malloc                              ; Get pointer to A
    STORE32_ECX_into_EAX                        ; A->NEXT = LIST
    STORE32_EDX_into_EAX_Immediate8 !8          ; A->S = S
    STORE32_EBX_into_EAX_Immediate8 !12         ; A->TYPE = T
    POP_EDX                                     ; Restore EDX
    RETURN


;; match function
;; Receives CHAR* in EAX and CHAR* in EBX
;; Returns 0 (TRUE) or 1 (FALSE) in EAX
:match
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    PUSH_EDX                                    ; Protect EDX
    COPY_EAX_to_ECX                             ; S1 in place
    COPY_EBX_to_EDX                             ; S2 in place
:match_Loop
    LOAD8_al_from_ECX                           ; S1[0]
    MOVZX_al                                    ; Make it useful
    LOAD8_bl_from_EDX                           ; S2[0]
    MOVZX_bl                                    ; Make it useful
    CMP_EAX_EBX                                 ; See if they match
    JNE32 %match_False                          ; If not

    ADDI8_ECX !1                                ; S1 = S1 + 1
    ADDI8_EDX !1                                ; S2 = S2 + 1
    CMPI8_EAX !0                                ; If reached end of string
    JE32 %match_Done                            ; Perfect match
    JMP32 %match_Loop                           ; Otherwise keep looping

:match_False
    LOADI32_EAX %1                              ; Return false
:match_Done
    POP_EDX                                     ; Restore EDX
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN


;; numerate_number function
;; Receives an INT A in EAX
;; Returns char* result in EAX
;; Allocates 16 bytes of memory
;; Behaves badly when given a negative number too large
;; Uses EAX for temp, EBX for DIVISOR, EDX for mod/0, ESI for result[i] and EBP for A
:numerate_number
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    PUSH_EDX                                    ; Protect EDX
    PUSH_ESI                                    ; Protect ESI
    PUSH_EBP                                    ; Protect EBP
    COPY_EAX_to_EBP                             ; Protect A

    LOADI32_EAX %16                             ; 16bytes
    CALL32 %malloc                              ; Get our pointer
    PUSH_EAX                                    ; Protect our pointer
    COPY_EAX_to_ESI                             ; put pointer in right place
    LOADI32_EBX %0x3B9ACA00                     ; Set divisor to largest positive number that fits in 32bits

    CMPI8_EBP !0                                ; Deal with 0 case
    JE32 %numerate_number_ZERO                  ; If it is
    JG32 %numerate_number_positive              ; If it is positive

    ;; Deal with negative case
    LOADI32_EAX %45                             ; Using "-"
    STORE8_al_into_Address_ESI                  ; Write it
    ADDI8_ESI !1                                ; increment
    IMULI8_EBP !-1                              ; A = A * -1

:numerate_number_positive
    LOADI32_EDX %0                              ; Set top to 0
    COPY_EBP_to_EAX                             ; Using A as bottom
    IDIV_EBX                                    ; edx:eax % ebx -> edx + edx:eax / ebx -> eax [Even if we don't want it]
    CMPI8_EAX !0                                ; IF 0 == (a / divisor)
    JNE32 %numerate_number_iter                 ; Clean up those leading Zeros

    LOADI32_EDX %0                              ; Set top to 0
    COPY_EBX_to_EAX                             ; Using Divisor for bottom
    LOADI32_EBX %10                             ; Make this shit work because idiv 10 doesn't work
    IDIV_EBX                                    ; edx:eax % 10 -> edx + edx:eax / 10 -> eax [Even if we don't want it]
    COPY_EAX_to_EBX                             ; Update divisor
    JMP32 %numerate_number_positive             ; Keep collecting

:numerate_number_iter
    CMPI8_EBX !0                                ; IF DIVISOR < 0
    JLE32 %numerate_number_done                 ; Be done

    LOADI32_EDX %0                              ; Set top to 0
    COPY_EBP_to_EAX                             ; Using A as bottom
    IDIV_EBX                                    ; edx:eax % ebx -> edx + edx:eax / ebx -> eax [Even if we don't want it]
    ADDI8_EAX !48                               ; ((a / divisor) + 48)
    STORE8_al_into_Address_ESI                  ; Write it
    COPY_EDX_to_EBP                             ; a = a % divisor

    LOADI32_EDX %0                              ; Set top to 0
    COPY_EBX_to_EAX                             ; Using Divisor for bottom
    LOADI32_EBX %10                             ; Make this shit work because idiv 10 doesn't work
    IDIV_EBX                                    ; edx:eax % 10 -> edx + edx:eax / 10 -> eax [Even if we don't want it]
    COPY_EAX_to_EBX                             ; Update divisor

    ADDI8_ESI !1                                ; increment
    JMP32 %numerate_number_iter                 ; Keep going

:numerate_number_done
    POP_EAX                                     ; Restore our result
    POP_EBP                                     ; Restore EBP
    POP_ESI                                     ; Restore ESI
    POP_EDX                                     ; Restore EDX
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN

:numerate_number_ZERO
    LOADI32_EAX %48                             ; Using '0'
    STORE8_al_into_Address_ESI                  ; Write it
    ADDI8_ESI !1                                ; increment
    JMP32 %numerate_number_done                 ; Be done


;; numerate_string function
;; Receives CHAR* in EAX
;; Returns value of CHAR* in EAX
;; Uses EAX for VALUE, EBX for S, ECX for CH and ESI for NEGATIVE?
:numerate_string
    PUSH_EBX                                    ; Protect EBX
    PUSH_ECX                                    ; Protect ECX
    PUSH_EDX                                    ; Protect EDX
    PUSH_ESI                                    ; Protect ESI
    COPY_EAX_to_EBX                             ; put S in correct place
    LOADI32_EAX %0                              ; Initialize to Zero
:numerate_string_loop
    LOAD8_cl_from_EBX_Immediate8 !1             ; S[1]
    MOVZX_cl                                    ; make it useful
    CMPI8_ECX !120                              ; IF 'x' == S[1]
    JE32 %numerate_hex                          ; Deal with hex input

    ;; Assume decimal input
    LOADI32_ESI %0                              ; Assume no negation
    LOAD8_cl_from_EBX                           ; S[0]
    MOVZX_cl                                    ; make it useful
    CMPI8_ECX !45                               ; IF '-' == S[0]
    JNE32 %numerate_decimal                     ; Skip negation

    LOADI32_ESI %1                              ; Set FLAG
    ADDI8_EBX !1                                ; S = S + 1

:numerate_decimal
    LOAD8_cl_from_EBX                           ; S[0]
    MOVZX_cl                                    ; make it useful
    CMPI8_ECX !0                                ; IF NULL == S[0]
    JE32 %numerate_decimal_done                 ; We are done

    IMULI8_EAX !10                              ; VALUE = VALUE * 10
    SUBI8_ECX !48                               ; CH = CH - '0'
    CMPI8_ECX !9                                ; Check for illegal
    JG32 %numerate_string_fail                  ; If CH > '9'
    CMPI8_ECX !0                                ; Check for illegal
    JL32 %numerate_string_fail                  ; IF CH < 0
    ADD_ecx_into_eax                            ; VALUE = VALUE + CH
    ADDI8_EBX !1                                ; S = S + 1
    JMP32 %numerate_decimal                     ; Keep looping

:numerate_decimal_done
    CMPI8_ESI !1                                ; Check if need to negate
    JNE32 %numerate_string_done                 ; Nope

    IMULI8_EAX !-1                              ; VALUE = VALUE * -1
    JMP32 %numerate_string_done                 ; Done

:numerate_hex
    ADDI8_EBX !2                                ; S = S + 2
:numerate_hex_loop
    LOAD8_cl_from_EBX                           ; S[0]
    MOVZX_cl                                    ; make it useful
    CMPI8_ECX !0                                ; IF NULL == S[0]
    JE32 %numerate_string_done                  ; We are done

    SALI8_EAX !4                                ; VALUE = VALUE << 4
    SUBI8_ECX !48                               ; CH = CH - '0'
    CMPI8_ECX !10                               ; IF 10 >= CH
    JL32 %numerate_hex_digit                    ; NO
    SUBI8_ECX !7                                ; Push A-F into range
:numerate_hex_digit
    CMPI8_ECX !15                               ; Check for illegal
    JG32 %numerate_string_fail                  ; If CH > 'F'
    CMPI8_ECX !0                                ; Check for illegal
    JL32 %numerate_string_fail                  ; IF CH < 0
    ADD_ecx_into_eax                            ; VALUE = VALUE + CH
    ADDI8_EBX !1                                ; S = S + 1
    JMP32 %numerate_hex_loop                    ; Keep looping

:numerate_string_fail
    LOADI32_EAX %0                              ; return ZERO

:numerate_string_done
    POP_ESI                                     ; Restore ESI
    POP_EDX                                     ; Restore EDX
    POP_ECX                                     ; Restore ECX
    POP_EBX                                     ; Restore EBX
    RETURN


;; Exit_Failure function
;; Receives nothing
;; And aborts hard
;; Does NOT return
:Exit_Failure
    LOADI32_EBX %1                              ; All is wrong
    LOADI32_EAX %1                              ; put the exit syscall number in eax
    INT_80                                      ; Call it a bad day

;; Keywords
:union  "union"
:struct  "struct"
:constant  "CONSTANT"
:main_string  "main"
:argc_string  "argc"
:argv_string  "argv"
:if_string  "if"
:else_string  "else"
:do_string  "do"
:while_string  "while"
:for_string  "for"
:asm_string  "asm"
:goto_string  "goto"
:return_string  "return"
:break_string  "break"
:continue_string  "continue"
:sizeof_string  "sizeof"
:plus_string  "+"
:minus_string  "-"
:multiply_string  "*"
:divide_string  "/"
:modulus_string  "%"
:left_shift_string  "<<"
:right_shift_string  ">>"
:less_than_string  "<"
:less_than_equal_string  "<="
:greater_than_equal_string  ">="
:greater_than_string  ">"
:equal_to_string  "=="
:not_equal_string  "!="
:bitwise_and  "&"
:logical_and  "&&"
:bitwise_or  "|"
:logical_or  "||"
:bitwise_xor  "^"
:arrow_string  "->"


;; Frequently Used strings
;; Generally used by require_match
:open_curly_brace  "{"
:close_curly_brace  "}"
:open_paren  "("
:close_paren  ")"
:open_bracket  "["
:close_bracket  "]"
:comma  ","
:semicolon  ";"
:equal  "="
:percent  "%"
:newline  "\n"
:underline  "_"


:prim_types
:type_void
    &type_int                                   ; NEXT
    %4                                          ; SIZE
    %0                                          ; OFFSET
    &type_void                                  ; INDIRECT
    %0                                          ; MEMBERS
    &type_void                                  ; TYPE
    &type_void_name                             ; NAME
:type_void_name  "void"

:type_int
    &type_char                                  ; NEXT
    %4                                          ; SIZE
    %0                                          ; OFFSET
    &type_int                                   ; INDIRECT
    %0                                          ; MEMBERS
    &type_int                                   ; TYPE
    &type_int_name                              ; NAME
:type_int_name  "int"

:type_char
    &type_file                                  ; NEXT
    %1                                          ; SIZE
    %0                                          ; OFFSET
    &type_char_indirect                         ; INDIRECT
    %0                                          ; MEMBERS
    &type_char                                  ; TYPE
    &type_char_name                             ; NAME
:type_char_name  "char"

:type_char_indirect
    &type_file                                  ; NEXT
    %4                                          ; SIZE
    %0                                          ; OFFSET
    &type_char_double_indirect                  ; INDIRECT
    %0                                          ; MEMBERS
    &type_char_indirect                         ; TYPE
    &type_char_indirect_name                    ; NAME
:type_char_indirect_name  "char*"

:type_char_double_indirect
    &type_file                                  ; NEXT
    %4                                          ; SIZE
    %0                                          ; OFFSET
    &type_char_double_indirect                  ; INDIRECT
    %0                                          ; MEMBERS
    &type_char_indirect                         ; TYPE
    &type_char_double_indirect_name             ; NAME
:type_char_double_indirect_name  "char**"

:type_file
    &type_function                              ; NEXT
    %4                                          ; SIZE
    %0                                          ; OFFSET
    &type_file                                  ; INDIRECT
    %0                                          ; MEMBERS
    &type_file                                  ; TYPE
    &type_file_name                             ; NAME
:type_file_name  "FILE"

:type_function
    &type_unsigned                              ; NEXT
    %4                                          ; SIZE
    %0                                          ; OFFSET
    &type_function                              ; INDIRECT
    %0                                          ; MEMBERS
    &type_function                              ; TYPE
    &type_function_name                         ; NAME
:type_function_name  "FUNCTION"

:type_unsigned
    &type_long                                  ; NEXT
    %4                                          ; SIZE
    %0                                          ; OFFSET
    &type_unsigned                              ; INDIRECT
    %0                                          ; MEMBERS
    &type_unsigned                              ; TYPE
    &type_unsigned_name                         ; NAME
:type_unsigned_name  "unsigned"

:type_long
    %0                                          ; NEXT
    %4                                          ; SIZE
    %0                                          ; OFFSET
    &type_long                                  ; INDIRECT
    %0                                          ; MEMBERS
    &type_long                                  ; TYPE
    &type_long_name                             ; NAME
:type_long_name  "long"

;; debug_list function
;; Receives struct token_list* in EAX
;; Prints contents of list and exits
;; Does NOT return
:debug_list
    COPY_EAX_to_EBP                             ; Protect the list pointer
    LOADI32_EAX %2                              ; Using Standard error
    STORE32_Absolute32_eax &Output_file         ; write to standard error

:debug_list_iter
    ;; Header
    LOADI32_EAX &debug_list_string0             ; Using our first string
    CALL32 %File_Print                          ; Print it
    COPY_EBP_to_EAX                             ; Use address of pointer
    CALL32 %numerate_number                     ; Convert it into string
    CALL32 %File_Print                          ; Print it

    ;; NEXT
    LOADI32_EAX &debug_list_string1             ; Using our second string
    CALL32 %File_Print                          ; Print it
    LOAD32_EAX_from_EBP_Immediate8 !0           ; Use address of pointer
    CALL32 %numerate_number                     ; Convert it into string
    CALL32 %File_Print                          ; Print it

    ;; PREV
    LOADI32_EAX &debug_list_string2             ; Using our third string
    CALL32 %File_Print                          ; Print it
    LOAD32_EAX_from_EBP_Immediate8 !4           ; Use address of pointer
    CALL32 %numerate_number                     ; Convert it into string
    CALL32 %File_Print                          ; Print it

    ;; S
    LOADI32_EAX &debug_list_string3             ; Using our fourth string
    CALL32 %File_Print                          ; Print it
    LOAD32_EAX_from_EBP_Immediate8 !8           ; Use address of pointer
    CALL32 %numerate_number                     ; Convert it into string
    CALL32 %File_Print                          ; Print it

    ;; S Contents
    LOADI32_EAX &debug_list_string4             ; Using our fifth string
    CALL32 %File_Print                          ; Print it
    LOAD32_EAX_from_EBP_Immediate8 !8           ; Use address of string
    CMPI8_EAX !0                                ; IF NULL Pointer
    JNE32 %debug_list_null                      ; otherwise display
    LOADI32_EAX &debug_list_string_null         ; Give meaningful message instead
:debug_list_null
    CALL32 %File_Print                          ; Print it

    ;; TYPE
    LOADI32_EAX &debug_list_string5             ; Using our sixth string
    CALL32 %File_Print                          ; Print it
    LOAD32_EAX_from_EBP_Immediate8 !12          ; Use address of pointer
    CALL32 %numerate_number                     ; Convert it into string
    CALL32 %File_Print                          ; Print it

    ;; ARGS/DEPTH
    LOADI32_EAX &debug_list_string6             ; Using our seventh string
    CALL32 %File_Print                          ; Print it
    LOAD32_EAX_from_EBP_Immediate8 !16          ; Use address of pointer
    CALL32 %numerate_number                     ; Convert it into string
    CALL32 %File_Print                          ; Print it

    LOADI32_EAX %10                             ; Add "\n"
    CALL32 %fputc                               ; print it
    CALL32 %fputc                               ; print it

    LOAD32_EBP_from_EBP                         ; TOKEN = TOKEN->NEXT
    CMPI8_EBP !0                                ; Check if NULL
    JNE32 %debug_list_iter                      ; iterate otherwise

    LOADI32_EBX %666                            ; All is HELL
    LOADI32_EAX %1                              ; put the exit syscall number in eax
    INT_80                                      ; Call it a bad day

:debug_list_string0  "Token_list node at address: "
:debug_list_string1  "
NEXT address: "
:debug_list_string2  "
PREV address: "
:debug_list_string3  "
S address: "
:debug_list_string4  "
The contents of S are: "
:debug_list_string5  "
TYPE address: "
:debug_list_string6  "
ARGUMENTS address: "
:debug_list_string_null  ">::<NULL>::<"


:Address_of
    NULL
:C
    NULL
:Input_file
    NULL
:MALLOC
    NULL
:Output_file
    NULL
:Token
    NULL
:break_frame
    NULL
:break_target_func
    NULL
:break_target_head
    NULL
:break_target_num
    NULL
:current_count
    NULL
:current_target
    NULL
:function
    NULL
:global_constant_list
    NULL
:global_function_list
    NULL
:global_symbol_list
    NULL
:global_token
    NULL
:global_types
    &prim_types
:globals_list
    NULL
:output_list
    NULL
:string_index
    NULL
:strings_list
    NULL

:ELF_end

https://github.com/oriansj/M2libc/blob/main/x86/linux/bootstrap.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/M2libc/x86/linux/bootstrap.c used in: Step 13, Step 19, Step 24
/* Copyright (C) 2016 Jeremiah Orians
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */

// CONSTANT stdin 0
// CONSTANT stdout 1
// CONSTANT stderr 2
// CONSTANT EOF 0xFFFFFFFF
// CONSTANT NULL 0
// CONSTANT EXIT_FAILURE 1
// CONSTANT EXIT_SUCCESS 0
// CONSTANT TRUE 1
// CONSTANT FALSE 0


int fgetc(FILE* f)
{
    asm("mov_eax, %3"
        "lea_ebx,[esp+DWORD] %4"
        "mov_ebx,[ebx]"
        "push_ebx"
        "mov_ecx,esp"
        "mov_edx, %1"
        "int !0x80"
        "test_eax,eax"
        "pop_eax"
        "jne %FUNCTION_fgetc_Done"
        "mov_eax, %-1"
        ":FUNCTION_fgetc_Done");
}

void fputc(char s, FILE* f)
{
    asm("mov_eax, %4"
        "lea_ebx,[esp+DWORD] %4"
        "mov_ebx,[ebx]"
        "lea_ecx,[esp+DWORD] %8"
        "mov_edx, %1"
        "int !0x80");
}

void fputs(char* s, FILE* f)
{
    while(0 != s[0])
    {
        fputc(s[0], f);
        s = s + 1;
    }
}

FILE* open(char* name, int flag, int mode)
{
    asm("lea_ebx,[esp+DWORD] %12"
        "mov_ebx,[ebx]"
        "lea_ecx,[esp+DWORD] %8"
        "mov_ecx,[ecx]"
        "lea_edx,[esp+DWORD] %4"
        "mov_edx,[edx]"
        "mov_eax, %5"
        "int !0x80");
}

FILE* fopen(char* filename, char* mode)
{
    FILE* f;
    if('w' == mode[0])
    { /* 577 is O_WRONLY|O_CREAT|O_TRUNC, 384 is 600 in octal */
        f = open(filename, 577 , 384);
    }
    else
    { /* Everything else is a read */
        f = open(filename, 0, 0);
    }

    /* Negative numbers are error codes */
    if(0 > f)
    {
        return 0;
    }
    return f;
}

int close(int fd)
{
    asm("lea_ebx,[esp+DWORD] %4"
        "mov_ebx,[ebx]"
        "mov_eax, %6"
        "int !0x80");
}

int fclose(FILE* stream)
{
    int error = close(stream);
    return error;
}

int brk(void *addr)
{
    asm("mov_eax,[esp+DWORD] %4"
        "push_eax"
        "mov_eax, %45"
        "pop_ebx"
        "int !0x80");
}

long _malloc_ptr;
long _brk_ptr;

void* malloc(int size)
{
    if(NULL == _brk_ptr)
    {
        _brk_ptr = brk(0);
        _malloc_ptr = _brk_ptr;
    }

    if(_brk_ptr < _malloc_ptr + size)
    {
        _brk_ptr = brk(_malloc_ptr + size);
        if(-1 == _brk_ptr) return 0;
    }

    long old_malloc = _malloc_ptr;
    _malloc_ptr = _malloc_ptr + size;
    return old_malloc;
}

int strlen(char* str )
{
    int i = 0;
    while(0 != str[i]) i = i + 1;
    return i;
}

void* memset(void* ptr, int value, int num)
{
    char* s;
    for(s = ptr; 0 < num; num = num - 1)
    {
        s[0] = value;
        s = s + 1;
    }
}

void* calloc(int count, int size)
{
    void* ret = malloc(count * size);
    if(NULL == ret) return NULL;
    memset(ret, 0, (count * size));
    return ret;
}

void free(void* l)
{
    return;
}

void exit(int value)
{
    asm("pop_ebx"
        "pop_ebx"
        "mov_eax, %1"
        "int !0x80");
}

https://github.com/oriansj/M2-Planet/blob/main/cc.h

File: ../git/live-bootstrap/sysa/stage0-posix/src/M2-Planet/cc.h used in: Step 13, Step 61
/* Copyright (C) 2016 Jeremiah Orians
 * Copyright (C) 2020 deesix <deesix@tuta.io>
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

// CONSTANT FALSE 0
#define FALSE 0
// CONSTANT TRUE 1
#define TRUE 1

// CONSTANT KNIGHT_NATIVE 1
#define KNIGHT_NATIVE 1
// CONSTANT KNIGHT_POSIX 2
#define KNIGHT_POSIX 2
// CONSTANT X86 3
#define X86 3
// CONSTANT AMD64 4
#define AMD64 4
// CONSTANT ARMV7L 5
#define ARMV7L 5
// CONSTANT AARCH64 6
#define AARCH64 6
// CONSTANT RISCV32 7
#define RISCV32 7
// CONSTANT RISCV64 8
#define RISCV64 8


void copy_string(char* target, char* source, int max);
int in_set(int c, char* s);
int match(char* a, char* b);
void require(int bool, char* error);
void reset_hold_string();


struct type
{
    struct type* next;
    int size;
    int offset;
    int is_signed;
    struct type* indirect;
    struct type* members;
    struct type* type;
    char* name;
};

struct token_list
{
    struct token_list* next;
    union
    {
        struct token_list* locals;
        struct token_list* prev;
    };
    char* s;
    union
    {
        struct type* type;
        char* filename;
    };
    union
    {
        struct token_list* arguments;
        int depth;
        int linenumber;
    };
};

#include "cc_globals.h"

https://github.com/oriansj/M2libc/blob/main/bootstrappable.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/M2libc/bootstrappable.c used in: Step 13, Step 19, Step 24, Step 30, Step 35, Step 39, Step 43, Step 49, Step 53, Step 57, Step 61, Step 66, Step 67, Step 68, Step 69, Step 70, Step 71, Step 73, Step 74, Step 75, Step 76, Step 79, Step 81
/* Copyright (C) 2016 Jeremiah Orians
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>
#include <stdlib.h>


#define TRUE 1
#define FALSE 0


void require(int bool, char* error)
{
    if(!bool)
    {
        fputs(error, stderr);
        exit(EXIT_FAILURE);
    }
}


int match(char* a, char* b)
{
    if((NULL == a) && (NULL == b)) return TRUE;
    if(NULL == a) return FALSE;
    if(NULL == b) return FALSE;

    int i = -1;
    do
    {
        i = i + 1;
        if(a[i] != b[i])
        {
            return FALSE;
        }
    } while((0 != a[i]) && (0 !=b[i]));
    return TRUE;
}


int in_set(int c, char* s)
{
    /* NULL set is always false */
    if(NULL == s) return FALSE;

    while(0 != s[0])
    {
        if(c == s[0]) return TRUE;
        s = s + 1;
    }
    return FALSE;
}

/* INTERNAL ONLY */
int __index_number(char* s, char c)
{
    int i = 0;
    while(s[i] != c)
    {
        i = i + 1;
        if(0 == s[i]) return -1;
    }
    return i;
}

/* INTERNAL ONLY */
int __toupper(int c)
{
    if(in_set(c, "abcdefghijklmnopqrstuvwxyz")) return (c & 0xDF);
    return c;
}

/* INTERNAL ONLY */
int __set_reader(char* set, int mult, char* input)
{
    int n = 0;
    int i = 0;
    int hold;
    int negative_p = FALSE;

    if(input[0] == '-')
    {
        negative_p = TRUE;
        i = i + 1;
    }

    while(in_set(input[i], set))
    {
        n = n * mult;
        hold = __index_number(set, __toupper(input[i]));

        /* Input managed to change between in_set and index_number */
        if(-1 == hold) return 0;
        n = n + hold;
        i = i + 1;
    }

    /* loop exited before NULL and thus invalid input */
    if(0 != input[i]) return 0;

    if(negative_p)
    {
        n = 0 - n;
    }

    return n;
}

int strtoint(char *a)
{
    int result = 0;
    /* If NULL string */
    if(0 == a[0])
    {
        result = 0;
    }
    /* Deal with binary */
    else if ('0' == a[0] && 'b' == a[1])
    {
        result = __set_reader("01", 2, a+2);
    }
    /* Deal with hex */
    else if ('0' == a[0] &&  'x' == a[1])
    {
        result = __set_reader("0123456789ABCDEFabcdef", 16, a+2);
    }
    /* Deal with octal */
    else if('0' == a[0])
    {
        result = __set_reader("01234567", 8, a+1);
    }
    /* Deal with decimal */
    else
    {
        result = __set_reader("0123456789", 10, a);
    }

    /* Deal with sign extension for 64bit hosts */
    if(0 != (0x80000000 & result)) result = (0xFFFFFFFF << 31) | result;
    return result;
}

char* int2str(int x, int base, int signed_p)
{
    require(1 < base, "int2str doesn't support a base less than 2\n");
    require(37 > base, "int2str doesn't support a base more than 36\n");
    /* Be overly conservative and save space for 32binary digits and padding null */
    char* p = calloc(34, sizeof(char));
    /* if calloc fails return null to let calling code deal with it */
    if(NULL == p) return p;

    p = p + 32;
    unsigned i;
    int sign_p = FALSE;
    char* table = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    if(signed_p && (10 == base) && (0 != (x & 0x80000000)))
    {
        /* Truncate to 31bits */
        i = -x & 0x7FFFFFFF;
        if(0 == i) return "-2147483648";
        sign_p = TRUE;
    } /* Truncate to 32bits */
    else i = x & (0x7FFFFFFF | (1 << 31));

    do
    {
        p[0] = table[i % base];
        p = p - 1;
        i = i / base;
    } while(0 < i);

    if(sign_p)
    {
        p[0] = '-';
        p = p - 1;
    }

    return p + 1;
}

https://github.com/oriansj/M2-Planet/blob/main/cc_globals.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/M2-Planet/cc_globals.c used in: Step 13, Step 61
/* Copyright (C) 2016 Jeremiah Orians
 * Copyright (C) 2020 deesix <deesix@tuta.io>
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */

/* What types we have */
struct type* global_types;
struct type* prim_types;

/* What we are currently working on */
struct token_list* global_token;

/* Output reorder collections*/
struct token_list* output_list;
struct token_list* strings_list;
struct token_list* globals_list;

/* Make our string collection more efficient */
char* hold_string;
int string_index;

/* Our Target Architecture */
int Architecture;
int register_size;

int MAX_STRING;
struct type* integer;

/* enable bootstrap-mode */
int BOOTSTRAP_MODE;

/* enable preprocessor-only mode */
int PREPROCESSOR_MODE;

https://github.com/oriansj/M2-Planet/blob/main/cc_reader.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/M2-Planet/cc_reader.c used in: Step 13, Step 61
/* Copyright (C) 2016 Jeremiah Orians
 * Copyright (C) 2021 Andrius Å tikonas <andrius@stikonas.eu>
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "cc.h"

int strtoint(char *a);

/* Globals */
FILE* input;
struct token_list* token;
int line;
char* file;

int grab_byte()
{
    int c = fgetc(input);
    if(10 == c) line = line + 1;
    return c;
}

int clearWhiteSpace(int c)
{
    if((32 == c) || (9 == c)) return clearWhiteSpace(grab_byte());
    return c;
}

int consume_byte(int c)
{
    hold_string[string_index] = c;
    string_index = string_index + 1;
    require(MAX_STRING > string_index, "Token exceeded MAX_STRING char limit\nuse --max-string number to increase\n");
    return grab_byte();
}

int preserve_string(int c)
{
    int frequent = c;
    int escape = FALSE;
    do
    {
        if(!escape && '\\' == c ) escape = TRUE;
        else escape = FALSE;
        c = consume_byte(c);
        require(EOF != c, "Unterminated string\n");
    } while(escape || (c != frequent));
    return grab_byte();
}


void copy_string(char* target, char* source, int max)
{
    int i = 0;
    while(0 != source[i])
    {
        target[i] = source[i];
        i = i + 1;
        if(i == max) break;
    }
}


void fixup_label()
{
    int hold = ':';
    int prev;
    int i = 0;
    do
    {
        prev = hold;
        hold = hold_string[i];
        hold_string[i] = prev;
        i = i + 1;
    } while(0 != hold);
}

int preserve_keyword(int c, char* S)
{
    while(in_set(c, S))
    {
        c = consume_byte(c);
    }
    return c;
}

void reset_hold_string()
{
    int i = MAX_STRING;
    while(0 <= i)
    {
        hold_string[i] = 0;
        i = i - 1;
    }
    string_index = 0;
}

/* note if this is the first token in the list, head needs fixing up */
struct token_list* eat_token(struct token_list* token)
{
    if(NULL != token->prev)
    {
        token->prev->next = token->next;
    }

    /* update backlinks */
    if(NULL != token->next)
    {
        token->next->prev = token->prev;
    }

    return token->next;
}

struct token_list* eat_until_newline(struct token_list* head)
{
    while (NULL != head)
    {
        if('\n' == head->s[0])
        {
            return head;
        }
        else
        {
            head = eat_token(head);
        }
    }

    return NULL;
}

struct token_list* remove_line_comments(struct token_list* head)
{
    struct token_list* first = NULL;

    while (NULL != head)
    {
        if(match("//", head->s))
        {
            head = eat_until_newline(head);
        }
        else
        {
            if(NULL == first)
            {
                first = head;
            }
            head = head->next;
        }
    }

    return first;
}

struct token_list* remove_line_comment_tokens(struct token_list* head)
{
    struct token_list* first = NULL;

    while (NULL != head)
    {
        if(match("//", head->s))
        {
            head = eat_token(head);
        }
        else
        {
            if(NULL == first)
            {
                first = head;
            }
            head = head->next;
        }
    }

    return first;
}

struct token_list* remove_preprocessor_directives(struct token_list* head)
{
    struct token_list* first = NULL;

    while (NULL != head)
    {
        if('#' == head->s[0])
        {
            head = eat_until_newline(head);
        }
        else
        {
            if(NULL == first)
            {
                first = head;
            }
            head = head->next;
        }
    }

    return first;
}

void new_token(char* s, int size)
{
    struct token_list* current = calloc(1, sizeof(struct token_list));
    require(NULL != current, "Exhausted memory while getting token\n");

    /* More efficiently allocate memory for string */
    current->s = calloc(size, sizeof(char));
    require(NULL != current->s, "Exhausted memory while trying to copy a token\n");
    copy_string(current->s, s, MAX_STRING);

    current->prev = token;
    current->next = token;
    current->linenumber = line;
    current->filename = file;
    token = current;
}

int get_token(int c)
{
    struct token_list* current = calloc(1, sizeof(struct token_list));
    require(NULL != current, "Exhausted memory while getting token\n");

reset:
    reset_hold_string();
    string_index = 0;

    c = clearWhiteSpace(c);
    if(c == EOF)
    {
        free(current);
        return c;
    }
    else if('#' == c)
    {
        c = consume_byte(c);
        c = preserve_keyword(c, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_");
    }
    else if(in_set(c, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"))
    {
        c = preserve_keyword(c, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_");
        if(':' == c)
        {
            fixup_label();
            c = ' ';
        }
    }
    else if(in_set(c, "<=>|&!^%"))
    {
        c = preserve_keyword(c, "<=>|&!^%");
    }
    else if(in_set(c, "'\""))
    {
        c = preserve_string(c);
    }
    else if(c == '/')
    {
        c = consume_byte(c);
        if(c == '*')
        {
            c = grab_byte();
            while(c != '/')
            {
                while(c != '*')
                {
                    c = grab_byte();
                    require(EOF != c, "Hit EOF inside of block comment\n");
                }
                c = grab_byte();
                require(EOF != c, "Hit EOF inside of block comment\n");
            }
            c = grab_byte();
            goto reset;
        }
        else if(c == '/')
        {
            c = consume_byte(c);
        }
        else if(c == '=')
        {
            c = consume_byte(c);
        }
    }
    else if (c == '\n')
    {
        c = consume_byte(c);
    }
    else if(c == '*')
    {
        c = consume_byte(c);
        if(c == '=')
        {
            c = consume_byte(c);
        }
    }
    else if(c == '+')
    {
        c = consume_byte(c);
        if(c == '=')
        {
            c = consume_byte(c);
        }
        if(c == '+')
        {
            c = consume_byte(c);
        }
    }
    else if(c == '-')
    {
        c = consume_byte(c);
        if(c == '=')
        {
            c = consume_byte(c);
        }
        if(c == '>')
        {
            c = consume_byte(c);
        }
        if(c == '-')
        {
            c = consume_byte(c);
        }
    }
    else
    {
        c = consume_byte(c);
    }

    new_token(hold_string, string_index + 2);
    return c;
}


int consume_filename(int c)
{
    reset_hold_string();
    int done = FALSE;

    while(!done)
    {
        if(c == EOF)
        {
            fputs("we don't support EOF as a filename in #FILENAME statements\n", stderr);
            exit(EXIT_FAILURE);
        }
        else if((32 == c) || (9 == c) || (c == '\n'))
        {
            c = grab_byte();
        }
        else
        {
            do
            {
                c = consume_byte(c);
                require(EOF != c, "Unterminated filename in #FILENAME\n");
            } while((32 != c) && (9 != c) && ('\n' != c));
            done = TRUE;
        }
    }

    /* with just a little extra to put in the matching at the end */
    new_token(hold_string, string_index + 3);
    return c;
}


int change_filename(int ch)
{
    require(EOF != ch, "#FILENAME failed to receive filename\n");
    /* Remove the #FILENAME */
    token = token->next;

    /* Get new filename */
    ch = consume_filename(ch);
    file = token->s;
    /* Remove it from the processing list */
    token = token->next;
    require(EOF != ch, "#FILENAME failed to receive filename\n");

    /* Get new line number */
    ch = get_token(ch);
    line = strtoint(token->s);
    if(0 == line)
    {
        if('0' != token->s[0])
        {
            fputs("non-line number: ", stderr);
            fputs(token->s, stderr);
            fputs(" provided to #FILENAME\n", stderr);
            exit(EXIT_FAILURE);
        }
    }
    /* Remove it from the processing list */
    token = token->next;

    return ch;
}

struct token_list* reverse_list(struct token_list* head)
{
    struct token_list* root = NULL;
    struct token_list* next;
    while(NULL != head)
    {
        next = head->next;
        head->next = root;
        root = head;
        head = next;
    }
    return root;
}

struct token_list* read_all_tokens(FILE* a, struct token_list* current, char* filename)
{
    input  = a;
    line = 1;
    file = filename;
    token = current;
    int ch = grab_byte();
    while(EOF != ch)
    {
        ch = get_token(ch);
        require(NULL != token, "Empty files don't need to be compiled\n");
        if(match("#FILENAME", token->s)) ch = change_filename(ch);
    }

    return token;
}

https://github.com/oriansj/M2-Planet/blob/main/cc_strings.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/M2-Planet/cc_strings.c used in: Step 13, Step 61
/* Copyright (C) 2016 Jeremiah Orians
 * Copyright (C) 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "cc.h"
#include <stdint.h>

struct token_list* emit(char *s, struct token_list* head);
void require(int bool, char* error);

char upcase(char a)
{
    if(in_set(a, "abcdefghijklmnopqrstuvwxyz"))
    {
        a = a - 32;
    }

    return a;
}


int char2hex(int c)
{
    if (c >= '0' && c <= '9') return (c - 48);
    else if (c >= 'a' && c <= 'f') return (c - 87);
    else if (c >= 'A' && c <= 'F') return (c - 55);
    else return -1;
}

int hexify(int c, int high)
{
    int i = char2hex(c);

    if(0 > i)
    {
        fputs("Tried to print non-hex number\n", stderr);
        exit(EXIT_FAILURE);
    }

    if(high)
    {
        i = i << 4;
    }
    return i;
}

int escape_lookup(char* c);
int weird(char* string)
{
    int c;
    string = string + 1;
weird_reset:
    c = string[0];
    if(0 == c) return FALSE;
    if('\\' == c)
    {
        c = escape_lookup(string);
        if('x' == string[1]) string = string + 2;
        string = string + 1;
    }

    if(!in_set(c, "\t\n !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~")) return TRUE;
    if(in_set(c, " \t\n\r") && (':' == string[1])) return TRUE;
    string = string + 1;
    goto weird_reset;
}

/* Lookup escape values */
int escape_lookup(char* c)
{
    if('\\' != c[0]) return c[0];

    if(c[1] == 'x')
    {
        int t1 = hexify(c[2], TRUE);
        int t2 = hexify(c[3], FALSE);
        return t1 + t2;
    }
    else if(c[1] == '0') return 0;
    else if(c[1] == 'a') return 7;
    else if(c[1] == 'b') return 8;
    else if(c[1] == 't') return 9;
    else if(c[1] == 'n') return 10;
    else if(c[1] == 'v') return 11;
    else if(c[1] == 'f') return 12;
    else if(c[1] == 'r') return 13;
    else if(c[1] == 'e') return 27;
    else if(c[1] == '"') return 34;
    else if(c[1] == '\'') return 39;
    else if(c[1] == '\\') return 92;

    fputs("Unknown escape received: ", stderr);
    fputs(c, stderr);
    fputs(" Unable to process\n", stderr);
    exit(EXIT_FAILURE);
}

/* Deal with human strings */
char* collect_regular_string(char* string)
{
    string_index = 0;

collect_regular_string_reset:
    require((MAX_STRING - 3) > string_index, "Attempt at parsing regular string exceeds max length\n");
    if(string[0] == '\\')
    {
        hold_string[string_index] = escape_lookup(string);
        if (string[1] == 'x') string = string + 2;
        string = string + 2;
    }
    else
    {
        hold_string[string_index] = string[0];
        string = string + 1;
    }

    string_index = string_index + 1;
    if(string[0] != 0) goto collect_regular_string_reset;

    hold_string[string_index] = '"';
    hold_string[string_index + 1] = '\n';
    char* message = calloc(string_index + 3, sizeof(char));
    require(NULL != message, "Exhausted memory while storing regular string\n");
    copy_string(message, hold_string, string_index + 2);
    reset_hold_string();
    return message;
}

/* Deal with non-human strings */
char* collect_weird_string(char* string)
{
    string_index = 1;
    int temp;
    char* table = "0123456789ABCDEF";

    hold_string[0] = '\'';
collect_weird_string_reset:
    require((MAX_STRING - 6) > string_index, "Attempt at parsing weird string exceeds max length\n");
    string = string + 1;
    hold_string[string_index] = ' ';
    temp = escape_lookup(string) & 0xFF;
    hold_string[string_index + 1] = table[(temp >> 4)];
    hold_string[string_index + 2] = table[(temp & 15)];

    if(string[0] == '\\')
    {
        if(string[1] == 'x') string = string + 2;
        string = string + 1;
    }

    string_index = string_index + 3;
    if(string[1] != 0) goto collect_weird_string_reset;

    hold_string[string_index] = ' ';
    hold_string[string_index + 1] = '0';
    hold_string[string_index + 2] = '0';
    hold_string[string_index + 3] = '\'';
    hold_string[string_index + 4] = '\n';

    char* hold = calloc(string_index + 6, sizeof(char));
    require(NULL != hold, "Exhausted available memory while attempting to collect a weird string\n");
    copy_string(hold, hold_string, string_index + 5);
    reset_hold_string();
    return hold;
}

/* Parse string to deal with hex characters*/
char* parse_string(char* string)
{
    /* the string */
    if(weird(string)) return collect_weird_string(string);
    else return collect_regular_string(string);
}

https://github.com/oriansj/M2-Planet/blob/main/cc_types.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/M2-Planet/cc_types.c used in: Step 13, Step 61
/* Copyright (C) 2016 Jeremiah Orians
 * Copyright (C) 2020 deesix <deesix@tuta.io>
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */
#include "cc.h"

/* Imported functions */
int strtoint(char *a);
void line_error();
void require(int bool, char* error);

/* enable easy primitive extension */
struct type* add_primitive(struct type* a)
{
    if(NULL == prim_types) return a;
    struct type* i = prim_types;
    while(NULL != i->next)
    {
        i = i->next;
    }
    i->next = a;

    return prim_types;
}

/* enable easy primitive creation */
struct type* new_primitive(char* name0, char* name1, char* name2, int size, int sign)
{
    /* Create type** */
    struct type* a = calloc(1, sizeof(struct type));
    require(NULL != a, "Exhausted memory while declaring new primitive**\n");
    a->name = name2;
    a->size = register_size;
    a->indirect = a;
    a->is_signed = sign;

    /* Create type* */
    struct type* b = calloc(1, sizeof(struct type));
    require(NULL != b, "Exhausted memory while declaring new primitive*\n");
    b->name = name1;
    b->size = register_size;
    b->is_signed = sign;
    b->indirect = a;
    a->type = b;

    struct type* r = calloc(1, sizeof(struct type));
    require(NULL != r, "Exhausted memory while declaring new primitive\n");
    r->name = name0;
    r->size = size;
    r->is_signed = sign;
    r->indirect = b;
    r->type = r;
    b->type = r;

    return r;
}

/* Initialize default types */
void initialize_types()
{
    if(AMD64 == Architecture || AARCH64 == Architecture || RISCV64 == Architecture) register_size = 8;
    else register_size = 4;

    /* Define void */
    struct type* hold = new_primitive("void", "void*", "void**", register_size, FALSE);
    prim_types = add_primitive(hold);

    /* Define unsigned LONG */
    hold = new_primitive("SCM","SCM*", "SCM**", register_size, FALSE);
    prim_types = add_primitive(hold);

    /* Define LONG */
    hold = new_primitive("long", "long*", "long**", register_size, TRUE);
    prim_types = add_primitive(hold);

    /* Define UNSIGNED */
    hold = new_primitive("unsigned", "unsigned*", "unsigned**", register_size, FALSE);
    prim_types = add_primitive(hold);

    /* Define int */
    integer = new_primitive("int", "int*", "int**", register_size, TRUE);
    prim_types = add_primitive(integer);

    /* Define uint32_t */
    hold = new_primitive("uint32_t", "uint32_t*", "uint32_t**", 4, FALSE);
    prim_types = add_primitive(hold);

    /* Define int32_t */
    hold = new_primitive("int32_t", "int32_t*", "int32_t**", 4, TRUE);
    prim_types = add_primitive(hold);

    /* Define uint16_t */
    hold = new_primitive("uint16_t", "uint16_t*", "uint16_t**", 2, FALSE);
    prim_types = add_primitive(hold);

    /* Define int16_t */
    hold = new_primitive("int16_t", "int16_t*", "int16_t**", 2, TRUE);
    prim_types = add_primitive(hold);

    /* Define uint8_t */
    hold = new_primitive("uint8_t", "uint8_t*", "uint8_t**", 1, FALSE);
    prim_types = add_primitive(hold);

    /* Define int8_t */
    hold = new_primitive("int8_t", "int8_t*", "int8_t**", 1, TRUE);
    prim_types = add_primitive(hold);

    /* Define char */
    hold = new_primitive("char", "char*", "char**", 1, TRUE);
    prim_types = add_primitive(hold);

    /* Define FUNCTION */
    hold = new_primitive("FUNCTION", "FUNCTION*", "FUNCTION**", register_size, FALSE);
    prim_types = add_primitive(hold);

    if(BOOTSTRAP_MODE)
    {
        /* Define FILE */
        hold = new_primitive("FILE", "FILE*", "FILE**", register_size, TRUE);
        prim_types = add_primitive(hold);

        /* Primitives mes.c wanted */
        hold = new_primitive("size_t", "size_t*", "size_t**", register_size, FALSE);
        prim_types = add_primitive(hold);

        hold = new_primitive("ssize_t", "ssize_t*", "ssize_t**", register_size, FALSE);
        prim_types = add_primitive(hold);
    }

    global_types = prim_types;
}

struct type* lookup_type(char* s, struct type* start)
{
    struct type* i;
    for(i = start; NULL != i; i = i->next)
    {
        if(match(i->name, s))
        {
            return i;
        }
    }
    return NULL;
}

struct type* lookup_member(struct type* parent, char* name)
{
    struct type* i;
    require(NULL != parent, "Not a valid struct type\n");
    for(i = parent->members; NULL != i; i = i->members)
    {
        if(match(i->name, name)) return i;
    }

    fputs("ERROR in lookup_member ", stderr);
    fputs(parent->name, stderr);
    fputs("->", stderr);
    fputs(global_token->s, stderr);
    fputs(" does not exist\n", stderr);
    line_error();
    fputs("\n", stderr);
    exit(EXIT_FAILURE);
}

struct type* type_name();
void require_match(char* message, char* required);

int member_size;
struct type* build_member(struct type* last, int offset)
{
    struct type* i = calloc(1, sizeof(struct type));
    require(NULL != i, "Exhausted memory while building a struct member\n");
    i->members = last;
    i->offset = offset;

    struct type* member_type = type_name();
    require(NULL != member_type, "struct member type can not be invalid\n");
    i->type = member_type;
    i->name = global_token->s;
    global_token = global_token->next;
    require(NULL != global_token, "struct member can not be EOF terminated\n");

    /* Check to see if array */
    if(match( "[", global_token->s))
    {
        global_token = global_token->next;
        require(NULL != global_token, "struct member arrays can not be EOF sized\n");
        i->size = member_type->type->size * strtoint(global_token->s);
        if(0 == i->size)
        {
            fputs("Struct only supports [num] form\n", stderr);
            exit(EXIT_FAILURE);
        }
        global_token = global_token->next;
        require_match("Struct only supports [num] form\n", "]");
    }
    else
    {
        i->size = member_type->size;
    }
    member_size = i->size;

    return i;
}

struct type* build_union(struct type* last, int offset)
{
    int size = 0;
    global_token = global_token->next;
    require_match("ERROR in build_union\nMissing {\n", "{");
    while('}' != global_token->s[0])
    {
        last = build_member(last, offset);
        if(member_size > size)
        {
            size = member_size;
        }
        require_match("ERROR in build_union\nMissing ;\n", ";");
        require(NULL != global_token, "Unterminated union\n");
    }
    member_size = size;
    global_token = global_token->next;
    return last;
}

void create_struct()
{
    int offset = 0;
    member_size = 0;
    struct type* head = calloc(1, sizeof(struct type));
    require(NULL != head, "Exhausted memory while creating a struct\n");
    struct type* i = calloc(1, sizeof(struct type));
    require(NULL != i, "Exhausted memory while creating a struct indirection\n");
    struct type* ii = calloc(1, sizeof(struct type));
    require(NULL != ii, "Exhausted memory while creating a struct double indirection\n");
    head->name = global_token->s;
    head->type = head;
    head->indirect = i;
    head->next = global_types;
    i->name = global_token->s;
    i->type = head;
    i->indirect = ii;
    i->size = register_size;
    ii->name = global_token->s;
    ii->type = i;
    ii->indirect = ii;
    ii->size = register_size;
    global_types = head;
    global_token = global_token->next;
    require_match("ERROR in create_struct\n Missing {\n", "{");
    struct type* last = NULL;
    require(NULL != global_token, "Incomplete struct definition at end of file\n");
    while('}' != global_token->s[0])
    {
        if(match(global_token->s, "union"))
        {
            last = build_union(last, offset);
        }
        else
        {
            last = build_member(last, offset);
        }
        offset = offset + member_size;
        require_match("ERROR in create_struct\n Missing ;\n", ";");
        require(NULL != global_token, "Unterminated struct\n");
    }

    global_token = global_token->next;
    require_match("ERROR in create_struct\n Missing ;\n", ";");

    head->size = offset;
    head->members = last;
    i->members = last;
}


struct type* type_name()
{
    struct type* ret;

    require(NULL != global_token, "Received EOF instead of type name\n");

    if(match("extern", global_token->s))
    {
        global_token = global_token->next;
        require(NULL != global_token, "unfinished type definition in extern\n");
    }

    if(match("struct", global_token->s))
    {
        global_token = global_token->next;
        require(NULL != global_token, "structs can not have a EOF type name\n");
        ret = lookup_type(global_token->s, global_types);
        if(NULL == ret)
        {
            create_struct();
            return NULL;
        }
    }
    else
    {
        ret = lookup_type(global_token->s, global_types);
        if(NULL == ret)
        {
            fputs("Unknown type ", stderr);
            fputs(global_token->s, stderr);
            fputs("\n", stderr);
            line_error();
            fputs("\n", stderr);
            exit(EXIT_FAILURE);
        }
    }

    global_token = global_token->next;
    require(NULL != global_token, "unfinished type definition\n");

    if(match("const", global_token->s))
    {
        global_token = global_token->next;
        require(NULL != global_token, "unfinished type definition in const\n");
    }

    while(global_token->s[0] == '*')
    {
        ret = ret->indirect;
        global_token = global_token->next;
        require(NULL != global_token, "unfinished type definition in indirection\n");
    }

    return ret;
}

struct type* mirror_type(struct type* source, char* name)
{
    struct type* head = calloc(1, sizeof(struct type));
    require(NULL != head, "Exhausted memory while creating a struct\n");
    struct type* i = calloc(1, sizeof(struct type));
    require(NULL != i, "Exhausted memory while creating a struct indirection\n");

    head->name = name;
    i->name = name;
    head->size = source->size;
    i->size = source->indirect->size;
    head->offset = source->offset;
    i->offset = source->indirect->offset;
    head->is_signed = source->is_signed;
    i->is_signed = source->indirect->is_signed;
    head->indirect = i;
    i->indirect = head;
    head->members = source->members;
    i->members =  source->indirect->members;
    head->type = head;
    i->type = i;

    return head;
}

https://github.com/oriansj/M2-Planet/blob/main/cc_core.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/M2-Planet/cc_core.c used in: Step 13, Step 61
/* Copyright (C) 2016 Jeremiah Orians
 * Copyright (C) 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 * Copyright (C) 2020 deesix <deesix@tuta.io>
 * Copyright (C) 2021 Andrius Å tikonas <andrius@stikonas.eu>
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "cc.h"
#include "gcc_req.h"
#include <stdint.h>

/* Global lists */
struct token_list* global_symbol_list;
struct token_list* global_function_list;
struct token_list* global_constant_list;

/* Core lists for this file */
struct token_list* function;

/* What we are currently working on */
struct type* current_target;
char* break_target_head;
char* break_target_func;
char* break_target_num;
char* continue_target_head;
struct token_list* break_frame;
int current_count;
int Address_of;

/* Imported functions */
char* int2str(int x, int base, int signed_p);
int strtoint(char *a);
char* parse_string(char* string);
int escape_lookup(char* c);
void require(int bool, char* error);
struct token_list* reverse_list(struct token_list* head);
struct type* mirror_type(struct type* source, char* name);
struct type* add_primitive(struct type* a);

struct token_list* emit(char *s, struct token_list* head)
{
    struct token_list* t = calloc(1, sizeof(struct token_list));
    require(NULL != t, "Exhausted memory while generating token to emit\n");
    t->next = head;
    t->s = s;
    return t;
}

void emit_out(char* s)
{
    output_list = emit(s, output_list);
}

struct token_list* uniqueID(char* s, struct token_list* l, char* num)
{
    l = emit("\n", emit(num, emit("_", emit(s, l))));
    return l;
}

void uniqueID_out(char* s, char* num)
{
    output_list = uniqueID(s, output_list, num);
}

struct token_list* sym_declare(char *s, struct type* t, struct token_list* list)
{
    struct token_list* a = calloc(1, sizeof(struct token_list));
    require(NULL != a, "Exhausted memory while attempting to declare a symbol\n");
    a->next = list;
    a->s = s;
    a->type = t;
    return a;
}

struct token_list* sym_lookup(char *s, struct token_list* symbol_list)
{
    struct token_list* i;
    for(i = symbol_list; NULL != i; i = i->next)
    {
        if(match(i->s, s)) return i;
    }
    return NULL;
}

void line_error_token(struct token_list *token)
{
    if(NULL == token)
    {
        fputs("EOF reached inside of line_error\n", stderr);
        fputs("problem at end of file\n", stderr);
        return;
    }
    fputs(token->filename, stderr);
    fputs(":", stderr);
    fputs(int2str(token->linenumber, 10, TRUE), stderr);
    fputs(":", stderr);
}

void line_error()
{
    line_error_token(global_token);
}

void require_match(char* message, char* required)
{
    if(NULL == global_token)
    {
        line_error();
        fputs("EOF reached inside of require match\n", stderr);
        fputs("problem at end of file\n", stderr);
        fputs(message, stderr);
        exit(EXIT_FAILURE);
    }
    if(!match(global_token->s, required))
    {
        line_error();
        fputs(message, stderr);
        exit(EXIT_FAILURE);
    }
    global_token = global_token->next;
}

void maybe_bootstrap_error(char* feature)
{
    if (BOOTSTRAP_MODE)
    {
        line_error();
        fputs(feature, stderr);
        fputs(" is not supported in --bootstrap-mode\n", stderr);
        exit(EXIT_FAILURE);
    }
}

void expression();
void function_call(char* s, int bool)
{
    require_match("ERROR in process_expression_list\nNo ( was found\n", "(");
    require(NULL != global_token, "Improper function call\n");
    int passed = 0;

    if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture))
    {
        emit_out("PUSHR R13 R15\t# Prevent overwriting in recursion\n");
        emit_out("PUSHR R14 R15\t# Protect the old base pointer\n");
        emit_out("COPY R13 R15\t# Copy new base pointer\n");
    }
    else if(X86 == Architecture)
    {
        emit_out("push_edi\t# Prevent overwriting in recursion\n");
        emit_out("push_ebp\t# Protect the old base pointer\n");
        emit_out("mov_edi,esp\t# Copy new base pointer\n");
    }
    else if(AMD64 == Architecture)
    {
        emit_out("push_rdi\t# Prevent overwriting in recursion\n");
        emit_out("push_rbp\t# Protect the old base pointer\n");
        emit_out("mov_rdi,rsp\t# Copy new base pointer\n");
    }
    else if(ARMV7L == Architecture)
    {
        emit_out("{R11} PUSH_ALWAYS\t# Prevent overwriting in recursion\n");
        emit_out("{BP} PUSH_ALWAYS\t# Protect the old base pointer\n");
        emit_out("'0' SP R11 NO_SHIFT MOVE_ALWAYS\t# Copy new base pointer\n");
    }
    else if(AARCH64 == Architecture)
    {
        emit_out("PUSH_X16\t# Protect a tmp register we're going to use\n");
        emit_out("PUSH_LR\t# Protect the old return pointer (link)\n");
        emit_out("PUSH_BP\t# Protect the old base pointer\n");
        emit_out("SET_X16_FROM_SP\t# The base pointer to-be\n");
    }
    else if(RISCV32 == Architecture)
    {
        emit_out("RD_SP RS1_SP !-12 ADDI\t# Allocate stack\n");
        emit_out("RS1_SP RS2_RA @4 SW\t# Protect the old return pointer\n");
        emit_out("RS1_SP RS2_FP SW\t# Protect the old frame pointer\n");
        emit_out("RS1_SP RS2_TP @8 SW\t# Protect temp register we are going to use\n");
        emit_out("RD_TP RS1_SP MV\t# The base pointer to-be\n");
    }
    else if(RISCV64 == Architecture)
    {
        emit_out("RD_SP RS1_SP !-24 ADDI\t# Allocate stack\n");
        emit_out("RS1_SP RS2_RA @8 SD\t# Protect the old return pointer\n");
        emit_out("RS1_SP RS2_FP SD\t# Protect the old frame pointer\n");
        emit_out("RS1_SP RS2_TP @16 SD\t# Protect temp register we are going to use\n");
        emit_out("RD_TP RS1_SP MV\t# The base pointer to-be\n");
    }

    if(global_token->s[0] != ')')
    {
        expression();
        require(NULL != global_token, "incomplete function call, received EOF instead of )\n");
        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("PUSHR R0 R15\t#_process_expression1\n");
        else if(X86 == Architecture) emit_out("push_eax\t#_process_expression1\n");
        else if(AMD64 == Architecture) emit_out("push_rax\t#_process_expression1\n");
        else if(ARMV7L == Architecture) emit_out("{R0} PUSH_ALWAYS\t#_process_expression1\n");
        else if(AARCH64 == Architecture) emit_out("PUSH_X0\t#_process_expression1\n");
        else if(RISCV32 == Architecture) emit_out("RD_SP RS1_SP !-4 ADDI\nRS1_SP RS2_A0 SW\t#_process_expression1\n");
        else if(RISCV64 == Architecture) emit_out("RD_SP RS1_SP !-8 ADDI\nRS1_SP RS2_A0 SD\t#_process_expression1\n");
        passed = 1;

        while(global_token->s[0] == ',')
        {
            global_token = global_token->next;
            require(NULL != global_token, "incomplete function call, received EOF instead of argument\n");
            expression();
            if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("PUSHR R0 R15\t#_process_expression2\n");
            else if(X86 == Architecture) emit_out("push_eax\t#_process_expression2\n");
            else if(AMD64 == Architecture) emit_out("push_rax\t#_process_expression2\n");
            else if(ARMV7L == Architecture) emit_out("{R0} PUSH_ALWAYS\t#_process_expression2\n");
            else if(AARCH64 == Architecture) emit_out("PUSH_X0\t#_process_expression2\n");
            else if(RISCV32 == Architecture) emit_out("RD_SP RS1_SP !-4 ADDI\nRS1_SP RS2_A0 SW\t#_process_expression2\n");
            else if(RISCV64 == Architecture) emit_out("RD_SP RS1_SP !-8 ADDI\nRS1_SP RS2_A0 SD\t#_process_expression2\n");
            passed = passed + 1;
        }
    }

    require_match("ERROR in process_expression_list\nNo ) was found\n", ")");

    if(TRUE == bool)
    {
        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture))
        {
            emit_out("LOAD R0 R14 ");
            emit_out(s);
            emit_out("\nMOVE R14 R13\n");
            emit_out("CALL R0 R15\n");
        }
        else if(X86 == Architecture)
        {
            emit_out("lea_eax,[ebp+DWORD] %");
            emit_out(s);
            emit_out("\nmov_eax,[eax]\n");
            emit_out("mov_ebp,edi\n");
            emit_out("call_eax\n");
        }
        else if(AMD64 == Architecture)
        {
            emit_out("lea_rax,[rbp+DWORD] %");
            emit_out(s);
            emit_out("\nmov_rax,[rax]\n");
            emit_out("mov_rbp,rdi\n");
            emit_out("call_rax\n");
        }
        else if(ARMV7L == Architecture)
        {
            emit_out("!");
            emit_out(s);
            emit_out(" R0 SUB BP ARITH_ALWAYS\n");
            emit_out("!0 R0 LOAD32 R0 MEMORY\n");
            emit_out("{LR} PUSH_ALWAYS\t# Protect the old link register\n");
            emit_out("'0' R11 BP NO_SHIFT MOVE_ALWAYS\n");
            emit_out("'3' R0 CALL_REG_ALWAYS\n");
            emit_out("{LR} POP_ALWAYS\t# Prevent overwrite\n");
        }
        else if(AARCH64 == Architecture)
        {
            emit_out("SET_X0_FROM_BP\n");
            emit_out("LOAD_W1_AHEAD\nSKIP_32_DATA\n%");
            emit_out(s);
            emit_out("\nSUB_X0_X0_X1\n");
            emit_out("DEREF_X0\n");
            emit_out("SET_BP_FROM_X16\n");
            emit_out("SET_X16_FROM_X0\n");
            emit_out("BLR_X16\n");
        }
        else if(RISCV32 == Architecture)
        {
            emit_out("RD_A0 RS1_FP !");
            emit_out(s);
            emit_out(" ADDI\n");
            emit_out("RD_A0 RS1_A0 LW\n");
            emit_out("RD_FP RS1_TP MV\n");
            emit_out("RD_RA RS1_A0 JALR\n");
        }
        else if(RISCV64 == Architecture)
        {
            emit_out("RD_A0 RS1_FP !");
            emit_out(s);
            emit_out(" ADDI\n");
            emit_out("RD_A0 RS1_A0 LD\n");
            emit_out("RD_FP RS1_TP MV\n");
            emit_out("RD_RA RS1_A0 JALR\n");
        }
    }
    else
    {
        if((KNIGHT_NATIVE == Architecture) || (KNIGHT_POSIX == Architecture))
        {
            emit_out("MOVE R14 R13\n");
            emit_out("LOADR R0 4\nJUMP 4\n&FUNCTION_");
            emit_out(s);
            emit_out("\nCALL R0 R15\n");
        }
        else if(X86 == Architecture)
        {
            emit_out("mov_ebp,edi\n");
            emit_out("call %FUNCTION_");
            emit_out(s);
            emit_out("\n");
        }
        else if(AMD64 == Architecture)
        {
            emit_out("mov_rbp,rdi\n");
            emit_out("call %FUNCTION_");
            emit_out(s);
            emit_out("\n");
        }
        else if(ARMV7L == Architecture)
        {
            emit_out("{LR} PUSH_ALWAYS\t# Protect the old link register\n");
            emit_out("'0' R11 BP NO_SHIFT MOVE_ALWAYS\n");
            emit_out("^~FUNCTION_");
            emit_out(s);
            emit_out(" CALL_ALWAYS\n");
            emit_out("{LR} POP_ALWAYS\t# Restore the old link register\n");
        }
        else if(AARCH64 == Architecture)
        {
            emit_out("SET_BP_FROM_X16\n");
            emit_out("LOAD_W16_AHEAD\nSKIP_32_DATA\n&FUNCTION_");
            emit_out(s);
            emit_out("\n");
            emit_out("BLR_X16\n");
        }
        else if((RISCV32 == Architecture) || (RISCV64 == Architecture))
        {
            emit_out("RD_FP RS1_TP MV\n");
            emit_out("RD_RA $FUNCTION_");
            emit_out(s);
            emit_out(" JAL\n");
        }
    }

    for(; passed > 0; passed = passed - 1)
    {
        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("POPR R1 R15\t# _process_expression_locals\n");
        else if(X86 == Architecture) emit_out("pop_ebx\t# _process_expression_locals\n");
        else if(AMD64 == Architecture) emit_out("pop_rbx\t# _process_expression_locals\n");
        else if(ARMV7L == Architecture) emit_out("{R1} POP_ALWAYS\t# _process_expression_locals\n");
        else if(AARCH64 == Architecture) emit_out("POP_X1\t# _process_expression_locals\n");
        else if(RISCV32 == Architecture) emit_out("RD_A1 RS1_SP LW\t# _process_expression_locals\nRD_SP RS1_SP !4 ADDI\n");
        else if(RISCV64 == Architecture) emit_out("RD_A1 RS1_SP LD\t# _process_expression_locals\nRD_SP RS1_SP !8 ADDI\n");
    }

    if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture))
    {
        emit_out("POPR R14 R15\t# Restore old base pointer\n");
        emit_out("POPR R13 R15\t# Prevent overwrite\n");
    }
    else if(X86 == Architecture)
    {
        emit_out("pop_ebp\t# Restore old base pointer\n");
        emit_out("pop_edi\t# Prevent overwrite\n");
    }
    else if(AMD64 == Architecture)
    {
        emit_out("pop_rbp\t# Restore old base pointer\n");
        emit_out("pop_rdi\t# Prevent overwrite\n");
    }
    else if(ARMV7L == Architecture)
    {
        emit_out("{BP} POP_ALWAYS\t# Restore old base pointer\n");
        emit_out("{R11} POP_ALWAYS\t# Prevent overwrite\n");
    }
    else if(AARCH64 == Architecture)
    {
        emit_out("POP_BP\t# Restore the old base pointer\n");
        emit_out("POP_LR\t# Restore the old return pointer (link)\n");
        emit_out("POP_X16\t# Restore a register we used as tmp\n");
    }
    else if(RISCV32 == Architecture)
    {
        emit_out("RD_FP RS1_SP LW\t# Restore old frame pointer\n");
        emit_out("RD_TP RS1_SP !8 LW\t# Restore temp register\n");
        emit_out("RD_RA RS1_SP !4 LW\t# Restore return address\n");
        emit_out("RD_SP RS1_SP !12 ADDI\t# Deallocate stack\n");
    }
    else if(RISCV64 == Architecture)
    {
        emit_out("RD_FP RS1_SP LD\t# Restore old frame pointer\n");
        emit_out("RD_TP RS1_SP !16 LD\t# Restore temp register\n");
        emit_out("RD_RA RS1_SP !8 LD\t# Restore return address\n");
        emit_out("RD_SP RS1_SP !24 ADDI\t# Deallocate stack\n");
    }
}

void constant_load(struct token_list* a)
{
    if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("LOADI R0 ");
    else if(X86 == Architecture) emit_out("mov_eax, %");
    else if(AMD64 == Architecture) emit_out("mov_rax, %");
    else if(ARMV7L == Architecture) emit_out("!0 R0 LOAD32 R15 MEMORY\n~0 JUMP_ALWAYS\n%");
    else if(AARCH64 == Architecture) emit_out("LOAD_W0_AHEAD\nSKIP_32_DATA\n%");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture))
    {
        emit_out("RD_A0 ~");
        emit_out(a->arguments->s);
        emit_out(" LUI\nRD_A0 RS1_A0 !");
    }
    emit_out(a->arguments->s);
    if(RISCV32 == Architecture) emit_out(" ADDI\n");
    else if(RISCV64 == Architecture) emit_out(" ADDIW\n");
    emit_out("\n");
}

char* load_value_signed(unsigned size)
{
    if(size == 1)
    {
        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) return "LOAD8 R0 R0 0\n";
        else if(X86 == Architecture) return "movsx_eax,BYTE_PTR_[eax]\n";
        else if(AMD64 == Architecture) return "movsx_rax,BYTE_PTR_[rax]\n";
        else if(ARMV7L == Architecture) return "LOADS8 R0 LOAD R0 HALF_MEMORY\n";
        else if(AARCH64 == Architecture) return "LDRSB_X0_[X0]\n";
        else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) return "RD_A0 RS1_A0 LB\n";
    }
    else if(size == 2)
    {
        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) return "LOAD16 R0 R0 0\n";
        else if(X86 == Architecture) return "movsx_eax,WORD_PTR_[eax]\n";
        else if(AMD64 == Architecture) return "movsx_rax,WORD_PTR_[rax]\n";
        else if(ARMV7L == Architecture) return "LOADS16 R0 LOAD R0 HALF_MEMORY\n";
        else if(AARCH64 == Architecture) return "LDRSH_X0_[X0]\n";
        else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) return "RD_A0 RS1_A0 LH\n";
    }
    else if(size == 4)
    {
        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) return "LOAD R0 R0 0\n";
        else if(X86 == Architecture) return "mov_eax,[eax]\n";
        else if(AMD64 == Architecture) return "movsx_rax,DWORD_PTR_[rax]\n";
        else if(ARMV7L == Architecture) return "!0 R0 LOAD32 R0 MEMORY\n";
        else if(AARCH64 == Architecture) return "LDR_W0_[X0]\n";
        else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) return "RD_A0 RS1_A0 LW\n";
    }
    else if(size == 8)
    {
        if(AMD64 == Architecture) return "mov_rax,[rax]\n";
        else if(AARCH64 == Architecture) return "DEREF_X0\n";
        else if(RISCV64 == Architecture) return "RD_A0 RS1_A0 LD\n";
    }
    line_error();
    fputs(" Got unsupported size ", stderr);
    fputs(int2str(size, 10, TRUE), stderr);
    fputs(" when trying to load value.\n", stderr);
    exit(EXIT_FAILURE);
}

char* load_value_unsigned(unsigned size)
{
    if(size == 1)
    {
        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) return "LOADU8 R0 R0 0\n";
        else if(X86 == Architecture) return "movzx_eax,BYTE_PTR_[eax]\n";
        else if(AMD64 == Architecture) return "movzx_rax,BYTE_PTR_[rax]\n";
        else if(ARMV7L == Architecture) return "!0 R0 LOAD R0 MEMORY\n";
        else if(AARCH64 == Architecture) return "DEREF_X0_BYTE\n";
        else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) return "RD_A0 RS1_A0 LBU\n";
    }
    else if(size == 2)
    {
        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) return "LOADU16 R0 R0 0\n";
        else if(X86 == Architecture) return "movzx_eax,WORD_PTR_[eax]\n";
        else if(AMD64 == Architecture) return "movzx_rax,WORD_PTR_[rax]\n";
        else if(ARMV7L == Architecture) return "NO_OFFSET R0 LOAD R0 HALF_MEMORY\n";
        else if(AARCH64 == Architecture) return "LDRH_W0_[X0]\n";
        else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) return "RD_A0 RS1_A0 LHU\n";
    }
    else if(size == 4)
    {
        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) return "LOAD R0 R0 0\n";
        else if(X86 == Architecture) return "mov_eax,[eax]\n";
        else if(AMD64 == Architecture) return "mov_eax,[rax]\n";
        else if(ARMV7L == Architecture) return "!0 R0 LOAD32 R0 MEMORY\n";
        else if(AARCH64 == Architecture) return "LDR_W0_[X0]\n";
        else if(RISCV32 == Architecture) return "RD_A0 RS1_A0 LW\n";
        else if(RISCV64 == Architecture) return "RD_A0 RS1_A0 LWU\n";
    }
    else if(size == 8)
    {
        if(AMD64 == Architecture) return "mov_rax,[rax]\n";
        else if(AARCH64 == Architecture) return "DEREF_X0\n";
        else if(RISCV64 == Architecture) return "RD_A0 RS1_A0 LD\n";
    }
    line_error();
    fputs(" Got unsupported size ", stderr);
    fputs(int2str(size, 10, TRUE), stderr);
    fputs(" when trying to load value.\n", stderr);
    exit(EXIT_FAILURE);
}

char* load_value(unsigned size, int is_signed)
{
    if(is_signed) return load_value_signed(size);
    return load_value_unsigned(size);
}

char* store_value(unsigned size)
{
    if(size == 1)
    {
        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) return "STORE8 R0 R1 0\n";
        else if(X86 == Architecture) return "mov_[ebx],al\n";
        else if(AMD64 == Architecture) return "mov_[rbx],al\n";
        else if(ARMV7L == Architecture) return "!0 R0 STORE8 R1 MEMORY\n";
        else if(AARCH64 == Architecture) return "STR_BYTE_W0_[X1]\n";
        else if(RISCV32 == Architecture) return "RS1_A1 RS2_A0 SB\n";
        else if(RISCV64 == Architecture) return "RS1_A1 RS2_A0 SB\n";
    }
    else if(size == 2)
    {
        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) return "STORE16 R0 R1 0\n";
        else if(X86 == Architecture) return "mov_[ebx],ax\n";
        else if(AMD64 == Architecture) return "mov_[rbx],ax\n";
        else if(ARMV7L == Architecture) return "NO_OFFSET R0 STORE16 R1 HALF_MEMORY\n";
        else if(AARCH64 == Architecture) return "STRH_W0_[X1]\n";
        else if(RISCV32 == Architecture || RISCV64 == Architecture) return "RS1_A1 RS2_A0 SH\n";
    }
    else if(size == 4)
    {
        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) return "STORE R0 R1 0\n";
        else if(X86 == Architecture) return "mov_[ebx],eax\n";
        else if(AMD64 == Architecture) return "mov_[rbx],eax\n";
        else if(ARMV7L == Architecture) return "!0 R0 STORE32 R1 MEMORY\n";
        else if(AARCH64 == Architecture) return "STR_W0_[X1]\n";
        else if(RISCV32 == Architecture || RISCV64 == Architecture) return "RS1_A1 RS2_A0 SW\n";
    }
    else if(size == 8)
    {
        if(AMD64 == Architecture) return "mov_[rbx],rax\n";
        else if(AARCH64 == Architecture) return "STR_X0_[X1]\n";
        else if(RISCV64 == Architecture) return "RS1_A1 RS2_A0 SD\n";
    }
    /* Should not happen but print error message. */
    fputs("Got unsupported size ", stderr);
    fputs(int2str(size, 10, TRUE), stderr);
    fputs(" when storing number in register.\n", stderr);
    line_error();
    exit(EXIT_FAILURE);
}

int is_compound_assignment(char* token)
{
    if(match("+=", token)) return TRUE;
    else if(match("-=", token)) return TRUE;
    else if(match("*=", token)) return TRUE;
    else if(match("/=", token)) return TRUE;
    else if(match("%=", token)) return TRUE;
    else if(match("<<=", token)) return TRUE;
    else if(match(">>=", token)) return TRUE;
    else if(match("&=", token)) return TRUE;
    else if(match("^=", token)) return TRUE;
    else if(match("|=", token)) return TRUE;
    return FALSE;
}

void postfix_expr_stub();
void variable_load(struct token_list* a, int num_dereference)
{
    require(NULL != global_token, "incomplete variable load received\n");
    if((match("FUNCTION", a->type->name) || match("FUNCTION*", a->type->name)) && match("(", global_token->s))
    {
        function_call(int2str(a->depth, 10, TRUE), TRUE);
        return;
    }
    current_target = a->type;

    if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("ADDI R0 R14 ");
    else if(X86 == Architecture) emit_out("lea_eax,[ebp+DWORD] %");
    else if(AMD64 == Architecture) emit_out("lea_rax,[rbp+DWORD] %");
    else if(ARMV7L == Architecture) emit_out("!");
    else if(AARCH64 == Architecture) emit_out("SET_X0_FROM_BP\nLOAD_W1_AHEAD\nSKIP_32_DATA\n%");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("RD_A0 RS1_FP !");

    emit_out(int2str(a->depth, 10, TRUE));
    if(ARMV7L == Architecture) emit_out(" R0 SUB BP ARITH_ALWAYS");
    else if(AARCH64 == Architecture) emit_out("\nSUB_X0_X0_X1\n");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out(" ADDI");
    emit_out("\n");

    if(TRUE == Address_of) return;
    if(match(".", global_token->s))
    {
        postfix_expr_stub();
        return;
    }
    if(!match("=", global_token->s) && !is_compound_assignment(global_token->s))
    {
        emit_out(load_value(current_target->size, current_target->is_signed));
    }

    while (num_dereference > 0)
    {
        current_target = current_target->type;
        emit_out(load_value(current_target->size, current_target->is_signed));
        num_dereference = num_dereference - 1;
    }
}

void function_load(struct token_list* a)
{
    require(NULL != global_token, "incomplete function load\n");
    if(match("(", global_token->s))
    {
        function_call(a->s, FALSE);
        return;
    }

    if((KNIGHT_NATIVE == Architecture) || (KNIGHT_POSIX == Architecture)) emit_out("LOADR R0 4\nJUMP 4\n&FUNCTION_");
    else if(X86 == Architecture) emit_out("mov_eax, &FUNCTION_");
    else if(AMD64 == Architecture) emit_out("lea_rax,[rip+DWORD] %FUNCTION_");
    else if(ARMV7L == Architecture) emit_out("!0 R0 LOAD32 R15 MEMORY\n~0 JUMP_ALWAYS\n&FUNCTION_");
    else if(AARCH64 == Architecture) emit_out("LOAD_W0_AHEAD\nSKIP_32_DATA\n&FUNCTION_");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("RD_A0 ~FUNCTION_");
    emit_out(a->s);
    if(RISCV32 == Architecture)
    {
        emit_out(" AUIPC\n");
        emit_out("RD_A0 RS1_A0 !FUNCTION_");
        emit_out(a->s);
        emit_out(" ADDI");
    }
    else if(RISCV64 == Architecture)
    {
        emit_out(" AUIPC\n");
        emit_out("RD_A0 RS1_A0 !FUNCTION_");
        emit_out(a->s);
        emit_out(" ADDIW");
    }
    emit_out("\n");
}

void global_load(struct token_list* a)
{
    current_target = a->type;
    if((KNIGHT_NATIVE == Architecture) || (KNIGHT_POSIX == Architecture)) emit_out("LOADR R0 4\nJUMP 4\n&GLOBAL_");
    else if(X86 == Architecture) emit_out("mov_eax, &GLOBAL_");
    else if(AMD64 == Architecture) emit_out("lea_rax,[rip+DWORD] %GLOBAL_");
    else if(ARMV7L == Architecture) emit_out("!0 R0 LOAD32 R15 MEMORY\n~0 JUMP_ALWAYS\n&GLOBAL_");
    else if(AARCH64 == Architecture) emit_out("LOAD_W0_AHEAD\nSKIP_32_DATA\n&GLOBAL_");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("RD_A0 ~GLOBAL_");
    emit_out(a->s);
    if((RISCV32 == Architecture) || (RISCV64 == Architecture))
    {
        emit_out(" AUIPC\n");
        emit_out("RD_A0 RS1_A0 !GLOBAL_");
        emit_out(a->s);
        emit_out(" ADDI");
    }
    emit_out("\n");

    require(NULL != global_token, "unterminated global load\n");
    if(TRUE == Address_of) return;
    if(match(".", global_token->s))
    {
        postfix_expr_stub();
        return;
    }
    if(match("=", global_token->s) || is_compound_assignment(global_token->s)) return;

    emit_out(load_value(register_size, current_target->is_signed));
}

/*
 * primary-expr:
 * FAILURE
 * "String"
 * 'Char'
 * [0-9]*
 * [a-z,A-Z]*
 * ( expression )
 */

void primary_expr_failure()
{
    require(NULL != global_token, "hit EOF when expecting primary expression\n");
    line_error();
    fputs("Received ", stderr);
    fputs(global_token->s, stderr);
    fputs(" in primary_expr\n", stderr);
    exit(EXIT_FAILURE);
}

void primary_expr_string()
{
    char* number_string = int2str(current_count, 10, TRUE);
    current_count = current_count + 1;
    if((KNIGHT_NATIVE == Architecture) || (KNIGHT_POSIX == Architecture)) emit_out("LOADR R0 4\nJUMP 4\n&STRING_");
    else if(X86 == Architecture) emit_out("mov_eax, &STRING_");
    else if(AMD64 == Architecture) emit_out("lea_rax,[rip+DWORD] %STRING_");
    else if(ARMV7L == Architecture) emit_out("!0 R0 LOAD32 R15 MEMORY\n~0 JUMP_ALWAYS\n&STRING_");
    else if(AARCH64 == Architecture) emit_out("LOAD_W0_AHEAD\nSKIP_32_DATA\n&STRING_");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("RD_A0 ~STRING_");
    uniqueID_out(function->s, number_string);
    if((RISCV32 == Architecture) || (RISCV64 == Architecture))
    {
        emit_out("AUIPC\n");
        emit_out("RD_A0 RS1_A0 !STRING_");
        uniqueID_out(function->s, number_string);
        emit_out("ADDI\n");
    }

    /* The target */
    strings_list = emit(":STRING_", strings_list);
    strings_list = uniqueID(function->s, strings_list, number_string);

    /* catch case of just "foo" from segfaulting */
    require(NULL != global_token->next, "a string by itself is not valid C\n");

    /* Parse the string */
    if('"' != global_token->next->s[0])
    {
        strings_list = emit(parse_string(global_token->s), strings_list);
        global_token = global_token->next;
    }
    else
    {
        char* s = calloc(MAX_STRING, sizeof(char));

        /* prefix leading string */
        s[0] = '"';
        int i = 1;

        int j;
        while('"' == global_token->s[0])
        {
            /* Step past the leading '"' */
            j = 1;

            /* Copy the rest of the string as is */
            while(0 != global_token->s[j])
            {
                require(i < MAX_STRING, "concat string exceeded max string length\n");
                s[i] = global_token->s[j];
                i = i + 1;
                j = j + 1;
            }

            /* Move on to the next token */
            global_token = global_token->next;
            require(NULL != global_token, "multi-string null is not valid C\n");
        }

        /* Now use it */
        strings_list = emit(parse_string(s), strings_list);
    }
}

void primary_expr_char()
{
    if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("LOADI R0 ");
    else if(X86 == Architecture) emit_out("mov_eax, %");
    else if(AMD64 == Architecture) emit_out("mov_rax, %");
    else if(ARMV7L == Architecture) emit_out("!");
    else if(AARCH64 == Architecture) emit_out("LOAD_W0_AHEAD\nSKIP_32_DATA\n%");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("RD_A0 !");
    emit_out(int2str(escape_lookup(global_token->s + 1), 10, TRUE));
    if(ARMV7L == Architecture) emit_out(" R0 LOADI8_ALWAYS");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out(" ADDI");
    emit_out("\n");
    global_token = global_token->next;
}

int hex2char(int c)
{
    if((c >= 0) && (c <= 9)) return (c + 48);
    else if((c >= 10) && (c <= 15)) return (c + 55);
    else return -1;
}

char* number_to_hex(int a, int bytes)
{
    require(bytes > 0, "number to hex must have a positive number of bytes greater than zero\n");
    char* result = calloc(1 + (bytes << 1), sizeof(char));
    if(NULL == result)
    {
        fputs("calloc failed in number_to_hex\n", stderr);
        exit(EXIT_FAILURE);
    }
    int i = 0;

    int divisor = (bytes << 3);
    require(divisor > 0, "unexpected wrap around in number_to_hex\n");

    /* Simply collect numbers until divisor is gone */
    while(0 != divisor)
    {
        divisor = divisor - 4;
        result[i] = hex2char((a >> divisor) & 0xF);
        i = i + 1;
    }

    return result;
}

void primary_expr_number()
{
    if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture))
    {
        int size = strtoint(global_token->s);
        if((32767 > size) && (size > -32768))
        {
            emit_out("LOADI R0 ");
            emit_out(global_token->s);
        }
        else
        {
            emit_out("LOADR R0 4\nJUMP 4\n'");
            emit_out(number_to_hex(size, register_size));
            emit_out("'");
        }
    }
    else if(X86 == Architecture)
    {
        emit_out("mov_eax, %");
        emit_out(global_token->s);
    }
    else if(AMD64 == Architecture)
    {
        emit_out("mov_rax, %");
        emit_out(global_token->s);
    }
    else if(ARMV7L == Architecture)
    {
        emit_out("!0 R0 LOAD32 R15 MEMORY\n~0 JUMP_ALWAYS\n%");
        emit_out(global_token->s);
    }
    else if(AARCH64 == Architecture)
    {
        emit_out("LOAD_W0_AHEAD\nSKIP_32_DATA\n%");
        emit_out(global_token->s);
    }
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture))
    {
        int size = strtoint(global_token->s);
        if((2047 > size) && (size > -2048))
        {
            emit_out("RD_A0 !");
            emit_out(global_token->s);
            emit_out(" ADDI");
        }
        else if (0 == (size >> 30))
        {
            emit_out("RD_A0 ~");
            emit_out(global_token->s);
            emit_out(" LUI\n");
            emit_out("RD_A0 RS1_A0 !");
            emit_out(global_token->s);
            emit_out(" ADDI");
        }
        else
        {
            int high = size >> 30;
            int low = ((size >> 30) << 30) ^ size;
            emit_out("RD_A0 ~");
            emit_out(int2str(high, 10, TRUE));
            emit_out(" LUI\n");
            emit_out("RD_A0 RS1_A0 !");
            emit_out(int2str(high, 10, TRUE));
            emit_out(" ADDI\n");
            emit_out("RD_A0 RS1_A0 RS2_X30 SLLI\n");
            emit_out("RD_T1 ~");
            emit_out(int2str(low, 10, TRUE));
            emit_out(" LUI\n");
            emit_out("RD_T1 RS1_T1 !");
            emit_out(int2str(low, 10, TRUE));
            emit_out(" ADDI\n");
            emit_out("RD_A0 RS1_A0 RS2_T1 OR\n");
        }
    }
    emit_out("\n");
    global_token = global_token->next;
}

void primary_expr_variable()
{
    int num_dereference = 0;
    while(global_token->s[0] == '*') {
        global_token = global_token->next;
        require(NULL != global_token, "Walked off the end of a variable dereference\n");
        num_dereference = num_dereference + 1;
    }
    char* s = global_token->s;
    global_token = global_token->next;
    struct token_list* a = sym_lookup(s, global_constant_list);
    if(NULL != a)
    {
        constant_load(a);
        return;
    }

    a = sym_lookup(s, function->locals);
    if(NULL != a)
    {
        variable_load(a, num_dereference);
        return;
    }

    a = sym_lookup(s, function->arguments);
    if(NULL != a)
    {
        variable_load(a, num_dereference);
        return;
    }

    a = sym_lookup(s, global_function_list);
    if(NULL != a)
    {
        function_load(a);
        return;
    }

    a = sym_lookup(s, global_symbol_list);
    if(NULL != a)
    {
        global_load(a);
        return;
    }

    line_error();
    fputs(s ,stderr);
    fputs(" is not a defined symbol\n", stderr);
    exit(EXIT_FAILURE);
}

void primary_expr();
struct type* promote_type(struct type* a, struct type* b)
{
    require(NULL != b, "impossible case 1 in promote_type\n");
    require(NULL != a, "impossible case 2 in promote_type\n");

    if(a == b) return a;

    struct type* i;
    for(i = global_types; NULL != i; i = i->next)
    {
        if(a->name == i->name) break;
        if(b->name == i->name) break;
        if(a->name == i->indirect->name) break;
        if(b->name == i->indirect->name) break;
        if(a->name == i->indirect->indirect->name) break;
        if(b->name == i->indirect->indirect->name) break;
    }
    require(NULL != i, "impossible case 3 in promote_type\n");
    return i;
}

void common_recursion(FUNCTION f)
{
    if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("PUSHR R0 R15\t#_common_recursion\n");
    else if(X86 == Architecture) emit_out("push_eax\t#_common_recursion\n");
    else if(AMD64 == Architecture) emit_out("push_rax\t#_common_recursion\n");
    else if(ARMV7L == Architecture) emit_out("{R0} PUSH_ALWAYS\t#_common_recursion\n");
    else if(AARCH64 == Architecture) emit_out("PUSH_X0\t#_common_recursion\n");
    else if(RISCV32 == Architecture) emit_out("RD_SP RS1_SP !-4 ADDI\t# _common_recursion\nRS1_SP RS2_A0 SW\n");
    else if(RISCV64 == Architecture) emit_out("RD_SP RS1_SP !-8 ADDI\t# _common_recursion\nRS1_SP RS2_A0 SD\n");

    struct type* last_type = current_target;
    global_token = global_token->next;
    require(NULL != global_token, "Received EOF in common_recursion\n");
    f();
    current_target = promote_type(current_target, last_type);

    if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("POPR R1 R15\t# _common_recursion\n");
    else if(X86 == Architecture) emit_out("pop_ebx\t# _common_recursion\n");
    else if(AMD64 == Architecture) emit_out("pop_rbx\t# _common_recursion\n");
    else if(ARMV7L == Architecture) emit_out("{R1} POP_ALWAYS\t# _common_recursion\n");
    else if(AARCH64 == Architecture) emit_out("POP_X1\t# _common_recursion\n");
    else if(RISCV32 == Architecture) emit_out("RD_A1 RS1_SP LW\nRD_SP RS1_SP !4 ADDI\t# _common_recursion\n");
    else if(RISCV64 == Architecture) emit_out("RD_A1 RS1_SP LD\nRD_SP RS1_SP !8 ADDI\t# _common_recursion\n");
}

void general_recursion(FUNCTION f, char* s, char* name, FUNCTION iterate)
{
    require(NULL != global_token, "Received EOF in general_recursion\n");
    if(match(name, global_token->s))
    {
        common_recursion(f);
        emit_out(s);
        iterate();
    }
}

void arithmetic_recursion(FUNCTION f, char* s1, char* s2, char* name, FUNCTION iterate)
{
    require(NULL != global_token, "Received EOF in arithmetic_recursion\n");
    if(match(name, global_token->s))
    {
        common_recursion(f);
        if(NULL == current_target)
        {
            emit_out(s1);
        }
        else if(current_target->is_signed)
        {
            emit_out(s1);
        }
        else
        {
            emit_out(s2);
        }
        iterate();
    }
}


/*
 * postfix-expr:
 *         primary-expr
 *         postfix-expr [ expression ]
 *         postfix-expr ( expression-list-opt )
 *         postfix-expr -> member
 *         postfix-expr . member
 */
struct type* lookup_member(struct type* parent, char* name);
void postfix_expr_arrow()
{
    emit_out("# looking up offset\n");
    global_token = global_token->next;
    require(NULL != global_token, "naked -> not allowed\n");

    struct type* i = lookup_member(current_target, global_token->s);
    current_target = i->type;
    global_token = global_token->next;
    require(NULL != global_token, "Unterminated -> expression not allowed\n");

    if(0 != i->offset)
    {
        emit_out("# -> offset calculation\n");
        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture))
        {
            emit_out("ADDUI R0 R0 ");
            emit_out(int2str(i->offset, 10, TRUE));
            emit_out("\n");
        }
        else if(X86 == Architecture)
        {
            emit_out("mov_ebx, %");
            emit_out(int2str(i->offset, 10, TRUE));
            emit_out("\nadd_eax,ebx\n");
        }
        else if(AMD64 == Architecture)
        {
            emit_out("mov_rbx, %");
            emit_out(int2str(i->offset, 10, TRUE));
            emit_out("\nadd_rax,rbx\n");
        }
        else if(ARMV7L == Architecture)
        {
            emit_out("!0 R1 LOAD32 R15 MEMORY\n~0 JUMP_ALWAYS\n%");
            emit_out(int2str(i->offset, 10, TRUE));
            emit_out("\n'0' R0 R0 ADD R1 ARITH2_ALWAYS\n");
        }
        else if(AARCH64 == Architecture)
        {
            emit_out("LOAD_W1_AHEAD\nSKIP_32_DATA\n%");
            emit_out(int2str(i->offset, 10, TRUE));
            emit_out("\nADD_X0_X1_X0\n");
        }
        else if((RISCV32 == Architecture) || (RISCV64 == Architecture))
        {
            emit_out("RD_A1 !");
            emit_out(int2str(i->offset, 10, TRUE));
            emit_out(" ADDI\n");
            emit_out("RD_A0 RS1_A1 RS2_A0 ADD\n");
        }
    }

    /* We don't yet support assigning structs to structs */
    if((!match("=", global_token->s) && !is_compound_assignment(global_token->s) && (register_size >= i->size)))
    {
        emit_out(load_value(i->size, i->is_signed));
    }
}

void postfix_expr_dot()
{
    maybe_bootstrap_error("Member access using .");
    emit_out("# looking up offset\n");
    global_token = global_token->next;
    require(NULL != global_token, "naked . not allowed\n");

    struct type* i = lookup_member(current_target, global_token->s);
    current_target = i->type;
    global_token = global_token->next;
    require(NULL != global_token, "Unterminated . expression not allowed\n");

    if(0 != i->offset)
    {
        emit_out("# . offset calculation\n");
        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture))
        {
            emit_out("ADDUI R0 R0 ");
            emit_out(int2str(i->offset, 10, TRUE));
            emit_out("\n");
        }
        else if(X86 == Architecture)
        {
            emit_out("mov_ebx, %");
            emit_out(int2str(i->offset, 10, TRUE));
            emit_out("\nadd_eax,ebx\n");
        }
        else if(AMD64 == Architecture)
        {
            emit_out("mov_rbx, %");
            emit_out(int2str(i->offset, 10, TRUE));
            emit_out("\nadd_rax,rbx\n");
        }
        else if(ARMV7L == Architecture)
        {
            emit_out("!0 R1 LOAD32 R15 MEMORY\n~0 JUMP_ALWAYS\n%");
            emit_out(int2str(i->offset, 10, TRUE));
            emit_out("\n'0' R0 R0 ADD R1 ARITH2_ALWAYS\n");
        }
        else if(AARCH64 == Architecture)
        {
            emit_out("LOAD_W1_AHEAD\nSKIP_32_DATA\n%");
            emit_out(int2str(i->offset, 10, TRUE));
            emit_out("\nADD_X0_X1_X0\n");
        }
        else if((RISCV32 == Architecture) || (RISCV64 == Architecture))
        {
            emit_out("RD_A1 !");
            emit_out(int2str(i->offset, 10, TRUE));
            emit_out(" ADDI\n");
            emit_out("RD_A0 RS1_A1 RS2_A0 ADD\n");
        }
    }
    if(match("=", global_token->s) || is_compound_assignment(global_token->s)) return;
    if(match("[", global_token->s)) return;

    emit_out(load_value(current_target->size, current_target->is_signed));
}

void postfix_expr_array()
{
    struct type* array = current_target;
    common_recursion(expression);
    current_target = array;
    require(NULL != current_target, "Arrays only apply to variables\n");

    char* assign = load_value(register_size, current_target->is_signed);

    /* Add support for Ints */
    if(match("char*", current_target->name))
    {
        assign = load_value(1, TRUE);
    }
    else
    {
        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("PUSHR R1 R15\nLOADI R1 ");
        else if(X86 == Architecture) emit_out("push_ebx\nmov_ebx, %");
        else if(AMD64 == Architecture) emit_out("push_rbx\nmov_rbx, %");
        else if(ARMV7L == Architecture) emit_out("{R1} PUSH_ALWAYS\n!0 R1 LOAD32 R15 MEMORY\n~0 JUMP_ALWAYS\n%");
        else if(AARCH64 == Architecture) emit_out("PUSH_X1\nLOAD_W1_AHEAD\nSKIP_32_DATA\n%");
        else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("RD_A2 RS1_A1 ADDI\nRD_A1 !");
        emit_out(int2str(current_target->type->size, 10, TRUE));
        if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out(" ADDI");

        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("\nMULU R0 R1 R0\nPOPR R1 R15\n");
        else if(X86 == Architecture) emit_out("\nmul_ebx\npop_ebx\n");
        else if(AMD64 == Architecture) emit_out("\nmul_rbx\npop_rbx\n");
        else if(ARMV7L == Architecture) emit_out("\n'9' R0 '0' R1 MUL R0 ARITH2_ALWAYS\n{R1} POP_ALWAYS\n");
        else if(AARCH64 == Architecture) emit_out("\nMUL_X0_X1_X0\nPOP_X1\n");
        else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("\nRD_A0 RS1_A1 RS2_A0 MUL\nRD_A1 RS1_A2 ADDI\n");
    }

    if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("ADD R0 R0 R1\n");
    else if(X86 == Architecture) emit_out("add_eax,ebx\n");
    else if(AMD64 == Architecture) emit_out("add_rax,rbx\n");
    else if(ARMV7L == Architecture) emit_out("'0' R0 R0 ADD R1 ARITH2_ALWAYS\n");
    else if(AARCH64 == Architecture) emit_out("ADD_X0_X1_X0\n");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("RD_A0 RS1_A1 RS2_A0 ADD\n");

    require_match("ERROR in postfix_expr\nMissing ]\n", "]");
    require(NULL != global_token, "truncated array expression\n");

    if(match("=", global_token->s) || is_compound_assignment(global_token->s) || match(".", global_token->s))
    {
        assign = "";
    }
    if(match("[", global_token->s))
    {
        current_target = current_target->type;
    }

    emit_out(assign);
}

/*
 * unary-expr:
 *         &postfix-expr
 *         - postfix-expr
 *         !postfix-expr
 *         sizeof ( type )
 */
struct type* type_name();
void unary_expr_sizeof()
{
    global_token = global_token->next;
    require(NULL != global_token, "Received EOF when starting sizeof\n");
    require_match("ERROR in unary_expr\nMissing (\n", "(");
    struct type* a = type_name();
    require_match("ERROR in unary_expr\nMissing )\n", ")");

    if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("LOADUI R0 ");
    else if(X86 == Architecture) emit_out("mov_eax, %");
    else if(AMD64 == Architecture) emit_out("mov_rax, %");
    else if(ARMV7L == Architecture) emit_out("!");
    else if(AARCH64 == Architecture) emit_out("LOAD_W0_AHEAD\nSKIP_32_DATA\n%");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("RD_A0 !");
    emit_out(int2str(a->size, 10, TRUE));
    if(ARMV7L == Architecture) emit_out(" R0 LOADI8_ALWAYS");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out(" ADDI");
    emit_out("\n");
}

void postfix_expr_stub()
{
    require(NULL != global_token, "Unexpected EOF, improperly terminated primary expression\n");
    if(match("[", global_token->s))
    {
        postfix_expr_array();
        postfix_expr_stub();
    }

    if(match("->", global_token->s))
    {
        postfix_expr_arrow();
        postfix_expr_stub();
    }

    if(match(".", global_token->s))
    {
        postfix_expr_dot();
        postfix_expr_stub();
    }
}

void postfix_expr()
{
    primary_expr();
    postfix_expr_stub();
}

/*
 * additive-expr:
 *         postfix-expr
 *         additive-expr * postfix-expr
 *         additive-expr / postfix-expr
 *         additive-expr % postfix-expr
 *         additive-expr + postfix-expr
 *         additive-expr - postfix-expr
 *         additive-expr << postfix-expr
 *         additive-expr >> postfix-expr
 */
void additive_expr_stub()
{
    if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture))
    {
        arithmetic_recursion(postfix_expr, "ADD R0 R1 R0\n", "ADDU R0 R1 R0\n", "+", additive_expr_stub);
        arithmetic_recursion(postfix_expr, "SUB R0 R1 R0\n", "SUBU R0 R1 R0\n", "-", additive_expr_stub);
        arithmetic_recursion(postfix_expr, "MUL R0 R1 R0\n", "MULU R0 R1 R0\n", "*", additive_expr_stub);
        arithmetic_recursion(postfix_expr, "DIV R0 R1 R0\n", "DIVU R0 R1 R0\n", "/", additive_expr_stub);
        arithmetic_recursion(postfix_expr, "MOD R0 R1 R0\n", "MODU R0 R1 R0\n", "%", additive_expr_stub);
        arithmetic_recursion(postfix_expr, "SAL R0 R1 R0\n", "SL0 R0 R1 R0\n", "<<", additive_expr_stub);
        arithmetic_recursion(postfix_expr, "SAR R0 R1 R0\n", "SR0 R0 R1 R0\n", ">>", additive_expr_stub);
    }
    else if(X86 == Architecture)
    {
        arithmetic_recursion(postfix_expr, "add_eax,ebx\n", "add_eax,ebx\n", "+", additive_expr_stub);
        arithmetic_recursion(postfix_expr, "sub_ebx,eax\nmov_eax,ebx\n", "sub_ebx,eax\nmov_eax,ebx\n", "-", additive_expr_stub);
        arithmetic_recursion(postfix_expr, "imul_ebx\n", "mul_ebx\n", "*", additive_expr_stub);
        arithmetic_recursion(postfix_expr, "xchg_ebx,eax\ncdq\nidiv_ebx\n", "xchg_ebx,eax\nmov_edx, %0\ndiv_ebx\n", "/", additive_expr_stub);
        arithmetic_recursion(postfix_expr, "xchg_ebx,eax\ncdq\nidiv_ebx\nmov_eax,edx\n", "xchg_ebx,eax\nmov_edx, %0\ndiv_ebx\nmov_eax,edx\n", "%", additive_expr_stub);
        arithmetic_recursion(postfix_expr, "mov_ecx,eax\nmov_eax,ebx\nsal_eax,cl\n", "mov_ecx,eax\nmov_eax,ebx\nshl_eax,cl\n", "<<", additive_expr_stub);
        arithmetic_recursion(postfix_expr, "mov_ecx,eax\nmov_eax,ebx\nsar_eax,cl\n", "mov_ecx,eax\nmov_eax,ebx\nshr_eax,cl\n", ">>", additive_expr_stub);
    }
    else if(AMD64 == Architecture)
    {
        arithmetic_recursion(postfix_expr, "add_rax,rbx\n", "add_rax,rbx\n", "+", additive_expr_stub);
        arithmetic_recursion(postfix_expr, "sub_rbx,rax\nmov_rax,rbx\n", "sub_rbx,rax\nmov_rax,rbx\n", "-", additive_expr_stub);
        arithmetic_recursion(postfix_expr, "imul_rbx\n", "mul_rbx\n", "*", additive_expr_stub);
        arithmetic_recursion(postfix_expr, "xchg_rbx,rax\ncqo\nidiv_rbx\n", "xchg_rbx,rax\nmov_rdx, %0\ndiv_rbx\n", "/", additive_expr_stub);
        arithmetic_recursion(postfix_expr, "xchg_rbx,rax\ncqo\nidiv_rbx\nmov_rax,rdx\n", "xchg_rbx,rax\nmov_rdx, %0\ndiv_rbx\nmov_rax,rdx\n", "%", additive_expr_stub);
        arithmetic_recursion(postfix_expr, "mov_rcx,rax\nmov_rax,rbx\nsal_rax,cl\n", "mov_rcx,rax\nmov_rax,rbx\nshl_rax,cl\n", "<<", additive_expr_stub);
        arithmetic_recursion(postfix_expr, "mov_rcx,rax\nmov_rax,rbx\nsar_rax,cl\n", "mov_rcx,rax\nmov_rax,rbx\nshr_rax,cl\n", ">>", additive_expr_stub);
    }
    else if(ARMV7L == Architecture)
    {
        arithmetic_recursion(postfix_expr, "'0' R0 R0 ADD R1 ARITH2_ALWAYS\n", "'0' R0 R0 ADD R1 ARITH2_ALWAYS\n", "+", additive_expr_stub);
        arithmetic_recursion(postfix_expr, "'0' R0 R0 SUB R1 ARITH2_ALWAYS\n", "'0' R0 R0 SUB R1 ARITH2_ALWAYS\n", "-", additive_expr_stub);
        arithmetic_recursion(postfix_expr, "'9' R0 '0' R1 MULS R0 ARITH2_ALWAYS\n", "'9' R0 '0' R1 MUL R0 ARITH2_ALWAYS\n", "*", additive_expr_stub);
        arithmetic_recursion(postfix_expr, "{LR} PUSH_ALWAYS\n^~divides CALL_ALWAYS\n{LR} POP_ALWAYS\n", "{LR} PUSH_ALWAYS\n^~divide CALL_ALWAYS\n{LR} POP_ALWAYS\n", "/", additive_expr_stub);
        arithmetic_recursion(postfix_expr, "{LR} PUSH_ALWAYS\n^~moduluss CALL_ALWAYS\n{LR} POP_ALWAYS\n", "{LR} PUSH_ALWAYS\n^~modulus CALL_ALWAYS\n{LR} POP_ALWAYS\n", "%", additive_expr_stub);
        arithmetic_recursion(postfix_expr, "LEFT R1 R0 R0 SHIFT AUX_ALWAYS\n", "LEFT R1 R0 R0 SHIFT AUX_ALWAYS\n", "<<", additive_expr_stub);
        arithmetic_recursion(postfix_expr, "ARITH_RIGHT R1 R0 R0 SHIFT AUX_ALWAYS\n", "RIGHT R1 R0 R0 SHIFT AUX_ALWAYS\n", ">>", additive_expr_stub);
    }
    else if(AARCH64 == Architecture)
    {
        general_recursion(postfix_expr, "ADD_X0_X1_X0\n", "+", additive_expr_stub);
        general_recursion(postfix_expr, "SUB_X0_X1_X0\n", "-", additive_expr_stub);
        general_recursion(postfix_expr, "MUL_X0_X1_X0\n", "*", additive_expr_stub);
        arithmetic_recursion(postfix_expr, "SDIV_X0_X1_X0\n", "UDIV_X0_X1_X0\n", "/", additive_expr_stub);
        arithmetic_recursion(postfix_expr, "SDIV_X2_X1_X0\nMSUB_X0_X0_X2_X1\n", "UDIV_X2_X1_X0\nMSUB_X0_X0_X2_X1\n", "%", additive_expr_stub);
        general_recursion(postfix_expr, "LSHIFT_X0_X1_X0\n", "<<", additive_expr_stub);
        arithmetic_recursion(postfix_expr, "ARITH_RSHIFT_X0_X1_X0\n", "LOGICAL_RSHIFT_X0_X1_X0\n", ">>", additive_expr_stub);
    }
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture))
    {
        general_recursion(postfix_expr, "RD_A0 RS1_A1 RS2_A0 ADD\n", "+", additive_expr_stub);
        general_recursion(postfix_expr, "RD_A0 RS1_A1 RS2_A0 SUB\n", "-", additive_expr_stub);
        general_recursion(postfix_expr, "RD_A0 RS1_A1 RS2_A0 MUL\n", "*", additive_expr_stub);
        arithmetic_recursion(postfix_expr, "RD_A0 RS1_A1 RS2_A0 DIV\n", "RD_A0 RS1_A1 RS2_A0 DIVU\n", "/", additive_expr_stub);
        arithmetic_recursion(postfix_expr, "RD_A0 RS1_A1 RS2_A0 REM\n", "RD_A0 RS1_A1 RS2_A0 REMU\n", "%", additive_expr_stub);
        general_recursion(postfix_expr, "RD_A0 RS1_A1 RS2_A0 SLL\n", "<<", additive_expr_stub);
        arithmetic_recursion(postfix_expr, "RD_A0 RS1_A1 RS2_A0 SRA\n", "RD_A0 RS1_A1 RS2_A0 SRL\n", ">>", additive_expr_stub);
    }
}


void additive_expr()
{
    postfix_expr();
    additive_expr_stub();
}


/*
 * relational-expr:
 *         additive_expr
 *         relational-expr < additive_expr
 *         relational-expr <= additive_expr
 *         relational-expr >= additive_expr
 *         relational-expr > additive_expr
 */

void relational_expr_stub()
{
    if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture))
    {
        arithmetic_recursion(additive_expr, "CMP R0 R1 R0\nSET.L R0 R0 1\n", "CMPU R0 R1 R0\nSET.L R0 R0 1\n", "<", relational_expr_stub);
        arithmetic_recursion(additive_expr, "CMP R0 R1 R0\nSET.LE R0 R0 1\n", "CMPU R0 R1 R0\nSET.LE R0 R0 1\n", "<=", relational_expr_stub);
        arithmetic_recursion(additive_expr, "CMP R0 R1 R0\nSET.GE R0 R0 1\n", "CMPU R0 R1 R0\nSET.GE R0 R0 1\n", ">=", relational_expr_stub);
        arithmetic_recursion(additive_expr, "CMP R0 R1 R0\nSET.G R0 R0 1\n", "CMPU R0 R1 R0\nSET.G R0 R0 1\n", ">", relational_expr_stub);
        arithmetic_recursion(additive_expr, "CMP R0 R1 R0\nSET.E R0 R0 1\n", "CMPU R0 R1 R0\nSET.E R0 R0 1\n", "==", relational_expr_stub);
        arithmetic_recursion(additive_expr, "CMP R0 R1 R0\nSET.NE R0 R0 1\n", "CMPU R0 R1 R0\nSET.NE R0 R0 1\n", "!=", relational_expr_stub);
    }
    else if(X86 == Architecture)
    {
        arithmetic_recursion(additive_expr, "cmp\nsetl_al\nmovzx_eax,al\n", "cmp\nsetb_al\nmovzx_eax,al\n", "<", relational_expr_stub);
        arithmetic_recursion(additive_expr, "cmp\nsetle_al\nmovzx_eax,al\n", "cmp\nsetbe_al\nmovzx_eax,al\n", "<=", relational_expr_stub);
        arithmetic_recursion(additive_expr, "cmp\nsetge_al\nmovzx_eax,al\n", "cmp\nsetae_al\nmovzx_eax,al\n", ">=", relational_expr_stub);
        arithmetic_recursion(additive_expr, "cmp\nsetg_al\nmovzx_eax,al\n", "cmp\nseta_al\nmovzx_eax,al\n", ">", relational_expr_stub);
        general_recursion(additive_expr, "cmp\nsete_al\nmovzx_eax,al\n", "==", relational_expr_stub);
        general_recursion(additive_expr, "cmp\nsetne_al\nmovzx_eax,al\n", "!=", relational_expr_stub);
    }
    else if(AMD64 == Architecture)
    {
        arithmetic_recursion(additive_expr, "cmp_rbx,rax\nsetl_al\nmovzx_rax,al\n", "cmp_rbx,rax\nsetb_al\nmovzx_rax,al\n", "<", relational_expr_stub);
        arithmetic_recursion(additive_expr, "cmp_rbx,rax\nsetle_al\nmovzx_rax,al\n", "cmp_rbx,rax\nsetbe_al\nmovzx_rax,al\n", "<=", relational_expr_stub);
        arithmetic_recursion(additive_expr, "cmp_rbx,rax\nsetge_al\nmovzx_rax,al\n", "cmp_rbx,rax\nsetae_al\nmovzx_rax,al\n", ">=", relational_expr_stub);
        arithmetic_recursion(additive_expr, "cmp_rbx,rax\nsetg_al\nmovzx_rax,al\n", "cmp_rbx,rax\nseta_al\nmovzx_rax,al\n", ">", relational_expr_stub);
        general_recursion(additive_expr, "cmp_rbx,rax\nsete_al\nmovzx_rax,al\n", "==", relational_expr_stub);
        general_recursion(additive_expr, "cmp_rbx,rax\nsetne_al\nmovzx_rax,al\n", "!=", relational_expr_stub);
    }
    else if(ARMV7L == Architecture)
    {
        arithmetic_recursion(additive_expr, "'0' R0 CMP R1 AUX_ALWAYS\n!0 R0 LOADI8_ALWAYS\n!1 R0 LOADI8_L\n", "'0' R0 CMP R1 AUX_ALWAYS\n!0 R0 LOADI8_ALWAYS\n!1 R0 LOADI8_LO\n", "<", relational_expr_stub);
        arithmetic_recursion(additive_expr, "'0' R0 CMP R1 AUX_ALWAYS\n!0 R0 LOADI8_ALWAYS\n!1 R0 LOADI8_LE\n", "'0' R0 CMP R1 AUX_ALWAYS\n!0 R0 LOADI8_ALWAYS\n!1 R0 LOADI8_LS\n", "<=", relational_expr_stub);
        arithmetic_recursion(additive_expr, "'0' R0 CMP R1 AUX_ALWAYS\n!0 R0 LOADI8_ALWAYS\n!1 R0 LOADI8_GE\n", "'0' R0 CMP R1 AUX_ALWAYS\n!0 R0 LOADI8_ALWAYS\n!1 R0 LOADI8_HS\n", ">=", relational_expr_stub);
        arithmetic_recursion(additive_expr, "'0' R0 CMP R1 AUX_ALWAYS\n!0 R0 LOADI8_ALWAYS\n!1 R0 LOADI8_G\n", "'0' R0 CMP R1 AUX_ALWAYS\n!0 R0 LOADI8_ALWAYS\n!1 R0 LOADI8_HI\n", ">", relational_expr_stub);
        general_recursion(additive_expr, "'0' R0 CMP R1 AUX_ALWAYS\n!0 R0 LOADI8_ALWAYS\n!1 R0 LOADI8_EQUAL\n", "==", relational_expr_stub);
        general_recursion(additive_expr, "'0' R0 CMP R1 AUX_ALWAYS\n!0 R0 LOADI8_ALWAYS\n!1 R0 LOADI8_NE\n", "!=", relational_expr_stub);
    }
    else if(AARCH64 == Architecture)
    {
        arithmetic_recursion(additive_expr, "CMP_X1_X0\nSET_X0_TO_1\nSKIP_INST_LT\nSET_X0_TO_0\n", "CMP_X1_X0\nSET_X0_TO_1\nSKIP_INST_LO\nSET_X0_TO_0\n", "<", relational_expr_stub);
        arithmetic_recursion(additive_expr, "CMP_X1_X0\nSET_X0_TO_1\nSKIP_INST_LE\nSET_X0_TO_0\n", "CMP_X1_X0\nSET_X0_TO_1\nSKIP_INST_LS\nSET_X0_TO_0\n", "<=", relational_expr_stub);
        arithmetic_recursion(additive_expr, "CMP_X1_X0\nSET_X0_TO_1\nSKIP_INST_GE\nSET_X0_TO_0\n", "CMP_X1_X0\nSET_X0_TO_1\nSKIP_INST_HS\nSET_X0_TO_0\n", ">=", relational_expr_stub);
        arithmetic_recursion(additive_expr, "CMP_X1_X0\nSET_X0_TO_1\nSKIP_INST_GT\nSET_X0_TO_0\n", "CMP_X1_X0\nSET_X0_TO_1\nSKIP_INST_HI\nSET_X0_TO_0\n", ">", relational_expr_stub);
        general_recursion(additive_expr, "CMP_X1_X0\nSET_X0_TO_1\nSKIP_INST_EQ\nSET_X0_TO_0\n", "==", relational_expr_stub);
        general_recursion(additive_expr, "CMP_X1_X0\nSET_X0_TO_1\nSKIP_INST_NE\nSET_X0_TO_0\n", "!=", relational_expr_stub);
    }
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture))
    {
        arithmetic_recursion(additive_expr, "RD_A0 RS1_A1 RS2_A0 SLT\n", "RD_A0 RS1_A1 RS2_A0 SLTU\n", "<", relational_expr_stub);
        arithmetic_recursion(additive_expr, "RD_A0 RS1_A0 RS2_A1 SLT\nRD_A0 RS1_A0 !1 XORI\n", "RD_A0 RS1_A0 RS2_A1 SLTU\nRD_A0 RS1_A0 !1 XORI\n", "<=", relational_expr_stub);
        arithmetic_recursion(additive_expr, "RD_A0 RS1_A1 RS2_A0 SLT\nRD_A0 RS1_A0 !1 XORI\n", "RD_A0 RS1_A1 RS2_A0 SLTU\nRD_A0 RS1_A0 !1 XORI\n", ">=", relational_expr_stub);
        arithmetic_recursion(additive_expr, "RD_A0 RS1_A0 RS2_A1 SLT\n", "RD_A0 RS1_A0 RS2_A1 SLTU\n", ">", relational_expr_stub);
        general_recursion(additive_expr, "RD_A0 RS1_A0 RS2_A1 SUB\nRD_A0 RS1_A0 !1 SLTIU\n", "==", relational_expr_stub);
        general_recursion(additive_expr, "RD_A0 RS1_A0 RS2_A1 SUB\nRD_A0 RS2_A0 SLTU\n", "!=", relational_expr_stub);
    }
}

void relational_expr()
{
    additive_expr();
    relational_expr_stub();
}

/*
 * bitwise-expr:
 *         relational-expr
 *         bitwise-expr & bitwise-expr
 *         bitwise-expr && bitwise-expr
 *         bitwise-expr | bitwise-expr
 *         bitwise-expr || bitwise-expr
 *         bitwise-expr ^ bitwise-expr
 */
void bitwise_expr_stub()
{
    if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture))
    {
        general_recursion(relational_expr, "AND R0 R0 R1\n", "&", bitwise_expr_stub);
        general_recursion(relational_expr, "AND R0 R0 R1\n", "&&", bitwise_expr_stub);
        general_recursion(relational_expr, "OR R0 R0 R1\n", "|", bitwise_expr_stub);
        general_recursion(relational_expr, "OR R0 R0 R1\n", "||", bitwise_expr_stub);
        general_recursion(relational_expr, "XOR R0 R0 R1\n", "^", bitwise_expr_stub);
    }
    else if(X86 == Architecture)
    {
        general_recursion(relational_expr, "and_eax,ebx\n", "&", bitwise_expr_stub);
        general_recursion(relational_expr, "and_eax,ebx\n", "&&", bitwise_expr_stub);
        general_recursion(relational_expr, "or_eax,ebx\n", "|", bitwise_expr_stub);
        general_recursion(relational_expr, "or_eax,ebx\n", "||", bitwise_expr_stub);
        general_recursion(relational_expr, "xor_eax,ebx\n", "^", bitwise_expr_stub);
    }
    else if(AMD64 == Architecture)
    {
        general_recursion(relational_expr, "and_rax,rbx\n", "&", bitwise_expr_stub);
        general_recursion(relational_expr, "and_rax,rbx\n", "&&", bitwise_expr_stub);
        general_recursion(relational_expr, "or_rax,rbx\n", "|", bitwise_expr_stub);
        general_recursion(relational_expr, "or_rax,rbx\n", "||", bitwise_expr_stub);
        general_recursion(relational_expr, "xor_rax,rbx\n", "^", bitwise_expr_stub);
    }
    else if(ARMV7L == Architecture)
    {
        general_recursion(relational_expr, "NO_SHIFT R0 R0 AND R1 ARITH2_ALWAYS\n", "&", bitwise_expr_stub);
        general_recursion(relational_expr, "NO_SHIFT R0 R0 AND R1 ARITH2_ALWAYS\n", "&&", bitwise_expr_stub);
        general_recursion(relational_expr, "NO_SHIFT R0 R0 OR R1 AUX_ALWAYS\n", "|", bitwise_expr_stub);
        general_recursion(relational_expr, "NO_SHIFT R0 R0 OR R1 AUX_ALWAYS\n", "||", bitwise_expr_stub);
        general_recursion(relational_expr, "'0' R0 R0 XOR R1 ARITH2_ALWAYS\n", "^", bitwise_expr_stub);
    }
    else if(AARCH64 == Architecture)
    {
        general_recursion(relational_expr, "AND_X0_X1_X0\n", "&", bitwise_expr_stub);
        general_recursion(relational_expr, "AND_X0_X1_X0\n", "&&", bitwise_expr_stub);
        general_recursion(relational_expr, "OR_X0_X1_X0\n", "|", bitwise_expr_stub);
        general_recursion(relational_expr, "OR_X0_X1_X0\n", "||", bitwise_expr_stub);
        general_recursion(relational_expr, "XOR_X0_X1_X0\n", "^", bitwise_expr_stub);
    }
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture))
    {
        general_recursion(relational_expr, "RD_A0 RS1_A1 RS2_A0 AND\n", "&", bitwise_expr_stub);
        general_recursion(relational_expr, "RD_A0 RS1_A1 RS2_A0 AND\n", "&&", bitwise_expr_stub);
        general_recursion(relational_expr, "RD_A0 RS1_A1 RS2_A0 OR\n", "|", bitwise_expr_stub);
        general_recursion(relational_expr, "RD_A0 RS1_A1 RS2_A0 OR\n", "||", bitwise_expr_stub);
        general_recursion(relational_expr, "RD_A0 RS1_A1 RS2_A0 XOR\n", "^", bitwise_expr_stub);
    }
}


void bitwise_expr()
{
    relational_expr();
    bitwise_expr_stub();
}

/*
 * expression:
 *         bitwise-or-expr
 *         bitwise-or-expr = expression
 */

void primary_expr()
{
    require(NULL != global_token, "Received EOF where primary expression expected\n");
    if(match("&", global_token->s))
    {
        Address_of = TRUE;
        global_token = global_token->next;
        require(NULL != global_token, "Received EOF after & where primary expression expected\n");
    }
    else
    {
        Address_of = FALSE;
    }

    if(match("sizeof", global_token->s)) unary_expr_sizeof();
    else if('-' == global_token->s[0])
    {
        if(X86 == Architecture) emit_out("mov_eax, %0\n");
        else if(AMD64 == Architecture) emit_out("mov_rax, %0\n");
        else if(ARMV7L == Architecture) emit_out("!0 R0 LOADI8_ALWAYS\n");
        else if(AARCH64 == Architecture) emit_out("SET_X0_TO_0\n");
        else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("RD_A0 MV\n");

        common_recursion(primary_expr);

        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("NEG R0 R0\n");
        else if(X86 == Architecture) emit_out("sub_ebx,eax\nmov_eax,ebx\n");
        else if(AMD64 == Architecture) emit_out("sub_rbx,rax\nmov_rax,rbx\n");
        else if(ARMV7L == Architecture) emit_out("'0' R0 R0 SUB R1 ARITH2_ALWAYS\n");
        else if(AARCH64 == Architecture) emit_out("SUB_X0_X1_X0\n");
        else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("RD_A0 RS1_A1 RS2_A0 SUB\n");
    }
    else if('!' == global_token->s[0])
    {
        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture))  emit_out("LOADI R0 1\n");
        else if(X86 == Architecture) emit_out("mov_eax, %1\n");
        else if(AMD64 == Architecture) emit_out("mov_rax, %1\n");
        else if(ARMV7L == Architecture) emit_out("!1 R0 LOADI8_ALWAYS\n");
        else if(AARCH64 == Architecture) emit_out("SET_X0_TO_1\n");

        common_recursion(postfix_expr);

        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("CMPU R0 R1 R0\nSET.G R0 R0 1\n");
        else if(X86 == Architecture) emit_out("cmp\nseta_al\nmovzx_eax,al\n");
        else if(AMD64 == Architecture) emit_out("cmp_rbx,rax\nseta_al\nmovzx_rax,al\n");
        else if(ARMV7L == Architecture) emit_out("'0' R0 CMP R1 AUX_ALWAYS\n!0 R0 LOADI8_ALWAYS\n!1 R0 LOADI8_HI\n");
        else if(AARCH64 == Architecture) emit_out("CMP_X1_X0\nSET_X0_TO_1\nSKIP_INST_HI\nSET_X0_TO_0\n");
        else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("RD_A0 RS1_A0 !1 SLTIU\n");
    }
    else if('~' == global_token->s[0])
    {
        common_recursion(postfix_expr);

        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("NOT R0 R0\n");
        else if(X86 == Architecture) emit_out("not_eax\n");
        else if(AMD64 == Architecture) emit_out("not_rax\n");
        else if(ARMV7L == Architecture) emit_out("'0' R0 R0 MVN_ALWAYS\n");
        else if(AARCH64 == Architecture) emit_out("MVN_X0\n");
        else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("RD_A0 RS1_A0 NOT\n");
    }
    else if(global_token->s[0] == '(')
    {
        global_token = global_token->next;
        expression();
        require_match("Error in Primary expression\nDidn't get )\n", ")");
    }
    else if(global_token->s[0] == '\'') primary_expr_char();
    else if(global_token->s[0] == '"') primary_expr_string();
    else if(in_set(global_token->s[0], "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_")) primary_expr_variable();
    else if(global_token->s[0] == '*') primary_expr_variable();
    else if(in_set(global_token->s[0], "0123456789")) primary_expr_number();
    else primary_expr_failure();
}

char* compound_operation(char* operator, int is_signed)
{
    char* operation = "";
    if(match("+=", operator))
    {
        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture))
        {
            if(is_signed) operation = "ADD R0 R1 R0\n";
            else operation = "ADDU R0 R1 R0\n";
        }
        else if(X86 == Architecture) operation = "add_eax,ebx\n";
        else if(AMD64 == Architecture) operation = "add_rax,rbx\n";
        else if(ARMV7L == Architecture) operation = "'0' R0 R0 ADD R1 ARITH2_ALWAYS\n";
        else if(AARCH64 == Architecture) operation = "ADD_X0_X1_X0\n";
        else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) operation = "RD_A0 RS1_A1 RS2_A0 ADD\n";
    }
    else if(match("-=", operator))
    {
        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture))
        {
            if(is_signed) operation = "SUB R0 R1 R0\n";
            else operation =  "SUBU R0 R1 R0\n";
        }
        else if(X86 == Architecture) operation = "sub_ebx,eax\nmov_eax,ebx\n";
        else if(AMD64 == Architecture) operation = "sub_rbx,rax\nmov_rax,rbx\n";
        else if(ARMV7L == Architecture) operation = "'0' R0 R0 SUB R1 ARITH2_ALWAYS\n";
        else if(AARCH64 == Architecture) operation = "SUB_X0_X1_X0\n";
        else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) operation = "RD_A0 RS1_A1 RS2_A0 SUB\n";
    }
    else if(match("*=", operator))
    {
        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture))
        {
            if(is_signed) operation = "MUL R0 R1 R0\n";
            else operation =  "MULU R0 R1 R0\n";
        }
        else if(X86 == Architecture)
        {
            if(is_signed) operation = "imul_ebx\n";
            else operation = "mul_ebx\n";
        }
        else if(AMD64 == Architecture)
        {
            if(is_signed) operation = "imul_rbx\n";
            else operation = "mul_rbx\n";
        }
        else if(ARMV7L == Architecture) operation = "'9' R0 '0' R1 MULS R0 ARITH2_ALWAYS\n";
        else if(AARCH64 == Architecture) operation = "MUL_X0_X1_X0\n";
        else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) operation = "RD_A0 RS1_A1 RS2_A0 MUL\n";
    }
    else if(match("/=", operator))
    {
        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture))
        {
            if(is_signed) operation = "DIV R0 R1 R0\n";
            else operation =  "DIVU R0 R1 R0\n";
        }
        else if(X86 == Architecture)
        {
            if (is_signed) operation = "xchg_ebx,eax\ncdq\nidiv_ebx\n";
            else operation = "xchg_ebx,eax\nmov_edx, %0\ndiv_ebx\n";
        }
        else if(AMD64 == Architecture)
        {
            if(is_signed) operation = "xchg_rbx,rax\ncqo\nidiv_rbx\n";
            else operation = "xchg_rbx,rax\nmov_rdx, %0\ndiv_rbx\n";
        }
        else if(ARMV7L == Architecture)
        {
            if(is_signed) operation = "{LR} PUSH_ALWAYS\n^~divides CALL_ALWAYS\n{LR} POP_ALWAYS\n";
            else operation = "{LR} PUSH_ALWAYS\n^~divide CALL_ALWAYS\n{LR} POP_ALWAYS\n";
        }
        else if(AARCH64 == Architecture)
        {
            if(is_signed) operation = "SDIV_X0_X1_X0\n";
            else operation = "UDIV_X0_X1_X0\n";
        }
        else if((RISCV32 == Architecture) || (RISCV64 == Architecture))
        {
            if(is_signed) operation = "RD_A0 RS1_A1 RS2_A0 DIV\n";
            else operation = "RD_A0 RS1_A1 RS2_A0 DIVU\n";
        }
    }
    else if(match("%=", operator))
    {
        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture))
        {
            if(is_signed) operation = "MOD R0 R1 R0\n";
            else operation = "MODU R0 R1 R0\n";
        }
        else if(X86 == Architecture)
        {
            if(is_signed) operation = "xchg_ebx,eax\ncdq\nidiv_ebx\nmov_eax,edx\n";
            else operation = "xchg_ebx,eax\nmov_edx, %0\ndiv_ebx\nmov_eax,edx\n";
        }
        else if(AMD64 == Architecture)
        {
            if(is_signed) operation = "xchg_rbx,rax\ncqo\nidiv_rbx\nmov_rax,rdx\n";
            else operation = "xchg_rbx,rax\nmov_rdx, %0\ndiv_rbx\nmov_rax,rdx\n";
        }
        else if(ARMV7L == Architecture)
        {
            if(is_signed) operation = "{LR} PUSH_ALWAYS\n^~moduluss CALL_ALWAYS\n{LR} POP_ALWAYS\n";
            else operation = "{LR} PUSH_ALWAYS\n^~modulus CALL_ALWAYS\n{LR} POP_ALWAYS\n";
        }
        else if(AARCH64 == Architecture)
        {
            if(is_signed) operation = "SDIV_X2_X1_X0\nMSUB_X0_X0_X2_X1\n";
            else operation = "UDIV_X2_X1_X0\nMSUB_X0_X0_X2_X1\n";
        }
        else if((RISCV32 == Architecture) || (RISCV64 == Architecture))
        {
            if(is_signed) operation = "RD_A0 RS1_A1 RS2_A0 REM\n";
            else operation = "RD_A0 RS1_A1 RS2_A0 REMU\n";
        }
    }
    else if(match("<<=", operator))
    {
        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture))
        {
            if(is_signed) operation = "SAL R0 R1 R0\n";
            else operation = "SL0 R0 R1 R0\n";
        }
        else if(X86 == Architecture)
        {
            if(is_signed) operation = "mov_ecx,eax\nmov_eax,ebx\nsal_eax,cl\n";
            else operation = "mov_ecx,eax\nmov_eax,ebx\nshl_eax,cl\n";
        }
        else if(AMD64 == Architecture)
        {
            if(is_signed) operation = "mov_rcx,rax\nmov_rax,rbx\nsal_rax,cl\n";
            else operation = "mov_rcx,rax\nmov_rax,rbx\nshl_rax,cl\n";
        }
        else if(ARMV7L == Architecture) operation = "LEFT R1 R0 R0 SHIFT AUX_ALWAYS\n";
        else if(AARCH64 == Architecture) operation = "LSHIFT_X0_X1_X0\n";
        else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) operation = "RD_A0 RS1_A1 RS2_A0 SLL\n";
    }
    else if(match(">>=", operator))
    {
        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture))
        {
            if(is_signed) operation = "SAR R0 R1 R0\n";
            else operation = "SR0 R0 R1 R0\n";
        }
        else if(X86 == Architecture)
        {
            if(is_signed) operation = "mov_ecx,eax\nmov_eax,ebx\nsar_eax,cl\n";
            else operation = "mov_ecx,eax\nmov_eax,ebx\nshr_eax,cl\n";
        }
        else if(AMD64 == Architecture)
        {
            if(is_signed) operation = "mov_rcx,rax\nmov_rax,rbx\nsar_rax,cl\n";
            else operation = "mov_rcx,rax\nmov_rax,rbx\nshr_rax,cl\n";
        }
        else if(ARMV7L == Architecture)
        {
            if(is_signed) operation = "ARITH_RIGHT R1 R0 R0 SHIFT AUX_ALWAYS\n";
            else operation = "RIGHT R1 R0 R0 SHIFT AUX_ALWAYS\n";
        }
        else if(AARCH64 == Architecture)
        {
            if(is_signed) operation = "ARITH_RSHIFT_X0_X1_X0\n";
            else operation = "LOGICAL_RSHIFT_X0_X1_X0\n";
        }
        else if((RISCV32 == Architecture) || (RISCV64 == Architecture))
        {
            if(is_signed) operation = "RD_A0 RS1_A1 RS2_A0 SRA\n";
            else operation = "RD_A0 RS1_A1 RS2_A0 SRL\n";
        }
    }
    else if(match("&=", operator))
    {
        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) operation = "AND R0 R0 R1\n";
        else if(X86 == Architecture) operation = "and_eax,ebx\n";
        else if(AMD64 == Architecture) operation = "and_rax,rbx\n";
        else if(ARMV7L == Architecture) operation = "NO_SHIFT R0 R0 AND R1 ARITH2_ALWAYS\n";
        else if(AARCH64 == Architecture) operation = "AND_X0_X1_X0\n";
        else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) operation = "RD_A0 RS1_A1 RS2_A0 AND\n";
    }
    else if(match("^=", operator))
    {
        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) operation = "XOR R0 R0 R1\n";
        else if(X86 == Architecture) operation = "xor_eax,ebx\n";
        else if(AMD64 == Architecture) operation = "xor_rax,rbx\n";
        else if(ARMV7L == Architecture) operation = "'0' R0 R0 XOR R1 ARITH2_ALWAYS\n";
        else if(AARCH64 == Architecture) operation = "XOR_X0_X1_X0\n";
        else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) operation = "RD_A0 RS1_A1 RS2_A0 XOR\n";
    }
    else if(match("|=", operator))
    {
        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) operation = "OR R0 R0 R1\n";
        else if(X86 == Architecture) operation = "or_eax,ebx\n";
        else if(AMD64 == Architecture) operation = "or_rax,rbx\n";
        else if(ARMV7L == Architecture) operation = "NO_SHIFT R0 R0 OR R1 AUX_ALWAYS\n";
        else if(AARCH64 == Architecture) operation = "OR_X0_X1_X0\n";
        else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) operation = "RD_A0 RS1_A1 RS2_A0 OR\n";
    }
    else
    {
        fputs("Found illegal compound assignment operator: ", stderr);
        fputs(operator, stderr);
        fputc('\n', stderr);
        exit(EXIT_FAILURE);
    }
    return operation;
}


void expression()
{
    bitwise_expr();
    if(match("=", global_token->s))
    {
        char* store = "";
        if(match("]", global_token->prev->s))
        {
            store = store_value(current_target->type->size);
        }
        else
        {
            store = store_value(current_target->size);
        }

        common_recursion(expression);
        emit_out(store);
        current_target = integer;
    }
    else if(is_compound_assignment(global_token->s))
    {
        maybe_bootstrap_error("compound operator");
        char* push = "";
        char* load = "";
        char* operation = "";
        char* pop = "";
        char* store = "";
        struct type* last_type = current_target;

        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) push = "PUSHR R1 R15\n";
        else if(X86 == Architecture) push = "push_ebx\n";
        else if(AMD64 == Architecture) push = "push_rbx\n";
        else if(ARMV7L == Architecture) push = "{R1} PUSH_ALWAYS\n";
        else if(AARCH64 == Architecture) push = "PUSH_X1\n";
        else if(RISCV32 == Architecture) push = "RS1_SP RS2_A1 @-4 SW\n";
        else if(RISCV64 == Architecture) push = "RS1_SP RS2_A1 @-8 SD\n";

        if(!match("]", global_token->prev->s) || !match("char*", current_target->name))
        {
            if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) load = "LOAD R1 R1 0\n";
            else if(X86 == Architecture) load = "mov_ebx,[ebx]\n";
            else if(AMD64 == Architecture) load = "mov_rbx,[rbx]\n";
            else if(ARMV7L == Architecture) load = "!0 R1 LOAD32 R1 MEMORY\n";
            else if(AARCH64 == Architecture) load = "DEREF_X1\n";
            else if(RISCV32 == Architecture) load = "RD_A1 RS1_A1 LW\n";
            else if(RISCV64 == Architecture) load = "RD_A1 RS1_A1 LD\n";
        }
        else
        {
            if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) load = "LOAD8 R1 R1 0\n";
            else if(X86 == Architecture) load = "movsx_ebx,BYTE_PTR_[ebx]\n";
            else if(AMD64 == Architecture) load = "movsx_rbx,BYTE_PTR_[rbx]\n";
            else if(ARMV7L == Architecture) load = "LOADU8 R1 LOAD R1 MEMORY\n";
            else if(AARCH64 == Architecture) load = "DEREF_X1_BYTE\n";
            else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) load = "RD_A1 RS1_A1 LBU\n";
        }

        char *operator = global_token->s;

        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) pop = "POPR R1 R15\n";
        else if(X86 == Architecture) pop = "pop_ebx\n";
        else if(AMD64 == Architecture) pop = "pop_rbx\n";
        else if(ARMV7L == Architecture) pop = "{R1} POP_ALWAYS\n";
        else if(AARCH64 == Architecture) pop = "POP_X1\n";
        else if(RISCV32 == Architecture) pop = "RD_A1 RS1_SP !-4 LW\n";
        else if(RISCV64 == Architecture) pop = "RD_A1 RS1_SP !-8 LD\n";

        if(match("]", global_token->prev->s))
        {
            store = store_value(current_target->type->size);
        }
        else
        {
            store = store_value(current_target->size);
        }

        common_recursion(expression);
        current_target = promote_type(current_target, last_type);
        emit_out(push);
        emit_out(load);
        operation = compound_operation(operator, current_target->is_signed);
        emit_out(operation);
        emit_out(pop);
        emit_out(store);
        current_target = integer;
    }
}


int iskeywordp(char* s)
{
    if(match("auto", s)) return TRUE;
    if(match("break", s)) return TRUE;
    if(match("case", s)) return TRUE;
    if(match("char", s)) return TRUE;
    if(match("const", s)) return TRUE;
    if(match("continue", s)) return TRUE;
    if(match("default", s)) return TRUE;
    if(match("do", s)) return TRUE;
    if(match("double", s)) return TRUE;
    if(match("else", s)) return TRUE;
    if(match("enum", s)) return TRUE;
    if(match("extern", s)) return TRUE;
    if(match("float", s)) return TRUE;
    if(match("for", s)) return TRUE;
    if(match("goto", s)) return TRUE;
    if(match("if", s)) return TRUE;
    if(match("int", s)) return TRUE;
    if(match("long", s)) return TRUE;
    if(match("register", s)) return TRUE;
    if(match("return", s)) return TRUE;
    if(match("short", s)) return TRUE;
    if(match("signed", s)) return TRUE;
    if(match("sizeof", s)) return TRUE;
    if(match("static", s)) return TRUE;
    if(match("struct", s)) return TRUE;
    if(match("switch", s)) return TRUE;
    if(match("typedef", s)) return TRUE;
    if(match("union", s)) return TRUE;
    if(match("unsigned", s)) return TRUE;
    if(match("void", s)) return TRUE;
    if(match("volatile", s)) return TRUE;
    if(match("while", s)) return TRUE;
    return FALSE;
}

/* Similar to integer division a / b but rounds up */
unsigned ceil_div(unsigned a, unsigned b)
{
    return (a + b - 1) / b;
}

/* Process local variable */
void collect_local()
{
    if(NULL != break_target_func)
    {
        fputs("Local variable initialized inside of loop in file: ", stderr);
        line_error();
        fputs("\nMove the variable outside of the loop to resolve\n", stderr);
        fputs("Otherwise the binary will segfault while running\n", stderr);
        exit(EXIT_FAILURE);
    }
    struct type* type_size = type_name();
    require(NULL != global_token, "Received EOF while collecting locals\n");
    require(!in_set(global_token->s[0], "[{(<=>)}]|&!^%;:'\""), "forbidden character in local variable name\n");
    require(!iskeywordp(global_token->s), "You are not allowed to use a keyword as a local variable name\n");
    require(NULL != type_size, "Must have non-null type\n");
    struct token_list* a = sym_declare(global_token->s, type_size, function->locals);
    if(match("main", function->s) && (NULL == function->locals))
    {
        if(KNIGHT_NATIVE == Architecture) a->depth = register_size;
        else if(KNIGHT_POSIX == Architecture) a->depth = 20;
        else if(X86 == Architecture) a->depth = -20;
        else if(AMD64 == Architecture) a->depth = -40;
        else if(ARMV7L == Architecture) a->depth = 16;
        else if(AARCH64 == Architecture) a->depth = 32; /* argc, argv, envp and the local (8 bytes each) */
        else if(RISCV32 == Architecture) a->depth = -16;
        else if(RISCV64 == Architecture) a->depth = -32;
    }
    else if((NULL == function->arguments) && (NULL == function->locals))
    {
        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) a->depth = register_size;
        else if(X86 == Architecture) a->depth = -8;
        else if(AMD64 == Architecture) a->depth = -16;
        else if(ARMV7L == Architecture) a->depth = 8;
        else if(AARCH64 == Architecture) a->depth = register_size;
        else if(RISCV32 == Architecture) a->depth = -4;
        else if(RISCV64 == Architecture) a->depth = -8;
    }
    else if(NULL == function->locals)
    {
        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) a->depth = function->arguments->depth + 8;
        else if(X86 == Architecture) a->depth = function->arguments->depth - 8;
        else if(AMD64 == Architecture) a->depth = function->arguments->depth - 16;
        else if(ARMV7L == Architecture) a->depth = function->arguments->depth + 8;
        else if(AARCH64 == Architecture) a->depth = function->arguments->depth + register_size;
        else if(RISCV32 == Architecture) a->depth = function->arguments->depth - 4;
        else if(RISCV64 == Architecture) a->depth = function->arguments->depth - 8;
    }
    else
    {
        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) a->depth = function->locals->depth + register_size;
        else if(X86 == Architecture) a->depth = function->locals->depth - register_size;
        else if(AMD64 == Architecture) a->depth = function->locals->depth - register_size;
        else if(ARMV7L == Architecture) a->depth = function->locals->depth + register_size;
        else if(AARCH64 == Architecture) a->depth = function->locals->depth + register_size;
        else if(RISCV32 == Architecture) a->depth = function->locals->depth - register_size;
        else if(RISCV64 == Architecture) a->depth = function->locals->depth - register_size;
    }

    /* Adjust the depth of local structs. When stack grows downwards, we want them to 
       start at the bottom of allocated space. */
    unsigned struct_depth_adjustment = (ceil_div(a->type->size, register_size) - 1) * register_size;
    if(KNIGHT_POSIX == Architecture) a->depth = a->depth + struct_depth_adjustment;
    else if(KNIGHT_NATIVE == Architecture) a->depth = a->depth + struct_depth_adjustment;
    else if(X86 == Architecture) a->depth = a->depth - struct_depth_adjustment;
    else if(AMD64 == Architecture) a->depth = a->depth - struct_depth_adjustment;
    else if(ARMV7L == Architecture) a->depth = a->depth + struct_depth_adjustment;
    else if(AARCH64 == Architecture) a->depth = a->depth + struct_depth_adjustment;
    else if(RISCV32 == Architecture) a->depth = a->depth - struct_depth_adjustment;
    else if(RISCV64 == Architecture) a->depth = a->depth - struct_depth_adjustment;

    function->locals = a;

    emit_out("# Defining local ");
    emit_out(global_token->s);
    emit_out("\n");

    global_token = global_token->next;
    require(NULL != global_token, "incomplete local missing name\n");

    if(match("=", global_token->s))
    {
        global_token = global_token->next;
        require(NULL != global_token, "incomplete local assignment\n");
        expression();
    }

    require_match("ERROR in collect_local\nMissing ;\n", ";");

    unsigned i = (a->type->size + register_size - 1) / register_size;
    while(i != 0)
    {
        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("PUSHR R0 R15\t#");
        else if(X86 == Architecture) emit_out("push_eax\t#");
        else if(AMD64 == Architecture) emit_out("push_rax\t#");
        else if(ARMV7L == Architecture) emit_out("{R0} PUSH_ALWAYS\t#");
        else if(AARCH64 == Architecture) emit_out("PUSH_X0\t#");
        else if(RISCV32 == Architecture) emit_out("RD_SP RS1_SP !-4 ADDI\nRS1_SP RS2_A0 SW\t#");
        else if(RISCV64 == Architecture) emit_out("RD_SP RS1_SP !-8 ADDI\nRS1_SP RS2_A0 SD\t#");
        emit_out(a->s);
        emit_out("\n");
        i = i - 1;
    }
}

void statement();

/* Evaluate if statements */
void process_if()
{
    char* number_string = int2str(current_count, 10, TRUE);
    current_count = current_count + 1;

    emit_out("# IF_");
    uniqueID_out(function->s, number_string);

    global_token = global_token->next;
    require_match("ERROR in process_if\nMISSING (\n", "(");
    expression();

    if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("JUMP.Z R0 @ELSE_");
    else if(X86 == Architecture) emit_out("test_eax,eax\nje %ELSE_");
    else if(AMD64 == Architecture) emit_out("test_rax,rax\nje %ELSE_");
    else if(ARMV7L == Architecture) emit_out("!0 CMPI8 R0 IMM_ALWAYS\n^~ELSE_");
    else if(AARCH64 == Architecture) emit_out("CBNZ_X0_PAST_BR\nLOAD_W16_AHEAD\nSKIP_32_DATA\n&ELSE_");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("RS1_A0 @8 BNEZ\n$ELSE_");

    uniqueID_out(function->s, number_string);
    if(ARMV7L == Architecture) emit_out(" JUMP_EQUAL\n");
    else if(AARCH64 == Architecture) emit_out("\nBR_X16\n");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("JAL\n");

    require_match("ERROR in process_if\nMISSING )\n", ")");
    statement();
    require(NULL != global_token, "Reached EOF inside of function\n");

    if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("JUMP @_END_IF_");
    else if(X86 == Architecture) emit_out("jmp %_END_IF_");
    else if(AMD64 == Architecture) emit_out("jmp %_END_IF_");
    else if(ARMV7L == Architecture) emit_out("^~_END_IF_");
    else if(AARCH64 == Architecture) emit_out("LOAD_W16_AHEAD\nSKIP_32_DATA\n&_END_IF_");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("$_END_IF_");

    uniqueID_out(function->s, number_string);
    if(ARMV7L == Architecture) emit_out(" JUMP_ALWAYS\n");
    else if(AARCH64 == Architecture) emit_out("\nBR_X16\n");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("JAL\n");

    emit_out(":ELSE_");
    uniqueID_out(function->s, number_string);

    if(match("else", global_token->s))
    {
        global_token = global_token->next;
        require(NULL != global_token, "Received EOF where an else statement expected\n");
        statement();
        require(NULL != global_token, "Reached EOF inside of function\n");
    }
    emit_out(":_END_IF_");
    uniqueID_out(function->s, number_string);
}

void process_for()
{
    struct token_list* nested_locals = break_frame;
    char* nested_break_head = break_target_head;
    char* nested_break_func = break_target_func;
    char* nested_break_num = break_target_num;
    char* nested_continue_head = continue_target_head;

    char* number_string = int2str(current_count, 10, TRUE);
    current_count = current_count + 1;

    break_target_head = "FOR_END_";
    continue_target_head = "FOR_ITER_";
    break_target_num = number_string;
    break_frame = function->locals;
    break_target_func = function->s;

    emit_out("# FOR_initialization_");
    uniqueID_out(function->s, number_string);

    global_token = global_token->next;

    require_match("ERROR in process_for\nMISSING (\n", "(");
    if(!match(";",global_token->s))
    {
        expression();
    }

    emit_out(":FOR_");
    uniqueID_out(function->s, number_string);

    require_match("ERROR in process_for\nMISSING ;1\n", ";");
    expression();

    if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("JUMP.Z R0 @FOR_END_");
    else if(X86 == Architecture) emit_out("test_eax,eax\nje %FOR_END_");
    else if(AMD64 == Architecture) emit_out("test_rax,rax\nje %FOR_END_");
    else if(ARMV7L == Architecture) emit_out("!0 CMPI8 R0 IMM_ALWAYS\n^~FOR_END_");
    else if(AARCH64 == Architecture) emit_out("CBNZ_X0_PAST_BR\nLOAD_W16_AHEAD\nSKIP_32_DATA\n&FOR_END_");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("RS1_A0 @8 BNEZ\n$FOR_END_");
    uniqueID_out(function->s, number_string);
    if(ARMV7L == Architecture) emit_out(" JUMP_EQUAL\n");
    else if(AARCH64 == Architecture) emit_out("\nBR_X16\n");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("JAL\n");

    if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("JUMP @FOR_THEN_");
    else if(X86 == Architecture) emit_out("jmp %FOR_THEN_");
    else if(AMD64 == Architecture) emit_out("jmp %FOR_THEN_");
    else if(ARMV7L == Architecture) emit_out("^~FOR_THEN_");
    else if(AARCH64 == Architecture) emit_out("LOAD_W16_AHEAD\nSKIP_32_DATA\n&FOR_THEN_");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("$FOR_THEN_");
    uniqueID_out(function->s, number_string);
    if(ARMV7L == Architecture) emit_out(" JUMP_ALWAYS\n");
    else if(AARCH64 == Architecture) emit_out("\nBR_X16\n");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("JAL\n");

    emit_out(":FOR_ITER_");
    uniqueID_out(function->s, number_string);

    require_match("ERROR in process_for\nMISSING ;2\n", ";");
    expression();

    if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("JUMP @FOR_");
    else if(X86 == Architecture) emit_out("jmp %FOR_");
    else if(AMD64 == Architecture) emit_out("jmp %FOR_");
    else if(ARMV7L == Architecture) emit_out("^~FOR_");
    else if(AARCH64 == Architecture) emit_out("LOAD_W16_AHEAD\nSKIP_32_DATA\n&FOR_");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("$FOR_");
    uniqueID_out(function->s, number_string);
    if(ARMV7L == Architecture) emit_out(" JUMP_ALWAYS\n");
    else if(AARCH64 == Architecture) emit_out("\nBR_X16\n");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("JAL\n");

    emit_out(":FOR_THEN_");
    uniqueID_out(function->s, number_string);

    require_match("ERROR in process_for\nMISSING )\n", ")");
    statement();
    require(NULL != global_token, "Reached EOF inside of function\n");

    if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("JUMP @FOR_ITER_");
    else if(X86 == Architecture) emit_out("jmp %FOR_ITER_");
    else if(AMD64 == Architecture) emit_out("jmp %FOR_ITER_");
    else if(ARMV7L == Architecture) emit_out("^~FOR_ITER_");
    else if(AARCH64 == Architecture) emit_out("LOAD_W16_AHEAD\nSKIP_32_DATA\n&FOR_ITER_");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("$FOR_ITER_");
    uniqueID_out(function->s, number_string);
    if(ARMV7L == Architecture) emit_out(" JUMP_ALWAYS\n");
    else if(AARCH64 == Architecture) emit_out("\nBR_X16\n");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("JAL\n");

    emit_out(":FOR_END_");
    uniqueID_out(function->s, number_string);

    break_target_head = nested_break_head;
    break_target_func = nested_break_func;
    break_target_num = nested_break_num;
    continue_target_head = nested_continue_head;
    break_frame = nested_locals;
}

/* Process Assembly statements */
void process_asm()
{
    global_token = global_token->next;
    require_match("ERROR in process_asm\nMISSING (\n", "(");
    while('"' == global_token->s[0])
    {
        emit_out((global_token->s + 1));
        emit_out("\n");
        global_token = global_token->next;
        require(NULL != global_token, "Received EOF inside asm statement\n");
    }
    require_match("ERROR in process_asm\nMISSING )\n", ")");
    require_match("ERROR in process_asm\nMISSING ;\n", ";");
}

/* Process do while loops */
void process_do()
{
    struct token_list* nested_locals = break_frame;
    char* nested_break_head = break_target_head;
    char* nested_break_func = break_target_func;
    char* nested_break_num = break_target_num;
    char* nested_continue_head = continue_target_head;

    char* number_string = int2str(current_count, 10, TRUE);
    current_count = current_count + 1;

    break_target_head = "DO_END_";
    continue_target_head = "DO_TEST_";
    break_target_num = number_string;
    break_frame = function->locals;
    break_target_func = function->s;

    emit_out(":DO_");
    uniqueID_out(function->s, number_string);

    global_token = global_token->next;
    require(NULL != global_token, "Received EOF where do statement is expected\n");
    statement();
    require(NULL != global_token, "Reached EOF inside of function\n");

    emit_out(":DO_TEST_");
    uniqueID_out(function->s, number_string);

    require_match("ERROR in process_do\nMISSING while\n", "while");
    require_match("ERROR in process_do\nMISSING (\n", "(");
    expression();
    require_match("ERROR in process_do\nMISSING )\n", ")");
    require_match("ERROR in process_do\nMISSING ;\n", ";");

    if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("JUMP.NZ R0 @DO_");
    else if(X86 == Architecture) emit_out("test_eax,eax\njne %DO_");
    else if(AMD64 == Architecture) emit_out("test_rax,rax\njne %DO_");
    else if(ARMV7L == Architecture) emit_out("!0 CMPI8 R0 IMM_ALWAYS\n^~DO_");
    else if(AARCH64 == Architecture) emit_out("CBZ_X0_PAST_BR\nLOAD_W16_AHEAD\nSKIP_32_DATA\n&DO_");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("RS1_A0 @DO_END_");
    uniqueID_out(function->s, number_string);
    if(ARMV7L == Architecture) emit_out(" JUMP_NE\n");
    else if(AARCH64 == Architecture) emit_out("\nBR_X16\n");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture))
    {
        emit_out("BEQZ\n$DO_");
        uniqueID_out(function->s, number_string);
        emit_out("JAL\n");
    }

    emit_out(":DO_END_");
    uniqueID_out(function->s, number_string);

    break_frame = nested_locals;
    break_target_head = nested_break_head;
    break_target_func = nested_break_func;
    break_target_num = nested_break_num;
    continue_target_head = nested_continue_head;
}


/* Process while loops */
void process_while()
{
    struct token_list* nested_locals = break_frame;
    char* nested_break_head = break_target_head;
    char* nested_break_func = break_target_func;
    char* nested_break_num = break_target_num;
    char* nested_continue_head = continue_target_head;

    char* number_string = int2str(current_count, 10, TRUE);
    current_count = current_count + 1;

    break_target_head = "END_WHILE_";
    continue_target_head = "WHILE_";
    break_target_num = number_string;
    break_frame = function->locals;
    break_target_func = function->s;

    emit_out(":WHILE_");
    uniqueID_out(function->s, number_string);

    global_token = global_token->next;
    require_match("ERROR in process_while\nMISSING (\n", "(");
    expression();

    if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("JUMP.Z R0 @END_WHILE_");
    else if(X86 == Architecture) emit_out("test_eax,eax\nje %END_WHILE_");
    else if(AMD64 == Architecture) emit_out("test_rax,rax\nje %END_WHILE_");
    else if(ARMV7L == Architecture) emit_out("!0 CMPI8 R0 IMM_ALWAYS\n^~END_WHILE_");
    else if(AARCH64 == Architecture) emit_out("CBNZ_X0_PAST_BR\nLOAD_W16_AHEAD\nSKIP_32_DATA\n&END_WHILE_");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("RS1_A0 @8 BNEZ\n$END_WHILE_");
    uniqueID_out(function->s, number_string);
    if(ARMV7L == Architecture) emit_out(" JUMP_EQUAL\t");
    else if(AARCH64 == Architecture) emit_out("\nBR_X16\n");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("JAL\n");
    emit_out("# THEN_while_");
    uniqueID_out(function->s, number_string);

    require_match("ERROR in process_while\nMISSING )\n", ")");
    statement();
    require(NULL != global_token, "Reached EOF inside of function\n");

    if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("JUMP @WHILE_");
    else if(X86 == Architecture) emit_out("jmp %WHILE_");
    else if(AMD64 == Architecture) emit_out("jmp %WHILE_");
    else if(ARMV7L == Architecture) emit_out("^~WHILE_");
    else if(AARCH64 == Architecture) emit_out("LOAD_W16_AHEAD\nSKIP_32_DATA\n&WHILE_");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("$WHILE_");
    uniqueID_out(function->s, number_string);
    if(ARMV7L == Architecture) emit_out(" JUMP_ALWAYS\n");
    else if(AARCH64 == Architecture) emit_out("\nBR_X16\n");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("JAL\n");
    emit_out(":END_WHILE_");
    uniqueID_out(function->s, number_string);

    break_target_head = nested_break_head;
    break_target_func = nested_break_func;
    break_target_num = nested_break_num;
    continue_target_head = nested_continue_head;
    break_frame = nested_locals;
}

/* Ensure that functions return */
void return_result()
{
    global_token = global_token->next;
    require(NULL != global_token, "Incomplete return statement received\n");
    if(global_token->s[0] != ';') expression();

    require_match("ERROR in return_result\nMISSING ;\n", ";");

    struct token_list* i;
    unsigned size_local_var;
    for(i = function->locals; NULL != i; i = i->next)
    {
        size_local_var = ceil_div(i->type->size, register_size);
        while(size_local_var != 0)
        {
            if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("POPR R1 R15\t# _return_result_locals\n");
            else if(X86 == Architecture) emit_out("pop_ebx\t# _return_result_locals\n");
            else if(AMD64 == Architecture) emit_out("pop_rbx\t# _return_result_locals\n");
            else if(ARMV7L == Architecture) emit_out("{R1} POP_ALWAYS\t# _return_result_locals\n");
            else if(AARCH64 == Architecture) emit_out("POP_X1\t# _return_result_locals\n");
            else if(RISCV32 == Architecture) emit_out("RD_A1 RS1_SP LW  # _return_result_locals\nRD_SP RS1_SP !4 ADDI\n");
            else if(RISCV64 == Architecture) emit_out("RD_A1 RS1_SP LD  # _return_result_locals\nRD_SP RS1_SP !8 ADDI\n");
            size_local_var = size_local_var - 1;
        }
    }

    if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("RET R15\n");
    else if(X86 == Architecture) emit_out("ret\n");
    else if(AMD64 == Architecture) emit_out("ret\n");
    else if(ARMV7L == Architecture) emit_out("'1' LR RETURN\n");
    else if(AARCH64 == Architecture) emit_out("RETURN\n");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("RETURN\n");
}

void process_break()
{
    if(NULL == break_target_head)
    {
        line_error();
        fputs("Not inside of a loop or case statement\n", stderr);
        exit(EXIT_FAILURE);
    }
    struct token_list* i = function->locals;
    while(i != break_frame)
    {
        if(NULL == i) break;
        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("POPR R1 R15\t# break_cleanup_locals\n");
        else if(X86 == Architecture) emit_out("pop_ebx\t# break_cleanup_locals\n");
        else if(AMD64 == Architecture) emit_out("pop_rbx\t# break_cleanup_locals\n");
        else if(ARMV7L == Architecture) emit_out("{R1} POP_ALWAYS\t# break_cleanup_locals\n");
        else if(AARCH64 == Architecture) emit_out("POP_X1\t# break_cleanup_locals\n");
        else if(RISCV32 == Architecture) emit_out("RD_A1 RS1_SP LW\t# break_cleanup_locals\nRD_SP RS1_SP !4 ADDI\n");
        else if(RISCV64 == Architecture) emit_out("RD_A1 RS1_SP LD\t# break_cleanup_locals\nRD_SP RS1_SP !8 ADDI\n");
        i = i->next;
    }
    global_token = global_token->next;

    if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("JUMP @");
    else if(X86 == Architecture) emit_out("jmp %");
    else if(AMD64 == Architecture) emit_out("jmp %");
    else if(ARMV7L == Architecture) emit_out("^~");
    else if(AARCH64 == Architecture) emit_out("LOAD_W16_AHEAD\nSKIP_32_DATA\n&");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("$");

    emit_out(break_target_head);
    emit_out(break_target_func);
    emit_out("_");
    emit_out(break_target_num);
    if(ARMV7L == Architecture) emit_out(" JUMP_ALWAYS");
    else if(AARCH64 == Architecture) emit_out("\nBR_X16");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out(" JAL");
    emit_out("\n");
    require_match("ERROR in break statement\nMissing ;\n", ";");
}

void process_continue()
{
    if(NULL == continue_target_head)
    {
        line_error();
        fputs("Not inside of a loop\n", stderr);
        exit(EXIT_FAILURE);
    }
    global_token = global_token->next;

    if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("JUMP @");
    else if(X86 == Architecture) emit_out("jmp %");
    else if(AMD64 == Architecture) emit_out("jmp %");
    else if(ARMV7L == Architecture) emit_out("^~");
    else if(AARCH64 == Architecture) emit_out("LOAD_W16_AHEAD\nSKIP_32_DATA\n&");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("$");

    emit_out(continue_target_head);
    emit_out(break_target_func);
    emit_out("_");
    emit_out(break_target_num);
    if(ARMV7L == Architecture) emit_out(" JUMP_ALWAYS");
    else if(AARCH64 == Architecture) emit_out("\nBR_X16");
    else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out(" JAL");
    emit_out("\n");
    require_match("ERROR in continue statement\nMissing ;\n", ";");
}

void recursive_statement()
{
    global_token = global_token->next;
    require(NULL != global_token, "Received EOF in recursive statement\n");
    struct token_list* frame = function->locals;

    while(!match("}", global_token->s))
    {
        statement();
        require(NULL != global_token, "Received EOF in recursive statement prior to }\n");
    }
    global_token = global_token->next;

    /* Clean up any locals added */

    if(((X86 == Architecture) && !match("ret\n", output_list->s)) ||
       ((AMD64 == Architecture) && !match("ret\n", output_list->s)) ||
       (((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) && !match("RET R15\n", output_list->s)) ||
       ((ARMV7L == Architecture) && !match("'1' LR RETURN\n", output_list->s)) ||
       ((AARCH64 == Architecture) && !match("RETURN\n", output_list->s)) ||
       (((RISCV32 == Architecture) || (RISCV64 == Architecture)) && !match("RETURN\n", output_list->s)))
    {
        struct token_list* i;
        for(i = function->locals; frame != i; i = i->next)
        {
            if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("POPR R1 R15\t# _recursive_statement_locals\n");
            else if(X86 == Architecture) emit_out( "pop_ebx\t# _recursive_statement_locals\n");
            else if(AMD64 == Architecture) emit_out("pop_rbx\t# _recursive_statement_locals\n");
            else if(ARMV7L == Architecture) emit_out("{R1} POP_ALWAYS\t# _recursive_statement_locals\n");
            else if(AARCH64 == Architecture) emit_out("POP_X1\t# _recursive_statement_locals\n");
            else if(RISCV32 == Architecture) emit_out("RD_A1 RS1_SP LW\t# _recursive_statement_locals\nRD_SP RS1_SP !4 ADDI\n");
            else if(RISCV64 == Architecture) emit_out("RD_A1 RS1_SP LD\t# _recursive_statement_locals\nRD_SP RS1_SP !8 ADDI\n");
        }
    }
    function->locals = frame;
}

/*
 * statement:
 *     { statement-list-opt }
 *     type-name identifier ;
 *     type-name identifier = expression;
 *     if ( expression ) statement
 *     if ( expression ) statement else statement
 *     do statement while ( expression ) ;
 *     while ( expression ) statement
 *     for ( expression ; expression ; expression ) statement
 *     asm ( "assembly" ... "assembly" ) ;
 *     goto label ;
 *     label:
 *     return ;
 *     break ;
 *     expr ;
 */

struct type* lookup_type(char* s, struct type* start);
void statement()
{
    require(NULL != global_token, "expected a C statement but received EOF\n");
    /* Always an integer until told otherwise */
    current_target = integer;

    if(global_token->s[0] == '{')
    {
        recursive_statement();
    }
    else if(':' == global_token->s[0])
    {
        emit_out(global_token->s);
        emit_out("\t#C goto label\n");
        global_token = global_token->next;
    }
    else if((NULL != lookup_type(global_token->s, prim_types)) ||
              match("struct", global_token->s))
    {
        collect_local();
    }
    else if(match("if", global_token->s))
    {
        process_if();
    }
    else if(match("do", global_token->s))
    {
        process_do();
    }
    else if(match("while", global_token->s))
    {
        process_while();
    }
    else if(match("for", global_token->s))
    {
        process_for();
    }
    else if(match("asm", global_token->s))
    {
        process_asm();
    }
    else if(match("goto", global_token->s))
    {
        global_token = global_token->next;
        require(NULL != global_token, "naked goto is not supported\n");
        if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("JUMP @");
        else if(X86 == Architecture) emit_out("jmp %");
        else if(AMD64 == Architecture) emit_out("jmp %");
        else if(ARMV7L == Architecture) emit_out("^~");
        else if(AARCH64 == Architecture) emit_out("LOAD_W16_AHEAD\nSKIP_32_DATA\n&");
        else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out("$");
        emit_out(global_token->s);
        if(ARMV7L == Architecture) emit_out(" JUMP_ALWAYS");
        else if(AARCH64 == Architecture) emit_out("\nBR_X16");
        else if((RISCV32 == Architecture) || (RISCV64 == Architecture)) emit_out(" JAL");
        emit_out("\n");
        global_token = global_token->next;
        require_match("ERROR in statement\nMissing ;\n", ";");
    }
    else if(match("return", global_token->s))
    {
        return_result();
    }
    else if(match("break", global_token->s))
    {
        process_break();
    }
    else if(match("continue", global_token->s))
    {
        process_continue();
    }
    else
    {
        expression();
        require_match("ERROR in statement\nMISSING ;\n", ";");
    }
}

/* Collect function arguments */
void collect_arguments()
{
    global_token = global_token->next;
    require(NULL != global_token, "Received EOF when attempting to collect arguments\n");
    struct type* type_size;
    struct token_list* a;

    while(!match(")", global_token->s))
    {
        type_size = type_name();
        require(NULL != global_token, "Received EOF when attempting to collect arguments\n");
        require(NULL != type_size, "Must have non-null type\n");
        if(global_token->s[0] == ')')
        {
            /* foo(int,char,void) doesn't need anything done */
            continue;
        }
        else if(global_token->s[0] != ',')
        {
            /* deal with foo(int a, char b) */
            require(!in_set(global_token->s[0], "[{(<=>)}]|&!^%;:'\""), "forbidden character in argument variable name\n");
            require(!iskeywordp(global_token->s), "You are not allowed to use a keyword as a argument variable name\n");
            a = sym_declare(global_token->s, type_size, function->arguments);
            if(NULL == function->arguments)
            {
                if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) a->depth = 0;
                else if(X86 == Architecture) a->depth = -4;
                else if(AMD64 == Architecture) a->depth = -8;
                else if(ARMV7L == Architecture) a->depth = 4;
                else if(AARCH64 == Architecture) a->depth = register_size;
                else if(RISCV32 == Architecture) a->depth = -4;
                else if(RISCV64 == Architecture) a->depth = -8;
            }
            else
            {
                if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) a->depth = function->arguments->depth + register_size;
                else if(X86 == Architecture) a->depth = function->arguments->depth - register_size;
                else if(AMD64 == Architecture) a->depth = function->arguments->depth - register_size;
                else if(ARMV7L == Architecture) a->depth = function->arguments->depth + register_size;
                else if(AARCH64 == Architecture) a->depth = function->arguments->depth + register_size;
                else if(RISCV32 == Architecture) a->depth = function->arguments->depth - register_size;
                else if(RISCV64 == Architecture) a->depth = function->arguments->depth - register_size;
            }

            global_token = global_token->next;
            require(NULL != global_token, "Incomplete argument list\n");
            function->arguments = a;
        }

        /* ignore trailing comma (needed for foo(bar(), 1); expressions*/
        if(global_token->s[0] == ',')
        {
            global_token = global_token->next;
            require(NULL != global_token, "naked comma in collect arguments\n");
        }

        require(NULL != global_token, "Argument list never completed\n");
    }
    global_token = global_token->next;
}

void declare_function()
{
    current_count = 0;
    function = sym_declare(global_token->prev->s, NULL, global_function_list);

    /* allow previously defined functions to be looked up */
    global_function_list = function;
    if((KNIGHT_NATIVE == Architecture) && match("main", function->s))
    {
        require_match("Impossible error ( vanished\n", "(");
        require_match("Reality ERROR (USING KNIGHT-NATIVE)\nHardware does not support arguments\nthus neither can main on this architecture\ntry tape_01 and tape_02 instead\n", ")");
    }
    else collect_arguments();

    require(NULL != global_token, "Function definitions either need to be prototypes or full\n");
    /* If just a prototype don't waste time */
    if(global_token->s[0] == ';') global_token = global_token->next;
    else
    {
        emit_out("# Defining function ");
        emit_out(function->s);
        emit_out("\n");
        emit_out(":FUNCTION_");
        emit_out(function->s);
        emit_out("\n");
        statement();

        /* Prevent duplicate RETURNS */
        if(((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) && !match("RET R15\n", output_list->s)) emit_out("RET R15\n");
        else if((X86 == Architecture) && !match("ret\n", output_list->s)) emit_out("ret\n");
        else if((AMD64 == Architecture) && !match("ret\n", output_list->s)) emit_out("ret\n");
        else if((ARMV7L == Architecture) && !match("'1' LR RETURN\n", output_list->s)) emit_out("'1' LR RETURN\n");
        else if((AARCH64 == Architecture) && !match("RETURN\n", output_list->s)) emit_out("RETURN\n");
        else if((RISCV32 == Architecture) && !match("RETURN\n", output_list->s)) emit_out("RETURN\n");
        else if((RISCV64 == Architecture) && !match("RETURN\n", output_list->s)) emit_out("RETURN\n");
    }
}

void global_constant()
{
    global_token = global_token->next;
    require(NULL != global_token, "CONSTANT lacks a name\n");
    global_constant_list = sym_declare(global_token->s, NULL, global_constant_list);

    require(NULL != global_token->next, "CONSTANT lacks a value\n");
    if(match("sizeof", global_token->next->s))
    {
        global_token = global_token->next->next;
        require_match("ERROR in CONSTANT with sizeof\nMissing (\n", "(");
        struct type* a = type_name();
        require_match("ERROR in CONSTANT with sizeof\nMissing )\n", ")");
        global_token->prev->s = int2str(a->size, 10, TRUE);
        global_constant_list->arguments = global_token->prev;
    }
    else
    {
        global_constant_list->arguments = global_token->next;
        global_token = global_token->next->next;
    }
}

struct type* global_typedef()
{
    struct type* type_size;
    /* typedef $TYPE $NAME; */
    global_token = global_token->next;
    type_size = type_name();
    require(NULL != global_token, "Received EOF while reading typedef\n");
    type_size = mirror_type(type_size, global_token->s);
    add_primitive(type_size);
    global_token = global_token->next;
    require_match("ERROR in typedef statement\nMissing ;\n", ";");
    return type_size;
}

void global_static_array(struct type* type_size, struct token_list* name)
{
    int size;
    maybe_bootstrap_error("global array definitions");
    globals_list = emit(":GLOBAL_", globals_list);
    globals_list = emit(name->s, globals_list);
    globals_list = emit("\n&GLOBAL_STORAGE_", globals_list);
    globals_list = emit(name->s, globals_list);
    if (AARCH64 == Architecture || AMD64 == Architecture || RISCV64 == Architecture)
    {
        globals_list = emit(" %0", globals_list);
    }
    globals_list = emit("\n:GLOBAL_STORAGE_", globals_list);
    globals_list = emit(name->s, globals_list);

    require(NULL != global_token->next, "Unterminated global\n");
    global_token = global_token->next;

    /* Make sure not negative */
    if(match("-", global_token->s))
    {
        line_error();
        fputs("Negative values are not supported for allocated arrays\n", stderr);
        exit(EXIT_FAILURE);
    }

    /* length */
    size = strtoint(global_token->s) * type_size->size;

    /* Stop bad states */
    if((size < 0) || (size > 0x100000))
    {
        line_error();
        fputs("M2-Planet is very inefficient so you probably don't want to allocate over 1MB into your binary for NULLs\n", stderr);
        exit(EXIT_FAILURE);
    }

    /* Ensure properly closed */
    global_token = global_token->next;
    require_match("missing close bracket\n", "]");
    require_match("missing ;\n", ";");

    globals_list = emit("\n'", globals_list);
    while (0 != size)
    {
        globals_list = emit(" 00", globals_list);
        size = size - 1;
    }
    globals_list = emit("'\n", globals_list);
}

void global_assignment()
{
    /* Store the global's value*/
    globals_list = emit(":GLOBAL_", globals_list);
    globals_list = emit(global_token->prev->s, globals_list);
    globals_list = emit("\n", globals_list);
    global_token = global_token->next;
    require(NULL != global_token, "Global locals value in assignment\n");
    if(in_set(global_token->s[0], "0123456789"))
    { /* Assume Int */
        globals_list = emit("%", globals_list);
        globals_list = emit(global_token->s, globals_list);
        globals_list = emit("\n", globals_list);
    }
    else if(('"' == global_token->s[0]))
    { /* Assume a string*/
        globals_list = emit("&GLOBAL_", globals_list);
        globals_list = emit(global_token->prev->prev->s, globals_list);
        globals_list = emit("_contents\n", globals_list);

        globals_list = emit(":GLOBAL_", globals_list);
        globals_list = emit(global_token->prev->prev->s, globals_list);
        globals_list = emit("_contents\n", globals_list);
        globals_list = emit(parse_string(global_token->s), globals_list);
    }
    else
    {
        line_error();
        fputs("Received ", stderr);
        fputs(global_token->s, stderr);
        fputs(" in program\n", stderr);
        exit(EXIT_FAILURE);
    }

    global_token = global_token->next;
    require_match("ERROR in Program\nMissing ;\n", ";");
}

/*
 * program:
 *     declaration
 *     declaration program
 *
 * declaration:
 *     CONSTANT identifer value
 *     typedef identifer type;
 *     type-name identifier ;
 *     type-name identifier = value ;
 *     type-name identifier [ value ];
 *     type-name identifier ( parameter-list ) ;
 *     type-name identifier ( parameter-list ) statement
 *
 * parameter-list:
 *     parameter-declaration
 *     parameter-list, parameter-declaration
 *
 * parameter-declaration:
 *     type-name identifier-opt
 */
void program()
{
    unsigned i;
    function = NULL;
    Address_of = FALSE;
    struct type* type_size;

new_type:
    /* Deal with garbage input */
    if (NULL == global_token) return;
    require('#' != global_token->s[0], "unhandled macro directive\n");
    require(!match("\n", global_token->s), "unexpected newline token\n");

    /* Handle cc_* CONSTANT statements */
    if(match("CONSTANT", global_token->s))
    {
        global_constant();
        goto new_type;
    }

    /* Handle c typedef statements */
    if(match("typedef", global_token->s))
    {
        type_size = global_typedef();
        goto new_type;
    }

    type_size = type_name();
    /* Deal with case of struct definitions */
    if(NULL == type_size) goto new_type;

    require(NULL != global_token->next, "Unterminated global\n");

    /* Add to global symbol table */
    global_symbol_list = sym_declare(global_token->s, type_size, global_symbol_list);
    global_token = global_token->next;

    /* Deal with global variables */
    if(match(";", global_token->s))
    {
        /* Ensure enough bytes are allocated to store global variable.
           In some cases it allocates too much but that is harmless. */
        globals_list = emit(":GLOBAL_", globals_list);
        globals_list = emit(global_token->prev->s, globals_list);

        /* round up division */
        i = ceil_div(type_size->size, register_size);
        globals_list = emit("\n", globals_list);
        while(i != 0)
        {
            globals_list = emit("NULL\n", globals_list);
            i = i - 1;
        }
        global_token = global_token->next;
        goto new_type;
    }

    /* Deal with global functions */
    if(match("(", global_token->s))
    {
        declare_function();
        goto new_type;
    }

    /* Deal with assignment to a global variable */
    if(match("=", global_token->s))
    {
        global_assignment();
        goto new_type;
    }

    /* Deal with global static arrays */
    if(match("[", global_token->s))
    {
        global_static_array(type_size, global_token->prev);
        goto new_type;
    }

    /* Everything else is just an error */
    line_error();
    fputs("Received ", stderr);
    fputs(global_token->s, stderr);
    fputs(" in program\n", stderr);
    exit(EXIT_FAILURE);
}

void recursive_output(struct token_list* head, FILE* out)
{
    struct token_list* i = reverse_list(head);
    while(NULL != i)
    {
        fputs(i->s, out);
        i = i->next;
    }
}

void output_tokens(struct token_list *i, FILE* out)
{
    while(NULL != i)
    {
        fputs(i->s, out);
        fputs(" ", out);
        i = i->next;
    }
}

https://github.com/oriansj/M2-Planet/blob/main/cc_macro.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/M2-Planet/cc_macro.c used in: Step 13, Step 61
/* Copyright (C) 2021 Sanne Wouda
 * Copyright (C) 2021 Andrius Å tikonas <andrius@stikonas.eu>
 * Copyright (C) 2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */
#include "cc.h"
#include "gcc_req.h"

void require(int bool, char* error);
int strtoint(char* a);
void line_error_token(struct token_list* list);
struct token_list* eat_token(struct token_list* head);

struct conditional_inclusion
{
    struct conditional_inclusion* prev;
    int include; /* 1 == include, 0 == skip */
    int previous_condition_matched; /* 1 == all subsequent conditions treated as FALSE */
};

struct macro_list
{
    struct macro_list* next;
    char* symbol;
    struct token_list* expansion;
};

struct macro_list* macro_env;
struct conditional_inclusion* conditional_inclusion_top;

/* point where we are currently modifying the global_token list */
struct token_list* macro_token;

void init_macro_env(char* sym, char* value, char* source, int num)
{
    struct macro_list* hold = macro_env;
    macro_env = calloc(1, sizeof(struct macro_list));
    macro_env->symbol = sym;
    macro_env->next = hold;
    macro_env->expansion = calloc(1, sizeof(struct token_list));
    macro_env->expansion->s = value;
    macro_env->expansion->filename = source;
    macro_env->expansion->linenumber = num;
}

void eat_current_token()
{
    int update_global_token = FALSE;
    if (macro_token == global_token)
        update_global_token = TRUE;

    macro_token = eat_token(macro_token);

    if(update_global_token)
        global_token = macro_token;
}

void eat_newline_tokens()
{
    macro_token = global_token;

    while(TRUE)
    {
        if(NULL == macro_token) return;

        if(match("\n", macro_token->s))
        {
            eat_current_token();
        }
        else
        {
            macro_token = macro_token->next;
        }
    }
}

/* returns the first token inserted; inserts *before* point */
struct token_list* insert_tokens(struct token_list* point, struct token_list* token)
{
    struct token_list* copy;
    struct token_list* first = NULL;

    while (NULL != token)
    {
        copy = calloc(1, sizeof(struct token_list));
        copy->s = token->s;
        copy->filename = token->filename;
        copy->linenumber = token->linenumber;

        if(NULL == first)
        {
            first = copy;
        }

        copy->next = point;

        if (NULL != point)
        {
            copy->prev = point->prev;

            if(NULL != point->prev)
            {
                point->prev->next = copy;
            }

            point->prev = copy;
        }

        token = token->next;
    }

    return first;
}

struct macro_list* lookup_macro(struct token_list* token)
{
    if(NULL == token)
    {
        line_error_token(macro_token);
        fputs("null token received in lookup_macro\n", stderr);
        exit(EXIT_FAILURE);
    }

    struct macro_list* hold = macro_env;

    while (NULL != hold)
    {
        if (match(token->s, hold->symbol))
        {
            /* found! */
            return hold;
        }

        hold = hold->next;
    }

    /* not found! */
    return NULL;
}

void remove_macro(struct token_list* token)
{
    if(NULL == token)
    {
        line_error_token(macro_token);
        fputs("received a null in remove_macro\n", stderr);
        exit(EXIT_FAILURE);
    }

    struct macro_list* hold = macro_env;
    struct macro_list* temp;

    /* Deal with the first element */
    if (match(token->s, hold->symbol)) {
        macro_env = hold->next;
        free(hold);
        return;
    }

    /* Remove element form the middle of linked list */
    while (NULL != hold->next)
    {
        if (match(token->s, hold->next->symbol))
        {
            temp = hold->next;
            hold->next = hold->next->next;
            free(temp);
            return;
        }

        hold = hold->next;
    }

    /* nothing to undefine */
    return;
}

int macro_expression();
int macro_variable()
{
    int value = 0;
    struct macro_list* hold = lookup_macro(macro_token);
    if (NULL != hold)
    {
        if(NULL == hold->expansion)
        {
            line_error_token(macro_token);
            fputs("hold->expansion is a null\n", stderr);
            exit(EXIT_FAILURE);
        }
        value = strtoint(hold->expansion->s);
    }
    eat_current_token();
    return value;
}

int macro_number()
{
    int result = strtoint(macro_token->s);
    eat_current_token();
    return result;
}

int macro_primary_expr()
{
    int defined_has_paren = FALSE;
    int hold;
    require(NULL != macro_token, "got an EOF terminated macro primary expression\n");

    if('-' == macro_token->s[0])
    {
        eat_current_token();
        return -macro_primary_expr();
    }
    else if('!' == macro_token->s[0])
    {
        eat_current_token();
        return !macro_primary_expr();
    }
    else if('(' == macro_token->s[0])
    {
        eat_current_token();
        hold = macro_expression();
        require(')' == macro_token->s[0], "missing ) in macro expression\n");
        eat_current_token();
        return hold;
    }
    else if(match("defined", macro_token->s))
    {
        eat_current_token();

        require(NULL != macro_token, "got an EOF terminated macro defined expression\n");

        if('(' == macro_token->s[0])
        {
            defined_has_paren = TRUE;
            eat_current_token();
        }

        if (NULL != lookup_macro(macro_token))
        {
            hold = TRUE;
        }
        else
        {
            hold = FALSE;
        }
        eat_current_token();

        if(TRUE == defined_has_paren)
        {
            if(NULL == macro_token)
            {
                line_error_token(macro_token);
                fputs("unterminated define ( statement\n", stderr);
                exit(EXIT_FAILURE);
            }
            require(')' == macro_token->s[0], "missing close parenthesis for defined()\n");
            eat_current_token();
        }

        return hold;
    }
    else if(in_set(macro_token->s[0], "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_"))
    {
        return macro_variable();
    }
    else if(in_set(macro_token->s[0], "0123456789"))
    {
        return macro_number();
    }
    else
    {
        return 0;    /* FIXME: error handling */
    }
}

int macro_additive_expr()
{
    int lhs = macro_primary_expr();
    int hold;

    require(NULL != macro_token, "got an EOF terminated macro additive expression\n");
    if(match("+", macro_token->s))
    {
        eat_current_token();
        return lhs + macro_additive_expr();
    }
    else if(match("-", macro_token->s))
    {
        eat_current_token();
        return lhs - macro_additive_expr();
    }
    else if(match("*", macro_token->s))
    {
        eat_current_token();
        return lhs * macro_additive_expr();
    }
    else if(match("/", macro_token->s))
    {
        eat_current_token();
        hold = macro_additive_expr();
        require(0 != hold, "divide by zero not valid even in C macros\n");
        return lhs / hold;
    }
    else if(match("%", macro_token->s))
    {
        eat_current_token();
        hold = macro_additive_expr();
        require(0 != hold, "modulus by zero not valid even in C macros\n");
        return lhs % hold;
    }
    else if(match(">>", macro_token->s))
    {
        eat_current_token();
        return lhs >> macro_additive_expr();
    }
    else if(match("<<", macro_token->s))
    {
        eat_current_token();
        return lhs << macro_additive_expr();
    }
    else
    {
        return lhs;
    }
}

int macro_relational_expr()
{
    int lhs = macro_additive_expr();

    if(match("<", macro_token->s))
    {
        eat_current_token();
        return lhs < macro_relational_expr();
    }
    else if(match("<=", macro_token->s))
    {
        eat_current_token();
        return lhs <= macro_relational_expr();
    }
    else if(match(">=", macro_token->s))
    {
        eat_current_token();
        return lhs >= macro_relational_expr();
    }
    else if(match(">", macro_token->s))
    {
        eat_current_token();
        return lhs > macro_relational_expr();
    }
    else if(match("==", macro_token->s))
    {
        eat_current_token();
        return lhs == macro_relational_expr();
    }
    else if(match("!=", macro_token->s))
    {
        eat_current_token();
        return lhs != macro_relational_expr();
    }
    else
    {
        return lhs;
    }
}

int macro_bitwise_expr()
{
    int rhs;
    int lhs = macro_relational_expr();

    if(match("&", macro_token->s))
    {
        eat_current_token();
        return lhs & macro_bitwise_expr();
    }
    else if(match("&&", macro_token->s))
    {
        eat_current_token();
        rhs = macro_bitwise_expr();
        return lhs && rhs;
    }
    else if(match("|", macro_token->s))
    {
        eat_current_token();
        rhs = macro_bitwise_expr();
        return lhs | rhs;
    }
    else if(match("||", macro_token->s))
    {
        eat_current_token();
        rhs = macro_bitwise_expr();
        return lhs || rhs;
    }
    else if(match("^", macro_token->s))
    {
        eat_current_token();
        rhs = macro_bitwise_expr();
        return lhs ^ rhs;
    }
    else
    {
        return lhs;
    }
}

int macro_expression()
{
    return macro_bitwise_expr();
}

void handle_define()
{
    struct macro_list* hold;
    struct token_list* expansion_end = NULL;

    /* don't use #define statements from non-included blocks */
    int conditional_define = TRUE;
    if(NULL != conditional_inclusion_top)
    {
        if(FALSE == conditional_inclusion_top->include)
        {
            conditional_define = FALSE;
        }
    }

    eat_current_token();

    require(NULL != macro_token, "got an EOF terminated #define\n");
    require('\n' != macro_token->s[0], "unexpected newline after #define\n");

    /* insert new macro */
    hold = calloc(1, sizeof(struct macro_list));
    hold->symbol = macro_token->s;
    hold->next = macro_env;
    /* provided it isn't in a non-included block */
    if(conditional_define) macro_env = hold;

    /* discard the macro name */
    eat_current_token();

    while (TRUE)
    {
        require(NULL != macro_token, "got an EOF terminated #define\n");

        if ('\n' == macro_token->s[0])
        {
            if(NULL == expansion_end)
            {
                hold->expansion = NULL;
                expansion_end = macro_token;
                return;
            }
            expansion_end->next = NULL;
            return;
        }

        require(NULL != hold, "#define got something it can't handle\n");

        expansion_end = macro_token;

        /* in the first iteration, we set the first token of the expansion, if
           it exists */
        if (NULL == hold->expansion)
        {
            hold->expansion = macro_token;
        }

        /* throw away if not used */
        if(!conditional_define && (NULL != hold))
        {
            free(hold);
            hold = NULL;
        }

        eat_current_token();
    }
}

void handle_undef()
{
    eat_current_token();
    remove_macro(macro_token);
    eat_current_token();
}

void handle_error(int warning_p)
{
    /* don't use #error statements from non-included blocks */
    int conditional_error = TRUE;
    if(NULL != conditional_inclusion_top)
    {
        if(FALSE == conditional_inclusion_top->include)
        {
            conditional_error = FALSE;
        }
    }
    eat_current_token();
    /* provided it isn't in a non-included block */
    if(conditional_error)
    {
        line_error_token(macro_token);
        if(warning_p) fputs(" warning: #warning ", stderr);
        else fputs(" error: #error ", stderr);
        while (TRUE)
        {
            require(NULL != macro_token, "\nFailed to properly terminate error message with \\n\n");
            if ('\n' == macro_token->s[0]) break;
            fputs(macro_token->s, stderr);
            macro_token = macro_token->next;
            fputs(" ", stderr);
        }
        fputs("\n", stderr);
        if(!warning_p) exit(EXIT_FAILURE);
    }
    while (TRUE)
    {
        require(NULL != macro_token, "\nFailed to properly terminate error message with \\n\n");
        /* discard the error */
        if ('\n' == macro_token->s[0])
        {
            return;
        }
        eat_current_token();
    }
}

void eat_block();
void macro_directive()
{
    struct conditional_inclusion *t;
    int result;

    /* FIXME: whitespace is allowed between "#"" and "if" */
    if(match("#if", macro_token->s))
    {
        eat_current_token();
        /* evaluate constant integer expression */
        result = macro_expression();
        /* push conditional inclusion */
        t = calloc(1, sizeof(struct conditional_inclusion));
        t->prev = conditional_inclusion_top;
        conditional_inclusion_top = t;
        t->include = TRUE;

        if(FALSE == result)
        {
            t->include = FALSE;
            eat_block();
        }

        t->previous_condition_matched = t->include;
    }
    else if(match("#ifdef", macro_token->s))
    {
        eat_current_token();
        require(NULL != macro_token, "got an EOF terminated macro defined expression\n");
        if (NULL != lookup_macro(macro_token))
        {
            result = TRUE;
            eat_current_token();
        }
        else
        {
            result = FALSE;
            eat_block();
        }

        /* push conditional inclusion */
        t = calloc(1, sizeof(struct conditional_inclusion));
        t->prev = conditional_inclusion_top;
        conditional_inclusion_top = t;
        t->include = TRUE;

        if(FALSE == result)
        {
            t->include = FALSE;
        }

        t->previous_condition_matched = t->include;
    }
    else if(match("#ifndef", macro_token->s))
    {
        eat_current_token();
        require(NULL != macro_token, "got an EOF terminated macro defined expression\n");
        if (NULL != lookup_macro(macro_token))
        {
            result = FALSE;
        }
        else
        {
            result = TRUE;
            eat_current_token();
        }

        /* push conditional inclusion */
        t = calloc(1, sizeof(struct conditional_inclusion));
        t->prev = conditional_inclusion_top;
        conditional_inclusion_top = t;
        t->include = TRUE;

        if(FALSE == result)
        {
            t->include = FALSE;
            eat_block();
        }

        t->previous_condition_matched = t->include;
    }
    else if(match("#elif", macro_token->s))
    {
        eat_current_token();
        result = macro_expression();
        require(NULL != conditional_inclusion_top, "#elif without leading #if\n");
        conditional_inclusion_top->include = result && !conditional_inclusion_top->previous_condition_matched;
        conditional_inclusion_top->previous_condition_matched =
            conditional_inclusion_top->previous_condition_matched || conditional_inclusion_top->include;
        if(FALSE == result)
        {
            eat_block();
        }
    }
    else if(match("#else", macro_token->s))
    {
        eat_current_token();
        require(NULL != conditional_inclusion_top, "#else without leading #if\n");
        conditional_inclusion_top->include = !conditional_inclusion_top->previous_condition_matched;
        if(FALSE == conditional_inclusion_top->include)
        {
            eat_block();
        }
    }
    else if(match("#endif", macro_token->s))
    {
        if(NULL == conditional_inclusion_top)
        {
            line_error_token(macro_token);
            fputs("unexpected #endif\n", stderr);
            exit(EXIT_FAILURE);
        }

        eat_current_token();
        /* pop conditional inclusion */
        t = conditional_inclusion_top;
        conditional_inclusion_top = conditional_inclusion_top->prev;
        free(t);
    }
    else if(match("#define", macro_token->s))
    {
        handle_define();
    }
    else if(match("#undef", macro_token->s))
    {
        handle_undef();
    }
    else if(match("#error", macro_token->s))
    {
        handle_error(FALSE);
    }
    else if(match("#warning", macro_token->s))
    {
        handle_error(TRUE);
    }
    else
    {
        if(!match("#include", macro_token->s))
        {
            /* Put a big fat warning but see if we can just ignore */
            fputs(">>WARNING<<\n>>WARNING<<\n", stderr);
            line_error_token(macro_token);
            fputs("feature: ", stderr);
            fputs(macro_token->s, stderr);
            fputs(" unsupported in M2-Planet\nIgnoring line, may result in bugs\n>>WARNING<<\n>>WARNING<<\n\n", stderr);
        }

        /* unhandled macro directive; let's eat until a newline; om nom nom */
        while(TRUE)
        {
            if(NULL == macro_token)
            {
                return;
            }

            if('\n' == macro_token->s[0])
            {
                return;
            }

            eat_current_token();
        }
    }
}


void eat_until_endif()
{
    /* This #if block is nested inside of an #if block that needs to be dropped, lose EVERYTHING */
    do
    {
        require(NULL != macro_token, "Unterminated #if block\n");
        if(match("#if", macro_token->s) || match("#ifdef", macro_token->s) || match("#ifndef", macro_token->s))
        {
            eat_current_token();
            eat_until_endif();
        }

        eat_current_token();
        require(NULL != macro_token, "Unterminated #if block\n");
    } while(!match("#endif", macro_token->s));
}

void eat_block()
{
    /* This conditional #if block is wrong, drop everything until the #elif/#else/#endif */
    do
    {
        if(match("#if", macro_token->s) || match("#ifdef", macro_token->s) || match("#ifndef", macro_token->s))
        {
            eat_current_token();
            eat_until_endif();
        }

        eat_current_token();
        require(NULL != macro_token, "Unterminated #if block\n");
        if(match("#elif", macro_token->s)) break;
        if(match("#else", macro_token->s)) break;
        if(match("#endif", macro_token->s)) break;
    } while(TRUE);
    require(NULL != macro_token->prev, "impossible #if block\n");

    /* rewind the newline */
    if(match("\n", macro_token->prev->s)) macro_token = macro_token->prev;
}


struct token_list* maybe_expand(struct token_list* token)
{
    if(NULL == token)
    {
        line_error_token(macro_token);
        fputs("maybe_expand passed a null token\n", stderr);
        exit(EXIT_FAILURE);
    }

    struct macro_list* hold = lookup_macro(token);
    struct token_list* hold2;
    if(NULL == token->next)
    {
        line_error_token(macro_token);
        fputs("we can't expand a null token: ", stderr);
        fputs(token->s, stderr);
        fputc('\n', stderr);
        exit(EXIT_FAILURE);
    }

    if (NULL == hold)
    {
        return token->next;
    }

    token = eat_token(token);

    if (NULL == hold->expansion)
    {
        return token->next;
    }
    hold2 = insert_tokens(token, hold->expansion);

    return hold2->next;
}

void preprocess()
{
    int start_of_line = TRUE;
    macro_token = global_token;

    while(NULL != macro_token)
    {
        if(start_of_line && '#' == macro_token->s[0])
        {
            macro_directive();

            if(macro_token)
            {
                if('\n' != macro_token->s[0])
                {
                    line_error_token(macro_token);
                    fputs("newline expected at end of macro directive\n", stderr);
                    fputs("found: '", stderr);
                    fputs(macro_token->s, stderr);
                    fputs("'\n", stderr);
                    exit(EXIT_FAILURE);
                }
            }
        }
        else if('\n' == macro_token->s[0])
        {
            start_of_line = TRUE;
            macro_token = macro_token->next;
        }
        else
        {
            start_of_line = FALSE;
            if(NULL == conditional_inclusion_top)
            {
                macro_token = maybe_expand(macro_token);
            }
            else if(!conditional_inclusion_top->include)
            {
                /* rewrite the token stream to exclude the current token */
                eat_block();
                start_of_line = TRUE;
            }
            else
            {
                macro_token = maybe_expand(macro_token);
            }
        }
    }
}

https://github.com/oriansj/M2-Planet/blob/main/cc.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/M2-Planet/cc.c used in: Step 13, Step 61
/* Copyright (C) 2016 Jeremiah Orians
 * Copyright (C) 2020 deesix <deesix@tuta.io>
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include"cc.h"

/* The core functions */
void initialize_types();
struct token_list* read_all_tokens(FILE* a, struct token_list* current, char* filename);
struct token_list* reverse_list(struct token_list* head);

struct token_list* remove_line_comments(struct token_list* head);
struct token_list* remove_line_comment_tokens(struct token_list* head);
struct token_list* remove_preprocessor_directives(struct token_list* head);

void eat_newline_tokens();
void init_macro_env(char* sym, char* value, char* source, int num);
void preprocess();
void program();
void recursive_output(struct token_list* i, FILE* out);
void output_tokens(struct token_list *i, FILE* out);
int strtoint(char *a);

int main(int argc, char** argv)
{
    MAX_STRING = 4096;
    BOOTSTRAP_MODE = FALSE;
    PREPROCESSOR_MODE = FALSE;
    int DEBUG = FALSE;
    FILE* in = stdin;
    FILE* destination_file = stdout;
    Architecture = 0; /* catch unset */
    init_macro_env("__M2__", "42", "__INTERNAL_M2__", 0); /* Setup __M2__ */
    char* arch;
    char* name;
    char* hold;
    int env=0;
    char* val;

    int i = 1;
    while(i <= argc)
    {
        if(NULL == argv[i])
        {
            i = i + 1;
        }
        else if(match(argv[i], "-f") || match(argv[i], "--file"))
        {
            if(NULL == hold_string)
            {
                hold_string = calloc(MAX_STRING + 4, sizeof(char));
                require(NULL != hold_string, "Impossible Exhaustion has occurred\n");
            }

            name = argv[i + 1];
            if(NULL == name)
            {
                fputs("did not receive a file name\n", stderr);
                exit(EXIT_FAILURE);
            }

            in = fopen(name, "r");
            if(NULL == in)
            {
                fputs("Unable to open for reading file: ", stderr);
                fputs(name, stderr);
                fputs("\n Aborting to avoid problems\n", stderr);
                exit(EXIT_FAILURE);
            }
            global_token = read_all_tokens(in, global_token, name);
            fclose(in);
            i = i + 2;
        }
        else if(match(argv[i], "-o") || match(argv[i], "--output"))
        {
            destination_file = fopen(argv[i + 1], "w");
            if(NULL == destination_file)
            {
                fputs("Unable to open for writing file: ", stderr);
                fputs(argv[i + 1], stderr);
                fputs("\n Aborting to avoid problems\n", stderr);
                exit(EXIT_FAILURE);
            }
            i = i + 2;
        }
        else if(match(argv[i], "-A") || match(argv[i], "--architecture"))
        {
            arch = argv[i + 1];
            if(match("knight-native", arch)) {
                Architecture = KNIGHT_NATIVE;
                init_macro_env("__knight__", "1", "--architecture", env);
                env = env + 1;
            }
            else if(match("knight-posix", arch)) {
                Architecture = KNIGHT_POSIX;
                init_macro_env("__knight_posix__", "1", "--architecture", env);
                env = env + 1;
            }
            else if(match("x86", arch))
            {
                Architecture = X86;
                init_macro_env("__i386__", "1", "--architecture", env);
                env = env + 1;
            }
            else if(match("amd64", arch))
            {
                Architecture = AMD64;
                init_macro_env("__x86_64__", "1", "--architecture", env);
                env = env + 1;
            }
            else if(match("armv7l", arch))
            {
                Architecture = ARMV7L;
                init_macro_env("__arm__", "1", "--architecture", env);
                env = env + 1;
            }
            else if(match("aarch64", arch))
            {
                Architecture = AARCH64;
                init_macro_env("__aarch64__", "1", "--architecture", env);
                env = env + 1;
            }
            else if(match("riscv32", arch))
            {
                Architecture = RISCV32;
                init_macro_env("__riscv", "1", "--architecture", env);
                init_macro_env("__riscv_xlen", "32", "--architecture", env + 1);
                env = env + 2;
            }
            else if(match("riscv64", arch))
            {
                Architecture = RISCV64;
                init_macro_env("__riscv", "1", "--architecture", env);
                init_macro_env("__riscv_xlen", "64", "--architecture", env + 1);
                env = env + 2;
            }
            else
            {
                fputs("Unknown architecture: ", stderr);
                fputs(arch, stderr);
                fputs(" know values are: knight-native, knight-posix, x86, amd64, armv7l, aarch64, riscv32 and riscv64\n", stderr);
                exit(EXIT_FAILURE);
            }
            i = i + 2;
        }
        else if(match(argv[i], "--max-string"))
        {
            hold = argv[i+1];
            if(NULL == hold)
            {
                fputs("--max-string requires a numeric argument\n", stderr);
                exit(EXIT_FAILURE);
            }
            MAX_STRING = strtoint(hold);
            require(0 < MAX_STRING, "Not a valid string size\nAbort and fix your --max-string\n");
            i = i + 2;
        }
        else if(match(argv[i], "--bootstrap-mode"))
        {
            BOOTSTRAP_MODE = TRUE;
            i = i + 1;
        }
        else if(match(argv[i], "-g") || match(argv[i], "--debug"))
        {
            DEBUG = TRUE;
            i = i + 1;
        }
        else if(match(argv[i], "-h") || match(argv[i], "--help"))
        {
            fputs(" -f input file\n -o output file\n --help for this message\n --version for file version\n", stdout);
            exit(EXIT_SUCCESS);
        }
        else if(match(argv[i], "-E"))
        {
            PREPROCESSOR_MODE = TRUE;
            i = i + 1;
        }
        else if(match(argv[i], "-D"))
        {
            val = argv[i+1];
            if(NULL == val)
            {
                fputs("-D requires an argument", stderr);
                exit(EXIT_FAILURE);
            }
            while(0 != val[0])
            {
                if('=' == val[0])
                {
                    val[0] = 0;
                    val = val + 1;
                    break;
                }
                val = val + 1;
            }
            init_macro_env(argv[i+1], val, "__ARGV__", env);
            env = env + 1;
            i = i + 2;
        }
        else if(match(argv[i], "-V") || match(argv[i], "--version"))
        {
            fputs("M2-Planet v1.10.0\n", stderr);
            exit(EXIT_SUCCESS);
        }
        else
        {
            fputs("UNKNOWN ARGUMENT\n", stdout);
            exit(EXIT_FAILURE);
        }
    }

    /* Deal with special case of architecture not being set */
    if(0 == Architecture)
    {
        Architecture = KNIGHT_NATIVE;
        init_macro_env("__knight__", "1", "--architecture", env);
    }

    /* Deal with special case of wanting to read from standard input */
    if(stdin == in)
    {
        hold_string = calloc(MAX_STRING + 4, sizeof(char));
        require(NULL != hold_string, "Impossible Exhaustion has occurred\n");
        global_token = read_all_tokens(in, global_token, "STDIN");
    }

    if(NULL == global_token)
    {
        fputs("Either no input files were given or they were empty\n", stderr);
        exit(EXIT_FAILURE);
    }
    global_token = reverse_list(global_token);

    if (BOOTSTRAP_MODE)
    {
        global_token = remove_line_comment_tokens(global_token);
        global_token = remove_preprocessor_directives(global_token);
    }
    else
    {
        global_token = remove_line_comments(global_token);
        preprocess();
    }

    if (PREPROCESSOR_MODE)
    {
        fputs("\n/* Preprocessed source */\n", destination_file);
        output_tokens(global_token, destination_file);
        goto exit_success;
    }

    /* the main parser doesn't know how to handle newline tokens */
    eat_newline_tokens();

    initialize_types();
    reset_hold_string();
    output_list = NULL;
    program();

    /* Output the program we have compiled */
    fputs("\n# Core program\n", destination_file);
    recursive_output(output_list, destination_file);
    if(KNIGHT_NATIVE == Architecture) fputs("\n", destination_file);
    else if(DEBUG) fputs("\n:ELF_data\n", destination_file);
    fputs("\n# Program global variables\n", destination_file);
    recursive_output(globals_list, destination_file);
    fputs("\n# Program strings\n", destination_file);
    recursive_output(strings_list, destination_file);
    if(KNIGHT_NATIVE == Architecture) fputs("\n:STACK\n", destination_file);
    else if(!DEBUG) fputs("\n:ELF_end\n", destination_file);

exit_success:
    if (destination_file != stdout)
    {
        fclose(destination_file);
    }
    return EXIT_SUCCESS;
}

https://github.com/oriansj/stage0-posix-x86/blob/main/x86_defs.M1

File: ../git/live-bootstrap/sysa/stage0-posix/src/x86/x86_defs.M1 used in: Step 15
## Copyright (C) 2017 Jeremiah Orians
## This file is part of M2-Planet.
##
## M2-Planet is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## M2-Planet is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.


DEFINE add_eax, 81C0
DEFINE add_ebp, 81C5
DEFINE add_ebx,eax 01C3
DEFINE add_eax,ebp 01E8
DEFINE add_eax,ebx 01D8
DEFINE and_eax,ebx 21D8
DEFINE call E8
DEFINE call_eax FFD0
DEFINE cmp 39C3
DEFINE cdq 99
DEFINE div_ebx F7F3
DEFINE idiv_ebx F7FB
DEFINE int CD
DEFINE je 0F84
DEFINE jne 0F85
DEFINE jmp E9
DEFINE lea_eax,[ebp+DWORD] 8D85
DEFINE lea_eax,[esp+DWORD] 8D8424
DEFINE lea_ebx,[esp+DWORD] 8D9C24
DEFINE lea_ecx,[esp+DWORD] 8D8C24
DEFINE lea_edx,[esp+DWORD] 8D9424
DEFINE mov_eax,[esp+DWORD] 8B8424
DEFINE mov_eax,ebp 89E8
DEFINE mov_eax,ebx 89D8
DEFINE mov_eax,ebx 89D8
DEFINE mov_eax,edx 89D0
DEFINE mov_ebx,eax 89C3
DEFINE mov_ecx,eax 89C1
DEFINE mov_ecx,esp 89E1
DEFINE mov_edi,esp 89E7
DEFINE mov_ebp,edi 89fd
DEFINE mov_ebp,esp 89E5
DEFINE mov_eax, B8
DEFINE mov_ebx, BB
DEFINE mov_edx, BA
DEFINE mov_eax,[eax] 8B00
DEFINE mov_ebx,[ebx] 8B1B
DEFINE mov_ecx,[ecx] 8B09
DEFINE mov_edx,[edx] 8B12
DEFINE mov_[ebx],al 8803
DEFINE mov_[ebx],eax 8903
DEFINE movsx_eax,BYTE_PTR_[eax] 0FBE00
DEFINE movsx_ebx,BYTE_PTR_[ebx] 0FBE1B
DEFINE movzx_eax,al 0FB6C0
DEFINE mul_ebx F7E3
DEFINE imul_ebx F7EB
DEFINE NULL 00000000
DEFINE not_eax F7D0
DEFINE or_eax,ebx 09D8
DEFINE pop_eax 58
DEFINE pop_ebx 5B
DEFINE pop_ebp 5D
DEFINE pop_edi 5F
DEFINE push_eax 50
DEFINE push_ebx 53
DEFINE push_ebp 55
DEFINE push_edi 57
DEFINE ret C3
DEFINE sal_eax, C1E0
DEFINE sal_eax,cl D3F0
DEFINE shl_eax,cl D3E0
DEFINE sar_eax,cl D3F8
DEFINE shr_eax,cl D3E8
DEFINE seta_al 0F97C0
DEFINE setae_al 0F93C0
DEFINE setb_al 0F92C0
DEFINE setbe_al 0F96C0
DEFINE sete_al 0F94C0
DEFINE setle_al 0F9EC0
DEFINE setl_al 0F9CC0
DEFINE setge_al 0F9DC0
DEFINE setg_al 0F9FC0
DEFINE setne_al 0F95C0
DEFINE sub_ebx,eax 29C3
DEFINE test_eax,eax 85C0
DEFINE xchg_ebx,eax 93
DEFINE xor_eax,ebx 31D8

https://github.com/oriansj/stage0-posix-x86/blob/main/libc-core.M1

File: ../git/live-bootstrap/sysa/stage0-posix/src/x86/libc-core.M1 used in: Step 15
## Copyright (C) 2016 Jeremiah Orians
## This file is part of stage0.
##
## stage0 is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## stage0 is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with stage0.  If not, see <http://www.gnu.org/licenses/>.

:_start

    mov_ebp,esp                 ; Protect esp

    ;; Prepare argv
    lea_eax,[ebp+DWORD] %4      ; ARGV_address = EBP + 4
    push_eax                    ; Put argv on the stack

    ;; Prepare envp
    mov_eax,ebp                 ; Address we need to load from
    mov_eax,[eax]               ; Get ARGC
    add_eax, %2                 ; OFFSET = ARGC + 2
    sal_eax, !2                 ; OFFSET = OFFSET * WORDSIZE
    add_eax,ebp                 ; ENVP_address = ESP + OFFSET
    push_eax                    ; Put envp on the stack

    ;; Stack offset
    add_ebp, %4                 ; Fix ebp

    ;; Perform the main loop
    call %FUNCTION_main

    ;; Exit to kernel
    mov_ebx,eax                 ; Using the return code given by main
    mov_eax, %1                 ; Syscall exit
    int !0x80                   ; Exit with that code

https://git.savannah.nongnu.org/gitweb/?p=mescc-tools.git;a=blob;f=stringify.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools/stringify.c used in: Step 19, Step 24, Step 35, Step 53
/* -*- c-file-style: "linux";indent-tabs-mode:t -*- */
/* Copyright (C) 2016 Jeremiah Orians
 * Copyright (C) 2017 Jan Nieuwenhuizen <janneke@gnu.org>
 * This file is part of mescc-tools.
 *
 * mescc-tools is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * mescc-tools is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with mescc-tools.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>

// CONSTANT HEX 16
#define HEX 16
// CONSTANT OCTAL 8
#define OCTAL 8
// CONSTANT BINARY 2
#define BINARY 2

/***********************************************************
 * Needed for current implementation of little endian      *
 * Can be used to support little bit endian instruction    *
 * sets if we ever find one that might be useful           *
 * But I seriously doubt it                                *
 ***********************************************************/
void reverseBitOrder(char* c, int ByteMode)
{
    if(NULL == c) return;
    if(0 == c[1]) return;
    int hold = c[0];

    if(HEX == ByteMode)
    {
        c[0] = c[1];
        c[1] = hold;
        reverseBitOrder(c+2, ByteMode);
    }
    else if(OCTAL == ByteMode)
    {
        c[0] = c[2];
        c[2] = hold;
        reverseBitOrder(c+3, ByteMode);
    }
    else if(BINARY == ByteMode)
    {
        c[0] = c[7];
        c[7] = hold;
        hold = c[1];
        c[1] = c[6];
        c[6] = hold;
        hold = c[2];
        c[2] = c[5];
        c[5] = hold;
        hold = c[3];
        c[3] = c[4];
        c[4] = hold;
        reverseBitOrder(c+8, ByteMode);
    }
}

void LittleEndian(char* start, int ByteMode)
{
    char* end = start;
    char* c = start;
    while(0 != end[0]) end = end + 1;
    int hold;
    for(end = end - 1; start < end; start = start + 1)
    {
        hold = start[0];
        start[0] = end[0];
        end[0] = hold;
        end = end - 1;
    }

    /* The above makes a reversed bit order */
    reverseBitOrder(c, ByteMode);
}

int hex2char(int c)
{
    if((c >= 0) && (c <= 9)) return (c + 48);
    else if((c >= 10) && (c <= 15)) return (c + 55);
    else return -1;
}

int stringify(char* s, int digits, int divisor, int value, int shift)
{
    int i = value;
    if(digits > 1)
    {
        i = stringify(s+1, (digits - 1), divisor, value, shift);
    }
    s[0] = hex2char(i & (divisor - 1));
    return (i >> shift);
}

https://git.savannah.nongnu.org/gitweb/?p=mescc-tools.git;a=blob;f=blood-elf.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools/blood-elf.c used in: Step 19, Step 53
/* -*- c-file-style: "linux";indent-tabs-mode:t -*- */
/* Copyright (C) 2017 Jeremiah Orians
 * Copyright (C) 2017 Jan Nieuwenhuizen <janneke@gnu.org>
 * This file is part of mescc-tools
 *
 * mescc-tools is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * mescc-tools is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with mescc-tools.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include "M2libc/bootstrappable.h"

// CONSTANT max_string 4096
#define max_string 4096
int BITSIZE;
int BigEndian;
// CONSTANT HEX 16
#define HEX 16
// CONSTANT OCTAL 8
#define OCTAL 8
// CONSTANT BINARY 2
#define BINARY 2


/* Strings needed for constants */
char* zero_8;
char* zero_16;
char* zero_32;
char* one_16;
char* one_32;
char* two_8;
char* two_32;
char* three_32;
char* six_32;
char* sixteen_32;
char* twentyfour_32;

/* Imported from stringify.c */
int stringify(char* s, int digits, int divisor, int value, int shift);
void LittleEndian(char* start, int ByteMode);

struct entry
{
    struct entry* next;
    char* name;
};

FILE* output;
struct entry* jump_table;
int count;
char* entry;

void consume_token(FILE* source_file, char* s)
{
    int i = 0;
    int c = fgetc(source_file);
    require(EOF != c, "Can not have an EOF token\n");
    do
    {
        s[i] = c;
        i = i + 1;
        require(max_string > i, "Token exceeds token length restriction\n");
        c = fgetc(source_file);
        if(EOF == c) break;
    } while(!in_set(c, " \t\n>"));
}

void storeLabel(FILE* source_file)
{
    struct entry* entry = calloc(1, sizeof(struct entry));

    /* Prepend to list */
    entry->next = jump_table;
    jump_table = entry;

    /* Store string */
    entry->name = calloc((max_string + 1), sizeof(char));
    consume_token(source_file, entry->name);

    count = count + 1;
}

void line_Comment(FILE* source_file)
{
    int c = fgetc(source_file);
    while(!in_set(c, "\n\r"))
    {
        if(EOF == c) break;
        c = fgetc(source_file);
    }
}

void purge_string(FILE* source_file)
{
    int c = fgetc(source_file);
    while((EOF != c) && ('"' != c))
    {
        c = fgetc(source_file);
    }
}

void first_pass(struct entry* input)
{
    if(NULL == input) return;
    first_pass(input->next);

    FILE* source_file = fopen(input->name, "r");

    if(NULL == source_file)
    {
        fputs("The file: ", stderr);
        fputs(input->name, stderr);
        fputs(" can not be opened!\n", stderr);
        exit(EXIT_FAILURE);
    }

    int c;
    for(c = fgetc(source_file); EOF != c; c = fgetc(source_file))
    {
        /* Check for and deal with label */
        if(58 == c)
        {
            storeLabel(source_file);
        }
        /* Check for and deal with line comments */
        else if (c == '#' || c == ';')
        {
            line_Comment(source_file);
        }
        else if ('"' == c)
        {
            purge_string(source_file);
        }
    }
    fclose(source_file);
}

void output_string_table(struct entry* node)
{
    fputs("\n# Generated string table\n:ELF_str\n", output);
    fputs(zero_8, output);
    fputs("\t# NULL string\n", output);
    struct entry* i;
    for(i = node; NULL != i; i = i->next)
    {
        fputs(":ELF_str_", output);
        fputs(i->name, output);
        fputs("\t\"", output);
        fputs(i->name, output);
        fputs("\"\n", output);
    }
    fputs("# END Generated string table\n\n", output);
}

void output_symbol_table(struct entry* node)
{
    fputs("\n# Generated symbol table\n:ELF_sym\n# Required NULL symbol entry\n", output);
    if(64 == BITSIZE)
    {
        fputs(zero_32, output);
        fputs("\t# st_name\n", output);

        fputs(zero_8, output);
        fputs("\t# st_info\n", output);

        fputs(zero_8, output);
        fputs("\t# st_other\n", output);

        fputs(one_16, output);
        fputs("\t# st_shndx\n", output);

        fputs(zero_32, output);
        fputc(' ', output);
        fputs(zero_32, output);
        fputs("\t# st_value\n", output);

        fputs(zero_32, output);
        fputc(' ', output);
        fputs(zero_32, output);
        fputs("\t# st_size\n\n", output);
    }
    else
    {
        fputs(zero_32, output);
        fputs("\t# st_name\n", output);

        fputs(zero_32, output);
        fputs("\t# st_value\n", output);

        fputs(zero_32, output);
        fputs("\t# st_size\n", output);

        fputs(zero_8, output);
        fputs("\t# st_info\n", output);

        fputs(zero_8, output);
        fputs("\t# st_other\n", output);

        fputs(one_16, output);
        fputs("\t# st_shndx\n\n", output);
    }

    struct entry* i;
    for(i = node; NULL != i; i = i->next)
    {
        fputs("%ELF_str_", output);
        fputs(i->name, output);
        fputs(">ELF_str\t# st_name\n", output);

        if(64 == BITSIZE)
        {
            fputs(two_8, output);
            fputs("\t# st_info (FUNC)\n", output);

            if(('_' == i->name[0]) && !match(entry, i->name))
            {
                fputs(two_8, output);
                fputs("\t# st_other (hidden)\n", output);
            }
            else
            {
                fputs(zero_8, output);
                fputs("\t# st_other (other)\n", output);
            }

            fputs(one_16, output);
            fputs("\t# st_shndx\n", output);

            fputs("&", output);
            fputs(i->name, output);
            fputc(' ', output);
            fputs(zero_32, output);
            fputs("\t# st_value\n", output);

            fputs(zero_32, output);
            fputc(' ', output);
            fputs(zero_32, output);
            fputs("\t# st_size (unknown size)\n\n", output);
        }
        else
        {
            fputs("&", output);
            fputs(i->name, output);
            fputs("\t#st_value\n", output);

            fputs(zero_32, output);
            fputs("\t# st_size (unknown size)\n", output);

            fputs(two_8, output);
            fputs("\t# st_info (FUNC)\n", output);

            if(('_' == i->name[0]) && !match(entry, i->name))
            {
                fputs(two_8, output);
                fputs("\t# st_other (hidden)\n", output);
            }
            else
            {
                fputs(zero_8, output);
                fputs("\t# st_other (default)\n", output);
            }

            fputs(one_16, output);
            fputs("\t# st_shndx\n\n", output);
        }
    }

    fputs("# END Generated symbol table\n", output);
}

struct entry* reverse_list(struct entry* head)
{
    struct entry* root = NULL;
    struct entry* next;
    while(NULL != head)
    {
        next = head->next;
        head->next = root;
        root = head;
        head = next;
    }
    return root;
}

void write_int(char* field, char* label)
{
    fputs(field, output);
    fputs("\t#", output);
    fputs(label, output);
    fputc('\n', output);
}

void write_register(char* field, char* label)
{
    /* $field section in the section headers are different size for 32 and 64bits */
    /* The below is broken for BigEndian */
    fputs(field, output);
    if(64 == BITSIZE)
    {
        fputc(' ', output);
        fputs(zero_32, output);
    }

    fputs("\t#", output);
    fputs(label, output);
    fputc('\n', output);
}

void write_section(char* label, char* name, char* type, char* flags, char* address, char* offset, char* size, char* link, char* info, char* entry)
{
    /* Write label */
    fputc('\n', output);
    fputs(label, output);
    fputc('\n', output);

    write_int(name, "sh_name");
    write_int(type, "sh_type");
    write_register(flags, "sh_flags");
    write_register(address, "sh_addr");
    write_register(offset, "sh_offset");
    write_register(size, "sh_size");
    write_int(link, "sh_link");

    /* Deal with the ugly case of stubs */
    fputs(info, output);
    fputs("\t#sh_info\n", output);

    /* Alignment section in the section headers are different size for 32 and 64bits */
    /* The below is broken for BigEndian */
    if(64 == BITSIZE)
    {
        fputs(one_32, output);
        fputc(' ', output);
        fputs(zero_32, output);
        fputs("\t#sh_addralign\n", output);
    }
    else
    {
        fputs(one_32, output);
        fputs("\t#sh_addralign\n", output);
    }

    write_register(entry, "sh_entsize");
}

char* get_string(int value, int size, int ByteMode, int shift)
{
    char* ch = calloc(42, sizeof(char));
    require(NULL != ch, "Exhausted available memory\n");
    ch[0] = '\'';
    stringify(ch+1, size, ByteMode, value, shift);
    if(!BigEndian) LittleEndian(ch+1, ByteMode);
    int i = 0;
    while(0 != ch[i])
    {
        i = i + 1;
    }
    ch[i] = '\'';
    return ch;
}

char* setup_string(int value, int number_of_bytes, int ByteMode)
{
    int shift;
    int size;
    if(HEX == ByteMode)
    {
        size = 2;
        shift = 4;
    }
    else if(OCTAL == ByteMode)
    {
        size = 3;
        shift = 3;
    }
    else if(BINARY == ByteMode)
    {
        size = 8;
        shift = 1;
    }
    else
    {
        fputs("reached impossible mode\n", stderr);
        exit(EXIT_FAILURE);
    }

    return get_string(value, number_of_bytes *size, ByteMode, shift);
}

void setup_strings(int ByteMode)
{
    zero_8 = setup_string(0, 1, ByteMode);
    zero_16 = setup_string(0, 2, ByteMode);
    zero_32 = setup_string(0, 4, ByteMode);
    one_16 = setup_string(1, 2, ByteMode);
    one_32 = setup_string(1, 4, ByteMode);
    two_8 = setup_string(2, 1, ByteMode);
    two_32 = setup_string(2, 4, ByteMode);
    three_32 = setup_string(3, 4, ByteMode);
    six_32 = setup_string(6, 4, ByteMode);
    sixteen_32 = setup_string(16, 4, ByteMode);
    twentyfour_32 = setup_string(24, 4, ByteMode);
}

/* Standard C main program */
int main(int argc, char **argv)
{
    jump_table = NULL;
    struct entry* input = NULL;
    output = stdout;
    char* output_file = "";
    entry = "";
    BITSIZE = 32;
    count = 1;
    BigEndian = TRUE;
    int ByteMode = HEX;
    int set = FALSE;
    struct entry* temp;
    struct entry* head;

    int option_index = 1;
    while(option_index <= argc)
    {
        if(NULL == argv[option_index])
        {
            option_index = option_index + 1;
        }
        else if(match(argv[option_index], "-h") || match(argv[option_index], "--help"))
        {
            fputs("Usage: ", stderr);
            fputs(argv[0], stderr);
            fputs(" --file FILENAME1 {--file FILENAME2} --output FILENAME\n", stderr);
            exit(EXIT_SUCCESS);
        }
        else if(match(argv[option_index], "--64"))
        {
            BITSIZE = 64;
            option_index = option_index + 1;
        }
        else if(match(argv[option_index], "-f") || match(argv[option_index], "--file"))
        {
            temp = calloc(1, sizeof(struct entry));
            temp->name = argv[option_index + 1];
            temp->next = input;
            input = temp;
            option_index = option_index + 2;
        }
        else if(match(argv[option_index], "-o") || match(argv[option_index], "--output"))
        {
            output_file = argv[option_index + 1];
            output = fopen(output_file, "w");

            if(NULL == output)
            {
                fputs("The file: ", stderr);
                fputs(input->name, stderr);
                fputs(" can not be opened!\n", stderr);
                exit(EXIT_FAILURE);
            }
            option_index = option_index + 2;
        }
        else if(match(argv[option_index], "-b") || match(argv[option_index], "--binary"))
        {
            ByteMode = BINARY;
            option_index = option_index + 1;
        }
        else if(match(argv[option_index], "-O") || match(argv[option_index], "--octal"))
        {
            ByteMode = OCTAL;
            option_index = option_index + 1;
        }
        else if(match(argv[option_index], "-X") || match(argv[option_index], "--hex"))
        {
            ByteMode = HEX;
            option_index = option_index + 1;
        }
        else if(match(argv[option_index], "--big-endian"))
        {
            BigEndian = TRUE;
            set = TRUE;
            option_index = option_index + 1;
        }
        else if(match(argv[option_index], "--little-endian"))
        {
            BigEndian = FALSE;
            set = TRUE;
            option_index = option_index + 1;
        }
        else if(match(argv[option_index], "-V") || match(argv[option_index], "--version"))
        {
            fputs("blood-elf 2.0.0\n(Basically Launches Odd Object Dump ExecutabLe Files\n", stdout);
            exit(EXIT_SUCCESS);
        }
        else if(match(argv[option_index], "--entry"))
        {
            head = calloc(1, sizeof(struct entry));
            /* Include _start or any other entry from your .hex2 */
            head->next = jump_table;
            jump_table = head;
            jump_table->name = argv[option_index + 1];
            /* However only the last one will be exempt from the _name hidden rule */
            entry = argv[option_index + 1];
            option_index = option_index + 2;
            count = count + 1;
        }
        else
        {
            fputs("Unknown option\n", stderr);
            exit(EXIT_FAILURE);
        }
    }

    /* Make sure we have a program tape to run */
    if (NULL == input)
    {
        return EXIT_FAILURE;
    }

    /* Force setting of endianness */
    if(!set)
    {
        fputs("either --little-endian or --big-endian MUST be set\n", stderr);
        return EXIT_FAILURE;
    }

    /* Setup the ugly formating because RISC-V sucks */
    setup_strings(ByteMode);

    /* Get all of the labels */
    first_pass(input);

    /* Reverse their order */
    jump_table = reverse_list(jump_table);

    /* Create sections */
    /* Create string names for sections */
    fputs("# Generated sections\n:ELF_shstr\n", output);
    fputs(zero_8, output);
    fputs("\t# NULL\n", output);
    fputs(":ELF_shstr__text\n\".text\"\n", output);
    fputs(":ELF_shstr__shstr\n\".shstrtab\"\n", output);
    fputs(":ELF_shstr__sym\n\".symtab\"\n", output);
    fputs(":ELF_shstr__str\n\".strtab\"\n", output);

    /* Create NULL section header as is required by the Spec. So dumb and waste of bytes*/
    write_section(":ELF_section_headers", zero_32, zero_32, zero_32, zero_32, zero_32, zero_32, zero_32, zero_32, zero_32);
    write_section(":ELF_section_header_text", "%ELF_shstr__text>ELF_shstr", one_32, six_32, "&ELF_text", "%ELF_text>ELF_base", "%ELF_data>ELF_text", zero_32, zero_32, zero_32);
    write_section(":ELF_section_header_shstr", "%ELF_shstr__shstr>ELF_shstr", three_32, zero_32, "&ELF_shstr", "%ELF_shstr>ELF_base", "%ELF_section_headers>ELF_shstr", zero_32, zero_32, zero_32);
    write_section(":ELF_section_header_str", "%ELF_shstr__str>ELF_shstr", three_32, zero_32, "&ELF_str", "%ELF_str>ELF_base", "%ELF_sym>ELF_str", zero_32, zero_32, zero_32);
    if(64 == BITSIZE) write_section(":ELF_section_header_sym", "%ELF_shstr__sym>ELF_shstr", two_32, zero_32, "&ELF_sym", "%ELF_sym>ELF_base", "%ELF_end>ELF_sym", three_32, setup_string(count, 4, ByteMode), twentyfour_32);
    else write_section(":ELF_section_header_sym", "%ELF_shstr__sym>ELF_shstr", two_32, zero_32, "&ELF_sym", "%ELF_sym>ELF_base", "%ELF_end>ELF_sym", three_32, setup_string(count, 4, ByteMode), sixteen_32);

    /* Create dwarf stubs needed for objdump -d to get function names */
    output_string_table(jump_table);
    output_symbol_table(jump_table);
    fputs("\n:ELF_end\n", output);

    /* Close output file */
    fclose(output);

    return EXIT_SUCCESS;
}

https://github.com/oriansj/M2libc/blob/main/x86/x86_defs.M1

File: ../git/live-bootstrap/sysa/stage0-posix/src/M2libc/x86/x86_defs.M1 used in: Step 20, Step 26, Step 32, Step 37, Step 41, Step 45, Step 51, Step 55, Step 59, Step 63, Step 101
## Copyright (C) 2017 Jeremiah Orians
## This file is part of M2-Planet.
##
## M2-Planet is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## M2-Planet is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.


DEFINE add_eax, 81C0
DEFINE add_ebp, 81C5
DEFINE add_ebx,eax 01C3
DEFINE add_eax,ebp 01E8
DEFINE add_eax,ebx 01D8
DEFINE and_eax,ebx 21D8
DEFINE call E8
DEFINE call_eax FFD0
DEFINE cmp 39C3
DEFINE cdq 99
DEFINE div_ebx F7F3
DEFINE idiv_ebx F7FB
DEFINE int CD
DEFINE je 0F84
DEFINE jne 0F85
DEFINE jmp E9
DEFINE lea_eax,[ebp+DWORD] 8D85
DEFINE lea_eax,[esp+DWORD] 8D8424
DEFINE lea_ebx,[esp+DWORD] 8D9C24
DEFINE lea_ecx,[esp+DWORD] 8D8C24
DEFINE lea_edx,[esp+DWORD] 8D9424
DEFINE mov_eax,[esp+DWORD] 8B8424
DEFINE mov_eax,ebp 89E8
DEFINE mov_eax,ebx 89D8
DEFINE mov_eax,ebx 89D8
DEFINE mov_eax,edx 89D0
DEFINE mov_ebx,eax 89C3
DEFINE mov_ecx,eax 89C1
DEFINE mov_ecx,esp 89E1
DEFINE mov_edi,esp 89E7
DEFINE mov_ebp,edi 89fd
DEFINE mov_ebp,esp 89E5
DEFINE mov_eax, B8
DEFINE mov_ebx, BB
DEFINE mov_edx, BA
DEFINE mov_eax,[eax] 8B00
DEFINE mov_ebx,[ebx] 8B1B
DEFINE mov_ecx,[ecx] 8B09
DEFINE mov_edx,[edx] 8B12
DEFINE mov_[ebx],al 8803
DEFINE mov_[ebx],ax 668903
DEFINE mov_[ebx],eax 8903
DEFINE movsx_eax,BYTE_PTR_[eax] 0FBE00
DEFINE movsx_ebx,BYTE_PTR_[ebx] 0FBE1B
DEFINE movsx_eax,WORD_PTR_[eax] 0FBF00
DEFINE movzx_eax,BYTE_PTR_[eax] 0FB600
DEFINE movzx_eax,WORD_PTR_[eax] 0FB700
DEFINE movzx_eax,al 0FB6C0
DEFINE mul_ebx F7E3
DEFINE imul_ebx F7EB
DEFINE NULL 00000000
DEFINE not_eax F7D0
DEFINE or_eax,ebx 09D8
DEFINE pop_eax 58
DEFINE pop_ebx 5B
DEFINE pop_ebp 5D
DEFINE pop_edi 5F
DEFINE push_eax 50
DEFINE push_ebx 53
DEFINE push_ebp 55
DEFINE push_edi 57
DEFINE ret C3
DEFINE sal_eax, C1E0
DEFINE sal_eax,cl D3F0
DEFINE shl_eax,cl D3E0
DEFINE sar_eax,cl D3F8
DEFINE shr_eax,cl D3E8
DEFINE seta_al 0F97C0
DEFINE setae_al 0F93C0
DEFINE setb_al 0F92C0
DEFINE setbe_al 0F96C0
DEFINE sete_al 0F94C0
DEFINE setle_al 0F9EC0
DEFINE setl_al 0F9CC0
DEFINE setge_al 0F9DC0
DEFINE setg_al 0F9FC0
DEFINE setne_al 0F95C0
DEFINE sub_ebx,eax 29C3
DEFINE test_eax,eax 85C0
DEFINE xchg_ebx,eax 93
DEFINE xor_eax,ebx 31D8

https://github.com/oriansj/M2libc/blob/main/x86/libc-core.M1

File: ../git/live-bootstrap/sysa/stage0-posix/src/M2libc/x86/libc-core.M1 used in: Step 20, Step 26
## Copyright (C) 2016 Jeremiah Orians
## This file is part of M2-Planet.
##
## M2-Planet is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## M2-Planet is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.

:_start

    mov_ebp,esp                 ; Protect esp

    ;; Prepare argv
    lea_eax,[ebp+DWORD] %4      ; ARGV_address = EBP + 4
    push_eax                    ; Put argv on the stack

    ;; Prepare envp
    mov_eax,ebp                 ; Address we need to load from
    mov_eax,[eax]               ; Get ARGC
    add_eax, %2                 ; OFFSET = ARGC + 2
    sal_eax, !2                 ; OFFSET = OFFSET * WORDSIZE
    add_eax,ebp                 ; ENVP_address = ESP + OFFSET
    push_eax                    ; Put envp on the stack

    ;; Stack offset
    add_ebp, %4                 ; Fix ebp

    ;; Perform the main loop
    call %FUNCTION_main
    push_eax                    ; Put return on stack
    push_eax                    ; so that _exit gets the value

    ;; Exit to kernel
:FUNCTION_exit
:FUNCTION__exit
    mov_ebx,eax                 ; Using the return code given by main
    mov_eax, %1                 ; Syscall exit
    int !0x80                   ; Exit with that code

https://github.com/oriansj/M2libc/blob/main/x86/ELF-x86.hex2

File: ../git/live-bootstrap/sysa/stage0-posix/src/M2libc/x86/ELF-x86.hex2 used in: Step 22
### Copyright (C) 2016 Jeremiah Orians
### Copyright (C) 2017 Jan Nieuwenhuizen <janneke@gnu.org>
### This file is part of M2-Planet.
###
### M2-Planet is free software: you can redistribute it and/or modify
### it under the terms of the GNU General Public License as published by
### the Free Software Foundation, either version 3 of the License, or
### (at your option) any later version.
###
### M2-Planet is distributed in the hope that it will be useful,
### but WITHOUT ANY WARRANTY; without even the implied warranty of
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
### GNU General Public License for more details.
###
### You should have received a copy of the GNU General Public License
### along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.

### stage0's hex2 format
###    !<label>          1 byte relative
###    $<label>          2 byte address
###    @<label>          2 byte relative
###    &<label>          4 byte address
###    %<label>          4 byte relative

### if you wish to use this header, you need to add :ELF_end to the end of your
### M1 or hex2 files.

## ELF Header

:ELF_base
7F 45 4C 46                    # e_ident[EI_MAG0-3] ELF's magic number

01                             # e_ident[EI_CLASS] Indicating 32 bit
01                             # e_ident[EI_DATA] Indicating little endianness
01                             # e_ident[EI_VERSION] Indicating original elf

03                             # e_ident[EI_OSABI] Set at 3 because FreeBSD is strict
00                             # e_ident[EI_ABIVERSION] See above

00 00 00 00 00 00 00           # e_ident[EI_PAD]

02 00                          # e_type Indicating Executable
03 00                          # e_machine Indicating 386
01 00 00 00                    # e_version Indicating original elf

&_start                        # e_entry Address of the entry point
%ELF_program_headers>ELF_base  # e_phoff Address of program header table
00 00 00 00                    # e_shoff Address of section header table

00 00 00 00                    # e_flags

34 00                          # e_ehsize Indicating our 52 Byte header

20 00                          # e_phentsize size of a program header table
01 00                          # e_phnum number of entries in program table

00 00                          # e_shentsize size of a section header table
00 00                          # e_shnum number of entries in section table

00 00                          # e_shstrndx index of the section names


:ELF_program_headers
:ELF_program_header__text
01 00 00 00                    # ph_type: PT-LOAD = 1
00 00 00 00                    # ph_offset
&ELF_base                      # ph_vaddr
&ELF_base                      # ph_physaddr
%ELF_end>ELF_base              # ph_filesz
%ELF_end>ELF_base              # ph_memsz
07 00 00 00                    # ph_flags: PF-X|PF-W|PF-R = 7
01 00 00 00                    # ph_alignment

:ELF_text

https://git.savannah.nongnu.org/gitweb/?p=mescc-tools.git;a=blob;f=M1-macro.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools/M1-macro.c used in: Step 24, Step 35
/* -*- c-file-style: "linux";indent-tabs-mode:t -*- */
/* Copyright (C) 2016 Jeremiah Orians
 * Copyright (C) 2017 Jan Nieuwenhuizen <janneke@gnu.org>
 * This file is part of mescc-tools.
 *
 * mescc-tools is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * mescc-tools is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with mescc-tools.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "M2libc/bootstrappable.h"

/* Internal processing Constants */
// CONSTANT max_string 4096
#define max_string 4096
// CONSTANT PROCESSED 1
#define PROCESSED 1
// CONSTANT STR 2
#define STR 2
// CONSTANT NEWLINE 3
#define NEWLINE 3

/* Unique code for each architecture */
// CONSTANT KNIGHT 0
#define KNIGHT 0
// CONSTANT X86 3
#define X86 0x03
// CONSTANT AMD64 62
#define AMD64 0x3E
// CONSTANT ARMV7L 40
#define ARMV7L 0x28
// CONSTANT AARM64 183
#define AARM64 0xB7
// CONSTANT PPC64LE 21
#define PPC64LE 0x15
// CONSTANT RISCV32 243
#define RISCV32 0xF3
// CONSTANT RISCV64 65779
#define RISCV64 0x100F3 /* Because RISC-V unlike all other architectures does get a seperate e_machine when changing from 32 to 64bit */


/* How do you want that output? */
// CONSTANT HEX 16
#define HEX 16
// CONSTANT OCTAL 8
#define OCTAL 8
// CONSTANT BINARY 2
#define BINARY 2

/* Imported from stringify.c */
int stringify(char* s, int digits, int divisor, int value, int shift);
void LittleEndian(char* start, int ByteMode);

struct blob
{
    struct blob* next;
    int type;
    char* Text;
    char* Expression;
    struct blob* hash_next;
};

struct Token
{
    struct Token* next;
    struct blob* contents;
    char* filename;
    int linenumber;
};

/* Globals */
FILE* source_file;
FILE* destination_file;
int BigEndian;
int ByteMode;
int Architecture;
int linenumber;
struct Token* token_list;
struct blob* blob_list;
struct blob* define_blob;
struct blob* newline_blob;
int blob_count;
char* SCRATCH;
struct blob** hash_table;

void line_error(char* filename, int linenumber)
{
    fputs(filename, stderr);
    fputs(":", stderr);
    fputs(int2str(linenumber,10, FALSE), stderr);
    fputs(" :", stderr);
}

void ClearScratch()
{
    int i = 0;
    int c = SCRATCH[i];
    while(0 != c)
    {
        SCRATCH[i] = 0;
        i = i + 1;
        c = SCRATCH[i];
    }
}

int GetHash(char* s)
{
    int i = 5381;
    while(0 != s[0])
    {
        i = (i << 5) + i + s[0];
        s = s + 1;
    }
    return i & 0xFFFF;
}

struct blob* FindBlob()
{
    int hash = GetHash(SCRATCH);
    struct blob* i = hash_table[hash];
    while(NULL != i)
    {
        if(match(SCRATCH, i->Text)) return i;
        i = i->hash_next;
    }

    return NULL;
}

void AddHash(struct blob* a, char* s)
{
    int i = GetHash(s);
    a->hash_next = hash_table[i];
    hash_table[i] = a;
}

void NewBlob(int size)
{
    blob_count = blob_count + 1;
    struct blob* a = calloc(1, sizeof(struct blob));
    require(NULL != a, "Exhausted available memory\n");
    a->Text = calloc(size + 1, sizeof(char));
    require(NULL != a->Text, "Exhausted available memory\n");

    int i = 0;
    while(i <= size)
    {
        a->Text[i] = SCRATCH[i];
        i = i + 1;
    }
    a->next = blob_list;
    blob_list = a;
    AddHash(a, SCRATCH);
}

struct Token* newToken(char* filename, int linenumber)
{
    struct Token* p;

    p = calloc (1, sizeof (struct Token));
    require(NULL != p, "Exhausted available memory\n");

    p->filename = filename;
    p->linenumber = linenumber;

    return p;
}

struct Token* reverse_list(struct Token* head)
{
    struct Token* root = NULL;
    struct Token* next;
    while(NULL != head)
    {
        next = head->next;
        head->next = root;
        root = head;
        head = next;
    }
    return root;
}

void purge_lineComment()
{
    int c = fgetc(source_file);
    while(!in_set(c, "\n\r"))
    {
        if(EOF == c) break;
        c = fgetc(source_file);
    }
}

struct Token* append_newline(struct Token* head, char* filename)
{
    linenumber = linenumber + 1;
    if(NULL == head) return NULL;
    if(NEWLINE == head->contents->type)
    {/* Don't waste whitespace*/
        return head;
    }

    struct Token* lf = newToken(filename, linenumber);
    lf->contents = newline_blob;
    lf->next = head;
    return lf;
}


struct Token* store_atom(struct Token* head, char c, char* filename)
{
    ClearScratch();
    int ch = c;
    int i = 0;
    do
    {
        SCRATCH[i] = ch;
        ch = fgetc(source_file);
        i = i + 1;
        if(i >= max_string)
        {
            fputs("storing atom of size larger than max_string\n", stderr);
            line_error(filename, linenumber);
            fputc('\n', stderr);
            exit(EXIT_FAILURE);
        }
        if(EOF == ch) break;
    } while (!in_set(ch, "\t\n "));

    head->contents = FindBlob();
    if(NULL == head->contents)
    {
        NewBlob(i);
        head->contents = blob_list;
    }

    if('\n' == ch)
    {
        return append_newline(head, filename);
    }
    return head;
}

struct blob* store_string(char c, char* filename)
{
    ClearScratch();

    int ch = c;
    int i = 0;
    do
    {
        SCRATCH[i] = ch;
        i = i + 1;
        if('\n' == ch) linenumber = linenumber + 1;
        ch = fgetc(source_file);
        require(EOF != ch, "Unmatched \"!\n");

        if(max_string == i)
        {
            line_error(filename, linenumber);
            fputs("String: ", stderr);
            fputs(SCRATCH, stderr);
            fputs(" exceeds max string size\n", stderr);
            exit(EXIT_FAILURE);
        }
    } while(ch != c);

    struct blob* a = FindBlob();
    if(NULL == a)
    {
        NewBlob(i);
        a = blob_list;
        a->type = STR;
    }

    return a;
}

struct Token* Tokenize_Line(struct Token* head, char* filename)
{
    int c;
    struct Token* p;
    linenumber = 1;

    do
    {
restart:
        c = fgetc(source_file);

        if(in_set(c, ";#"))
        {
            purge_lineComment();
            head = append_newline(head, filename);
            goto restart;
        }

        if(in_set(c, "\t "))
        {
            goto restart;
        }

        if('\n' == c)
        {
            head = append_newline(head, filename);
            goto restart;
        }

        if(EOF == c)
        {
            head = append_newline(head, filename);
            goto done;
        }

        p = newToken(filename, linenumber);
        p->next = head;
        if(in_set(c, "'\""))
        {
            p->contents = store_string(c, filename);
        }
        else
        {
            p = store_atom(p, c, filename);
        }

        head = p;
    } while(TRUE);
done:
    return head;
}

void line_macro(struct Token* p)
{
    struct Token* i;
    for(i = p; NULL != i; i = i->next)
    {
        if(define_blob == i->contents)
        {
            require(NULL != i->next, "Macro name must exist\n");
            require(NULL != i->next->next, "Macro value must exist\n");
            if(PROCESSED == i->next->contents->type)
            {
                line_error(i->filename, i->linenumber);
                fputs("Multiple definitions for macro ", stderr);
                fputs(i->next->contents->Text, stderr);
                fputs("\n", stderr);
                exit(EXIT_FAILURE);
            }

            i->contents = newline_blob;

            if (STR == i->next->next->contents->type)
            {
                i->contents->Expression = i->next->next->contents->Text + 1;
            }
            else
            {
                i->next->contents->Expression = i->next->next->contents->Text;
            }
            i->next = i->next->next->next;
        }
    }
}

void hexify_string(struct blob* p)
{
    char* table = "0123456789ABCDEF";
    int i = strlen(p->Text);
    int size;

    if(HEX == ByteMode) size = (((i << 1) + i) + 12);
    else if(OCTAL == ByteMode) size = (i << 2) + 1;
    else if(BINARY == ByteMode) size = (i << 3) + i + 1;
    else size = 1;

    require(1 != size, "hexify_string lacked a valid bytemode\n");
    char* d = calloc(size, sizeof(char));
    require(NULL != d, "Exhausted available memory\n");
    p->Expression = d;
    char* S = p->Text;

    if((KNIGHT == Architecture) && (HEX == ByteMode))
    {
        i = (((((i - 1) >> 2) + 1) << 3) + i);
        while( 0 < i)
        {
            i = i - 1;
            d[i] = '0';
        }
    }

    if(HEX == ByteMode)
    {
        while(0 != S[0])
        {
            S = S + 1;
            d[0] = table[S[0] >> 4];
            d[1] = table[S[0] & 0xF];
            d[2] = ' ';
            d = d + 3;
        }
    }
    else if(OCTAL == ByteMode)
    {
        while(0 != S[0])
        {
            S = S + 1;
            d[0] = table[S[0] >> 6];
            d[1] = table[(S[0] >> 3) & 0x7];
            d[2] = table[S[0] & 0x7];
            d[3] = ' ';
            d = d + 4;
        }
    }
    else if(BINARY == ByteMode)
    {
        while(0 != S[0])
        {
            S = S + 1;
            d[0] = table[S[0] >> 7];
            d[1] = table[(S[0] >> 6) & 0x1];
            d[2] = table[(S[0] >> 5) & 0x1];
            d[3] = table[(S[0] >> 4) & 0x1];
            d[4] = table[(S[0] >> 3) & 0x1];
            d[5] = table[(S[0] >> 2) & 0x1];
            d[6] = table[(S[0] >> 1) & 0x1];
            d[7] = table[S[0] & 0x1];
            d[8] = ' ';
            d = d + 9;
        }
    }
}

void process_string(struct blob* p)
{
    struct blob* i;
    for(i = p; NULL != i; i = i->next)
    {
        if(STR == i->type)
        {
            if('\'' == i->Text[0])
            {
                i->Expression = i->Text + 1;
            }
            else if('"' == i->Text[0])
            {
                hexify_string(i);
            }
        }
    }
}

char* pad_nulls(int size, char* nil)
{
    if(0 == size) return nil;
    require(size > 0, "negative null padding not possible\n");
    if(HEX == ByteMode) size = size * 2;
    else if (OCTAL == ByteMode) size = size * 3;
    else if (BINARY == ByteMode) size = size * 8;

    char* s = calloc(size + 1, sizeof(char));
    require(NULL != s, "Exhausted available memory\n");

    int i = 0;
    while(i < size)
    {
        s[i] = '0';
        i = i + 1;
    }

    return s;
}

void preserve_other(struct blob* p)
{
    struct blob* i;
    char c;
    for(i = p; NULL != i; i = i->next)
    {
        if((NULL == i->Expression) && !(i->type & PROCESSED))
        {
            c = i->Text[0];

            if(in_set(c, "!@$~%&:^"))
            {
                i->Expression = i->Text;
            }
            else if('<' == c)
            {
                i->Expression = pad_nulls(strtoint(i->Text + 1), i->Text);
            }
        }
    }
}

void bound_values(int displacement, int number_of_bytes, int low, int high)
{
    if((high < displacement) || (displacement < low))
    {
        fputs("A displacement of ", stderr);
        fputs(int2str(displacement, 10, TRUE), stderr);
        fputs(" does not fit in ", stderr);
        fputs(int2str(number_of_bytes, 10, TRUE), stderr);
        fputs(" bytes\n", stderr);
        exit(EXIT_FAILURE);
    }
}

void range_check(int displacement, int number_of_bytes)
{
    if(4 == number_of_bytes) return;
    else if(3 == number_of_bytes)
    {
        bound_values(displacement, number_of_bytes, -8388608, 16777216);
        return;
    }
    else if(2 == number_of_bytes)
    {
        bound_values(displacement, number_of_bytes, -32768, 65535);
        return;
    }
    else if(1 == number_of_bytes)
    {
        bound_values(displacement, number_of_bytes, -128, 255);
        return;
    }

    fputs("Received an invalid number of bytes in range_check\n", stderr);
    exit(EXIT_FAILURE);
}

char* express_number(int value, char c)
{
    char* ch = calloc(42, sizeof(char));
    require(NULL != ch, "Exhausted available memory\n");
    int size;
    int number_of_bytes;
    int shift;
    if('!' == c)
    {
        number_of_bytes = 1;
        value = value & 0xFF;
    }
    else if('@' == c)
    {
        number_of_bytes = 2;
        value = value & 0xFFFF;
    }
    else if('~' == c)
    {
        number_of_bytes = 3;
        value = value & 0xFFFFFF;
    }
    else if('%' == c)
    {
        number_of_bytes = 4;
        value = value & 0xFFFFFFFF;
    }
    else
    {
        fputs("Given symbol ", stderr);
        fputc(c, stderr);
        fputs(" to express immediate value ", stderr);
        fputs(int2str(value, 10, TRUE), stderr);
        fputc('\n', stderr);
        exit(EXIT_FAILURE);
    }

    range_check(value, number_of_bytes);

    if(HEX == ByteMode)
    {
        size = number_of_bytes * 2;
        shift = 4;
    }
    else if(OCTAL == ByteMode)
    {
        size = number_of_bytes * 3;
        shift = 3;
    }
    else if(BINARY == ByteMode)
    {
        size = number_of_bytes * 8;
        shift = 1;
    }
    else
    {
        fputs("Got invalid ByteMode in express_number\n", stderr);
        exit(EXIT_FAILURE);
    }

    stringify(ch, size, ByteMode, value, shift);

    if(!BigEndian) LittleEndian(ch, ByteMode);
    return ch;
}

char* express_word(int value, char c)
{
    char* s = calloc(43, sizeof(char));
    s[0] = '.';
    char* ch = s + 1;
    require(NULL != ch, "Exhausted available memory\n");
    int size;
    int shift;
    int immediate;
    if('!' == c)
    {
        /* Corresponds to RISC-V I format */
        immediate = (value & 0xFFF) << 20;
    }
    else if('@' == c)
    {
        /* Corresponds to RISC-V S format */
        immediate = ((value & 0x1F) << 7) | ((value & 0xFE0) << (31 - 11));
    }
    else if('~' == c)
    {
        /* Corresponds with RISC-V U format */
        if ((value & 0xFFF) < 0x800)
        {
            immediate = value & 0xFFFFF000;
        }
        else
        {
            immediate = (value & 0xFFFFF000) + 0x1000;
        }
    }
    else if('%' == c)
    {
        /* provides an option for 32bit immediate constants */
        immediate = value & 0xFFFFFFFF;
        /* Drop the leading . */
        ch = s;
    }
    else
    {
        fputs("Given symbol ", stderr);
        fputc(c, stderr);
        fputs(" to express immediate value ", stderr);
        fputs(int2str(value, 10, TRUE), stderr);
        fputc('\n', stderr);
        exit(EXIT_FAILURE);
    }

    if(HEX == ByteMode)
    {
        size = 4 * 2;
        shift = 4;
    }
    else if(OCTAL == ByteMode)
    {
        size = 4 * 3;
        shift = 3;
    }
    else if(BINARY == ByteMode)
    {
        size = 4 * 8;
        shift = 1;
    }
    else
    {
        fputs("Got invalid ByteMode in express_number\n", stderr);
        exit(EXIT_FAILURE);
    }

    stringify(ch, size, ByteMode, immediate, shift);

    if(!BigEndian) LittleEndian(ch, ByteMode);
    return s;
}

void eval_immediates(struct blob* p)
{
    struct blob* i;
    int value;
    for(i = p; NULL != i; i = i->next)
    {
        if(PROCESSED == i->type) continue;
        else if(NEWLINE == i->type) continue;
        else if('<' == i->Text[0]) continue;
        else if(NULL == i->Expression)
        {
            if((X86 == Architecture) || (AMD64 == Architecture) || (ARMV7L == Architecture) || (AARM64 == Architecture) || (PPC64LE == Architecture))
            {
                if(in_set(i->Text[0], "%~@!"))
                {
                    value = strtoint(i->Text + 1);

                    if(('0' == i->Text[1]) || (0 != value))
                    {
                        i->Expression = express_number(value, i->Text[0]);
                    }
                }
            }
            else if((RISCV32 == Architecture) || (RISCV64 == Architecture))
            {
                if(in_set(i->Text[0], "%~@!"))
                {
                    value = strtoint(i->Text + 1);

                    if(('0' == i->Text[1]) || (0 != value))
                    {
                        i->Expression = express_word(value, i->Text[0]);
                    }
                }
            }
            else if(KNIGHT == Architecture)
            {
                value = strtoint(i->Text);
                if(('0' == i->Text[0]) || (0 != value))
                {
                    i->Expression = express_number(value, '@');
                }
            }
            else
            {
                fputs("Unknown architecture received in eval_immediates\n", stderr);
                exit(EXIT_FAILURE);
            }
        }
    }
}

void print_hex(struct Token* p)
{
    struct Token* i;
    for(i = p; NULL != i; i = i->next)
    {
        if(NEWLINE == i->contents->type)
        {
            if(NULL == i->next) fputc('\n', destination_file);
            else if(NEWLINE != i->next->contents->type) fputc('\n', destination_file);
        }
        else if(NULL != i->contents->Expression)
        {
            fputs(i->contents->Expression, destination_file);
            if(NEWLINE != i->next->contents->type) fputc(' ', destination_file);
        }
        else
        {
            line_error(i->filename, i->linenumber);
            fputs("Received invalid other; ", stderr);
            fputs(i->contents->Text, stderr);
            fputs("\n", stderr);
            exit(EXIT_FAILURE);
        }
    }
}

/* Standard C main program */
int main(int argc, char **argv)
{
    BigEndian = TRUE;
    Architecture = KNIGHT;
    destination_file = stdout;
    ByteMode = HEX;
    char* filename;
    char* arch;
    blob_count = 2;
    hash_table = calloc(65537, sizeof(struct blob*));
    require(NULL != hash_table, "failed to allocate hash_table\n");

    /* Create newline blob */
    newline_blob = calloc(1, sizeof(struct blob));
    require(NULL != newline_blob, "failed to allocate newline_blob\n");
    newline_blob->Text = "\n";
    newline_blob->Expression = "\n";
    newline_blob->type = NEWLINE;
    AddHash(newline_blob, "\n");

    /* Start the blob list with DEFINE and newline */
    blob_list = calloc(1, sizeof(struct blob));
    require(NULL != blob_list, "failed to allocate DEFINE blob\n");
    blob_list->Text = "DEFINE";
    define_blob = blob_list;
    blob_list->next = newline_blob;
    AddHash(define_blob, "DEFINE");

    /* Initialize scratch */
    SCRATCH = calloc(max_string + 1, sizeof(char));
    require(NULL != SCRATCH, "failed to allocate SCRATCH buffer");

    int option_index = 1;
    while(option_index <= argc)
    {
        if(NULL == argv[option_index])
        {
            option_index = option_index + 1;
        }
        else if(match(argv[option_index], "--big-endian"))
        {
            BigEndian = TRUE;
            option_index = option_index + 1;
        }
        else if(match(argv[option_index], "--little-endian"))
        {
            BigEndian = FALSE;
            option_index = option_index + 1;
        }
        else if(match(argv[option_index], "-A") || match(argv[option_index], "--architecture"))
        {
            arch = argv[option_index + 1];
            if(match("knight-native", arch) || match("knight-posix", arch)) Architecture = KNIGHT;
            else if(match("x86", arch)) Architecture = X86;
            else if(match("amd64", arch)) Architecture = AMD64;
            else if(match("armv7l", arch)) Architecture = ARMV7L;
            else if(match("aarch64", arch)) Architecture = AARM64;
            else if(match("ppc64le", arch)) Architecture = PPC64LE;
            else if(match("riscv32", arch)) Architecture = RISCV32;
            else if(match("riscv64", arch)) Architecture = RISCV64;
            else
            {
                fputs("Unknown architecture: ", stderr);
                fputs(arch, stderr);
                fputs(" know values are: knight-native, knight-posix, x86, amd64, armv7l, aarch64, ppc64le, riscv32 and riscv64", stderr);
                exit(EXIT_FAILURE);
            }
            option_index = option_index + 2;
        }
        else if(match(argv[option_index], "-b") || match(argv[option_index], "--binary"))
        {
            ByteMode = BINARY;
            option_index = option_index + 1;
        }
        else if(match(argv[option_index], "-h") || match(argv[option_index], "--help"))
        {
            fputs("Usage: ", stderr);
            fputs(argv[0], stderr);
            fputs(" --file FILENAME1 {-f FILENAME2} (--big-endian|--little-endian) ", stderr);
            fputs("[--architecture name]\nArchitectures: knight-native, knight-posix, x86, amd64, armv7, riscv32 and riscv64\n", stderr);
            fputs("To leverage octal or binary output: --octal, --binary\n", stderr);
            exit(EXIT_SUCCESS);
        }
        else if(match(argv[option_index], "-f") || match(argv[option_index], "--file"))
        {
            filename = argv[option_index + 1];
            source_file = fopen(filename, "r");

            if(NULL == source_file)
            {
                fputs("The file: ", stderr);
                fputs(argv[option_index + 1], stderr);
                fputs(" can not be opened!\n", stderr);
                exit(EXIT_FAILURE);
            }

            token_list = Tokenize_Line(token_list, filename);

            fclose(source_file);

            option_index = option_index + 2;
        }
        else if(match(argv[option_index], "-o") || match(argv[option_index], "--output"))
        {
            destination_file = fopen(argv[option_index + 1], "w");

            if(NULL == destination_file)
            {
                fputs("The file: ", stderr);
                fputs(argv[option_index + 1], stderr);
                fputs(" can not be opened!\n", stderr);
                exit(EXIT_FAILURE);
            }
            option_index = option_index + 2;
        }
        else if(match(argv[option_index], "-O") || match(argv[option_index], "--octal"))
        {
            ByteMode = OCTAL;
            option_index = option_index + 1;
        }
        else if(match(argv[option_index], "-V") || match(argv[option_index], "--version"))
        {
            fputs("M1 1.4.0\n", stdout);
            exit(EXIT_SUCCESS);
        }
        else
        {
            fputs("Unknown option\n", stderr);
            exit(EXIT_FAILURE);
        }
    }

    if(NULL == token_list)
    {
        fputs("Either no input files were given or they were empty\n", stderr);
        exit(EXIT_FAILURE);
    }

    token_list = reverse_list(token_list);
    line_macro(token_list);
    process_string(blob_list);
    eval_immediates(blob_list);
    preserve_other(blob_list);
    print_hex(token_list);

    fclose(destination_file);

    return EXIT_SUCCESS;
}

https://github.com/oriansj/M2libc/blob/main/x86/ELF-x86-debug.hex2

File: ../git/live-bootstrap/sysa/stage0-posix/src/M2libc/x86/ELF-x86-debug.hex2 used in: Step 28, Step 33, Step 38, Step 42, Step 46, Step 52, Step 56, Step 60, Step 64
### Copyright (C) 2016 Jeremiah Orians
### Copyright (C) 2017 Jan Nieuwenhuizen <janneke@gnu.org>
### This file is part of M2-Planet.
###
### M2-Planet is free software: you can redistribute it and/or modify
### it under the terms of the GNU General Public License as published by
### the Free Software Foundation, either version 3 of the License, or
### (at your option) any later version.
###
### M2-Planet is distributed in the hope that it will be useful,
### but WITHOUT ANY WARRANTY; without even the implied warranty of
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
### GNU General Public License for more details.
###
### You should have received a copy of the GNU General Public License
### along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.

### stage0's hex2 format
###    !<label>          1 byte relative
###    $<label>          2 byte address
###    @<label>          2 byte relative
###    &<label>          4 byte address
###    %<label>          4 byte relative

### if you wish to use this header, you need to add :ELF_end to the end of your
### M1 or hex2 files.

## ELF Header

:ELF_base
7F 45 4C 46                    # e_ident[EI_MAG0-3] ELF's magic number

01                             # e_ident[EI_CLASS] Indicating 32 bit
01                             # e_ident[EI_DATA] Indicating little endianness
01                             # e_ident[EI_VERSION] Indicating original elf

03                             # e_ident[EI_OSABI] Set at 3 because FreeBSD is strict
00                             # e_ident[EI_ABIVERSION] See above

00 00 00 00 00 00 00           # e_ident[EI_PAD]

02 00                          # e_type Indicating Executable
03 00                          # e_machine Indicating 386
01 00 00 00                    # e_version Indicating original elf

&_start                        # e_entry Address of the entry point
%ELF_program_headers>ELF_base  # e_phoff Address of program header table
%ELF_section_headers>ELF_base  # e_shoff Address of section header table

00 00 00 00                    # e_flags

34 00                          # e_ehsize Indicating our 52 Byte header

20 00                          # e_phentsize size of a program header table
01 00                          # e_phnum number of entries in program table

28 00                          # e_shentsize size of a section header table
05 00                          # e_shnum number of entries in section table

02 00                          # e_shstrndx index of the section names


:ELF_program_headers
:ELF_program_header__text
01 00 00 00                    # ph_type: PT-LOAD = 1
00 00 00 00                    # ph_offset
&ELF_base                      # ph_vaddr
&ELF_base                      # ph_physaddr
%ELF_end>ELF_base              # ph_filesz
%ELF_end>ELF_base              # ph_memsz
07 00 00 00                    # ph_flags: PF-X|PF-W|PF-R = 7
01 00 00 00                    # ph_alignment

:ELF_text

https://github.com/oriansj/M2libc/blob/main/sys/types.h

File: ../git/live-bootstrap/sysa/stage0-posix/src/M2libc/sys/types.h used in: Step 30, Step 35, Step 39, Step 43, Step 49, Step 53, Step 57, Step 61, Step 66, Step 67, Step 68, Step 69, Step 70, Step 71, Step 72, Step 73, Step 74, Step 75, Step 76, Step 79, Step 81
/* Copyright (C) 2016 Jeremiah Orians
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _SYS_TYPES_H
#define _SYS_TYPES_H

#ifndef __M2__
#include "../gcc_req.h"
#endif

typedef SCM ulong;
typedef long ssize_t;
typedef int pid_t;
typedef long intptr_t;
typedef ulong uintptr_t;
typedef long clock_t;
typedef int mode_t;
typedef long dev_t;
#endif

https://github.com/oriansj/M2libc/blob/main/stddef.h

File: ../git/live-bootstrap/sysa/stage0-posix/src/M2libc/stddef.h used in: Step 30, Step 35, Step 39, Step 43, Step 49, Step 53, Step 57, Step 61, Step 66, Step 67, Step 68, Step 69, Step 70, Step 71, Step 72, Step 73, Step 74, Step 75, Step 76, Step 79, Step 81
/* Copyright (C) 2016 Jeremiah Orians
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _STDDEF_H
#define _STDDEF_H
#include <sys/types.h>

#define NULL 0
typedef long ptrdiff_t;
typedef ulong size_t;

#endif

https://github.com/oriansj/M2libc/blob/main/x86/linux/unistd.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/M2libc/x86/linux/unistd.c used in: Step 30, Step 35, Step 39, Step 43, Step 49, Step 53, Step 57, Step 61
/* Copyright (C) 2020 Jeremiah Orians
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _UNISTD_C
#define _UNISTD_C

#define NULL 0
#define __PATH_MAX 4096

void* malloc(unsigned size);

int access(char* pathname, int mode)
{
    asm("lea_ebx,[esp+DWORD] %8"
        "mov_ebx,[ebx]"
        "lea_ecx,[esp+DWORD] %4"
        "mov_ecx,[ecx]"
        "mov_eax, %33"
        "int !0x80");
}

int chdir(char* path)
{
    asm("lea_ebx,[esp+DWORD] %4"
        "mov_ebx,[ebx]"
        "mov_eax, %12"
        "int !0x80");
}

int fchdir(int fd)
{
    asm("lea_ebx,[esp+DWORD] %4"
        "mov_ebx,[ebx]"
        "mov_eax, %133"
        "int !0x80");
}

/* Defined in the libc */
void _exit(int value);

int fork()
{
    asm("mov_eax, %2"
        "mov_ebx, %0"
        "int !0x80");
}


int waitpid (int pid, int* status_ptr, int options)
{
    asm("lea_ebx,[esp+DWORD] %12"
        "mov_ebx,[ebx]"
        "lea_ecx,[esp+DWORD] %8"
        "mov_ecx,[ecx]"
        "lea_edx,[esp+DWORD] %4"
        "mov_edx,[edx]"
        "mov_eax, %7"
        "int !0x80");
}


int execve(char* file_name, char** argv, char** envp)
{
    asm("lea_ebx,[esp+DWORD] %12"
        "mov_ebx,[ebx]"
        "lea_ecx,[esp+DWORD] %8"
        "mov_ecx,[ecx]"
        "lea_edx,[esp+DWORD] %4"
        "mov_edx,[edx]"
        "mov_eax, %11"
        "int !0x80");
}

int read(int fd, char* buf, unsigned count) {
    asm("lea_ebx,[esp+DWORD] %12"
        "mov_ebx,[ebx]"
        "lea_ecx,[esp+DWORD] %8"
        "mov_ecx,[ecx]"
        "lea_edx,[esp+DWORD] %4"
        "mov_edx,[edx]"
        "mov_eax, %3"
        "int !0x80");
}

int write(int fd, char* buf, unsigned count) {
    asm("lea_ebx,[esp+DWORD] %12"
        "mov_ebx,[ebx]"
        "lea_ecx,[esp+DWORD] %8"
        "mov_ecx,[ecx]"
        "lea_edx,[esp+DWORD] %4"
        "mov_edx,[edx]"
        "mov_eax, %4"
        "int !0x80");
}

int lseek(int fd, int offset, int whence)
{
    asm("lea_ebx,[esp+DWORD] %12"
        "mov_ebx,[ebx]"
        "lea_ecx,[esp+DWORD] %8"
        "mov_ecx,[ecx]"
        "lea_edx,[esp+DWORD] %4"
        "mov_edx,[edx]"
        "mov_eax, %19"
        "int !0x80");
}

int close(int fd)
{
    asm("lea_ebx,[esp+DWORD] %4"
        "mov_ebx,[ebx]"
        "mov_eax, %6"
        "int !0x80");
}


int unlink (char *filename)
{
    asm("lea_ebx,[esp+DWORD] %4"
        "mov_ebx,[ebx]"
        "mov_eax, %10"
        "int !0x80");
}


int _getcwd(char* buf, int size)
{
    asm("lea_ebx,[esp+DWORD] %8"
        "mov_ebx,[ebx]"
        "lea_ecx,[esp+DWORD] %4"
        "mov_ecx,[ecx]"
        "mov_eax, %183"
        "int !0x80");
}


char* getcwd(char* buf, unsigned size)
{
    int c = _getcwd(buf, size);
    if(0 == c) return NULL;
    return buf;
}


char* getwd(char* buf)
{
    return getcwd(buf, __PATH_MAX);
}


char* get_current_dir_name()
{
    return getcwd(malloc(__PATH_MAX), __PATH_MAX);
}


int brk(void *addr)
{
    asm("mov_eax,[esp+DWORD] %4"
        "push_eax"
        "mov_eax, %45"
        "pop_ebx"
        "int !0x80");
}

struct utsname
{
    char sysname[65];    /* Operating system name (e.g., "Linux") */
    char nodename[65];   /* Name within "some implementation-defined network" */
    char release[65];    /* Operating system release (e.g., "2.6.28") */
    char version[65];    /* Operating system version */
    char machine[65];    /* Hardware identifier */
};

int uname(struct utsname* unameData)
{
    asm("lea_ebx,[esp+DWORD] %4"
        "mov_ebx,[ebx]"
        "mov_eax, %109"
        "int !0x80");
}

#endif

https://github.com/oriansj/M2libc/blob/main/x86/linux/fcntl.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/M2libc/x86/linux/fcntl.c used in: Step 30, Step 35, Step 39, Step 43, Step 49, Step 53, Step 57, Step 61
/* Copyright (C) 2016 Jeremiah Orians
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef __FCNTL_C
#define __FCNTL_C

#define O_RDONLY 0
#define O_WRONLY 1
#define O_RDWR 2
#define O_CREAT 00100
#define O_EXCL 00200
#define O_TRUNC 001000
#define O_APPEND 002000

#define S_IXUSR 00100
#define S_IWUSR 00200
#define S_IRUSR 00400
#define S_IRWXU 00700


int _open(char* name, int flag, int mode)
{
    asm("lea_ebx,[esp+DWORD] %12"
        "mov_ebx,[ebx]"
        "lea_ecx,[esp+DWORD] %8"
        "mov_ecx,[ecx]"
        "lea_edx,[esp+DWORD] %4"
        "mov_edx,[edx]"
        "mov_eax, %5"
        "int !0x80");
}

#define STDIN_FILENO  0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#endif

https://github.com/oriansj/M2libc/blob/main/fcntl.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/M2libc/fcntl.c used in: Step 30, Step 35, Step 39, Step 43, Step 49, Step 53, Step 57, Step 61, Step 66, Step 67, Step 68, Step 69, Step 70, Step 71, Step 72, Step 73, Step 74, Step 75, Step 76, Step 79, Step 81
/* Copyright (C) 2016 Jeremiah Orians
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _FCNTL_C
#define _FCNTL_C

#ifdef __M2__
#if __uefi__
#include <uefi/fcntl.c>
#elif __i386__
#include <x86/linux/fcntl.c>
#elif __x86_64__
#include <amd64/linux/fcntl.c>
#elif __arm__
#include <armv7l/linux/fcntl.c>
#elif __aarch64__
#include <aarch64/linux/fcntl.c>
#elif __riscv && __riscv_xlen==32
#include <riscv32/linux/fcntl.c>
#elif __riscv && __riscv_xlen==64
#include <riscv64/linux/fcntl.c>
#elif __knight_posix__
#include <knight/linux/fcntl.c>
#elif __knight__
#include <knight/native/fcntl.c>
#else
#error arch not supported
#endif
#else
extern int _open(char* name, int flag, int mode);
#endif

int errno;

int open(char* name, int flag, int mode)
{
    int fd = _open(name, flag, mode);
    if(0 > fd)
    {
        errno = -fd;
        fd = -1;
    }
    return fd;
}

#endif

https://github.com/oriansj/M2libc/blob/main/x86/linux/sys/stat.c

Files:
/* Copyright (C) 2020 Jeremiah Orians
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _SYS_STAT_C
#define _SYS_STAT_C

#include <sys/types.h>

#define S_IRWXU 00700
#define S_IXUSR 00100
#define S_IWUSR 00200
#define S_IRUSR 00400

#define S_ISUID 04000
#define S_ISGID 02000
#define S_IXGRP 00010
#define S_IXOTH 00001
#define S_IRGRP 00040
#define S_IROTH 00004
#define S_IWGRP 00020
#define S_IWOTH 00002
#define S_IRWXG 00070
#define S_IRWXO 00007


int chmod(char *pathname, int mode)
{
    asm("lea_ebx,[esp+DWORD] %8"
        "mov_ebx,[ebx]"
        "lea_ecx,[esp+DWORD] %4"
        "mov_ecx,[ecx]"
        "mov_eax, %15"
        "int !0x80");
}


int fchmod(int a, mode_t b)
{
    asm("lea_ebx,[esp+DWORD] %8"
        "mov_ebx,[ebx]"
        "lea_ecx,[esp+DWORD] %4"
        "mov_ecx,[ecx]"
        "mov_eax, %94"
        "int !0x80");
}


int mkdir(char const* a, mode_t b)
{
    asm("lea_ebx,[esp+DWORD] %8"
        "mov_ebx,[ebx]"
        "lea_ecx,[esp+DWORD] %4"
        "mov_ecx,[ecx]"
        "mov_eax, %39"
        "int !0x80");
}


int mknod(char const* a, mode_t b, dev_t c)
{
    asm("lea_ebx,[esp+DWORD] %12"
        "mov_ebx,[ebx]"
        "lea_ecx,[esp+DWORD] %8"
        "mov_ecx,[ecx]"
        "lea_edx,[esp+DWORD] %4"
        "mov_edx,[edx]"
        "mov_eax, %14"
        "int !0x80");
}


mode_t umask(mode_t m)
{
    asm("lea_ebx,[esp+DWORD] %4"
        "mov_ebx,[ebx]"
        "mov_eax, %60"
        "int !0x80");
}

#endif

https://github.com/oriansj/M2libc/blob/main/stdlib.c

Files:
/* Copyright (C) 2016 Jeremiah Orians
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>

#define EXIT_FAILURE 1
#define EXIT_SUCCESS 0

#define _IN_USE 1
#define _NOT_IN_USE 0

typedef char wchar_t;

void exit(int value);

struct _malloc_node
{
    struct _malloc_node *next;
    void* block;
    size_t size;
    int used;
};

struct _malloc_node* _allocated_list;
struct _malloc_node* _free_list;

/********************************
 * The core POSIX malloc        *
 ********************************/
long _malloc_ptr;
long _brk_ptr;
void* _malloc_brk(unsigned size)
{
    if(NULL == _brk_ptr)
    {
        _brk_ptr = brk(0);
        _malloc_ptr = _brk_ptr;
    }

    if(_brk_ptr < _malloc_ptr + size)
    {
        _brk_ptr = brk(_malloc_ptr + size);
        if(-1 == _brk_ptr) return 0;
    }

    long old_malloc = _malloc_ptr;
    _malloc_ptr = _malloc_ptr + size;
    return old_malloc;
}

void __init_malloc()
{
    _free_list = NULL;
    _allocated_list = NULL;
    return;
}

/************************************************************************
 * Handle with the tricky insert behaviors for our nodes                *
 * As free lists must be sorted from smallest to biggest to enable      *
 * cheap first fit logic                                                *
 * The free function however is rarely called, so it can kick sand and  *
 * do things the hard way                                               *
 ************************************************************************/
void _malloc_insert_block(struct _malloc_node* n, int used)
{
    /* Allocated block doesn't care about order */
    if(_IN_USE == used)
    {
        /* Literally just be done as fast as possible */
        n->next = _allocated_list;
        _allocated_list = n;
        return;
    }

    /* sanity check garbage */
    if(_NOT_IN_USE != used) exit(EXIT_FAILURE);
    if(_NOT_IN_USE != n->used) exit(EXIT_FAILURE);
    if(NULL != n->next) exit(EXIT_FAILURE);

    /* Free block really does care about order */
    struct _malloc_node* i = _free_list;
    struct _malloc_node* last = NULL;
    while(NULL != i)
    {
        /* sort smallest to largest */
        if(n->size <= i->size)
        {
            /* Connect */
            n->next = i;
            /* If smallest yet */
            if(NULL == last) _free_list = n;
            /* or just another average block */
            else last->next = n;
            return;
        }

        /* iterate */
        last = i;
        i = i->next;
    }

    /* looks like we are the only one */
    if(NULL == last) _free_list = n;
    /* or we are the biggest yet */
    else last->next = n;
}

/************************************************************************
 * We only mark a block as unused, we don't actually deallocate it here *
 * But rather shove it into our _free_list                              *
 ************************************************************************/
void free(void* ptr)
{
/* just in case someone needs to quickly turn it off */
#ifndef _MALLOC_DISABLE_FREE
    struct _malloc_node* i = _allocated_list;
    struct _malloc_node* last = NULL;

    /* walk the whole freaking list if needed to do so */
    while(NULL != i)
    {
        /* did we find it? */
        if(i->block == ptr)
        {
            /* detach the block */
            if(NULL == last) _allocated_list = i->next;
            /* in a way that doesn't break the allocated list */
            else last->next = i->next;

            /* insert into free'd list */
            i->used = _NOT_IN_USE;
            i->next = NULL;
            _malloc_insert_block(i, _NOT_IN_USE);
            return;
        }

        /* iterate */
        last = i;
        i = i->next;
    }

    /* we received a pointer to a block that wasn't allocated */
    /* Bail *HARD* because I don't want to cover this edge case */
    exit(EXIT_FAILURE);
#endif
    /* if free is disabled, there is nothing to do */
    return;
}

/************************************************************************
 * find if there is any "FREED" blocks big enough to sit on our memory  *
 * budget's face and ruin its life. Respectfully of course              *
 ************************************************************************/
void* _malloc_find_free(unsigned size)
{
    struct _malloc_node* i = _free_list;
    struct _malloc_node* last = NULL;
    /* Walk the whole list if need be */
    while(NULL != i)
    {
        /* see if anything in it is equal or bigger than what I need */
        if((_NOT_IN_USE == i->used) && (i->size > size))
        {
            /* disconnect from list ensuring we don't break free doing so */
            if(NULL == last) _free_list = i->next;
            else last->next = i->next;

            /* insert into allocated list */
            i->used = _IN_USE;
            i->next = NULL;
            _malloc_insert_block(i, _IN_USE);
            return i->block;
        }

        /* iterate (will loop forever if you get this wrong) */
        last = i;
        i = i->next;
    }

    /* Couldn't find anything big enough */
    return NULL;
}

/************************************************************************
 * Well we couldn't find any memory good enough to satisfy our needs so *
 * we are going to have to go beg for some memory on the street corner  *
 ************************************************************************/
void* _malloc_add_new(unsigned size)
{
    struct _malloc_node* n;
#ifdef __uefi__
    n = _malloc_uefi(sizeof(struct _malloc_node));
    /* Check if we were beaten */
    if(NULL == n) return NULL;
    n->block = _malloc_uefi(size);
#else
    n = _malloc_brk(sizeof(struct _malloc_node));
    /* Check if we were beaten */
    if(NULL == n) return NULL;
    n->block = _malloc_brk(size);
#endif
    /* check if we were robbed */
    if(NULL == n->block) return NULL;

    /* Looks like we made it home safely */
    n->size = size;
    n->next = NULL;
    n->used = _IN_USE;
    /* lets pop the cork and party */
    _malloc_insert_block(n, _IN_USE);
    return n->block;
}

/************************************************************************
 * Safely iterates over all malloc nodes and frees them                 *
 ************************************************************************/
void __malloc_node_iter(struct _malloc_node* node, FUNCTION _free)
{
    struct _malloc_node* current;
    while(node != NULL)
    {
        current = node;
        node = node->next;
        _free(current->block);
        _free(current);
    }
}

/************************************************************************
 * Runs a callback with all previously allocated nodes.                 *
 * This can be useful if operating system does not do any clean up.     *
 ************************************************************************/
void* _malloc_release_all(FUNCTION _free)
{
    __malloc_node_iter(_allocated_list, _free);
    __malloc_node_iter(_free_list, _free);
}

/************************************************************************
 * Provide a POSIX standardish malloc function to keep things working   *
 ************************************************************************/
void* malloc(unsigned size)
{
    /* skip allocating nothing */
    if(0 == size) return NULL;

    /* use one of the standard block sizes */
    size_t max = 1 << 30;
    size_t used = 256;
    while(used < size)
    {
        used = used << 1;

        /* fail big allocations */
        if(used > max) return NULL;
    }

    /* try the cabinets around the house */
    void* ptr = _malloc_find_free(used);

    /* looks like we need to get some more from the street corner */
    if(NULL == ptr)
    {
        ptr = _malloc_add_new(used);
    }

    /* hopefully you can handle NULL pointers, good luck */
    return ptr;
}

/************************************************************************
 * Provide a POSIX standardish memset function to keep things working   *
 ************************************************************************/
void* memset(void* ptr, int value, int num)
{
    char* s;
    /* basically walk the block 1 byte at a time and set it to any value you want */
    for(s = ptr; 0 < num; num = num - 1)
    {
        s[0] = value;
        s = s + 1;
    }

    return ptr;
}

/************************************************************************
 * Provide a POSIX standardish calloc function to keep things working   *
 ************************************************************************/
void* calloc(int count, int size)
{
    /* if things get allocated, we are good*/
    void* ret = malloc(count * size);
    /* otherwise good luck */
    if(NULL == ret) return NULL;
    memset(ret, 0, (count * size));
    return ret;
}


/* USED EXCLUSIVELY BY MKSTEMP */
void __set_name(char* s, int i)
{
    s[5] = '0' + (i % 10);
    i = i / 10;
    s[4] = '0' + (i % 10);
    i = i / 10;
    s[3] = '0' + (i % 10);
    i = i / 10;
    s[2] = '0' + (i % 10);
    i = i / 10;
    s[1] = '0' + (i % 10);
    i = i / 10;
    s[0] = '0' + i;
}

/************************************************************************
 * Provide a POSIX standardish mkstemp function to keep things working  *
 ************************************************************************/
int mkstemp(char *template)
{
    /* get length of template */
    int i = 0;
    while(0 != template[i]) i = i + 1;
    i = i - 1;

    /* String MUST be more than 6 characters in length */
    if(i < 6) return -1;

    /* Sanity check the string matches the template requirements */
    int count = 6;
    int c;
    while(count > 0)
    {
        c = template[i];
        /* last 6 chars must be X */
        if('X' != c) return -1;
        template[i] = '0';
        i = i - 1;
        count = count - 1;
    }

    int fd = -1;
    count = -1;
    /* open will return -17 or other values */
    while(0 > fd)
    {
        /* Just give up after the planet has blown up */
        if(9000 < count) return -1;

        /* Try up to 9000 unique filenames before stopping */
        count = count + 1;
        __set_name(template+i+1, count);

        /* Pray we can */
        fd = open(template, O_RDWR | O_CREAT | O_EXCL, 00600);
    }

    /* well that only took count many tries */
    return fd;
}

/************************************************************************
 * wcstombs - convert a wide-character string to a multibyte string     *
 * because seriously UEFI??? UTF-16 is a bad design choice but I guess  *
 * they were drinking pretty hard when they designed UEFI; it is DOS    *
 * but somehow they magically found ways of making it worse             *
 ************************************************************************/
size_t wcstombs(char* dest, char* src, size_t n)
{
    int i = 0;

    do
    {
        /* UTF-16 is 2bytes per char and that first byte maps good enough to ASCII */
        dest[i] = src[2 * i];
        if(dest[i] == 0)
        {
            break;
        }
        i = i + 1;
        n = n - 1;
    } while (n != 0);

    return i;
}

/************************************************************************
 * getenv - get an environmental variable                               *
 ************************************************************************/
size_t _strlen(char const* str)
{
    size_t i = 0;
    while(0 != str[i]) i = i + 1;
    return i;
}
int _strncmp(char const* lhs, char const* rhs, size_t count)
{
    size_t i = 0;
    while(count > i)
    {
        if(0 == lhs[i]) break;
        if(lhs[i] != rhs[i]) return lhs[i] - rhs[i];
        i = i + 1;
    }

    return 0;
}
char** _envp;
char* getenv (char const* name)
{
    char** p = _envp;
    char* q;
    int length = _strlen(name);

    while (p[0] != 0)
    {
        if(_strncmp(name, p[0], length) == 0)
        {
            q = p[0] + length;
            if(q[0] == '=')
                return q + 1;
        }
        p += sizeof(char**); /* M2 pointer arithemtic */
    }

    return 0;
}

/************************************************************************
 * setenv - set an environmental variable                               *
 ************************************************************************/
char* _strcpy(char* dest, char const* src)
{
    int i = 0;

    while (0 != src[i])
    {
        dest[i] = src[i];
        i = i + 1;
    }
    dest[i] = 0;

    return dest;
}

int setenv(char const *s, char const *v, int overwrite_p)
{
    char** p = _envp;
    int length = _strlen(s);
    char* q;

    while (p[0] != 0)
    {
        if (_strncmp (s, p[0], length) == 0)
        {
            q = p[0] + length;
            if (q[0] == '=')
                break;
        }
        p += sizeof(char**); /* M2 pointer arithemtic */
    }
    char *entry = malloc (length + _strlen(v) + 2);
    int end_p = p[0] == 0;
    p[0] = entry;
    _strcpy(entry, s);
    _strcpy(entry + length, "=");
    _strcpy(entry + length + 1, v);
    entry[length + _strlen(v) + 2] = 0;
    if (end_p != 0)
        p[1] = 0;

    return 0;
}

https://github.com/oriansj/M2libc/blob/main/stdio.h

Files:
/* Copyright (C) 2016 Jeremiah Orians
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _STDIO_H
#define _STDIO_H

#ifdef __M2__

/* Actual format of FILE */
struct __IO_FILE
{
    int fd;
    int bufmode; /* O_RDONLY = 0, O_WRONLY = 1 */
    int bufpos;
    int file_pos;
    int buflen;
    char* buffer;
    struct __IO_FILE* next;
    struct __IO_FILE* prev;
};

/* Now give us the FILE we all love */
typedef struct __IO_FILE FILE;

#include <stdio.c>
#else

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

/* Required constants */
/* For file I/O*/
#define EOF -1
#define BUFSIZ 4096

/* For lseek */
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2

/* Actual format of FILE */
struct __IO_FILE
{
    int fd;
    int bufmode; /* 0 = no buffer, 1 = read, 2 = write */
    int bufpos;
    int buflen;
    char* buffer;
};

/* Now give us the FILE we all love */
typedef struct __IO_FILE FILE;

/* Required variables */
extern FILE* stdin;
extern FILE* stdout;
extern FILE* stderr;

/* Standard C functions */
/* Getting */
extern int fgetc(FILE* f);
extern int getchar();
extern char* fgets(char* str, int count, FILE* stream);
extern size_t fread( void* buffer, size_t size, size_t count, FILE* stream );

/* Putting */
extern void fputc(char s, FILE* f);
extern void putchar(char s);
extern int fputs(char const* str, FILE* stream);
extern int puts(char const* str);
extern size_t fwrite(void const* buffer, size_t size, size_t count, FILE* stream );

/* File management */
extern FILE* fopen(char const* filename, char const* mode);
extern int fclose(FILE* stream);
extern int fflush(FILE* stream);

/* File Positioning */
extern int ungetc(int ch, FILE* stream);
extern long ftell(FILE* stream);
extern int fseek(FILE* f, long offset, int whence);
extern void rewind(FILE* f);
#endif
#endif

https://github.com/oriansj/M2libc/blob/main/stdio.c

Files:
/* Copyright (C) 2016 Jeremiah Orians
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stddef.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

/* Required constants */
/* For file I/O*/
#define EOF 0xFFFFFFFF
#define BUFSIZ 0x1000

/* For lseek */
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2

/* Required variables */
FILE* stdin;
FILE* stdout;
FILE* stderr;
FILE* __list;

void __init_io()
{
    __list = NULL;
    stdin = calloc(1, sizeof(FILE));
    stdin->fd = STDIN_FILENO;
    stdin->bufmode = O_RDONLY;
    stdin->buflen = 1;
    stdin->buffer = calloc(2, sizeof(char));

    stdout = calloc(1, sizeof(FILE));
    stdout->fd = STDOUT_FILENO;
    stdout->bufmode = O_WRONLY;
    stdout->buflen = 512;
    stdout->buffer = calloc(514, sizeof(char));

    stderr = calloc(1, sizeof(FILE));
    stderr->fd = STDERR_FILENO;
    stderr->bufmode = O_WRONLY;
    stderr->buflen = 512;
    stderr->buffer = calloc(514, sizeof(char));
}


/* Flush all IO on exit */
int fflush(FILE* stream);
void __kill_io()
{
    fflush(stdout);
    fflush(stderr);
    while(NULL != __list)
    {
        fflush(__list);
        __list = __list->next;
    }
}

/* Standard C functions */
/* Getting */
int read(int fd, char* buf, unsigned count);
int fgetc(FILE* f)
{
    /* Only read on read buffers */
    if(O_WRONLY == f->bufmode) return EOF;

    /* Deal with stdin */
    if(STDIN_FILENO == f->fd)
    {
        f->bufpos = 0;
        int r = read(f->fd, f->buffer, 1);

        /* Catch special case of STDIN gets nothing (AN EOF) */
        if(0 == r) return EOF;
    }

    /* Catch EOF */
    if(f->buflen <= f->bufpos) return EOF;

    /* Deal with standard case */
    int ret = f->buffer[f->bufpos];
    f->bufpos = f->bufpos + 1;

    /* Ensure 0xFF doesn't return EOF */
    return (ret & 0xFF);
}

size_t fread( void* buffer, size_t size, size_t count, FILE* stream )
{
    if(0 == size) return 0;
    if(0 == count) return 0;

    long n = size + count - 1;
    char* p = buffer;
    long i;
    unsigned c;
    for(i = 0; i < n; i = i + 1)
    {
        c = fgetc(stream);
        if(EOF == c) return (i/size);
        p[i] = c;
    }

    return (i/size);
}

int getchar()
{
    return fgetc(stdin);
}


char* fgets(char* str, int count, FILE* stream)
{
    int i = 0;
    int ch;
    while(i < count)
    {
        ch = fgetc(stream);
        if(EOF == ch) break;

        str[i] = ch;
        i = i + 1;

        if('\n' == ch) break;
    }

    return str;
}

/* Putting */
void fputc(char s, FILE* f)
{
    /* Only write on write buffers */
    if(O_RDONLY == f->bufmode) return;

    /* Add to buffer */
    f->buffer[f->bufpos] = s;
    f->bufpos = f->bufpos + 1;

    /* Flush if full or '\n' */
    if(f->bufpos == f->buflen) fflush(f);
    else if(('\n' == s) && (2 >= f->fd)) fflush(f);
}

size_t fwrite(void const* buffer, size_t size, size_t count, FILE* stream )
{
    long n = size * count;
    if(0 == n) return 0;

    char* p = buffer;
    int c;
    long i;
    for(i=0; i < n; i = i + 1)
    {
        c = p[i];
        fputc(c, stream);
    }

    return (i/size);
}

void putchar(char s)
{
    fputc(s, stdout);
}


int fputs(char const* str, FILE* stream)
{
    while(0 != str[0])
    {
        fputc(str[0], stream);
        str = str + 1;
    }
    return 0;
}


int puts(char const* str)
{
    fputs(str, stdout);
    fputc('\n', stdout);
    return 0;
}


int lseek(int fd, int offset, int whence);
/* File management */
FILE* fopen(char const* filename, char const* mode)
{
    int f;
    FILE* fi = calloc(1, sizeof(FILE));
    fi->next = __list;
    if(NULL != __list) __list->prev = fi;
    __list = fi;
    int size;

    if('w' == mode[0]) f = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 00600);
    else f = open(filename, 0, 0); /* Everything else is a read */

    /* Negative numbers are error codes */
    if(0 > f)
    {
        return 0;
    }

    if('w' == mode[0])
    {
        /* Buffer as much as possible */
        fi->buffer = malloc(BUFSIZ * sizeof(char));
        fi->buflen = BUFSIZ;
        fi->bufmode = O_WRONLY;
    }
    else
    {
        /* Get enough buffer to read it all */
        size = lseek(f, 0, SEEK_END);
        fi->buffer = malloc((size + 1) * sizeof(char));
        fi->buflen = size;
        fi->bufmode = O_RDONLY;

        /* Now read it all */
        lseek(f, 0, SEEK_SET);
        read(f, fi->buffer, size);
    }

    fi->fd = f;
    return fi;
}

FILE* fdopen(int fd, char* mode)
{
    FILE* fi = calloc(1, sizeof(FILE));
    fi->next = __list;
    if(NULL != __list) __list->prev = fi;
    __list = fi;
    int size;

    if('w' == mode[0])
    {
        /* Buffer as much as possible */
        fi->buffer = malloc(BUFSIZ * sizeof(char));
        fi->buflen = BUFSIZ;
        fi->bufmode = O_WRONLY;
    }
    else
    {
        /* Get enough buffer to read it all */
        size = lseek(fd, 0, SEEK_END);
        fi->buffer = malloc((size + 1) * sizeof(char));
        fi->buflen = size;
        fi->bufmode = O_RDONLY;

        /* Now read it all */
        lseek(fd, 0, SEEK_SET);
        read(fd, fi->buffer, size);
    }

    fi->fd = fd;
    return fi;
}


int write(int fd, char* buf, unsigned count);
int fflush(FILE* stream)
{
    /* We only need to flush on writes */
    if(O_RDONLY == stream->bufmode) return 0;

    /* If nothing to flush */
    if(0 ==stream->bufpos) return 0;

    /* The actual flushing */
    int error = write(stream->fd, stream->buffer, stream->bufpos);

    /* Keep track of position */
    stream->file_pos = stream->file_pos + stream->bufpos;
    stream->bufpos = 0;

    return error;
}


int close(int fd);
int fclose(FILE* stream)
{
    /* Deal with STDIN, STDOUT and STDERR */
    /* No close for you */
    if(2 >= stream->fd) return 0;

    /* We only need to flush on writes */
    if(O_WRONLY == stream->bufmode)
    {
        fflush(stream);
    }

    /* Need to keep the File Descriptor for a moment */
    int fd = stream->fd;

    /* Remove from __list */
    if(NULL != stream->prev) stream->prev->next = stream->next;
    if(NULL != stream->next) stream->next->prev = stream->prev;
    /* Deal with special case of first node in __list */
    if (__list == stream) __list = __list->next;

    /* Free up the buffer and struct used for FILE */
    free(stream->buffer);
    free(stream);

    /* Do the actual closing */
    return close(fd);
}


int unlink(char* filename);
/* File Removal */
int remove(char *pathname)
{
    return unlink(pathname);
}


/* File Positioning */
int ungetc(int ch, FILE* stream)
{
    /* Deal with STDIN, STDOUT and STDERR */
    /* No ungetc for you */
    if(2 >= stream->fd) return EOF;

    /* You can't unget on a write stream! */
    if(O_WRONLY == stream->bufmode) return EOF;

    /* Don't underflow */
    if(0 == stream->bufpos) return EOF;

    /* Don't let crap be shoved into read stream */
    if(stream->buffer[stream->bufpos - 1] != ch) return EOF;

    stream->bufpos = stream->bufpos - 1;

    return ch;
}


long ftell(FILE* stream)
{
    /* Deal with STDIN, STDOUT and STDERR */
    /* No ftell for you */
    if(2 >= stream->fd) return 0;

    /* Deal with buffered output */
    if(O_WRONLY == stream->bufmode) return stream->file_pos + stream->bufpos;

    /* Deal with read */
    return stream->bufpos;
}


int fseek(FILE* f, long offset, int whence)
{
    /* Deal with STDIN, STDOUT and STDERR */
    /* No seek and destroy missions */
    if(2 >= f->fd) return 0;

    /* Deal with ugly case */
    if(O_WRONLY == f->bufmode)
    {
        fflush(f);
        return lseek(f->fd, offset, whence);
    }

    /* Deal with read mode */
    int pos;

    if(SEEK_SET == whence)
    {
        pos = offset;
    }
    else if(SEEK_CUR == whence)
    {
        pos = f->bufpos + offset;
    }
    else if(SEEK_END == whence)
    {
        pos = f->buflen + offset;
    }
    else return -1;

    if(pos < 0) return -1;
    if(pos > f->buflen) return -1;

    f->bufpos = pos;
    return pos;
}


void rewind(FILE* f)
{
    fseek(f, 0, SEEK_SET);
}

https://git.savannah.nongnu.org/gitweb/?p=mescc-tools.git;a=blob;f=hex2.h

File: ../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools/hex2.h used in: Step 30, Step 39
/* -*- c-file-style: "linux";indent-tabs-mode:t -*- */
/* Copyright (C) 2017 Jeremiah Orians
 * Copyright (C) 2017 Jan Nieuwenhuizen <janneke@gnu.org>
 * This file is part of mescc-tools
 *
 * mescc-tools is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * mescc-tools is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with mescc-tools.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include "M2libc/bootstrappable.h"

#define max_string 4096
#define TRUE 1
#define FALSE 0

#define KNIGHT 0
#define X86 0x03
#define AMD64 0x3E
#define ARMV7L 0x28
#define AARM64 0xB7
#define PPC64LE 0x15
#define RISCV32 0xF3
#define RISCV64 0x100F3 /* Because RISC-V unlike all other architectures does get a seperate e_machine when changing from 32 to 64bit */

#define HEX 16
#define OCTAL 8
#define BINARY 2


struct input_files
{
    struct input_files* next;
    char* filename;
};

struct entry
{
    struct entry* next;
    unsigned target;
    char* name;
};

https://git.savannah.nongnu.org/gitweb/?p=mescc-tools.git;a=blob;f=hex2_linker.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools/hex2_linker.c used in: Step 30, Step 39
/* -*- c-file-style: "linux";indent-tabs-mode:t -*- */
/* Copyright (C) 2017 Jeremiah Orians
 * Copyright (C) 2017 Jan Nieuwenhuizen <janneke@gnu.org>
 * This file is part of mescc-tools
 *
 * mescc-tools is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * mescc-tools is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with mescc-tools.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "hex2_globals.h"

/* Globals */
FILE* output;
struct entry** jump_tables;
int BigEndian;
int Base_Address;
int Architecture;
int ByteMode;
int exec_enable;
int ip;
char* scratch;
char* filename;
int linenumber;
int ALIGNED;

/* For processing bytes */
int hold;
int toggle;

void line_error()
{
    fputs(filename, stderr);
    fputs(":", stderr);
    fputs(int2str(linenumber, 10, FALSE), stderr);
    fputs(" :", stderr);
}

int consume_token(FILE* source_file)
{
    int i = 0;
    int c = fgetc(source_file);
    while(!in_set(c, " \t\n>"))
    {
        scratch[i] = c;
        i = i + 1;
        c = fgetc(source_file);
        require(max_string > i, "Consumed token exceeds length restriction\n");
        if(EOF == c) break;
    }

    return c;
}

int Throwaway_token(FILE* source_file)
{
    int c;
    do
    {
        c = fgetc(source_file);
        if(EOF == c) break;
    } while(!in_set(c, " \t\n>"));

    return c;
}

int length(char* s)
{
    int i = 0;
    while(0 != s[i]) i = i + 1;
    return i;
}

void Clear_Scratch(char* s)
{
    do
    {
        s[0] = 0;
        s = s + 1;
    } while(0 != s[0]);
}

void Copy_String(char* a, char* b)
{
    while(0 != a[0])
    {
        b[0] = a[0];
        a = a + 1;
        b = b + 1;
    }
}

int GetHash(char* s)
{
    int i = 5381;
    while(0 != s[0])
    {
        i = i * 31 + s[0];
        s = s + 1;
    }
    return (i & 0xFFFF);
}

unsigned GetTarget(char* c)
{
    struct entry* i;
    for(i = jump_tables[GetHash(c)]; NULL != i; i = i->next)
    {
        if(match(c, i->name))
        {
            return i->target;
        }
    }
    fputs("Target label ", stderr);
    fputs(c, stderr);
    fputs(" is not valid\n", stderr);
    exit(EXIT_FAILURE);
}

int storeLabel(FILE* source_file, int ip)
{
    struct entry* entry = calloc(1, sizeof(struct entry));
    require(NULL != entry, "failed to allocate entry\n");

    /* Ensure we have target address */
    entry->target = ip;

    /* Store string */
    int c = consume_token(source_file);
    entry->name = calloc(length(scratch) + 1, sizeof(char));
    require(NULL != entry->name, "failed to allocate entry->name\n");
    Copy_String(scratch, entry->name);
    Clear_Scratch(scratch);

    /* Prepend to list */
    int h = GetHash(entry->name);
    entry->next = jump_tables[h];
    jump_tables[h] = entry;

    return c;
}

void range_check(int displacement, int number_of_bytes)
{
    if(4 == number_of_bytes) return;
    else if (3 == number_of_bytes)
    {
        if((8388607 < displacement) || (displacement < -8388608))
        {
            fputs("A displacement of ", stderr);
            fputs(int2str(displacement, 10, TRUE), stderr);
            fputs(" does not fit in 3 bytes\n", stderr);
            exit(EXIT_FAILURE);
        }
        return;
    }
    else if (2 == number_of_bytes)
    {
        if((32767 < displacement) || (displacement < -32768))
        {
            fputs("A displacement of ", stderr);
            fputs(int2str(displacement, 10, TRUE), stderr);
            fputs(" does not fit in 2 bytes\n", stderr);
            exit(EXIT_FAILURE);
        }
        return;
    }
    else if (1 == number_of_bytes)
    {
        if((127 < displacement) || (displacement < -128))
        {
            fputs("A displacement of ", stderr);
            fputs(int2str(displacement, 10, TRUE), stderr);
            fputs(" does not fit in 1 byte\n", stderr);
            exit(EXIT_FAILURE);
        }
        return;
    }

    fputs("Invalid number of bytes given\n", stderr);
    exit(EXIT_FAILURE);
}

void outputPointer(int displacement, int number_of_bytes)
{
    unsigned value = displacement;

    /* HALT HARD if we are going to do something BAD*/
    range_check(displacement, number_of_bytes);

    if(BigEndian)
    { /* Deal with BigEndian */
        if(4 == number_of_bytes) fputc((value >> 24), output);
        if(3 <= number_of_bytes) fputc(((value >> 16)%256), output);
        if(2 <= number_of_bytes) fputc(((value >> 8)%256), output);
        if(1 <= number_of_bytes) fputc((value % 256), output);
    }
    else
    { /* Deal with LittleEndian */
        unsigned byte;
        while(number_of_bytes > 0)
        {
            byte = value % 256;
            value = value / 256;
            fputc(byte, output);
            number_of_bytes = number_of_bytes - 1;
        }
    }
}

int Architectural_displacement(int target, int base)
{
    if(KNIGHT == Architecture) return (target - base);
    else if(X86 == Architecture) return (target - base);
    else if(AMD64 == Architecture) return (target - base);
    else if(ALIGNED && (ARMV7L == Architecture))
    {
        ALIGNED = FALSE;
        /* Note: Branch displacements on ARM are in number of instructions to skip, basically. */
        if (target & 3)
        {
            line_error();
            fputs("error: Unaligned branch target: ", stderr);
            fputs(scratch, stderr);
            fputs(", aborting\n", stderr);
            exit(EXIT_FAILURE);
        }
        /*
         * The "fetch" stage already moved forward by 8 from the
         * beginning of the instruction because it is already
         * prefetching the next instruction.
         * Compensate for it by subtracting the space for
         * two instructions (including the branch instruction).
         * and the size of the aligned immediate.
         */
        return (((target - base + (base & 3)) >> 2) - 2);
    }
    else if(ARMV7L == Architecture)
    {
        /*
         * The size of the offset is 8 according to the spec but that value is
         * based on the end of the immediate, which the documentation gets wrong
         * and needs to be adjusted to the size of the immediate.
         * Eg 1byte immediate => -8 + 1 = -7
         */
        return ((target - base) - 8 + (3 & base));
    }
    else if(ALIGNED && (AARM64 == Architecture))
    {
            ALIGNED = FALSE;
            return (target - (~3 & base)) >> 2;
    }
    else if (AARM64 == Architecture)
    {
        return ((target - base) - 8 + (3 & base));
    }
    else if(ALIGNED && (PPC64LE == Architecture))
    {
        ALIGNED = FALSE;
        /* set Link register with branch */
        return (target - (base & 0xFFFFFFFC )) | 1;
    }
    else if(PPC64LE == Architecture)
    {
        /* DO *NOT* set link register with branch */
        return (target - (base & 0xFFFFFFFC));
    }
    else if(RISCV32 == Architecture || RISCV64 == Architecture) return (target - base);

    fputs("Unknown Architecture, aborting before harm is done\n", stderr);
    exit(EXIT_FAILURE);
}

void Update_Pointer(char ch)
{
    /* Calculate pointer size*/
    if(in_set(ch, "%&")) ip = ip + 4; /* Deal with % and & */
    else if(in_set(ch, "@$")) ip = ip + 2; /* Deal with @ and $ */
    else if('~' == ch) ip = ip + 3; /* Deal with ~ */
    else if('!' == ch) ip = ip + 1; /* Deal with ! */
    else
    {
        line_error();
        fputs("storePointer given unknown\n", stderr);
        exit(EXIT_FAILURE);
    }
}

void storePointer(char ch, FILE* source_file)
{
    /* Get string of pointer */
    Clear_Scratch(scratch);
    Update_Pointer(ch);
    int base_sep_p = consume_token(source_file);

    /* Lookup token */
    int target = GetTarget(scratch);
    int displacement;

    int base = ip;

    /* Change relative base address to :<base> */
    if ('>' == base_sep_p)
    {
        Clear_Scratch(scratch);
        consume_token (source_file);
        base = GetTarget (scratch);

        /* Force universality of behavior */
        displacement = (target - base);
    }
    else
    {
        displacement = Architectural_displacement(target, base);
    }

    /* output calculated difference */
    if('!' == ch) outputPointer(displacement, 1); /* Deal with ! */
    else if('$' == ch) outputPointer(target, 2); /* Deal with $ */
    else if('@' == ch) outputPointer(displacement, 2); /* Deal with @ */
    else if('~' == ch) outputPointer(displacement, 3); /* Deal with ~ */
    else if('&' == ch) outputPointer(target, 4); /* Deal with & */
    else if('%' == ch) outputPointer(displacement, 4);  /* Deal with % */
    else
    {
        line_error();
        fputs("error: storePointer reached impossible case: ch=", stderr);
        fputc(ch, stderr);
        fputs("\n", stderr);
        exit(EXIT_FAILURE);
    }
}

void line_Comment(FILE* source_file)
{
    int c = fgetc(source_file);
    while(!in_set(c, "\n\r"))
    {
        if(EOF == c) break;
        c = fgetc(source_file);
    }
    linenumber = linenumber + 1;
}

int hex(int c, FILE* source_file)
{
    if (in_set(c, "0123456789")) return (c - 48);
    else if (in_set(c, "abcdef")) return (c - 87);
    else if (in_set(c, "ABCDEF")) return (c - 55);
    else if (in_set(c, "#;")) line_Comment(source_file);
    else if ('\n' == c) linenumber = linenumber + 1;
    return -1;
}

int octal(int c, FILE* source_file)
{
    if (in_set(c, "01234567")) return (c - 48);
    else if (in_set(c, "#;")) line_Comment(source_file);
    else if ('\n' == c) linenumber = linenumber + 1;
    return -1;
}

int binary(int c, FILE* source_file)
{
    if (in_set(c, "01")) return (c - 48);
    else if (in_set(c, "#;")) line_Comment(source_file);
    else if ('\n' == c) linenumber = linenumber + 1;
    return -1;
}

void process_byte(char c, FILE* source_file, int write)
{
    if(HEX == ByteMode)
    {
        if(0 <= hex(c, source_file))
        {
            if(toggle)
            {
                if(write) fputc(((hold * 16)) + hex(c, source_file), output);
                ip = ip + 1;
                hold = 0;
            }
            else
            {
                hold = hex(c, source_file);
            }
            toggle = !toggle;
        }
    }
    else if(OCTAL ==ByteMode)
    {
        if(0 <= octal(c, source_file))
        {
            if(2 == toggle)
            {
                if(write) fputc(((hold * 8)) + octal(c, source_file), output);
                ip = ip + 1;
                hold = 0;
                toggle = 0;
            }
            else if(1 == toggle)
            {
                hold = ((hold * 8) + octal(c, source_file));
                toggle = 2;
            }
            else
            {
                hold = octal(c, source_file);
                toggle = 1;
            }
        }
    }
    else if(BINARY == ByteMode)
    {
        if(0 <= binary(c, source_file))
        {
            if(7 == toggle)
            {
                if(write) fputc((hold * 2) + binary(c, source_file), output);
                ip = ip + 1;
                hold = 0;
                toggle = 0;
            }
            else
            {
                hold = ((hold * 2) + binary(c, source_file));
                toggle = toggle + 1;
            }
        }
    }
}

void pad_to_align(int write)
{
    if((ARMV7L == Architecture) || (AARM64 == Architecture) || (RISCV32 == Architecture) || (RISCV64 == Architecture))
    {
        if(1 == (ip & 0x1))
        {
            ip = ip + 1;
            if(write) fputc('\0', output);
        }
        if(2 == (ip & 0x2))
        {
            ip = ip + 2;
            if(write)
            {
                fputc('\0', output);
                fputc('\0', output);
            }
        }
    }
}

void first_pass(struct input_files* input)
{
    if(NULL == input) return;
    first_pass(input->next);
    filename = input->filename;
    linenumber = 1;
    FILE* source_file = fopen(filename, "r");

    if(NULL == source_file)
    {
        fputs("The file: ", stderr);
        fputs(input->filename, stderr);
        fputs(" can not be opened!\n", stderr);
        exit(EXIT_FAILURE);
    }

    toggle = FALSE;
    int c;
    for(c = fgetc(source_file); EOF != c; c = fgetc(source_file))
    {
        /* Check for and deal with label */
        if(':' == c)
        {
            c = storeLabel(source_file, ip);
        }

        /* check for and deal with relative/absolute pointers to labels */
        if(in_set(c, "!@$~%&"))
        { /* deal with 1byte pointer !; 2byte pointers (@ and $); 3byte pointers ~; 4byte pointers (% and &) */
            Update_Pointer(c);
            c = Throwaway_token(source_file);
            if ('>' == c)
            { /* deal with label>base */
                c = Throwaway_token(source_file);
            }
        }
        else if('<' == c)
        {
            pad_to_align(FALSE);
        }
        else if('^' == c)
        {
            /* Just ignore */
            continue;
        }
        else process_byte(c, source_file, FALSE);
    }
    fclose(source_file);
}

void second_pass(struct input_files* input)
{
    if(NULL == input) return;
    second_pass(input->next);
    filename = input->filename;
    linenumber = 1;
    FILE* source_file = fopen(filename, "r");

    /* Something that should never happen */
    if(NULL == source_file)
    {
        fputs("The file: ", stderr);
        fputs(input->filename, stderr);
        fputs(" can not be opened!\nWTF-pass2\n", stderr);
        exit(EXIT_FAILURE);
    }

    toggle = FALSE;
    hold = 0;

    int c;
    for(c = fgetc(source_file); EOF != c; c = fgetc(source_file))
    {
        if(':' == c) c = Throwaway_token(source_file); /* Deal with : */
        else if(in_set(c, "!@$~%&")) storePointer(c, source_file);  /* Deal with !, @, $, ~, % and & */
        else if('<' == c) pad_to_align(TRUE);
        else if('^' == c) ALIGNED = TRUE;
        else process_byte(c, source_file, TRUE);
    }

    fclose(source_file);
}

https://git.savannah.nongnu.org/gitweb/?p=mescc-tools.git;a=blob;f=hex2_word.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools/hex2_word.c used in: Step 30, Step 39
/* -*- c-file-style: "linux";indent-tabs-mode:t -*- */
/* Copyright (C) 2017 Jeremiah Orians
 * Copyright (C) 2017 Jan Nieuwenhuizen <janneke@gnu.org>
 * This file is part of mescc-tools
 *
 * mescc-tools is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * mescc-tools is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with mescc-tools.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "hex2_globals.h"

unsigned shiftregister;
unsigned tempword;
int updates;

void outOfRange(char* s, int value)
{
    line_error();
    fputs("error: value ", stderr);
    fputs(int2str(value, 10, TRUE), stderr);
    fputs(" out of range for field type ", stderr);
    fputs(s, stderr);
    fputs("\n", stderr);
    exit(EXIT_FAILURE);
}

void UpdateShiftRegister(char ch, int value)
{
    if ('.' == ch)
    {
        unsigned swap;
        /* Assume the user knows what they are doing */
        if(!BigEndian)
        {
            /* Swap from big-endian to little endian order */
            swap = (((value >> 24) & 0xFF) |
                    ((value << 8) & 0xFF0000) |
                    ((value >> 8) & 0xFF00) |
                    ((value & 0xFF) << 24));
        }
        else
        {
            /* Big endian needs no change */
            swap = value;
        }
        /* we just take the 4 bytes after the . and shove in the shift register */
        swap = swap & ((0xFFFF << 16) | 0xFFFF);
        shiftregister = shiftregister ^ swap;
    }
    else if ('!' == ch)
    {
        /* Corresponds to RISC-V I format */
        /* Will need architecture specific logic if more architectures go this route */
        /* no range check because it needs to work with labels for lui/addi + AUIPC combos */
        /* !label is used in the second instruction of AUIPC combo but we want an offset from */
        /* the first instruction */
        value = value + 4;
        tempword = (value & 0xFFF) << 20;
        /* Update shift register */
        tempword = tempword & ((0xFFFF << 16) | 0xFFFF);
        shiftregister = shiftregister ^ tempword;
    }
    else if ('@' == ch)
    {
        /* Corresponds to RISC-V B format (formerly known as SB) */
        /* Will need architecture specific logic if more architectures go this route */
        if ((value < -0x1000 || value > 0xFFF) || (value & 1)) outOfRange("B", value);

        /* Prepare the immediate's word */
        tempword = ((value & 0x1E) << 7)
            | ((value & 0x7E0) << (31 - 11))
            | ((value & 0x800) >> 4)
            | ((value & 0x1000) << (31 - 12));
        tempword = tempword & ((0xFFFF << 16) | 0xFFFF);
        /* Update shift register */
        shiftregister = shiftregister ^ tempword;
    }
    else if ('$' == ch)
    {
        /* Corresponds with RISC-V J format (formerly known as UJ) */
        /* Will need architecture specific logic if more architectures go this route */
        if ((value < -0x100000 || value > 0xFFFFF) || (value & 1)) outOfRange("J", value);

        tempword = ((value & 0x7FE) << (30 - 10))
            | ((value & 0x800) << (20 - 11))
            | ((value & 0xFF000))
            | ((value & 0x100000) << (31 - 20));
        tempword = tempword & ((0xFFFF << 16) | 0xFFFF);
        shiftregister = shiftregister ^ tempword;
    }
    else if ('~' == ch)
    {
        /* Corresponds with RISC-V U format */
        /* Will need architecture specific logic if more architectures go this route */
        if ((value & 0xFFF) < 0x800) tempword = value & (0xFFFFF << 12);
        else tempword = (value & (0xFFFFF << 12)) + 0x1000;
        tempword = tempword & ((0xFFFF << 16) | 0xFFFF);
        shiftregister = shiftregister ^ tempword;
    }
    else
    {
        line_error();
        fputs("error: UpdateShiftRegister reached impossible case: ch=", stderr);
        fputc(ch, stderr);
        fputs("\n", stderr);
        exit(EXIT_FAILURE);
    }
}

void WordStorePointer(char ch, FILE* source_file)
{
    /* Get string of pointer */
    ip = ip + 4;
    Clear_Scratch(scratch);
    int base_sep_p = consume_token(source_file);

    /* Lookup token */
    int target = GetTarget(scratch);
    int displacement;

    int base = ip;

    /* Change relative base address to :<base> */
    if ('>' == base_sep_p)
    {
        Clear_Scratch(scratch);
        consume_token (source_file);
        base = GetTarget (scratch);

        /* Force universality of behavior */
        displacement = (target - base);
    }
    else
    {
        displacement = Architectural_displacement(target, base);
    }

    /* output calculated difference */
    if('&' == ch) outputPointer(target, 4); /* Deal with & */
    else if('%' == ch) outputPointer(displacement, 4);  /* Deal with % */
    else
    {
        line_error();
        fputs("error: WordStorePointer reached impossible case: ch=", stderr);
        fputc(ch, stderr);
        fputs("\n", stderr);
        exit(EXIT_FAILURE);
    }
}

unsigned sr_nextb()
{
    unsigned rv = shiftregister & 0xff;
    shiftregister = shiftregister >> 8;
    return rv;
}

void DoByte(char c, FILE* source_file, int write, int update)
{
    if(HEX == ByteMode)
    {
        if(0 <= hex(c, source_file))
        {
            if(toggle)
            {
                if(write) fputc(((hold * 16)) + hex(c, source_file) ^ sr_nextb(), output);
                ip = ip + 1;
                if(update)
                {
                    hold = (hold * 16) + hex(c, source_file);
                    tempword = (tempword << 8) ^ hold;
                    updates = updates + 1;
                }
                hold = 0;
            }
            else
            {
                hold = hex(c, source_file);
            }
            toggle = !toggle;
        }
    }
    else if(OCTAL ==ByteMode)
    {
        if(0 <= octal(c, source_file))
        {
            if(2 == toggle)
            {
                if(write) fputc(((hold * 8)) + octal(c, source_file) ^ sr_nextb(), output);
                ip = ip + 1;
                if(update)
                {
                    hold = ((hold * 8) + octal(c, source_file));
                    tempword = (tempword << 8) ^ hold;
                    updates = updates + 1;
                }
                hold = 0;
                toggle = 0;
            }
            else if(1 == toggle)
            {
                hold = ((hold * 8) + octal(c, source_file));
                toggle = 2;
            }
            else
            {
                hold = octal(c, source_file);
                toggle = 1;
            }
        }
    }
    else if(BINARY == ByteMode)
    {
        if(0 <= binary(c, source_file))
        {
            if(7 == toggle)
            {
                if(write) fputc((hold * 2) + binary(c, source_file) ^ sr_nextb(), output);
                ip = ip + 1;
                if(update)
                {
                    hold = ((hold * 2) + binary(c, source_file));
                    tempword = (tempword << 8) ^ hold;
                    updates = updates + 1;
                }
                hold = 0;
                toggle = 0;
            }
            else
            {
                hold = ((hold * 2) + binary(c, source_file));
                toggle = toggle + 1;
            }
        }
    }
}

void WordFirstPass(struct input_files* input)
{
    if(NULL == input) return;
    WordFirstPass(input->next);
    filename = input->filename;
    linenumber = 1;
    FILE* source_file = fopen(filename, "r");

    if(NULL == source_file)
    {
        fputs("The file: ", stderr);
        fputs(input->filename, stderr);
        fputs(" can not be opened!\n", stderr);
        exit(EXIT_FAILURE);
    }

    toggle = FALSE;
    int c;
    for(c = fgetc(source_file); EOF != c; c = fgetc(source_file))
    {
        /* Check for and deal with label */
        if(':' == c)
        {
            c = storeLabel(source_file, ip);
        }

        /* check for and deal with relative/absolute pointers to labels */
        if('.' == c)
        {
            /* Read architecture specific number of bytes for what is defined as a word */
            /* 4bytes in RISC-V's case */
            updates = 0;
            tempword = 0;
            while (updates < 4)
            {
                c = fgetc(source_file);
                DoByte(c, source_file, FALSE, TRUE);
            }
            ip = ip - 4;
        }
        else if(in_set(c, "!@$~"))
        {
            /* Don't update IP */
            c = Throwaway_token(source_file);
        }
        else if(in_set(c, "%&"))
        {
            ip = ip + 4;
            c = Throwaway_token(source_file);
            if ('>' == c)
            { /* deal with label>base */
                c = Throwaway_token(source_file);
            }
        }
        else if('<' == c)
        {
            pad_to_align(FALSE);
        }
        else if('^' == c)
        {
            /* Just ignore */
            continue;
        }
        else DoByte(c, source_file, FALSE, FALSE);
    }
    fclose(source_file);
}

void WordSecondPass(struct input_files* input)
{
    shiftregister = 0;
    tempword = 0;

    if(NULL == input) return;
    WordSecondPass(input->next);
    filename = input->filename;
    linenumber = 1;
    FILE* source_file = fopen(filename, "r");

    /* Something that should never happen */
    if(NULL == source_file)
    {
        fputs("The file: ", stderr);
        fputs(input->filename, stderr);
        fputs(" can not be opened!\nWTF-pass2\n", stderr);
        exit(EXIT_FAILURE);
    }

    toggle = FALSE;
    hold = 0;

    int c;
    for(c = fgetc(source_file); EOF != c; c = fgetc(source_file))
    {
        if(':' == c) c = Throwaway_token(source_file); /* Deal with : */
        else if('.' == c)
        {
            /* Read architecture specific number of bytes for what is defined as a word */
            /* 4bytes in RISC-V's case */
            updates = 0;
            tempword = 0;
            while (updates < 4)
            {
                c = fgetc(source_file);
                DoByte(c, source_file, FALSE, TRUE);
            }
            UpdateShiftRegister('.', tempword);
            ip = ip - 4;
        }
        else if(in_set(c, "%&")) WordStorePointer(c, source_file);  /* Deal with % and & */
        else if(in_set(c, "!@$~"))
        {
            Clear_Scratch(scratch);
            consume_token(source_file);
            UpdateShiftRegister(c, Architectural_displacement(GetTarget(scratch), ip)); /* Play with shift register */
        }
        else if('<' == c) pad_to_align(TRUE);
        else if('^' == c) ALIGNED = TRUE;
        else DoByte(c, source_file, TRUE, FALSE);
    }

    fclose(source_file);
}

https://git.savannah.nongnu.org/gitweb/?p=mescc-tools.git;a=blob;f=hex2.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools/hex2.c used in: Step 30, Step 39
/* -*- c-file-style: "linux";indent-tabs-mode:t -*- */
/* Copyright (C) 2017 Jeremiah Orians
 * Copyright (C) 2017 Jan Nieuwenhuizen <janneke@gnu.org>
 * This file is part of mescc-tools
 *
 * mescc-tools is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * mescc-tools is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with mescc-tools.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "hex2_globals.h"

/* The essential functions */
void first_pass(struct input_files* input);
void second_pass(struct input_files* input);
void WordFirstPass(struct input_files* input);
void WordSecondPass(struct input_files* input);

/* Standard C main program */
int main(int argc, char **argv)
{
    int InsaneArchitecture = FALSE;
    ALIGNED = FALSE;
    BigEndian = TRUE;
    jump_tables = calloc(65537, sizeof(struct entry*));
    require(NULL != jump_tables, "Failed to allocate our jump_tables\n");

    Architecture = KNIGHT;
    Base_Address = 0;
    struct input_files* input = NULL;
    output = stdout;
    char* output_file = "";
    exec_enable = TRUE;
    ByteMode = HEX;
    scratch = calloc(max_string + 1, sizeof(char));
    require(NULL != scratch, "failed to allocate our scratch buffer\n");
    char* arch;
    struct input_files* temp;

    int option_index = 1;
    while(option_index <= argc)
    {
        if(NULL == argv[option_index])
        {
            option_index = option_index + 1;
        }
        else if(match(argv[option_index], "--big-endian"))
        {
            BigEndian = TRUE;
            option_index = option_index + 1;
        }
        else if(match(argv[option_index], "--little-endian"))
        {
            BigEndian = FALSE;
            option_index = option_index + 1;
        }
        else if(match(argv[option_index], "--non-executable"))
        {
            exec_enable = FALSE;
            option_index = option_index + 1;
        }
        else if(match(argv[option_index], "-A") || match(argv[option_index], "--architecture"))
        {
            arch = argv[option_index + 1];
            if(match("knight-native", arch) || match("knight-posix", arch)) Architecture = KNIGHT;
            else if(match("x86", arch)) Architecture = X86;
            else if(match("amd64", arch)) Architecture = AMD64;
            else if(match("armv7l", arch)) Architecture = ARMV7L;
            else if(match("aarch64", arch)) Architecture = AARM64;
            else if(match("ppc64le", arch)) Architecture = PPC64LE;
            else if(match("riscv32", arch)) Architecture = RISCV32;
            else if(match("riscv64", arch)) Architecture = RISCV64;
            else
            {
                fputs("Unknown architecture: ", stderr);
                fputs(arch, stderr);
                fputs(" know values are: knight-native, knight-posix, x86, amd64, armv7l, riscv32 and riscv64", stderr);
            }
            option_index = option_index + 2;
        }
        else if(match(argv[option_index], "-b") || match(argv[option_index], "--binary"))
        {
            ByteMode = BINARY;
            option_index = option_index + 1;
        }
        else if(match(argv[option_index], "-B") || match(argv[option_index], "--base-address"))
        {
            Base_Address = strtoint(argv[option_index + 1]);
            option_index = option_index + 2;
        }
        else if(match(argv[option_index], "-h") || match(argv[option_index], "--help"))
        {
            fputs("Usage: ", stderr);
            fputs(argv[0], stderr);
            fputs(" --file FILENAME1 {-f FILENAME2} (--big-endian|--little-endian)", stderr);
            fputs(" [--base-address 0x12345] [--architecture name]\nArchitecture:", stderr);
            fputs(" knight-native, knight-posix, x86, amd64, armv7l, aarch64, riscv32 and riscv64\n", stderr);
            fputs("To leverage octal or binary input: --octal, --binary\n", stderr);
            exit(EXIT_SUCCESS);
        }
        else if(match(argv[option_index], "-f") || match(argv[option_index], "--file"))
        {
            temp = calloc(1, sizeof(struct input_files));
            require(NULL != temp, "failed to allocate file for processing\n");
            temp->filename = argv[option_index + 1];
            temp->next = input;
            input = temp;
            option_index = option_index + 2;
        }
        else if(match(argv[option_index], "-o") || match(argv[option_index], "--output"))
        {
            output_file = argv[option_index + 1];
            output = fopen(output_file, "w");

            if(NULL == output)
            {
                fputs("The file: ", stderr);
                fputs(argv[option_index + 1], stderr);
                fputs(" can not be opened!\n", stderr);
                exit(EXIT_FAILURE);
            }
            option_index = option_index + 2;
        }
        else if(match(argv[option_index], "-O") || match(argv[option_index], "--octal"))
        {
            ByteMode = OCTAL;
            option_index = option_index + 1;
        }
        else if(match(argv[option_index], "-V") || match(argv[option_index], "--version"))
        {
            fputs("hex2 1.4.0\n", stdout);
            exit(EXIT_SUCCESS);
        }
        else
        {
            fputs("Unknown option\n", stderr);
            exit(EXIT_FAILURE);
        }
    }

    if((Architecture == RISCV32) || (Architecture == RISCV64))
    {
        /* Forcing me to use words instead of just byting into the problem */
        InsaneArchitecture = TRUE;
    }

    /* Catch a common mistake */
    if((KNIGHT != Architecture) && (0 == Base_Address))
    {
        fputs(">> WARNING <<\n>> WARNING <<\n>> WARNING <<\n", stderr);
        fputs("If you are not generating a ROM image this binary will likely not work\n", stderr);
    }

    /* Catch implicitly false assumptions */
    if(BigEndian && ((X86 == Architecture) || ( AMD64 == Architecture) || (ARMV7L == Architecture) || (AARM64 == Architecture) || (RISCV32 == Architecture) || (RISCV64 == Architecture)))
    {
        fputs(">> WARNING <<\n>> WARNING <<\n>> WARNING <<\n", stderr);
        fputs("You have specified big endian output on likely a little endian processor\n", stderr);
        fputs("if this is a mistake please pass --little-endian next time\n", stderr);
    }

    /* Make sure we have a program tape to run */
    if (NULL == input)
    {
        return EXIT_FAILURE;
    }

    /* Get all of the labels */
    ip = Base_Address;
    if(InsaneArchitecture) WordFirstPass(input);
    else first_pass(input);

    /* Fix all the references*/
    ip = Base_Address;
    if(InsaneArchitecture) WordSecondPass(input);
    else second_pass(input);

    /* flush all writes */
    fflush(output);

    /* Set file as executable */
    if(exec_enable && (output != stdout))
    {
        /* Close output file */
        fclose(output);

        if(0 != chmod(output_file, 0750))
        {
            fputs("Unable to change permissions\n", stderr);
            exit(EXIT_FAILURE);
        }
    }

    return EXIT_SUCCESS;
}

https://github.com/oriansj/M2libc/blob/main/x86/libc-full.M1

Files:
## Copyright (C) 2016 Jeremiah Orians
## This file is part of M2-Planet.
##
## M2-Planet is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## M2-Planet is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.

:_start

    mov_ebp,esp                 ; Protect esp

    ;; Prepare argv
    lea_eax,[ebp+DWORD] %4      ; ARGV_address = EBP + 4
    push_eax                    ; Put argv on the stack

    ;; Prepare envp
    mov_eax,ebp                 ; Address we need to load from
    mov_eax,[eax]               ; Get ARGC
    add_eax, %2                 ; OFFSET = ARGC + 2
    sal_eax, !2                 ; OFFSET = OFFSET * WORDSIZE
    add_eax,ebp                 ; ENVP_address = ESP + OFFSET
    push_eax                    ; Put envp on the stack
    mov_ebx, &GLOBAL__envp      ; Get _envp global
    mov_[ebx],eax               ; Save environment to _envp

    ;; Stack offset
    add_ebp, %4                 ; Fix ebp

    ;; Setup for malloc
    call %FUNCTION___init_malloc

    ;; Setup for FILE*
    call %FUNCTION___init_io

    ;; Perform the main loop
    call %FUNCTION_main
    push_eax                    ; Put return on stack
    push_eax                    ; so that _exit gets the value

:FUNCTION_exit
    call %FUNCTION___kill_io
:FUNCTION__exit
    pop_ebx
    pop_ebx
    mov_eax, %1
    int !0x80

:GLOBAL__envp
    NULL

https://github.com/oriansj/M2libc/blob/main/string.c

Files:
/* Copyright (C) 2016 Jeremiah Orians
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stddef.h>

char* strcpy(char* dest, char const* src)
{
    int i = 0;

    while (0 != src[i])
    {
        dest[i] = src[i];
        i = i + 1;
    }
    dest[i] = 0;

    return dest;
}


char* strncpy(char* dest, char const* src, size_t count)
{
    if(0 == count) return dest;
    size_t i = 0;
    while(0 != src[i])
    {
        dest[i] = src[i];
        i = i + 1;
        if(count == i) return dest;
    }

    while(i <= count)
    {
        dest[i] = 0;
        i = i + 1;
    }

    return dest;
}


char* strcat(char* dest, char const* src)
{
    int i = 0;
    int j = 0;
    while(0 != dest[i]) i = i + 1;
    while(0 != src[j])
    {
        dest[i] = src[j];
        i = i + 1;
        j = j + 1;
    }
    dest[i] = 0;
    return dest;
}


char* strncat(char* dest, char const* src, size_t count)
{
    size_t i = 0;
    size_t j = 0;
    while(0 != dest[i]) i = i + 1;
    while(0 != src[j])
    {
        if(count == j)
        {
            dest[i] = 0;
            return dest;
        }
        dest[i] = src[j];
        i = i + 1;
        j = j + 1;
    }
    dest[i] = 0;
    return dest;
}


size_t strlen(char const* str )
{
    size_t i = 0;
    while(0 != str[i]) i = i + 1;
    return i;
}


size_t strnlen_s(char const* str, size_t strsz )
{
    size_t i = 0;
    while(0 != str[i])
    {
        if(strsz == i) return i;
        i = i + 1;
    }
    return i;
}


int strcmp(char const* lhs, char const* rhs )
{
    int i = 0;
    while(0 != lhs[i])
    {
        if(lhs[i] != rhs[i]) return lhs[i] - rhs[i];
        i = i + 1;
    }

    return lhs[i] - rhs[i];
}


int strncmp(char const* lhs, char const* rhs, size_t count)
{
    size_t i = 0;
    while(count > i)
    {
        if(0 == lhs[i]) break;
        if(lhs[i] != rhs[i]) return lhs[i] - rhs[i];
        i = i + 1;
    }

    return 0;
}


char* strchr(char const* str, int ch)
{
    char* p = str;
    while(ch != p[0])
    {
        if(0 == p[0]) return NULL;
        p = p + 1;
    }
    if(0 == p[0]) return NULL;
    return p;
}


char* strrchr(char const* str, int ch)
{
    char* p = str;
    int i = 0;
    while(0 != p[i]) i = i + 1;
    while(ch != p[i])
    {
        if(0 == i) return NULL;
        i = i - 1;
    }
    return (p + i);
}


size_t strspn(char const* dest, char const* src)
{
    if(0 == dest[0]) return 0;
    int i = 0;
    while(NULL != strchr(src, dest[i])) i = i + 1;
    return i;
}


size_t strcspn(char const* dest, char const* src)
{
    int i = 0;
    while(NULL == strchr(src, dest[i])) i = i + 1;
    return i;
}


char* strpbrk(char const* dest, char const* breakset)
{
    char* p = dest;
    char* s;
    while(0 != p[0])
    {
        s = strchr(breakset, p[0]);
        if(NULL != s) return strchr(p,  s[0]);
        p = p + 1;
    }
    return p;
}


void* memset(void* dest, int ch, size_t count)
{
    if(NULL == dest) return dest;
    size_t i = 0;
    char* s = dest;
    while(i < count)
    {
        s[i] = ch;
        i = i + 1;
    }
    return dest;
}


void* memcpy(void* dest, void const* src, size_t count)
{
    if(NULL == dest) return dest;
    if(NULL == src) return NULL;

    char* s1 = dest;
    char const* s2 = src;
    size_t i = 0;
    while(i < count)
    {
        s1[i] = s2[i];
        i = i + 1;
    }
    return dest;
}

void* memmove(void* dest, void const* src, size_t count)
{
    if (dest < src) return memcpy (dest, src, count);
    char *p = dest;
    char const *q = src;
    count = count - 1;
    while (count >= 0)
    {
        p[count] = q[count];
        count = count - 1;
    }
    return dest;
}


int memcmp(void const* lhs, void const* rhs, size_t count)
{
    if(0 == count) return 0;
    size_t i = 0;
    count = count - 1;
    char const* s1 = lhs;
    char const* s2 = rhs;
    while(i < count)
    {
        if(s1[i] != s2[i]) break;
        i = i + 1;
    }
    return (s1[i] - s2[i]);
}

https://git.savannah.nongnu.org/gitweb/?p=mescc-tools.git;a=blob;f=Kaem/kaem.h

File: ../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools/Kaem/kaem.h used in: Step 43
/* Copyright (C) 2016-2020 Jeremiah Orians
 * Copyright (C) 2020 fosslinux
 * This file is part of mescc-tools.
 *
 * mescc-tools is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * mescc-tools is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with mescc-tools.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>
#include "../M2libc/bootstrappable.h"

/*
 * DEFINES
 */

#define FALSE 0
#define TRUE 1
// CONSTANT SUCCESS 0
#define SUCCESS 0
// CONSTANT FAILURE 1
#define FAILURE 1
#define MAX_STRING 4096
#define MAX_ARRAY 256


/*
 * Here is the token struct. It is used for both the token linked-list and
 * env linked-list.
 */
struct Token
{
    /*
     * For the token linked-list, this stores the token; for the env linked-list
     * this stores the value of the variable.
     */
    char* value;
    /*
     * Used only for the env linked-list. It holds a string containing the
     * name of the var.
     */
    char* var;
    /*
     * This struct stores a node of a singly linked list, store the pointer to
     * the next node.
     */
    struct Token* next;
};

#include "kaem_globals.h"

https://git.savannah.nongnu.org/gitweb/?p=mescc-tools.git;a=blob;f=Kaem/variable.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools/Kaem/variable.c used in: Step 43
/*
 * Copyright (C) 2020 fosslinux
 * This file is part of mescc-tools.
 *
 * mescc-tools is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * mescc-tools is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with mescc-tools.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "kaem.h"

/* Prototypes from other files */
int array_length(char** array);
char* env_lookup(char* variable);

/*
 * VARIABLE HANDLING FUNCTIONS
 */

/* Substitute a variable into n->value */
int run_substitution(char* var_name, struct Token* n)
{
    char* value = env_lookup(var_name);
    /* If there is nothing to substitute, don't substitute anything! */
    if(value != NULL)
    {
        char* s = calloc(MAX_STRING, sizeof(char));
        s = strcat(s, n->value);
        s = strcat(s, value);
        n->value = s;
        return TRUE;
    }
    return FALSE;
}

/* Handle ${var:-text} format of variables - i.e. ifset format */
int variable_substitute_ifset(char* input, struct Token* n, int index)
{
    /*
     * In ${var:-text} format, we evaluate like follows.
     * If var is set as an envar, then we substitute the contents of that
     * envar. If it is not set, we substitute alternative text.
     *
     * In this function, we assume that input is the raw token,
     * n->value is everything already done in variable_substitute,
     * index is where we are up to in input. offset is for n->value.
     */

    /*
     * Check if we should even be performing this function.
     * We perform this function when we come across ${var:-text} syntax.
     */
    int index_old = index;
    int perform = FALSE;
    int input_length = strlen(input);
    while(index < input_length)
    { /* Loop over each character */
        if(input[index] == ':' && input[index + 1] == '-')
        { /* Yes, this is (most likely) ${var:-text} format. */
            perform = TRUE;
            break;
        }
        index = index + 1;
    }

    /* Don't perform it if we shouldn't */
    if(perform == FALSE) return index_old;
    index = index_old;

    /*
     * Get offset.
     * offset is the difference between the index of the variable we write to
     * in the following blocks and input.
     * This stays relatively constant.
     */
    int offset = index;

    /* Get the variable name */
    char* var_name = calloc(MAX_STRING, sizeof(char));
    require(var_name != NULL, "Memory initialization of var_name in variable_substitute_ifset failed\n");
    while(input[index] != ':')
    { /* Copy into var_name until :- */
        var_name[index - offset] = input[index];
        index = index + 1;
    }

    /* Skip over :- */
    index = index + 2;
    offset = index;

    /* Get the alternative text */
    char* text = calloc(MAX_STRING, sizeof(char));
    require(text != NULL, "Memory initialization of text in variable_substitute_ifset failed\n");
    while(input[index] != '}')
    { /* Copy into text until } */
        require(input_length > index, "IMPROPERLY TERMINATED VARIABLE\nABORTING HARD\n");
        text[index - offset] = input[index];
        index = index + 1;
    }

    /* Do the substitution */
    if(run_substitution(var_name, n) == FALSE)
    { /* The variable was not found. Substitute the alternative text. */
        char* s = calloc(MAX_STRING, sizeof(char));
        s = strcat(s, n->value);
        s = strcat(s, text);
        n->value = s;
    }

    return index;
}

/* Controls substitution for ${variable} and derivatives */
int variable_substitute(char* input, struct Token* n, int index)
{
    /* NOTE: index is the pos of input */
    index = index + 1; /* We don't want the { */

    /*
     * Check for "special" types
     * If we do find a special type we delegate the substitution to it
     * and return here; as we are done... there's nothing more do do in
     * that case.
     */
    int index_old = index;
    index = variable_substitute_ifset(input, n, index);
    if(index != index_old) return index;

    /* Reset index */
    index = index_old;

    /*
     * If we reach here it is a normal substitution
     * Let's do it!
     */
    /* Initialize var_name and offset */
    char* var_name = calloc(MAX_STRING, sizeof(char));
    require(var_name != NULL, "Memory initialization of var_name in variable_substitute failed\n");
    int offset = index;

    /* Get the variable name */
    int substitute_done = FALSE;
    char c;
    while(substitute_done == FALSE)
    {
        c = input[index];
        require(MAX_STRING > index, "LINE IS TOO LONG\nABORTING HARD\n");
        if(EOF == c || '\n' == c || index > strlen(input))
        { /* We never should hit EOF, EOL or run past the end of the line 
             while collecting a variable */
            fputs("IMPROPERLY TERMINATED VARIABLE!\nABORTING HARD\n", stderr);
            exit(EXIT_FAILURE);
        }
        else if('\\' == c)
        { /* Drop the \ - poor mans escaping. */
            index = index + 1;
        }
        else if('}' == c)
        { /* End of variable name */
            substitute_done = TRUE;
        }
        else
        {
            var_name[index - offset] = c;
            index = index + 1;
        }
    }

    /* Substitute the variable */
    run_substitution(var_name, n);

    return index;
}

/* Function to concatenate all command line arguments */
void variable_all(char** argv, struct Token* n)
{
    fflush(stdout);
    /* index refernences the index of n->value, unlike other functions */
    int index = 0;
    int argv_length = array_length(argv);
    int i = 0;
    char* argv_element = calloc(MAX_STRING, sizeof(char));
    char* hold = argv[i];
    n->value = argv_element;
    /* Assuming the form kaem -f script or kaem -f script -- 123 we want matching results to bash, so skip the kaem, -f and script */
    while(!match("--", hold))
    {
        i = i + 1;
        hold = argv[i];
        if(argv_length == i) break;
    }

    /* put i = i + 1 in the for initialization to skip past the -- */
    for(; i < argv_length; i = i + 1)
    {
        /* Ends up with (n->value) (argv[i]) */
        /* If we don't do this we get jumbled results in M2-Planet */
        hold = argv[i];
        strcpy(argv_element + index, hold);
        index = index + strlen(hold);

        /* Add space on the end */
        n->value[index] = ' ';
        index = index + 1;
    }
    /* Remove trailing space */
    index = index - 1;
    n->value[index] = 0;
}

/* Function controlling substitution of variables */
void handle_variables(char** argv, struct Token* n)
{
    /* NOTE: index is the position of input */
    int index = 0;

    /* Create input */
    char* input = calloc(MAX_STRING, sizeof(char));
    require(input != NULL, "Memory initialization of input in collect_variable failed\n");
    strcpy(input, n->value);
    /* Reset n->value */
    n->value = calloc(MAX_STRING, sizeof(char));
    require(n->value != NULL, "Memory initialization of n->value in collect_variable failed\n");

    /* Copy everything up to the $ */
    /*
     * TODO: Not need allocation of input before this check if there is no
     * variable in it.
     */
    while(input[index] != '$')
    {
        if(input[index] == 0)
        { /* No variable in it */
            n->value = input;
            return; /* We don't need to do anything more */
        }
        n->value[index] = input[index];
        index = index + 1;
    }

    /* Must be outside the loop */
    int offset;

substitute:
    index = index + 1; /* We are uninterested in the $ */
    /* Run the substitution */
    if(input[index] == '{')
    { /* Handle everything ${ related */
        index = variable_substitute(input, n, index);
        index = index + 1; /* We don't want the closing } */
    }
    else if(input[index] == '@')
    { /* Handles $@ */
        index = index + 1; /* We don't want the @ */
        variable_all(argv, n);
    }
    else
    { /* We don't know that */
        fputs("IMPROPERLY USED VARIABLE!\nOnly ${foo} and $@ format are accepted at this time.\nABORTING HARD\n", stderr);
        exit(EXIT_FAILURE);
    }

    offset = strlen(n->value) - index;
    /* Copy everything from the end of the variable to the end of the token */
    while(input[index] != 0)
    {
        if(input[index] == '$')
        { /* We have found another variable */
            fflush(stdout);
            goto substitute;
        }
        n->value[index + offset] = input[index];
        index = index + 1;
    }
}

https://git.savannah.nongnu.org/gitweb/?p=mescc-tools.git;a=blob;f=Kaem/kaem_globals.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools/Kaem/kaem_globals.c used in: Step 43
/* Copyright (C) 2016-2020 Jeremiah Orians
 * Copyright (C) 2020 fosslinux
 * This file is part of mescc-tools.
 *
 * mescc-tools is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * mescc-tools is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with mescc-tools.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "kaem.h"

int command_done;
int VERBOSE;
int VERBOSE_EXIT;
int STRICT;
int INIT_MODE;
int FUZZING;
int WARNINGS;
char* KAEM_BINARY;
char* PATH;

/* Token linked-list; stores the tokens of each line */
struct Token* token;
/* Env linked-list; stores the environment variables */
struct Token* env;
/* Alias linked-list; stores the aliases */
struct Token* alias;

https://git.savannah.nongnu.org/gitweb/?p=mescc-tools.git;a=blob;f=Kaem/kaem.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools/Kaem/kaem.c used in: Step 43
/* Copyright (C) 2016-2020 Jeremiah Orians
 * Copyright (C) 2020 fosslinux
 * Copyright (C) 2021 Andrius Å tikonas
 * This file is part of mescc-tools.
 *
 * mescc-tools is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * mescc-tools is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with mescc-tools.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
#include "kaem.h"

/* Prototypes from other files */
void handle_variables(char** argv, struct Token* n);

/*
 * UTILITY FUNCTIONS
 */

/* Function to find a character in a string */
char* find_char(char* string, char a)
{
    if(0 == string[0])
    {
        return NULL;
    }

    while(a != string[0])
    {
        string = string + 1;

        if(0 == string[0])
        {
            return string;
        }
    }

    return string;
}

/* Function to find the length of a char**; an array of strings */
int array_length(char** array)
{
    int length = 0;

    while(array[length] != NULL)
    {
        length = length + 1;
    }

    return length;
}

/* Search for a variable in the token linked-list */
char* token_lookup(char* variable, struct Token* token)
{
    /* Start at the head */
    struct Token* n = token;

    /* Loop over the linked-list */
    while(n != NULL)
    {
        if(match(variable, n->var))
        {
            /* We have found the correct node */
            return n->value; /* Done */
        }

        /* Nope, try the next */
        n = n->next;
    }

    /* We didn't find anything! */
    return NULL;
}

/* Search for a variable in the env linked-list */
char* env_lookup(char* variable)
{
    return token_lookup(variable, env);
}

/* Search for a variable in the alias linked-list */
char* alias_lookup(char* variable)
{
    return token_lookup(variable, alias);
}

/* Find the full path to an executable */
char* find_executable(char* name)
{
    if(match("", name))
    {
        return NULL;
    }

    if(('.' == name[0]) || ('/' == name[0]))
    {
        /* assume names that start with . or / are relative or absolute */
        return name;
    }

    char* trial = calloc(MAX_STRING, sizeof(char));
    char* MPATH = calloc(MAX_STRING, sizeof(char)); /* Modified PATH */
    require(MPATH != NULL, "Memory initialization of MPATH in find_executable failed\n");
    strcpy(MPATH, PATH);
    FILE* t;
    char* next = find_char(MPATH, ':');
    int index;
    int offset;
    int mpath_length;
    int name_length;
    int trial_length;

    while(NULL != next)
    {
        /* Reset trial */
        trial_length = strlen(trial);

        for(index = 0; index < trial_length; index = index + 1)
        {
            trial[index] = 0;
        }

        next[0] = 0;
        /* prepend_string(MPATH, prepend_string("/", name)) */
        mpath_length = strlen(MPATH);

        for(index = 0; index < mpath_length; index = index + 1)
        {
            require(MAX_STRING > index, "Element of PATH is too long\n");
            trial[index] = MPATH[index];
        }

        trial[index] = '/';
        offset = strlen(trial);
        name_length = strlen(name);

        for(index = 0; index < name_length; index = index + 1)
        {
            require(MAX_STRING > index, "Element of PATH is too long\n");
            trial[index + offset] = name[index];
        }

        /* Try the trial */
        require(strlen(trial) < MAX_STRING, "COMMAND TOO LONG!\nABORTING HARD\n");
        t = fopen(trial, "r");

        if(NULL != t)
        {
            fclose(t);
            return trial;
        }

        MPATH = next + 1;
        next = find_char(MPATH, ':');
    }

    return NULL;
}

/* Function to convert a Token linked-list into an array of strings */
char** list_to_array(struct Token* s)
{
    struct Token* n;
    n = s;
    char** array = calloc(MAX_ARRAY, sizeof(char*));
    require(array != NULL, "Memory initialization of array in conversion of list to array failed\n");
    char* element = calloc(MAX_STRING, sizeof(char));
    require(element != NULL, "Memory initialization of element in conversion of list to array failed\n");
    int index = 0;
    int i;
    int value_length;
    int var_length;
    int offset;

    while(n != NULL)
    {
        /* Loop through each node and assign it to an array index */
        array[index] = calloc(MAX_STRING, sizeof(char));
        require(array[index] != NULL, "Memory initialization of array[index] in conversion of list to array failed\n");
        /* Bounds checking */
        /* No easy way to tell which it is, output generic message */
        require(index < MAX_ARRAY, "SCRIPT TOO LONG or TOO MANY ENVARS\nABORTING HARD\n");

        if(n->var == NULL)
        {
            /* It is a line */
            array[index] = n->value;
        }
        else
        {
            /* It is a var */
            /* prepend_string(n->var, prepend_string("=", n->value)) */
            var_length = strlen(n->var);

            for(i = 0; i < var_length; i = i + 1)
            {
                element[i] = n->var[i];
            }

            element[i] = '=';
            i = i + 1;
            offset = i;
            value_length = strlen(n->value);

            for(i = 0; i < value_length; i = i + 1)
            {
                element[i + offset] = n->value[i];
            }
        }

        /* Insert elements if not empty */
        if(!match("", element))
        {
            strcpy(array[index], element);
        }

        n = n->next;
        index = index + 1;

        /* Reset element */
        for(i = 0; i < MAX_STRING; i = i + 1)
        {
            element[i] = 0;
        }
    }

    return array;
}

/* Function to handle the correct options for escapes */
int handle_escape(int c)
{
    if(c == '\n')
    {
        /* Do nothing - eat up the newline */
        return -1;
    }
    else if('n' == c)
    {
        /* Add a newline to the token */
        return '\n';
    }
    else if('r' == c)
    {
        /* Add a return to the token */
        return '\r';
    }
    else if('\\' == c)
    {
        /* Add a real backslash to the token */
        return '\\';
    }
    else
    {
        /* Just add it to the token (eg, quotes) */
        return c;
    }
}

/*
 * TOKEN COLLECTION FUNCTIONS
 */

/* Function for skipping over line comments */
void collect_comment(FILE* input)
{
    int c;

    /* Eat up the comment, one character at a time */
    /*
     * Sanity check that the comment ends with \n.
     * Remove the comment from the FILE*
     */
    do
    {
        c = fgetc(input);
        /* We reached an EOF!! */
        require(EOF != c, "IMPROPERLY TERMINATED LINE COMMENT!\nABORTING HARD\n");
    } while('\n' != c); /* We can now be sure it ended with \n -- and have purged the comment */
}

/* Function for collecting strings and removing the "" pair that goes with them */
int collect_string(FILE* input, char* n, int index)
{
    int string_done = FALSE;
    int c;

    do
    {
        /* Bounds check */
        require(MAX_STRING > index, "LINE IS TOO LONG\nABORTING HARD\n");
        c = fgetc(input);
        require(EOF != c, "IMPROPERLY TERMINATED STRING!\nABORTING HARD\n");

        if('\\' == c)
        {
            /* We are escaping the next character */
            /* This correctly handles escaped quotes as it just returns the quote */
            c = fgetc(input);
            c = handle_escape(c);
            n[index] = c;
            index = index + 1;
        }
        else if('"' == c)
        {
            /* End of string */
            string_done = TRUE;
        }
        else
        {
            n[index] = c;
            index = index + 1;
        }
    } while(string_done == FALSE);

    return index;
}

/* Function to parse and assign token->value */
int collect_token(FILE* input, char* n, int last_index)
{
    int c;
    int cc;
    int token_done = FALSE;
    int index = 0;

    do
    {
        /* Loop over each character in the token */
        c = fgetc(input);
        /* Bounds checking */
        require(MAX_STRING > index, "LINE IS TOO LONG\nABORTING HARD\n");

        if(EOF == c)
        {
            /* End of file -- this means script complete */
            /* We don't actually exit here. This logically makes more sense;
             * let the code follow its natural path of execution and exit
             * sucessfuly at the end of main().
             */
            token_done = TRUE;
            command_done = TRUE;
            return -1;
        }
        else if((' ' == c) || ('\t' == c))
        {
            /* Space and tab are token separators */
            token_done = TRUE;
        }
        else if(('\n' == c) || (';' == c))
        {
            /* Command terminates at the end of a line or at semicolon */
            command_done = TRUE;
            token_done = TRUE;

            if(0 == index)
            {
                index = last_index;
            }
        }
        else if('"' == c)
        {
            /* Handle strings -- everything between a pair of "" */
            index = collect_string(input, n, index);
            token_done = TRUE;
        }
        else if('#' == c)
        {
            /* Handle line comments */
            collect_comment(input);
            command_done = TRUE;
            token_done = TRUE;

            if(0 == index)
            {
                index = last_index;
            }
        }
        else if('\\' == c)
        {
            /* Support for escapes */
            c = fgetc(input); /* Skips over \, gets the next char */
            cc = handle_escape(c);

            if(-1 != cc)
            {
                /* We need to put it into the token */
                n[index] = cc;
            }

            index = index + 1;
        }
        else if(0 == c)
        {
            /* We have come to the end of the token */
            token_done = TRUE;
        }
        else
        {
            /* It's a character to assign */
            n[index] = c;
            index = index + 1;
        }
    } while(token_done == FALSE);

    return index;
}

/* Function to parse string and assign token->value */
int collect_alias_token(char* input, char* n, int index)
{
    int c;
    int cc;
    int token_done = FALSE;
    int output_index = 0;

    do
    {
        /* Loop over each character in the token */
        c = input[index];
        index = index + 1;

        if((' ' == c) || ('\t' == c))
        {
            /* Space and tab are token separators */
            token_done = TRUE;
        }
        else if('\\' == c)
        {
            /* Support for escapes */
            c = input[index];
            index = index + 1;
            cc = handle_escape(c);

            /* We need to put it into the token */
            n[output_index] = cc;
            output_index = output_index + 1;
        }
        else if(0 == c)
        {
            /* We have come to the end of the token */
            token_done = TRUE;
            index = 0;
        }
        else
        {
            /* It's a character to assign */
            n[output_index] = c;
            output_index = output_index + 1;
        }
    } while(token_done == FALSE);

    return index;
}

/*
 * EXECUTION FUNCTIONS
 * Note: All of the builtins return SUCCESS (0) when they exit successfully
 * and FAILURE (1) when they fail.
 */

/* Function to check if the token is an envar */
int is_envar(char* token)
{
    int i = 0;
    int token_length = strlen(token);

    while(i < token_length)
    {
        if(token[i] == '=')
        {
            return FAILURE;
        }

        i = i + 1;
    }

    return SUCCESS;
}

/* Add an envar */
void add_envar()
{
    /* Pointers to strings we want */
    char* name = calloc(strlen(token->value) + 4, sizeof(char));
    char* value = token->value;
    char* newvalue;
    int i = 0;

    /* Isolate the name */
    while('=' != value[i])
    {
        name[i] = value[i];
        i = i + 1;
    }

    /* Isolate the value */
    newvalue = name + i + 2;
    value = value + i + 1;
    i = 0;
    require(0 != value[i], "add_envar received improper variable\n");

    while(0 != value[i])
    {
        newvalue[i] = value[i];
        i = i + 1;
    }

    /* If we are in init-mode and this is the first var env == NULL, rectify */
    if(env == NULL)
    {
        env = calloc(1, sizeof(struct Token));
        require(env != NULL, "Memory initialization of env failed\n");
        env->var = name; /* Add our first variable */
    }

    /*
     * If the name of the envar is PATH, then we need to set our (internal)
     * global PATH value.
     */
    if(match(name, "PATH"))
    {
        strcpy(PATH, newvalue);
    }

    struct Token* n = env;

    /* Find match if possible */
    while(!match(name, n->var))
    {
        if(NULL == n->next)
        {
            n->next = calloc(1, sizeof(struct Token));
            require(n->next != NULL, "Memory initialization of next env node in add_envar failed\n");
            n->next->var = name;
        } /* Loop will match and exit */

        n = n->next;
    }

    /* Since we found the variable we need only to set it to its new value */
    n->value = newvalue;
}

/* Add an alias */
void add_alias()
{
    token = token->next; /* Skip the actual alias */
    if(token->next == NULL)
    {
        /* No arguments */
        char** array = list_to_array(alias);
        int index = 0;
        while(array[index] != NULL) {
            fputs(array[index], stdout);
            fputc('\n', stdout);
            index = index + 1;
        }
        fflush(stdout);
        return;
    }
    if(!is_envar(token->value)) {
        char** array = list_to_array(token);
        int index = 0;
        while(array[index] != NULL) {
            fputs(array[index], stdout);
            fputc(' ', stdout);
            index = index + 1;
        }
        fputc('\n', stdout);
        fflush(stdout);
        return;
    }

    /* Pointers to strings we want */
    char* name = calloc(strlen(token->value) + 4, sizeof(char));
    char* value = token->value;
    char* newvalue;
    int i = 0;

    /* Isolate the name */
    while('=' != value[i])
    {
        name[i] = value[i];
        i = i + 1;
    }

    /* Isolate the value */
    newvalue = name + i + 2;
    value = value + i + 1;
    i = 0;
    require(0 != value[i], "add_alias received improper variable\n");

    while(0 != value[i])
    {
        newvalue[i] = value[i];
        i = i + 1;
    }

    /* If this is the first alias, rectify */
    if(alias == NULL)
    {
        alias = calloc(1, sizeof(struct Token));
        require(alias != NULL, "Memory initialization of alias failed\n");
        alias->var = name; /* Add our first variable */
    }

    struct Token* n = alias;

    /* Find match if possible */
    while(!match(name, n->var))
    {
        if(NULL == n->next)
        {
            n->next = calloc(1, sizeof(struct Token));
            require(n->next != NULL, "Memory initialization of next alias node in alias failed\n");
            n->next->var = name;
        } /* Loop will match and exit */

        n = n->next;
    }

    /* Since we found the variable we need only to set it to its new value */
    n->value = newvalue;
}

/* cd builtin */
int cd()
{
    if(NULL == token->next)
    {
        return FAILURE;
    }

    token = token->next;

    if(NULL == token->value)
    {
        return FAILURE;
    }

    int ret = chdir(token->value);

    if(0 > ret)
    {
        return FAILURE;
    }

    return SUCCESS;
}

/* pwd builtin */
int pwd()
{
    char* path = calloc(MAX_STRING, sizeof(char));
    require(path != NULL, "Memory initialization of path in pwd failed\n");
    getcwd(path, MAX_STRING);
    require(!match("", path), "getcwd() failed\n");
    fputs(path, stdout);
    fputs("\n", stdout);
    return SUCCESS;
}

/* set builtin */
int set()
{
    /* Get the options */
    int i;

    if(NULL == token->next)
    {
        goto cleanup_set;
    }

    token = token->next;

    if(NULL == token->value)
    {
        goto cleanup_set;
    }

    char* options = calloc(MAX_STRING, sizeof(char));
    require(options != NULL, "Memory initialization of options in set failed\n");
    int last_position = strlen(token->value) - 1;

    for(i = 0; i < last_position; i = i + 1)
    {
        options[i] = token->value[i + 1];
    }

    /* Parse the options */
    int options_length = strlen(options);

    for(i = 0; i < options_length; i = i + 1)
    {
        if(options[i] == 'a')
        {
            /* set -a is on by default and cannot be disabled at this time */
            if(WARNINGS)
            {
                fputs("set -a is on by default and cannot be disabled\n", stdout);
            }

            continue;
        }
        else if(options[i] == 'e')
        {
            /* Fail on failure */
            STRICT = TRUE;
        }
        else if(options[i] == 'x')
        {
            /* Show commands as executed */
            /* TODO: this currently behaves like -v. Make it do what it should */
            VERBOSE = TRUE;
            /*
             * Output the set -x because VERBOSE didn't catch it before.
             * We don't do just -x because we support multiple options in one command,
             * eg set -ex.
             */
            fputs(" +> set -", stdout);
            fputs(options, stdout);
            fputs("\n", stdout);
            fflush(stdout);
        }
        else
        {
            /* Invalid */
            fputc(options[i], stderr);
            fputs(" is an invalid set option!\n", stderr);
            exit(EXIT_FAILURE);
        }
    }

    return SUCCESS;
cleanup_set:
    return FAILURE;
}

/* echo builtin */
void echo()
{
    if(token->next == NULL)
    {
        /* No arguments */
        fputs("\n", stdout);
        return;
    }

    if(token->next->value == NULL)
    {
        /* No arguments */
        fputs("\n", stdout);
        return;
    }

    token = token->next; /* Skip the actual echo */

    while(token != NULL)
    {
        /* Output each argument to echo to stdout */
        if(token->value == NULL)
        {
            break;
        }

        fputs(token->value, stdout);
        if(NULL != token->next)
        {
            /* M2-Planet doesn't short circuit */
            if(NULL != token->next->value) fputc(' ', stdout);
        }
        token = token->next;
    }

    fputs("\n", stdout);
}

/* unset builtin */
void unset()
{
    struct Token* e;
    /* We support multiple variables on the same line */
    struct Token* t;
    t = token->next;

    while(t != NULL)
    {
        e = env;

        /* Look for the variable; we operate on ->next because we need to remove ->next */
        while(e->next != NULL)
        {
            if(NULL == t->value)
            {
                break;
            }

            if(match(e->next->var, t->value))
            {
                break;
            }

            e = e->next;
        }

        t = t->next;

        /* If it's NULL nothing was found */
        if(e->next == NULL)
        {
            continue;
        }

        /* Otherwise there is something to unset */
        e->next = e->next->next;
    }
}

void execute(FILE* script, char** argv);
int _execute(FILE* script, char** argv);
int collect_command(FILE* script, char** argv);

/* if builtin */
void if_cmd(FILE* script, char** argv)
{
    int index;
    int old_VERBOSE;
    token = token->next; /* Skip the actual if */
    /* Do not check for successful exit status */
    int if_status = _execute(script, argv);
    old_VERBOSE = VERBOSE;
    VERBOSE = VERBOSE && !if_status;

    do
    {
        index = collect_command(script, argv);
        require(index != -1, "Unexpected EOF, improperly terminated if statement.\n");

        if(0 == index)
        {
            continue;
        }

        if(0 == if_status)
        {
            /* Stuff to exec */
            execute(script, argv);
        }

        if(match(token->value, "else"))
        {
            if_status = !if_status;
        }
    } while(!match(token->value, "fi"));

    VERBOSE = old_VERBOSE;
}

int what_exit(char* program, int status)
{
    /***********************************************************************************
     * If the low-order 8 bits of w_status are equal to 0x7F or zero, the child        *
     * process has stopped. If the low-order 8 bits of w_status are non-zero and are   *
     * not equal to 0x7F, the child process terminated due to a signal otherwise, the  *
     * child process terminated due to an exit() call.                                 *
     *                                                                                 *
     * In the event it was a signal that stopped the process the top 8 bits of         *
     * w_status contain the signal that caused the process to stop.                    *
     *                                                                                 *
     * In the event it was terminated the bottom 7 bits of w_status contain the        *
     * terminating error number for the process.                                       *
     *                                                                                 *
     * If bit 0x80 of w_status is set, a core dump was produced.                       *
     ***********************************************************************************/

    int WIFEXITED = !(status & 0x7F);
    int WEXITSTATUS = (status & 0xFF00) >> 8;
    int WTERMSIG = status & 0x7F;
    int WCOREDUMP = status & 0x80;
    int WIFSIGNALED = !((0x7F == WTERMSIG) || (0 == WTERMSIG));
    int WIFSTOPPED = ((0x7F == WTERMSIG) && (0 == WCOREDUMP));

    if(WIFEXITED)
    {
        if(VERBOSE_EXIT)
        {
            fputc('\n', stderr);
            fputs(program, stderr);
            fputs(" normal termination, exit status = ", stderr);
            fputs(int2str(WEXITSTATUS, 10, TRUE), stderr);
            fputs("\n\n\n", stderr);
        }
        return WEXITSTATUS;
    }
    else if (WIFSIGNALED)
    {
        fputc('\n', stderr);
        fputs(program, stderr);
        fputs(" abnormal termination, signal number = ", stderr);
        fputs(int2str(WTERMSIG, 10, TRUE), stderr);
        fputc('\n', stderr);
        if(WCOREDUMP) fputs("core dumped\n", stderr);
        return WTERMSIG;
    }
    else if(WIFSTOPPED)
    {
        fputc('\n', stderr);
        fputs(program, stderr);
        fputs(" child stopped, signal number = ", stderr);
        fputs(int2str(WEXITSTATUS, 10, TRUE), stderr);
        fputc('\n', stderr);
        return WEXITSTATUS;
    }

    fputc('\n', stderr);
    fputs(program, stderr);
    fputs(" :: something crazy happened with execve\nI'm just gonna get the hell out of here\n", stderr);
    exit(EXIT_FAILURE);
}

/* Execute program and check for error */
void execute(FILE* script, char** argv)
{
    int status = _execute(script, argv);

    if(STRICT == TRUE && (0 != status))
    {
        /* Clearly the script hit an issue that should never have happened */
        fputs("Subprocess error ", stderr);
        fputs(int2str(status, 10, TRUE), stderr);
        fputs("\nABORTING HARD\n", stderr);
        exit(EXIT_FAILURE);
    }
}

/* Execute program */
int _execute(FILE* script, char** argv)
{
    /* Run the command */
    /* rc = return code */
    int rc;
    /* exec without forking */
    int exec = FALSE;

    /* Actually do the execution */
    if(is_envar(token->value) == TRUE)
    {
        add_envar();
        return 0;
    }
    else if(match(token->value, "cd"))
    {
        rc = cd();

        if(STRICT)
        {
            require(rc == SUCCESS, "cd failed!\n");
        }

        return 0;
    }
    else if(match(token->value, "set"))
    {
        rc = set();

        if(STRICT)
        {
            require(rc == SUCCESS, "set failed!\n");
        }

        return 0;
    }
    else if(match(token->value, "alias"))
    {
        add_alias();
        return 0;
    }
    else if(match(token->value, "pwd"))
    {
        rc = pwd();

        if(STRICT)
        {
            require(rc == SUCCESS, "pwd failed!\n");
        }

        return 0;
    }
    else if(match(token->value, "echo"))
    {
        echo();
        return 0;
    }
    else if(match(token->value, "unset"))
    {
        unset();
        return 0;
    }
    else if(match(token->value, "exec"))
    {
        token = token->next; /* Skip the actual exec */
        exec = TRUE;
    }
    else if(match(token->value, "if"))
    {
        if_cmd(script, argv);
        return 0;
    }
    else if(match(token->value, "then"))
    {
        /* ignore */
        return 0;
    }
    else if(match(token->value, "else"))
    {
        /* ignore */
        return 0;
    }
    else if(match(token->value, "fi"))
    {
        /* ignore */
        return 0;
    }

    /* If it is not a builtin, run it as an executable */
    int status; /* i.e. return code */
    char** array;
    char** envp;
    /* Get the full path to the executable */
    char* program = find_executable(token->value);

    /* Check we can find the executable */
    if(NULL == program)
    {
        if(STRICT == TRUE)
        {
            fputs("WHILE EXECUTING ", stderr);
            fputs(token->value, stderr);
            fputs(" NOT FOUND!\nABORTING HARD\n", stderr);
            exit(EXIT_FAILURE);
        }

        /* If we are not strict simply return */
        return 0;
    }

    int f = 0;

#ifdef __uefi__
    array = list_to_array(token);
    envp = list_to_array(env);
    return spawn(program, array, envp);
#else
    if(!exec)
    {
        f = fork();
    }

    /* Ensure fork succeeded */
    if(f == -1)
    {
        fputs("WHILE EXECUTING ", stderr);
        fputs(token->value, stderr);
        fputs(" fork() FAILED\nABORTING HARD\n", stderr);
        exit(EXIT_FAILURE);
    }
    else if(f == 0)
    {
        /* Child */
        /**************************************************************
         * Fuzzing produces random stuff; we don't want it running    *
         * dangerous commands. So we just don't execve.               *
         * But, we still do the list_to_array calls to check for      *
         * segfaults.                                                 *
         **************************************************************/
        array = list_to_array(token);
        envp = list_to_array(env);

        if(FALSE == FUZZING)
        {
            /* We are not fuzzing */
            /* execve() returns only on error */
            execve(program, array, envp);
        }

        /* Prevent infinite loops */
        _exit(EXIT_FAILURE);
    }

    /* Otherwise we are the parent */
    /* And we should wait for it to complete */
    waitpid(f, &status, 0);
    return what_exit(program, status);
#endif
}

int collect_command(FILE* script, char** argv)
{
    command_done = FALSE;
    /* Initialize token */
    struct Token* n;
    n = calloc(1, sizeof(struct Token));
    require(n != NULL, "Memory initialization of token in collect_command failed\n");
    char* s = calloc(MAX_STRING, sizeof(char));
    require(s != NULL, "Memory initialization of token in collect_command failed\n");
    token = n;
    int index = 0;
    int alias_index;
    char* alias_string;

    /* Get the tokens */
    while(command_done == FALSE)
    {
        index = collect_token(script, s, index);
        /* Don't allocate another node if the current one yielded nothing, OR
         * if we are done.
         */

        if(match(s, ""))
        {
            continue;
        }

        alias_string = alias_lookup(s);
        alias_index = 0;
        do
        {
            if(alias_string != NULL)
            {
                alias_index = collect_alias_token(alias_string, s, alias_index);
            }

            /* add to token */
            n->value = s;
            s = calloc(MAX_STRING, sizeof(char));
            require(s != NULL, "Memory initialization of next token node in collect_command failed\n");
            /* Deal with variables */
            handle_variables(argv, n);

            /* If the variable expands into nothing */
            if(match(n->value, " "))
            {
                n->value = NULL;
                continue;
            }

            /* Prepare for next loop */
            n->next = calloc(1, sizeof(struct Token));
            require(n->next != NULL, "Memory initialization of next token node in collect_command failed\n");
            n = n->next;
        }
        while(alias_index != 0);
    }

    /* -1 means the script is done */
    if(EOF == index)
    {
        return index;
    }

    /* Output the command if verbose is set */
    /* Also if there is nothing in the command skip over */
    if(VERBOSE && !match(token->value, "") && !match(token->value, NULL))
    {
        n = token;
        fputs(" +>", stdout);

        while(n != NULL)
        {
            /* Print out each token token */
            fputs(" ", stdout);

            /* M2-Planet doesn't let us do this in the while */
            if(n->value != NULL)
            {
                if(!match(n->value, ""))
                {
                    fputs(n->value, stdout);
                }
            }

            n = n->next;
        }

        fputc('\n', stdout);
        fflush(stdout);
    }

    return index;
}

/* Function for executing our programs with desired arguments */
void run_script(FILE* script, char** argv)
{
    int index;

    while(TRUE)
    {
        /*
         * Tokens has to be reset each time, as we need a new linked-list for
         * each line.
         * See, the program flows like this as a high level overview:
         * Get line -> Sanitize line and perform variable replacement etc ->
         * Execute line -> Next.
         * We don't need the previous lines once they are done with, so tokens
         * are hence for each line.
         */
        index = collect_command(script, argv);

        /* -1 means the script is done */
        if(EOF == index)
        {
            break;
        }

        if(0 == index)
        {
            continue;
        }

        /* Stuff to exec */
        execute(script, argv);
    }
}

/* Function to populate env */
void populate_env(char** envp)
{
    /* You can't populate a NULL environment */
    if(NULL == envp)
    {
        return;
    }

    /* avoid empty arrays */
    int max = array_length(envp);

    if(0 == max)
    {
        return;
    }

    /* Initialize env and n */
    env = calloc(1, sizeof(struct Token));
    require(env != NULL, "Memory initialization of env failed\n");
    struct Token* n;
    n = env;
    int i;
    int j;
    int k;
    char* envp_line;

    for(i = 0; i < max; i = i + 1)
    {
        n->var = calloc(MAX_STRING, sizeof(char));
        require(n->var != NULL, "Memory initialization of n->var in population of env failed\n");
        n->value = calloc(MAX_STRING, sizeof(char));
        require(n->value != NULL, "Memory initialization of n->var in population of env failed\n");
        j = 0;
        /*
         * envp is weird.
         * When referencing envp[i]'s characters directly, they were all jumbled.
         * So just copy envp[i] to envp_line, and work with that - that seems
         * to fix it.
         */
        envp_line = calloc(MAX_STRING, sizeof(char));
        require(envp_line != NULL, "Memory initialization of envp_line in population of env failed\n");
        strcpy(envp_line, envp[i]);

        while(envp_line[j] != '=')
        {
            /* Copy over everything up to = to var */
            n->var[j] = envp_line[j];
            j = j + 1;
        }

        /* If we get strange input, we need to ignore it */
        if(n->var == NULL)
        {
            continue;
        }

        j = j + 1; /* Skip over = */
        k = 0; /* As envp[i] will continue as j but n->value begins at 0 */

        while(envp_line[j] != 0)
        {
            /* Copy everything else to value */
            n->value[k] = envp_line[j];
            j = j + 1;
            k = k + 1;
        }

        /* Sometimes, we get lines like VAR=, indicating nothing is in the variable */
        if(n->value == NULL)
        {
            n->value = "";
        }

        /* Advance to next part of linked list */
        n->next = calloc(1, sizeof(struct Token));
        require(n->next != NULL, "Memory initialization of n->next in population of env failed\n");
        n = n->next;
    }

    /* Get rid of node on the end */
    n = NULL;
    /* Also destroy the n->next reference */
    n = env;

    while(n->next->var != NULL)
    {
        n = n->next;
    }

    n->next = NULL;
}

int main(int argc, char** argv, char** envp)
{
    VERBOSE = FALSE;
    VERBOSE_EXIT = FALSE;
    STRICT = TRUE;
    FUZZING = FALSE;
    WARNINGS = FALSE;
    char* filename = "kaem.run";
    FILE* script = NULL;
    /* Initalize structs */
    token = calloc(1, sizeof(struct Token));
    require(token != NULL, "Memory initialization of token failed\n");
    if(NULL != argv[0]) KAEM_BINARY = argv[0];
    else KAEM_BINARY = "./bin/kaem";
    int i = 1;

    /* Loop over arguments */
    while(i <= argc)
    {
        if(NULL == argv[i])
        {
            /* Ignore the argument */
            i = i + 1;
        }
        else if(match(argv[i], "-h") || match(argv[i], "--help"))
        {
            /* Help information */
            fputs("Usage: ", stdout);
            fputs(argv[0], stdout);
            fputs(" [-h | --help] [-V | --version] [--file filename | -f filename] [-i | --init-mode] [-v | --verbose] [--non-strict] [--warn] [--fuzz]\n", stdout);
            exit(EXIT_SUCCESS);
        }
        else if(match(argv[i], "-f") || match(argv[i], "--file"))
        {
            /* Set the filename */
            if(argv[i + 1] != NULL)
            {
                filename = argv[i + 1];
            }

            i = i + 2;
        }
        else if(match(argv[i], "-i") || match(argv[i], "--init-mode"))
        {
            /* init mode does not populate env */
            INIT_MODE = TRUE;
            i = i + 1;
        }
        else if(match(argv[i], "-V") || match(argv[i], "--version"))
        {
            /* Output version */
            fputs("kaem version 1.4.0\n", stdout);
            exit(EXIT_SUCCESS);
        }
        else if(match(argv[i], "-v") || match(argv[i], "--verbose"))
        {
            /* Set verbose */
            VERBOSE = TRUE;
            i = i + 1;
        }
        else if(match(argv[i], "--strict"))
        {
            /* it is a NOP */
            STRICT = TRUE;
            i = i + 1;
        }
        else if(match(argv[i], "--non-strict"))
        {
            /* Set strict */
            STRICT = FALSE;
            i = i + 1;
        }
        else if(match(argv[i], "--warn"))
        {
            /* Set warnings */
            WARNINGS = TRUE;
            i = i + 1;
        }
        else if(match(argv[i], "--fuzz"))
        {
            /* Set fuzzing */
            FUZZING = TRUE;
            i = i + 1;
        }
        else if(match(argv[i], "--show-exit-codes"))
        {
            /* show exit codes */
            VERBOSE_EXIT = TRUE;
            i = i + 1;
        }
        else if(match(argv[i], "--"))
        {
            /* Nothing more after this */
            break;
        }
        else
        {
            /* We don't know this argument */
            fputs("UNKNOWN ARGUMENT\n", stdout);
            exit(EXIT_FAILURE);
        }
    }

    /* Populate env */
    if(INIT_MODE == FALSE)
    {
        populate_env(envp);
    }

    /* make sure SHELL is set */
    if(NULL == env_lookup("SHELL"))
    {
        struct Token* shell = calloc(1, sizeof(struct Token));
        require(NULL != shell, "unable to create SHELL environment variable\n");
        shell->next = env;
        shell->var = "SHELL";
        shell->value= KAEM_BINARY;
        env = shell;
    }

    /* Populate PATH variable
     * We don't need to calloc() because env_lookup() does this for us.
     */
    PATH = env_lookup("PATH");
    /* Populate USERNAME variable */
    char* USERNAME = env_lookup("LOGNAME");

    /* Handle edge cases */
    if((NULL == PATH) && (NULL == USERNAME))
    {
        /* We didn't find either of PATH or USERNAME -- use a generic PATH */
        PATH = calloc(MAX_STRING, sizeof(char));
        require(PATH != NULL, "Memory initialization of PATH failed\n");
        strcpy(PATH, "/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin");
    }
    else if(NULL == PATH)
    {
        /* We did find a username but not a PATH -- use a generic PATH but with /home/USERNAME */
        PATH = calloc(MAX_STRING, sizeof(char));
        PATH = strcat(PATH, "/home/");
        PATH = strcat(PATH, USERNAME);
        PATH = strcat(PATH, "/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games");
    }

    /* Open the script */
    script = fopen(filename, "r");

    if(NULL == script)
    {
        fputs("The file: ", stderr);
        fputs(filename, stderr);
        fputs(" can not be opened!\n", stderr);
        exit(EXIT_FAILURE);
    }

    /* Run the commands */
    run_script(script, argv);
    /* Cleanup */
    fclose(script);
    return EXIT_SUCCESS;
}

https://github.com/oriansj/M2-Mesoplanet/blob/main/cc.h

File: ../git/live-bootstrap/sysa/stage0-posix/src/M2-Mesoplanet/cc.h used in: Step 49
/* Copyright (C) 2016 Jeremiah Orians
 * Copyright (C) 2020 deesix <deesix@tuta.io>
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>


#define FALSE 0
#define TRUE 1


int in_set(int c, char* s);
int match(char* a, char* b);
void require(int bool, char* error);
char* int2str(int x, int base, int signed_p);
void reset_hold_string();


struct type
{
    struct type* next;
    int size;
    int offset;
    int is_signed;
    struct type* indirect;
    struct type* members;
    struct type* type;
    char* name;
};

struct token_list
{
    struct token_list* next;
    union
    {
        struct token_list* locals;
        struct token_list* prev;
    };
    char* s;
    union
    {
        struct type* type;
        char* filename;
    };
    union
    {
        struct token_list* arguments;
        struct token_list* expansion;
        int depth;
        int linenumber;
    };
};

#include "cc_globals.h"

https://github.com/oriansj/M2-Mesoplanet/blob/main/cc_globals.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/M2-Mesoplanet/cc_globals.c used in: Step 49
/* Copyright (C) 2016 Jeremiah Orians
 * Copyright (C) 2020 deesix <deesix@tuta.io>
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */

/* What types we have */
struct type* global_types;
struct type* prim_types;

/* What we are currently working on */
struct token_list* global_token;

/* Output reorder collections*/
struct token_list* output_list;
struct token_list* strings_list;
struct token_list* globals_list;

/* Make our string collection more efficient */
char* hold_string;
int string_index;

int MAX_STRING;

/* enable preprocessor-only mode */
int PREPROCESSOR_MODE;

/* enable spawn behavior to be effective */
char* M2LIBC_PATH;
char* Architecture;
char* OperatingSystem;
int WORDSIZE;
int ENDIAN;
char* BASEADDRESS;
int STDIO_USED;
char* TEMPDIR;

/* So we don't shoot ourself in the face */
int FUZZING;
int DIRTY_MODE;
int DEBUG_LEVEL;

https://github.com/oriansj/M2-Mesoplanet/blob/main/cc_env.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/M2-Mesoplanet/cc_env.c used in: Step 49
/* Copyright (C) 2016 Jeremiah Orians
 * Copyright (C) 2020 deesix <deesix@tuta.io>
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */

#include"cc.h"
#include <sys/utsname.h>

void init_macro_env(char* sym, char* value, char* source, int num);
char* env_lookup(char* variable);
void clear_string(char* s);

struct utsname* get_uname_data()
{
    struct utsname* unameData = calloc(1, sizeof(struct utsname));
    require(NULL != unameData, "unameData calloc failed\n");
    uname(unameData);
    if(4 <= DEBUG_LEVEL)
    {
        fputs("utsname details: ", stderr);
        fputs(unameData->sysname, stderr);
        fputc(' ', stderr);
        fputs(unameData->machine, stderr);
        fputc('\n', stderr);
    }
    return unameData;
}

void setup_env()
{
    if(2 <= DEBUG_LEVEL) fputs("Starting setup_env\n", stderr);
    char* ARCH;
    if(NULL != Architecture)
    {
        ARCH = Architecture;
    }
    else
    {
        ARCH = NULL;
        struct utsname* unameData = get_uname_data();

        if(match("i386", unameData->machine) ||
           match("i486", unameData->machine) ||
           match("i586", unameData->machine) ||
           match("i686", unameData->machine) ||
           match("i686-pae", unameData->machine)) ARCH = "x86";
        else if(match("x86_64", unameData->machine)) ARCH = "amd64";
        else ARCH = unameData->machine;
        if(3 <= DEBUG_LEVEL)
        {
            fputs("Architecture selected: ", stderr);
            fputs(ARCH, stderr);
            fputc('\n', stderr);
        }

        /* Check for override */
        char* hold = env_lookup("ARCHITECTURE_OVERRIDE");
        if(NULL != hold)
        {
            ARCH = hold;
            if(3 <= DEBUG_LEVEL)
            {
                fputs("environmental override for ARCH: ", stderr);
                fputs(ARCH, stderr);
                fputc('\n', stderr);
            }
        }
        free(unameData);
    }


    /* Set desired architecture */
    WORDSIZE = 32;
    ENDIAN = FALSE;
    BASEADDRESS = "0x0";
    if(match("knight-native", ARCH))
    {
        if(4 <= DEBUG_LEVEL) fputs("Using knight-native architecture\n", stderr);
        ENDIAN = TRUE;
        Architecture = "knight-native";
    }
    else if(match("knight-posix", ARCH))
    {
        if(4 <= DEBUG_LEVEL) fputs("Using knight-posix architecture\n", stderr);
        ENDIAN = TRUE;
        Architecture = "knight-posix";
    }
    else if(match("x86", ARCH))
    {
        if(4 <= DEBUG_LEVEL) fputs("Using x86 architecture\n", stderr);
        BASEADDRESS = "0x8048000";
        Architecture = "x86";
        init_macro_env("__i386__", "1", "--architecture", 0);
    }
    else if(match("amd64", ARCH))
    {
        if(4 <= DEBUG_LEVEL) fputs("Using amd64 architecture\n", stderr);
        BASEADDRESS = "0x00600000";
        Architecture = "amd64";
        WORDSIZE = 64;
        init_macro_env("__x86_64__", "1", "--architecture", 0);
    }
    else if(match("armv7l", ARCH))
    {
        if(4 <= DEBUG_LEVEL) fputs("Using armv7l architecture\n", stderr);
        BASEADDRESS = "0x10000";
        Architecture = "armv7l";
        init_macro_env("__arm__", "1", "--architecture", 0);
    }
    else if(match("aarch64", ARCH))
    {
        if(4 <= DEBUG_LEVEL) fputs("Using aarch64 architecture\n", stderr);
        BASEADDRESS = "0x400000";
        Architecture = "aarch64";
        WORDSIZE = 64;
        init_macro_env("__aarch64__", "1", "--architecture", 0);
    }
    else if(match("riscv32", ARCH))
    {
        if(4 <= DEBUG_LEVEL) fputs("Using riscv32 architecture\n", stderr);
        BASEADDRESS = "0x600000";
        Architecture = "riscv32";
        init_macro_env("__riscv", "1", "--architecture", 0);
        init_macro_env("__riscv_xlen", "32", "--architecture", 1);
    }
    else if(match("riscv64", ARCH))
    {
        if(4 <= DEBUG_LEVEL) fputs("Using riscv64 architecture\n", stderr);
        BASEADDRESS = "0x600000";
        Architecture = "riscv64";
        WORDSIZE = 64;
        init_macro_env("__riscv", "1", "--architecture", 0);
        init_macro_env("__riscv_xlen", "64", "--architecture", 1);
    }
    else
    {
        fputs("Unknown architecture: ", stderr);
        fputs(ARCH, stderr);
        fputs(" know values are: knight-native, knight-posix, x86, amd64, armv7l, aarch64, riscv32 and riscv64\n", stderr);
        exit(EXIT_FAILURE);
    }


    /* Setup Operating System */
    if(NULL == OperatingSystem)
    {
        OperatingSystem = "Linux";
        if(3 <= DEBUG_LEVEL)
        {
            fputs("Operating System selected: ", stderr);
            fputs(OperatingSystem, stderr);
            fputc('\n', stderr);
        }

        /* Check for override */
        char* hold = env_lookup("OS_OVERRIDE");
        if(NULL != hold)
        {
            OperatingSystem = hold;
            if(3 <= DEBUG_LEVEL)
            {
                fputs("environmental override for OS: ", stderr);
                fputs(OperatingSystem, stderr);
                fputc('\n', stderr);
            }
        }
    }

    if(match("UEFI", OperatingSystem))
    {
        if(4 <= DEBUG_LEVEL) fputs("Using UEFI\n", stderr);
        BASEADDRESS = "0x0";
        OperatingSystem = "UEFI";
        init_macro_env("__uefi__", "1", "--os", 0);
    }

    if(2 <= DEBUG_LEVEL) fputs("setup_env successful\n", stderr);
}

struct Token
{
    /*
     * For the token linked-list, this stores the token; for the env linked-list
     * this stores the value of the variable.
     */
    char* value;
    /*
     * Used only for the env linked-list. It holds a string containing the
     * name of the var.
     */
    char* var;
    /*
     * This struct stores a node of a singly linked list, store the pointer to
     * the next node.
     */
    struct Token* next;
};

struct Token* env;

int array_length(char** array)
{
    int length = 0;

    while(array[length] != NULL)
    {
        length = length + 1;
    }

    return length;
}

/* Search for a variable in the token linked-list */
char* token_lookup(char* variable, struct Token* token)
{
    if(6 <= DEBUG_LEVEL)
    {
        fputs("in token_lookup\nLooking for: ", stderr);
        fputs(variable, stderr);
        fputc('\n', stderr);
    }
    /* Start at the head */
    struct Token* n = token;

    /* Loop over the linked-list */
    while(n != NULL)
    {
        if(15 <= DEBUG_LEVEL)
        {
            fputs(n->var, stderr);
            fputc('\n', stderr);
        }
        if(match(variable, n->var))
        {
            if(6 <= DEBUG_LEVEL) fputs("match found in token_lookup\n", stderr);
            /* We have found the correct node */
            return n->value; /* Done */
        }

        /* Nope, try the next */
        n = n->next;
    }

    /* We didn't find anything! */
    return NULL;
}

/* Search for a variable in the env linked-list */
char* env_lookup(char* variable)
{
    return token_lookup(variable, env);
}

char* envp_hold;
int envp_index;

void reset_envp_hold()
{
    clear_string(envp_hold);
    envp_index = 0;
}

void push_env_byte(int c)
{
    envp_hold[envp_index] = c;
    envp_index = envp_index + 1;
    require(4096 > envp_index, "Token exceeded 4096 char envp limit\n");
}

struct Token* process_env_variable(char* envp_line, struct Token* n)
{
    struct Token* node = calloc(1, sizeof(struct Token));
    require(node != NULL, "Memory initialization of node failed\n");
    reset_envp_hold();
    int i = 0;

    while(envp_line[i] != '=')
    {
        /* Copy over everything up to = to var */
        push_env_byte(envp_line[i]);
        i = i + 1;
    }

    node->var = calloc(i + 2, sizeof(char));
    require(node->var != NULL, "Memory initialization of n->var in population of env failed\n");
    strcpy(node->var, envp_hold);

    i = i + 1; /* Skip over = */

    reset_envp_hold();
    while(envp_line[i] != 0)
    {
        /* Copy everything else to value */
        push_env_byte(envp_line[i]);
        i = i + 1;
    }

    /* Sometimes, we get lines like VAR=, indicating nothing is in the variable */
    if(0 == strlen(envp_hold))
    {
        node->value = "";
    }
    else
    {
        /* but looks like we got something so, lets use it */
        node->value = calloc(strlen(envp_hold) + 2, sizeof(char));
        require(node->value != NULL, "Memory initialization of n->var in population of env failed\n");
        strcpy(node->value, envp_hold);
    }

    node->next = n;
    return node;
}

void populate_env(char** envp)
{
    if(2 <= DEBUG_LEVEL) fputs("populate_env started\n", stderr);
    /* You can't populate a NULL environment */
    if(NULL == envp)
    {
        if(3 <= DEBUG_LEVEL) fputs("NULL envp\n", stderr);
        return;
    }

    /* avoid empty arrays */
    int max = array_length(envp);

    if(0 == max)
    {
        if(3 <= DEBUG_LEVEL) fputs("Empty envp\n", stderr);
        return;
    }

    /* Initialize env and n */
    env = NULL;
    int i;
    envp_hold = calloc(4096, sizeof(char));
    require(envp_hold != NULL, "Memory initialization of envp_hold in population of env failed\n");
    char* envp_line = calloc(4096, sizeof(char));
    require(envp_line != NULL, "Memory initialization of envp_line in population of env failed\n");

    if(3 <= DEBUG_LEVEL) fputs("starting env loop\n", stderr);
    for(i = 0; i < max; i = i + 1)
    {
        /*
         * envp is weird.
         * When referencing envp[i]'s characters directly, they were all jumbled.
         * So just copy envp[i] to envp_line, and work with that - that seems
         * to fix it.
         */
        clear_string(envp_line);
        require(4096 > strlen(envp[i]), "envp line exceeds 4096byte limit\n");
        strcpy(envp_line, envp[i]);

        if(9 <= DEBUG_LEVEL)
        {
            fputs("trying envp_line: ", stderr);
            fputs(envp_line, stderr);
            fputc('\n', stderr);
        }

        env = process_env_variable(envp_line, env);

        if(9 <= DEBUG_LEVEL)
        {
            fputs("got var of: ", stderr);
            fputs(env->var, stderr);
            fputs("\nAnd value of: ", stderr);
            fputs(env->value, stderr);
            fputc('\n', stderr);
        }
    }

    free(envp_line);
    free(envp_hold);
    if(3 <= DEBUG_LEVEL)
    {
        fputs("\n\nenv loop successful\n", stderr);
        fputs(int2str(i, 10, FALSE), stderr);
        fputs(" envp records processed\n\n", stderr);
    }

    require(NULL != env, "can't have an empty environment from the creation of a non-null environment\n");
    if(2 <= DEBUG_LEVEL) fputs("populate_env successful\n", stderr);
}

https://github.com/oriansj/M2-Mesoplanet/blob/main/cc_reader.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/M2-Mesoplanet/cc_reader.c used in: Step 49
/* Copyright (C) 2016 Jeremiah Orians
 * Copyright (C) 2021 Andrius Å tikonas <andrius@stikonas.eu>
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "cc.h"
char* env_lookup(char* variable);
char* int2str(int x, int base, int signed_p);

struct visited
{
    struct visited* prev;
    char* name;
};

/* Globals */
FILE* input;
struct token_list* token;
int line;
char* file;
struct visited* vision;

int previously_seen(char* s)
{
    struct visited* v = vision;
    while(NULL != v)
    {
        if(match(v->name, s)) return TRUE;
        v = v->prev;
    }
    return FALSE;
}

void just_seen(char* s)
{
    struct visited* hold = calloc(1, sizeof(struct visited));
    hold->prev = vision;
    hold->name = s;
    vision = hold;
}

int grab_byte()
{
    int c = fgetc(input);
    if(10 == c) line = line + 1;
    return c;
}

void push_byte(int c)
{
    hold_string[string_index] = c;
    string_index = string_index + 1;
    require(MAX_STRING > string_index, "Token exceeded MAX_STRING char limit\nuse --max-string number to increase\n");
}

int consume_byte(int c)
{
    push_byte(c);
    return grab_byte();
}

int preserve_string(int c)
{
    int frequent = c;
    int escape = FALSE;
    do
    {
        if(!escape && '\\' == c ) escape = TRUE;
        else escape = FALSE;
        c = consume_byte(c);
        require(EOF != c, "Unterminated string\n");
    } while(escape || (c != frequent));
    c = consume_byte(frequent);
    return c;
}


void copy_string(char* target, char* source, int max)
{
    int i = 0;
    while(0 != source[i])
    {
        target[i] = source[i];
        i = i + 1;
        if(i == max) break;
    }
}


int preserve_keyword(int c, char* S)
{
    while(in_set(c, S))
    {
        c = consume_byte(c);
    }
    return c;
}

void clear_string(char* s)
{
    int i = 0;
    while(0 != s[i])
    {
        s[i] = 0;
        i = i + 1;
        require(i < MAX_STRING, "string exceeded max string size while clearing string\n");
    }
}

void reset_hold_string()
{
    clear_string(hold_string);
    string_index = 0;
}


/* note if this is the first token in the list, head needs fixing up */
struct token_list* eat_token(struct token_list* token)
{
    if(NULL != token->prev)
    {
        token->prev->next = token->next;
    }

    /* update backlinks */
    if(NULL != token->next)
    {
        token->next->prev = token->prev;
    }

    return token->next;
}


void new_token(char* s, int size)
{
    struct token_list* current = calloc(1, sizeof(struct token_list));
    require(NULL != current, "Exhausted memory while getting token\n");

    /* More efficiently allocate memory for string */
    current->s = calloc(size, sizeof(char));
    require(NULL != current->s, "Exhausted memory while trying to copy a token\n");
    copy_string(current->s, s, MAX_STRING);

    current->prev = token;
    current->next = token;
    current->linenumber = line;
    current->filename = file;
    token = current;
}

int get_token(int c)
{
    reset_hold_string();

    if(c == EOF)
    {
        return c;
    }
    else if((32 == c) || (9 == c) || (c == '\n'))
    {
        c = consume_byte(c);
    }
    else if('#' == c)
    {
        c = consume_byte(c);
        c = preserve_keyword(c, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_");
    }
    else if(in_set(c, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"))
    {
        c = preserve_keyword(c, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_:");
    }
    else if(in_set(c, "<=>|&!^%"))
    {
        c = preserve_keyword(c, "<=>|&!^%");
    }
    else if(in_set(c, "'\""))
    {
        c = preserve_string(c);
    }
    else if(c == '/')
    {
        c = consume_byte(c);
        if(c == '*')
        {
            c = consume_byte(c);
            while(c != '/')
            {
                while(c != '*')
                {
                    c = consume_byte(c);
                    require(EOF != c, "Hit EOF inside of block comment\n");
                }
                c = consume_byte(c);
                require(EOF != c, "Hit EOF inside of block comment\n");
            }
            c = consume_byte(c);
        }
        else if(c == '/')
        {
            while(c != '\n')
            {
                c = consume_byte(c);
                require(EOF != c, "Hit EOF inside of line comment\n");
            }
            c = consume_byte(c);
        }
        else if(c == '=')
        {
            c = consume_byte(c);
        }
    }
    else if(c == '*')
    {
        c = consume_byte(c);
        if(c == '=')
        {
            c = consume_byte(c);
        }
    }
    else if(c == '+')
    {
        c = consume_byte(c);
        if(c == '=')
        {
            c = consume_byte(c);
        }
        if(c == '+')
        {
            c = consume_byte(c);
        }
    }
    else if(c == '-')
    {
        c = consume_byte(c);
        if(c == '=')
        {
            c = consume_byte(c);
        }
        if(c == '>')
        {
            c = consume_byte(c);
        }
        if(c == '-')
        {
            c = consume_byte(c);
        }
    }
    else
    {
        c = consume_byte(c);
    }

    return c;
}

struct token_list* reverse_list(struct token_list* head)
{
    struct token_list* root = NULL;
    struct token_list* next;
    while(NULL != head)
    {
        next = head->next;
        head->next = root;
        root = head;
        head = next;
    }
    return root;
}

int read_include(int c)
{
    reset_hold_string();
    int done = FALSE;
    int ch;

    while(!done)
    {
        if(c == EOF)
        {
            fputs("we don't support EOF as a filename in #include statements\n", stderr);
            exit(EXIT_FAILURE);
        }
        else if((32 == c) || (9 == c) || (c == '\n'))
        {
            c = grab_byte();
        }
        else if(('"' == c) || ('<' == c))
        {
            if('<' == c) c = '>';
            ch = c;
            do
            {
                c = consume_byte(c);
                require(EOF != c, "Unterminated filename in #include\n");
            } while(c != ch);
            if('>' == ch) hold_string[0] = '<';
            done = TRUE;
        }
    }

    return c;
}

void insert_file_header(char* name, int line)
{
    char* hold_line = int2str(line, 10, FALSE);
    reset_hold_string();
    strcat(hold_string, "// #FILENAME ");
    strcat(hold_string, name);
    strcat(hold_string, " ");
    strcat(hold_string, hold_line);
    new_token(hold_string, strlen(hold_string)+2);
    new_token("\n", 3);
}

struct token_list* read_all_tokens(FILE* a, struct token_list* current, char* filename, int include);
int include_file(int ch, int include_file)
{
    /* The old state to restore to */
    char* hold_filename = file;
    FILE* hold_input = input;
    int hold_number;

    /* The new file to load */
    char* new_filename;
    FILE* new_file;

    require(EOF != ch, "#include failed to receive filename\n");
    /* Remove the #include */
    token = token->next;

    /* Get new filename */
    read_include(ch);
    /* with just a little extra to put in the matching at the end */
    new_token(hold_string, string_index + 3);

    ch = '\n';
    new_filename = token->s;
    /* Remove name from stream */
    token = token->next;

    /* Try to open the file */
    if('<' == new_filename[0])
    {
        if(match("stdio.h", new_filename + 1)) STDIO_USED = TRUE;
        reset_hold_string();
        strcat(hold_string, M2LIBC_PATH);
        strcat(hold_string, "/");
        strcat(hold_string, new_filename + 1);
        strcat(new_filename, ">");
        new_file = fopen(hold_string, "r");
    }
    else
    {
        if(match("M2libc/bootstrappable.h", new_filename+1))
        {
            reset_hold_string();
            strcat(hold_string, M2LIBC_PATH);
            strcat(hold_string, "/bootstrappable.h");
            new_file = fopen(hold_string, "r");
        }
        else new_file = fopen(new_filename+1, "r");

        strcat(new_filename, "\"");
    }

    /* prevent multiple visits */
    if(previously_seen(new_filename)) return ch;
    just_seen(new_filename);

    /* special case this compatibility crap */
    if(match("\"../gcc_req.h\"", new_filename) || match("\"gcc_req.h\"", new_filename)) return ch;

    if(include_file)
    {
        fputs("reading file: ", stderr);
        fputs(new_filename, stderr);
        fputc('\n', stderr);
    }

    /* catch garbage input */
    if(NULL == new_file)
    {
        fputs("unable to read file: ", stderr);
        fputs(new_filename, stderr);
        fputs("\nAborting hard!\n", stderr);
        exit(EXIT_FAILURE);
    }

    /* protect our current line number */
    hold_number = line + 1;

    /* Read the new file */
    if(include_file) read_all_tokens(new_file, token, new_filename, include_file);

    /* put back old file info */
    insert_file_header(hold_filename, hold_number);

    /* resume reading old file */
    input = hold_input;
    line = hold_number;
    file = hold_filename;
    return ch;
}

struct token_list* read_all_tokens(FILE* a, struct token_list* current, char* filename, int include)
{
    token = current;
    insert_file_header(filename, 1);
    input  = a;
    line = 1;
    file = filename;
    int ch = grab_byte();
    while(EOF != ch)
    {
        ch = get_token(ch);
        new_token(hold_string, string_index + 2);
        if(match("#include", token->s)) ch = include_file(ch, include);
    }

    return token;
}

https://github.com/oriansj/M2-Mesoplanet/blob/main/cc_spawn.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/M2-Mesoplanet/cc_spawn.c used in: Step 49
/* Copyright (C) 2016 Jeremiah Orians
 * Copyright (C) 2020 deesix <deesix@tuta.io>
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */

#include"cc.h"
#include <unistd.h>
#include <sys/wait.h>
#define MAX_ARRAY 256

char* env_lookup(char* variable);

/* Function to find a character in a string */
char* find_char(char* string, char a)
{
    if(0 == string[0])
    {
        return NULL;
    }

    while(a != string[0])
    {
        string = string + 1;

        if(0 == string[0])
        {
            return string;
        }
    }

    return string;
}

/* Find the full path to an executable */
char* find_executable(char* name)
{
    char* PATH = env_lookup("PATH");
    require(NULL != PATH, "No PATH found\nAborting\n");
    if(match("", name))
    {
        return NULL;
    }

    if(('.' == name[0]) || ('/' == name[0]))
    {
        /* assume names that start with . or / are relative or absolute */
        return name;
    }

    char* trial = calloc(MAX_STRING, sizeof(char));
    char* MPATH = calloc(MAX_STRING, sizeof(char)); /* Modified PATH */
    require(MPATH != NULL, "Memory initialization of MPATH in find_executable failed\n");
    strcpy(MPATH, PATH);
    FILE* t;
    char* next = find_char(MPATH, ':');
    int index;
    int offset;
    int mpath_length;
    int name_length;
    int trial_length;

    while(NULL != next)
    {
        /* Reset trial */
        trial_length = strlen(trial);

        for(index = 0; index < trial_length; index = index + 1)
        {
            trial[index] = 0;
        }

        next[0] = 0;
        /* prepend_string(MPATH, prepend_string("/", name)) */
        mpath_length = strlen(MPATH);

        for(index = 0; index < mpath_length; index = index + 1)
        {
            require(MAX_STRING > index, "Element of PATH is too long\n");
            trial[index] = MPATH[index];
        }

        trial[index] = '/';
        offset = strlen(trial);
        name_length = strlen(name);

        for(index = 0; index < name_length; index = index + 1)
        {
            require(MAX_STRING > index, "Element of PATH is too long\n");
            trial[index + offset] = name[index];
        }

        /* Try the trial */
        trial_length = strlen(trial);
        require(trial_length < MAX_STRING, "COMMAND TOO LONG!\nABORTING HARD\n");
        t = fopen(trial, "r");

        if(NULL != t)
        {
            fclose(t);
            return trial;
        }

        MPATH = next + 1;
        next = find_char(MPATH, ':');
    }

    return NULL;
}

void sanity_command_check(char** array)
{
    int i = 0;
    char* s = array[0];
    while(NULL != s)
    {
        fputs(s, stderr);
        fputc(' ', stderr);
        i = i + 1;
        s = array[i];
    }
    fputc('\n', stderr);
}


int what_exit(char* program, int status)
{
    /***********************************************************************************
     * If the low-order 8 bits of w_status are equal to 0x7F or zero, the child        *
     * process has stopped. If the low-order 8 bits of w_status are non-zero and are   *
     * not equal to 0x7F, the child process terminated due to a signal otherwise, the  *
     * child process terminated due to an exit() call.                                 *
     *                                                                                 *
     * In the event it was a signal that stopped the process the top 8 bits of         *
     * w_status contain the signal that caused the process to stop.                    *
     *                                                                                 *
     * In the event it was terminated the bottom 7 bits of w_status contain the        *
     * terminating error number for the process.                                       *
     *                                                                                 *
     * If bit 0x80 of w_status is set, a core dump was produced.                       *
     ***********************************************************************************/

    if(DEBUG_LEVEL > 6)
    {
        fputs("in what_exit with char* program of: ", stderr);
        fputs(program, stderr);
        fputs("\nAnd int status of: 0x", stderr);
        fputs(int2str(status, 16, FALSE), stderr);
        fputc('\n', stderr);
    }

    int WIFEXITED = !(status & 0x7F);
    int WEXITSTATUS = (status & 0xFF00) >> 8;
    int WTERMSIG = status & 0x7F;
    int WCOREDUMP = status & 0x80;
    int WIFSIGNALED = !((0x7F == WTERMSIG) || (0 == WTERMSIG));
    int WIFSTOPPED = ((0x7F == WTERMSIG) && (0 == WCOREDUMP));

    if(WIFEXITED)
    {
        if(DEBUG_LEVEL > 2)
        {
            fputc('\n', stderr);
            fputs(program, stderr);
            fputs(" normal termination, exit status = ", stderr);
            fputs(int2str(WEXITSTATUS, 10, TRUE), stderr);
            fputc('\n', stderr);
        }
        return WEXITSTATUS;
    }
    else if (WIFSIGNALED)
    {
        fputc('\n', stderr);
        fputs(program, stderr);
        fputs(" abnormal termination, signal number = ", stderr);
        fputs(int2str(WTERMSIG, 10, TRUE), stderr);
        fputc('\n', stderr);
        if(WCOREDUMP) fputs("core dumped\n", stderr);
        return WTERMSIG;
    }
    else if(WIFSTOPPED)
    {
        fputc('\n', stderr);
        fputs(program, stderr);
        fputs(" child stopped, signal number = ", stderr);
        fputs(int2str(WEXITSTATUS, 10, TRUE), stderr);
        fputc('\n', stderr);
        return WEXITSTATUS;
    }

    fputc('\n', stderr);
    fputs(program, stderr);
    fputs(" :: something crazy happened with execve\nI'm just gonna get the hell out of here\n", stderr);
    exit(EXIT_FAILURE);
}


void _execute(char* name, char** array, char** envp)
{
    int status; /* i.e. return code */
    /* Get the full path to the executable */
    char* program = find_executable(name);

    /* Check we can find the executable */
    if(NULL == program)
    {
        fputs("WHILE EXECUTING ", stderr);
        fputs(name, stderr);
        fputs(" NOT FOUND!\nABORTING HARD\n", stderr);
        exit(EXIT_FAILURE);
    }

    sanity_command_check(array);

    int result;
#ifdef __uefi__
    result = spawn(program, array, envp);
#else
    int f = fork();

    /* Ensure fork succeeded */
    if(f == -1)
    {
        fputs("WHILE EXECUTING ", stderr);
        fputs(name, stderr);
        fputs("fork() FAILED\nABORTING HARD\n", stderr);
        exit(EXIT_FAILURE);
    }
    else if(f == 0)
    {
        /* Child */
        /**************************************************************
         * Fuzzing produces random stuff; we don't want it running    *
         * dangerous commands. So we just don't execve.               *
         **************************************************************/
        if(FALSE == FUZZING)
        {
            /* We are not fuzzing */
            /* execve() returns only on error */
            execve(program, array, envp);
            fputs("Unable to execute: ", stderr);
            fputs(program, stderr);
            fputs("\nPlease check file permissions and that it is a valid binary\n", stderr);
        }

        /* Prevent infinite loops */
        _exit(EXIT_FAILURE);
    }

    /* Otherwise we are the parent */
    /* And we should wait for it to complete */
    waitpid(f, &status, 0);

    result = what_exit(program, status);
#endif
    if(0 != result)
    {
        fputs("Subprocess: ", stderr);
        fputs(program, stderr);
        fputs(" error\nAborting for safety\n", stderr);
        exit(result);
    }
}

void insert_array(char** array, int index, char* string)
{
    int size = strlen(string);
    array[index] = calloc(size+2, sizeof(char));
    strcpy(array[index], string);
}


void spawn_hex2(char* input, char* output, char* architecture, char** envp, int debug)
{
    char* hex2;
#ifdef __uefi__
    hex2 = "hex2.efi";
#else
    hex2 = "hex2";
#endif

    char* elf_header = calloc(MAX_STRING, sizeof(char));
    elf_header = strcat(elf_header, M2LIBC_PATH);
    elf_header = strcat(elf_header, "/");
    elf_header = strcat(elf_header, architecture);
    if(match("UEFI", OperatingSystem)) elf_header = strcat(elf_header, "/uefi/PE32-");
    else elf_header = strcat(elf_header, "/ELF-");
    elf_header = strcat(elf_header, architecture);
    if(debug)
    {
        elf_header = strcat(elf_header, "-debug.hex2");
    }
    else
    {
        elf_header = strcat(elf_header, ".hex2");
    }

    fputs("# starting hex2 linking\n", stdout);
    char** array = calloc(MAX_ARRAY, sizeof(char*));
    insert_array(array, 0, hex2);
    insert_array(array, 1, "--file");
    insert_array(array, 2, elf_header);
    insert_array(array, 3, "--file");
    insert_array(array, 4, input);
    insert_array(array, 5, "--output");
    insert_array(array, 6, output);
    insert_array(array, 7, "--architecture");
    insert_array(array, 8, architecture);
    insert_array(array, 9, "--base-address");
    insert_array(array, 10, BASEADDRESS);
    if(ENDIAN)
    {
        insert_array(array, 11, "--big-endian");
    }
    else
    {
        insert_array(array, 11, "--little-endian");
    }
    _execute(hex2, array, envp);
}


void spawn_M1(char* input, char* debug_file, char* output, char* architecture, char** envp, int debug_flag)
{
    char* M1;
#ifdef __uefi__
    M1 = "M1.efi";
#else
    M1 = "M1";
#endif

    fputs("# starting M1 assembly\n", stdout);
    char* definitions = calloc(MAX_STRING, sizeof(char));
    definitions = strcat(definitions, M2LIBC_PATH);
    definitions = strcat(definitions, "/");
    definitions = strcat(definitions, architecture);
    definitions = strcat(definitions, "/");
    definitions = strcat(definitions, architecture);
    definitions = strcat(definitions, "_defs.M1");

    char* libc = calloc(MAX_STRING, sizeof(char));
    libc = strcat(libc, M2LIBC_PATH);
    libc = strcat(libc, "/");
    libc = strcat(libc, architecture);

    if(match("UEFI", OperatingSystem))
    {
        libc = strcat(libc, "/uefi/libc-full.M1");
    }
    else if(STDIO_USED)
    {
        libc = strcat(libc, "/libc-full.M1");
    }
    else
    {
        libc = strcat(libc, "/libc-core.M1");
    }

    char** array = calloc(MAX_ARRAY, sizeof(char*));
    insert_array(array, 0, M1);
    insert_array(array, 1, "--file");
    insert_array(array, 2, definitions);
    insert_array(array, 3, "--file");
    insert_array(array, 4, libc);
    insert_array(array, 5, "--file");
    insert_array(array, 6, input);
    if(ENDIAN)
    {
        insert_array(array, 7, "--big-endian");
    }
    else
    {
        insert_array(array, 7, "--little-endian");
    }
    insert_array(array, 8, "--architecture");
    insert_array(array, 9, architecture);

    if(debug_flag)
    {
        insert_array(array, 10, "--file");
        insert_array(array, 11, debug_file);
        insert_array(array, 12, "--output");
        insert_array(array, 13, output);
    }
    else
    {
        insert_array(array, 10, "--output");
        insert_array(array, 11, output);
    }
    _execute(M1, array, envp);
}


void spawn_blood_elf(char* input, char* output, char** envp, int large_flag)
{
    char* blood_elf;
#ifdef __uefi__
    blood_elf = "blood-elf.efi";
#else
    blood_elf = "blood-elf";
#endif

    fputs("# starting Blood-elf stub generation\n", stdout);
    char** array = calloc(MAX_ARRAY, sizeof(char*));
    insert_array(array, 0,blood_elf);
    insert_array(array, 1, "--file");
    insert_array(array, 2, input);
    if(ENDIAN)
    {
        insert_array(array, 3, "--big-endian");
    }
    else
    {
        insert_array(array, 3, "--little-endian");
    }
    insert_array(array, 4, "--output");
    insert_array(array, 5, output);
    if(large_flag) insert_array(array, 6, "--64");
    _execute(blood_elf, array, envp);
}

void spawn_M2(char* input, char* output, char* architecture, char** envp, int debug_flag)
{
    char* M2_Planet;
#ifdef __uefi__
    M2_Planet = "M2-Planet.efi";
#else
    M2_Planet = "M2-Planet";
#endif

    fputs("# starting M2-Planet build\n", stdout);
    char** array = calloc(MAX_ARRAY, sizeof(char*));
    insert_array(array, 0, M2_Planet);
    insert_array(array, 1, "--file");
    insert_array(array, 2, input);
    insert_array(array, 3, "--output");
    insert_array(array, 4, output);
    insert_array(array, 5, "--architecture");
    insert_array(array, 6, architecture);
    if(debug_flag) insert_array(array, 7, "--debug");
    _execute(M2_Planet, array, envp);
}

void spawn_processes(int debug_flag, char* prefix, char* preprocessed_file, char* destination, char** envp)
{
    int large_flag = FALSE;
    if(WORDSIZE > 32) large_flag = TRUE;

    if(match("UEFI", OperatingSystem))
    {
        debug_flag = FALSE;
    }

    char* M2_output = calloc(100, sizeof(char));
    strcpy(M2_output, prefix);
    strcat(M2_output, "/M2-Planet-XXXXXX");
    int i = mkstemp(M2_output);
    if(-1 != i)
    {
        close(i);
        spawn_M2(preprocessed_file, M2_output, Architecture, envp, debug_flag);
    }
    else
    {
        fputs("unable to get a tempfile for M2-Planet output\n", stderr);
        exit(EXIT_FAILURE);
    }

    char* blood_output = "";
    if(debug_flag)
    {
        blood_output = calloc(100, sizeof(char));
        strcpy(blood_output, prefix);
        strcat(blood_output, "/blood-elf-XXXXXX");
        i = mkstemp(blood_output);
        if(-1 != i)
        {
            close(i);
            spawn_blood_elf(M2_output, blood_output, envp, large_flag);
        }
        else
        {
            fputs("unable to get a tempfile for blood-elf output\n", stderr);
            exit(EXIT_FAILURE);
        }
    }

    char* M1_output = calloc(100, sizeof(char));
    strcpy(M1_output, prefix);
    strcat(M1_output, "/M1-macro-XXXXXX");
    i = mkstemp(M1_output);
    if(-1 != i)
    {
        close(i);
        spawn_M1(M2_output, blood_output, M1_output, Architecture, envp, debug_flag);
    }
    else
    {
        fputs("unable to get a tempfile for M1 output\n", stderr);
        exit(EXIT_FAILURE);
    }

    /* We no longer need the M2-Planet tempfile output */
    if(!DIRTY_MODE) remove(M2_output);
    /* Nor the blood-elf output anymore if it exists */
    if(!match("", blood_output))
    {
        if(!DIRTY_MODE) remove(blood_output);
    }

    /* Build the final binary */
    spawn_hex2(M1_output, destination, Architecture, envp, debug_flag);

    /* clean up after ourselves*/
    if(!DIRTY_MODE) remove(M1_output);
}

https://github.com/oriansj/M2-Mesoplanet/blob/main/cc_core.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/M2-Mesoplanet/cc_core.c used in: Step 49
/* Copyright (C) 2016 Jeremiah Orians
 * Copyright (C) 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 * Copyright (C) 2020 deesix <deesix@tuta.io>
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "cc.h"
#include "gcc_req.h"
#include <stdint.h>

/* Imported functions */
char* int2str(int x, int base, int signed_p);

void line_error_token(struct token_list *token)
{
    if(NULL == token)
    {
        fputs("EOF reached inside of line_error\n", stderr);
        fputs("problem at end of file\n", stderr);
        return;
    }
    fputs(token->filename, stderr);
    fputs(":", stderr);
    fputs(int2str(token->linenumber, 10, TRUE), stderr);
    fputs(":", stderr);
}

void line_error()
{
    line_error_token(global_token);
}

void require_match(char* message, char* required)
{
    require(NULL != global_token, "EOF reached inside of require match\n");
    if(!match(global_token->s, required))
    {
        line_error();
        fputs(message, stderr);
        exit(EXIT_FAILURE);
    }
    global_token = global_token->next;
    require(NULL != global_token, "EOF after require match occurred\n");
}

void output_tokens(struct token_list *i, FILE* out)
{
    while(NULL != i)
    {
        fputs(i->s, out);
        i = i->next;
    }
}

https://github.com/oriansj/M2-Mesoplanet/blob/main/cc_macro.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/M2-Mesoplanet/cc_macro.c used in: Step 49
/* Copyright (C) 2021 Sanne Wouda
 * Copyright (C) 2021 Andrius Å tikonas <andrius@stikonas.eu>
 * Copyright (C) 2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */
#include "cc.h"
#include "gcc_req.h"

void require(int bool, char* error);
int strtoint(char* a);
void line_error_token(struct token_list* list);
struct token_list* eat_token(struct token_list* head);
struct token_list* reverse_list(struct token_list* head);

struct conditional_inclusion
{
    struct conditional_inclusion* prev;
    int include; /* 1 == include, 0 == skip */
    int previous_condition_matched; /* 1 == all subsequent conditions treated as FALSE */
};

struct macro_list
{
    struct macro_list* next;
    char* symbol;
    struct token_list* expansion;
    struct token_list* arguments;
};

struct macro_list* macro_env;
struct conditional_inclusion* conditional_inclusion_top;

/* point where we are currently modifying the global_token list */
struct token_list* macro_token;

void init_macro_env(char* sym, char* value, char* source, int num)
{
    struct macro_list* hold = macro_env;
    macro_env = calloc(1, sizeof(struct macro_list));
    macro_env->symbol = sym;
    macro_env->next = hold;
    macro_env->expansion = calloc(1, sizeof(struct token_list));
    macro_env->expansion->s = value;
    macro_env->expansion->filename = source;
    macro_env->expansion->linenumber = num;
}

void _eat_current_token(int eat_whitespace)
{
    int update_global_token = FALSE;
    if (macro_token == global_token)
        update_global_token = TRUE;

    macro_token = eat_token(macro_token);
    if(eat_whitespace)
    {
        while (macro_token->s[0] == ' ')
        macro_token = eat_token(macro_token);
    }

    if(update_global_token)
        global_token = macro_token;
}

void eat_current_token()
{
    _eat_current_token(TRUE);
}

void eat_current_token_without_space()
{
    _eat_current_token(FALSE);
}

struct token_list* lookup_token(struct token_list* token, struct token_list* arguments)
{
    if(NULL == token)
    {
        fputs("null token received in token\n", stderr);
        exit(EXIT_FAILURE);
    }

    struct token_list* hold = arguments;

    while (NULL != hold)
    {
        if (match(token->s, hold->s))
        {
            /* found! */
            return hold->expansion;
        }

        hold = hold->next;
    }

    /* not found! */
    return NULL;
}

/* returns the first token inserted; inserts *before* point */
struct token_list* insert_tokens(struct token_list* point, struct token_list* token)
{
    struct token_list* copy;
    struct token_list* first = NULL;

    while (NULL != token)
    {
        copy = calloc(1, sizeof(struct token_list));
        copy->s = token->s;
        copy->filename = token->filename;
        copy->linenumber = token->linenumber;

        if(NULL == first)
        {
            first = copy;
        }

        copy->next = point;

        if (NULL != point)
        {
            copy->prev = point->prev;

            if(NULL != point->prev)
            {
                point->prev->next = copy;
            }

            point->prev = copy;
        }

        token = token->next;
    }

    return first;
}

/* returns the first token inserted; inserts *before* point */
struct token_list* copy_list(struct token_list* token)
{
    struct token_list* copy;
    struct token_list* prev = NULL;

    while (NULL != token)
    {
        copy = calloc(1, sizeof(struct token_list));
        copy->s = token->s;

        copy->next = prev;
        copy->prev = prev;
        prev = copy;
        token = token->next;
    }
    copy = reverse_list(copy);

    return copy;
}

struct macro_list* lookup_macro(struct token_list* token)
{
    if(NULL == token)
    {
        line_error_token(macro_token);
        fputs("null token received in lookup_macro\n", stderr);
        exit(EXIT_FAILURE);
    }

    struct macro_list* hold = macro_env;

    while (NULL != hold)
    {
        if (match(token->s, hold->symbol))
        {
            /* found! */
            return hold;
        }

        hold = hold->next;
    }

    /* not found! */
    return NULL;
}

void remove_macro(struct token_list* token)
{
    if(NULL == token)
    {
        line_error_token(macro_token);
        fputs("received a null in remove_macro\n", stderr);
        exit(EXIT_FAILURE);
    }

    struct macro_list* hold = macro_env;
    struct macro_list* temp;

    /* Deal with the first element */
    if (match(token->s, hold->symbol)) {
        macro_env = hold->next;
        free(hold);
        return;
    }

    /* Remove element form the middle of linked list */
    while (NULL != hold->next)
    {
        if (match(token->s, hold->next->symbol))
        {
            temp = hold->next;
            hold->next = hold->next->next;
            free(temp);
            return;
        }

        hold = hold->next;
    }

    /* nothing to undefine */
    return;
}

int macro_expression();
int macro_variable()
{
    int value = 0;
    struct macro_list* hold = lookup_macro(macro_token);
    if (NULL != hold)
    {
        if(NULL == hold->expansion)
        {
            line_error_token(macro_token);
            fputs("hold->expansion is a null\n", stderr);
            exit(EXIT_FAILURE);
        }
        value = strtoint(hold->expansion->s);
    }
    eat_current_token();
    return value;
}

int macro_number()
{
    int result = strtoint(macro_token->s);
    eat_current_token();
    return result;
}

int macro_primary_expr()
{
    int defined_has_paren = FALSE;
    int hold;
    require(NULL != macro_token, "got an EOF terminated macro primary expression\n");

    if('-' == macro_token->s[0])
    {
        eat_current_token();
        return -macro_primary_expr();
    }
    else if('!' == macro_token->s[0])
    {
        eat_current_token();
        return !macro_primary_expr();
    }
    else if('(' == macro_token->s[0])
    {
        eat_current_token();
        hold = macro_expression();
        require(')' == macro_token->s[0], "missing ) in macro expression\n");
        eat_current_token();
        return hold;
    }
    else if(match("defined", macro_token->s))
    {
        eat_current_token();

        require(NULL != macro_token, "got an EOF terminated macro defined expression\n");

        if('(' == macro_token->s[0])
        {
            defined_has_paren = TRUE;
            eat_current_token();
        }

        if (NULL != lookup_macro(macro_token))
        {
            hold = TRUE;
        }
        else
        {
            hold = FALSE;
        }
        eat_current_token();

        if(TRUE == defined_has_paren)
        {
            if(NULL == macro_token)
            {
                line_error_token(macro_token);
                fputs("unterminated define ( statement\n", stderr);
                exit(EXIT_FAILURE);
            }
            require(')' == macro_token->s[0], "missing close parenthesis for defined()\n");
            eat_current_token();
        }

        return hold;
    }
    else if(in_set(macro_token->s[0], "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_"))
    {
        return macro_variable();
    }
    else if(in_set(macro_token->s[0], "0123456789"))
    {
        return macro_number();
    }
    else
    {
        return 0;    /* FIXME: error handling */
    }
}

int macro_additive_expr()
{
    int lhs = macro_primary_expr();
    int hold;

    require(NULL != macro_token, "got an EOF terminated macro additive expression\n");
    if(match("+", macro_token->s))
    {
        eat_current_token();
        return lhs + macro_additive_expr();
    }
    else if(match("-", macro_token->s))
    {
        eat_current_token();
        return lhs - macro_additive_expr();
    }
    else if(match("*", macro_token->s))
    {
        eat_current_token();
        return lhs * macro_additive_expr();
    }
    else if(match("/", macro_token->s))
    {
        eat_current_token();
        hold = macro_additive_expr();
        require(0 != hold, "divide by zero not valid even in C macros\n");
        return lhs / hold;
    }
    else if(match("%", macro_token->s))
    {
        eat_current_token();
        hold = macro_additive_expr();
        require(0 != hold, "modulus by zero not valid even in C macros\n");
        return lhs % hold;
    }
    else if(match(">>", macro_token->s))
    {
        eat_current_token();
        return lhs >> macro_additive_expr();
    }
    else if(match("<<", macro_token->s))
    {
        eat_current_token();
        return lhs << macro_additive_expr();
    }
    else
    {
        return lhs;
    }
}

int macro_relational_expr()
{
    int lhs = macro_additive_expr();

    if(match("<", macro_token->s))
    {
        eat_current_token();
        return lhs < macro_relational_expr();
    }
    else if(match("<=", macro_token->s))
    {
        eat_current_token();
        return lhs <= macro_relational_expr();
    }
    else if(match(">=", macro_token->s))
    {
        eat_current_token();
        return lhs >= macro_relational_expr();
    }
    else if(match(">", macro_token->s))
    {
        eat_current_token();
        return lhs > macro_relational_expr();
    }
    else if(match("==", macro_token->s))
    {
        eat_current_token();
        return lhs == macro_relational_expr();
    }
    else if(match("!=", macro_token->s))
    {
        eat_current_token();
        return lhs != macro_relational_expr();
    }
    else
    {
        return lhs;
    }
}

int macro_bitwise_expr()
{
    int rhs;
    int lhs = macro_relational_expr();

    if(match("&", macro_token->s))
    {
        eat_current_token();
        return lhs & macro_bitwise_expr();
    }
    else if(match("&&", macro_token->s))
    {
        eat_current_token();
        rhs = macro_bitwise_expr();
        return lhs && rhs;
    }
    else if(match("|", macro_token->s))
    {
        eat_current_token();
        rhs = macro_bitwise_expr();
        return lhs | rhs;
    }
    else if(match("||", macro_token->s))
    {
        eat_current_token();
        rhs = macro_bitwise_expr();
        return lhs || rhs;
    }
    else if(match("^", macro_token->s))
    {
        eat_current_token();
        rhs = macro_bitwise_expr();
        return lhs ^ rhs;
    }
    else
    {
        return lhs;
    }
}

int macro_expression()
{
    return macro_bitwise_expr();
}

void handle_define()
{
    struct macro_list* hold;
    struct token_list* arg;
    struct token_list* expansion_end = NULL;

    /* don't use #define statements from non-included blocks */
    int conditional_define = TRUE;
    if(NULL != conditional_inclusion_top)
    {
        if(FALSE == conditional_inclusion_top->include)
        {
            conditional_define = FALSE;
        }
    }

    eat_current_token();

    require(NULL != macro_token, "got an EOF terminated #define\n");
    require('\n' != macro_token->s[0], "unexpected newline after #define\n");

    /* insert new macro */
    hold = calloc(1, sizeof(struct macro_list));
    hold->symbol = macro_token->s;
    hold->next = macro_env;
    /* provided it isn't in a non-included block */
    if(conditional_define) macro_env = hold;

    /* discard the macro name */
    eat_current_token_without_space();

    /* Handle macro arguments */
    if(macro_token->s[0] == '(')
    {
        /* discard ( */
        eat_current_token();
        require(NULL != macro_token, "got an EOF terminated #define\n");
        if(macro_token->s[0] != ')')
        {
            arg = calloc(1, sizeof(struct token_list));
            arg->s = macro_token->s;
            hold->arguments = arg;
            eat_current_token();
            require(NULL != macro_token, "incomplete macro call\n");
            while(macro_token->s[0] == ',')
            {
                eat_current_token();
                require(NULL != macro_token, "incomplete macro call, got an EOF instead of an argument\n");
                arg = calloc(1, sizeof(struct token_list));
                arg->s = macro_token->s;
                arg->next = hold->arguments;
                hold->arguments = arg;
                eat_current_token();
                require(NULL != macro_token, "incomplete macro call\n");
            }
        }
        eat_current_token();

        /* Reverse argument list */
        hold->arguments = reverse_list(hold->arguments);

        require(NULL != macro_token, "got an EOF terminated #define\n");
    }
    else if(macro_token->s[0] == ' ')
    {
        eat_current_token();
    }

    while (TRUE)
    {
        require(NULL != macro_token, "got an EOF terminated #define\n");

        if ('\n' == macro_token->s[0])
        {
            if(NULL == expansion_end)
            {
                hold->expansion = NULL;
                expansion_end = macro_token;
                return;
            }
            expansion_end->next = NULL;
            return;
        }
        else if(('/' == macro_token->s[0]) && ('*' == macro_token->s[1]))
        {
            eat_current_token();
            continue;
        }
        else if(('/' == macro_token->s[0]) && ('/' == macro_token->s[1]))
        {
            macro_token->s = "\n";
            if(NULL == expansion_end)
            {
                hold->expansion = NULL;
                expansion_end = macro_token;
                return;
            }
            expansion_end->next = NULL;
            return;
        }

        if(NULL == hold)
        {
            eat_current_token();
            continue;
        }

        expansion_end = macro_token;

        /* in the first iteration, we set the first token of the expansion, if
           it exists */
        if (NULL == hold->expansion)
        {
            hold->expansion = macro_token;
        }

        /* throw away if not used */
        if(!conditional_define && (NULL != hold))
        {
            free(hold);
            hold = NULL;
        }

        eat_current_token();
    }
}

void handle_undef()
{
    eat_current_token();
    remove_macro(macro_token);
    eat_current_token();
}

void handle_error(int warning_p)
{
    /* don't use #error statements from non-included blocks */
    int conditional_error = TRUE;
    if(NULL != conditional_inclusion_top)
    {
        if(FALSE == conditional_inclusion_top->include)
        {
            conditional_error = FALSE;
        }
    }
    eat_current_token();
    /* provided it isn't in a non-included block */
    if(conditional_error)
    {
        line_error_token(macro_token);
        if(warning_p) fputs(" warning: #warning ", stderr);
        else fputs(" error: #error ", stderr);
        while (TRUE)
        {
            if ('\n' == macro_token->s[0]) break;
            fputs(macro_token->s, stderr);
            macro_token = macro_token->next;
        }
        fputs("\n", stderr);
        if(!warning_p) exit(EXIT_FAILURE);
    }
    while (TRUE)
    {
        /* discard the error */
        if ('\n' == macro_token->s[0])
        {
            return;
        }
        eat_current_token();
    }
}

void macro_directive()
{
    struct conditional_inclusion *t;
    int result;

    /* FIXME: whitespace is allowed between "#"" and "if" */
    if(match("#if", macro_token->s))
    {
        eat_current_token();
        /* evaluate constant integer expression */
        result = macro_expression();
        /* push conditional inclusion */
        t = calloc(1, sizeof(struct conditional_inclusion));
        t->prev = conditional_inclusion_top;
        conditional_inclusion_top = t;
        t->include = TRUE;

        if(FALSE == result)
        {
            t->include = FALSE;
        }

        t->previous_condition_matched = t->include;
    }
    else if(match("#ifdef", macro_token->s))
    {
        eat_current_token();
        require(NULL != macro_token, "got an EOF terminated macro defined expression\n");
        if (NULL != lookup_macro(macro_token))
        {
            result = TRUE;
        }
        else
        {
            result = FALSE;
        }
        eat_current_token();

        /* push conditional inclusion */
        t = calloc(1, sizeof(struct conditional_inclusion));
        t->prev = conditional_inclusion_top;
        conditional_inclusion_top = t;
        t->include = TRUE;

        if(FALSE == result)
        {
            t->include = FALSE;
        }

        t->previous_condition_matched = t->include;
    }
    else if(match("#ifndef", macro_token->s))
    {
        eat_current_token();
        require(NULL != macro_token, "got an EOF terminated macro defined expression\n");
        if (NULL != lookup_macro(macro_token))
        {
            result = FALSE;
        }
        else
        {
            result = TRUE;
        }
        eat_current_token();

        /* push conditional inclusion */
        t = calloc(1, sizeof(struct conditional_inclusion));
        t->prev = conditional_inclusion_top;
        conditional_inclusion_top = t;
        t->include = TRUE;

        if(FALSE == result)
        {
            t->include = FALSE;
        }

        t->previous_condition_matched = t->include;
    }
    else if(match("#elif", macro_token->s))
    {
        eat_current_token();
        result = macro_expression();
        require(NULL != conditional_inclusion_top, "#elif without leading #if\n");
        conditional_inclusion_top->include = result && !conditional_inclusion_top->previous_condition_matched;
        conditional_inclusion_top->previous_condition_matched =
            conditional_inclusion_top->previous_condition_matched || conditional_inclusion_top->include;
    }
    else if(match("#else", macro_token->s))
    {
        eat_current_token();
        require(NULL != conditional_inclusion_top, "#else without leading #if\n");
        conditional_inclusion_top->include = !conditional_inclusion_top->previous_condition_matched;
    }
    else if(match("#endif", macro_token->s))
    {
        if(NULL == conditional_inclusion_top)
        {
            line_error_token(macro_token);
            fputs("unexpected #endif\n", stderr);
            exit(EXIT_FAILURE);
        }

        eat_current_token();
        /* pop conditional inclusion */
        t = conditional_inclusion_top;
        conditional_inclusion_top = conditional_inclusion_top->prev;
        free(t);
    }
    else if(match("#define", macro_token->s))
    {
        handle_define();
    }
    else if(match("#undef", macro_token->s))
    {
        handle_undef();
    }
    else if(match("#error", macro_token->s))
    {
        handle_error(FALSE);
    }
    else if(match("#warning", macro_token->s))
    {
        handle_error(TRUE);
    }
    else if(match("#FILENAME", macro_token->s))
    {
        while(TRUE)
        {
            if(NULL == macro_token)
            {
                return;
            }

            if('\n' == macro_token->s[0])
            {
                return;
            }

            eat_current_token();
        }
    }
    else
    {
        /* Put a big fat warning but see if we can just ignore */
        fputs(">>WARNING<<\n>>WARNING<<\n", stderr);
        line_error_token(macro_token);
        fputs("feature: ", stderr);
        fputs(macro_token->s, stderr);
        fputs(" unsupported in M2-Planet\nIgnoring line, may result in bugs\n>>WARNING<<\n>>WARNING<<\n\n", stderr);

        /* unhandled macro directive; let's eat until a newline; om nom nom */
        while(TRUE)
        {
            if(NULL == macro_token)
            {
                return;
            }

            if('\n' == macro_token->s[0])
            {
                return;
            }

            eat_current_token();
        }
    }
}

struct token_list* expand_macro_functions(struct token_list* expansion, struct token_list* arguments)
{
    struct token_list* expanded_token;
    struct token_list* head;
    struct token_list* hold; /* Same as head unless head == NULL */
    head = copy_list(expansion);
    while(NULL != head)
    {
        expanded_token = lookup_token(head, arguments);
        hold = head;
        if(NULL != expanded_token)
        {
            insert_tokens(head, expanded_token);
            hold = head->prev;
            head = eat_token(head);
        }
        else
        {
            head = head->next;
        }
    }
    while(NULL != hold->prev) hold = hold->prev;
    return hold;
}

void eat_until_endif()
{
    /* This #if block is nested inside of an #if block that needs to be dropped, lose EVERYTHING */
    do
    {
        if(match("#if", macro_token->s) || match("#ifdef", macro_token->s) || match("#ifndef", macro_token->s))
        {
            eat_current_token();
            eat_until_endif();
        }

        eat_current_token();
        require(NULL != macro_token, "Unterminated #if block\n");
    } while(!match("#endif", macro_token->s));
}

void eat_block()
{
    /* This conditional #if block is wrong, drop everything until the #elif/#else/#endif */
    do
    {
        if(match("#if", macro_token->s) || match("#ifdef", macro_token->s) || match("#ifndef", macro_token->s))
        {
            eat_current_token();
            eat_until_endif();
        }

        eat_current_token();
        require(NULL != macro_token, "Unterminated #if block\n");
    } while(!match("#elif", macro_token->s) && !match("#else", macro_token->s) && !match("#endif", macro_token->s));
}

struct token_list* maybe_expand(struct token_list* token)
{
    if(NULL == token)
    {
        line_error_token(macro_token);
        fputs("maybe_expand passed a null token\n", stderr);
        exit(EXIT_FAILURE);
    }

    struct macro_list* hold = lookup_macro(token);
    struct token_list* hold2;
    struct token_list* hold3;
    struct token_list* hold4;
    if(NULL == token->next)
    {
        line_error_token(macro_token);
        fputs("we can't expand a null token: ", stderr);
        fputs(token->s, stderr);
        fputc('\n', stderr);
        exit(EXIT_FAILURE);
    }

    if (NULL == hold)
    {
        return token->next;
    }

    if(match("__M2__", token->s)) return token->next;

    token = eat_token(token);

    if (NULL == hold->expansion)
    {
        return token->next;
    }

    /* Match macro arguments with stored names */
    hold3 = hold->arguments;
    if(NULL != hold3)
    {
        if(token->s[0] == ' ')
        {
            token = eat_token(token);
        }
        require('(' == token->s[0], "missing open parenthesis for macro function\n");
        token = eat_token(token);
        require(NULL != token, "got an EOF terminated macro function\n");
        do
        {
            hold2 = calloc(1, sizeof(struct token_list));
            hold2->s = token->s;
            hold2->next = hold->arguments->expansion;
            hold->arguments->expansion = hold2;
            token = eat_token(token);
            require(NULL != token, "incomplete macro call\n");
            if(token->s[0] == ',')
            {
                hold->arguments->expansion = reverse_list(hold->arguments->expansion);
                hold->arguments = hold->arguments->next;
                require(NULL != hold->arguments, "too many arguments in macro call\n");
                token = eat_token(token);
                require(NULL != token, "incomplete macro call\n");
            }
        } while(token->s[0] != ')');
        hold->arguments->expansion = reverse_list(hold->arguments->expansion);
        hold->arguments = hold3;
        token = eat_token(token);
    }
    hold4 = expand_macro_functions(hold->expansion, hold->arguments);
    hold4 = insert_tokens(token, hold4);

    return hold4;
}

void preprocess()
{
    int start_of_line = TRUE;
    macro_token = global_token;

    while(NULL != macro_token)
    {
        if(start_of_line && '#' == macro_token->s[0])
        {
            macro_directive();

            if(macro_token)
            {
                if('\n' != macro_token->s[0])
                {
                    line_error_token(macro_token);
                    fputs("newline expected at end of macro directive\n", stderr);
                    fputs("found: '", stderr);
                    fputs(macro_token->s, stderr);
                    fputs("'\n", stderr);
                    exit(EXIT_FAILURE);
                }
            }
        }
        else if('\n' == macro_token->s[0])
        {
            start_of_line = TRUE;
            macro_token = macro_token->next;
        }
        else
        {
            start_of_line = FALSE;
            if(NULL == conditional_inclusion_top)
            {
                macro_token = maybe_expand(macro_token);
            }
            else if(!conditional_inclusion_top->include)
            {
                /* rewrite the token stream to exclude the current token */
                eat_block();
                start_of_line = TRUE;
            }
            else
            {
                macro_token = maybe_expand(macro_token);
            }
        }
    }
}

https://github.com/oriansj/M2-Mesoplanet/blob/main/cc.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/M2-Mesoplanet/cc.c used in: Step 49
/* Copyright (C) 2016, 2021 Jeremiah Orians
 * Copyright (C) 2020 deesix <deesix@tuta.io>
 * Copyright (C) 2020 Gabriel Wicki
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */

#include"cc.h"
#include <unistd.h>

/* The core functions */
void populate_env(char** envp);
void setup_env();
char* env_lookup(char* variable);
void initialize_types();
struct token_list* read_all_tokens(FILE* a, struct token_list* current, char* filename, int include);
struct token_list* reverse_list(struct token_list* head);

void init_macro_env(char* sym, char* value, char* source, int num);
void preprocess();
void output_tokens(struct token_list *i, FILE* out);
int strtoint(char *a);
void spawn_processes(int debug_flag, char* prefix, char* preprocessed_file, char* destination, char** envp);

int follow_includes;

void prechecks(int argc, char** argv)
{
    int env = 0;
    char* hold;
    int i = 1;
    while(i <= argc)
    {
        if(NULL == argv[i])
        {
            i += 1;
        }
        else if(match(argv[i], "--debug-mode"))
        {
            hold = argv[i+1];
            require(NULL != hold, "--debug-mode requires an argument\n");
            DEBUG_LEVEL = strtoint(hold);
            if(0 == DEBUG_LEVEL)
            {
                require(match("0", hold), "--debug-mode values must be numbers\n"
                                          "and level 0 needed to be expressed as 0\n");
            }
            fputs("DEBUG_LEVEL set to: ", stderr);
            fputs(hold, stderr);
            fputc('\n', stderr);
            i+= 2;
        }
        else if(match(argv[i], "-A") || match(argv[i], "--architecture"))
        {
            hold = argv[i+1];
            require(NULL != hold, "--architecture needs to be passed an architecture\n");
            Architecture = hold;
            i += 2;
        }
        else if(match(argv[i], "--os") || match(argv[i], "--operating-system"))
        {
            hold = argv[i+1];
            require(NULL != hold, "--operating-system needs to be passed an operating system\n");
            OperatingSystem = hold;
            i += 2;
        }
        else if(match(argv[i], "--max-string"))
        {
            hold = argv[i+1];
            require(NULL != hold, "--max-string requires a numeric argument\n");
            MAX_STRING = strtoint(hold);
            require(0 < MAX_STRING, "Not a valid string size\nAbort and fix your --max-string\n");
            i += 2;
        }
        else if(match(argv[i], "--no-includes"))
        {
            follow_includes = FALSE;
            i+= 1;
        }
        else if(match(argv[i], "-I"))
        {
            hold = argv[i+1];
            if(NULL == hold)
            {
                fputs("-I requires a PATH\n", stderr);
                exit(EXIT_FAILURE);
            }
            if(1 <= DEBUG_LEVEL)
            {
                fputs("M2LIBC_PATH set by -I to ", stderr);
                fputs(hold, stderr);
                fputc('\n', stderr);
            }
            M2LIBC_PATH = hold;
            i += 2;
        }
        else if(match(argv[i], "-D"))
        {
            hold = argv[i+1];
            if(NULL == hold)
            {
                fputs("-D requires an argument", stderr);
                exit(EXIT_FAILURE);
            }
            while(0 != hold[0])
            {
                if('=' == hold[0])
                {
                    hold[0] = 0;
                    hold = hold + 1;
                    break;
                }
                hold = hold + 1;
            }
            init_macro_env(argv[i+1], hold, "__ARGV__", env);
            env = env + 1;
            i += 2;
        }
        else
        {
            i += 1;
        }
    }
}

int main(int argc, char** argv, char** envp)
{
    /****************************************************************************
     * Zero means no debugging messages and larger positive values means more   *
     * chatty output. Level 15 means EVERYTHING but 7 should cover most magic   *
     ****************************************************************************/
    DEBUG_LEVEL = 0;
    /* Setup __M2__ (It is very very special *DO NOT MESS WITH IT* ) */
    init_macro_env("__M2__", "__M2__", "__INTERNAL_M2__", 0);

    /* Our fun globals */
    FUZZING = FALSE;
    MAX_STRING = 65536;
    PREPROCESSOR_MODE = FALSE;
    STDIO_USED = FALSE;
    DIRTY_MODE = FALSE;
    Architecture = NULL;
    OperatingSystem = NULL;

    /* Our fun locals */
    int debug_flag = TRUE;
    FILE* in = stdin;
    FILE* tempfile;
    char* destination_name = "a.out";
    FILE* destination_file = stdout;
    char* name;
    int DUMP_MODE = FALSE;
    follow_includes = TRUE;

    /* Try to get our needed updates */
    prechecks(argc, argv);

    /* Get the environmental bits */
    if(1 <= DEBUG_LEVEL) fputs("Starting to setup Environment\n", stderr);
    populate_env(envp);
    setup_env();
    if(1 <= DEBUG_LEVEL) fputs("Environment setup\n", stderr);

    M2LIBC_PATH = env_lookup("M2LIBC_PATH");
    if(NULL == M2LIBC_PATH) M2LIBC_PATH = "./M2libc";
    else if(1 <= DEBUG_LEVEL)
    {
        fputs("M2LIBC_PATH set by environment variable to ", stderr);
        fputs(M2LIBC_PATH, stderr);
        fputc('\n', stderr);
    }

    TEMPDIR = env_lookup("TMPDIR");
    if(NULL == TEMPDIR) TEMPDIR = "/tmp";
    else if(1 <= DEBUG_LEVEL)
    {
        fputs("TEMPDIR set by environment variable to ", stderr);
        fputs(TEMPDIR, stderr);
        fputc('\n', stderr);
    }

    int i = 1;
    while(i <= argc)
    {
        if(NULL == argv[i])
        {
            i += 1;
        }
        else if(match(argv[i], "-E") || match(argv[i], "--preprocess-only"))
        {
            PREPROCESSOR_MODE = TRUE;
            i += 1;
        }
        else if(match(argv[i], "--dump-mode"))
        {
            DUMP_MODE = TRUE;
            i+= 1;
        }
        else if(match(argv[i], "--dirty-mode"))
        {
            DIRTY_MODE = TRUE;
            i+= 1;
        }
        else if(match(argv[i], "--no-includes"))
        {
            /* Handled by precheck*/
            i+= 1;
        }
        else if(match(argv[i], "--debug-mode"))
        {
            /* Handled by precheck */
            i+= 2;
        }
        else if(match(argv[i], "-A") || match(argv[i], "--architecture"))
        {
            /* Handled by precheck */
            i += 2;
        }
        else if(match(argv[i], "--os") || match(argv[i], "--operating-system"))
        {
            /* Handled by precheck */
            i += 2;
        }
        else if(match(argv[i], "-f") || match(argv[i], "--file"))
        {
            if(NULL == hold_string)
            {
                hold_string = calloc(MAX_STRING + 4, sizeof(char));
                require(NULL != hold_string, "Impossible Exhaustion has occured\n");
            }

            name = argv[i + 1];
            if(NULL == name)
            {
                fputs("did not receive a file name\n", stderr);
                exit(EXIT_FAILURE);
            }

            in = fopen(name, "r");
            if(NULL == in)
            {
                fputs("Unable to open for reading file: ", stderr);
                fputs(name, stderr);
                fputs("\n Aborting to avoid problems\n", stderr);
                exit(EXIT_FAILURE);
            }
            global_token = read_all_tokens(in, global_token, name, follow_includes);
            fclose(in);
            i += 2;
        }
        else if(match(argv[i], "-o") || match(argv[i], "--output"))
        {
            destination_name = argv[i + 1];
            require(NULL != destination_name, "--output option requires a filename to follow\n");
            destination_file = fopen(destination_name, "w");
            if(NULL == destination_file)
            {
                fputs("Unable to open for writing file: ", stderr);
                fputs(argv[i + 1], stderr);
                fputs("\n Aborting to avoid problems\n", stderr);
                exit(EXIT_FAILURE);
            }
            i += 2;
        }
        else if(match(argv[i], "--max-string"))
        {
            /* handled by precheck */
            i += 2;
        }
        else if(match(argv[i], "-I"))
        {
            /* Handled by precheck */
            i += 2;
        }
        else if(match(argv[i], "-D"))
        {
            /* Handled by precheck */
            i += 2;
        }
        else if(match(argv[i], "-h") || match(argv[i], "--help"))
        {
            fputs(" -f input file\n -o output file\n --help for this message\n --version for file version\n-E or --preprocess-only\n--max-string N (N is a number)\n--fuzz\n--no-debug\n", stdout);
            exit(EXIT_SUCCESS);
        }
        else if(match(argv[i], "-V") || match(argv[i], "--version"))
        {
            fputs("M2-Mesoplanet v1.10.0\n", stderr);
            exit(EXIT_SUCCESS);
        }
        else if(match(argv[i], "--fuzz"))
        {
            /* Set fuzzing */
            FUZZING = TRUE;
            i += 1;
        }
        else if(match(argv[i], "--no-debug"))
        {
            /* strip things down */
            debug_flag = FALSE;
            i += 1;
        }
        else if(match(argv[i], "--temp-directory"))
        {
            name = argv[i+1];
            if(NULL == name)
            {
                fputs("--temp-directory requires a PATH\n", stderr);
                exit(EXIT_FAILURE);
            }
            if(1 <= DEBUG_LEVEL)
            {
                fputs("TEMPDIR set by --temp-directory to ", stderr);
                fputs(name, stderr);
                fputc('\n', stderr);
            }
            TEMPDIR = name;
            i += 2;
        }
        else
        {
            if(5 <= DEBUG_LEVEL)
            {
                fputs("on index: ", stderr);
                fputs(int2str(i, 10, TRUE), stderr);
                fputc('\n', stderr);
            }
            fputs("UNKNOWN ARGUMENT: ", stdout);
            fputs(argv[i], stdout);
            fputc('\n', stdout);
            exit(EXIT_FAILURE);
        }
    }

    if(1 <= DEBUG_LEVEL) fputs("READ all files\n", stderr);

    /* Deal with special case of wanting to read from standard input */
    if(stdin == in)
    {
        hold_string = calloc(MAX_STRING, sizeof(char));
        require(NULL != hold_string, "Impossible Exhaustion has occured\n");
        global_token = read_all_tokens(in, global_token, "STDIN", follow_includes);
    }

    if(NULL == global_token)
    {
        fputs("Either no input files were given or they were empty\n", stderr);
        exit(EXIT_FAILURE);
    }

    if(1 <= DEBUG_LEVEL) fputs("Start to reverse list\n", stderr);
    global_token = reverse_list(global_token);
    if(1 <= DEBUG_LEVEL) fputs("List reversed\n", stderr);

    if(DUMP_MODE)
    {
        output_tokens(global_token, destination_file);
        exit(EXIT_SUCCESS);
    }

    preprocess();

    if(PREPROCESSOR_MODE)
    {
        fputs("/* M2-Mesoplanet Preprocessed source */\n", destination_file);
        output_tokens(global_token, destination_file);
        fclose(destination_file);
    }
    else
    {
        /* Ensure we can write to the temp directory */
        int permissions = access(TEMPDIR, 0);
        if(0 != permissions)
        {
            fputs("unable to access: ", stderr);
            fputs(TEMPDIR, stderr);
            fputs(" for use as a temp directory\nPlease use --temp-directory to set a directory you can use or set the TMPDIR variable\n", stderr);
            exit(EXIT_FAILURE);
        }

        name = calloc(100, sizeof(char));
        strcpy(name, TEMPDIR);
        strcat(name, "/M2-Mesoplanet-XXXXXX");
        i = mkstemp(name);
        tempfile = fdopen(i, "w");
        if(NULL != tempfile)
        {
            /* Our preprocessed crap */
            output_tokens(global_token, tempfile);
            fclose(tempfile);

            /* Make me a real binary */
            spawn_processes(debug_flag, TEMPDIR, name, destination_name, envp);

            /* And clean up the donkey */
            if(!DIRTY_MODE) remove(name);
        }
        else
        {
            fputs("unable to get a tempfile for M2-Mesoplanet output\n", stderr);
            exit(EXIT_FAILURE);
        }
    }
    return EXIT_SUCCESS;
}

https://git.savannah.nongnu.org/gitweb/?p=mescc-tools.git;a=blob;f=get_machine.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools/get_machine.c used in: Step 57
/* -*- c-file-style: "linux";indent-tabs-mode:t -*- */
/* Copyright (C) 2017 Jeremiah Orians
 * This file is part of mescc-tools.
 *
 * mescc-tools is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * mescc-tools is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with mescc-tools.  If not, see <http://www.gnu.org/licenses/>.
 */


#include <stdio.h>
#include <stdlib.h>
#include <sys/utsname.h>
int match(char* a, char* b);

#define TRUE 1
//CONSTANT TRUE 1
#define FALSE 0
//CONSTANT FALSE 0

/* Standard C main program */
int main(int argc, char **argv)
{
    int exact = FALSE;
    int override = FALSE;
    char* override_string;
    int option_index = 1;

    struct utsname* unameData = calloc(1, sizeof(struct utsname));
    uname(unameData);

    while(option_index <= argc)
    {
        if(NULL == argv[option_index])
        {
            option_index = option_index + 1;
        }
        else if(match(argv[option_index], "--exact"))
        {
            exact = TRUE;
            option_index = option_index + 1;
        }
        else if(match(argv[option_index], "--override"))
        {
            override = TRUE;
            if((option_index + 1) < argc)
            {
                override_string = argv[option_index + 1];
                option_index = option_index + 2;
            }
            else
            {
                fputs("--override requires an actual override string\n", stderr);
                exit(EXIT_FAILURE);
            }
        }
        else if(match(argv[option_index], "--os") || match(argv[option_index], "--OS"))
        {
            if(override) fputs(override_string, stdout);
            else fputs(unameData->sysname, stdout);
            fputc('\n', stdout);
            exit(EXIT_SUCCESS);
        }
        else if(match(argv[option_index], "--blood"))
        {
            if(override) fputs(override_string, stdout);
            else if(match("aarch64", unameData->machine)
                 || match("amd64", unameData->machine)
                 || match("ppc64le", unameData->machine)
                 || match("riscv64", unameData->machine)
                 || match("x86_64", unameData->machine)) fputs("--64", stdout);
            fputc('\n', stdout);
            exit(EXIT_SUCCESS);
        }
        else if(match(argv[option_index], "--endian"))
        {
            if(override) fputs(override_string, stdout);
            else if(match("aarch64", unameData->machine)
                 || match("amd64", unameData->machine)
                 || match("ppc64le", unameData->machine)
                 || match("riscv64", unameData->machine)
                 || match("x86_64", unameData->machine)
                 || match("i386", unameData->machine)
                 || match("i486", unameData->machine)
                 || match("i586", unameData->machine)
                 || match("i686", unameData->machine)
                 || match("i686-pae", unameData->machine))fputs("--little-endian", stdout);
            else fputs("--big-endian", stdout);
            fputc('\n', stdout);
            exit(EXIT_SUCCESS);
        }
        else if(match(argv[option_index], "--hex2"))
        {
            if(override) fputs(override_string, stdout);
            else if(match("aarch64", unameData->machine)) fputs("0x400000", stdout);
            else if(match("armv7l", unameData->machine)) fputs("0x10000", stdout);
            else if(match("amd64", unameData->machine)
                 || match("x86_64", unameData->machine)) fputs("0x600000", stdout);
            else if(match("ppc64le", unameData->machine)) fputs("0x10000", stdout);
            else if(match("riscv64", unameData->machine)) fputs("0x600000", stdout);
            else if(match("i386", unameData->machine)
                 || match("i486", unameData->machine)
                 || match("i586", unameData->machine)
                 || match("i686", unameData->machine)
                 || match("i686-pae", unameData->machine)) fputs("0x08048000", stdout);
            else fputs("0x0", stdout);
            fputc('\n', stdout);
            exit(EXIT_SUCCESS);
        }
        else if(match(argv[option_index], "-V") || match(argv[option_index], "--version"))
        {
            fputs("get_machine 1.4.0\n", stdout);
            exit(EXIT_SUCCESS);
        }
        else if(match(argv[option_index], "-h") || match(argv[option_index], "--help"))
        {
            fputs("If you want exact architecture use --exact\n", stderr);
            fputs("If you want to know the Operating system use --os\n", stderr);
            fputs("If you wish to override the output to anything you want use --override\n", stderr);
            exit(EXIT_SUCCESS);
        }
        else
        {
            fputs("Unknown option\n", stderr);
            exit(EXIT_FAILURE);
        }
    }

    if(override) fputs(override_string, stdout);
    else if(!exact)
    {
        if(match("i386", unameData->machine) ||
           match("i486", unameData->machine) ||
           match("i586", unameData->machine) ||
           match("i686", unameData->machine) ||
           match("i686-pae", unameData->machine)) fputs("x86", stdout);
        else if(match("x86_64", unameData->machine)) fputs("amd64", stdout);
        else fputs(unameData->machine, stdout);
    }
    else fputs(unameData->machine, stdout);
    fputs("\n", stdout);
    return EXIT_SUCCESS;
}

https://github.com/oriansj/mescc-tools-extra/blob/main/sha256sum.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools-extra/sha256sum.c used in: Step 66
/* Copyright (C) 2021 Bastian Bittorf <bb@npl.de>
 * Copyright (C) 2021 Alain Mosnier <alain@wanamoon.net>
 * Copyright (C) 2017-2021 Jan Venekamp
 * Copyright (C) 2021 Jeremiah Orians
 * This file is part of mescc-tools
 *
 * mescc-tools is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * mescc-tools is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with mescc-tools.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "M2libc/bootstrappable.h"

#define CHUNK_SIZE 64
#define TOTAL_LEN_LEN 8

int mask;

/*
 * Initialize array of round constants:
 * (first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311):
 */
unsigned* init_k()
{
    unsigned* k = calloc(65, sizeof(unsigned));
    k[0] = 0x428a2f98;
    k[1] = 0x71374491;
    k[2] = 0xb5c0fbcf;
    k[3] = 0xe9b5dba5;
    k[4] = 0x3956c25b;
    k[5] = 0x59f111f1;
    k[6] = 0x923f82a4;
    k[7] = 0xab1c5ed5;
    k[8] = 0xd807aa98;
    k[9] = 0x12835b01;
    k[10] = 0x243185be;
    k[11] = 0x550c7dc3;
    k[12] = 0x72be5d74;
    k[13] = 0x80deb1fe;
    k[14] = 0x9bdc06a7;
    k[15] = 0xc19bf174;
    k[16] = 0xe49b69c1;
    k[17] = 0xefbe4786;
    k[18] = 0x0fc19dc6;
    k[19] = 0x240ca1cc;
    k[20] = 0x2de92c6f;
    k[21] = 0x4a7484aa;
    k[22] = 0x5cb0a9dc;
    k[23] = 0x76f988da;
    k[24] = 0x983e5152;
    k[25] = 0xa831c66d;
    k[26] = 0xb00327c8;
    k[27] = 0xbf597fc7;
    k[28] = 0xc6e00bf3;
    k[29] = 0xd5a79147;
    k[30] = 0x06ca6351;
    k[31] = 0x14292967;
    k[32] = 0x27b70a85;
    k[33] = 0x2e1b2138;
    k[34] = 0x4d2c6dfc;
    k[35] = 0x53380d13;
    k[36] = 0x650a7354;
    k[37] = 0x766a0abb;
    k[38] = 0x81c2c92e;
    k[39] = 0x92722c85;
    k[40] = 0xa2bfe8a1;
    k[41] = 0xa81a664b;
    k[42] = 0xc24b8b70;
    k[43] = 0xc76c51a3;
    k[44] = 0xd192e819;
    k[45] = 0xd6990624;
    k[46] = 0xf40e3585;
    k[47] = 0x106aa070;
    k[48] = 0x19a4c116;
    k[49] = 0x1e376c08;
    k[50] = 0x2748774c;
    k[51] = 0x34b0bcb5;
    k[52] = 0x391c0cb3;
    k[53] = 0x4ed8aa4a;
    k[54] = 0x5b9cca4f;
    k[55] = 0x682e6ff3;
    k[56] = 0x748f82ee;
    k[57] = 0x78a5636f;
    k[58] = 0x84c87814;
    k[59] = 0x8cc70208;
    k[60] = 0x90befffa;
    k[61] = 0xa4506ceb;
    k[62] = 0xbef9a3f7;
    k[63] = 0xc67178f2;
    return k;
}

unsigned* init_h()
{
    unsigned* h = calloc(9, sizeof(unsigned));
    h[0] = 0x6a09e667;
    h[1] = 0xbb67ae85;
    h[2] = 0x3c6ef372;
    h[3] = 0xa54ff53a;
    h[4] = 0x510e527f;
    h[5] = 0x9b05688c;
    h[6] = 0x1f83d9ab;
    h[7] = 0x5be0cd19;
    return h;
}

struct buffer_state
{
    char* p;
    size_t len;
    size_t total_len;
    int single_one_delivered; /* bool */
    int total_len_delivered; /* bool */
};

unsigned right_rot(unsigned value, unsigned count)
{
    /*
     * Defined behaviour in standard C for all count where 0 < count < 32,
     * which is what we need here.
     */

    value &= mask;
    int hold1 = (value >> count) & mask;
    int hold2 = (value << (32 - count)) & mask;
    int hold = (hold1 | hold2) & mask;
    return hold;
}

void init_buf_state(struct buffer_state * state, char* input, size_t len)
{
    state->p = input;
    state->len = len;
    state->total_len = len;
    state->single_one_delivered = 0;
    state->total_len_delivered = 0;
}

/* Return value: bool */
int calc_chunk(char* chunk, struct buffer_state * state)
{
    size_t space_in_chunk;

    if(state->total_len_delivered)
    {
        return 0;
    }

    if(state->len >= CHUNK_SIZE)
    {
        memcpy(chunk, state->p, CHUNK_SIZE);
        state->p += CHUNK_SIZE;
        state->len -= CHUNK_SIZE;
        return 1;
    }

    memcpy(chunk, state->p, state->len);
    chunk += state->len;
    space_in_chunk = CHUNK_SIZE - state->len;
    state->p += state->len;
    state->len = 0;

    /* If we are here, space_in_chunk is one at minimum. */
    if(!state->single_one_delivered)
    {
        chunk[0] = 0x80;
        chunk += 1;
        space_in_chunk -= 1;
        state->single_one_delivered = 1;
    }

    /*
     * Now:
     * - either there is enough space left for the total length, and we can conclude,
     * - or there is too little space left, and we have to pad the rest of this chunk with zeroes.
     * In the latter case, we will conclude at the next invocation of this function.
     */
    if(space_in_chunk >= TOTAL_LEN_LEN)
    {
        size_t left = space_in_chunk - TOTAL_LEN_LEN;
        size_t len = state->total_len;
        int i;
        memset(chunk, 0x00, left);
        chunk += left;
        /* Storing of len * 8 as a big endian 64-bit without overflow. */
        chunk[7] = (len << 3);
        len >>= 5;

        for(i = 6; i >= 0; i -= 1)
        {
            chunk[i] = len;
            len >>= 8;
        }

        state->total_len_delivered = 1;
    }
    else
    {
        memset(chunk, 0x00, space_in_chunk);
    }

    return 1;
}

/*
 * Limitations:
 * - Since input is a pointer in RAM, the data to hash should be in RAM, which could be a problem
 *   for large data sizes.
 * - SHA algorithms theoretically operate on bit strings. However, this implementation has no support
 *   for bit string lengths that are not multiples of eight, and it really operates on arrays of bytes.
 *   In particular, the len parameter is a number of bytes.
 */
void calc_sha_256(char* hash, char* input, size_t len)
{
    /*
     * Note 1: All integers (expect indexes) are 32-bit unsigned integers and addition is calculated modulo 2^32.
     * Note 2: For each round, there is one round constant k[i] and one entry in the message schedule array w[i], 0 = i = 63
     * Note 3: The compression function uses 8 working variables, a through h
     * Note 4: Big-endian convention is used when expressing the constants in this pseudocode,
     *     and when parsing message block data from bytes to words, for example,
     *     the first word of the input message "abc" after padding is 0x61626380
     */
    /*
     * Initialize hash values:
     * (first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):
     */
    unsigned* k = init_k();
    unsigned* h = init_h();
    unsigned i;
    unsigned j;
    unsigned hold1;
    unsigned hold2;
    /* 512-bit chunks is what we will operate on. */
    char* chunk = calloc(65, sizeof(char));
    struct buffer_state* state = calloc(1, sizeof(struct buffer_state));
    init_buf_state(state, input, len);
    unsigned* ah = calloc(9, sizeof(unsigned));
    char *p;
    unsigned* w = calloc(17, sizeof(unsigned));
    unsigned s0;
    unsigned s1;
    unsigned ch;
    unsigned temp1;
    unsigned temp2;
    unsigned maj;

    while(calc_chunk(chunk, state))
    {
        p = chunk;

        /* Initialize working variables to current hash value: */
        for(i = 0; i < 8; i += 1)
        {
            ah[i] = h[i];
        }

        /* Compression function main loop: */
        for(i = 0; i < 4; i += 1)
        {
            /*
             * The w-array is really w[64], but since we only need
             * 16 of them at a time, we save stack by calculating
             * 16 at a time.
             *
             * This optimization was not there initially and the
             * rest of the comments about w[64] are kept in their
             * initial state.
             */
            /*
             * create a 64-entry message schedule array w[0..63] of 32-bit words
             * (The initial values in w[0..63] don't matter, so many implementations zero them here)
             * copy chunk into first 16 words w[0..15] of the message schedule array
             */

            for(j = 0; j < 16; j += 1)
            {
                if(i == 0)
                {
                    w[j] = ((p[0] & 0xFF) << 24) | ((p[1] & 0xFF) << 16) | ((p[2] & 0xFF) << 8) | (p[3] & 0xFF);
                    p += 4;
                }
                else
                {
                    /* Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array: */
                    hold1 = (j + 1) & 0xf;
                    hold2 = w[hold1];
                    s0 = right_rot(hold2, 7) ^ right_rot(hold2, 18) ^ ((hold2 & mask) >> 3);

                    hold1 = (j + 14) & 0xf;
                    hold2 = w[hold1];
                    s1 = right_rot(hold2, 17) ^ right_rot(hold2, 19) ^ ((hold2 & mask) >> 10);

                    w[j] += s0 + w[(j + 9) & 0xf] + s1;
                }

                s1 = right_rot(ah[4], 6) ^ right_rot(ah[4], 11) ^ right_rot(ah[4], 25);
                ch = (ah[4] & ah[5]) ^ (~ah[4] & ah[6]);
                temp1 = ah[7] + s1 + ch + k[i << 4 | j] + w[j];
                s0 = right_rot(ah[0], 2) ^ right_rot(ah[0], 13) ^ right_rot(ah[0], 22);
                maj = (ah[0] & ah[1]) ^ (ah[0] & ah[2]) ^ (ah[1] & ah[2]);
                temp2 = s0 + maj;
                ah[7] = ah[6];
                ah[6] = ah[5];
                ah[5] = ah[4];
                ah[4] = ah[3] + temp1;
                ah[3] = ah[2];
                ah[2] = ah[1];
                ah[1] = ah[0];
                ah[0] = temp1 + temp2;
            }
        }

        /* Add the compressed chunk to the current hash value: */
        for(i = 0; i < 8; i +=  1)
        {
            h[i] += ah[i];
        }
    }

    /* Produce the final hash value (big-endian): */
    i = 0;
    for(j = 0; i < 8; i += 1)
    {
        hash[j] = ((h[i] >> 24) & 0xFF);
        j += 1;
        hash[j] = ((h[i] >> 16) & 0xFF);
        j += 1;
        hash[j] = ((h[i] >> 8) & 0xFF);
        j += 1;
        hash[j] = (h[i] & 0xFF);
        j += 1;
    }
}

struct list
{
    int found;
    char* name;
    FILE* f;
    size_t size;
    char* buffer;
    char* hash;
    struct list* next;
};

void bad_checkfile(char* filename)
{
    fputs(filename, stdout);
    puts(": no properly formatted SHA256 checksum lines found");
}

int hex2int(char c, char* filename)
{
    if((c >= '0') && (c <= '9')) return (c - 48);
    else if((c >= 'a') && (c <= 'f')) return (c - 87);
    else if ((c >= 'F') && (c <= 'F')) return (c - 55);
    bad_checkfile(filename);
    exit(EXIT_FAILURE);
}

char* hash_to_string(char* a)
{
    char* table = "0123456789abcdef";
    char* r = calloc(66, sizeof(char));
    int i;
    int j = 0;
    int c;
    for(i = 0; i < 32; i += 1)
    {
        c = a[i] & 0xFF;
        r[j] = table[(c >> 4)];
        j += 1;
        r[j] = table[(c & 0xF)];
        j += 1;
    }
    return r;
}

int check_file(char* b, char* filename)
{
    int r = TRUE;
    size_t i;
    int hold1;
    int hold2;
    FILE* f;
    char* name = calloc(4097, sizeof(char));
    char* hash = calloc(33, sizeof(char));
    char* hash2 = calloc(33, sizeof(char));
    size_t size;
    char* buffer;
go_again:
    for(i = 0; i < 32; i += 1)
    {
        hold1 = hex2int(b[0], filename);
        hold2 = hex2int(b[1], filename);
        hash[i] = (hold1 << 4) + hold2;
        b += 2;
    }

    if((' ' != b[0]) || (' ' != b[1]))
    {
        bad_checkfile(filename);
        exit(EXIT_FAILURE);
    }

    b += 2;
    for(i = 0; i < 4096; i += 1)
    {
        if('\n' == b[0])
        {
            name[i] = 0;
            b += 1;
            break;
        }
        name[i] = b[0];
        b += 1;
    }

    f = fopen(name, "r");
    if(NULL == f)
    {
        fputs(name, stdout);
        puts(": No such file or directory");
        exit(EXIT_FAILURE);
    }
    else
    {
        fseek(f, 0, SEEK_END);
        size = ftell(f);
        rewind(f);
        buffer = calloc(size + 1, sizeof(char));
        fread(buffer, sizeof(char), size, f);
        calc_sha_256(hash2, buffer, size);
        if(match(hash_to_string(hash), hash_to_string(hash2)))
        {
            fputs(name, stdout);
            puts(": OK");
        }
        else
        {
            fputs(name, stdout);
            fputs(": FAILED\nWanted:   ", stdout);
            fputs(hash_to_string(hash), stdout);
            fputs("\nReceived: ", stdout);
            puts(hash_to_string(hash2));
            r = FALSE;
        }
    }

    if(0 == b[0]) return r;
    goto go_again;
}

/* reverse the linked list */
void reverse(struct list** head)
{
    struct list* prev = NULL;
    struct list* current = *head;
    struct list* next = NULL;
    while (current != NULL)
    {
        next = current->next;
        current->next = prev;
        prev = current;
        current = next;
    }
    *head = prev;
}

int main(int argc, char **argv)
{
    struct list* l = NULL;
    struct list* t = NULL;
    size_t read;
    int check = FALSE;
    int r = TRUE;
    char* output_file = "";
    FILE* output = stdout;
    mask = (0x7FFFFFFF << 1) | 0x1;

    int i = 1;
    while(i <= argc)
    {
        if(NULL == argv[i])
        {
            i += 1;
        }
        else if(match(argv[i], "-c") || match(argv[i], "--check"))
        {
            check = TRUE;
            i += 1;
        }
        else if (match(argv[i], "-o") || match(argv[i], "--output"))
        {
            output_file = argv[i + 1];
            i += 2;
            if (output != stdout) {
                fclose(output);
            }
            output = fopen(output_file, "w");
            require(output != NULL, "Output file cannot be opened!\n");
        }
        else if(match(argv[i], "-h") || match(argv[i], "--help"))
        {
            puts("Usage: sha256sum <file> [--check]");
            exit(EXIT_SUCCESS);
        }
        else
        {
            t = calloc(1, sizeof(struct list));
            t->hash = calloc(33, sizeof(char));
            t->name = argv[i];
            t->f = fopen(t->name, "r");
            if(NULL != t->f)
            {
                t->found = TRUE;
                fseek(t->f, 0, SEEK_END);
                t->size = ftell(t->f);
                rewind(t->f);
                t->buffer = calloc(t->size + 1, sizeof(char));
                read = fread(t->buffer, sizeof(char), t->size, t->f);
            }
            t->next = l;
            l = t;
            i += 1;
        }
    }
    reverse(&l);

    if(check)
    {
        while(NULL != l)
        {
            if(l->found)
            {
                if(!check_file(l->buffer, l->name)) r = FALSE;
            }
            else
            {
                fputs(l->name, stdout);
                puts(": No such file or directory");
                exit(EXIT_FAILURE);
            }
            l = l->next;
        }
    }
    else
    {
        while(NULL != l)
        {
            if(l->found)
            {
                calc_sha_256(l->hash, l->buffer, l->size);
                fputs(hash_to_string(l->hash), output);
                fputs("  ", output);
                fputs(l->name, output);
                fputc('\n', output);
            }
            else
            {
                fputs(l->name, output);
                fputs(": No such file or directory\n", output);
                exit(EXIT_FAILURE);
            }
            l = l->next;
        }
    }
    if (output != stdout) {
        fclose(output);
    }

    if(r) return 0;
    else return 1;
}

https://github.com/oriansj/M2libc/blob/main/string.h

Files:
/* Copyright (C) 2016 Jeremiah Orians
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _STRING_H
#define _STRING_H

#ifdef __M2__
#include <string.c>
#else
#include <stddef.h>

/* String manipulation */
char* strcpy(char* dest, char const* src);
char* strncpy(char* dest, char const* src, size_t count);
char* strcat(char* dest, char const* src);
char* strncat(char* dest, char const* src, size_t count);

/* String examination */
size_t strlen(char const* str );
size_t strnlen_s(char const* str, size_t strsz );
int strcmp(char const* lhs, char const* rhs );
int strncmp(char const* lhs, char const* rhs, size_t count);
char* strchr(char const* str, int ch);
char* strrchr(char const* str, int ch);
size_t strspn(char const* dest, char const* src);
size_t strcspn(char const* dest, char const* src);
char* strpbrk(char const* dest, char const* breakset);

/* Memory manipulation */
void* memset(void* dest, int ch, size_t count);
void* memcpy(void* dest, void const* src, size_t count);
void* memmove(void* dest, void const* src, size_t count);
int memcmp(void const* lhs, void const* rhs, size_t count);
void* memchr(void const* ptr, int ch, size_t count);
#endif
#endif

https://github.com/oriansj/M2libc/blob/main/sys/stat.h

File: ../git/live-bootstrap/sysa/stage0-posix/src/M2libc/sys/stat.h used in: Step 66, Step 67, Step 68, Step 69, Step 70, Step 71, Step 72, Step 73, Step 74, Step 75, Step 76, Step 79, Step 81
/* Copyright (C) 2020 Jeremiah Orians
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _SYS_STAT_H
#define _SYS_STAT_H

#ifdef __M2__
#if __uefi__
#include <uefi/sys/stat.c>
#elif __i386__
#include <x86/linux/sys/stat.c>
#elif __x86_64__
#include <amd64/linux/sys/stat.c>
#elif __arm__
#include <armv7l/linux/sys/stat.c>
#elif __aarch64__
#include <aarch64/linux/sys/stat.c>
#elif __riscv && __riscv_xlen==32
#include <riscv32/linux/sys/stat.c>
#elif __riscv && __riscv_xlen==64
#include <riscv64/linux/sys/stat.c>
#else
#error arch not supported
#endif

#else
#include <sys/types.h>

#define S_IRWXU 00700
#define S_IXUSR 00100
#define S_IWUSR 00200
#define S_IRUSR 00400

#define S_ISUID 04000
#define S_ISGID 02000
#define S_IXGRP 00010
#define S_IXOTH 00001
#define S_IRGRP 00040
#define S_IROTH 00004
#define S_IWGRP 00020
#define S_IWOTH 00002
#define S_IRWXG 00070
#define S_IRWXO 00007


int chmod(char *pathname, int mode);
int fchmod(int a, mode_t b);
int mkdir(char const* a, mode_t b);
int mknod(char const* a, mode_t b, dev_t c);
mode_t umask(mode_t m);

#endif
#endif

https://github.com/oriansj/M2libc/blob/main/fcntl.h

File: ../git/live-bootstrap/sysa/stage0-posix/src/M2libc/fcntl.h used in: Step 66, Step 67, Step 68, Step 69, Step 70, Step 71, Step 72, Step 73, Step 74, Step 75, Step 76, Step 79, Step 81
/* Copyright (C) 2016 Jeremiah Orians
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _FCNTL_H
#define _FCNTL_H

#ifdef __M2__
#include <fcntl.c>
#else
#define O_RDONLY 0
#define O_WRONLY 1
#define O_RDWR 2
#define O_CREAT 00100
#define O_EXCL 00200
#define O_TRUNC 001000
#define O_APPEND 002000

#define S_IXUSR 00100
#define S_IWUSR 00200
#define S_IRUSR 00400
#define S_IRWXU 00700


extern int open(char* name, int flag, int mode);

#define STDIN_FILENO  0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#endif
#endif

https://github.com/oriansj/M2libc/blob/main/unistd.h

File: ../git/live-bootstrap/sysa/stage0-posix/src/M2libc/unistd.h used in: Step 66, Step 67, Step 68, Step 69, Step 70, Step 71, Step 72, Step 73, Step 74, Step 75, Step 76, Step 79, Step 81
/* Copyright (C) 2020 Jeremiah Orians
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _UNISTD_H
#define _UNISTD_H

#ifdef __M2__
#if __uefi__
#include <uefi/unistd.c>
#elif __i386__
#include <x86/linux/unistd.c>
#elif __x86_64__
#include <amd64/linux/unistd.c>
#elif __arm__
#include <armv7l/linux/unistd.c>
#elif __aarch64__
#include <aarch64/linux/unistd.c>
#elif __riscv && __riscv_xlen==32
#include <riscv32/linux/unistd.c>
#elif __riscv && __riscv_xlen==64
#include <riscv64/linux/unistd.c>
#else
#error arch not supported
#endif

#else
#define NULL 0
#define __PATH_MAX 4096

void* malloc(unsigned size);
int access(char* pathname, int mode);
int chdir(char* path);
int fchdir(int fd);
void _exit(int value);
int fork();
int waitpid (int pid, int* status_ptr, int options);
int execve(char* file_name, char** argv, char** envp);
int read(int fd, char* buf, unsigned count);
int write(int fd, char* buf, unsigned count);
int lseek(int fd, int offset, int whence);
int close(int fd);
int unlink (char *filename);
int _getcwd(char* buf, int size);
char* getcwd(char* buf, unsigned size);
char* getwd(char* buf);
char* get_current_dir_name();
int brk(void *addr);

struct utsname
{
    char sysname[65];    /* Operating system name (e.g., "Linux") */
    char nodename[65];   /* Name within "some implementation-defined network" */
    char release[65];    /* Operating system release (e.g., "2.6.28") */
    char version[65];    /* Operating system version */
    char machine[65];    /* Hardware identifier */
};

int uname(struct utsname* unameData);

#endif
#endif

https://github.com/oriansj/M2libc/blob/main/stdlib.h

File: ../git/live-bootstrap/sysa/stage0-posix/src/M2libc/stdlib.h used in: Step 66, Step 67, Step 68, Step 69, Step 70, Step 71, Step 72, Step 73, Step 74, Step 75, Step 76, Step 79, Step 81
/* Copyright (C) 2016 Jeremiah Orians
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _STDLIB_H
#define _STDLIB_H
#include <unistd.h>

#ifdef __M2__
#include <stdlib.c>
#else


#define EXIT_FAILURE 1
#define EXIT_SUCCESS 0

extern void exit(int value);

extern long _malloc_ptr;
extern long _brk_ptr;

extern void free(void* l);
extern void* malloc(unsigned size);
extern void* memset(void* ptr, int value, int num);
extern void* calloc(int count, int size);
extern char *getenv(const char *name);

size_t wcstombs(char* dest, const wchar_t* src, size_t n);

#endif
#endif

https://github.com/oriansj/M2libc/blob/main/bootstrappable.h

Files:
/* Copyright (C) 2016 Jeremiah Orians
 * This file is part of M2-Planet.
 *
 * M2-Planet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * M2-Planet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _BOOTSTRAPPABLE_H
#define _BOOTSTRAPPABLE_H

/* Essential common CONSTANTS*/
#define TRUE 1
#define FALSE 0

#ifdef __M2__
#include <bootstrappable.c>
#else
/* Universally useful functions */
void require(int bool, char* error);
int match(char* a, char* b);
int in_set(int c, char* s);
int strtoint(char *a);
char* int2str(int x, int base, int signed_p);

#endif
#endif

https://github.com/oriansj/mescc-tools-extra/blob/main/match.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools-extra/match.c used in: Step 67
/* Copyright (C) 2021 Andrius Å tikonas
 * This file is part of mescc-tools-extra
 *
 * mescc-tools-extra is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * mescc-tools-extra is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with mescc-tools-extra.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
 * "match" can be used to compare strings. It is useful to write conditional
 * code in kaem.
 *
 * Usage: match string1 string2
 * Returns: 0 if strings match
 */ 

#include <stdio.h>
#include <string.h>

#include "M2libc/bootstrappable.h"

int main(int argc, char **argv)
{
    if(argc != 3)
    {
        fputs("match needs exactly 2 arguments.\n", stderr);
        return 2;
    }

    return !match(argv[1], argv[2]);
}

https://github.com/oriansj/mescc-tools-extra/blob/main/mkdir.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools-extra/mkdir.c used in: Step 68
/* Copyright (C) 2009 Tim Kientzle
 * Copyright (C) 2021 Jeremiah Orians
 * Copyright (C) 2021 Andrius Å tikonas
 * This file is part of mescc-tools-extra
 *
 * mescc-tools-extra is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * mescc-tools-extra is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with mescc-tools-extra.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
 * "mkdir" can be used to create empty directories. It can also create
 * required parent directories.
 *
 * Usage: mkdir <dir1>/<dir2> <dir3>
 *
 * These are all highly standard and portable headers. */
#include <stdio.h>
#include <string.h>

/* This is for mkdir(); this may need to be changed for some platforms. */
#include <sys/stat.h>  /* For mkdir() */
#include <stdlib.h>
#include "M2libc/bootstrappable.h"

int parents;

/* Create a directory, including parent directories as necessary. */
void create_dir(char *pathname, int mode)
{
    char *p;
    int r;

    /* Strip trailing '/' */
    if(pathname[strlen(pathname) - 1] == '/')
    {
        pathname[strlen(pathname) - 1] = '\0';
    }

    /* Try creating the directory. */
    r = mkdir(pathname, mode);

    if((r != 0) && parents)
    {
        /* On failure, try creating parent directory. */
        p = strrchr(pathname, '/');

        if(p != NULL)
        {
            p[0] = '\0';
            create_dir(pathname, 0755);
            p[0] = '/';
            r = mkdir(pathname, mode);
        }
    }

    if((r != 0) && !parents)
    {
        fputs("Could not create directory ", stderr);
        fputs(pathname, stderr);
        fputc('\n', stderr);
        exit(EXIT_FAILURE);
    }
}

int main(int argc, char **argv)
{
    /* This adds some quasi-compatibility with GNU coreutils' mkdir. */
    parents = FALSE;
    int i;
    for(i = 1; argc > i; i = i + 1)
    {
        if(match(argv[i], "-p")) parents = TRUE;
        else create_dir(argv[i], 0755);
    }

    return 0;
}

https://github.com/oriansj/mescc-tools-extra/blob/main/untar.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools-extra/untar.c used in: Step 69
/* Copyright (C) 2009 Tim Kientzle
 * Copyright (C) 2021 Jeremiah Orians
 * This file is part of mescc-tools-extra
 *
 * mescc-tools-extra is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * mescc-tools-extra is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with mescc-tools-extra.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
 * "untar" is an extremely simple tar extractor:
 *  * A single C source file, so it should be easy to compile
 *    and run on any system with a C compiler.
 *  * Extremely portable standard C.  The only non-ANSI function
 *    used is mkdir().
 *  * Reads basic ustar tar archives.
 *  * Does not require libarchive or any other special library.
 *
 * To compile: cc -o untar untar.c
 *
 * Usage:  untar <archive>
 *
 * In particular, this program should be sufficient to extract the
 * distribution for libarchive, allowing people to bootstrap
 * libarchive on systems that do not already have a tar program.
 *
 * To unpack libarchive-x.y.z.tar.gz:
 *    * gunzip libarchive-x.y.z.tar.gz
 *    * untar libarchive-x.y.z.tar
 *
 * Written by Tim Kientzle, March 2009.
 *
 * Released into the public domain.
 */

/* These are all highly standard and portable headers. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* This is for mkdir(); this may need to be changed for some platforms. */
#include <sys/stat.h>  /* For mkdir() */
#include "M2libc/bootstrappable.h"

int FUZZING;
int VERBOSE;
int STRICT;

/* Parse an octal number, ignoring leading and trailing nonsense. */
int parseoct(char const* p, size_t n)
{
    int i = 0;
    int h;

    while(((p[0] < '0') || (p[0] > '7')) && (n > 0))
    {
        p = p + 1;
        n = n - 1;
    }

    while((p[0] >= '0') && (p[0] <= '7') && (n > 0))
    {
        i = i << 3;
        h = p[0];
        i = i + h - 48;
        p = p + 1;
        n = n - 1;
    }

    return i;
}

/* Returns true if this is 512 zero bytes. */
int is_end_of_archive(char const* p)
{
    int n;

    for(n = 511; n >= 0; n = n - 1)
    {
        if(p[n] != 0)
        {
            return FALSE;
        }
    }

    return TRUE;
}

/* Create a directory, including parent directories as necessary. */
void create_dir(char *pathname, int mode)
{
    char *p;
    int r;

    /* Strip trailing '/' */
    if(pathname[strlen(pathname) - 1] == '/')
    {
        pathname[strlen(pathname) - 1] = '\0';
    }

    /* Try creating the directory. */
    if(!FUZZING)
    {
        r = mkdir(pathname, mode);

        if(r != 0)
        {
            /* On failure, try creating parent directory. */
            p = strrchr(pathname, '/');

            if(p != NULL)
            {
                p[0] = '\0';
                create_dir(pathname, 0755);
                p[0] = '/';
                r = mkdir(pathname, mode);
            }
        }

        if(r != 0)
        {
            fputs("Could not create directory ", stderr);
            fputs(pathname, stderr);
            fputc('\n', stderr);
        }
    }
}

/* Create a file, including parent directory as necessary. */
FILE* create_file(char *pathname)
{
    if(FUZZING) return NULL;
    FILE* f;
    f = fopen(pathname, "w");

    if(f == NULL)
    {
        /* Try creating parent dir and then creating file. */
        char *p = strrchr(pathname, '/');

        if(p != NULL)
        {
            p[0] = '\0';
            create_dir(pathname, 0755);
            p[0] = '/';
            f = fopen(pathname, "w");
        }
    }

    return f;
}

/* Verify the tar checksum. */
int verify_checksum(char const* p)
{
    int n;
    int u = 0;
    unsigned h;

    for(n = 0; n < 512; n = n + 1)
    {
        /* Standard tar checksum adds unsigned bytes. */
        if((n < 148) || (n > 155))
        {
            h = p[n];
            u = u + h;
        }
        else
        {
            u = u + 0x20;
        }
    }

    int r = parseoct(p + 148, 8);

    return (u == r);
}

/* Extract a tar archive. */
int untar(FILE *a, char const* path)
{
    char* buff = calloc(514, sizeof(char));
    FILE* f = NULL;
    size_t bytes_read;
    size_t bytes_written;
    int filesize;
    int op;
    if(VERBOSE)
    {
        fputs("Extracting from ", stdout);
        puts(path);
    }

    while(TRUE)
    {
        memset(buff, 0, 514);
        bytes_read = fread(buff, sizeof(char), 512, a);

        if(bytes_read < 512)
        {
            fputs("Short read on ", stderr);
            fputs(path, stderr);
            fputs(": expected 512, got ", stderr);
            fputs(int2str(bytes_read, 10, TRUE), stderr);
            fputc('\n', stderr);
            return FALSE;
        }

        if(is_end_of_archive(buff))
        {
            if(VERBOSE)
            {
                fputs("End of ", stdout);
                puts(path);
            }
            return TRUE;
        }

        if(!verify_checksum(buff))
        {
            fputs("Checksum failure\n", stderr);
            return FALSE;
        }

        filesize = parseoct(buff + 124, 12);

        op = buff[156];
        if('1' == op)
        {
            if(STRICT)
            {
                fputs("unable to create hardlinks\n", stderr);
                exit(EXIT_FAILURE);
            }
            fputs(" Ignoring hardlink ", stdout);
            puts(buff);
        }
        else if('2' == op)
        {
            if(STRICT)
            {
                fputs("unable to create symlinks\n", stderr);
                exit(EXIT_FAILURE);
            }
            fputs(" Ignoring symlink ", stdout);
            puts(buff);
        }
        else if('3' == op)
        {
            if(STRICT)
            {
                fputs("unable to create character devices\n", stderr);
                exit(EXIT_FAILURE);
            }
            fputs(" Ignoring character device ", stdout);
            puts(buff);
        }
        else if('4' == op)
        {
            if(STRICT)
            {
                fputs("unable to create block devices\n", stderr);
                exit(EXIT_FAILURE);
            }
            fputs(" Ignoring block device ", stdout);
            puts(buff);
        }
        else if('5' == op)
        {
            if(VERBOSE)
            {
                fputs(" Extracting dir ", stdout);
                puts(buff);
            }
            create_dir(buff, parseoct(buff + 100, 8));
            filesize = 0;
        }
        else if('6' == op)
        {
            if(STRICT)
            {
                fputs("unable to create FIFO\n", stderr);
                exit(EXIT_FAILURE);
            }
            fputs(" Ignoring FIFO ", stdout);
            puts(buff);
        }
        else
        {
            if(VERBOSE)
            {
                fputs(" Extracting file ", stdout);
                puts(buff);
            }
            f = create_file(buff);
        }

        while(filesize > 0)
        {
            bytes_read = fread(buff, 1, 512, a);

            if(bytes_read < 512)
            {
                fputs("Short read on ", stderr);
                fputs(path, stderr);
                fputs(": Expected 512, got ", stderr);
                puts(int2str(bytes_read, 10, TRUE));
                return FALSE;
            }

            if(filesize < 512)
            {
                bytes_read = filesize;
            }

            if(f != NULL)
            {
                if(!FUZZING)
                {
                    bytes_written = fwrite(buff, 1, bytes_read, f);
                    if(bytes_written != bytes_read)
                    {
                        fputs("Failed write\n", stderr);
                        fclose(f);
                        f = NULL;
                    }
                }
            }

            filesize = filesize - bytes_read;
        }

        if(f != NULL)
        {
            fclose(f);
            f = NULL;
        }
    }
    return TRUE;
}

struct files_queue
{
    char* name;
    FILE* f;
    struct files_queue* next;
};

int main(int argc, char **argv)
{
    struct files_queue* list = NULL;
    struct files_queue* a;
    STRICT = TRUE;
    FUZZING = FALSE;
    int r;

    int i = 1;
    while (i < argc)
    {
        if(NULL == argv[i])
        {
            i = i + 1;
        }
        else if(match(argv[i], "-f") || match(argv[i], "--file"))
        {
            a = calloc(1, sizeof(struct files_queue));
            require(NULL != a, "failed to allocate enough memory to even get the file name\n");
            a->next = list;
            a->name = argv[i+1];
            require(NULL != a->name, "the --file option requires a filename to be given\n");
            a->f = fopen(a->name, "r");
            if(a->f == NULL)
            {
                fputs("Unable to open ", stderr);
                fputs(a->name, stderr);
                fputc('\n', stderr);
                if(STRICT) exit(EXIT_FAILURE);
            }
            list = a;
            i = i + 2;
        }
        else if(match(argv[i], "--chaos") || match(argv[i], "--fuzz-mode") || match(argv[i], "--fuzzing"))
        {
            FUZZING = TRUE;
            fputs("fuzz-mode enabled, preparing for chaos\n", stderr);
            i = i + 1;
        }
        else if(match(argv[i], "-v") || match(argv[i], "--verbose"))
        {
            VERBOSE = TRUE;
            i = i + 1;
        }

        else if(match(argv[i], "--non-strict") || match(argv[i], "--bad-decisions-mode") || match(argv[i], "--drunk-mode"))
        {
            STRICT = FALSE;
            fputs("non-strict mode enabled, preparing for chaos\n", stderr);
            i = i + 1;
        }
        else if(match(argv[i], "-h") || match(argv[i], "--help"))
        {
            fputs("Usage: ", stderr);
            fputs(argv[0], stderr);
            fputs(" --file $input.gz\n", stderr);
            fputs("--verbose to print list of extracted files\n", stderr);
            fputs("--help to get this message\n", stderr);
            fputs("--fuzz-mode if you wish to fuzz this application safely\n", stderr);
            fputs("--non-strict if you wish to just ignore files not existing\n", stderr);
            exit(EXIT_SUCCESS);
        }
        else
        {
            fputs("Unknown option:", stderr);
            fputs(argv[i], stderr);
            fputs("\nAborting to avoid problems\n", stderr);
            exit(EXIT_FAILURE);
        }
    }

    /* Process the queue one file at a time */
    while(NULL != list)
    {
        r = untar(list->f, list->name);
        fputs("The extraction of ", stderr);
        fputs(list->name, stderr);
        if(r) fputs(" was successful\n", stderr);
        else fputs(" produced errors\n", stderr);
        fclose(list->f);
        list = list->next;
    }

    return 0;
}

https://github.com/oriansj/mescc-tools-extra/blob/main/ungz.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools-extra/ungz.c used in: Step 70
/* Copyright (C) 2002-2013 Mark Adler, all rights reserved
 * Copyright (C) 2021 Jeremiah Orians
 * This file is part of mescc-tools-extra
 *
 * mescc-tools-extra is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * mescc-tools-extra is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with mescc-tools-extra.  If not, see <http://www.gnu.org/licenses/>.
 */

/* puff.c
 * Copyright (C) 2002-2013 Mark Adler, all rights reserved
 * version 2.3, 21 Jan 2013
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the author be held liable for any damages
 * arising from the use of this software.
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 * 1. The origin of this software must not be misrepresented; you must not
 *    claim that you wrote the original software. If you use this software
 *    in a product, an acknowledgment in the product documentation would be
 *    appreciated but is not required.
 * 2. Altered source versions must be plainly marked as such, and must not be
 *    misrepresented as being the original software.
 * 3. This notice may not be removed or altered from any source distribution.
 * Mark Adler    madler@alumni.caltech.edu
 */

/* ungz.c is a gz file decompression utility that leverages puff.c to provide
 * the deflate algorithm with multiple modifications to enable being built by
 * M2-Planet with M2libc.
 *
 *
 * puff.c is a simple inflate written to be an unambiguous way to specify the
 * deflate format.  It is not written for speed but rather simplicity.  As a
 * side benefit, this code might actually be useful when small code is more
 * important than speed, such as bootstrap applications.  For typical deflate
 * data, zlib's inflate() is about four times as fast as puff().  zlib's
 * inflate compiles to around 20K on my machine, whereas puff.c compiles to
 * around 4K on my machine (a PowerPC using GNU cc).  If the faster decode()
 * function here is used, then puff() is only twice as slow as zlib's
 * inflate().
 *
 * All dynamically allocated memory comes from the stack.  The stack required
 * is less than 2K bytes.  This code is compatible with 16-bit int's and
 * assumes that long's are at least 32 bits.  puff.c uses the short data type,
 * assumed to be 16 bits, for arrays in order to conserve memory.  The code
 * works whether integers are stored big endian or little endian.
 *
 * In the comments below are "Format notes" that describe the inflate process
 * and document some of the less obvious aspects of the format.  This source
 * code is meant to supplement RFC 1951, which formally describes the deflate
 * format:
 *
 *    http://www.zlib.org/rfc-deflate.html
 */

/*
 * Change history:
 *
 * 1.0  10 Feb 2002     - First version
 * 1.1  17 Feb 2002     - Clarifications of some comments and notes
 *                      - Update puff() dest and source pointers on negative
 *                        errors to facilitate debugging deflators
 *                      - Remove longest from struct huffman -- not needed
 *                      - Simplify offs[] index in construct()
 *                      - Add input size and checking, using longjmp() to
 *                        maintain easy readability
 *                      - Use short data type for large arrays
 *                      - Use pointers instead of long to specify source and
 *                        destination sizes to avoid arbitrary 4 GB limits
 * 1.2  17 Mar 2002     - Add faster version of decode(), doubles speed (!),
 *                        but leave simple version for readabilty
 *                      - Make sure invalid distances detected if pointers
 *                        are 16 bits
 *                      - Fix fixed codes table error
 *                      - Provide a scanning mode for determining size of
 *                        uncompressed data
 * 1.3  20 Mar 2002     - Go back to lengths for puff() parameters [Gailly]
 *                      - Add a puff.h file for the interface
 *                      - Add braces in puff() for else do [Gailly]
 *                      - Use indexes instead of pointers for readability
 * 1.4  31 Mar 2002     - Simplify construct() code set check
 *                      - Fix some comments
 *                      - Add FIXLCODES #define
 * 1.5   6 Apr 2002     - Minor comment fixes
 * 1.6   7 Aug 2002     - Minor format changes
 * 1.7   3 Mar 2003     - Added test code for distribution
 *                      - Added zlib-like license
 * 1.8   9 Jan 2004     - Added some comments on no distance codes case
 * 1.9  21 Feb 2008     - Fix bug on 16-bit integer architectures [Pohland]
 *                      - Catch missing end-of-block symbol error
 * 2.0  25 Jul 2008     - Add #define to permit distance too far back
 *                      - Add option in TEST code for puff to write the data
 *                      - Add option in TEST code to skip input bytes
 *                      - Allow TEST code to read from piped stdin
 * 2.1   4 Apr 2010     - Avoid variable initialization for happier compilers
 *                      - Avoid unsigned comparisons for even happier compilers
 * 2.2  25 Apr 2010     - Fix bug in variable initializations [Oberhumer]
 *                      - Add const where appropriate [Oberhumer]
 *                      - Split if's and ?'s for coverage testing
 *                      - Break out test code to separate file
 *                      - Move NIL to puff.h
 *                      - Allow incomplete code only if single code length is 1
 *                      - Add full code coverage test to Makefile
 * 2.3  21 Jan 2013     - Check for invalid code length codes in dynamic blocks
 * ??   22 May 2021     - Convert to M2-Planet C subset for bootstrapping purposes.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "M2libc/bootstrappable.h"

/*
 * Maximums for allocations and loops.  It is not useful to change these --
 * they are fixed by the deflate format.
 */
#define MAXBITS 15              /* maximum bits in a code */
#define MAXLCODES 286           /* maximum number of literal/length codes */
#define MAXDCODES 30            /* maximum number of distance codes */
#define MAXCODES 316            /* maximum codes lengths to read (MAXLCODES+MAXDCODES) */
#define FIXLCODES 288           /* number of fixed literal/length codes */

/* input and output state */
struct state {
    /* output state */
    char *out;                  /* output buffer */
    size_t outlen;              /* available space at out */
    size_t outcnt;              /* bytes written to out so far */

    /* input state */
    char *in;                   /* input buffer */
    size_t inlen;               /* available input at in */
    size_t incnt;               /* bytes read so far */
    int bitbuf;                 /* bit buffer */
    int bitcnt;                 /* number of bits in bit buffer */
};

/*
 * Return need bits from the input stream.  This always leaves less than
 * eight bits in the buffer.  bits() works properly for need == 0.
 *
 * Format notes:
 *
 * - Bits are stored in bytes from the least significant bit to the most
 *   significant bit.  Therefore bits are dropped from the bottom of the bit
 *   buffer, using shift right, and new bytes are appended to the top of the
 *   bit buffer, using shift left.
 */
int bits(struct state *s, int need)
{
    long val;           /* bit accumulator (can use up to 20 bits) */
    long hold;

    /* load at least need bits into val */
    val = s->bitbuf;
    while (s->bitcnt < need)
    {
        if (s->incnt == s->inlen)
        {
            fputs("out of input\n", stderr);
            exit(EXIT_FAILURE);
        }
        hold = (s->in[s->incnt] & 0xFF);
        s->incnt = s->incnt + 1;
        val = val | (hold << s->bitcnt);  /* load eight bits */
        s->bitcnt = s->bitcnt + 8;
    }

    /* drop need bits and update buffer, always zero to seven bits left */
    s->bitbuf = (val >> need);
    s->bitcnt = s->bitcnt - need;

    /* return need bits, zeroing the bits above that */
    val = (val & ((1 << need) - 1));
    #if defined(DEBUG)
        fputs(int2str(val, 16, FALSE), stderr);
        fputs(" : bits\n", stderr);
    #endif
    return val;
}

/*
 * Process a stored block.
 *
 * Format notes:
 *
 * - After the two-bit stored block type (00), the stored block length and
 *   stored bytes are byte-aligned for fast copying.  Therefore any leftover
 *   bits in the byte that has the last bit of the type, as many as seven, are
 *   discarded.  The value of the discarded bits are not defined and should not
 *   be checked against any expectation.
 *
 * - The second inverted copy of the stored block length does not have to be
 *   checked, but it's probably a good idea to do so anyway.
 *
 * - A stored block can have zero length.  This is sometimes used to byte-align
 *   subsets of the compressed data for random access or partial recovery.
 */
int stored(struct state *s)
{
    unsigned len;       /* length of stored block */

    /* discard leftover bits from current byte (assumes s->bitcnt < 8) */
    s->bitbuf = 0;
    s->bitcnt = 0;

    /* get length and check against its one's complement */
    if ((s->incnt + 4) > s->inlen) return 2;    /* not enough input */
    len = s->in[s->incnt];
    s->incnt = s->incnt + 1;
    len = len | (s->in[s->incnt] << 8);
    s->incnt = s->incnt + 1;
    if(s->in[s->incnt] != (~len & 0xff)) return -2;                              /* didn't match complement! */
    s->incnt = s->incnt + 1;
    if(s->in[s->incnt] != ((~len >> 8) & 0xff)) return -2;                              /* didn't match complement! */
    s->incnt = s->incnt + 1;

    /* copy len bytes from in to out */
    if ((s->incnt + len) > s->inlen) return 2;                               /* not enough input */
    if (s->out != 0)
    {
        if ((s->outcnt + len) > s->outlen) return 1;                           /* not enough output space */
        while (0 != len)
        {
            len = len - 1;
            s->out[s->outcnt] = s->in[s->incnt];
            s->outcnt = s->outcnt + 1;
            s->incnt = s->incnt + 1;
        }
    }
    else
    {                                      /* just scanning */
        s->outcnt = s->outcnt + len;
        s->incnt = s->incnt + len;
    }

    /* done with a valid stored block */
    return 0;
}

/*
 * Huffman code decoding tables.  count[1..MAXBITS] is the number of symbols of
 * each length, which for a canonical code are stepped through in order.
 * symbol[] are the symbol values in canonical order, where the number of
 * entries is the sum of the counts in count[].  The decoding process can be
 * seen in the function decode() below.
 */
struct huffman
{
    int *count;       /* number of symbols of each length */
    int *symbol;      /* canonically ordered symbols */
};

/*
 * Decode a code from the stream s using huffman table h.  Return the symbol or
 * a negative value if there is an error.  If all of the lengths are zero, i.e.
 * an empty code, or if the code is incomplete and an invalid code is received,
 * then -10 is returned after reading MAXBITS bits.
 *
 * Format notes:
 *
 * - The codes as stored in the compressed data are bit-reversed relative to
 *   a simple integer ordering of codes of the same lengths.  Hence below the
 *   bits are pulled from the compressed data one at a time and used to
 *   build the code value reversed from what is in the stream in order to
 *   permit simple integer comparisons for decoding.  A table-based decoding
 *   scheme (as used in zlib) does not need to do this reversal.
 *
 * - The first code for the shortest length is all zeros.  Subsequent codes of
 *   the same length are simply integer increments of the previous code.  When
 *   moving up a length, a zero bit is appended to the code.  For a complete
 *   code, the last code of the longest length will be all ones.
 *
 * - Incomplete codes are handled by this decoder, since they are permitted
 *   in the deflate format.  See the format notes for fixed() and dynamic().
 */
int decode(struct state *s, struct huffman *h)
{
    int len;            /* current number of bits in code */
    int code = 0;       /* len bits being decoded */
    int first = 0;      /* first code of length len */
    int count;          /* number of codes of length len */
    int index = 0;      /* index of first code of length len in symbol table */
    long hold;

    for (len = 1; len <= MAXBITS; len = len + 1)
    {
        hold = bits(s, 1);              /* get next bit */
        code = code | hold;
        count = h->count[len];
        if ((code - count) < first)
        {
            hold = index + (code - first);
            return h->symbol[hold]; /* if length len, return symbol */
        }
        index = index + count;                 /* else update for next length */
        first = first + count;
        first = first << 1;
        code = code << 1;
    }
    return -10;                         /* ran out of codes */
}

/*
 * Given the list of code lengths length[0..n-1] representing a canonical
 * Huffman code for n symbols, construct the tables required to decode those
 * codes.  Those tables are the number of codes of each length, and the symbols
 * sorted by length, retaining their original order within each length.  The
 * return value is zero for a complete code set, negative for an over-
 * subscribed code set, and positive for an incomplete code set.  The tables
 * can be used if the return value is zero or positive, but they cannot be used
 * if the return value is negative.  If the return value is zero, it is not
 * possible for decode() using that table to return an error--any stream of
 * enough bits will resolve to a symbol.  If the return value is positive, then
 * it is possible for decode() using that table to return an error for received
 * codes past the end of the incomplete lengths.
 *
 * Not used by decode(), but used for error checking, h->count[0] is the number
 * of the n symbols not in the code.  So n - h->count[0] is the number of
 * codes.  This is useful for checking for incomplete codes that have more than
 * one symbol, which is an error in a dynamic block.
 *
 * Assumption: for all i in 0..n-1, 0 <= length[i] <= MAXBITS
 * This is assured by the construction of the length arrays in dynamic() and
 * fixed() and is not verified by construct().
 *
 * Format notes:
 *
 * - Permitted and expected examples of incomplete codes are one of the fixed
 *   codes and any code with a single symbol which in deflate is coded as one
 *   bit instead of zero bits.  See the format notes for fixed() and dynamic().
 *
 * - Within a given code length, the symbols are kept in ascending order for
 *   the code bits definition.
 */
int construct(struct huffman *h, int *length, int n)
{
    int symbol;         /* current symbol when stepping through length[] */
    int len;            /* current length when stepping through h->count[] */
    int left;           /* number of possible codes left of current length */
    int* offs;          /* offsets in symbol table for each length */
    offs = calloc(MAXBITS+1, sizeof(int));
    long hold;

    #if defined(DEBUG)
        int i;
        fputs(int2str(n, 16, FALSE), stderr);
        fputs(" : construct 0\n", stderr);

        for(i = 0; i < n; i = i + 1)
        {
            fputs(int2str(length[i], 16, FALSE), stderr);
            fputs(" : construct 2\n", stderr);
        }
    #endif

    /* count number of codes of each length */
    for (len = 0; len <= MAXBITS; len = len + 1)
    {
        h->count[len] = 0;
    }

    for (symbol = 0; symbol < n; symbol = symbol + 1)
    {
        hold = length[symbol];
        h->count[hold] = h->count[hold] + 1;    /* assumes lengths are within bounds */
    }

    if (h->count[0] == n) return 0;             /* no codes! complete, but decode() will fail */

    /* check for an over-subscribed or incomplete set of lengths */
    left = 1;                                   /* one possible code of zero length */
    for (len = 1; len <= MAXBITS; len = len + 1)
    {
        left = left << 1;                       /* one more bit, double codes left */
        left = left - h->count[len];            /* deduct count from possible codes */
        if (left < 0) return left;              /* over-subscribed--return negative */
    }                                           /* left > 0 means incomplete */

    /* generate offsets into symbol table for each length for sorting */
    offs[1] = 0;
    for (len = 1; len < MAXBITS; len = len + 1)
    {
        offs[len + 1] = offs[len] + h->count[len];
    }

    /*
     * put symbols in table sorted by length, by symbol order within each
     * length
     */
    for (symbol = 0; symbol < n; symbol = symbol + 1)
    {
        if (length[symbol] != 0)
        {
            hold = length[symbol];
            hold = offs[hold];
            h->symbol[hold] = symbol;
            hold = length[symbol];
            offs[hold] = offs[hold] + 1;
        }
    }

    /* return zero for complete set, positive for incomplete set */
    return left;
}

/*
 * Decode literal/length and distance codes until an end-of-block code.
 *
 * Format notes:
 *
 * - Compressed data that is after the block type if fixed or after the code
 *   description if dynamic is a combination of literals and length/distance
 *   pairs terminated by and end-of-block code.  Literals are simply Huffman
 *   coded bytes.  A length/distance pair is a coded length followed by a
 *   coded distance to represent a string that occurs earlier in the
 *   uncompressed data that occurs again at the current location.
 *
 * - Literals, lengths, and the end-of-block code are combined into a single
 *   code of up to 286 symbols.  They are 256 literals (0..255), 29 length
 *   symbols (257..285), and the end-of-block symbol (256).
 *
 * - There are 256 possible lengths (3..258), and so 29 symbols are not enough
 *   to represent all of those.  Lengths 3..10 and 258 are in fact represented
 *   by just a length symbol.  Lengths 11..257 are represented as a symbol and
 *   some number of extra bits that are added as an integer to the base length
 *   of the length symbol.  The number of extra bits is determined by the base
 *   length symbol.  These are in the static arrays below, lens[] for the base
 *   lengths and lext[] for the corresponding number of extra bits.
 *
 * - The reason that 258 gets its own symbol is that the longest length is used
 *   often in highly redundant files.  Note that 258 can also be coded as the
 *   base value 227 plus the maximum extra value of 31.  While a good deflate
 *   should never do this, it is not an error, and should be decoded properly.
 *
 * - If a length is decoded, including its extra bits if any, then it is
 *   followed a distance code.  There are up to 30 distance symbols.  Again
 *   there are many more possible distances (1..32768), so extra bits are added
 *   to a base value represented by the symbol.  The distances 1..4 get their
 *   own symbol, but the rest require extra bits.  The base distances and
 *   corresponding number of extra bits are below in the static arrays dist[]
 *   and dext[].
 *
 * - Literal bytes are simply written to the output.  A length/distance pair is
 *   an instruction to copy previously uncompressed bytes to the output.  The
 *   copy is from distance bytes back in the output stream, copying for length
 *   bytes.
 *
 * - Distances pointing before the beginning of the output data are not
 *   permitted.
 *
 * - Overlapped copies, where the length is greater than the distance, are
 *   allowed and common.  For example, a distance of one and a length of 258
 *   simply copies the last byte 258 times.  A distance of four and a length of
 *   twelve copies the last four bytes three times.  A simple forward copy
 *   ignoring whether the length is greater than the distance or not implements
 *   this correctly.  You should not use memcpy() since its behavior is not
 *   defined for overlapped arrays.  You should not use memmove() or bcopy()
 *   since though their behavior -is- defined for overlapping arrays, it is
 *   defined to do the wrong thing in this case.
 */

int* codes_lens()
{
    /* Size base for length codes 257..285 */
    int* r = calloc(30, sizeof(int));
    r[0] = 3;
    r[1] = 4;
    r[2] = 5;
    r[3] = 6;
    r[4] = 7;
    r[5] = 8;
    r[6] = 9;
    r[7] = 10;
    r[8] = 11;
    r[9] = 13;
    r[10] = 15;
    r[11] = 17;
    r[12] = 19;
    r[13] = 23;
    r[14] = 27;
    r[15] = 31;
    r[16] = 35;
    r[17] = 43;
    r[18] = 51;
    r[19] = 59;
    r[20] = 67;
    r[21] = 83;
    r[22] = 99;
    r[23] = 115;
    r[24] = 131;
    r[25] = 163;
    r[26] = 195;
    r[27] = 227;
    r[28] = 258;
    return r;
}

int* codes_lext()
{
    /* Extra bits for length codes 257..285 */
    int* r = calloc(30, sizeof(int));
    r[0] = 0;
    r[1] = 0;
    r[2] = 0;
    r[3] = 0;
    r[4] = 0;
    r[5] = 0;
    r[6] = 0;
    r[7] = 0;
    r[8] = 1;
    r[9] = 1;
    r[10] = 1;
    r[11] = 1;
    r[12] = 2;
    r[13] = 2;
    r[14] = 2;
    r[15] = 2;
    r[16] = 3;
    r[17] = 3;
    r[18] = 3;
    r[19] = 3;
    r[20] = 4;
    r[21] = 4;
    r[22] = 4;
    r[23] = 4;
    r[24] = 5;
    r[25] = 5;
    r[26] = 5;
    r[27] = 5;
    r[28] = 0;
    return r;
}

int* codes_dists()
{
    /* Offset base for distance codes 0..29 */
    int* r = calloc(31, sizeof(int));
    r[0] = 1;
    r[1] = 2;
    r[2] = 3;
    r[3] = 4;
    r[4] = 5;
    r[5] = 7;
    r[6] = 9;
    r[7] = 13;
    r[8] = 17;
    r[9] = 25;
    r[10] = 33;
    r[11] = 49;
    r[12] = 65;
    r[13] = 97;
    r[14] = 129;
    r[15] = 193;
    r[16] = 257;
    r[17] = 385;
    r[18] = 513;
    r[19] = 769;
    r[20] = 1025;
    r[21] = 1537;
    r[22] = 2049;
    r[23] = 3073;
    r[24] = 4097;
    r[25] = 6145;
    r[26] = 8193;
    r[27] = 12289;
    r[28] = 16385;
    r[29] = 24577;
    return r;
}

int* codes_dext()
{
    /* Extra bits for distance codes 0..29 */
    int* r = calloc(31, sizeof(int));
    r[0] = 0;
    r[1] = 0;
    r[2] = 0;
    r[3] = 0;
    r[4] = 1;
    r[5] = 1;
    r[6] = 2;
    r[7] = 2;
    r[8] = 3;
    r[9] = 3;
    r[10] = 4;
    r[11] = 4;
    r[12] = 5;
    r[13] = 5;
    r[14] = 6;
    r[15] = 6;
    r[16] = 7;
    r[17] = 7;
    r[18] = 8;
    r[19] = 8;
    r[20] = 9;
    r[21] = 9;
    r[22] = 10;
    r[23] = 10;
    r[24] = 11;
    r[25] = 11;
    r[26] = 12;
    r[27] = 12;
    r[28] = 13;
    r[29] = 13;
    return r;
}

int codes(struct state *s, struct huffman *lencode, struct huffman *distcode)
{
    int symbol;         /* decoded symbol */
    int len;            /* length for copy */
    unsigned dist;      /* distance for copy */
    int* lens = codes_lens();
    int* lext = codes_lext();
    int* dists = codes_dists();
    int* dext = codes_dext();

    /* decode literals and length/distance pairs */
    do
    {
        symbol = decode(s, lencode);
        if (symbol < 0) return symbol;          /* invalid symbol */
        if (symbol < 256)                       /* literal: symbol is the byte */
        {
            /* write out the literal */
            if (s->out != 0)
            {
                if (s->outcnt == s->outlen) return 1;
                s->out[s->outcnt] = symbol;
            }
            s->outcnt = s->outcnt + 1;
        }
        else if (symbol > 256)                  /* length */
        {
            /* get and compute length */
            symbol = symbol - 257;
            if (symbol >= 29) return -10;       /* invalid fixed code */
            len = lens[symbol] + bits(s, lext[symbol]);

            /* get and check distance */
            symbol = decode(s, distcode);
            if (symbol < 0) return symbol;      /* invalid symbol */
            dist = dists[symbol] + bits(s, dext[symbol]);
            if (dist > s->outcnt) return -11;   /* distance too far back */

            /* copy length bytes from distance bytes back */
            if (s->out != 0)
            {
                if (s->outcnt + len > s->outlen) return 1;
                while (0 != len)
                {
                    len = len - 1;
                    if(dist > s->outcnt) s->out[s->outcnt] = 0;
                    else s->out[s->outcnt] = s->out[s->outcnt - dist];
                    s->outcnt = s->outcnt + 1;
                }
            }
            else s->outcnt = s->outcnt + len;
        }
    } while (symbol != 256);            /* end of block symbol */

    /* done with a valid fixed or dynamic block */
    return 0;
}

/*
 * Process a fixed codes block.
 *
 * Format notes:
 *
 * - This block type can be useful for compressing small amounts of data for
 *   which the size of the code descriptions in a dynamic block exceeds the
 *   benefit of custom codes for that block.  For fixed codes, no bits are
 *   spent on code descriptions.  Instead the code lengths for literal/length
 *   codes and distance codes are fixed.  The specific lengths for each symbol
 *   can be seen in the "for" loops below.
 *
 * - The literal/length code is complete, but has two symbols that are invalid
 *   and should result in an error if received.  This cannot be implemented
 *   simply as an incomplete code since those two symbols are in the "middle"
 *   of the code.  They are eight bits long and the longest literal/length\
 *   code is nine bits.  Therefore the code must be constructed with those
 *   symbols, and the invalid symbols must be detected after decoding.
 *
 * - The fixed distance codes also have two invalid symbols that should result
 *   in an error if received.  Since all of the distance codes are the same
 *   length, this can be implemented as an incomplete code.  Then the invalid
 *   codes are detected while decoding.
 */
int fixed(struct state *s)
{
    int* lencnt = calloc((MAXBITS + 1), sizeof(int));
    int* lensym = calloc(FIXLCODES, sizeof(int));
    int* distcnt = calloc((MAXBITS + 1), sizeof(int));
    int* distsym = calloc(MAXDCODES, sizeof(int));
    struct huffman* lencode = calloc(1, sizeof(struct huffman));
    struct huffman* distcode = calloc(1, sizeof(struct huffman));
    int hold;

    /* build fixed huffman tables if first call (may not be thread safe) */
    int symbol;
    int* lengths = calloc(FIXLCODES, sizeof(int));

    /* construct lencode and distcode */
    lencode->count = lencnt;
    lencode->symbol = lensym;
    distcode->count = distcnt;
    distcode->symbol = distsym;

    /* literal/length table */
    for (symbol = 0; symbol < 144; symbol = symbol + 1)
    {
        lengths[symbol] = 8;
    }

    while(symbol < 256)
    {
        lengths[symbol] = 9;
        symbol = symbol + 1;
    }

    while(symbol < 280)
    {
        lengths[symbol] = 7;
        symbol = symbol + 1;
    }

    while(symbol < FIXLCODES)
    {
        lengths[symbol] = 8;
        symbol = symbol + 1;
    }

    construct(lencode, lengths, FIXLCODES);

    /* distance table */
    for (symbol = 0; symbol < MAXDCODES; symbol = symbol + 1)
    {
        lengths[symbol] = 5;
    }

    construct(distcode, lengths, MAXDCODES);

    /* decode data until end-of-block code */
    hold = codes(s, lencode, distcode);
    return hold;
}

/*
 * Process a dynamic codes block.
 *
 * Format notes:
 *
 * - A dynamic block starts with a description of the literal/length and
 *   distance codes for that block.  New dynamic blocks allow the compressor to
 *   rapidly adapt to changing data with new codes optimized for that data.
 *
 * - The codes used by the deflate format are "canonical", which means that
 *   the actual bits of the codes are generated in an unambiguous way simply
 *   from the number of bits in each code.  Therefore the code descriptions
 *   are simply a list of code lengths for each symbol.
 *
 * - The code lengths are stored in order for the symbols, so lengths are
 *   provided for each of the literal/length symbols, and for each of the
 *   distance symbols.
 *
 * - If a symbol is not used in the block, this is represented by a zero as
 *   as the code length.  This does not mean a zero-length code, but rather
 *   that no code should be created for this symbol.  There is no way in the
 *   deflate format to represent a zero-length code.
 *
 * - The maximum number of bits in a code is 15, so the possible lengths for
 *   any code are 1..15.
 *
 * - The fact that a length of zero is not permitted for a code has an
 *   interesting consequence.  Normally if only one symbol is used for a given
 *   code, then in fact that code could be represented with zero bits.  However
 *   in deflate, that code has to be at least one bit.  So for example, if
 *   only a single distance base symbol appears in a block, then it will be
 *   represented by a single code of length one, in particular one 0 bit.  This
 *   is an incomplete code, since if a 1 bit is received, it has no meaning,
 *   and should result in an error.  So incomplete distance codes of one symbol
 *   should be permitted, and the receipt of invalid codes should be handled.
 *
 * - It is also possible to have a single literal/length code, but that code
 *   must be the end-of-block code, since every dynamic block has one.  This
 *   is not the most efficient way to create an empty block (an empty fixed
 *   block is fewer bits), but it is allowed by the format.  So incomplete
 *   literal/length codes of one symbol should also be permitted.
 *
 * - If there are only literal codes and no lengths, then there are no distance
 *   codes.  This is represented by one distance code with zero bits.
 *
 * - The list of up to 286 length/literal lengths and up to 30 distance lengths
 *   are themselves compressed using Huffman codes and run-length encoding.  In
 *   the list of code lengths, a 0 symbol means no code, a 1..15 symbol means
 *   that length, and the symbols 16, 17, and 18 are run-length instructions.
 *   Each of 16, 17, and 18 are follwed by extra bits to define the length of
 *   the run.  16 copies the last length 3 to 6 times.  17 represents 3 to 10
 *   zero lengths, and 18 represents 11 to 138 zero lengths.  Unused symbols
 *   are common, hence the special coding for zero lengths.
 *
 * - The symbols for 0..18 are Huffman coded, and so that code must be
 *   described first.  This is simply a sequence of up to 19 three-bit values
 *   representing no code (0) or the code length for that symbol (1..7).
 *
 * - A dynamic block starts with three fixed-size counts from which is computed
 *   the number of literal/length code lengths, the number of distance code
 *   lengths, and the number of code length code lengths (ok, you come up with
 *   a better name!) in the code descriptions.  For the literal/length and
 *   distance codes, lengths after those provided are considered zero, i.e. no
 *   code.  The code length code lengths are received in a permuted order (see
 *   the order[] array below) to make a short code length code length list more
 *   likely.  As it turns out, very short and very long codes are less likely
 *   to be seen in a dynamic code description, hence what may appear initially
 *   to be a peculiar ordering.
 *
 * - Given the number of literal/length code lengths (nlen) and distance code
 *   lengths (ndist), then they are treated as one long list of nlen + ndist
 *   code lengths.  Therefore run-length coding can and often does cross the
 *   boundary between the two sets of lengths.
 *
 * - So to summarize, the code description at the start of a dynamic block is
 *   three counts for the number of code lengths for the literal/length codes,
 *   the distance codes, and the code length codes.  This is followed by the
 *   code length code lengths, three bits each.  This is used to construct the
 *   code length code which is used to read the remainder of the lengths.  Then
 *   the literal/length code lengths and distance lengths are read as a single
 *   set of lengths using the code length codes.  Codes are constructed from
 *   the resulting two sets of lengths, and then finally you can start
 *   decoding actual compressed data in the block.
 *
 * - For reference, a "typical" size for the code description in a dynamic
 *   block is around 80 bytes.
 */

int* dynamic_order()
{
    /* permutation of code length codes */
    int* r = calloc(20, sizeof(int));
    r[0] = 16;
    r[1] = 17;
    r[2] = 18;
    r[3] = 0;
    r[4] = 8;
    r[5] = 7;
    r[6] = 9;
    r[7] = 6;
    r[8] = 10;
    r[9] = 5;
    r[10] = 11;
    r[11] = 4;
    r[12] = 12;
    r[13] = 3;
    r[14] = 13;
    r[15] = 2;
    r[16] = 14;
    r[17] = 1;
    r[18] = 15;
    return r;
}

int dynamic(struct state *s)
{
    #if defined(__M2__)
        int array = sizeof(int);
    #else
        int array = 1;
    #endif

    int nlen;
    int ndist;
    int ncode;                          /* number of lengths in descriptor */
    int index;                          /* index of lengths[] */
    int err;                            /* construct() return value */
    int* lengths = calloc(MAXCODES, sizeof(int));       /* descriptor code lengths */
    int* lencnt = calloc((MAXBITS + 1), sizeof(int));
    int* lensym = calloc(MAXLCODES, sizeof(int));       /* lencode memory */
    int* distcnt = calloc((MAXBITS + 1), sizeof(int));
    int* distsym = calloc(MAXDCODES, sizeof(int));      /* distcode memory */
    struct huffman* lencode = calloc(1, sizeof(struct huffman));
    struct huffman* distcode = calloc(1, sizeof(struct huffman));
    int* order = dynamic_order();
    long hold;
    int* set;

    /* construct lencode and distcode */
    lencode->count = lencnt;
    lencode->symbol = lensym;
    distcode->count = distcnt;
    distcode->symbol = distsym;

    /* get number of lengths in each table, check lengths */
    nlen = bits(s, 5) + 257;
    ndist = bits(s, 5) + 1;
    ncode = bits(s, 4) + 4;
    if (nlen > MAXLCODES) return -3;    /* bad counts */
    if(ndist > MAXDCODES) return -3;    /* bad counts */

    /* read code length code lengths (really), missing lengths are zero */
    for (index = 0; index < ncode; index = index + 1)
    {
        hold = order[index];
        lengths[hold] = bits(s, 3);
    }

    while(index < 19)
    {
        hold = order[index];
        lengths[hold] = 0;
        index = index + 1;
    }

    /* build huffman table for code lengths codes (use lencode temporarily) */
    err = construct(lencode, lengths, 19);
    if (err != 0) return -4;            /* require complete code set here */

    /* read length/literal and distance code length tables */
    index = 0;
    int symbol;                         /* decoded value */
    int len;                            /* last length to repeat */
    while (index < (nlen + ndist))
    {
        symbol = decode(s, lencode);
        if (symbol < 0) return symbol;  /* invalid symbol */

        if (symbol < 16)                /* length in 0..15 */
        {
            lengths[index] = symbol;
            index = index + 1;
        }
        else                            /* repeat instruction */
        {
            len = 0;                    /* assume repeating zeros */
            if (symbol == 16)           /* repeat last length 3..6 times */
            {
                if (index == 0) return -5;      /* no last length! */
                len = lengths[index - 1];       /* last length */
                symbol = 3 + bits(s, 2);
            }
            else if (symbol == 17) symbol = 3 + bits(s, 3); /* repeat zero 3..10 times */
            else symbol = 11 + bits(s, 7);      /* == 18, repeat zero 11..138 times */

            if ((index + symbol) > (nlen + ndist)) return -6;   /* too many lengths! */

            while(0 != symbol)            /* repeat last or zero symbol times */
            {
                lengths[index] = len;
                index = index + 1;
                symbol = symbol - 1;
            }
        }
    }

    /* check for end-of-block code -- there better be one! */
    if (lengths[256] == 0) return -9;

    /* build huffman table for literal/length codes */
    err = construct(lencode, lengths, nlen);

    /* incomplete code ok only for single length 1 code */
    if (err < 0) return -7;
    if((0 != err) && (nlen != (lencode->count[0] + lencode->count[1]))) return -7;

    /* build huffman table for distance codes */
    set = lengths + (nlen * array);
    err = construct(distcode, set, ndist);

    /* incomplete code ok only for single length 1 code */
    if (err < 0) return -8;
    if((0 != err) && (ndist != (distcode->count[0] + distcode->count[1]))) return -8;

    /* decode data until end-of-block code */
    hold = codes(s, lencode, distcode);
    return hold;
}

/*
 * Inflate source to dest.  On return, destlen and sourcelen are updated to the
 * size of the uncompressed data and the size of the deflate data respectively.
 * On success, the return value of puff() is zero.  If there is an error in the
 * source data, i.e. it is not in the deflate format, then a negative value is
 * returned.  If there is not enough input available or there is not enough
 * output space, then a positive error is returned.  In that case, destlen and
 * sourcelen are not updated to facilitate retrying from the beginning with the
 * provision of more input data or more output space.  In the case of invalid
 * inflate data (a negative error), the dest and source pointers are updated to
 * facilitate the debugging of deflators.
 *
 * puff() also has a mode to determine the size of the uncompressed output with
 * no output written.  For this dest must be (unsigned char *)0.  In this case,
 * the input value of *destlen is ignored, and on return *destlen is set to the
 * size of the uncompressed output.
 *
 * The return codes are:
 *
 *   2:  available inflate data did not terminate
 *   1:  output space exhausted before completing inflate
 *   0:  successful inflate
 *  -1:  invalid block type (type == 3)
 *  -2:  stored block length did not match one's complement
 *  -3:  dynamic block code description: too many length or distance codes
 *  -4:  dynamic block code description: code lengths codes incomplete
 *  -5:  dynamic block code description: repeat lengths with no first length
 *  -6:  dynamic block code description: repeat more than specified lengths
 *  -7:  dynamic block code description: invalid literal/length code lengths
 *  -8:  dynamic block code description: invalid distance code lengths
 *  -9:  dynamic block code description: missing end-of-block code
 * -10:  invalid literal/length or distance code in fixed or dynamic block
 * -11:  distance is too far back in fixed or dynamic block
 *
 * Format notes:
 *
 * - Three bits are read for each block to determine the kind of block and
 *   whether or not it is the last block.  Then the block is decoded and the
 *   process repeated if it was not the last block.
 *
 * - The leftover bits in the last byte of the deflate data after the last
 *   block (if it was a fixed or dynamic block) are undefined and have no
 *   expected values to check.
 */

struct puffer
{
    int error;
    size_t destlen;
    size_t sourcelen;
};

struct puffer* puff(char* dest, size_t destlen, char* source, size_t sourcelen)
{
    struct state* s = calloc(1, sizeof(struct state));             /* input/output state */
    int last;
    int type;                   /* block information */
    int err;                    /* return value */

    /* initialize output state */
    s->out = dest;
    s->outlen = destlen;                /* ignored if dest is NIL */
    s->outcnt = 0;

    /* initialize input state */
    s->in = source;
    s->inlen = sourcelen;
    s->incnt = 0;
    s->bitbuf = 0;
    s->bitcnt = 0;

    /* process blocks until last block or error */
    do
    {
        last = bits(s, 1);         /* one if last block */
        type = bits(s, 2);         /* block type 0..3 */

        if(0 == type)
        {
            err = stored(s);
        }
        else if(1 == type)
        {
            err = fixed(s);
        }
        else if(2 == type)
        {
            err = dynamic(s);
        }
        else err = -1;

        if (err != 0) break;                  /* return with error */
    } while (!last);

    /* update the lengths and return */
    struct puffer* r = calloc(1, sizeof(struct puffer));
    r->error = err;
    r->destlen = s->outcnt;
    r->sourcelen = s->incnt;
    return r;
}

void write_blob(char* s, int start, int len, FILE* f)
{
    char* table = "0123456789ABCDEF";
    if(start > len) return;

    int i = s[start] & 0xFF;
    fputc(table[(i >> 4)], f);
    fputc(table[(i & 0xF)], f);
    fputc(' ', f);

    if(start == len) fputc('\n', f);
    else fputc(' ', f);
    write_blob(s, start + 1, len, f);
}

#define FTEXT 0x01
#define FHCRC 0x02
#define FEXTRA 0x04
#define FNAME 0x08
#define FCOMMENT 0x10


struct gz
{
    char* HEADER;
    int ID;
    int CM;
    int FLG;
    int MTIME;
    int XFL;
    int OS;
    int XLEN;
    char* FLG_FEXTRA;
    char* FLG_FNAME;
    char* FLG_FCOMMENT;
    int CRC16;
    char* FLG_FHCRC;
    char* block;
    int CRC32;
    size_t ISIZE;
    size_t file_size;
};

/* Read the input file *name, or stdin if name is NULL, into allocated memory.
   Reallocate to larger buffers until the entire file is read in.  Return a
   pointer to the allocated data, or NULL if there was a memory allocation
   failure.  *len is the number of bytes of data read from the input file (even
   if load() returns NULL).  If the input file was empty or could not be opened
   or read, *len is zero. */
struct gz* load(char* name)
{
    struct gz* r = calloc(1, sizeof(struct gz));
    char* scratch = calloc(5, sizeof(char));
    FILE* f = fopen(name, "r");
    int count;
    int ID1;
    int ID2;
    int count1;
    int count2;
    int count3;
    int count4;
    int c;
    int i;
    char* s = calloc(11, sizeof(char));

    if(NULL == f)
    {
        fputs("unable to open file: ", stderr);
        fputs(name, stderr);
        fputs("\nfor reading\n", stderr);
        return NULL;
    }

    fseek(f, 0, SEEK_END);
    r->file_size = ftell(f);
    fseek(f, 0, SEEK_SET);
    count = fread(s, sizeof(char), 10, f);

    if(10 != count)
    {
        fputs("incomplete gzip header\n", stderr);
        return NULL;
    }

    /* Verify header */
    r->HEADER = s;

    #if defined(DEBUG)
        write_blob(s, 0, 10, stderr);
    #endif

    ID1 = (s[0] & 0xFF);
    ID2 = (s[1] & 0xFF);
    r->ID = ((ID1 << 8) | ID2);
    if(0x1f8b != r->ID)
    {
        fputs("bad header\n", stderr);
        return NULL;
    }

    /* Verify Compression */
    r->CM = (r->HEADER[2] & 0xFF);
    if(8 != r->CM)
    {
        fputs("NOT DEFLATE COMPRESSION\n", stderr);
        return NULL;
    }

    /* Get specials specified in flag bits */
    r->FLG = (r->HEADER[3] & 0xFF);

    if(0 != (FEXTRA & r->FLG))
    {
        count = fread(scratch, sizeof(char), 4, f);
        count1 = (scratch[0] & 0xFF);
        count2 = (scratch[1] & 0xFF);
        count3 = (scratch[2] & 0xFF);
        count4 = (scratch[3] & 0xFF);
        count = (count1 << 24) | (count2 << 16) | (count3 << 8) | count4;
        require(0 < count, "FEXTRA field needs to be a positive number of bytes in size\n");
        require(100000000 > count, "we don't support FEXTRA fields greater than 100MB in size\n");
        r->FLG_FEXTRA = calloc(count + 1, sizeof(char));
        fread(r->FLG_FEXTRA, sizeof(char), count, f);
    }

    if(0 != (FNAME & r->FLG))
    {
        r->FLG_FNAME = calloc(r->file_size, sizeof(char));
        i = 0;
        do
        {
            c = fgetc(f);
            require(0 <= c, "received a non-null terminated filename in the file\n");
            r->FLG_FNAME[i] = c;
            i = i + 1;
        } while(0 != c);
    }

    if(0 != (FCOMMENT & r->FLG))
    {
        r->FLG_FCOMMENT = calloc(r->file_size, sizeof(char));
        i = 0;
        do
        {
            c = fgetc(f);
            require(0 <= c, "received a non-null terminated comment in the file\n");
            r->FLG_FCOMMENT[i] = c;
            i = i + 1;
        } while(0 != c);
    }

    if(0 != (FHCRC & r->FLG))
    {
        /* Not implemented */
        fputs("FHCRC is not implemented at this time\n", stderr);
        return NULL;
    }

    if(NULL == r->FLG_FNAME)
    {
        count = strlen(name) - 3;
        r->FLG_FNAME = calloc(count + 4, sizeof(char));
        i = 0;
        while(i < count)
        {
            r->FLG_FNAME[i] = name[i];
            i = i + 1;
        }
    }

    r->block = calloc(r->file_size, sizeof(char));
    count = fread(r->block, sizeof(char), r->file_size, f);
    r->ISIZE = count;
    fclose(f);
    return r;
}

int main(int argc, char **argv)
{
    struct puffer* ret;
    char* name;
    char* buffer;
    char *dest;
    struct gz* in;
    FILE* out;
    int FUZZING = FALSE;

    /* process arguments */
    int i = 1;
    while (i < argc)
    {
        if(NULL == argv[i])
        {
            i = i + 1;
        }
        else if(match(argv[i], "-f") || match(argv[i], "--file"))
        {
            name = argv[i+1];
            require(NULL != name, "the --file option requires a filename to be given\n");
            i = i + 2;
        }
        else if(match(argv[i], "-o") || match(argv[i], "--output"))
        {
            dest = argv[i+1];
            require(NULL != dest, "the --output option requires a filename to be given\n");
            i = i + 2;
        }
        else if(match(argv[i], "--chaos") || match(argv[i], "--fuzz-mode") || match(argv[i], "--fuzzing"))
        {
            FUZZING = TRUE;
            fputs("fuzz-mode enabled, preparing for chaos\n", stderr);
            i = i + 1;
        }
        else if(match(argv[i], "-h") || match(argv[i], "--help"))
        {
            fputs("Usage: ", stderr);
            fputs(argv[0], stderr);
            fputs(" --file $input.gz", stderr);
            fputs(" [--output $output] (or it'll use the internal filename)\n", stderr);
            fputs("--help to get this message\n", stderr);
            fputs("--fuzz-mode if you wish to fuzz this application safely\n", stderr);
            exit(EXIT_SUCCESS);
        }
        else
        {
            fputs("Unknown option:", stderr);
            fputs(argv[i], stderr);
            fputs("\nAborting to avoid problems\n", stderr);
            exit(EXIT_FAILURE);
        }
    }

    in = load(name);

    if (in == NULL)
    {
        fputs("memory allocation failure\nDidn't read file\n", stderr);
        exit(1);
    }

    ret = puff(0, 0, in->block, in->ISIZE);

    if(NULL == dest)
    {
        dest = in->FLG_FNAME;
    }

    fputs(name, stderr);
    fputs(" => ", stderr);
    fputs(dest, stderr);

    if (0 != ret->error)
    {
        fputs("puff() failed with return code ", stderr);
        fputs(int2str(ret->error, 10, TRUE), stderr);
        fputc('\n', stderr);
        exit(3);
    }
    else
    {
        fputs(": succeeded uncompressing ", stderr);
        fputs(int2str(ret->destlen, 10, FALSE), stderr);
        fputs(" bytes\n", stderr);
    }

    buffer = malloc(ret->destlen);
    if (buffer == NULL)
    {
        fputs("memory allocation failure\n", stderr);
        return 4;
    }

    ret = puff(buffer, ret->destlen, in->block, in->ISIZE);

    if(!FUZZING)
    {
        out = fopen(dest, "w");
        fwrite(buffer, 1, ret->destlen, out);
    }
    else
    {
        fputs("skipped write to file due to --fuzz-mode flag\n", stderr);
    }
    free(buffer);

    /* clean up */
    return 0;
}

https://github.com/oriansj/mescc-tools-extra/blob/main/unbz2.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools-extra/unbz2.c used in: Step 71
/* Copyright (C) 2003, 2007 Rob Landley <rob@landley.net>
 * Copyright (C) 2022 Paul Dersey <pdersey@gmail.com>
 * This file is part of mescc-tools-extra
 *
 * mescc-tools-extra is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * mescc-tools-extra is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with mescc-tools-extra.  If not, see <http://www.gnu.org/licenses/>.
 */

/* bzcat.c - bzip2 decompression
 *
 * Copyright 2003, 2007 Rob Landley <rob@landley.net>
 *
 * Based on a close reading (but not the actual code) of the original bzip2
 * decompression code by Julian R Seward (jseward@acm.org), which also
 * acknowledges contributions by Mike Burrows, David Wheeler, Peter Fenwick,
 * Alistair Moffat, Radford Neal, Ian H. Witten, Robert Sedgewick, and
 * Jon L. Bentley.
 *
 * No standard.
*/

/* unbz2.c is a bz2 file decompression utility based on bzcat.c with
 * modifications to enable being built by M2-Planet with M2libc.
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include "M2libc/bootstrappable.h"

// Constants for huffman coding
#define MAX_GROUPS               6
#define GROUP_SIZE               50     /* 64 would have been more efficient */
#define MAX_HUFCODE_BITS         20     /* Longest huffman code allowed */
#define MAX_SYMBOLS              258    /* 256 literals + RUNA + RUNB */
#define SYMBOL_RUNA              0
#define SYMBOL_RUNB              1

// Other housekeeping constants
#define IOBUF_SIZE               4096

// Status return values
#define RETVAL_LAST_BLOCK        (-100)
#define RETVAL_NOT_BZIP_DATA     (-1)
#define RETVAL_DATA_ERROR        (-2)
#define RETVAL_OBSOLETE_INPUT    (-3)

#define INT_MAX 2147483647

// This is what we know about each huffman coding group
struct group_data
{
    int *limit;
    int *base;
    int *permute;
    char minLen;
    char maxLen;
};

// Data for burrows wheeler transform

struct bwdata
{
    unsigned origPtr;
    int *byteCount;
    // State saved when interrupting output
    int writePos;
    int writeRun;
    int writeCount;
    int writeCurrent;
    unsigned dataCRC;
    unsigned headerCRC;
    unsigned *dbuf;
};

// Structure holding all the housekeeping data, including IO buffers and
// memory that persists between calls to bunzip
struct bunzip_data
{
    // Input stream, input buffer, input bit buffer
    int in_fd;
    int inbufCount;
    int inbufPos;
    char *inbuf;
    unsigned inbufBitCount;
    unsigned inbufBits;

    // Output buffer
    char *outbuf;
    int outbufPos;

    unsigned totalCRC;

    // First pass decompression data (Huffman and MTF decoding)
    char *selectors;                  // nSelectors=15 bits
    struct group_data *groups;   // huffman coding tables
    int symTotal;
    int groupCount;
    int nSelectors;
    unsigned *symToByte;
    unsigned *mtfSymbol;

    // The CRC values stored in the block header and calculated from the data
    unsigned *crc32Table;

    // Second pass decompression data (burrows-wheeler transform)
    unsigned dbufSize;
    struct bwdata* bwdata;
};

int FUZZING;


void crc_init(unsigned *crc_table, int little_endian)
{
    unsigned i;
    unsigned j;
    unsigned c;

    // Init the CRC32 table (big endian)
    for(i = 0; i < 256; i += 1)
    {
        if(little_endian)
        {
            c = i;
        }
        else
        {
            c = i << 24;
        }

        for(j = 8; j > 0; j -= 1)
        {
            if(little_endian)
            {
                if(c & 1)
                {
                    c = (c >> 1) ^ 0xEDB88320;
                }
                else
                {
                    c = c >> 1;
                }
            }
            else
            {
                if(c & 0x80000000)
                {
                    c = (c << 1) ^ 0x04C11DB7;
#if defined(__M2__)

                    // & 0xFFFFFFFF not working
                    if(sizeof(unsigned) == 8)
                    {
                        c <<= 32;
                        c >>= 32;
                    }

#endif
                }
                else
                {
                    c = c << 1;
                }
            }
        }

        crc_table[i] = c;
    }
}

// Return the next nnn bits of input.  All reads from the compressed input
// are done through this function.  All reads are big endian.
unsigned get_bits(struct bunzip_data *bd, char bits_wanted)
{
    unsigned bits = 0;

    // If we need to get more data from the byte buffer, do so.  (Loop getting
    // one byte at a time to enforce endianness and avoid unaligned access.)
    while(bd->inbufBitCount < bits_wanted)
    {
        // If we need to read more data from file into byte buffer, do so
        if(bd->inbufPos == bd->inbufCount)
        {
            if(0 >= (bd->inbufCount = read(bd->in_fd, bd->inbuf, IOBUF_SIZE)))
            {
                exit(1);
            }

            bd->inbufPos = 0;
        }

        // Avoid 32-bit overflow (dump bit buffer to top of output)
        if(bd->inbufBitCount >= 24)
        {
            bits = bd->inbufBits & ((1 << bd->inbufBitCount) - 1);
            bits_wanted = bits_wanted - bd->inbufBitCount;
            bits = bits << bits_wanted;
            bd->inbufBitCount = 0;
        }

        // Grab next 8 bits of input from buffer.
        bd->inbufBits = (bd->inbufBits << 8) | (bd->inbuf[bd->inbufPos] & 0xFF);
        bd->inbufPos = bd->inbufPos + 1;
        bd->inbufBitCount = bd->inbufBitCount + 8;
    }

    // Calculate result
    bd->inbufBitCount = bd->inbufBitCount - bits_wanted;
    bits = bits | ((bd->inbufBits >> bd->inbufBitCount) & ((1 << bits_wanted) - 1));
    return bits;
}

/* Read block header at start of a new compressed data block.  Consists of:
 *
 * 48 bits : Block signature, either pi (data block) or e (EOF block).
 * 32 bits : bw->headerCRC
 * 1  bit  : obsolete feature flag.
 * 24 bits : origPtr (Burrows-wheeler unwind index, only 20 bits ever used)
 * 16 bits : Mapping table index.
 *[16 bits]: symToByte[symTotal] (Mapping table.  For each bit set in mapping
 *           table index above, read another 16 bits of mapping table data.
 *           If correspondig bit is unset, all bits in that mapping table
 *           section are 0.)
 *  3 bits : groupCount (how many huffman tables used to encode, anywhere
 *           from 2 to MAX_GROUPS)
 * variable: hufGroup[groupCount] (MTF encoded huffman table data.)
 */

int read_block_header(struct bunzip_data *bd, struct bwdata *bw)
{
    struct group_data *hufGroup;
    int hh;
    int ii;
    int jj;
    int kk;
    int symCount;
    int *base;
    int *limit;
    unsigned uc;
    unsigned *length = calloc(MAX_SYMBOLS, sizeof(unsigned));
    unsigned *temp = calloc(MAX_HUFCODE_BITS + 1, sizeof(unsigned));
    size_t minLen;
    size_t maxLen;
    int pp;
#if defined(__M2__)
    int int_array = sizeof(int);
    int group_data_array = sizeof(struct group_data);
#else
    int int_array = 1;
    int group_data_array = 1;
#endif
    size_t hold;
    // Read in header signature and CRC (which is stored big endian)
    ii = get_bits(bd, 24);
    jj = get_bits(bd, 24);
    bw->headerCRC = get_bits(bd, 32);

    // Is this the EOF block with CRC for whole file?  (Constant is "e")
    if(ii == 0x177245 && jj == 0x385090)
    {
        free(length);
        free(temp);
        return RETVAL_LAST_BLOCK;
    }

    // Is this a valid data block?  (Constant is "pi".)
    if(ii != 0x314159 || jj != 0x265359)
    {
        return RETVAL_NOT_BZIP_DATA;
    }

    // We can add support for blockRandomised if anybody complains.
    if(get_bits(bd, 1))
    {
        return RETVAL_OBSOLETE_INPUT;
    }

    if((bw->origPtr = get_bits(bd, 24)) > bd->dbufSize)
    {
        return RETVAL_DATA_ERROR;
    }

    // mapping table: if some byte values are never used (encoding things
    // like ascii text), the compression code removes the gaps to have fewer
    // symbols to deal with, and writes a sparse bitfield indicating which
    // values were present.  We make a translation table to convert the symbols
    // back to the corresponding bytes.
    hh = get_bits(bd, 16);
    bd->symTotal = 0;

    for(ii = 0; ii < 16; ii += 1)
    {
        if(hh & (1 << (15 - ii)))
        {
            kk = get_bits(bd, 16);

            for(jj = 0; jj < 16; jj += 1)
            {
                if(kk & (1 << (15 - jj)))
                {
                    bd->symToByte[bd->symTotal] = (16 * ii) + jj;
                    bd->symTotal += 1;
                }
            }
        }
    }

    // How many different huffman coding groups does this block use?
    bd->groupCount = get_bits(bd, 3);

    if(bd->groupCount < 2 || bd->groupCount > MAX_GROUPS)
    {
        return RETVAL_DATA_ERROR;
    }

    // nSelectors: Every GROUP_SIZE many symbols we switch huffman coding
    // tables.  Each group has a selector, which is an index into the huffman
    // coding table arrays.
    //
    // Read in the group selector array, which is stored as MTF encoded
    // bit runs.  (MTF = Move To Front.  Every time a symbol occurs its moved
    // to the front of the table, so it has a shorter encoding next time.)
    if(!(bd->nSelectors = get_bits(bd, 15)))
    {
        return RETVAL_DATA_ERROR;
    }

    for(ii = 0; ii < bd->groupCount; ii += 1)
    {
        bd->mtfSymbol[ii] = ii;
    }

    for(ii = 0; ii < bd->nSelectors; ii += 1)
    {
        // Get next value
        for(jj = 0; get_bits(bd, 1); jj += 1)
            if(jj >= bd->groupCount)
            {
                return RETVAL_DATA_ERROR;
            }

        // Decode MTF to get the next selector, and move it to the front.
        uc = bd->mtfSymbol[jj];

        while(jj)
        {
            jj = jj - 1;
            bd->mtfSymbol[jj + 1] = bd->mtfSymbol[jj];
        }

        bd->mtfSymbol[0] = bd->selectors[ii] = uc;
    }

    // Read the huffman coding tables for each group, which code for symTotal
    // literal symbols, plus two run symbols (RUNA, RUNB)
    symCount = bd->symTotal + 2;

    for(jj = 0; jj < bd->groupCount; jj += 1)
    {
        // Read lengths
        hh = get_bits(bd, 5);

        for(ii = 0; ii < symCount; ii += 1)
        {
            while(TRUE)
            {
                // !hh || hh > MAX_HUFCODE_BITS in one test.
                if(MAX_HUFCODE_BITS - 1 < hh - 1)
                {
                    return RETVAL_DATA_ERROR;
                }

                // Grab 2 bits instead of 1 (slightly smaller/faster).  Stop if
                // first bit is 0, otherwise second bit says whether to
                // increment or decrement.
                kk = get_bits(bd, 2);

                if(kk & 2)
                {
                    hh += (1 - ((kk & 1) << 1));
                }
                else
                {
                    bd->inbufBitCount += 1;
                    break;
                }
            }

            length[ii] = hh;
        }

        // Find largest and smallest lengths in this group
        minLen = maxLen = length[0];

        for(ii = 1; ii < symCount; ii += 1)
        {
            hold = length[ii];
            if(hold > maxLen)
            {
                maxLen = hold;
            }
            else if(hold < minLen)
            {
                minLen = hold;
            }
        }

        /* Calculate permute[], base[], and limit[] tables from length[].
         *
         * permute[] is the lookup table for converting huffman coded symbols
         * into decoded symbols.  It contains symbol values sorted by length.
         *
         * base[] is the amount to subtract from the value of a huffman symbol
         * of a given length when using permute[].
         *
         * limit[] indicates the largest numerical value a symbol with a given
         * number of bits can have.  It lets us know when to stop reading.
         *
         * To use these, keep reading bits until value <= limit[bitcount] or
         * youve read over 20 bits (error).  Then the decoded symbol
         * equals permute[hufcode_value - base[hufcode_bitcount]].
         */
        hufGroup = bd->groups + (group_data_array * jj);
        require(minLen > 0, "hufGroup minLen can't have negative values\n");
        require(minLen <= MAX_HUFCODE_BITS, "hufGroup minLen can't exceed MAX_HUFCODE_BITS\n");
        hufGroup->minLen = minLen;
        require(maxLen > 0, "hufGroup maxLen can't have negative values\n");
        require(maxLen <= MAX_HUFCODE_BITS, "hufGroup maxLen can't exceed MAX_HUFCODE_BITS\n");
        hufGroup->maxLen = maxLen;
        // Note that minLen cant be smaller than 1, so we adjust the base
        // and limit array pointers so were not always wasting the first
        // entry.  We do this again when using them (during symbol decoding).
        base = hufGroup->base - (int_array * 1);
        require(0 <= base, "can't have a negative hufGroup->base\n");
        limit = hufGroup->limit - (int_array * 1);
        // zero temp[] and limit[], and calculate permute[]
        pp = 0;

        for(ii = minLen; ii <= maxLen; ii += 1)
        {
            require(MAX_HUFCODE_BITS >= ii, "Invalid HUFCODE_BITS length\n");
            temp[ii] = 0;
            limit[ii] = 0;

            for(hh = 0; hh < symCount; hh += 1)
            {
                if(length[hh] == ii)
                {
                    require(MAX_SYMBOLS >= pp, "pp exceeded MAX_SYMBOLS\n");
                    hufGroup->permute[pp] = hh;
                    pp += 1;
                }
            }
        }

        // Count symbols coded for at each bit length
        for(ii = 0; ii < symCount; ii += 1)
        {
            hold = length[ii];
            require(MAX_HUFCODE_BITS >= hold, "Invalid HUFCODE_BITS length\n");
            temp[hold] += 1;
        }

        /* Calculate limit[] (the largest symbol-coding value at each bit
         * length, which is (previous limit<<1)+symbols at this level), and
         * base[] (number of symbols to ignore at each bit length, which is
         * limit minus the cumulative count of symbols coded for already). */
        pp = hh = 0;

        for(ii = minLen; ii < maxLen; ii += 1)
        {
            pp += temp[ii];
            limit[ii] = pp - 1;
            pp = pp << 1;
            hh += temp[ii];
            base[ii + 1] = pp - hh;
        }

        limit[maxLen] = pp + temp[maxLen] - 1;
        limit[maxLen + 1] = INT_MAX;
        base[minLen] = 0;
    }

    free(length);
    free(temp);
    return 0;
}

/* First pass, read blocks symbols into dbuf[dbufCount].
 *
 * This undoes three types of compression: huffman coding, run length encoding,
 * and move to front encoding.  We have to undo all those to know when weve
 * read enough input.
 */

int read_huffman_data(struct bunzip_data *bd, struct bwdata *bw)
{
    struct group_data *hufGroup;
    int ii;
    int jj;
    int kk;
    int runPos;
    int dbufCount;
    int symCount;
    int selector;
    int nextSym;
    int *byteCount;
    int *base;
    int *limit;
    unsigned hh;
    unsigned *dbuf = bw->dbuf;
    unsigned uc;
#if defined(__M2__)
    int int_array = sizeof(int);
    int group_data_array = sizeof(struct group_data);
#else
    int int_array = 1;
    int group_data_array = 1;
#endif
    // Weve finished reading and digesting the block header.  Now read this
    // blocks huffman coded symbols from the file and undo the huffman coding
    // and run length encoding, saving the result into dbuf[dbufCount++] = uc
    // Initialize symbol occurrence counters and symbol mtf table
    byteCount = bw->byteCount;

    for(ii = 0; ii < 256; ii += 1)
    {
        byteCount[ii] = 0;
        bd->mtfSymbol[ii] = ii;
    }

    // Loop through compressed symbols.  This is the first "tight inner loop"
    // that needs to be micro-optimized for speed.  (This one fills out dbuf[]
    // linearly, staying in cache more, so isnt as limited by DRAM access.)
    runPos = 0;
    dbufCount = 0;
    symCount = 0;
    selector = 0;
    // Some unnecessary initializations to shut gcc up.
    base = 0;
    limit = 0;
    hufGroup = 0;
    hh = 0;

    while(TRUE)
    {
        // Have we reached the end of this huffman group?
        if(!(symCount))
        {
            // Determine which huffman coding group to use.
            symCount = GROUP_SIZE - 1;

            if(selector >= bd->nSelectors)
            {
                return RETVAL_DATA_ERROR;
            }

            hufGroup = bd->groups + (group_data_array * bd->selectors[selector]);
            selector += 1;
            base = hufGroup->base - (int_array * 1);
            require(0 <= base, "can't have negative hufGroup->base\n");
            limit = hufGroup->limit - (int_array * 1);
        }
        else
        {
            symCount -= 1;
        }

        // Read next huffman-coded symbol (into jj).
        ii = hufGroup->minLen;
        jj = get_bits(bd, ii);

        while(jj > limit[ii])
        {
            // if (ii > hufGroup->maxLen) return RETVAL_DATA_ERROR;
            ii += 1;

            // Unroll get_bits() to avoid a function call when the datas in
            // the buffer already.
            if(bd->inbufBitCount)
            {
                bd->inbufBitCount -= 1;
                kk = (bd->inbufBits >> bd->inbufBitCount) & 1;
            }
            else
            {
                kk = get_bits(bd, 1);
            }

            jj = (jj << 1) | kk;
        }

        // Huffman decode jj into nextSym (with bounds checking)
        jj -= base[ii];

        if(ii > hufGroup->maxLen || jj >= MAX_SYMBOLS)
        {
            return RETVAL_DATA_ERROR;
        }

        nextSym = hufGroup->permute[jj];

        // If this is a repeated run, loop collecting data
        if(nextSym <= SYMBOL_RUNB)
        {
            // If this is the start of a new run, zero out counter
            if(!runPos)
            {
                runPos = 1;
                hh = 0;
            }

            /* Neat trick that saves 1 symbol: instead of or-ing 0 or 1 at
               each bit position, add 1 or 2 instead. For example,
               1011 is 1<<0 + 1<<1 + 2<<2. 1010 is 2<<0 + 2<<1 + 1<<2.
               You can make any bit pattern that way using 1 less symbol than
               the basic or 0/1 method (except all bits 0, which would use no
               symbols, but a run of length 0 doesnt mean anything in this
               context). Thus space is saved. */
            hh += (runPos << nextSym); // +runPos if RUNA; +2*runPos if RUNB
            runPos = runPos << 1;
            continue;
        }

        /* When we hit the first non-run symbol after a run, we now know
           how many times to repeat the last literal, so append that many
           copies to our buffer of decoded symbols (dbuf) now. (The last
           literal used is the one at the head of the mtfSymbol array.) */
        if(runPos)
        {
            runPos = 0;

            // Check for integer overflow
            if(hh > bd->dbufSize || dbufCount + hh > bd->dbufSize)
            {
                return RETVAL_DATA_ERROR;
            }

            uc = bd->symToByte[bd->mtfSymbol[0]];
            byteCount[uc] += hh;

            while(hh)
            {
                hh -= 1;
                dbuf[dbufCount] = uc;
                dbufCount += 1;
            }
        }

        // Is this the terminating symbol?
        if(nextSym > bd->symTotal)
        {
            break;
        }

        /* At this point, the symbol we just decoded indicates a new literal
           character. Subtract one to get the position in the MTF array
           at which this literal is currently to be found. (Note that the
           result cant be -1 or 0, because 0 and 1 are RUNA and RUNB.
           Another instance of the first symbol in the mtf array, position 0,
           would have been handled as part of a run.) */
        if(dbufCount >= bd->dbufSize)
        {
            return RETVAL_DATA_ERROR;
        }

        ii = nextSym - 1;
        uc = bd->mtfSymbol[ii];

        // On my laptop, unrolling this memmove() into a loop shaves 3.5% off
        // the total running time.
        while(ii)
        {
            ii -= 1;
            bd->mtfSymbol[ii + 1] = bd->mtfSymbol[ii];
        }

        bd->mtfSymbol[0] = uc;
        uc = bd->symToByte[uc];
        // We have our literal byte.  Save it into dbuf.
        byteCount[uc] += 1;
        dbuf[dbufCount] = uc;
        dbufCount += 1;
    }

    // Now we know what dbufCount is, do a better sanity check on origPtr.
    if(bw->origPtr >= (bw->writeCount = dbufCount))
    {
        return RETVAL_DATA_ERROR;
    }

    return 0;
}

// Flush output buffer to disk
void flush_bunzip_outbuf(struct bunzip_data *bd, int out_fd)
{
    if(bd->outbufPos)
    {
        if(write(out_fd, bd->outbuf, bd->outbufPos) != bd->outbufPos)
        {
            exit(1);
        }

        bd->outbufPos = 0;
    }
}

void burrows_wheeler_prep(struct bunzip_data *bd, struct bwdata *bw)
{
    int ii;
    int jj;
    int kk;
    unsigned *dbuf = bw->dbuf;
    int *byteCount = bw->byteCount;
    unsigned uc;
    // Turn byteCount into cumulative occurrence counts of 0 to n-1.
    jj = 0;

    for(ii = 0; ii < 256; ii += 1)
    {
        kk = jj + byteCount[ii];
        byteCount[ii] = jj;
        jj = kk;
    }

    // Use occurrence counts to quickly figure out what order dbuf would be in
    // if we sorted it.
    for(ii = 0; ii < bw->writeCount; ii += 1)
    {
        uc = dbuf[ii] & 0xFF;
        dbuf[byteCount[uc]] = dbuf[byteCount[uc]] | (ii << 8);
        byteCount[uc] += 1;
    }

    // blockRandomised support would go here.
    // Using ii as position, jj as previous character, hh as current character,
    // and uc as run count.
    bw->dataCRC = 0xffffffff;

    /* Decode first byte by hand to initialize "previous" byte. Note that it
       doesnt get output, and if the first three characters are identical
       it doesnt qualify as a run (hence uc=255, which will either wrap
       to 1 or get reset). */
    if(bw->writeCount)
    {
        bw->writePos = dbuf[bw->origPtr];
        bw->writeCurrent = bw->writePos;
        bw->writePos = bw->writePos >> 8;
        bw->writeRun = -1;
    }
}

// Decompress a block of text to intermediate buffer
int read_bunzip_data(struct bunzip_data *bd)
{
    int rc = read_block_header(bd, bd->bwdata);

    if(!rc)
    {
        rc = read_huffman_data(bd, bd->bwdata);
    }

    // First thing that can be done by a background thread.
    burrows_wheeler_prep(bd, bd->bwdata);
    return rc;
}

// Undo burrows-wheeler transform on intermediate buffer to produce output.
// If !len, write up to len bytes of data to buf.  Otherwise write to out_fd.
// Returns len ? bytes written : 0.  Notice all errors are negative #s.
//
// Burrows-wheeler transform is described at:
// http://dogma.net/markn/articles/bwt/bwt.htm
// http://marknelson.us/1996/09/01/bwt/

int write_bunzip_data(struct bunzip_data *bd, struct bwdata *bw,
                      int out_fd, char *outbuf, int len)
{
    unsigned *dbuf = bw->dbuf;
    int count;
    int pos;
    int current;
    int run;
    int copies;
    int outbyte;
    int previous;
    int gotcount = 0;
    int i;
    int crc_index;

    while(TRUE)
    {
        // If last read was short due to end of file, return last block now
        if(bw->writeCount < 0)
        {
            return bw->writeCount;
        }

        // If we need to refill dbuf, do it.
        if(!bw->writeCount)
        {
            i = read_bunzip_data(bd);

            if(i)
            {
                if(i == RETVAL_LAST_BLOCK)
                {
                    bw->writeCount = i;
                    return gotcount;
                }
                else
                {
                    return i;
                }
            }
        }

        // loop generating output
        count = bw->writeCount;
        pos = bw->writePos;
        current = bw->writeCurrent;
        run = bw->writeRun;

        while(count)
        {
            // If somebody (like tar) wants a certain number of bytes of
            // data from memory instead of written to a file, humor them.
            if(len && bd->outbufPos >= len)
            {
                goto dataus_interruptus;
            }

            count -= 1;
            // Follow sequence vector to undo Burrows-Wheeler transform.
            previous = current;
            pos = dbuf[pos];
            current = pos & 0xff;
            pos = pos >> 8;

            // Whenever we see 3 consecutive copies of the same byte,
            // the 4th is a repeat count
            if(run == 3)
            {
                run += 1;
                copies = current;
                outbyte = previous;
                current = -1;
            }
            else
            {
                run += 1;
                copies = 1;
                outbyte = current;
            }

            // Output bytes to buffer, flushing to file if necessary
            while(copies)
            {
                copies -= 1;

                if(bd->outbufPos == IOBUF_SIZE)
                {
                    flush_bunzip_outbuf(bd, out_fd);
                }

                bd->outbuf[bd->outbufPos] = outbyte;
                bd->outbufPos += 1;
                crc_index = ((bw->dataCRC >> 24) ^ outbyte) & 0xFF;
                bw->dataCRC = (bw->dataCRC << 8) ^ bd->crc32Table[crc_index];
            }

            if(current != previous)
            {
                run = 0;
            }
        }

        // decompression of this block completed successfully
        bw->dataCRC = ~(bw->dataCRC);
#if defined(__M2__)

        // & 0xFFFFFFFF not working
        if(sizeof(unsigned) == 8)
        {
            bw->dataCRC <<= 32;
            bw->dataCRC >>= 32;
        }

#endif
        bd->totalCRC = ((bd->totalCRC << 1) | (bd->totalCRC >> 31)) ^ bw->dataCRC;

        // if this block had a crc error, force file level crc error.
        if(bw->dataCRC != bw->headerCRC)
        {
            bd->totalCRC = bw->headerCRC + 1;
            return RETVAL_LAST_BLOCK;
        }

dataus_interruptus:
        bw->writeCount = count;

        if(len)
        {
            gotcount += bd->outbufPos;
            memcpy(outbuf, bd->outbuf, len);
            // If we got enough data, checkpoint loop state and return
            len -= bd->outbufPos;

            if(len < 1)
            {
                bd->outbufPos -= len;

                if(bd->outbufPos)
                {
                    memmove(bd->outbuf, bd->outbuf + len, bd->outbufPos);
                }

                bw->writePos = pos;
                bw->writeCurrent = current;
                bw->writeRun = run;
                return gotcount;
            }
        }
    }
}

// Allocate the structure, read file header. If !len, src_fd contains
// filehandle to read from. Else inbuf contains data.
int start_bunzip(struct bunzip_data **bdp, int src_fd)
{
    struct bunzip_data *bd;
    unsigned i;
    // Figure out how much data to allocate.
    i = sizeof(struct bunzip_data);
    // Allocate bunzip_data. Most fields initialize to zero.
    *bdp = malloc(i);
    bd = *bdp;
    memset(bd, 0, i);
    bd->inbuf = calloc(IOBUF_SIZE, sizeof(char));
    bd->outbuf = calloc(IOBUF_SIZE, sizeof(char));
    bd->selectors = calloc(32768, sizeof(char));
    bd->groups = calloc(MAX_GROUPS, sizeof(struct group_data));

    for(i = 0; i < MAX_GROUPS; i += 1)
    {
        bd->groups[i].limit = calloc(MAX_HUFCODE_BITS + 1, sizeof(int));
        bd->groups[i].base = calloc(MAX_HUFCODE_BITS, sizeof(int));
        bd->groups[i].permute = calloc(MAX_SYMBOLS, sizeof(int));
    }

    bd->symToByte = calloc(256, sizeof(unsigned));
    bd->mtfSymbol = calloc(256, sizeof(unsigned));
    bd->crc32Table = calloc(256, sizeof(unsigned));
    bd->bwdata = calloc(1, sizeof(struct bwdata));
    bd->bwdata->byteCount = calloc(256, sizeof(int));
    unsigned *crc32Table;
    bd->in_fd = src_fd;
    crc_init(bd->crc32Table, 0);
    // Ensure that file starts with "BZh".
    char *header = "BZh";

    for(i = 0; i < 3; i += 1) if(get_bits(bd, 8) != header[i])
        {
            return RETVAL_NOT_BZIP_DATA;
        }

    // Next byte ascii 1-9, indicates block size in units of 100k of
    // uncompressed data. Allocate intermediate buffer for block.
    i = get_bits(bd, 8);

    if(i < 49 || i > 57)
    {
        return RETVAL_NOT_BZIP_DATA;
    }

    bd->dbufSize = 100000 * (i - 48);
    bd->bwdata[0].dbuf = malloc(bd->dbufSize * sizeof(int));
    return 0;
}

// Example usage: decompress src_fd to dst_fd. (Stops at end of bzip data,
// not end of file.)
int bunzipStream(int src_fd, int dst_fd)
{
    struct bunzip_data *bd;
    int i;
    int j;

    if(!(i = start_bunzip(&bd, src_fd)))
    {
        i = write_bunzip_data(bd, bd->bwdata, dst_fd, 0, 0);

        if(i == RETVAL_LAST_BLOCK)
        {
            if(bd->bwdata[0].headerCRC == bd->totalCRC)
            {
                i = 0;
            }
            else
            {
                i = RETVAL_DATA_ERROR;
            }
        }
    }

    flush_bunzip_outbuf(bd, dst_fd);
    free(bd->bwdata[0].dbuf);
    free(bd->inbuf);
    free(bd->outbuf);
    free(bd->selectors);

    for(j = 0; j < MAX_GROUPS; j += 1)
    {
        free(bd->groups[j].limit);
        free(bd->groups[j].base);
        free(bd->groups[j].permute);
    }

    free(bd->groups);
    free(bd->symToByte);
    free(bd->mtfSymbol);
    free(bd->crc32Table);
    free(bd->bwdata->byteCount);
    free(bd->bwdata);
    free(bd);
    return -i;
}

void do_bunzip2(int in_fd, int out_fd)
{
    int err = bunzipStream(in_fd, out_fd);

    if(err)
    {
        exit(1);
    }
}

int main(int argc, char **argv)
{
    char *name = NULL;
    char *dest = NULL;
    FUZZING = FALSE;

    /* process arguments */
    int i = 1;

    while(i < argc)
    {
        if(NULL == argv[i])
        {
            i += 1;
        }
        else if(match(argv[i], "-f") || match(argv[i], "--file"))
        {
            name = argv[i + 1];
            require(NULL != name, "the --file option requires a filename to be given\n");
            i += 2;
        }
        else if(match(argv[i], "-o") || match(argv[i], "--output"))
        {
            dest = argv[i + 1];
            require(NULL != dest, "the --output option requires a filename to be given\n");
            i += 2;
        }
        else if(match(argv[i], "--fuzzing-mode"))
        {
            FUZZING = TRUE;
            i += 1;
        }
        else if(match(argv[i], "-h") || match(argv[i], "--help"))
        {
            fputs("Usage: ", stderr);
            fputs(argv[0], stderr);
            fputs(" --file $input.bz2", stderr);
            fputs(" --output $output\n", stderr);
            fputs("--help to get this message\n", stderr);
            exit(EXIT_SUCCESS);
        }
        else
        {
            fputs("Unknown option:", stderr);
            fputs(argv[i], stderr);
            fputs("\nAborting to avoid problems\n", stderr);
            exit(EXIT_FAILURE);
        }
    }

    /* Deal with no input */
    if(NULL == name)
    {
        fputs("an input file (--file $name) must be provided\n", stderr);
        exit(EXIT_FAILURE);
    }

    int in_fd = open(name, 0, 0);

    if(in_fd < 0)
    {
        fputs("Unable to open input file\n", stderr);
        exit(EXIT_FAILURE);
    }

    /* If an output name isn't provided */
    if(NULL == dest)
    {
        int length = strlen(name);
        require(length > 4, "file name length not sufficient, please provide output name with --output $filename\n");
    }

    int out_fd;
    if(FUZZING)
    {
        /* Dump to /dev/null the garbage data produced during fuzzing */
        out_fd = open("/dev/null", O_WRONLY|O_CREAT|O_TRUNC, 0600);
    }
    else
    {
        out_fd = open(dest, O_WRONLY|O_CREAT|O_TRUNC, 0600);
    }

    if(out_fd < 0)
    {
        fputs("Unable to open output file for writing\n", stderr);
        exit(EXIT_FAILURE);
    }

    do_bunzip2(in_fd, out_fd);
    close(in_fd);
    close(out_fd);
    exit(0);
}

https://github.com/oriansj/mescc-tools-extra/blob/main/catm.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools-extra/catm.c used in: Step 72
/* Copyright (C) 2019 Jeremiah Orians
 * This file is part of mescc-tools
 *
 * mescc-tools is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * mescc-tools is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with mescc-tools.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

// CONSTANT BUFFER_SIZE 4096
#define BUFFER_SIZE 4096

int main(int argc, char** argv)
{
    if(2 > argc)
    {
        fputs("catm requires 2 or more arguments\n", stderr);
        exit(EXIT_FAILURE);
    }

    int output = open(argv[1], 577 , 384);
    if(-1 == output)
    {
        fputs("The file: ", stderr);
        fputs(argv[1], stderr);
        fputs(" is not a valid output file name\n", stderr);
        exit(EXIT_FAILURE);
    }

    int i;
    int bytes;
    char* buffer = calloc(BUFFER_SIZE + 1, sizeof(char));
    int input;
    for(i = 2; i < argc ; i =  i + 1)
    {
        input = open(argv[i], 0, 0);
        if(-1 == input)
        {
            fputs("The file: ", stderr);
            fputs(argv[i], stderr);
            fputs(" is not a valid input file name\n", stderr);
            exit(EXIT_FAILURE);
        }
keep:
        bytes = read(input, buffer, BUFFER_SIZE);
        write(output, buffer, bytes);
        if(BUFFER_SIZE == bytes) goto keep;
    }

    free(buffer);
    return EXIT_SUCCESS;
}

https://github.com/oriansj/mescc-tools-extra/blob/main/cp.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools-extra/cp.c used in: Step 73
/* Copyright (C) 2020 fosslinux
 * This file is part of mescc-tools
 *
 * mescc-tools is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * mescc-tools is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with mescc-tools.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include "M2libc/bootstrappable.h"

/* Define all of the constants */
// CONSTANT FALSE 0
#define FALSE 0
// CONSTANT TRUE 1
#define TRUE 1
// CONSTANT MAX_STRING 4096
#define MAX_STRING 4096
// CONSTANT MAX_ARRAY 256
#define MAX_ARRAY 256

/* Prototypes for external funcs */

/* Globals */
int verbose;

/* UTILITY FUNCTIONS */

/* Function to find a character's position in a string (last match) */
int find_last_char_pos(char* string, char a)
{
    int i = strlen(string) - 1;
    if(i < 0) return i;
    while(i >= 0)
    {
        /*
         * This conditional should be in the while conditional but we are
         * running into the M2-Planet short-circuit bug.
         */
        if(a == string[i]) break;
        i = i - 1;
    }
    return i;
}

/* Function to find the length of a char**; an array of strings */
int array_length(char** array)
{
    int length = 0;
    while(array[length] != NULL)
    {
        length = length + 1;
    }
    return length;
}

/* PROCESSING FUNCTIONS */

char* directory_dest(char* dest, char* source, int require_directory)
{
    /*
     * First, check if it is a directory to copy to.
     * We have two ways of knowing this:
     * - If the destination ends in a slash, the user has explicitly said
     *   it is a directory.
     * - Normally we would use stat() but we don't want to force support for
     *   that syscall onto the kernel, so we just attempt to chdir() into it
     *   and if it works then it must be a directory. A bit hacky, bit it
     *   works.
     */
    int isdirectory = FALSE;
    if(dest[strlen(dest) - 1] == '/')
    {
        isdirectory = TRUE;
    }
    if(!isdirectory)
    { /* Use the other testing method */
        /*
         * Get the current path so that we can chdir back to it if it does
         * chdir successfully.
         */
        char* current_path = calloc(MAX_STRING, sizeof(char));
        require(current_path != NULL, "Memory initialization of current_path in directory_dest failed\n");
        getcwd(current_path, MAX_STRING);
        require(!match("", current_path), "getcwd() failed\n");
        /*
         * chdir expects an absolute path.
         * If the first character is / then it is already absolute, otherwise
         * it is relative and needs to be changed (by appending current_path
         * to the dest path).
         */
        char* chdir_dest = calloc(MAX_STRING, sizeof(char));
        require(chdir_dest != NULL, "Memory initialization of chdir_dest in directory_dest failed\n");
        if(dest[0] != '/')
        { /* The path is relative, append current_path */
            strcat(chdir_dest, current_path);
            strcat(chdir_dest, "/");
            strcat(chdir_dest, dest);
        }
        else
        { /* The path is absolute */
            strcpy(chdir_dest, dest);
        }
        if(0 <= chdir(chdir_dest))
        { /* chdir returned successfully */
            /*
             * But because of M2-Planet, that dosen't mean anything actually
             * happened, check that before we go any further.
             */
            char* new_path = calloc(MAX_STRING, sizeof(char));
            require(new_path != NULL, "Memory initialization of new_path in directory_dest failed\n");
            getcwd(new_path, MAX_STRING);
            if(!match(current_path, new_path))
            {
                isdirectory = TRUE;
                chdir(current_path);
            }
        }
        free(chdir_dest);
        free(current_path);
    }

    /*
     * If it isn't a directory, and we require one, error out.
     * Otherwise, just return what we were given, we're done here.
     */
    if(require_directory) require(isdirectory, "Provide a directory destination for multiple source files\n");
    if(!isdirectory) return dest;

    /* If it is, we need to make dest a full path */
    /* 1. Get the basename of source */
    char* basename = calloc(MAX_STRING, sizeof(char));
    require(basename != NULL, "Memory initialization of basename in directory_dest failed\n");
    int last_slash_pos = find_last_char_pos(source, '/');
    if(last_slash_pos >= 0)
    { /* Yes, there is a slash in it, copy over everything after that pos */
        unsigned spos; /* source pos */
        unsigned bpos = 0; /* basename pos */
        /* Do the actual copy */
        for(spos = last_slash_pos + 1; spos < strlen(source); spos = spos + 1)
        {
            basename[bpos] = source[spos];
            bpos = bpos + 1;
        }
    }
    else
    { /* No, there is no slash in it, hence the basename is just the source */
        strcpy(basename, source);
    }
    /* 2. Ensure our dest (which is a directory) has a trailing slash */
    if(dest[strlen(dest) - 1] != '/')
    {
        strcat(dest, "/");
    }
    /* 3. Add the basename to the end of the directory */
    strcat(dest, basename);
    free(basename);

    /* Now we have a returnable path! */
    return dest;
}

void copy_file(char* source, char* dest)
{
    if(verbose)
    { /* Output message */
        /* Of the form 'source' -> 'dest' */
        fputs("'", stdout);
        fputs(source, stdout);
        fputs("' -> '", stdout);
        fputs(dest, stdout);
        fputs("'\n", stdout);
    }

    /* Open source and dest as FILE*s */
    FILE* fsource = fopen(source, "r");
    if(fsource == NULL)
    {
        fputs("Error opening source file ", stderr);
        fputs(source, stderr);
        fputc('\n', stderr);
        exit(EXIT_FAILURE);
    }
    FILE* fdest = fopen(dest, "w");
    if(fdest < 0)
    {
        fputs("Error opening destination file", stderr);
        fputs(dest, stderr);
        fputc('\n', stderr);
        exit(EXIT_FAILURE);
    }

    /*
     * The following loop reads a character from the source and writes it to the
     * dest file. This is all M2-Planet supports.
     */
    int c = fgetc(fsource);
    while(c != EOF)
    {
        fputc(c, fdest);
        c = fgetc(fsource);
    }

    /* Cleanup */
    fclose(fsource);
    fclose(fdest);
}

int main(int argc, char** argv)
{
    /* Initialize variables */
    char** sources = calloc(MAX_ARRAY, sizeof(char*));
    require(sources != NULL, "Memory initialization of sources failed\n");
    int sources_index = 0;
    char* dest = NULL;

    /* Set defaults */
    verbose = FALSE;

    int i = 1;
    int j;
    int args_found;
    /* Loop arguments */
    while(i <= argc)
    {
        if(NULL == argv[i])
        { /* Ignore and continue */
            i = i + 1;
        }
        else if(match(argv[i], "-h") || match(argv[i], "--help"))
        {
            fputs("Usage: ", stdout);
            fputs(argv[0], stdout);
            fputs(" [-h | --help] [-V | --version] [-v | --verbose] source1 source2 sourcen destination\n", stdout);
            exit(EXIT_SUCCESS);
        }
        else if(match(argv[i], "-V") || match(argv[i], "--version"))
        { /* Output version */
            fputs("cp version 1.2.1\n", stdout);
            exit(EXIT_SUCCESS);
        }
        else if(match(argv[i], "-v") || match(argv[i], "--verbose"))
        {
            verbose = TRUE;
            i = i + 1;
        }
        else if(argv[i][0] != '-')
        { /* It is not an option */
            /*
             * We can tell if this is the source file or the destination file
             * through looking *ahead*. If it is the last of this type of argument then
             * it must be the destination. (1 destination, many sources).
             */
            j = i + 1;
            args_found = 0;
            while(j < array_length(argv))
            {
                if(argv[j][0] != '-')
                { /* It's one of these type of arguments */
                    args_found = args_found + 1;
                }
                j = j + 1;
            }
            if(args_found == 0)
            { /* We are setting the destination (there are no more left after this) */
                dest = calloc(MAX_STRING, sizeof(char));
                require(dest != NULL, "Memory initialization of dest failed\n");
                strcpy(dest, argv[i]);
            }
            else
            { /* We are setting a source */
                require(sources_index < MAX_ARRAY, "Too many files\n");
                sources[sources_index] = calloc(MAX_STRING, sizeof(char));
                require(sources[sources_index] != NULL, "Memory initialization of sources[source_index] failed\n");
                strcpy(sources[sources_index], argv[i]);
                sources_index = sources_index + 1;
            }
            i = i + 1;
        }
        else
        { /* Unknown argument */
            fputs("UNKNOWN_ARGUMENT\n", stderr);
            exit(EXIT_FAILURE);
        }
    }

    /* Sanitize values */
    /* Ensure the two values have values */
    /* Another workaround for short-circuit bug */
    int error = FALSE;
    if(sources[0] == NULL) error = TRUE;
    if(error == FALSE) if(match(sources[0], "")) error = TRUE;
    require(!error, "Provide a source file\n");
    error = FALSE;
    if(dest == NULL) error = TRUE;
    if(error == FALSE) if(match(dest, "")) error = TRUE;
    require(!error, "Provide a destination file\n");

    /* Loop through all of the sources, copying each one */
    char* this_dest;
    for(i = 0; i < array_length(sources); i = i + 1)
    {
        /* Convert the dest variable to a full path if it's a directory copying to */
        /*
         * Also, if there is more than one source, we have to be copying to
         * a directory destination...
         */
        if(array_length(sources) == 1)
        {
            dest = directory_dest(dest, sources[i], FALSE);
            copy_file(sources[i], dest);
        }
        else
        {
            this_dest = calloc(MAX_STRING, sizeof(char));
            require(this_dest != NULL, "Memory initalization of this_dest failed\n");
            this_dest = directory_dest(dest, sources[i], TRUE);
            copy_file(sources[i], this_dest);
        }
        /* Perform the actual copy */
        free(sources[i]);
    }

    free(sources);
    free(dest);

    return EXIT_SUCCESS;
}

https://github.com/oriansj/mescc-tools-extra/blob/main/chmod.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools-extra/chmod.c used in: Step 74
/* Copyright (C) 2020 fosslinux
 * This file is part of mescc-tools
 *
 * mescc-tools is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * mescc-tools is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with mescc-tools.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include "M2libc/bootstrappable.h"

/* Define all of the constants */
// CONSTANT FALSE 0
#define FALSE 0
// CONSTANT TRUE 1
#define TRUE 1
// CONSTANT MAX_STRING 4096
#define MAX_STRING 4096
// CONSTANT MAX_ARRAY 256
#define MAX_ARRAY 256

struct files
{
    char* name;
    struct files* next;
};

/* Globals */
int verbose;

/* PROCESSING FUNCTIONS */
int main(int argc, char** argv)
{
    /* Initialize variables */
    char* mode = NULL;
    struct files* f = NULL;
    struct files* n;
    int ok;

    /* Set defaults */
    verbose = FALSE;

    int i = 1;
    /* Loop arguments */
    while(i <= argc)
    {
        if(NULL == argv[i])
        { /* Ignore and continue */
            i = i + 1;
        }
        else if(match(argv[i], "-h") || match(argv[i], "--help"))
        {
            fputs("Usage: ", stdout);
            fputs(argv[0], stdout);
            fputs(" [-h | --help] [-V | --version] [-v | --verbose]\n", stdout);
            exit(EXIT_SUCCESS);
        }
        else if(match(argv[i], "-V") || match(argv[i], "--version"))
        { /* Output version */
            fputs("chmod version 1.2.1\n", stdout);
            exit(EXIT_SUCCESS);
        }
        else if(match(argv[i], "-v") || match(argv[i], "--verbose"))
        {
            verbose = TRUE;
            i = i + 1;
        }
        else
        { /* It must be the file or the mode */
            if(mode == NULL)
            { /* Mode always comes first */
                mode = calloc(MAX_STRING, sizeof(char));
                require(mode != NULL, "Memory initialization of mode failed\n");
                /* We need to indicate it is octal */
                strcat(mode, "0");
                strcat(mode, argv[i]);
            }
            else
            { /* It's a file, as the mode is already done */
                n = calloc(1, sizeof(struct files));
                require(n != NULL, "Memory initialization of files failed\n");
                n->next = f;
                f = n;
                f->name = argv[i];
            }
            i = i + 1;
        }
    }

    /* Ensure the two values have values */
    require(mode != NULL, "Provide a mode\n");
    require(f != NULL, "Provide a file\n");

    /* Convert the mode str into octal */
    int omode = strtoint(mode);

    /* Loop over files to be operated on */
    while(NULL != f)
    {
        /* Make sure the file can be opened */
        ok = access(f->name, 0);
        if(ok != 0)
        {
            fputs("The file: ", stderr);
            fputs(f->name, stderr);
            fputs(" does not exist\n", stderr);
            exit(EXIT_FAILURE);
        }

        /* Verbose message */
        if(verbose)
        {
            fputs("mode of '", stdout);
            fputs(f->name, stdout);
            fputs("' changed to ", stdout);
            fputs(mode, stdout);
            fputs("\n", stdout);
        }

        /* Perform the chmod */
        chmod(f->name, omode);
        f = f->next;
    }
}

https://github.com/oriansj/mescc-tools-extra/blob/main/rm.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools-extra/rm.c used in: Step 75
/* Copyright (C) 2021 Jeremiah Orians
 * This file is part of mescc-tools-extra
 *
 * mescc-tools-extra is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * mescc-tools-extra is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with mescc-tools-extra.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
 * "rm" can be used to delete files. It can also delete
 * parent directories.
 *
 * Usage: rm <dir1>/<file1> <file2>
 *
 * These are all highly standard and portable headers. */
#include <stdio.h>
#include <string.h>

/* This is for unlink() ; this may need to be changed for some platforms. */
#include <unistd.h>  /* For unlink() */
#include <stdlib.h>
#include "M2libc/bootstrappable.h"

void delete_dir(char* name)
{
    int r = unlink(name);
    if(0 != r)
    {
        fputs("unable to delete file: ", stderr);
        fputs(name, stderr);
        fputs(" !!!\n", stderr);
    }
}

int main(int argc, char **argv)
{
    int i;
    for(i = 1; argc > i; i = i + 1)
    {
        delete_dir(argv[i]);
    }

    return 0;
}

https://github.com/oriansj/mescc-tools-extra/blob/main/replace.c

File: ../git/live-bootstrap/sysa/stage0-posix/src/mescc-tools-extra/replace.c used in: Step 76
/* Copyright (C) 2019 Jeremiah Orians
 * This file is part of mescc-tools
 *
 * mescc-tools is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * mescc-tools is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with mescc-tools.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "M2libc/bootstrappable.h"

char* input_name;
FILE* input;
char* output_name;
FILE* output;
char* pattern;
size_t pattern_length;
char* replacement;
char* buffer;
size_t buffer_index;
char* hold;

void read_next_byte()
{
    int c= hold[0];
    size_t i = 0;
    while(i < pattern_length)
    {
        hold[i] = hold[i+1];
        i = i + 1;
    }

    hold[pattern_length-1] = buffer[buffer_index];
    buffer_index = buffer_index + 1;

    /* NEVER WRITE NULLS!!! */
    if(0 != c) fputc(c, output);
}

void clear_hold()
{
    /* FILL hold with NULLS */
    size_t i = 0;
    while(i < pattern_length)
    {
        hold[i] = 0;
        i = i + 1;
    }
}

void check_match()
{
    /* Do the actual replacing */
    if(match(pattern, hold))
    {
        fputs(replacement, output);
        clear_hold();
    }
}

int main(int argc, char** argv)
{
    output_name = "/dev/stdout";
    pattern = NULL;
    replacement = NULL;
    buffer_index = 0;

    int i = 1;
    while (i < argc)
    {
        if(NULL == argv[i])
        {
            i = i + 1;
        }
        else if(match(argv[i], "-f") || match(argv[i], "--file"))
        {
            input_name = argv[i+1];
            require(NULL != input_name, "the --file option requires a filename to be given\n");
            i = i + 2;
        }
        else if(match(argv[i], "-o") || match(argv[i], "--output"))
        {
            output_name = argv[i+1];
            require(NULL != output_name, "the --output option requires a filename to be given\n");
            i = i + 2;
        }
        else if(match(argv[i], "-m") || match(argv[i], "--match-on"))
        {
            pattern = argv[i+1];
            require(NULL != pattern, "the --match-on option requires a string to be given\n");
            i = i + 2;
        }
        else if(match(argv[i], "-r") || match(argv[i], "--replace-with"))
        {
            replacement = argv[i+1];
            require(NULL != replacement, "the --replace-with option requires a string to be given\n");
            i = i + 2;
        }
        else if(match(argv[i], "-h") || match(argv[i], "--help"))
        {
            fputs("Usage: ", stderr);
            fputs(argv[0], stderr);
            fputs(" --file $input", stderr);
            fputs(" --match-on $string", stderr);
            fputs(" --replace-with $string", stderr);
            fputs(" [--output $output] (or it'll dump to stdout)\n", stderr);
            fputs("--help to get this message\n", stderr);
            exit(EXIT_SUCCESS);
        }
        else
        {
            fputs("Unknown option:", stderr);
            fputs(argv[i], stderr);
            fputs("\nAborting to avoid problems\n", stderr);
            exit(EXIT_FAILURE);
        }
    }

    /* Sanity check that we got everything we need */
    require(NULL != input_name, "You need to pass an input file with --file\n");
    require(NULL != output_name, "You need to pass an output file with --output\n");
    require(NULL != pattern, "You can't do a replacement without something to match on\n");
    require(NULL != replacement, "You can't do a replacement without something to replace it with\n");

    input = fopen(input_name, "r");
    require(NULL != input, "unable to open requested input file!\n");

    /* Get enough buffer to read it all */
    fseek(input, 0, SEEK_END);
    size_t size = ftell(input);
    buffer = malloc((size + 8) * sizeof(char));

    /* Save ourself work if the input file is too small */
    pattern_length = strlen(pattern);
    require(pattern_length < size, "input file is to small for pattern\n");

    /* Now read it all into buffer */
    fseek(input, 0, SEEK_SET);
    size_t r = fread(buffer,sizeof(char), size, input);
    require(r == size, "incomplete read of input\n");
    fclose(input);

    /* Now we can safely open the output (which could have been the same as the input */
    output = fopen(output_name, "w");
    require(NULL != input, "unable to open requested output file!\n");

    /* build our match buffer */
    hold = calloc(pattern_length + 4, sizeof(char));
    require(NULL != hold, "temp memory allocation failed\n");

    /* Replace it all */
    while((size + pattern_length + 4) >= buffer_index)
    {
        read_next_byte();
        check_match();
    }
    fclose(output);
}

https://github.com/oriansj/stage0-posix/blob/main/x86.answers

File: ../git/live-bootstrap/sysa/stage0-posix/src/x86.answers used in: Step 77
275d135eea485d900553def672a53a1d3c627010660da3e5834658154bc9b8e6  x86/bin/blood-elf
dee788ac575fbaea8695c5f2f79fda5593fa23b5aae14420b74df0a6fa15be45  x86/bin/catm
7a2bd22b80a88d28d88df2193d71d506dbd09713b412287a71449ef8f727d90a  x86/bin/chmod
7b4e27df73125e37b2ca6fac8fec5ad14a6ffe3d9efdebbddeb675c59175ca25  x86/bin/cp
941863a4dc7188c44a38cf312b7259f4cd32dfe1b75775db108dd09ccc1595ca  x86/bin/get_machine
92b2414feba8744bc41ad4b165004ce42a4c47208094868d0b60e9ac6cdf229a  x86/bin/hex2
967caba7eb0f3223d685f67341e0df072c9700fed3dd61e892a3cce1f4404cb4  x86/bin/kaem
b7e7e05714748e919e2ec8f985afd4e5c8a08dca6384f3179721a2ca5845a57a  x86/bin/M1
f8c09c42c203fb21c3bb8ff6537df7864b85007a72380bd06cd1bfb5acd92588  x86/bin/M2-Mesoplanet
e33eb9c487d1e34bcca70e0d55c158cc24ed5b671fba72db8102182daa0d35a8  x86/bin/M2-Planet
481ad71972d5fece4de35dd2c357910d3740fbd5d18bcab1ae0353fcde45d846  x86/bin/match
1e3f266c93d56e4ee05fec8422f92e9261c674a09b22efa31b4198172be07b6f  x86/bin/mkdir
47bcca1d7f9a07df1256c6372fbcd14afb98b0e53f4cd3a42eb73bcef1468aa2  x86/bin/replace
91d2a629a99f9b23c66acdc5f156a21bf1b26306031ca2ad3da4869e142d29d8  x86/bin/rm
130cdb574ea4e78b703182387d610d27bff3fb5bc9f19c8f6a22d3b88e47a796  x86/bin/sha256sum
c43dc403413cdd11e5d10159219a6984c3571fd3bc025f23123257b6d03641b5  x86/bin/ungz
caf4adc1d50b35147f16a03cbca4b45339b11d3aec260d13eb21050185438d3a  x86/bin/unbz2
b8339525443c02be31b0b6d55cbc0cdebb7921ce641eff1596800a1be1a874e5  x86/bin/untar

https://github.com/fosslinux/live-bootstrap/blob/master/sysa/checksum-transcriber.c

File: ../git/live-bootstrap/sysa/checksum-transcriber.c used in: Step 79
/*
 * SPDX-FileCopyrightText: 2022 fosslinux <fosslinux@aussies.space>
 *
 * SPDX-License-Identifier: GPL-3.0-or-later
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <bootstrappable.h>
#include <unistd.h>

#define MAX_STRING 4096
#define MAX_TOKENS 3

char *get_distfiles(char **envp) {
    char *envvar = "distfiles=";
    int i = 0;
    while (envp[i] != NULL && strncmp(envp[i], envvar, strlen(envvar)) != 0) i += 1;
    // Now we have distfiles= - get just the part we want.
    require(envp[i] != NULL, "Unable to find distfiles environment variable");
    return envp[i] + strlen(envvar);
}

int main(int argc, char **argv, char **envp) {
    // Random file things
    require(argc == 2, "Usage: checksum-transcriber FILENAME");
    char *input = argv[1];
    FILE *in = fopen(input, "r");
    require(in != NULL, "File does not exist");
    char *output = calloc(MAX_STRING, sizeof(char));
    require(strcpy(output, input) != NULL, "Failed copying string");
    require(strcat(output, ".SHA256SUM") != NULL, "Failed concating string");
    FILE *out = fopen(output, "w+");
    require(out != NULL, "Failed opening output file");

    char *orig_line;
    char *line = calloc(MAX_STRING, sizeof(char));
    require(line != NULL, "Failed allocating string");
    char **tokens;
    char *new_line;
    char *checksum;
    char *filename;
    int i;
    fgets(line, MAX_STRING, in);
    while (strlen(line) != 0) {
        // Split each line into tokens
        orig_line = line;
        tokens = calloc(MAX_TOKENS, sizeof(char*));
        i = 0;
        while (i < MAX_TOKENS) {
            tokens[i] = line;
            new_line = strchr(line, ' ');
            // Occurs when there are only two tokens
            if (new_line == NULL) break;
            line = new_line;
            line[0] = '\0';
            line += 1;
            i += 1;
        }
        line = strchr(line, '\n');
        line[0] = '\0';
        // Get checksum and filename
        checksum = tokens[1];
        if (tokens[2] != NULL) {
            filename = tokens[2];
        } else {
            filename = strrchr(tokens[0], '/');
            filename += 1;
        }
        // Put it all together
        fputs(checksum, out);
        fputs("  ", out);
        fputs(get_distfiles(envp), out);
        fputc('/', out);
        fputs(filename, out);
        fputc('\n', out);
        // Cleanup
        i = 0;
        free(orig_line);
        free(tokens);
        line = calloc(MAX_STRING, sizeof(char));
        require(line != NULL, "Failed allocating string");
        fgets(line, MAX_STRING, in);
    }

    // Clean up
    fclose(in);
    fclose(out);
}

https://github.com/fosslinux/live-bootstrap/blob/master/sysa/checksum-transcriber.x86.SHA256SUM

File: ../git/live-bootstrap/sysa/checksum-transcriber.x86.SHA256SUM used in: Step 80
216fe50dd8e70928f382d40ced1d9a2c167f7a5aafd555901194c5559af8c526  /usr/bin/checksum-transcriber

https://github.com/fosslinux/live-bootstrap/blob/master/sysa/simple-patch.c

File: ../git/live-bootstrap/sysa/simple-patch.c used in: Step 81
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "M2libc/bootstrappable.h"

/*
SPDX-FileCopyrightText: 2023 Richard Masters <grick23@gmail.com>
SPDX-License-Identifier: MIT

Simple Patch program.

This program is written in a subset of C called M2, which is from the
stage0-posix bootstrap project.

Example usage:
./simple-patch file_to_patch before_pattern_file after_pattern_file

*/

// function prototypes
void read_file_or_die(char *file_name, char **buffer, int *file_size);
void patch_buffer_or_die(char *patch_file_before_buffer, int patch_file_before_size,
                 char *before_pattern_buffer, int before_pattern_size,
                 char *after_pattern_buffer, int after_pattern_size,
                 char *patch_file_after_buffer);
void writestr_fd(int fd, char *str);
int memsame(char *search_buffer, int search_size,
            char *pattern_buffer, int pattern_size);


int main(int argc, char **argv) {
    char *patch_file_before_buffer;
    int patch_file_before_size;

    char *before_pattern_buffer;
    int before_pattern_size;

    char *after_pattern_buffer;
    int after_pattern_size;

    int patch_file_after_size;
    char *patch_file_after_buffer;

    int patch_file_fd;

    read_file_or_die(argv[1], &patch_file_before_buffer, &patch_file_before_size);
    read_file_or_die(argv[2], &before_pattern_buffer, &before_pattern_size);
    read_file_or_die(argv[3], &after_pattern_buffer, &after_pattern_size);

    patch_file_after_size = patch_file_before_size - before_pattern_size + after_pattern_size;
    patch_file_after_buffer = calloc(patch_file_after_size, sizeof(char));

    patch_buffer_or_die(patch_file_before_buffer, patch_file_before_size,
                 before_pattern_buffer, before_pattern_size,
                 after_pattern_buffer, after_pattern_size,
                 patch_file_after_buffer);
    
    patch_file_fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0);
    write(patch_file_fd, patch_file_after_buffer, patch_file_after_size);
    close(patch_file_fd);

    return EXIT_SUCCESS;
}


void read_file_or_die(char *file_name, char **buffer, int *file_size) {
    int file_fd;
    int num_bytes_read;

    file_fd = open(file_name, O_RDONLY, 0);
    if (file_fd == -1) {
        writestr_fd(2, "Could not open file: ");
        writestr_fd(2, file_name);
        writestr_fd(2, "\n");
        exit(1);
    }
    // determine file size
    *file_size = lseek(file_fd, 0, SEEK_END);
    // go back to beginning of file
    lseek(file_fd, 0, SEEK_SET);
    // alloc a buffer to read the entire file
    *buffer = calloc(*file_size, sizeof(char));

    // read the entire patch file
    num_bytes_read = read(file_fd, *buffer, *file_size);
    if (num_bytes_read != *file_size) {
        writestr_fd(2, "Could not read file: ");
        writestr_fd(2, file_name);
        writestr_fd(2, "\n");
        exit(1);
    }
    close(file_fd);
}

void patch_buffer_or_die(char *patch_file_before_buffer, int patch_file_before_size,
                 char *before_pattern_buffer, int before_pattern_size,
                 char *after_pattern_buffer, int after_pattern_size,
                 char *patch_file_after_buffer) {

    char *pos = patch_file_before_buffer;
    int prefix_len = 0;

    // look for the pattern at every offset
    while (prefix_len < patch_file_before_size) {
        // if we find the pattern, replace it and return
        if (memsame(pos, patch_file_before_size - prefix_len, before_pattern_buffer, before_pattern_size)) {
           memcpy(patch_file_after_buffer, patch_file_before_buffer, prefix_len);
           memcpy(patch_file_after_buffer + prefix_len, after_pattern_buffer, after_pattern_size);
           memcpy(patch_file_after_buffer + prefix_len + after_pattern_size, 
                  patch_file_before_buffer + prefix_len + before_pattern_size, 
                  patch_file_before_size - (prefix_len + before_pattern_size));
           return;
        }
        pos = pos + 1;
        prefix_len = prefix_len + 1;
    }

    /* if we don't find the pattern, something is wrong, so exit with error */
    exit(1);
}

/*
    Write the string to the given file descriptor.
*/
void writestr_fd(int fd, char *str) {
    write(fd, str, strlen(str));
}

/*
    Is the pattern located at the start of the search buffer
    (and not exceeding the length of the search buffer)?
*/

int memsame(char *search_buffer, int search_size,
            char *pattern_buffer, int pattern_size) {
    int check_offset = 0;

    if (pattern_size > search_size) {
        return FALSE;
    }
    while (check_offset < pattern_size) {
        if (search_buffer[check_offset] != pattern_buffer[check_offset]) {
             return FALSE;
        }
        check_offset = check_offset + 1;
    }
    return TRUE;
}

https://github.com/fosslinux/live-bootstrap/blob/master/sysa/mes-0.24.2/sources

File: ../git/live-bootstrap/sysa/mes-0.24.2/sources used in: Step 85
https://mirrors.kernel.org/gnu/mes/mes-0.24.2.tar.gz 7ddae0854e46ebfa18c13ab37e64839a7b86ea88aeed366a8d017efd11dae86e
https://download.savannah.gnu.org/releases/nyacc/nyacc-1.00.2.tar.gz f36e4fb7dd524dc3f4b354d3d5313f69e7ce5a6ae93711e8cf6d51eaa8d2b318

https://github.com/fosslinux/live-bootstrap/blob/master/sysa/mes-0.24.2/files/config.h

File: ../git/live-bootstrap/sysa/mes-0.24.2/files/config.h used in: Step 94, Step 121, Step 122, Step 123, Step 124, Step 125, Step 128, Step 129, Step 130, Step 137, Step 138, Step 139, Step 140, Step 141, Step 142, Step 143, Step 144, Step 145, Step 146, Step 147, Step 148, Step 149, Step 150, Step 151, Step 152, Step 153, Step 154, Step 155, Step 156, Step 157, Step 158, Step 159, Step 160, Step 161, Step 162, Step 163, Step 164, Step 165, Step 166, Step 167, Step 168, Step 170, Step 171, Step 172, Step 173, Step 174, Step 175, Step 176, Step 177, Step 182, Step 189, Step 190, Step 191, Step 192, Step 198, Step 199, Step 200, Step 201, Step 202, Step 203, Step 205, Step 212, Step 213, Step 214, Step 215, Step 216, Step 217, Step 218, Step 219, Step 220, Step 221, Step 222, Step 223, Step 224, Step 225, Step 226, Step 227, Step 228, Step 229, Step 230, Step 236, Step 237, Step 238, Step 239, Step 240, Step 241, Step 242, Step 243, Step 244, Step 245, Step 246, Step 247, Step 248, Step 249, Step 250, Step 251, Step 252, Step 253, Step 254, Step 255, Step 256, Step 257, Step 259, Step 262, Step 264, Step 277, Step 278, Step 279, Step 280, Step 281, Step 283
// SPDX-FileCopyrightText: 2020 fosslinux <fosslinux@aussies.space>
// SPDX-FileCopyrightText: 2021 Andrius Å tikonas <andrius@stikonas.eu>
//
// SPDX-License-Identifier: GPL-3.0-or-later

#undef SYSTEM_LIBC
#define MES_VERSION "0.24.2"

https://git.savannah.gnu.org/cgit/mes.git/tree/include/linux/x86/syscall.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_LINUX_X86_SYSCALL_H
#define __MES_LINUX_X86_SYSCALL_H 1

/* libc-mini */
#ifndef SYS_exit
// CONSTANT SYS_exit 0x01
#define SYS_exit    0x01
#endif
#ifndef SYS_write
// CONSTANT SYS_write 0x04
#define SYS_write   0x04
#endif

/* libc */
// CONSTANT SYS_fork 0x02
#define SYS_fork    0x02
// CONSTANT SYS_read 0x03
#define SYS_read    0x03
// CONSTANT SYS_open 0x05
#define SYS_open    0x05
// CONSTANT SYS_waitpid 0x07
#define SYS_waitpid 0x07
// CONSTANT SYS_wait4 0x72
#define SYS_wait4   0x72
// CONSTANT SYS_execve 0x0b
#define SYS_execve  0x0b
// CONSTANT SYS_chmod 0x0f
#define SYS_chmod   0x0f
// CONSTANT SYS_access 0x21
#define SYS_access  0x21
// CONSTANT SYS_brk 0x2d
#define SYS_brk     0x2d
// CONSTANT SYS_ioctl 0x36
#define SYS_ioctl   0x36
// CONSTANT SYS_fsync 0x76
#define SYS_fsync   0x76
// CONSTANT SYS_getcwd 0xb7
#define SYS_getcwd 0xb7
// CONSTANT SYS_dup 0x29
#define SYS_dup       0x29
// CONSTANT SYS_dup2 0x3f
#define SYS_dup2      0x3f
// CONSTANT SYS_unlink 0x0a
#define SYS_unlink 0x0a
// CONSTANT SYS_gettimeofday 0x4e
#define SYS_gettimeofday 0x4e
// CONSTANT SYS_clock_gettime 0x109
#define SYS_clock_gettime 0x109
// CONSTANT SYS_time 0x0d
#define SYS_time   0x0d

/* libc+tcc */
#define SYS_close  0x06
#define SYS_lseek  0x13
#define SYS_rmdir  0x28
#define SYS_stat   0x6a

/* libc+gnu */
#define SYS_chdir     0x0c
#define SYS_link      0x09
#define SYS_getpid    0x14
#define SYS_getuid    0x18
#define SYS_kill      0x25
#define SYS_rename    0x26
#define SYS_mkdir     0x27
#define SYS_pipe      0x2a
#define SYS_getgid    0x2f
#define SYS_signal    0x30
#define SYS_sigaction 0x43
#define SYS_rt_sigaction 0xae
#define SYS_signal    0x30
#define SYS_fcntl     0x37
#define SYS_getrusage 0x4d
#define SYS_lstat     0x6b
#define SYS_setitimer 0x68
#define SYS_fstat     0x6c
#define SYS_nanosleep 0xa2
#define SYS_getdents  0x8d

/* bash */
#define SYS_setuid    0x17
#define SYS_geteuid   0x31
#define SYS_getegid   0x32
#define SYS_setgid    0x3e
#define SYS_getppid   0x40

/* make+POSIX */
#define SYS_sigprocmask 0x7e

/* tar */
#define SYS_symlink   0x53
#define SYS_readlink  0x55
#define SYS_mknod     0x0e

#if __SIZEOF_LONG_LONG__ == 8

#define SYS_stat64     0xc3
#define SYS_lstat64    0xc4
#define SYS_fstat64    0xc5
#define SYS_fcntl64    0xdd
#define SYS_getdents64 0xdc

#undef SYS_stat
#define SYS_stat SYS_stat64

#undef SYS_lstat
#define SYS_lstat SYS_lstat64

#undef SYS_fstat
#define SYS_fstat SYS_fstat64

#endif  // __SIZEOF_LONG_LONG__ == 8

#endif /* __MES_LINUX_X86_SYSCALL_H */

https://git.savannah.gnu.org/cgit/mes.git/tree/include/linux/x86/kernel-stat.h?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/include/linux/x86/kernel-stat.h used in: Step 97
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_LINUX_X86_KERNEL_STAT_H
#define __MES_LINUX_X86_KERNEL_STAT_H 1

// https://github.com/torvalds/linux/blob/master/arch/x86/include/uapi/asm/stat.h

#include <arch/syscall.h>

#if __SIZEOF_LONG_LONG__ != 8

// *INDENT-OFF*
struct stat
{
  unsigned long  st_dev;
  unsigned long  st_ino;
  unsigned short st_mode;
  unsigned short st_nlink;
  unsigned short st_uid;
  unsigned short st_gid;
  unsigned long  st_rdev;
  unsigned long  st_size;
  unsigned long  st_blksize;
  unsigned long  st_blocks;
  unsigned long  st_atime;
  unsigned long  st_atime_usec;
  unsigned long  st_mtime;
  unsigned long  st_mtime_usec;
  unsigned long  st_ctime;
  unsigned long  st_ctime_usec;
  unsigned long  __pad0;
  unsigned long  __pad1;
};

#else // __SIZEOF_LONG_LONG__ == 8

struct stat
{
  unsigned long long st_dev;
  unsigned char __pad0[4];
  unsigned long __st_ino;
  unsigned int st_mode;
  unsigned int st_nlink;
  unsigned long st_uid;
  unsigned long st_gid;
  unsigned long long st_rdev;
  unsigned char __pad3[4];
  long long st_size;
  unsigned long st_blksize;
  unsigned long long st_blocks;
  unsigned long st_atime;
  unsigned long st_atime_nsec;
  unsigned long st_mtime;
  unsigned int st_mtime_nsec;
  unsigned long st_ctime;
  unsigned long st_ctime_nsec;
  unsigned long long st_ino;
};

#endif // __SIZEOF_LONG_LONG__ == 8

#endif // __MES_LINUX_X86_KERNEL_STAT_H

https://git.savannah.gnu.org/cgit/mes.git/tree/mes/module/mes/psyntax.pp?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/mes/module/mes/psyntax.pp used in:
;;; -*-scheme-*-
;;; GNU Mes --- Maxwell Equations of Software
;;; Copyright (C) 2016, 2017, 2018 Free Software Foundation, Inc.
;;;
;;; This file is part of GNU Mes.
;;;
;;; GNU Mes is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Mes is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.

;;; Commentary:

;;; This file is generated from psyntax.ss.

;;; Code:
(letrec ((syntmp-lambda-var-list-167
           (lambda (syntmp-vars-552)
             (let syntmp-lvl-553 ((syntmp-vars-554 syntmp-vars-552)
                                  (syntmp-ls-555 (quote ()))
                                  (syntmp-w-556 (quote (()))))
               (cond ((pair? syntmp-vars-554)
                      (syntmp-lvl-553
                        (cdr syntmp-vars-554)
                        (cons (syntmp-wrap-146
                                (car syntmp-vars-554)
                                syntmp-w-556)
                              syntmp-ls-555)
                        syntmp-w-556))
                     ((syntmp-id?-118 syntmp-vars-554)
                      (cons (syntmp-wrap-146 syntmp-vars-554 syntmp-w-556)
                            syntmp-ls-555))
                     ((null? syntmp-vars-554) syntmp-ls-555)
                     ((syntmp-syntax-object?-104 syntmp-vars-554)
                      (syntmp-lvl-553
                        (syntmp-syntax-object-expression-105
                          syntmp-vars-554)
                        syntmp-ls-555
                        (syntmp-join-wraps-137
                          syntmp-w-556
                          (syntmp-syntax-object-wrap-106 syntmp-vars-554))))
                     ((syntmp-annotation?-92 syntmp-vars-554)
                      (syntmp-lvl-553
                        (annotation-expression syntmp-vars-554)
                        syntmp-ls-555
                        syntmp-w-556))
                     (else (cons syntmp-vars-554 syntmp-ls-555))))))
         (syntmp-gen-var-166
           (lambda (syntmp-id-557)
             (let ((syntmp-id-558
                     (if (syntmp-syntax-object?-104 syntmp-id-557)
                       (syntmp-syntax-object-expression-105
                         syntmp-id-557)
                       syntmp-id-557)))
               (if (syntmp-annotation?-92 syntmp-id-558)
                 (gensym
                   (symbol->string
                     (annotation-expression syntmp-id-558)))
                 (gensym (symbol->string syntmp-id-558))))))
         (syntmp-strip-165
           (lambda (syntmp-x-559 syntmp-w-560)
             (if (memq 'top
                       (syntmp-wrap-marks-121 syntmp-w-560))
               (if (or (syntmp-annotation?-92 syntmp-x-559)
                       (and (pair? syntmp-x-559)
                            (syntmp-annotation?-92 (car syntmp-x-559))))
                 (syntmp-strip-annotation-164 syntmp-x-559 #f)
                 syntmp-x-559)
               (let syntmp-f-561 ((syntmp-x-562 syntmp-x-559))
                 (cond ((syntmp-syntax-object?-104 syntmp-x-562)
                        (syntmp-strip-165
                          (syntmp-syntax-object-expression-105
                            syntmp-x-562)
                          (syntmp-syntax-object-wrap-106 syntmp-x-562)))
                       ((pair? syntmp-x-562)
                        (let ((syntmp-a-563 (syntmp-f-561 (car syntmp-x-562)))
                              (syntmp-d-564 (syntmp-f-561 (cdr syntmp-x-562))))
                          (if (and (eq? syntmp-a-563 (car syntmp-x-562))
                                   (eq? syntmp-d-564 (cdr syntmp-x-562)))
                            syntmp-x-562
                            (cons syntmp-a-563 syntmp-d-564))))
                       ((vector? syntmp-x-562)
                        (let ((syntmp-old-565 (vector->list syntmp-x-562)))
                          (let ((syntmp-new-566
                                  (map syntmp-f-561 syntmp-old-565)))
                            (if (andmap eq? syntmp-old-565 syntmp-new-566)
                              syntmp-x-562
                              (list->vector syntmp-new-566)))))
                       (else syntmp-x-562))))))
         (syntmp-strip-annotation-164
           (lambda (syntmp-x-567 syntmp-parent-568)
             (cond ((pair? syntmp-x-567)
                    (let ((syntmp-new-569 (cons #f #f)))
                      (begin
                        (when syntmp-parent-568
                              (set-annotation-stripped!
                                syntmp-parent-568
                                syntmp-new-569))
                        (set-car!
                          syntmp-new-569
                          (syntmp-strip-annotation-164
                            (car syntmp-x-567)
                            #f))
                        (set-cdr!
                          syntmp-new-569
                          (syntmp-strip-annotation-164
                            (cdr syntmp-x-567)
                            #f))
                        syntmp-new-569)))
                   ((syntmp-annotation?-92 syntmp-x-567)
                    (or (annotation-stripped syntmp-x-567)
                        (syntmp-strip-annotation-164
                          (annotation-expression syntmp-x-567)
                          syntmp-x-567)))
                   ((vector? syntmp-x-567)
                    (let ((syntmp-new-570
                            (make-vector (vector-length syntmp-x-567))))
                      (begin
                        (when syntmp-parent-568
                              (set-annotation-stripped!
                                syntmp-parent-568
                                syntmp-new-570))
                        (let syntmp-loop-571 ((syntmp-i-572
                                                (- (vector-length syntmp-x-567)
                                                   1)))
                          (unless
                            (syntmp-fx<-91 syntmp-i-572 0)
                            (vector-set!
                              syntmp-new-570
                              syntmp-i-572
                              (syntmp-strip-annotation-164
                                (vector-ref syntmp-x-567 syntmp-i-572)
                                #f))
                            (syntmp-loop-571 (syntmp-fx--89 syntmp-i-572 1))))
                        syntmp-new-570)))
                   (else syntmp-x-567))))
         (syntmp-ellipsis?-163
           (lambda (syntmp-e-573 syntmp-r-574)
             (and (syntmp-nonsymbol-id?-117 syntmp-e-573)
                  (let ((syntmp-id-575
                          (syntmp-make-syntax-object-103
                            '$sc-ellipsis
                            (syntmp-syntax-object-wrap-106 syntmp-e-573))))
                    (let ((syntmp-n-576
                            (syntmp-id-var-name-140
                              syntmp-id-575
                              '(()))))
                      (let ((syntmp-b-577
                              (syntmp-lookup-115 syntmp-n-576 syntmp-r-574)))
                        (if (eq? (syntmp-binding-type-110 syntmp-b-577)
                                 'ellipsis)
                          (syntmp-bound-id=?-142
                            syntmp-e-573
                            (syntmp-binding-value-111 syntmp-b-577))
                          (syntmp-free-id=?-141
                            syntmp-e-573
                            '#(syntax-object
                               ...
                               ((top)
                                #(ribcage () () ())
                                #(ribcage () () ())
                                #(ribcage #(b) #((top)) #("i"))
                                #(ribcage () () ())
                                #(ribcage #(n) #((top)) #("i"))
                                #(ribcage () () ())
                                #(ribcage #(id) #((top)) #("i"))
                                #(ribcage () () ())
                                #(ribcage #(e r) #((top) (top)) #("i" "i"))
                                #(ribcage
                                  (lambda-var-list
                                    gen-var
                                    strip
                                    strip-annotation
                                    ellipsis?
                                    chi-void
                                    eval-local-transformer
                                    chi-local-syntax
                                    chi-lambda-clause
                                    chi-body
                                    chi-macro
                                    chi-application
                                    chi-expr
                                    chi
                                    chi-top
                                    syntax-type
                                    chi-when-list
                                    chi-install-global
                                    chi-top-sequence
                                    chi-sequence
                                    source-wrap
                                    wrap
                                    bound-id-member?
                                    distinct-bound-ids?
                                    valid-bound-ids?
                                    bound-id=?
                                    free-id=?
                                    id-var-name
                                    same-marks?
                                    join-marks
                                    join-wraps
                                    smart-append
                                    make-binding-wrap
                                    extend-ribcage!
                                    make-empty-ribcage
                                    new-mark
                                    anti-mark
                                    the-anti-mark
                                    top-marked?
                                    top-wrap
                                    empty-wrap
                                    set-ribcage-labels!
                                    set-ribcage-marks!
                                    set-ribcage-symnames!
                                    ribcage-labels
                                    ribcage-marks
                                    ribcage-symnames
                                    ribcage?
                                    make-ribcage
                                    gen-labels
                                    gen-label
                                    make-rename
                                    rename-marks
                                    rename-new
                                    rename-old
                                    subst-rename?
                                    wrap-subst
                                    wrap-marks
                                    make-wrap
                                    id-sym-name&marks
                                    id-sym-name
                                    id?
                                    nonsymbol-id?
                                    global-extend
                                    lookup
                                    macros-only-env
                                    extend-var-env
                                    extend-env
                                    null-env
                                    binding-value
                                    binding-type
                                    make-binding
                                    arg-check
                                    source-annotation
                                    no-source
                                    unannotate
                                    set-syntax-object-wrap!
                                    set-syntax-object-expression!
                                    syntax-object-wrap
                                    syntax-object-expression
                                    syntax-object?
                                    make-syntax-object
                                    build-lexical-var
                                    build-letrec
                                    build-named-let
                                    build-let
                                    build-sequence
                                    build-data
                                    build-primref
                                    build-lambda
                                    build-global-definition
                                    build-global-assignment
                                    build-global-reference
                                    build-lexical-assignment
                                    build-lexical-reference
                                    build-conditional
                                    build-application
                                    get-global-definition-hook
                                    put-global-definition-hook
                                    gensym-hook
                                    error-hook
                                    local-eval-hook
                                    top-level-eval-hook
                                    annotation?
                                    fx<
                                    fx=
                                    fx-
                                    fx+
                                    noexpand)
                                  ((top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top)
                                   (top))
                                  ("i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"
                                   "i"))
                                #(ribcage
                                  (define-structure)
                                  ((top))
                                  ("i"))))))))))))
         (syntmp-chi-void-162
           (lambda () (list (quote void))))
         (syntmp-eval-local-transformer-161
           (lambda (syntmp-expanded-578)
             (let ((syntmp-p-579
                     (syntmp-local-eval-hook-94 syntmp-expanded-578)))
               (if (procedure? syntmp-p-579)
                 syntmp-p-579
                 (syntax-error
                   syntmp-p-579
                   "nonprocedure transformer")))))
         (syntmp-chi-local-syntax-160
           (lambda (syntmp-rec?-580
                    syntmp-e-581
                    syntmp-r-582
                    syntmp-w-583
                    syntmp-s-584
                    syntmp-k-585)
             ((lambda (syntmp-tmp-586)
                ((lambda (syntmp-tmp-587)
                   (if syntmp-tmp-587
                     (apply (lambda (syntmp-_-588
                                     syntmp-id-589
                                     syntmp-val-590
                                     syntmp-e1-591
                                     syntmp-e2-592)
                              (let ((syntmp-ids-593 syntmp-id-589))
                                (if (not (syntmp-valid-bound-ids?-143
                                           syntmp-ids-593))
                                  (syntax-error
                                    syntmp-e-581
                                    "duplicate bound keyword in")
                                  (let ((syntmp-labels-595
                                          (syntmp-gen-labels-124
                                            syntmp-ids-593)))
                                    (let ((syntmp-new-w-596
                                            (syntmp-make-binding-wrap-135
                                              syntmp-ids-593
                                              syntmp-labels-595
                                              syntmp-w-583)))
                                      (syntmp-k-585
                                        (cons syntmp-e1-591 syntmp-e2-592)
                                        (syntmp-extend-env-112
                                          syntmp-labels-595
                                          (let ((syntmp-w-598
                                                  (if syntmp-rec?-580
                                                    syntmp-new-w-596
                                                    syntmp-w-583))
                                                (syntmp-trans-r-599
                                                  (syntmp-macros-only-env-114
                                                    syntmp-r-582)))
                                            (map (lambda (syntmp-x-600)
                                                   (cons 'macro
                                                         (syntmp-eval-local-transformer-161
                                                           (syntmp-chi-154
                                                             syntmp-x-600
                                                             syntmp-trans-r-599
                                                             syntmp-w-598))))
                                                 syntmp-val-590))
                                          syntmp-r-582)
                                        syntmp-new-w-596
                                        syntmp-s-584))))))
                            syntmp-tmp-587)
                     ((lambda (syntmp-_-602)
                        (syntax-error
                          (syntmp-source-wrap-147
                            syntmp-e-581
                            syntmp-w-583
                            syntmp-s-584)))
                      syntmp-tmp-586)))
                 (syntax-dispatch
                   syntmp-tmp-586
                   '(any #(each (any any)) any . each-any))))
              syntmp-e-581)))
         (syntmp-chi-lambda-clause-159
           (lambda (syntmp-e-603
                    syntmp-c-604
                    syntmp-r-605
                    syntmp-w-606
                    syntmp-k-607)
             ((lambda (syntmp-tmp-608)
                ((lambda (syntmp-tmp-609)
                   (if syntmp-tmp-609
                     (apply (lambda (syntmp-id-610 syntmp-e1-611 syntmp-e2-612)
                              (let ((syntmp-ids-613 syntmp-id-610))
                                (if (not (syntmp-valid-bound-ids?-143
                                           syntmp-ids-613))
                                  (syntax-error
                                    syntmp-e-603
                                    "invalid parameter list in")
                                  (let ((syntmp-labels-615
                                          (syntmp-gen-labels-124
                                            syntmp-ids-613))
                                        (syntmp-new-vars-616
                                          (map syntmp-gen-var-166
                                               syntmp-ids-613)))
                                    (syntmp-k-607
                                      syntmp-new-vars-616
                                      (syntmp-chi-body-158
                                        (cons syntmp-e1-611 syntmp-e2-612)
                                        syntmp-e-603
                                        (syntmp-extend-var-env-113
                                          syntmp-labels-615
                                          syntmp-new-vars-616
                                          syntmp-r-605)
                                        (syntmp-make-binding-wrap-135
                                          syntmp-ids-613
                                          syntmp-labels-615
                                          syntmp-w-606)))))))
                            syntmp-tmp-609)
                     ((lambda (syntmp-tmp-618)
                        (if syntmp-tmp-618
                          (apply (lambda (syntmp-ids-619
                                          syntmp-e1-620
                                          syntmp-e2-621)
                                   (let ((syntmp-old-ids-622
                                           (syntmp-lambda-var-list-167
                                             syntmp-ids-619)))
                                     (if (not (syntmp-valid-bound-ids?-143
                                                syntmp-old-ids-622))
                                       (syntax-error
                                         syntmp-e-603
                                         "invalid parameter list in")
                                       (let ((syntmp-labels-623
                                               (syntmp-gen-labels-124
                                                 syntmp-old-ids-622))
                                             (syntmp-new-vars-624
                                               (map syntmp-gen-var-166
                                                    syntmp-old-ids-622)))
                                         (syntmp-k-607
                                           (let syntmp-f-625 ((syntmp-ls1-626
                                                                (cdr syntmp-new-vars-624))
                                                              (syntmp-ls2-627
                                                                (car syntmp-new-vars-624)))
                                             (if (null? syntmp-ls1-626)
                                               syntmp-ls2-627
                                               (syntmp-f-625
                                                 (cdr syntmp-ls1-626)
                                                 (cons (car syntmp-ls1-626)
                                                       syntmp-ls2-627))))
                                           (syntmp-chi-body-158
                                             (cons syntmp-e1-620 syntmp-e2-621)
                                             syntmp-e-603
                                             (syntmp-extend-var-env-113
                                               syntmp-labels-623
                                               syntmp-new-vars-624
                                               syntmp-r-605)
                                             (syntmp-make-binding-wrap-135
                                               syntmp-old-ids-622
                                               syntmp-labels-623
                                               syntmp-w-606)))))))
                                 syntmp-tmp-618)
                          ((lambda (syntmp-_-629)
                             (syntax-error syntmp-e-603))
                           syntmp-tmp-608)))
                      (syntax-dispatch
                        syntmp-tmp-608
                        '(any any . each-any)))))
                 (syntax-dispatch
                   syntmp-tmp-608
                   '(each-any any . each-any))))
              syntmp-c-604)))
         (syntmp-chi-body-158
           (lambda (syntmp-body-630
                    syntmp-outer-form-631
                    syntmp-r-632
                    syntmp-w-633)
             (let ((syntmp-r-634
                     (cons '("placeholder" placeholder)
                           syntmp-r-632)))
               (let ((syntmp-ribcage-635
                       (syntmp-make-ribcage-125
                         '()
                         '()
                         '())))
                 (let ((syntmp-w-636
                         (syntmp-make-wrap-120
                           (syntmp-wrap-marks-121 syntmp-w-633)
                           (cons syntmp-ribcage-635
                                 (syntmp-wrap-subst-122 syntmp-w-633)))))
                   (let syntmp-parse-637 ((syntmp-body-638
                                            (map (lambda (syntmp-x-644)
                                                   (cons syntmp-r-634
                                                         (syntmp-wrap-146
                                                           syntmp-x-644
                                                           syntmp-w-636)))
                                                 syntmp-body-630))
                                          (syntmp-ids-639 (quote ()))
                                          (syntmp-labels-640 (quote ()))
                                          (syntmp-vars-641 (quote ()))
                                          (syntmp-vals-642 (quote ()))
                                          (syntmp-bindings-643 (quote ())))
                     (if (null? syntmp-body-638)
                       (syntax-error
                         syntmp-outer-form-631
                         "no expressions in body")
                       (let ((syntmp-e-645 (cdar syntmp-body-638))
                             (syntmp-er-646 (caar syntmp-body-638)))
                         (call-with-values
                           (lambda ()
                             (syntmp-syntax-type-152
                               syntmp-e-645
                               syntmp-er-646
                               '(())
                               #f
                               syntmp-ribcage-635))
                           (lambda (syntmp-type-647
                                    syntmp-value-648
                                    syntmp-e-649
                                    syntmp-w-650
                                    syntmp-s-651)
                             (let ((syntmp-t-652 syntmp-type-647))
                               (if (memv syntmp-t-652 (quote (define-form)))
                                 (let ((syntmp-id-653
                                         (syntmp-wrap-146
                                           syntmp-value-648
                                           syntmp-w-650))
                                       (syntmp-label-654
                                         (syntmp-gen-label-123)))
                                   (let ((syntmp-var-655
                                           (syntmp-gen-var-166 syntmp-id-653)))
                                     (begin
                                       (syntmp-extend-ribcage!-134
                                         syntmp-ribcage-635
                                         syntmp-id-653
                                         syntmp-label-654)
                                       (syntmp-parse-637
                                         (cdr syntmp-body-638)
                                         (cons syntmp-id-653 syntmp-ids-639)
                                         (cons syntmp-label-654
                                               syntmp-labels-640)
                                         (cons syntmp-var-655 syntmp-vars-641)
                                         (cons (cons syntmp-er-646
                                                     (syntmp-wrap-146
                                                       syntmp-e-649
                                                       syntmp-w-650))
                                               syntmp-vals-642)
                                         (cons (cons 'lexical
                                                     syntmp-var-655)
                                               syntmp-bindings-643)))))
                                 (if (memv syntmp-t-652
                                           '(define-syntax-form))
                                   (let ((syntmp-id-656
                                           (syntmp-wrap-146
                                             syntmp-value-648
                                             syntmp-w-650))
                                         (syntmp-label-657
                                           (syntmp-gen-label-123)))
                                     (begin
                                       (syntmp-extend-ribcage!-134
                                         syntmp-ribcage-635
                                         syntmp-id-656
                                         syntmp-label-657)
                                       (syntmp-parse-637
                                         (cdr syntmp-body-638)
                                         (cons syntmp-id-656 syntmp-ids-639)
                                         (cons syntmp-label-657
                                               syntmp-labels-640)
                                         syntmp-vars-641
                                         syntmp-vals-642
                                         (cons (cons 'macro
                                                     (cons syntmp-er-646
                                                           (syntmp-wrap-146
                                                             syntmp-e-649
                                                             syntmp-w-650)))
                                               syntmp-bindings-643))))
                                   (if (memv syntmp-t-652 (quote (begin-form)))
                                     ((lambda (syntmp-tmp-658)
                                        ((lambda (syntmp-tmp-659)
                                           (if syntmp-tmp-659
                                             (apply (lambda (syntmp-_-660
                                                             syntmp-e1-661)
                                                      (syntmp-parse-637
                                                        (let syntmp-f-662 ((syntmp-forms-663
                                                                             syntmp-e1-661))
                                                          (if (null? syntmp-forms-663)
                                                            (cdr syntmp-body-638)
                                                            (cons (cons syntmp-er-646
                                                                        (syntmp-wrap-146
                                                                          (car syntmp-forms-663)
                                                                          syntmp-w-650))
                                                                  (syntmp-f-662
                                                                    (cdr syntmp-forms-663)))))
                                                        syntmp-ids-639
                                                        syntmp-labels-640
                                                        syntmp-vars-641
                                                        syntmp-vals-642
                                                        syntmp-bindings-643))
                                                    syntmp-tmp-659)
                                             (syntax-error syntmp-tmp-658)))
                                         (syntax-dispatch
                                           syntmp-tmp-658
                                           '(any . each-any))))
                                      syntmp-e-649)
                                     (if (memv syntmp-t-652
                                               '(local-syntax-form))
                                       (syntmp-chi-local-syntax-160
                                         syntmp-value-648
                                         syntmp-e-649
                                         syntmp-er-646
                                         syntmp-w-650
                                         syntmp-s-651
                                         (lambda (syntmp-forms-665
                                                  syntmp-er-666
                                                  syntmp-w-667
                                                  syntmp-s-668)
                                           (syntmp-parse-637
                                             (let syntmp-f-669 ((syntmp-forms-670
                                                                  syntmp-forms-665))
                                               (if (null? syntmp-forms-670)
                                                 (cdr syntmp-body-638)
                                                 (cons (cons syntmp-er-666
                                                             (syntmp-wrap-146
                                                               (car syntmp-forms-670)
                                                               syntmp-w-667))
                                                       (syntmp-f-669
                                                         (cdr syntmp-forms-670)))))
                                             syntmp-ids-639
                                             syntmp-labels-640
                                             syntmp-vars-641
                                             syntmp-vals-642
                                             syntmp-bindings-643)))
                                       (if (null? syntmp-ids-639)
                                         (syntmp-build-sequence-99
                                           #f
                                           (map (lambda (syntmp-x-671)
                                                  (syntmp-chi-154
                                                    (cdr syntmp-x-671)
                                                    (car syntmp-x-671)
                                                    '(())))
                                                (cons (cons syntmp-er-646
                                                            (syntmp-source-wrap-147
                                                              syntmp-e-649
                                                              syntmp-w-650
                                                              syntmp-s-651))
                                                      (cdr syntmp-body-638))))
                                         (begin
                                           (if (not (syntmp-valid-bound-ids?-143
                                                      syntmp-ids-639))
                                             (syntax-error
                                               syntmp-outer-form-631
                                               "invalid or duplicate identifier in definition"))
                                           (let syntmp-loop-672 ((syntmp-bs-673
                                                                   syntmp-bindings-643)
                                                                 (syntmp-er-cache-674
                                                                   #f)
                                                                 (syntmp-r-cache-675
                                                                   #f))
                                             (if (not (null? syntmp-bs-673))
                                               (let ((syntmp-b-676
                                                       (car syntmp-bs-673)))
                                                 (if (eq? (car syntmp-b-676)
                                                          'macro)
                                                   (let ((syntmp-er-677
                                                           (cadr syntmp-b-676)))
                                                     (let ((syntmp-r-cache-678
                                                             (if (eq? syntmp-er-677
                                                                      syntmp-er-cache-674)
                                                               syntmp-r-cache-675
                                                               (syntmp-macros-only-env-114
                                                                 syntmp-er-677))))
                                                       (begin
                                                         (set-cdr!
                                                           syntmp-b-676
                                                           (syntmp-eval-local-transformer-161
                                                             (syntmp-chi-154
                                                               (cddr syntmp-b-676)
                                                               syntmp-r-cache-678
                                                               '(()))))
                                                         (syntmp-loop-672
                                                           (cdr syntmp-bs-673)
                                                           syntmp-er-677
                                                           syntmp-r-cache-678))))
                                                   (syntmp-loop-672
                                                     (cdr syntmp-bs-673)
                                                     syntmp-er-cache-674
                                                     syntmp-r-cache-675)))))
                                           (set-cdr!
                                             syntmp-r-634
                                             (syntmp-extend-env-112
                                               syntmp-labels-640
                                               syntmp-bindings-643
                                               (cdr syntmp-r-634)))
                                           (syntmp-build-letrec-102
                                             #f
                                             syntmp-vars-641
                                             (map (lambda (syntmp-x-679)
                                                    (syntmp-chi-154
                                                      (cdr syntmp-x-679)
                                                      (car syntmp-x-679)
                                                      '(())))
                                                  syntmp-vals-642)
                                             (syntmp-build-sequence-99
                                               #f
                                               (map (lambda (syntmp-x-680)
                                                      (syntmp-chi-154
                                                        (cdr syntmp-x-680)
                                                        (car syntmp-x-680)
                                                        '(())))
                                                    (cons (cons syntmp-er-646
                                                                (syntmp-source-wrap-147
                                                                  syntmp-e-649
                                                                  syntmp-w-650
                                                                  syntmp-s-651))
                                                          (cdr syntmp-body-638))))))))))))))))))))))
         (syntmp-chi-macro-157
           (lambda (syntmp-p-681
                    syntmp-e-682
                    syntmp-r-683
                    syntmp-w-684
                    syntmp-rib-685)
             (letrec ((syntmp-rebuild-macro-output-686
                        (lambda (syntmp-x-687 syntmp-m-688)
                          (cond ((pair? syntmp-x-687)
                                 (cons (syntmp-rebuild-macro-output-686
                                         (car syntmp-x-687)
                                         syntmp-m-688)
                                       (syntmp-rebuild-macro-output-686
                                         (cdr syntmp-x-687)
                                         syntmp-m-688)))
                                ((syntmp-syntax-object?-104 syntmp-x-687)
                                 (let ((syntmp-w-689
                                         (syntmp-syntax-object-wrap-106
                                           syntmp-x-687)))
                                   (let ((syntmp-ms-690
                                           (syntmp-wrap-marks-121
                                             syntmp-w-689))
                                         (syntmp-s-691
                                           (syntmp-wrap-subst-122
                                             syntmp-w-689)))
                                     (syntmp-make-syntax-object-103
                                       (syntmp-syntax-object-expression-105
                                         syntmp-x-687)
                                       (if (and (pair? syntmp-ms-690)
                                                (eq? (car syntmp-ms-690) #f))
                                         (syntmp-make-wrap-120
                                           (cdr syntmp-ms-690)
                                           (if syntmp-rib-685
                                             (cons syntmp-rib-685
                                                   (cdr syntmp-s-691))
                                             (cdr syntmp-s-691)))
                                         (syntmp-make-wrap-120
                                           (cons syntmp-m-688 syntmp-ms-690)
                                           (if syntmp-rib-685
                                             (cons syntmp-rib-685
                                                   (cons 'shift
                                                         syntmp-s-691))
                                             (cons 'shift
                                                   syntmp-s-691))))))))
                                ((vector? syntmp-x-687)
                                 (let ((syntmp-n-692
                                         (vector-length syntmp-x-687)))
                                   (let ((syntmp-v-693
                                           (make-vector syntmp-n-692)))
                                     (let syntmp-doloop-694 ((syntmp-i-695 0))
                                       (if (syntmp-fx=-90
                                             syntmp-i-695
                                             syntmp-n-692)
                                         syntmp-v-693
                                         (begin
                                           (vector-set!
                                             syntmp-v-693
                                             syntmp-i-695
                                             (syntmp-rebuild-macro-output-686
                                               (vector-ref
                                                 syntmp-x-687
                                                 syntmp-i-695)
                                               syntmp-m-688))
                                           (syntmp-doloop-694
                                             (syntmp-fx+-88
                                               syntmp-i-695
                                               1))))))))
                                ((symbol? syntmp-x-687)
                                 (syntax-error
                                   syntmp-x-687
                                   "encountered raw symbol in macro output"))
                                (else syntmp-x-687)))))
               (syntmp-rebuild-macro-output-686
                 (syntmp-p-681
                   (syntmp-wrap-146
                     syntmp-e-682
                     (syntmp-anti-mark-133 syntmp-w-684)))
                 (string #\m)))))
         (syntmp-chi-application-156
           (lambda (syntmp-x-696
                    syntmp-e-697
                    syntmp-r-698
                    syntmp-w-699
                    syntmp-s-700)
             ((lambda (syntmp-tmp-701)
                ((lambda (syntmp-tmp-702)
                   (if syntmp-tmp-702
                     (apply (lambda (syntmp-e0-703 syntmp-e1-704)
                              (cons syntmp-x-696
                                    (map (lambda (syntmp-e-705)
                                           (syntmp-chi-154
                                             syntmp-e-705
                                             syntmp-r-698
                                             syntmp-w-699))
                                         syntmp-e1-704)))
                            syntmp-tmp-702)
                     (syntax-error syntmp-tmp-701)))
                 (syntax-dispatch
                   syntmp-tmp-701
                   '(any . each-any))))
              syntmp-e-697)))
         (syntmp-chi-expr-155
           (lambda (syntmp-type-707
                    syntmp-value-708
                    syntmp-e-709
                    syntmp-r-710
                    syntmp-w-711
                    syntmp-s-712)
             (let ((syntmp-t-713 syntmp-type-707))
               (if (memv syntmp-t-713 (quote (lexical)))
                 syntmp-value-708
                 (if (memv syntmp-t-713 (quote (core external-macro)))
                   (syntmp-value-708
                     syntmp-e-709
                     syntmp-r-710
                     syntmp-w-711
                     syntmp-s-712)
                   (if (memv syntmp-t-713 (quote (lexical-call)))
                     (syntmp-chi-application-156
                       syntmp-value-708
                       syntmp-e-709
                       syntmp-r-710
                       syntmp-w-711
                       syntmp-s-712)
                     (if (memv syntmp-t-713 (quote (global-call)))
                       (syntmp-chi-application-156
                         syntmp-value-708
                         syntmp-e-709
                         syntmp-r-710
                         syntmp-w-711
                         syntmp-s-712)
                       (if (memv syntmp-t-713 (quote (constant)))
                         (syntmp-build-data-98
                           syntmp-s-712
                           (syntmp-strip-165
                             (syntmp-source-wrap-147
                               syntmp-e-709
                               syntmp-w-711
                               syntmp-s-712)
                             '(())))
                         (if (memv syntmp-t-713 (quote (global)))
                           syntmp-value-708
                           (if (memv syntmp-t-713 (quote (call)))
                             (syntmp-chi-application-156
                               (syntmp-chi-154
                                 (car syntmp-e-709)
                                 syntmp-r-710
                                 syntmp-w-711)
                               syntmp-e-709
                               syntmp-r-710
                               syntmp-w-711
                               syntmp-s-712)
                             (if (memv syntmp-t-713 (quote (begin-form)))
                               ((lambda (syntmp-tmp-714)
                                  ((lambda (syntmp-tmp-715)
                                     (if syntmp-tmp-715
                                       (apply (lambda (syntmp-_-716
                                                       syntmp-e1-717
                                                       syntmp-e2-718)
                                                (syntmp-chi-sequence-148
                                                  (cons syntmp-e1-717
                                                        syntmp-e2-718)
                                                  syntmp-r-710
                                                  syntmp-w-711
                                                  syntmp-s-712))
                                              syntmp-tmp-715)
                                       (syntax-error syntmp-tmp-714)))
                                   (syntax-dispatch
                                     syntmp-tmp-714
                                     '(any any . each-any))))
                                syntmp-e-709)
                               (if (memv syntmp-t-713
                                         '(local-syntax-form))
                                 (syntmp-chi-local-syntax-160
                                   syntmp-value-708
                                   syntmp-e-709
                                   syntmp-r-710
                                   syntmp-w-711
                                   syntmp-s-712
                                   syntmp-chi-sequence-148)
                                 (if (memv syntmp-t-713
                                           '(eval-when-form))
                                   ((lambda (syntmp-tmp-720)
                                      ((lambda (syntmp-tmp-721)
                                         (if syntmp-tmp-721
                                           (apply (lambda (syntmp-_-722
                                                           syntmp-x-723
                                                           syntmp-e1-724
                                                           syntmp-e2-725)
                                                    (let ((syntmp-when-list-726
                                                            (syntmp-chi-when-list-151
                                                              syntmp-e-709
                                                              syntmp-x-723
                                                              syntmp-w-711)))
                                                      (if (memq 'eval
                                                                syntmp-when-list-726)
                                                        (syntmp-chi-sequence-148
                                                          (cons syntmp-e1-724
                                                                syntmp-e2-725)
                                                          syntmp-r-710
                                                          syntmp-w-711
                                                          syntmp-s-712)
                                                        (syntmp-chi-void-162))))
                                                  syntmp-tmp-721)
                                           (syntax-error syntmp-tmp-720)))
                                       (syntax-dispatch
                                         syntmp-tmp-720
                                         '(any each-any any . each-any))))
                                    syntmp-e-709)
                                   (if (memv syntmp-t-713
                                             '(define-form define-syntax-form))
                                     (syntax-error
                                       (syntmp-wrap-146
                                         syntmp-value-708
                                         syntmp-w-711)
                                       "invalid context for definition of")
                                     (if (memv syntmp-t-713 (quote (syntax)))
                                       (syntax-error
                                         (syntmp-source-wrap-147
                                           syntmp-e-709
                                           syntmp-w-711
                                           syntmp-s-712)
                                         "reference to pattern variable outside syntax form")
                                       (if (memv syntmp-t-713
                                                 '(displaced-lexical))
                                         (syntax-error
                                           (syntmp-source-wrap-147
                                             syntmp-e-709
                                             syntmp-w-711
                                             syntmp-s-712)
                                           "reference to identifier outside its scope")
                                         (syntax-error
                                           (syntmp-source-wrap-147
                                             syntmp-e-709
                                             syntmp-w-711
                                             syntmp-s-712))))))))))))))))))
         (syntmp-chi-154
           (lambda (syntmp-e-729 syntmp-r-730 syntmp-w-731)
             (call-with-values
               (lambda ()
                 (syntmp-syntax-type-152
                   syntmp-e-729
                   syntmp-r-730
                   syntmp-w-731
                   #f
                   #f))
               (lambda (syntmp-type-732
                        syntmp-value-733
                        syntmp-e-734
                        syntmp-w-735
                        syntmp-s-736)
                 (syntmp-chi-expr-155
                   syntmp-type-732
                   syntmp-value-733
                   syntmp-e-734
                   syntmp-r-730
                   syntmp-w-735
                   syntmp-s-736)))))
         (syntmp-chi-top-153
           (lambda (syntmp-e-737
                    syntmp-r-738
                    syntmp-w-739
                    syntmp-m-740
                    syntmp-esew-741)
             (call-with-values
               (lambda ()
                 (syntmp-syntax-type-152
                   syntmp-e-737
                   syntmp-r-738
                   syntmp-w-739
                   #f
                   #f))
               (lambda (syntmp-type-754
                        syntmp-value-755
                        syntmp-e-756
                        syntmp-w-757
                        syntmp-s-758)
                 (let ((syntmp-t-759 syntmp-type-754))
                   (if (memv syntmp-t-759 (quote (begin-form)))
                     ((lambda (syntmp-tmp-760)
                        ((lambda (syntmp-tmp-761)
                           (if syntmp-tmp-761
                             (apply (lambda (syntmp-_-762)
                                      (syntmp-chi-void-162))
                                    syntmp-tmp-761)
                             ((lambda (syntmp-tmp-763)
                                (if syntmp-tmp-763
                                  (apply (lambda (syntmp-_-764
                                                  syntmp-e1-765
                                                  syntmp-e2-766)
                                           (syntmp-chi-top-sequence-149
                                             (cons syntmp-e1-765 syntmp-e2-766)
                                             syntmp-r-738
                                             syntmp-w-757
                                             syntmp-s-758
                                             syntmp-m-740
                                             syntmp-esew-741))
                                         syntmp-tmp-763)
                                  (syntax-error syntmp-tmp-760)))
                              (syntax-dispatch
                                syntmp-tmp-760
                                '(any any . each-any)))))
                         (syntax-dispatch syntmp-tmp-760 (quote (any)))))
                      syntmp-e-756)
                     (if (memv syntmp-t-759 (quote (local-syntax-form)))
                       (syntmp-chi-local-syntax-160
                         syntmp-value-755
                         syntmp-e-756
                         syntmp-r-738
                         syntmp-w-757
                         syntmp-s-758
                         (lambda (syntmp-body-768
                                  syntmp-r-769
                                  syntmp-w-770
                                  syntmp-s-771)
                           (syntmp-chi-top-sequence-149
                             syntmp-body-768
                             syntmp-r-769
                             syntmp-w-770
                             syntmp-s-771
                             syntmp-m-740
                             syntmp-esew-741)))
                       (if (memv syntmp-t-759 (quote (eval-when-form)))
                         ((lambda (syntmp-tmp-772)
                            ((lambda (syntmp-tmp-773)
                               (if syntmp-tmp-773
                                 (apply (lambda (syntmp-_-774
                                                 syntmp-x-775
                                                 syntmp-e1-776
                                                 syntmp-e2-777)
                                          (let ((syntmp-when-list-778
                                                  (syntmp-chi-when-list-151
                                                    syntmp-e-756
                                                    syntmp-x-775
                                                    syntmp-w-757))
                                                (syntmp-body-779
                                                  (cons syntmp-e1-776
                                                        syntmp-e2-777)))
                                            (cond ((eq? syntmp-m-740 (quote e))
                                                   (if (memq 'eval
                                                             syntmp-when-list-778)
                                                     (syntmp-chi-top-sequence-149
                                                       syntmp-body-779
                                                       syntmp-r-738
                                                       syntmp-w-757
                                                       syntmp-s-758
                                                       'e
                                                       '(eval))
                                                     (syntmp-chi-void-162)))
                                                  ((memq 'load
                                                         syntmp-when-list-778)
                                                   (if (or (memq 'compile
                                                                 syntmp-when-list-778)
                                                           (and (eq? syntmp-m-740
                                                                     'c&e)
                                                                (memq 'eval
                                                                      syntmp-when-list-778)))
                                                     (syntmp-chi-top-sequence-149
                                                       syntmp-body-779
                                                       syntmp-r-738
                                                       syntmp-w-757
                                                       syntmp-s-758
                                                       'c&e
                                                       '(compile load))
                                                     (if (memq syntmp-m-740
                                                               '(c c&e))
                                                       (syntmp-chi-top-sequence-149
                                                         syntmp-body-779
                                                         syntmp-r-738
                                                         syntmp-w-757
                                                         syntmp-s-758
                                                         'c
                                                         '(load))
                                                       (syntmp-chi-void-162))))
                                                  ((or (memq 'compile
                                                             syntmp-when-list-778)
                                                       (and (eq? syntmp-m-740
                                                                 'c&e)
                                                            (memq 'eval
                                                                  syntmp-when-list-778)))
                                                   (syntmp-top-level-eval-hook-93
                                                     (syntmp-chi-top-sequence-149
                                                       syntmp-body-779
                                                       syntmp-r-738
                                                       syntmp-w-757
                                                       syntmp-s-758
                                                       'e
                                                       '(eval)))
                                                   (syntmp-chi-void-162))
                                                  (else
                                                   (syntmp-chi-void-162)))))
                                        syntmp-tmp-773)
                                 (syntax-error syntmp-tmp-772)))
                             (syntax-dispatch
                               syntmp-tmp-772
                               '(any each-any any . each-any))))
                          syntmp-e-756)
                         (if (memv syntmp-t-759 (quote (define-syntax-form)))
                           (let ((syntmp-n-782
                                   (syntmp-id-var-name-140
                                     syntmp-value-755
                                     syntmp-w-757))
                                 (syntmp-r-783
                                   (syntmp-macros-only-env-114 syntmp-r-738)))
                             (let ((syntmp-t-784 syntmp-m-740))
                               (if (memv syntmp-t-784 (quote (c)))
                                 (if (memq (quote compile) syntmp-esew-741)
                                   (let ((syntmp-e-785
                                           (syntmp-chi-install-global-150
                                             syntmp-n-782
                                             (syntmp-chi-154
                                               syntmp-e-756
                                               syntmp-r-783
                                               syntmp-w-757))))
                                     (begin
                                       (syntmp-top-level-eval-hook-93
                                         syntmp-e-785)
                                       (if (memq (quote load) syntmp-esew-741)
                                         syntmp-e-785
                                         (syntmp-chi-void-162))))
                                   (if (memq (quote load) syntmp-esew-741)
                                     (syntmp-chi-install-global-150
                                       syntmp-n-782
                                       (syntmp-chi-154
                                         syntmp-e-756
                                         syntmp-r-783
                                         syntmp-w-757))
                                     (syntmp-chi-void-162)))
                                 (if (memv syntmp-t-784 (quote (c&e)))
                                   (let ((syntmp-e-786
                                           (syntmp-chi-install-global-150
                                             syntmp-n-782
                                             (syntmp-chi-154
                                               syntmp-e-756
                                               syntmp-r-783
                                               syntmp-w-757))))
                                     (begin
                                       (syntmp-top-level-eval-hook-93
                                         syntmp-e-786)
                                       syntmp-e-786))
                                   (begin
                                     (if (memq (quote eval) syntmp-esew-741)
                                       (syntmp-top-level-eval-hook-93
                                         (syntmp-chi-install-global-150
                                           syntmp-n-782
                                           (syntmp-chi-154
                                             syntmp-e-756
                                             syntmp-r-783
                                             syntmp-w-757))))
                                     (syntmp-chi-void-162))))))
                           (if (memv syntmp-t-759 (quote (define-form)))
                             (let ((syntmp-n-787
                                     (syntmp-id-var-name-140
                                       syntmp-value-755
                                       syntmp-w-757)))
                               (let ((syntmp-type-788
                                       (syntmp-binding-type-110
                                         (syntmp-lookup-115
                                           syntmp-n-787
                                           syntmp-r-738))))
                                 (let ((syntmp-t-789 syntmp-type-788))
                                   (if (memv syntmp-t-789 (quote (global)))
                                     (let ((syntmp-x-790
                                             (list 'define
                                                   syntmp-n-787
                                                   (syntmp-chi-154
                                                     syntmp-e-756
                                                     syntmp-r-738
                                                     syntmp-w-757))))
                                       (begin
                                         (if (eq? syntmp-m-740 (quote c&e))
                                           (syntmp-top-level-eval-hook-93
                                             syntmp-x-790))
                                         syntmp-x-790))
                                     (if (memv syntmp-t-789
                                               '(displaced-lexical))
                                       (syntax-error
                                         (syntmp-wrap-146
                                           syntmp-value-755
                                           syntmp-w-757)
                                         "identifier out of context")
                                       (if (eq? syntmp-type-788
                                                'external-macro)
                                         (let ((syntmp-x-791
                                                 (list 'define
                                                       syntmp-n-787
                                                       (syntmp-chi-154
                                                         syntmp-e-756
                                                         syntmp-r-738
                                                         syntmp-w-757))))
                                           (begin
                                             (if (eq? syntmp-m-740 (quote c&e))
                                               (syntmp-top-level-eval-hook-93
                                                 syntmp-x-791))
                                             syntmp-x-791))
                                         (syntax-error
                                           (syntmp-wrap-146
                                             syntmp-value-755
                                             syntmp-w-757)
                                           "cannot define keyword at top level")))))))
                             (let ((syntmp-x-792
                                     (syntmp-chi-expr-155
                                       syntmp-type-754
                                       syntmp-value-755
                                       syntmp-e-756
                                       syntmp-r-738
                                       syntmp-w-757
                                       syntmp-s-758)))
                               (begin
                                 (if (eq? syntmp-m-740 (quote c&e))
                                   (syntmp-top-level-eval-hook-93
                                     syntmp-x-792))
                                 syntmp-x-792))))))))))))
         (syntmp-syntax-type-152
           (lambda (syntmp-e-793
                    syntmp-r-794
                    syntmp-w-795
                    syntmp-s-796
                    syntmp-rib-797)
             (cond ((symbol? syntmp-e-793)
                    (let ((syntmp-n-798
                            (syntmp-id-var-name-140
                              syntmp-e-793
                              syntmp-w-795)))
                      (let ((syntmp-b-799
                              (syntmp-lookup-115 syntmp-n-798 syntmp-r-794)))
                        (let ((syntmp-type-800
                                (syntmp-binding-type-110 syntmp-b-799)))
                          (let ((syntmp-t-801 syntmp-type-800))
                            (if (memv syntmp-t-801 (quote (lexical)))
                              (values
                                syntmp-type-800
                                (syntmp-binding-value-111 syntmp-b-799)
                                syntmp-e-793
                                syntmp-w-795
                                syntmp-s-796)
                              (if (memv syntmp-t-801 (quote (global)))
                                (values
                                  syntmp-type-800
                                  syntmp-n-798
                                  syntmp-e-793
                                  syntmp-w-795
                                  syntmp-s-796)
                                (if (memv syntmp-t-801 (quote (macro)))
                                  (syntmp-syntax-type-152
                                    (syntmp-chi-macro-157
                                      (syntmp-binding-value-111 syntmp-b-799)
                                      syntmp-e-793
                                      syntmp-r-794
                                      syntmp-w-795
                                      syntmp-rib-797)
                                    syntmp-r-794
                                    '(())
                                    syntmp-s-796
                                    syntmp-rib-797)
                                  (values
                                    syntmp-type-800
                                    (syntmp-binding-value-111 syntmp-b-799)
                                    syntmp-e-793
                                    syntmp-w-795
                                    syntmp-s-796)))))))))
                   ((pair? syntmp-e-793)
                    (let ((syntmp-first-802 (car syntmp-e-793)))
                      (if (syntmp-id?-118 syntmp-first-802)
                        (let ((syntmp-n-803
                                (syntmp-id-var-name-140
                                  syntmp-first-802
                                  syntmp-w-795)))
                          (let ((syntmp-b-804
                                  (syntmp-lookup-115
                                    syntmp-n-803
                                    syntmp-r-794)))
                            (let ((syntmp-type-805
                                    (syntmp-binding-type-110 syntmp-b-804)))
                              (let ((syntmp-t-806 syntmp-type-805))
                                (if (memv syntmp-t-806 (quote (lexical)))
                                  (values
                                    'lexical-call
                                    (syntmp-binding-value-111 syntmp-b-804)
                                    syntmp-e-793
                                    syntmp-w-795
                                    syntmp-s-796)
                                  (if (memv syntmp-t-806 (quote (global)))
                                    (values
                                      'global-call
                                      syntmp-n-803
                                      syntmp-e-793
                                      syntmp-w-795
                                      syntmp-s-796)
                                    (if (memv syntmp-t-806 (quote (macro)))
                                      (syntmp-syntax-type-152
                                        (syntmp-chi-macro-157
                                          (syntmp-binding-value-111
                                            syntmp-b-804)
                                          syntmp-e-793
                                          syntmp-r-794
                                          syntmp-w-795
                                          syntmp-rib-797)
                                        syntmp-r-794
                                        '(())
                                        syntmp-s-796
                                        syntmp-rib-797)
                                      (if (memv syntmp-t-806
                                                '(core external-macro))
                                        (values
                                          syntmp-type-805
                                          (syntmp-binding-value-111
                                            syntmp-b-804)
                                          syntmp-e-793
                                          syntmp-w-795
                                          syntmp-s-796)
                                        (if (memv syntmp-t-806
                                                  '(local-syntax))
                                          (values
                                            'local-syntax-form
                                            (syntmp-binding-value-111
                                              syntmp-b-804)
                                            syntmp-e-793
                                            syntmp-w-795
                                            syntmp-s-796)
                                          (if (memv syntmp-t-806
                                                    '(begin))
                                            (values
                                              'begin-form
                                              #f
                                              syntmp-e-793
                                              syntmp-w-795
                                              syntmp-s-796)
                                            (if (memv syntmp-t-806
                                                      '(eval-when))
                                              (values
                                                'eval-when-form
                                                #f
                                                syntmp-e-793
                                                syntmp-w-795
                                                syntmp-s-796)
                                              (if (memv syntmp-t-806
                                                        '(define))
                                                ((lambda (syntmp-tmp-807)
                                                   ((lambda (syntmp-tmp-808)
                                                      (if (if syntmp-tmp-808
                                                            (apply (lambda (syntmp-_-809
                                                                            syntmp-name-810
                                                                            syntmp-val-811)
                                                                     (syntmp-id?-118
                                                                       syntmp-name-810))
                                                                   syntmp-tmp-808)
                                                            #f)
                                                        (apply (lambda (syntmp-_-812
                                                                        syntmp-name-813
                                                                        syntmp-val-814)
                                                                 (values
                                                                   'define-form
                                                                   syntmp-name-813
                                                                   syntmp-val-814
                                                                   syntmp-w-795
                                                                   syntmp-s-796))
                                                               syntmp-tmp-808)
                                                        ((lambda (syntmp-tmp-815)
                                                           (if (if syntmp-tmp-815
                                                                 (apply (lambda (syntmp-_-816
                                                                                 syntmp-name-817
                                                                                 syntmp-args-818
                                                                                 syntmp-e1-819
                                                                                 syntmp-e2-820)
                                                                          (and (syntmp-id?-118
                                                                                 syntmp-name-817)
                                                                               (syntmp-valid-bound-ids?-143
                                                                                 (syntmp-lambda-var-list-167
                                                                                   syntmp-args-818))))
                                                                        syntmp-tmp-815)
                                                                 #f)
                                                             (apply (lambda (syntmp-_-821
                                                                             syntmp-name-822
                                                                             syntmp-args-823
                                                                             syntmp-e1-824
                                                                             syntmp-e2-825)
                                                                      (values
                                                                        'define-form
                                                                        (syntmp-wrap-146
                                                                          syntmp-name-822
                                                                          syntmp-w-795)
                                                                        (cons '#(syntax-object
                                                                                 lambda
                                                                                 ((top)
                                                                                  #(ribcage
                                                                                    #(_
                                                                                      name
                                                                                      args
                                                                                      e1
                                                                                      e2)
                                                                                    #((top)
                                                                                      (top)
                                                                                      (top)
                                                                                      (top)
                                                                                      (top))
                                                                                    #("i"
                                                                                      "i"
                                                                                      "i"
                                                                                      "i"
                                                                                      "i"))
                                                                                  #(ribcage
                                                                                    ()
                                                                                    ()
                                                                                    ())
                                                                                  #(ribcage
                                                                                    #(t)
                                                                                    #(("m"
                                                                                       top))
                                                                                    #("i"))
                                                                                  #(ribcage
                                                                                    ()
                                                                                    ()
                                                                                    ())
                                                                                  #(ribcage
                                                                                    ()
                                                                                    ()
                                                                                    ())
                                                                                  #(ribcage
                                                                                    ()
                                                                                    ()
                                                                                    ())
                                                                                  #(ribcage
                                                                                    #(type)
                                                                                    #((top))
                                                                                    #("i"))
                                                                                  #(ribcage
                                                                                    ()
                                                                                    ()
                                                                                    ())
                                                                                  #(ribcage
                                                                                    #(b)
                                                                                    #((top))
                                                                                    #("i"))
                                                                                  #(ribcage
                                                                                    ()
                                                                                    ()
                                                                                    ())
                                                                                  #(ribcage
                                                                                    #(n)
                                                                                    #((top))
                                                                                    #("i"))
                                                                                  #(ribcage
                                                                                    ()
                                                                                    ()
                                                                                    ())
                                                                                  #(ribcage
                                                                                    #(first)
                                                                                    #((top))
                                                                                    #("i"))
                                                                                  #(ribcage
                                                                                    ()
                                                                                    ()
                                                                                    ())
                                                                                  #(ribcage
                                                                                    #(e
                                                                                      r
                                                                                      w
                                                                                      s
                                                                                      rib)
                                                                                    #((top)
                                                                                      (top)
                                                                                      (top)
                                                                                      (top)
                                                                                      (top))
                                                                                    #("i"
                                                                                      "i"
                                                                                      "i"
                                                                                      "i"
                                                                                      "i"))
                                                                                  #(ribcage
                                                                                    (lambda-var-list
                                                                                      gen-var
                                                                                      strip
                                                                                      strip-annotation
                                                                                      ellipsis?
                                                                                      chi-void
                                                                                      eval-local-transformer
                                                                                      chi-local-syntax
                                                                                      chi-lambda-clause
                                                                                      chi-body
                                                                                      chi-macro
                                                                                      chi-application
                                                                                      chi-expr
                                                                                      chi
                                                                                      chi-top
                                                                                      syntax-type
                                                                                      chi-when-list
                                                                                      chi-install-global
                                                                                      chi-top-sequence
                                                                                      chi-sequence
                                                                                      source-wrap
                                                                                      wrap
                                                                                      bound-id-member?
                                                                                      distinct-bound-ids?
                                                                                      valid-bound-ids?
                                                                                      bound-id=?
                                                                                      free-id=?
                                                                                      id-var-name
                                                                                      same-marks?
                                                                                      join-marks
                                                                                      join-wraps
                                                                                      smart-append
                                                                                      make-binding-wrap
                                                                                      extend-ribcage!
                                                                                      make-empty-ribcage
                                                                                      new-mark
                                                                                      anti-mark
                                                                                      the-anti-mark
                                                                                      top-marked?
                                                                                      top-wrap
                                                                                      empty-wrap
                                                                                      set-ribcage-labels!
                                                                                      set-ribcage-marks!
                                                                                      set-ribcage-symnames!
                                                                                      ribcage-labels
                                                                                      ribcage-marks
                                                                                      ribcage-symnames
                                                                                      ribcage?
                                                                                      make-ribcage
                                                                                      gen-labels
                                                                                      gen-label
                                                                                      make-rename
                                                                                      rename-marks
                                                                                      rename-new
                                                                                      rename-old
                                                                                      subst-rename?
                                                                                      wrap-subst
                                                                                      wrap-marks
                                                                                      make-wrap
                                                                                      id-sym-name&marks
                                                                                      id-sym-name
                                                                                      id?
                                                                                      nonsymbol-id?
                                                                                      global-extend
                                                                                      lookup
                                                                                      macros-only-env
                                                                                      extend-var-env
                                                                                      extend-env
                                                                                      null-env
                                                                                      binding-value
                                                                                      binding-type
                                                                                      make-binding
                                                                                      arg-check
                                                                                      source-annotation
                                                                                      no-source
                                                                                      unannotate
                                                                                      set-syntax-object-wrap!
                                                                                      set-syntax-object-expression!
                                                                                      syntax-object-wrap
                                                                                      syntax-object-expression
                                                                                      syntax-object?
                                                                                      make-syntax-object
                                                                                      build-lexical-var
                                                                                      build-letrec
                                                                                      build-named-let
                                                                                      build-let
                                                                                      build-sequence
                                                                                      build-data
                                                                                      build-primref
                                                                                      build-lambda
                                                                                      build-global-definition
                                                                                      build-global-assignment
                                                                                      build-global-reference
                                                                                      build-lexical-assignment
                                                                                      build-lexical-reference
                                                                                      build-conditional
                                                                                      build-application
                                                                                      get-global-definition-hook
                                                                                      put-global-definition-hook
                                                                                      gensym-hook
                                                                                      error-hook
                                                                                      local-eval-hook
                                                                                      top-level-eval-hook
                                                                                      annotation?
                                                                                      fx<
                                                                                      fx=
                                                                                      fx-
                                                                                      fx+
                                                                                      noexpand)
                                                                                    ((top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top))
                                                                                    ("i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"))
                                                                                  #(ribcage
                                                                                    (define-structure)
                                                                                    ((top))
                                                                                    ("i"))))
                                                                              (syntmp-wrap-146
                                                                                (cons syntmp-args-823
                                                                                      (cons syntmp-e1-824
                                                                                            syntmp-e2-825))
                                                                                syntmp-w-795))
                                                                        '(())
                                                                        syntmp-s-796))
                                                                    syntmp-tmp-815)
                                                             ((lambda (syntmp-tmp-827)
                                                                (if (if syntmp-tmp-827
                                                                      (apply (lambda (syntmp-_-828
                                                                                      syntmp-name-829)
                                                                               (syntmp-id?-118
                                                                                 syntmp-name-829))
                                                                             syntmp-tmp-827)
                                                                      #f)
                                                                  (apply (lambda (syntmp-_-830
                                                                                  syntmp-name-831)
                                                                           (values
                                                                             'define-form
                                                                             (syntmp-wrap-146
                                                                               syntmp-name-831
                                                                               syntmp-w-795)
                                                                             '(#(syntax-object
                                                                                 void
                                                                                 ((top)
                                                                                  #(ribcage
                                                                                    #(_
                                                                                      name)
                                                                                    #((top)
                                                                                      (top))
                                                                                    #("i"
                                                                                      "i"))
                                                                                  #(ribcage
                                                                                    ()
                                                                                    ()
                                                                                    ())
                                                                                  #(ribcage
                                                                                    #(t)
                                                                                    #(("m"
                                                                                       top))
                                                                                    #("i"))
                                                                                  #(ribcage
                                                                                    ()
                                                                                    ()
                                                                                    ())
                                                                                  #(ribcage
                                                                                    ()
                                                                                    ()
                                                                                    ())
                                                                                  #(ribcage
                                                                                    ()
                                                                                    ()
                                                                                    ())
                                                                                  #(ribcage
                                                                                    #(type)
                                                                                    #((top))
                                                                                    #("i"))
                                                                                  #(ribcage
                                                                                    ()
                                                                                    ()
                                                                                    ())
                                                                                  #(ribcage
                                                                                    #(b)
                                                                                    #((top))
                                                                                    #("i"))
                                                                                  #(ribcage
                                                                                    ()
                                                                                    ()
                                                                                    ())
                                                                                  #(ribcage
                                                                                    #(n)
                                                                                    #((top))
                                                                                    #("i"))
                                                                                  #(ribcage
                                                                                    ()
                                                                                    ()
                                                                                    ())
                                                                                  #(ribcage
                                                                                    #(first)
                                                                                    #((top))
                                                                                    #("i"))
                                                                                  #(ribcage
                                                                                    ()
                                                                                    ()
                                                                                    ())
                                                                                  #(ribcage
                                                                                    #(e
                                                                                      r
                                                                                      w
                                                                                      s
                                                                                      rib)
                                                                                    #((top)
                                                                                      (top)
                                                                                      (top)
                                                                                      (top)
                                                                                      (top))
                                                                                    #("i"
                                                                                      "i"
                                                                                      "i"
                                                                                      "i"
                                                                                      "i"))
                                                                                  #(ribcage
                                                                                    (lambda-var-list
                                                                                      gen-var
                                                                                      strip
                                                                                      strip-annotation
                                                                                      ellipsis?
                                                                                      chi-void
                                                                                      eval-local-transformer
                                                                                      chi-local-syntax
                                                                                      chi-lambda-clause
                                                                                      chi-body
                                                                                      chi-macro
                                                                                      chi-application
                                                                                      chi-expr
                                                                                      chi
                                                                                      chi-top
                                                                                      syntax-type
                                                                                      chi-when-list
                                                                                      chi-install-global
                                                                                      chi-top-sequence
                                                                                      chi-sequence
                                                                                      source-wrap
                                                                                      wrap
                                                                                      bound-id-member?
                                                                                      distinct-bound-ids?
                                                                                      valid-bound-ids?
                                                                                      bound-id=?
                                                                                      free-id=?
                                                                                      id-var-name
                                                                                      same-marks?
                                                                                      join-marks
                                                                                      join-wraps
                                                                                      smart-append
                                                                                      make-binding-wrap
                                                                                      extend-ribcage!
                                                                                      make-empty-ribcage
                                                                                      new-mark
                                                                                      anti-mark
                                                                                      the-anti-mark
                                                                                      top-marked?
                                                                                      top-wrap
                                                                                      empty-wrap
                                                                                      set-ribcage-labels!
                                                                                      set-ribcage-marks!
                                                                                      set-ribcage-symnames!
                                                                                      ribcage-labels
                                                                                      ribcage-marks
                                                                                      ribcage-symnames
                                                                                      ribcage?
                                                                                      make-ribcage
                                                                                      gen-labels
                                                                                      gen-label
                                                                                      make-rename
                                                                                      rename-marks
                                                                                      rename-new
                                                                                      rename-old
                                                                                      subst-rename?
                                                                                      wrap-subst
                                                                                      wrap-marks
                                                                                      make-wrap
                                                                                      id-sym-name&marks
                                                                                      id-sym-name
                                                                                      id?
                                                                                      nonsymbol-id?
                                                                                      global-extend
                                                                                      lookup
                                                                                      macros-only-env
                                                                                      extend-var-env
                                                                                      extend-env
                                                                                      null-env
                                                                                      binding-value
                                                                                      binding-type
                                                                                      make-binding
                                                                                      arg-check
                                                                                      source-annotation
                                                                                      no-source
                                                                                      unannotate
                                                                                      set-syntax-object-wrap!
                                                                                      set-syntax-object-expression!
                                                                                      syntax-object-wrap
                                                                                      syntax-object-expression
                                                                                      syntax-object?
                                                                                      make-syntax-object
                                                                                      build-lexical-var
                                                                                      build-letrec
                                                                                      build-named-let
                                                                                      build-let
                                                                                      build-sequence
                                                                                      build-data
                                                                                      build-primref
                                                                                      build-lambda
                                                                                      build-global-definition
                                                                                      build-global-assignment
                                                                                      build-global-reference
                                                                                      build-lexical-assignment
                                                                                      build-lexical-reference
                                                                                      build-conditional
                                                                                      build-application
                                                                                      get-global-definition-hook
                                                                                      put-global-definition-hook
                                                                                      gensym-hook
                                                                                      error-hook
                                                                                      local-eval-hook
                                                                                      top-level-eval-hook
                                                                                      annotation?
                                                                                      fx<
                                                                                      fx=
                                                                                      fx-
                                                                                      fx+
                                                                                      noexpand)
                                                                                    ((top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top)
                                                                                     (top))
                                                                                    ("i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"
                                                                                     "i"))
                                                                                  #(ribcage
                                                                                    (define-structure)
                                                                                    ((top))
                                                                                    ("i")))))
                                                                             '(())
                                                                             syntmp-s-796))
                                                                         syntmp-tmp-827)
                                                                  (syntax-error
                                                                    syntmp-tmp-807)))
                                                              (syntax-dispatch
                                                                syntmp-tmp-807
                                                                '(any any)))))
                                                         (syntax-dispatch
                                                           syntmp-tmp-807
                                                           '(any (any . any)
                                                                 any
                                                                 .
                                                                 each-any)))))
                                                    (syntax-dispatch
                                                      syntmp-tmp-807
                                                      '(any any any))))
                                                 syntmp-e-793)
                                                (if (memv syntmp-t-806
                                                          '(define-syntax))
                                                  ((lambda (syntmp-tmp-832)
                                                     ((lambda (syntmp-tmp-833)
                                                        (if (if syntmp-tmp-833
                                                              (apply (lambda (syntmp-_-834
                                                                              syntmp-name-835
                                                                              syntmp-val-836)
                                                                       (syntmp-id?-118
                                                                         syntmp-name-835))
                                                                     syntmp-tmp-833)
                                                              #f)
                                                          (apply (lambda (syntmp-_-837
                                                                          syntmp-name-838
                                                                          syntmp-val-839)
                                                                   (values
                                                                     'define-syntax-form
                                                                     syntmp-name-838
                                                                     syntmp-val-839
                                                                     syntmp-w-795
                                                                     syntmp-s-796))
                                                                 syntmp-tmp-833)
                                                          (syntax-error
                                                            syntmp-tmp-832)))
                                                      (syntax-dispatch
                                                        syntmp-tmp-832
                                                        '(any any any))))
                                                   syntmp-e-793)
                                                  (if (memv syntmp-t-806
                                                            '(ellipsis))
                                                    (values
                                                      'ellipsis
                                                      (syntmp-make-syntax-object-103
                                                        (syntmp-syntax-object-expression-105
                                                          value)
                                                        (syntmp-anti-mark-133
                                                          (syntmp-syntax-object-wrap-106
                                                            value))))
                                                    (values
                                                      'call
                                                      #f
                                                      syntmp-e-793
                                                      syntmp-w-795
                                                      syntmp-s-796)))))))))))))))
                        (values
                          'call
                          #f
                          syntmp-e-793
                          syntmp-w-795
                          syntmp-s-796))))
                   ((syntmp-syntax-object?-104 syntmp-e-793)
                    (syntmp-syntax-type-152
                      (syntmp-syntax-object-expression-105
                        syntmp-e-793)
                      syntmp-r-794
                      (syntmp-join-wraps-137
                        syntmp-w-795
                        (syntmp-syntax-object-wrap-106 syntmp-e-793))
                      #f
                      syntmp-rib-797))
                   ((syntmp-annotation?-92 syntmp-e-793)
                    (syntmp-syntax-type-152
                      (annotation-expression syntmp-e-793)
                      syntmp-r-794
                      syntmp-w-795
                      (annotation-source syntmp-e-793)
                      syntmp-rib-797))
                   ((self-evaluating? syntmp-e-793)
                    (values
                      'constant
                      #f
                      syntmp-e-793
                      syntmp-w-795
                      syntmp-s-796))
                   (else
                    (values
                      'other
                      #f
                      syntmp-e-793
                      syntmp-w-795
                      syntmp-s-796)))))
         (syntmp-chi-when-list-151
           (lambda (syntmp-e-840 syntmp-when-list-841 syntmp-w-842)
             (let syntmp-f-843 ((syntmp-when-list-844 syntmp-when-list-841)
                                (syntmp-situations-845 (quote ())))
               (if (null? syntmp-when-list-844)
                 syntmp-situations-845
                 (syntmp-f-843
                   (cdr syntmp-when-list-844)
                   (cons (let ((syntmp-x-846 (car syntmp-when-list-844)))
                           (cond ((syntmp-free-id=?-141
                                    syntmp-x-846
                                    '#(syntax-object
                                       compile
                                       ((top)
                                        #(ribcage () () ())
                                        #(ribcage #(x) #((top)) #("i"))
                                        #(ribcage () () ())
                                        #(ribcage
                                          #(f when-list situations)
                                          #((top) (top) (top))
                                          #("i" "i" "i"))
                                        #(ribcage () () ())
                                        #(ribcage
                                          #(e when-list w)
                                          #((top) (top) (top))
                                          #("i" "i" "i"))
                                        #(ribcage
                                          (lambda-var-list
                                            gen-var
                                            strip
                                            strip-annotation
                                            ellipsis?
                                            chi-void
                                            eval-local-transformer
                                            chi-local-syntax
                                            chi-lambda-clause
                                            chi-body
                                            chi-macro
                                            chi-application
                                            chi-expr
                                            chi
                                            chi-top
                                            syntax-type
                                            chi-when-list
                                            chi-install-global
                                            chi-top-sequence
                                            chi-sequence
                                            source-wrap
                                            wrap
                                            bound-id-member?
                                            distinct-bound-ids?
                                            valid-bound-ids?
                                            bound-id=?
                                            free-id=?
                                            id-var-name
                                            same-marks?
                                            join-marks
                                            join-wraps
                                            smart-append
                                            make-binding-wrap
                                            extend-ribcage!
                                            make-empty-ribcage
                                            new-mark
                                            anti-mark
                                            the-anti-mark
                                            top-marked?
                                            top-wrap
                                            empty-wrap
                                            set-ribcage-labels!
                                            set-ribcage-marks!
                                            set-ribcage-symnames!
                                            ribcage-labels
                                            ribcage-marks
                                            ribcage-symnames
                                            ribcage?
                                            make-ribcage
                                            gen-labels
                                            gen-label
                                            make-rename
                                            rename-marks
                                            rename-new
                                            rename-old
                                            subst-rename?
                                            wrap-subst
                                            wrap-marks
                                            make-wrap
                                            id-sym-name&marks
                                            id-sym-name
                                            id?
                                            nonsymbol-id?
                                            global-extend
                                            lookup
                                            macros-only-env
                                            extend-var-env
                                            extend-env
                                            null-env
                                            binding-value
                                            binding-type
                                            make-binding
                                            arg-check
                                            source-annotation
                                            no-source
                                            unannotate
                                            set-syntax-object-wrap!
                                            set-syntax-object-expression!
                                            syntax-object-wrap
                                            syntax-object-expression
                                            syntax-object?
                                            make-syntax-object
                                            build-lexical-var
                                            build-letrec
                                            build-named-let
                                            build-let
                                            build-sequence
                                            build-data
                                            build-primref
                                            build-lambda
                                            build-global-definition
                                            build-global-assignment
                                            build-global-reference
                                            build-lexical-assignment
                                            build-lexical-reference
                                            build-conditional
                                            build-application
                                            get-global-definition-hook
                                            put-global-definition-hook
                                            gensym-hook
                                            error-hook
                                            local-eval-hook
                                            top-level-eval-hook
                                            annotation?
                                            fx<
                                            fx=
                                            fx-
                                            fx+
                                            noexpand)
                                          ((top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top))
                                          ("i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"))
                                        #(ribcage
                                          (define-structure)
                                          ((top))
                                          ("i")))))
                                  'compile)
                                 ((syntmp-free-id=?-141
                                    syntmp-x-846
                                    '#(syntax-object
                                       load
                                       ((top)
                                        #(ribcage () () ())
                                        #(ribcage #(x) #((top)) #("i"))
                                        #(ribcage () () ())
                                        #(ribcage
                                          #(f when-list situations)
                                          #((top) (top) (top))
                                          #("i" "i" "i"))
                                        #(ribcage () () ())
                                        #(ribcage
                                          #(e when-list w)
                                          #((top) (top) (top))
                                          #("i" "i" "i"))
                                        #(ribcage
                                          (lambda-var-list
                                            gen-var
                                            strip
                                            strip-annotation
                                            ellipsis?
                                            chi-void
                                            eval-local-transformer
                                            chi-local-syntax
                                            chi-lambda-clause
                                            chi-body
                                            chi-macro
                                            chi-application
                                            chi-expr
                                            chi
                                            chi-top
                                            syntax-type
                                            chi-when-list
                                            chi-install-global
                                            chi-top-sequence
                                            chi-sequence
                                            source-wrap
                                            wrap
                                            bound-id-member?
                                            distinct-bound-ids?
                                            valid-bound-ids?
                                            bound-id=?
                                            free-id=?
                                            id-var-name
                                            same-marks?
                                            join-marks
                                            join-wraps
                                            smart-append
                                            make-binding-wrap
                                            extend-ribcage!
                                            make-empty-ribcage
                                            new-mark
                                            anti-mark
                                            the-anti-mark
                                            top-marked?
                                            top-wrap
                                            empty-wrap
                                            set-ribcage-labels!
                                            set-ribcage-marks!
                                            set-ribcage-symnames!
                                            ribcage-labels
                                            ribcage-marks
                                            ribcage-symnames
                                            ribcage?
                                            make-ribcage
                                            gen-labels
                                            gen-label
                                            make-rename
                                            rename-marks
                                            rename-new
                                            rename-old
                                            subst-rename?
                                            wrap-subst
                                            wrap-marks
                                            make-wrap
                                            id-sym-name&marks
                                            id-sym-name
                                            id?
                                            nonsymbol-id?
                                            global-extend
                                            lookup
                                            macros-only-env
                                            extend-var-env
                                            extend-env
                                            null-env
                                            binding-value
                                            binding-type
                                            make-binding
                                            arg-check
                                            source-annotation
                                            no-source
                                            unannotate
                                            set-syntax-object-wrap!
                                            set-syntax-object-expression!
                                            syntax-object-wrap
                                            syntax-object-expression
                                            syntax-object?
                                            make-syntax-object
                                            build-lexical-var
                                            build-letrec
                                            build-named-let
                                            build-let
                                            build-sequence
                                            build-data
                                            build-primref
                                            build-lambda
                                            build-global-definition
                                            build-global-assignment
                                            build-global-reference
                                            build-lexical-assignment
                                            build-lexical-reference
                                            build-conditional
                                            build-application
                                            get-global-definition-hook
                                            put-global-definition-hook
                                            gensym-hook
                                            error-hook
                                            local-eval-hook
                                            top-level-eval-hook
                                            annotation?
                                            fx<
                                            fx=
                                            fx-
                                            fx+
                                            noexpand)
                                          ((top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top))
                                          ("i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"))
                                        #(ribcage
                                          (define-structure)
                                          ((top))
                                          ("i")))))
                                  'load)
                                 ((syntmp-free-id=?-141
                                    syntmp-x-846
                                    '#(syntax-object
                                       eval
                                       ((top)
                                        #(ribcage () () ())
                                        #(ribcage #(x) #((top)) #("i"))
                                        #(ribcage () () ())
                                        #(ribcage
                                          #(f when-list situations)
                                          #((top) (top) (top))
                                          #("i" "i" "i"))
                                        #(ribcage () () ())
                                        #(ribcage
                                          #(e when-list w)
                                          #((top) (top) (top))
                                          #("i" "i" "i"))
                                        #(ribcage
                                          (lambda-var-list
                                            gen-var
                                            strip
                                            strip-annotation
                                            ellipsis?
                                            chi-void
                                            eval-local-transformer
                                            chi-local-syntax
                                            chi-lambda-clause
                                            chi-body
                                            chi-macro
                                            chi-application
                                            chi-expr
                                            chi
                                            chi-top
                                            syntax-type
                                            chi-when-list
                                            chi-install-global
                                            chi-top-sequence
                                            chi-sequence
                                            source-wrap
                                            wrap
                                            bound-id-member?
                                            distinct-bound-ids?
                                            valid-bound-ids?
                                            bound-id=?
                                            free-id=?
                                            id-var-name
                                            same-marks?
                                            join-marks
                                            join-wraps
                                            smart-append
                                            make-binding-wrap
                                            extend-ribcage!
                                            make-empty-ribcage
                                            new-mark
                                            anti-mark
                                            the-anti-mark
                                            top-marked?
                                            top-wrap
                                            empty-wrap
                                            set-ribcage-labels!
                                            set-ribcage-marks!
                                            set-ribcage-symnames!
                                            ribcage-labels
                                            ribcage-marks
                                            ribcage-symnames
                                            ribcage?
                                            make-ribcage
                                            gen-labels
                                            gen-label
                                            make-rename
                                            rename-marks
                                            rename-new
                                            rename-old
                                            subst-rename?
                                            wrap-subst
                                            wrap-marks
                                            make-wrap
                                            id-sym-name&marks
                                            id-sym-name
                                            id?
                                            nonsymbol-id?
                                            global-extend
                                            lookup
                                            macros-only-env
                                            extend-var-env
                                            extend-env
                                            null-env
                                            binding-value
                                            binding-type
                                            make-binding
                                            arg-check
                                            source-annotation
                                            no-source
                                            unannotate
                                            set-syntax-object-wrap!
                                            set-syntax-object-expression!
                                            syntax-object-wrap
                                            syntax-object-expression
                                            syntax-object?
                                            make-syntax-object
                                            build-lexical-var
                                            build-letrec
                                            build-named-let
                                            build-let
                                            build-sequence
                                            build-data
                                            build-primref
                                            build-lambda
                                            build-global-definition
                                            build-global-assignment
                                            build-global-reference
                                            build-lexical-assignment
                                            build-lexical-reference
                                            build-conditional
                                            build-application
                                            get-global-definition-hook
                                            put-global-definition-hook
                                            gensym-hook
                                            error-hook
                                            local-eval-hook
                                            top-level-eval-hook
                                            annotation?
                                            fx<
                                            fx=
                                            fx-
                                            fx+
                                            noexpand)
                                          ((top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top)
                                           (top))
                                          ("i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"
                                           "i"))
                                        #(ribcage
                                          (define-structure)
                                          ((top))
                                          ("i")))))
                                  'eval)
                                 (else
                                  (syntax-error
                                    (syntmp-wrap-146 syntmp-x-846 syntmp-w-842)
                                    "invalid eval-when situation"))))
                         syntmp-situations-845))))))
         (syntmp-chi-install-global-150
           (lambda (syntmp-name-847 syntmp-e-848)
             (list 'install-global-transformer
                   (syntmp-build-data-98 #f syntmp-name-847)
                   syntmp-e-848)))
         (syntmp-chi-top-sequence-149
           (lambda (syntmp-body-849
                    syntmp-r-850
                    syntmp-w-851
                    syntmp-s-852
                    syntmp-m-853
                    syntmp-esew-854)
             (syntmp-build-sequence-99
               syntmp-s-852
               (let syntmp-dobody-855 ((syntmp-body-856 syntmp-body-849)
                                       (syntmp-r-857 syntmp-r-850)
                                       (syntmp-w-858 syntmp-w-851)
                                       (syntmp-m-859 syntmp-m-853)
                                       (syntmp-esew-860 syntmp-esew-854))
                 (if (null? syntmp-body-856)
                   '()
                   (let ((syntmp-first-861
                           (syntmp-chi-top-153
                             (car syntmp-body-856)
                             syntmp-r-857
                             syntmp-w-858
                             syntmp-m-859
                             syntmp-esew-860)))
                     (cons syntmp-first-861
                           (syntmp-dobody-855
                             (cdr syntmp-body-856)
                             syntmp-r-857
                             syntmp-w-858
                             syntmp-m-859
                             syntmp-esew-860))))))))
         (syntmp-chi-sequence-148
           (lambda (syntmp-body-862
                    syntmp-r-863
                    syntmp-w-864
                    syntmp-s-865)
             (syntmp-build-sequence-99
               syntmp-s-865
               (let syntmp-dobody-866 ((syntmp-body-867 syntmp-body-862)
                                       (syntmp-r-868 syntmp-r-863)
                                       (syntmp-w-869 syntmp-w-864))
                 (if (null? syntmp-body-867)
                   '()
                   (let ((syntmp-first-870
                           (syntmp-chi-154
                             (car syntmp-body-867)
                             syntmp-r-868
                             syntmp-w-869)))
                     (cons syntmp-first-870
                           (syntmp-dobody-866
                             (cdr syntmp-body-867)
                             syntmp-r-868
                             syntmp-w-869))))))))
         (syntmp-source-wrap-147
           (lambda (syntmp-x-871 syntmp-w-872 syntmp-s-873)
             (syntmp-wrap-146
               (if syntmp-s-873
                 (make-annotation syntmp-x-871 syntmp-s-873 #f)
                 syntmp-x-871)
               syntmp-w-872)))
         (syntmp-wrap-146
           (lambda (syntmp-x-874 syntmp-w-875)
             (cond ((and (null? (syntmp-wrap-marks-121 syntmp-w-875))
                         (null? (syntmp-wrap-subst-122 syntmp-w-875)))
                    syntmp-x-874)
                   ((syntmp-syntax-object?-104 syntmp-x-874)
                    (syntmp-make-syntax-object-103
                      (syntmp-syntax-object-expression-105
                        syntmp-x-874)
                      (syntmp-join-wraps-137
                        syntmp-w-875
                        (syntmp-syntax-object-wrap-106 syntmp-x-874))))
                   ((null? syntmp-x-874) syntmp-x-874)
                   (else
                    (syntmp-make-syntax-object-103
                      syntmp-x-874
                      syntmp-w-875)))))
         (syntmp-bound-id-member?-145
           (lambda (syntmp-x-876 syntmp-list-877)
             (and (not (null? syntmp-list-877))
                  (or (syntmp-bound-id=?-142
                        syntmp-x-876
                        (car syntmp-list-877))
                      (syntmp-bound-id-member?-145
                        syntmp-x-876
                        (cdr syntmp-list-877))))))
         (syntmp-distinct-bound-ids?-144
           (lambda (syntmp-ids-878)
             (let syntmp-distinct?-879 ((syntmp-ids-880 syntmp-ids-878))
               (or (null? syntmp-ids-880)
                   (and (not (syntmp-bound-id-member?-145
                               (car syntmp-ids-880)
                               (cdr syntmp-ids-880)))
                        (syntmp-distinct?-879 (cdr syntmp-ids-880)))))))
         (syntmp-valid-bound-ids?-143
           (lambda (syntmp-ids-881)
             (and (let syntmp-all-ids?-882 ((syntmp-ids-883 syntmp-ids-881))
                    (or (null? syntmp-ids-883)
                        (and (syntmp-id?-118 (car syntmp-ids-883))
                             (syntmp-all-ids?-882 (cdr syntmp-ids-883)))))
                  (syntmp-distinct-bound-ids?-144 syntmp-ids-881))))
         (syntmp-bound-id=?-142
           (lambda (syntmp-i-884 syntmp-j-885)
             (if (and (syntmp-syntax-object?-104 syntmp-i-884)
                      (syntmp-syntax-object?-104 syntmp-j-885))
               (and (eq? (let ((syntmp-e-886
                                 (syntmp-syntax-object-expression-105
                                   syntmp-i-884)))
                           (if (syntmp-annotation?-92 syntmp-e-886)
                             (annotation-expression syntmp-e-886)
                             syntmp-e-886))
                         (let ((syntmp-e-887
                                 (syntmp-syntax-object-expression-105
                                   syntmp-j-885)))
                           (if (syntmp-annotation?-92 syntmp-e-887)
                             (annotation-expression syntmp-e-887)
                             syntmp-e-887)))
                    (syntmp-same-marks?-139
                      (syntmp-wrap-marks-121
                        (syntmp-syntax-object-wrap-106 syntmp-i-884))
                      (syntmp-wrap-marks-121
                        (syntmp-syntax-object-wrap-106 syntmp-j-885))))
               (eq? (let ((syntmp-e-888 syntmp-i-884))
                      (if (syntmp-annotation?-92 syntmp-e-888)
                        (annotation-expression syntmp-e-888)
                        syntmp-e-888))
                    (let ((syntmp-e-889 syntmp-j-885))
                      (if (syntmp-annotation?-92 syntmp-e-889)
                        (annotation-expression syntmp-e-889)
                        syntmp-e-889))))))
         (syntmp-free-id=?-141
           (lambda (syntmp-i-890 syntmp-j-891)
             (and (eq? (let ((syntmp-x-892 syntmp-i-890))
                         (let ((syntmp-e-893
                                 (if (syntmp-syntax-object?-104 syntmp-x-892)
                                   (syntmp-syntax-object-expression-105
                                     syntmp-x-892)
                                   syntmp-x-892)))
                           (if (syntmp-annotation?-92 syntmp-e-893)
                             (annotation-expression syntmp-e-893)
                             syntmp-e-893)))
                       (let ((syntmp-x-894 syntmp-j-891))
                         (let ((syntmp-e-895
                                 (if (syntmp-syntax-object?-104 syntmp-x-894)
                                   (syntmp-syntax-object-expression-105
                                     syntmp-x-894)
                                   syntmp-x-894)))
                           (if (syntmp-annotation?-92 syntmp-e-895)
                             (annotation-expression syntmp-e-895)
                             syntmp-e-895))))
                  (eq? (syntmp-id-var-name-140
                         syntmp-i-890
                         '(()))
                       (syntmp-id-var-name-140
                         syntmp-j-891
                         '(()))))))
         (syntmp-id-var-name-140
           (lambda (syntmp-id-896 syntmp-w-897)
             (letrec ((syntmp-search-vector-rib-900
                        (lambda (syntmp-sym-911
                                 syntmp-subst-912
                                 syntmp-marks-913
                                 syntmp-symnames-914
                                 syntmp-ribcage-915)
                          (let ((syntmp-n-916
                                  (vector-length syntmp-symnames-914)))
                            (let syntmp-f-917 ((syntmp-i-918 0))
                              (cond ((syntmp-fx=-90 syntmp-i-918 syntmp-n-916)
                                     (syntmp-search-898
                                       syntmp-sym-911
                                       (cdr syntmp-subst-912)
                                       syntmp-marks-913))
                                    ((and (eq? (vector-ref
                                                 syntmp-symnames-914
                                                 syntmp-i-918)
                                               syntmp-sym-911)
                                          (syntmp-same-marks?-139
                                            syntmp-marks-913
                                            (vector-ref
                                              (syntmp-ribcage-marks-128
                                                syntmp-ribcage-915)
                                              syntmp-i-918)))
                                     (values
                                       (vector-ref
                                         (syntmp-ribcage-labels-129
                                           syntmp-ribcage-915)
                                         syntmp-i-918)
                                       syntmp-marks-913))
                                    (else
                                     (syntmp-f-917
                                       (syntmp-fx+-88 syntmp-i-918 1))))))))
                      (syntmp-search-list-rib-899
                        (lambda (syntmp-sym-919
                                 syntmp-subst-920
                                 syntmp-marks-921
                                 syntmp-symnames-922
                                 syntmp-ribcage-923)
                          (let syntmp-f-924 ((syntmp-symnames-925
                                               syntmp-symnames-922)
                                             (syntmp-i-926 0))
                            (cond ((null? syntmp-symnames-925)
                                   (syntmp-search-898
                                     syntmp-sym-919
                                     (cdr syntmp-subst-920)
                                     syntmp-marks-921))
                                  ((and (eq? (car syntmp-symnames-925)
                                             syntmp-sym-919)
                                        (syntmp-same-marks?-139
                                          syntmp-marks-921
                                          (list-ref
                                            (syntmp-ribcage-marks-128
                                              syntmp-ribcage-923)
                                            syntmp-i-926)))
                                   (values
                                     (list-ref
                                       (syntmp-ribcage-labels-129
                                         syntmp-ribcage-923)
                                       syntmp-i-926)
                                     syntmp-marks-921))
                                  (else
                                   (syntmp-f-924
                                     (cdr syntmp-symnames-925)
                                     (syntmp-fx+-88 syntmp-i-926 1)))))))
                      (syntmp-search-898
                        (lambda (syntmp-sym-927
                                 syntmp-subst-928
                                 syntmp-marks-929)
                          (if (null? syntmp-subst-928)
                            (values #f syntmp-marks-929)
                            (let ((syntmp-fst-930 (car syntmp-subst-928)))
                              (if (eq? syntmp-fst-930 (quote shift))
                                (syntmp-search-898
                                  syntmp-sym-927
                                  (cdr syntmp-subst-928)
                                  (cdr syntmp-marks-929))
                                (let ((syntmp-symnames-931
                                        (syntmp-ribcage-symnames-127
                                          syntmp-fst-930)))
                                  (if (vector? syntmp-symnames-931)
                                    (syntmp-search-vector-rib-900
                                      syntmp-sym-927
                                      syntmp-subst-928
                                      syntmp-marks-929
                                      syntmp-symnames-931
                                      syntmp-fst-930)
                                    (syntmp-search-list-rib-899
                                      syntmp-sym-927
                                      syntmp-subst-928
                                      syntmp-marks-929
                                      syntmp-symnames-931
                                      syntmp-fst-930)))))))))
               (cond ((symbol? syntmp-id-896)
                      (or (call-with-values
                            (lambda ()
                              (syntmp-search-898
                                syntmp-id-896
                                (syntmp-wrap-subst-122 syntmp-w-897)
                                (syntmp-wrap-marks-121 syntmp-w-897)))
                            (lambda (syntmp-x-933 . syntmp-ignore-932)
                              syntmp-x-933))
                          syntmp-id-896))
                     ((syntmp-syntax-object?-104 syntmp-id-896)
                      (let ((syntmp-id-934
                              (let ((syntmp-e-936
                                      (syntmp-syntax-object-expression-105
                                        syntmp-id-896)))
                                (if (syntmp-annotation?-92 syntmp-e-936)
                                  (annotation-expression syntmp-e-936)
                                  syntmp-e-936)))
                            (syntmp-w1-935
                              (syntmp-syntax-object-wrap-106 syntmp-id-896)))
                        (let ((syntmp-marks-937
                                (syntmp-join-marks-138
                                  (syntmp-wrap-marks-121 syntmp-w-897)
                                  (syntmp-wrap-marks-121 syntmp-w1-935))))
                          (call-with-values
                            (lambda ()
                              (syntmp-search-898
                                syntmp-id-934
                                (syntmp-wrap-subst-122 syntmp-w-897)
                                syntmp-marks-937))
                            (lambda (syntmp-new-id-938 syntmp-marks-939)
                              (or syntmp-new-id-938
                                  (call-with-values
                                    (lambda ()
                                      (syntmp-search-898
                                        syntmp-id-934
                                        (syntmp-wrap-subst-122 syntmp-w1-935)
                                        syntmp-marks-939))
                                    (lambda (syntmp-x-941 . syntmp-ignore-940)
                                      syntmp-x-941))
                                  syntmp-id-934))))))
                     ((syntmp-annotation?-92 syntmp-id-896)
                      (let ((syntmp-id-942
                              (let ((syntmp-e-943 syntmp-id-896))
                                (if (syntmp-annotation?-92 syntmp-e-943)
                                  (annotation-expression syntmp-e-943)
                                  syntmp-e-943))))
                        (or (call-with-values
                              (lambda ()
                                (syntmp-search-898
                                  syntmp-id-942
                                  (syntmp-wrap-subst-122 syntmp-w-897)
                                  (syntmp-wrap-marks-121 syntmp-w-897)))
                              (lambda (syntmp-x-945 . syntmp-ignore-944)
                                syntmp-x-945))
                            syntmp-id-942)))
                     (else
                      (syntmp-error-hook-95
                        'id-var-name
                        "invalid id"
                        syntmp-id-896))))))
         (syntmp-same-marks?-139
           (lambda (syntmp-x-946 syntmp-y-947)
             (or (eq? syntmp-x-946 syntmp-y-947)
                 (and (not (null? syntmp-x-946))
                      (not (null? syntmp-y-947))
                      (eq? (car syntmp-x-946) (car syntmp-y-947))
                      (syntmp-same-marks?-139
                        (cdr syntmp-x-946)
                        (cdr syntmp-y-947))))))
         (syntmp-join-marks-138
           (lambda (syntmp-m1-948 syntmp-m2-949)
             (syntmp-smart-append-136
               syntmp-m1-948
               syntmp-m2-949)))
         (syntmp-join-wraps-137
           (lambda (syntmp-w1-950 syntmp-w2-951)
             (let ((syntmp-m1-952
                     (syntmp-wrap-marks-121 syntmp-w1-950))
                   (syntmp-s1-953
                     (syntmp-wrap-subst-122 syntmp-w1-950)))
               (if (null? syntmp-m1-952)
                 (if (null? syntmp-s1-953)
                   syntmp-w2-951
                   (syntmp-make-wrap-120
                     (syntmp-wrap-marks-121 syntmp-w2-951)
                     (syntmp-smart-append-136
                       syntmp-s1-953
                       (syntmp-wrap-subst-122 syntmp-w2-951))))
                 (syntmp-make-wrap-120
                   (syntmp-smart-append-136
                     syntmp-m1-952
                     (syntmp-wrap-marks-121 syntmp-w2-951))
                   (syntmp-smart-append-136
                     syntmp-s1-953
                     (syntmp-wrap-subst-122 syntmp-w2-951)))))))
         (syntmp-smart-append-136
           (lambda (syntmp-m1-954 syntmp-m2-955)
             (if (null? syntmp-m2-955)
               syntmp-m1-954
               (append syntmp-m1-954 syntmp-m2-955))))
         (syntmp-make-binding-wrap-135
           (lambda (syntmp-ids-956 syntmp-labels-957 syntmp-w-958)
             (if (null? syntmp-ids-956)
               syntmp-w-958
               (syntmp-make-wrap-120
                 (syntmp-wrap-marks-121 syntmp-w-958)
                 (cons (let ((syntmp-labelvec-959
                               (list->vector syntmp-labels-957)))
                         (let ((syntmp-n-960
                                 (vector-length syntmp-labelvec-959)))
                           (let ((syntmp-symnamevec-961
                                   (make-vector syntmp-n-960))
                                 (syntmp-marksvec-962
                                   (make-vector syntmp-n-960)))
                             (begin
                               (let syntmp-f-963 ((syntmp-ids-964
                                                    syntmp-ids-956)
                                                  (syntmp-i-965 0))
                                 (if (not (null? syntmp-ids-964))
                                   (call-with-values
                                     (lambda ()
                                       (syntmp-id-sym-name&marks-119
                                         (car syntmp-ids-964)
                                         syntmp-w-958))
                                     (lambda (syntmp-symname-966
                                              syntmp-marks-967)
                                       (begin
                                         (vector-set!
                                           syntmp-symnamevec-961
                                           syntmp-i-965
                                           syntmp-symname-966)
                                         (vector-set!
                                           syntmp-marksvec-962
                                           syntmp-i-965
                                           syntmp-marks-967)
                                         (syntmp-f-963
                                           (cdr syntmp-ids-964)
                                           (syntmp-fx+-88 syntmp-i-965 1)))))))
                               (syntmp-make-ribcage-125
                                 syntmp-symnamevec-961
                                 syntmp-marksvec-962
                                 syntmp-labelvec-959)))))
                       (syntmp-wrap-subst-122 syntmp-w-958))))))
         (syntmp-extend-ribcage!-134
           (lambda (syntmp-ribcage-968
                    syntmp-id-969
                    syntmp-label-970)
             (begin
               (syntmp-set-ribcage-symnames!-130
                 syntmp-ribcage-968
                 (cons (let ((syntmp-e-971
                               (syntmp-syntax-object-expression-105
                                 syntmp-id-969)))
                         (if (syntmp-annotation?-92 syntmp-e-971)
                           (annotation-expression syntmp-e-971)
                           syntmp-e-971))
                       (syntmp-ribcage-symnames-127 syntmp-ribcage-968)))
               (syntmp-set-ribcage-marks!-131
                 syntmp-ribcage-968
                 (cons (syntmp-wrap-marks-121
                         (syntmp-syntax-object-wrap-106 syntmp-id-969))
                       (syntmp-ribcage-marks-128 syntmp-ribcage-968)))
               (syntmp-set-ribcage-labels!-132
                 syntmp-ribcage-968
                 (cons syntmp-label-970
                       (syntmp-ribcage-labels-129 syntmp-ribcage-968))))))
         (syntmp-anti-mark-133
           (lambda (syntmp-w-972)
             (syntmp-make-wrap-120
               (cons #f (syntmp-wrap-marks-121 syntmp-w-972))
               (cons 'shift
                     (syntmp-wrap-subst-122 syntmp-w-972)))))
         (syntmp-set-ribcage-labels!-132
           (lambda (syntmp-x-973 syntmp-update-974)
             (vector-set! syntmp-x-973 3 syntmp-update-974)))
         (syntmp-set-ribcage-marks!-131
           (lambda (syntmp-x-975 syntmp-update-976)
             (vector-set! syntmp-x-975 2 syntmp-update-976)))
         (syntmp-set-ribcage-symnames!-130
           (lambda (syntmp-x-977 syntmp-update-978)
             (vector-set! syntmp-x-977 1 syntmp-update-978)))
         (syntmp-ribcage-labels-129
           (lambda (syntmp-x-979)
             (vector-ref syntmp-x-979 3)))
         (syntmp-ribcage-marks-128
           (lambda (syntmp-x-980)
             (vector-ref syntmp-x-980 2)))
         (syntmp-ribcage-symnames-127
           (lambda (syntmp-x-981)
             (vector-ref syntmp-x-981 1)))
         (syntmp-ribcage?-126
           (lambda (syntmp-x-982)
             (and (vector? syntmp-x-982)
                  (= (vector-length syntmp-x-982) 4)
                  (eq? (vector-ref syntmp-x-982 0) (quote ribcage)))))
         (syntmp-make-ribcage-125
           (lambda (syntmp-symnames-983
                    syntmp-marks-984
                    syntmp-labels-985)
             (vector
               'ribcage
               syntmp-symnames-983
               syntmp-marks-984
               syntmp-labels-985)))
         (syntmp-gen-labels-124
           (lambda (syntmp-ls-986)
             (if (null? syntmp-ls-986)
               '()
               (cons (syntmp-gen-label-123)
                     (syntmp-gen-labels-124 (cdr syntmp-ls-986))))))
         (syntmp-gen-label-123 (lambda () (string #\i)))
         (syntmp-wrap-subst-122 cdr)
         (syntmp-wrap-marks-121 car)
         (syntmp-make-wrap-120 cons)
         (syntmp-id-sym-name&marks-119
           (lambda (syntmp-x-987 syntmp-w-988)
             (if (syntmp-syntax-object?-104 syntmp-x-987)
               (values
                 (let ((syntmp-e-989
                         (syntmp-syntax-object-expression-105
                           syntmp-x-987)))
                   (if (syntmp-annotation?-92 syntmp-e-989)
                     (annotation-expression syntmp-e-989)
                     syntmp-e-989))
                 (syntmp-join-marks-138
                   (syntmp-wrap-marks-121 syntmp-w-988)
                   (syntmp-wrap-marks-121
                     (syntmp-syntax-object-wrap-106 syntmp-x-987))))
               (values
                 (let ((syntmp-e-990 syntmp-x-987))
                   (if (syntmp-annotation?-92 syntmp-e-990)
                     (annotation-expression syntmp-e-990)
                     syntmp-e-990))
                 (syntmp-wrap-marks-121 syntmp-w-988)))))
         (syntmp-id?-118
           (lambda (syntmp-x-991)
             (cond ((symbol? syntmp-x-991) #t)
                   ((syntmp-syntax-object?-104 syntmp-x-991)
                    (symbol?
                      (let ((syntmp-e-992
                              (syntmp-syntax-object-expression-105
                                syntmp-x-991)))
                        (if (syntmp-annotation?-92 syntmp-e-992)
                          (annotation-expression syntmp-e-992)
                          syntmp-e-992))))
                   ((syntmp-annotation?-92 syntmp-x-991)
                    (symbol? (annotation-expression syntmp-x-991)))
                   (else #f))))
         (syntmp-nonsymbol-id?-117
           (lambda (syntmp-x-993)
             (and (syntmp-syntax-object?-104 syntmp-x-993)
                  (symbol?
                    (let ((syntmp-e-994
                            (syntmp-syntax-object-expression-105
                              syntmp-x-993)))
                      (if (syntmp-annotation?-92 syntmp-e-994)
                        (annotation-expression syntmp-e-994)
                        syntmp-e-994))))))
         (syntmp-global-extend-116
           (lambda (syntmp-type-995 syntmp-sym-996 syntmp-val-997)
             (syntmp-put-global-definition-hook-96
               syntmp-sym-996
               (cons syntmp-type-995 syntmp-val-997))))
         (syntmp-lookup-115
           (lambda (syntmp-x-998 syntmp-r-999)
             (cond ((assq syntmp-x-998 syntmp-r-999) => cdr)
                   ((symbol? syntmp-x-998)
                    (or (syntmp-get-global-definition-hook-97
                          syntmp-x-998)
                        '(global)))
                   (else (quote (displaced-lexical))))))
         (syntmp-macros-only-env-114
           (lambda (syntmp-r-1000)
             (if (null? syntmp-r-1000)
               '()
               (let ((syntmp-a-1001 (car syntmp-r-1000)))
                 (if (memq (cadr syntmp-a-1001)
                           '(macro ellipsis))
                   (cons syntmp-a-1001
                         (syntmp-macros-only-env-114 (cdr syntmp-r-1000)))
                   (syntmp-macros-only-env-114 (cdr syntmp-r-1000)))))))
         (syntmp-extend-var-env-113
           (lambda (syntmp-labels-1002
                    syntmp-vars-1003
                    syntmp-r-1004)
             (if (null? syntmp-labels-1002)
               syntmp-r-1004
               (syntmp-extend-var-env-113
                 (cdr syntmp-labels-1002)
                 (cdr syntmp-vars-1003)
                 (cons (cons (car syntmp-labels-1002)
                             (cons (quote lexical) (car syntmp-vars-1003)))
                       syntmp-r-1004)))))
         (syntmp-extend-env-112
           (lambda (syntmp-labels-1005
                    syntmp-bindings-1006
                    syntmp-r-1007)
             (if (null? syntmp-labels-1005)
               syntmp-r-1007
               (syntmp-extend-env-112
                 (cdr syntmp-labels-1005)
                 (cdr syntmp-bindings-1006)
                 (cons (cons (car syntmp-labels-1005)
                             (car syntmp-bindings-1006))
                       syntmp-r-1007)))))
         (syntmp-binding-value-111 cdr)
         (syntmp-binding-type-110 car)
         (syntmp-source-annotation-109
           (lambda (syntmp-x-1008)
             (cond ((syntmp-annotation?-92 syntmp-x-1008)
                    (annotation-source syntmp-x-1008))
                   ((syntmp-syntax-object?-104 syntmp-x-1008)
                    (syntmp-source-annotation-109
                      (syntmp-syntax-object-expression-105
                        syntmp-x-1008)))
                   (else #f))))
         (syntmp-set-syntax-object-wrap!-108
           (lambda (syntmp-x-1009 syntmp-update-1010)
             (vector-set! syntmp-x-1009 2 syntmp-update-1010)))
         (syntmp-set-syntax-object-expression!-107
           (lambda (syntmp-x-1011 syntmp-update-1012)
             (vector-set! syntmp-x-1011 1 syntmp-update-1012)))
         (syntmp-syntax-object-wrap-106
           (lambda (syntmp-x-1013)
             (vector-ref syntmp-x-1013 2)))
         (syntmp-syntax-object-expression-105
           (lambda (syntmp-x-1014)
             (vector-ref syntmp-x-1014 1)))
         (syntmp-syntax-object?-104
           (lambda (syntmp-x-1015)
             (and (vector? syntmp-x-1015)
                  (= (vector-length syntmp-x-1015) 3)
                  (eq? (vector-ref syntmp-x-1015 0)
                       'syntax-object))))
         (syntmp-make-syntax-object-103
           (lambda (syntmp-expression-1016 syntmp-wrap-1017)
             (vector
               'syntax-object
               syntmp-expression-1016
               syntmp-wrap-1017)))
         (syntmp-build-letrec-102
           (lambda (syntmp-src-1018
                    syntmp-vars-1019
                    syntmp-val-exps-1020
                    syntmp-body-exp-1021)
             (if (null? syntmp-vars-1019)
               syntmp-body-exp-1021
               (list 'letrec
                     (map list syntmp-vars-1019 syntmp-val-exps-1020)
                     syntmp-body-exp-1021))))
         (syntmp-build-named-let-101
           (lambda (syntmp-src-1022
                    syntmp-vars-1023
                    syntmp-val-exps-1024
                    syntmp-body-exp-1025)
             (if (null? syntmp-vars-1023)
               syntmp-body-exp-1025
               (list 'let
                     (car syntmp-vars-1023)
                     (map list
                          (cdr syntmp-vars-1023)
                          syntmp-val-exps-1024)
                     syntmp-body-exp-1025))))
         (syntmp-build-let-100
           (lambda (syntmp-src-1026
                    syntmp-vars-1027
                    syntmp-val-exps-1028
                    syntmp-body-exp-1029)
             (if (null? syntmp-vars-1027)
               syntmp-body-exp-1029
               (list 'let
                     (map list syntmp-vars-1027 syntmp-val-exps-1028)
                     syntmp-body-exp-1029))))
         (syntmp-build-sequence-99
           (lambda (syntmp-src-1030 syntmp-exps-1031)
             (if (null? (cdr syntmp-exps-1031))
               (car syntmp-exps-1031)
               (cons (quote begin) syntmp-exps-1031))))
         (syntmp-build-data-98
           (lambda (syntmp-src-1032 syntmp-exp-1033)
             (if (and (self-evaluating? syntmp-exp-1033)
                      (not (vector? syntmp-exp-1033)))
               syntmp-exp-1033
               (list (quote quote) syntmp-exp-1033))))
         (syntmp-get-global-definition-hook-97
           (lambda (syntmp-symbol-1034)
             (getprop
               syntmp-symbol-1034
               '*sc-expander*)))
         (syntmp-put-global-definition-hook-96
           (lambda (syntmp-symbol-1035 syntmp-binding-1036)
             (putprop
               syntmp-symbol-1035
               '*sc-expander*
               syntmp-binding-1036)))
         (syntmp-error-hook-95
           (lambda (syntmp-who-1037
                    syntmp-why-1038
                    syntmp-what-1039)
             (error syntmp-who-1037
                    "~a ~s"
                    syntmp-why-1038
                    syntmp-what-1039)))
         (syntmp-local-eval-hook-94
           (lambda (syntmp-x-1040)
             (eval (list syntmp-noexpand-87 syntmp-x-1040)
                   (interaction-environment))))
         (syntmp-top-level-eval-hook-93
           (lambda (syntmp-x-1041)
             (eval (list syntmp-noexpand-87 syntmp-x-1041)
                   (interaction-environment))))
         (syntmp-annotation?-92
           (lambda (syntmp-x-1042) #f))
         (syntmp-fx<-91 <)
         (syntmp-fx=-90 =)
         (syntmp-fx--89 -)
         (syntmp-fx+-88 +)
         (syntmp-noexpand-87 "noexpand"))
  (begin
    (syntmp-global-extend-116
      'local-syntax
      'letrec-syntax
      #t)
    (syntmp-global-extend-116
      'local-syntax
      'let-syntax
      #f)
    (syntmp-global-extend-116
      'core
      'fluid-let-syntax
      (lambda (syntmp-e-1043
               syntmp-r-1044
               syntmp-w-1045
               syntmp-s-1046)
        ((lambda (syntmp-tmp-1047)
           ((lambda (syntmp-tmp-1048)
              (if (if syntmp-tmp-1048
                    (apply (lambda (syntmp-_-1049
                                    syntmp-var-1050
                                    syntmp-val-1051
                                    syntmp-e1-1052
                                    syntmp-e2-1053)
                             (syntmp-valid-bound-ids?-143 syntmp-var-1050))
                           syntmp-tmp-1048)
                    #f)
                (apply (lambda (syntmp-_-1055
                                syntmp-var-1056
                                syntmp-val-1057
                                syntmp-e1-1058
                                syntmp-e2-1059)
                         (let ((syntmp-names-1060
                                 (map (lambda (syntmp-x-1061)
                                        (syntmp-id-var-name-140
                                          syntmp-x-1061
                                          syntmp-w-1045))
                                      syntmp-var-1056)))
                           (begin
                             (for-each
                               (lambda (syntmp-id-1063 syntmp-n-1064)
                                 (let ((syntmp-t-1065
                                         (syntmp-binding-type-110
                                           (syntmp-lookup-115
                                             syntmp-n-1064
                                             syntmp-r-1044))))
                                   (if (memv syntmp-t-1065
                                             '(displaced-lexical))
                                     (syntax-error
                                       (syntmp-source-wrap-147
                                         syntmp-id-1063
                                         syntmp-w-1045
                                         syntmp-s-1046)
                                       "identifier out of context"))))
                               syntmp-var-1056
                               syntmp-names-1060)
                             (syntmp-chi-body-158
                               (cons syntmp-e1-1058 syntmp-e2-1059)
                               (syntmp-source-wrap-147
                                 syntmp-e-1043
                                 syntmp-w-1045
                                 syntmp-s-1046)
                               (syntmp-extend-env-112
                                 syntmp-names-1060
                                 (let ((syntmp-trans-r-1068
                                         (syntmp-macros-only-env-114
                                           syntmp-r-1044)))
                                   (map (lambda (syntmp-x-1069)
                                          (cons 'macro
                                                (syntmp-eval-local-transformer-161
                                                  (syntmp-chi-154
                                                    syntmp-x-1069
                                                    syntmp-trans-r-1068
                                                    syntmp-w-1045))))
                                        syntmp-val-1057))
                                 syntmp-r-1044)
                               syntmp-w-1045))))
                       syntmp-tmp-1048)
                ((lambda (syntmp-_-1071)
                   (syntax-error
                     (syntmp-source-wrap-147
                       syntmp-e-1043
                       syntmp-w-1045
                       syntmp-s-1046)))
                 syntmp-tmp-1047)))
            (syntax-dispatch
              syntmp-tmp-1047
              '(any #(each (any any)) any . each-any))))
         syntmp-e-1043)))
    (syntmp-global-extend-116
      'core
      'quote
      (lambda (syntmp-e-1072
               syntmp-r-1073
               syntmp-w-1074
               syntmp-s-1075)
        ((lambda (syntmp-tmp-1076)
           ((lambda (syntmp-tmp-1077)
              (if syntmp-tmp-1077
                (apply (lambda (syntmp-_-1078 syntmp-e-1079)
                         (syntmp-build-data-98
                           syntmp-s-1075
                           (syntmp-strip-165 syntmp-e-1079 syntmp-w-1074)))
                       syntmp-tmp-1077)
                ((lambda (syntmp-_-1080)
                   (syntax-error
                     (syntmp-source-wrap-147
                       syntmp-e-1072
                       syntmp-w-1074
                       syntmp-s-1075)))
                 syntmp-tmp-1076)))
            (syntax-dispatch
              syntmp-tmp-1076
              '(any any))))
         syntmp-e-1072)))
    (syntmp-global-extend-116
      'core
      'syntax
      (letrec ((syntmp-regen-1088
                 (lambda (syntmp-x-1089)
                   (let ((syntmp-t-1090 (car syntmp-x-1089)))
                     (if (memv syntmp-t-1090 (quote (ref)))
                       (cadr syntmp-x-1089)
                       (if (memv syntmp-t-1090 (quote (primitive)))
                         (cadr syntmp-x-1089)
                         (if (memv syntmp-t-1090 (quote (quote)))
                           (syntmp-build-data-98 #f (cadr syntmp-x-1089))
                           (if (memv syntmp-t-1090 (quote (lambda)))
                             (list 'lambda
                                   (cadr syntmp-x-1089)
                                   (syntmp-regen-1088 (caddr syntmp-x-1089)))
                             (if (memv syntmp-t-1090 (quote (map)))
                               (let ((syntmp-ls-1091
                                       (map syntmp-regen-1088
                                            (cdr syntmp-x-1089))))
                                 (cons (if (syntmp-fx=-90
                                             (length syntmp-ls-1091)
                                             2)
                                         'map
                                         'map)
                                       syntmp-ls-1091))
                               (cons (car syntmp-x-1089)
                                     (map syntmp-regen-1088
                                          (cdr syntmp-x-1089)))))))))))
               (syntmp-gen-vector-1087
                 (lambda (syntmp-x-1092)
                   (cond ((eq? (car syntmp-x-1092) (quote list))
                          (cons (quote vector) (cdr syntmp-x-1092)))
                         ((eq? (car syntmp-x-1092) (quote quote))
                          (list 'quote
                                (list->vector (cadr syntmp-x-1092))))
                         (else (list (quote list->vector) syntmp-x-1092)))))
               (syntmp-gen-append-1086
                 (lambda (syntmp-x-1093 syntmp-y-1094)
                   (if (equal? syntmp-y-1094 (quote (quote ())))
                     syntmp-x-1093
                     (list (quote append) syntmp-x-1093 syntmp-y-1094))))
               (syntmp-gen-cons-1085
                 (lambda (syntmp-x-1095 syntmp-y-1096)
                   (let ((syntmp-t-1097 (car syntmp-y-1096)))
                     (if (memv syntmp-t-1097 (quote (quote)))
                       (if (eq? (car syntmp-x-1095) (quote quote))
                         (list 'quote
                               (cons (cadr syntmp-x-1095)
                                     (cadr syntmp-y-1096)))
                         (if (eq? (cadr syntmp-y-1096) (quote ()))
                           (list (quote list) syntmp-x-1095)
                           (list (quote cons) syntmp-x-1095 syntmp-y-1096)))
                       (if (memv syntmp-t-1097 (quote (list)))
                         (cons 'list
                               (cons syntmp-x-1095 (cdr syntmp-y-1096)))
                         (list (quote cons) syntmp-x-1095 syntmp-y-1096))))))
               (syntmp-gen-map-1084
                 (lambda (syntmp-e-1098 syntmp-map-env-1099)
                   (let ((syntmp-formals-1100
                           (map cdr syntmp-map-env-1099))
                         (syntmp-actuals-1101
                           (map (lambda (syntmp-x-1102)
                                  (list (quote ref) (car syntmp-x-1102)))
                                syntmp-map-env-1099)))
                     (cond ((eq? (car syntmp-e-1098) (quote ref))
                            (car syntmp-actuals-1101))
                           ((andmap
                              (lambda (syntmp-x-1103)
                                (and (eq? (car syntmp-x-1103) (quote ref))
                                     (memq (cadr syntmp-x-1103)
                                           syntmp-formals-1100)))
                              (cdr syntmp-e-1098))
                            (cons 'map
                                  (cons (list 'primitive
                                              (car syntmp-e-1098))
                                        (map (let ((syntmp-r-1104
                                                     (map cons
                                                          syntmp-formals-1100
                                                          syntmp-actuals-1101)))
                                               (lambda (syntmp-x-1105)
                                                 (cdr (assq (cadr syntmp-x-1105)
                                                            syntmp-r-1104))))
                                             (cdr syntmp-e-1098)))))
                           (else
                            (cons 'map
                                  (cons (list 'lambda
                                              syntmp-formals-1100
                                              syntmp-e-1098)
                                        syntmp-actuals-1101)))))))
               (syntmp-gen-mappend-1083
                 (lambda (syntmp-e-1106 syntmp-map-env-1107)
                   (list 'apply
                         '(primitive append)
                         (syntmp-gen-map-1084
                           syntmp-e-1106
                           syntmp-map-env-1107))))
               (syntmp-gen-ref-1082
                 (lambda (syntmp-src-1108
                          syntmp-var-1109
                          syntmp-level-1110
                          syntmp-maps-1111)
                   (if (syntmp-fx=-90 syntmp-level-1110 0)
                     (values syntmp-var-1109 syntmp-maps-1111)
                     (if (null? syntmp-maps-1111)
                       (syntax-error
                         syntmp-src-1108
                         "missing ellipsis in syntax form")
                       (call-with-values
                         (lambda ()
                           (syntmp-gen-ref-1082
                             syntmp-src-1108
                             syntmp-var-1109
                             (syntmp-fx--89 syntmp-level-1110 1)
                             (cdr syntmp-maps-1111)))
                         (lambda (syntmp-outer-var-1112 syntmp-outer-maps-1113)
                           (let ((syntmp-b-1114
                                   (assq syntmp-outer-var-1112
                                         (car syntmp-maps-1111))))
                             (if syntmp-b-1114
                               (values (cdr syntmp-b-1114) syntmp-maps-1111)
                               (let ((syntmp-inner-var-1115
                                       (syntmp-gen-var-166 (quote tmp))))
                                 (values
                                   syntmp-inner-var-1115
                                   (cons (cons (cons syntmp-outer-var-1112
                                                     syntmp-inner-var-1115)
                                               (car syntmp-maps-1111))
                                         syntmp-outer-maps-1113)))))))))))
               (syntmp-gen-syntax-1081
                 (lambda (syntmp-src-1116
                          syntmp-e-1117
                          syntmp-r-1118
                          syntmp-maps-1119
                          syntmp-ellipsis?-1120)
                   (if (syntmp-id?-118 syntmp-e-1117)
                     (let ((syntmp-label-1121
                             (syntmp-id-var-name-140
                               syntmp-e-1117
                               '(()))))
                       (let ((syntmp-b-1122
                               (syntmp-lookup-115
                                 syntmp-label-1121
                                 syntmp-r-1118)))
                         (if (eq? (syntmp-binding-type-110 syntmp-b-1122)
                                  'syntax)
                           (call-with-values
                             (lambda ()
                               (let ((syntmp-var.lev-1123
                                       (syntmp-binding-value-111
                                         syntmp-b-1122)))
                                 (syntmp-gen-ref-1082
                                   syntmp-src-1116
                                   (car syntmp-var.lev-1123)
                                   (cdr syntmp-var.lev-1123)
                                   syntmp-maps-1119)))
                             (lambda (syntmp-var-1124 syntmp-maps-1125)
                               (values
                                 (list (quote ref) syntmp-var-1124)
                                 syntmp-maps-1125)))
                           (if (syntmp-ellipsis?-1120
                                 syntmp-e-1117
                                 syntmp-r-1118)
                             (syntax-error
                               syntmp-src-1116
                               "misplaced ellipsis in syntax form")
                             (values
                               (list (quote quote) syntmp-e-1117)
                               syntmp-maps-1119)))))
                     ((lambda (syntmp-tmp-1126)
                        ((lambda (syntmp-tmp-1127)
                           (if (if syntmp-tmp-1127
                                 (apply (lambda (syntmp-dots-1128
                                                 syntmp-e-1129)
                                          (syntmp-ellipsis?-1120
                                            syntmp-dots-1128
                                            syntmp-r-1118))
                                        syntmp-tmp-1127)
                                 #f)
                             (apply (lambda (syntmp-dots-1130 syntmp-e-1131)
                                      (syntmp-gen-syntax-1081
                                        syntmp-src-1116
                                        syntmp-e-1131
                                        syntmp-r-1118
                                        syntmp-maps-1119
                                        (lambda (syntmp-e-1132 syntmp-r-1133)
                                          #f)))
                                    syntmp-tmp-1127)
                             ((lambda (syntmp-tmp-1134)
                                (if (if syntmp-tmp-1134
                                      (apply (lambda (syntmp-x-1135
                                                      syntmp-dots-1136
                                                      syntmp-y-1137)
                                               (syntmp-ellipsis?-1120
                                                 syntmp-dots-1136
                                                 syntmp-r-1118))
                                             syntmp-tmp-1134)
                                      #f)
                                  (apply (lambda (syntmp-x-1138
                                                  syntmp-dots-1139
                                                  syntmp-y-1140)
                                           (let syntmp-f-1141 ((syntmp-y-1142
                                                                 syntmp-y-1140)
                                                               (syntmp-k-1143
                                                                 (lambda (syntmp-maps-1144)
                                                                   (call-with-values
                                                                     (lambda ()
                                                                       (syntmp-gen-syntax-1081
                                                                         syntmp-src-1116
                                                                         syntmp-x-1138
                                                                         syntmp-r-1118
                                                                         (cons '()
                                                                               syntmp-maps-1144)
                                                                         syntmp-ellipsis?-1120))
                                                                     (lambda (syntmp-x-1145
                                                                              syntmp-maps-1146)
                                                                       (if (null? (car syntmp-maps-1146))
                                                                         (syntax-error
                                                                           syntmp-src-1116
                                                                           "extra ellipsis in syntax form")
                                                                         (values
                                                                           (syntmp-gen-map-1084
                                                                             syntmp-x-1145
                                                                             (car syntmp-maps-1146))
                                                                           (cdr syntmp-maps-1146))))))))
                                             ((lambda (syntmp-tmp-1147)
                                                ((lambda (syntmp-tmp-1148)
                                                   (if (if syntmp-tmp-1148
                                                         (apply (lambda (syntmp-dots-1149
                                                                         syntmp-y-1150)
                                                                  (syntmp-ellipsis?-1120
                                                                    syntmp-dots-1149
                                                                    syntmp-r-1118))
                                                                syntmp-tmp-1148)
                                                         #f)
                                                     (apply (lambda (syntmp-dots-1151
                                                                     syntmp-y-1152)
                                                              (syntmp-f-1141
                                                                syntmp-y-1152
                                                                (lambda (syntmp-maps-1153)
                                                                  (call-with-values
                                                                    (lambda ()
                                                                      (syntmp-k-1143
                                                                        (cons '()
                                                                              syntmp-maps-1153)))
                                                                    (lambda (syntmp-x-1154
                                                                             syntmp-maps-1155)
                                                                      (if (null? (car syntmp-maps-1155))
                                                                        (syntax-error
                                                                          syntmp-src-1116
                                                                          "extra ellipsis in syntax form")
                                                                        (values
                                                                          (syntmp-gen-mappend-1083
                                                                            syntmp-x-1154
                                                                            (car syntmp-maps-1155))
                                                                          (cdr syntmp-maps-1155))))))))
                                                            syntmp-tmp-1148)
                                                     ((lambda (syntmp-_-1156)
                                                        (call-with-values
                                                          (lambda ()
                                                            (syntmp-gen-syntax-1081
                                                              syntmp-src-1116
                                                              syntmp-y-1142
                                                              syntmp-r-1118
                                                              syntmp-maps-1119
                                                              syntmp-ellipsis?-1120))
                                                          (lambda (syntmp-y-1157
                                                                   syntmp-maps-1158)
                                                            (call-with-values
                                                              (lambda ()
                                                                (syntmp-k-1143
                                                                  syntmp-maps-1158))
                                                              (lambda (syntmp-x-1159
                                                                       syntmp-maps-1160)
                                                                (values
                                                                  (syntmp-gen-append-1086
                                                                    syntmp-x-1159
                                                                    syntmp-y-1157)
                                                                  syntmp-maps-1160))))))
                                                      syntmp-tmp-1147)))
                                                 (syntax-dispatch
                                                   syntmp-tmp-1147
                                                   '(any . any))))
                                              syntmp-y-1142)))
                                         syntmp-tmp-1134)
                                  ((lambda (syntmp-tmp-1161)
                                     (if syntmp-tmp-1161
                                       (apply (lambda (syntmp-x-1162
                                                       syntmp-y-1163)
                                                (call-with-values
                                                  (lambda ()
                                                    (syntmp-gen-syntax-1081
                                                      syntmp-src-1116
                                                      syntmp-x-1162
                                                      syntmp-r-1118
                                                      syntmp-maps-1119
                                                      syntmp-ellipsis?-1120))
                                                  (lambda (syntmp-x-1164
                                                           syntmp-maps-1165)
                                                    (call-with-values
                                                      (lambda ()
                                                        (syntmp-gen-syntax-1081
                                                          syntmp-src-1116
                                                          syntmp-y-1163
                                                          syntmp-r-1118
                                                          syntmp-maps-1165
                                                          syntmp-ellipsis?-1120))
                                                      (lambda (syntmp-y-1166
                                                               syntmp-maps-1167)
                                                        (values
                                                          (syntmp-gen-cons-1085
                                                            syntmp-x-1164
                                                            syntmp-y-1166)
                                                          syntmp-maps-1167))))))
                                              syntmp-tmp-1161)
                                       ((lambda (syntmp-tmp-1168)
                                          (if syntmp-tmp-1168
                                            (apply (lambda (syntmp-e1-1169
                                                            syntmp-e2-1170)
                                                     (call-with-values
                                                       (lambda ()
                                                         (syntmp-gen-syntax-1081
                                                           syntmp-src-1116
                                                           (cons syntmp-e1-1169
                                                                 syntmp-e2-1170)
                                                           syntmp-r-1118
                                                           syntmp-maps-1119
                                                           syntmp-ellipsis?-1120))
                                                       (lambda (syntmp-e-1172
                                                                syntmp-maps-1173)
                                                         (values
                                                           (syntmp-gen-vector-1087
                                                             syntmp-e-1172)
                                                           syntmp-maps-1173))))
                                                   syntmp-tmp-1168)
                                            ((lambda (syntmp-_-1174)
                                               (values
                                                 (list 'quote
                                                       syntmp-e-1117)
                                                 syntmp-maps-1119))
                                             syntmp-tmp-1126)))
                                        (syntax-dispatch
                                          syntmp-tmp-1126
                                          '#(vector (any . each-any))))))
                                   (syntax-dispatch
                                     syntmp-tmp-1126
                                     '(any . any)))))
                              (syntax-dispatch
                                syntmp-tmp-1126
                                '(any any . any)))))
                         (syntax-dispatch
                           syntmp-tmp-1126
                           '(any any))))
                      syntmp-e-1117)))))
        (lambda (syntmp-e-1175
                 syntmp-r-1176
                 syntmp-w-1177
                 syntmp-s-1178)
          (let ((syntmp-e-1179
                  (syntmp-source-wrap-147
                    syntmp-e-1175
                    syntmp-w-1177
                    syntmp-s-1178)))
            ((lambda (syntmp-tmp-1180)
               ((lambda (syntmp-tmp-1181)
                  (if syntmp-tmp-1181
                    (apply (lambda (syntmp-_-1182 syntmp-x-1183)
                             (call-with-values
                               (lambda ()
                                 (syntmp-gen-syntax-1081
                                   syntmp-e-1179
                                   syntmp-x-1183
                                   syntmp-r-1176
                                   '()
                                   syntmp-ellipsis?-163))
                               (lambda (syntmp-e-1184 syntmp-maps-1185)
                                 (syntmp-regen-1088 syntmp-e-1184))))
                           syntmp-tmp-1181)
                    ((lambda (syntmp-_-1186)
                       (syntax-error syntmp-e-1179))
                     syntmp-tmp-1180)))
                (syntax-dispatch
                  syntmp-tmp-1180
                  '(any any))))
             syntmp-e-1179)))))
    (syntmp-global-extend-116
      'core
      'lambda
      (lambda (syntmp-e-1187
               syntmp-r-1188
               syntmp-w-1189
               syntmp-s-1190)
        ((lambda (syntmp-tmp-1191)
           ((lambda (syntmp-tmp-1192)
              (if syntmp-tmp-1192
                (apply (lambda (syntmp-_-1193 syntmp-c-1194)
                         (syntmp-chi-lambda-clause-159
                           (syntmp-source-wrap-147
                             syntmp-e-1187
                             syntmp-w-1189
                             syntmp-s-1190)
                           syntmp-c-1194
                           syntmp-r-1188
                           syntmp-w-1189
                           (lambda (syntmp-vars-1195 syntmp-body-1196)
                             (list 'lambda
                                   syntmp-vars-1195
                                   syntmp-body-1196))))
                       syntmp-tmp-1192)
                (syntax-error syntmp-tmp-1191)))
            (syntax-dispatch
              syntmp-tmp-1191
              '(any . any))))
         syntmp-e-1187)))
    (syntmp-global-extend-116
      'core
      'with-ellipsis
      (lambda (syntmp-e-1197
               syntmp-r-1198
               syntmp-w-1199
               syntmp-s-1200)
        (let ((syntmp-tmp-1201 syntmp-e-1197))
          (let ((syntmp-tmp-1202
                  (syntax-dispatch
                    syntmp-tmp-1201
                    '(_ any any . each-any))))
            (if (and syntmp-tmp-1202
                     (apply (lambda (syntmp-dots-1203
                                     syntmp-e1-1204
                                     syntmp-e2-1205)
                              (syntmp-id?-118 syntmp-dots-1203))
                            syntmp-tmp-1202))
              (apply (lambda (syntmp-dots-1206 syntmp-e1-1207 syntmp-e2-1208)
                       (let ((syntmp-id-1209
                               (if (symbol? syntmp-dots-1206)
                                 '$sc-ellipsis
                                 (syntmp-make-syntax-object-103
                                   '$sc-ellipsis
                                   (syntmp-syntax-object-wrap-106
                                     syntmp-dots-1206)))))
                         (let ((syntmp-ids-1210 (list syntmp-id-1209))
                               (syntmp-labels-1211
                                 (list (syntmp-gen-label-123)))
                               (syntmp-bindings-1212
                                 (list (cons 'ellipsis
                                             (syntmp-source-wrap-147
                                               syntmp-dots-1206
                                               syntmp-w-1199
                                               syntmp-s-1200)))))
                           (let ((syntmp-nw-1213
                                   (syntmp-make-binding-wrap-135
                                     syntmp-ids-1210
                                     syntmp-labels-1211
                                     syntmp-w-1199))
                                 (syntmp-nr-1214
                                   (syntmp-extend-env-112
                                     syntmp-labels-1211
                                     syntmp-bindings-1212
                                     syntmp-r-1198)))
                             (syntmp-chi-body-158
                               (cons syntmp-e1-1207 syntmp-e2-1208)
                               (syntmp-source-wrap-147
                                 syntmp-e-1197
                                 syntmp-nw-1213
                                 syntmp-s-1200)
                               syntmp-nr-1214
                               syntmp-nw-1213)))))
                     syntmp-tmp-1202)
              (syntax-error (quote with-ellipsis) "bad syntax"))))))
    (syntmp-global-extend-116
      'core
      'let
      (letrec ((syntmp-chi-let-1215
                 (lambda (syntmp-e-1216
                          syntmp-r-1217
                          syntmp-w-1218
                          syntmp-s-1219
                          syntmp-constructor-1220
                          syntmp-ids-1221
                          syntmp-vals-1222
                          syntmp-exps-1223)
                   (if (not (syntmp-valid-bound-ids?-143 syntmp-ids-1221))
                     (syntax-error
                       syntmp-e-1216
                       "duplicate bound variable in")
                     (let ((syntmp-labels-1224
                             (syntmp-gen-labels-124 syntmp-ids-1221))
                           (syntmp-new-vars-1225
                             (map syntmp-gen-var-166 syntmp-ids-1221)))
                       (let ((syntmp-nw-1226
                               (syntmp-make-binding-wrap-135
                                 syntmp-ids-1221
                                 syntmp-labels-1224
                                 syntmp-w-1218))
                             (syntmp-nr-1227
                               (syntmp-extend-var-env-113
                                 syntmp-labels-1224
                                 syntmp-new-vars-1225
                                 syntmp-r-1217)))
                         (syntmp-constructor-1220
                           syntmp-s-1219
                           syntmp-new-vars-1225
                           (map (lambda (syntmp-x-1228)
                                  (syntmp-chi-154
                                    syntmp-x-1228
                                    syntmp-r-1217
                                    syntmp-w-1218))
                                syntmp-vals-1222)
                           (syntmp-chi-body-158
                             syntmp-exps-1223
                             (syntmp-source-wrap-147
                               syntmp-e-1216
                               syntmp-nw-1226
                               syntmp-s-1219)
                             syntmp-nr-1227
                             syntmp-nw-1226))))))))
        (lambda (syntmp-e-1229
                 syntmp-r-1230
                 syntmp-w-1231
                 syntmp-s-1232)
          ((lambda (syntmp-tmp-1233)
             ((lambda (syntmp-tmp-1234)
                (if syntmp-tmp-1234
                  (apply (lambda (syntmp-_-1235
                                  syntmp-id-1236
                                  syntmp-val-1237
                                  syntmp-e1-1238
                                  syntmp-e2-1239)
                           (syntmp-chi-let-1215
                             syntmp-e-1229
                             syntmp-r-1230
                             syntmp-w-1231
                             syntmp-s-1232
                             syntmp-build-let-100
                             syntmp-id-1236
                             syntmp-val-1237
                             (cons syntmp-e1-1238 syntmp-e2-1239)))
                         syntmp-tmp-1234)
                  ((lambda (syntmp-tmp-1243)
                     (if (if syntmp-tmp-1243
                           (apply (lambda (syntmp-_-1244
                                           syntmp-f-1245
                                           syntmp-id-1246
                                           syntmp-val-1247
                                           syntmp-e1-1248
                                           syntmp-e2-1249)
                                    (syntmp-id?-118 syntmp-f-1245))
                                  syntmp-tmp-1243)
                           #f)
                       (apply (lambda (syntmp-_-1250
                                       syntmp-f-1251
                                       syntmp-id-1252
                                       syntmp-val-1253
                                       syntmp-e1-1254
                                       syntmp-e2-1255)
                                (syntmp-chi-let-1215
                                  syntmp-e-1229
                                  syntmp-r-1230
                                  syntmp-w-1231
                                  syntmp-s-1232
                                  syntmp-build-named-let-101
                                  (cons syntmp-f-1251 syntmp-id-1252)
                                  syntmp-val-1253
                                  (cons syntmp-e1-1254 syntmp-e2-1255)))
                              syntmp-tmp-1243)
                       ((lambda (syntmp-_-1259)
                          (syntax-error
                            (syntmp-source-wrap-147
                              syntmp-e-1229
                              syntmp-w-1231
                              syntmp-s-1232)))
                        syntmp-tmp-1233)))
                   (syntax-dispatch
                     syntmp-tmp-1233
                     '(any any #(each (any any)) any . each-any)))))
              (syntax-dispatch
                syntmp-tmp-1233
                '(any #(each (any any)) any . each-any))))
           syntmp-e-1229))))
    (syntmp-global-extend-116
      'core
      'letrec
      (lambda (syntmp-e-1260
               syntmp-r-1261
               syntmp-w-1262
               syntmp-s-1263)
        ((lambda (syntmp-tmp-1264)
           ((lambda (syntmp-tmp-1265)
              (if syntmp-tmp-1265
                (apply (lambda (syntmp-_-1266
                                syntmp-id-1267
                                syntmp-val-1268
                                syntmp-e1-1269
                                syntmp-e2-1270)
                         (let ((syntmp-ids-1271 syntmp-id-1267))
                           (if (not (syntmp-valid-bound-ids?-143
                                      syntmp-ids-1271))
                             (syntax-error
                               syntmp-e-1260
                               "duplicate bound variable in")
                             (let ((syntmp-labels-1273
                                     (syntmp-gen-labels-124 syntmp-ids-1271))
                                   (syntmp-new-vars-1274
                                     (map syntmp-gen-var-166 syntmp-ids-1271)))
                               (let ((syntmp-w-1275
                                       (syntmp-make-binding-wrap-135
                                         syntmp-ids-1271
                                         syntmp-labels-1273
                                         syntmp-w-1262))
                                     (syntmp-r-1276
                                       (syntmp-extend-var-env-113
                                         syntmp-labels-1273
                                         syntmp-new-vars-1274
                                         syntmp-r-1261)))
                                 (syntmp-build-letrec-102
                                   syntmp-s-1263
                                   syntmp-new-vars-1274
                                   (map (lambda (syntmp-x-1277)
                                          (syntmp-chi-154
                                            syntmp-x-1277
                                            syntmp-r-1276
                                            syntmp-w-1275))
                                        syntmp-val-1268)
                                   (syntmp-chi-body-158
                                     (cons syntmp-e1-1269 syntmp-e2-1270)
                                     (syntmp-source-wrap-147
                                       syntmp-e-1260
                                       syntmp-w-1275
                                       syntmp-s-1263)
                                     syntmp-r-1276
                                     syntmp-w-1275)))))))
                       syntmp-tmp-1265)
                ((lambda (syntmp-_-1280)
                   (syntax-error
                     (syntmp-source-wrap-147
                       syntmp-e-1260
                       syntmp-w-1262
                       syntmp-s-1263)))
                 syntmp-tmp-1264)))
            (syntax-dispatch
              syntmp-tmp-1264
              '(any #(each (any any)) any . each-any))))
         syntmp-e-1260)))
    (syntmp-global-extend-116
      'core
      'set!
      (lambda (syntmp-e-1281
               syntmp-r-1282
               syntmp-w-1283
               syntmp-s-1284)
        ((lambda (syntmp-tmp-1285)
           ((lambda (syntmp-tmp-1286)
              (if (if syntmp-tmp-1286
                    (apply (lambda (syntmp-_-1287
                                    syntmp-id-1288
                                    syntmp-val-1289)
                             (syntmp-id?-118 syntmp-id-1288))
                           syntmp-tmp-1286)
                    #f)
                (apply (lambda (syntmp-_-1290 syntmp-id-1291 syntmp-val-1292)
                         (let ((syntmp-val-1293
                                 (syntmp-chi-154
                                   syntmp-val-1292
                                   syntmp-r-1282
                                   syntmp-w-1283))
                               (syntmp-n-1294
                                 (syntmp-id-var-name-140
                                   syntmp-id-1291
                                   syntmp-w-1283)))
                           (let ((syntmp-b-1295
                                   (syntmp-lookup-115
                                     syntmp-n-1294
                                     syntmp-r-1282)))
                             (let ((syntmp-t-1296
                                     (syntmp-binding-type-110 syntmp-b-1295)))
                               (if (memv syntmp-t-1296 (quote (lexical)))
                                 (list 'set!
                                       (syntmp-binding-value-111 syntmp-b-1295)
                                       syntmp-val-1293)
                                 (if (memv syntmp-t-1296 (quote (global)))
                                   (list 'set!
                                         syntmp-n-1294
                                         syntmp-val-1293)
                                   (if (memv syntmp-t-1296
                                             '(displaced-lexical))
                                     (syntax-error
                                       (syntmp-wrap-146
                                         syntmp-id-1291
                                         syntmp-w-1283)
                                       "identifier out of context")
                                     (syntax-error
                                       (syntmp-source-wrap-147
                                         syntmp-e-1281
                                         syntmp-w-1283
                                         syntmp-s-1284)))))))))
                       syntmp-tmp-1286)
                ((lambda (syntmp-tmp-1297)
                   (if syntmp-tmp-1297
                     (apply (lambda (syntmp-_-1298
                                     syntmp-getter-1299
                                     syntmp-arg-1300
                                     syntmp-val-1301)
                              (cons (syntmp-chi-154
                                      (list '#(syntax-object
                                               setter
                                               ((top)
                                                #(ribcage
                                                  #(_ getter arg val)
                                                  #((top) (top) (top) (top))
                                                  #("i" "i" "i" "i"))
                                                #(ribcage () () ())
                                                #(ribcage
                                                  #(e r w s)
                                                  #((top) (top) (top) (top))
                                                  #("i" "i" "i" "i"))
                                                #(ribcage
                                                  (lambda-var-list
                                                    gen-var
                                                    strip
                                                    strip-annotation
                                                    ellipsis?
                                                    chi-void
                                                    eval-local-transformer
                                                    chi-local-syntax
                                                    chi-lambda-clause
                                                    chi-body
                                                    chi-macro
                                                    chi-application
                                                    chi-expr
                                                    chi
                                                    chi-top
                                                    syntax-type
                                                    chi-when-list
                                                    chi-install-global
                                                    chi-top-sequence
                                                    chi-sequence
                                                    source-wrap
                                                    wrap
                                                    bound-id-member?
                                                    distinct-bound-ids?
                                                    valid-bound-ids?
                                                    bound-id=?
                                                    free-id=?
                                                    id-var-name
                                                    same-marks?
                                                    join-marks
                                                    join-wraps
                                                    smart-append
                                                    make-binding-wrap
                                                    extend-ribcage!
                                                    make-empty-ribcage
                                                    new-mark
                                                    anti-mark
                                                    the-anti-mark
                                                    top-marked?
                                                    top-wrap
                                                    empty-wrap
                                                    set-ribcage-labels!
                                                    set-ribcage-marks!
                                                    set-ribcage-symnames!
                                                    ribcage-labels
                                                    ribcage-marks
                                                    ribcage-symnames
                                                    ribcage?
                                                    make-ribcage
                                                    gen-labels
                                                    gen-label
                                                    make-rename
                                                    rename-marks
                                                    rename-new
                                                    rename-old
                                                    subst-rename?
                                                    wrap-subst
                                                    wrap-marks
                                                    make-wrap
                                                    id-sym-name&marks
                                                    id-sym-name
                                                    id?
                                                    nonsymbol-id?
                                                    global-extend
                                                    lookup
                                                    macros-only-env
                                                    extend-var-env
                                                    extend-env
                                                    null-env
                                                    binding-value
                                                    binding-type
                                                    make-binding
                                                    arg-check
                                                    source-annotation
                                                    no-source
                                                    unannotate
                                                    set-syntax-object-wrap!
                                                    set-syntax-object-expression!
                                                    syntax-object-wrap
                                                    syntax-object-expression
                                                    syntax-object?
                                                    make-syntax-object
                                                    build-lexical-var
                                                    build-letrec
                                                    build-named-let
                                                    build-let
                                                    build-sequence
                                                    build-data
                                                    build-primref
                                                    build-lambda
                                                    build-global-definition
                                                    build-global-assignment
                                                    build-global-reference
                                                    build-lexical-assignment
                                                    build-lexical-reference
                                                    build-conditional
                                                    build-application
                                                    get-global-definition-hook
                                                    put-global-definition-hook
                                                    gensym-hook
                                                    error-hook
                                                    local-eval-hook
                                                    top-level-eval-hook
                                                    annotation?
                                                    fx<
                                                    fx=
                                                    fx-
                                                    fx+
                                                    noexpand)
                                                  ((top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top))
                                                  ("i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"
                                                   "i"))
                                                #(ribcage
                                                  (define-structure)
                                                  ((top))
                                                  ("i"))))
                                            syntmp-getter-1299)
                                      syntmp-r-1282
                                      syntmp-w-1283)
                                    (map (lambda (syntmp-e-1302)
                                           (syntmp-chi-154
                                             syntmp-e-1302
                                             syntmp-r-1282
                                             syntmp-w-1283))
                                         (append
                                           syntmp-arg-1300
                                           (list syntmp-val-1301)))))
                            syntmp-tmp-1297)
                     ((lambda (syntmp-_-1304)
                        (syntax-error
                          (syntmp-source-wrap-147
                            syntmp-e-1281
                            syntmp-w-1283
                            syntmp-s-1284)))
                      syntmp-tmp-1285)))
                 (syntax-dispatch
                   syntmp-tmp-1285
                   '(any (any . each-any) any)))))
            (syntax-dispatch
              syntmp-tmp-1285
              '(any any any))))
         syntmp-e-1281)))
    (syntmp-global-extend-116
      'begin
      'begin
      '())
    (syntmp-global-extend-116
      'define
      'define
      '())
    (syntmp-global-extend-116
      'define-syntax
      'define-syntax
      '())
    (syntmp-global-extend-116
      'eval-when
      'eval-when
      '())
    (syntmp-global-extend-116
      'core
      'syntax-case
      (letrec ((syntmp-gen-syntax-case-1308
                 (lambda (syntmp-x-1309
                          syntmp-keys-1310
                          syntmp-clauses-1311
                          syntmp-r-1312)
                   (if (null? syntmp-clauses-1311)
                     (list (quote syntax-error) syntmp-x-1309)
                     ((lambda (syntmp-tmp-1313)
                        ((lambda (syntmp-tmp-1314)
                           (if syntmp-tmp-1314
                             (apply (lambda (syntmp-pat-1315 syntmp-exp-1316)
                                      (if (and (syntmp-id?-118 syntmp-pat-1315)
                                               (andmap
                                                 (lambda (syntmp-x-1317)
                                                   (not (syntmp-free-id=?-141
                                                          syntmp-pat-1315
                                                          syntmp-x-1317)))
                                                 (cons '#(syntax-object
                                                          ...
                                                          ((top)
                                                           #(ribcage
                                                             #(pat exp)
                                                             #((top) (top))
                                                             #("i" "i"))
                                                           #(ribcage () () ())
                                                           #(ribcage
                                                             #(x
                                                               keys
                                                               clauses
                                                               r)
                                                             #((top)
                                                               (top)
                                                               (top)
                                                               (top))
                                                             #("i"
                                                               "i"
                                                               "i"
                                                               "i"))
                                                           #(ribcage
                                                             (gen-syntax-case
                                                               gen-clause
                                                               build-dispatch-call
                                                               convert-pattern)
                                                             ((top)
                                                              (top)
                                                              (top)
                                                              (top))
                                                             ("i" "i" "i" "i"))
                                                           #(ribcage
                                                             (lambda-var-list
                                                               gen-var
                                                               strip
                                                               strip-annotation
                                                               ellipsis?
                                                               chi-void
                                                               eval-local-transformer
                                                               chi-local-syntax
                                                               chi-lambda-clause
                                                               chi-body
                                                               chi-macro
                                                               chi-application
                                                               chi-expr
                                                               chi
                                                               chi-top
                                                               syntax-type
                                                               chi-when-list
                                                               chi-install-global
                                                               chi-top-sequence
                                                               chi-sequence
                                                               source-wrap
                                                               wrap
                                                               bound-id-member?
                                                               distinct-bound-ids?
                                                               valid-bound-ids?
                                                               bound-id=?
                                                               free-id=?
                                                               id-var-name
                                                               same-marks?
                                                               join-marks
                                                               join-wraps
                                                               smart-append
                                                               make-binding-wrap
                                                               extend-ribcage!
                                                               make-empty-ribcage
                                                               new-mark
                                                               anti-mark
                                                               the-anti-mark
                                                               top-marked?
                                                               top-wrap
                                                               empty-wrap
                                                               set-ribcage-labels!
                                                               set-ribcage-marks!
                                                               set-ribcage-symnames!
                                                               ribcage-labels
                                                               ribcage-marks
                                                               ribcage-symnames
                                                               ribcage?
                                                               make-ribcage
                                                               gen-labels
                                                               gen-label
                                                               make-rename
                                                               rename-marks
                                                               rename-new
                                                               rename-old
                                                               subst-rename?
                                                               wrap-subst
                                                               wrap-marks
                                                               make-wrap
                                                               id-sym-name&marks
                                                               id-sym-name
                                                               id?
                                                               nonsymbol-id?
                                                               global-extend
                                                               lookup
                                                               macros-only-env
                                                               extend-var-env
                                                               extend-env
                                                               null-env
                                                               binding-value
                                                               binding-type
                                                               make-binding
                                                               arg-check
                                                               source-annotation
                                                               no-source
                                                               unannotate
                                                               set-syntax-object-wrap!
                                                               set-syntax-object-expression!
                                                               syntax-object-wrap
                                                               syntax-object-expression
                                                               syntax-object?
                                                               make-syntax-object
                                                               build-lexical-var
                                                               build-letrec
                                                               build-named-let
                                                               build-let
                                                               build-sequence
                                                               build-data
                                                               build-primref
                                                               build-lambda
                                                               build-global-definition
                                                               build-global-assignment
                                                               build-global-reference
                                                               build-lexical-assignment
                                                               build-lexical-reference
                                                               build-conditional
                                                               build-application
                                                               get-global-definition-hook
                                                               put-global-definition-hook
                                                               gensym-hook
                                                               error-hook
                                                               local-eval-hook
                                                               top-level-eval-hook
                                                               annotation?
                                                               fx<
                                                               fx=
                                                               fx-
                                                               fx+
                                                               noexpand)
                                                             ((top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top))
                                                             ("i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"))
                                                           #(ribcage
                                                             (define-structure)
                                                             ((top))
                                                             ("i"))))
                                                       syntmp-keys-1310)))
                                        (let ((syntmp-labels-1318
                                                (list (syntmp-gen-label-123)))
                                              (syntmp-var-1319
                                                (syntmp-gen-var-166
                                                  syntmp-pat-1315)))
                                          (list (list 'lambda
                                                      (list syntmp-var-1319)
                                                      (syntmp-chi-154
                                                        syntmp-exp-1316
                                                        (syntmp-extend-env-112
                                                          syntmp-labels-1318
                                                          (list (cons 'syntax
                                                                      (cons syntmp-var-1319
                                                                            0)))
                                                          syntmp-r-1312)
                                                        (syntmp-make-binding-wrap-135
                                                          (list syntmp-pat-1315)
                                                          syntmp-labels-1318
                                                          '(()))))
                                                syntmp-x-1309))
                                        (syntmp-gen-clause-1307
                                          syntmp-x-1309
                                          syntmp-keys-1310
                                          (cdr syntmp-clauses-1311)
                                          syntmp-r-1312
                                          syntmp-pat-1315
                                          #t
                                          syntmp-exp-1316)))
                                    syntmp-tmp-1314)
                             ((lambda (syntmp-tmp-1320)
                                (if syntmp-tmp-1320
                                  (apply (lambda (syntmp-pat-1321
                                                  syntmp-fender-1322
                                                  syntmp-exp-1323)
                                           (syntmp-gen-clause-1307
                                             syntmp-x-1309
                                             syntmp-keys-1310
                                             (cdr syntmp-clauses-1311)
                                             syntmp-r-1312
                                             syntmp-pat-1321
                                             syntmp-fender-1322
                                             syntmp-exp-1323))
                                         syntmp-tmp-1320)
                                  ((lambda (syntmp-_-1324)
                                     (syntax-error
                                       (car syntmp-clauses-1311)
                                       "invalid syntax-case clause"))
                                   syntmp-tmp-1313)))
                              (syntax-dispatch
                                syntmp-tmp-1313
                                '(any any any)))))
                         (syntax-dispatch
                           syntmp-tmp-1313
                           '(any any))))
                      (car syntmp-clauses-1311)))))
               (syntmp-gen-clause-1307
                 (lambda (syntmp-x-1325
                          syntmp-keys-1326
                          syntmp-clauses-1327
                          syntmp-r-1328
                          syntmp-pat-1329
                          syntmp-fender-1330
                          syntmp-exp-1331)
                   (call-with-values
                     (lambda ()
                       (syntmp-convert-pattern-1305
                         syntmp-pat-1329
                         syntmp-keys-1326
                         (lambda (syntmp-e-1332)
                           (syntmp-ellipsis?-163
                             syntmp-e-1332
                             syntmp-r-1328))))
                     (lambda (syntmp-p-1333 syntmp-pvars-1334)
                       (cond ((not (syntmp-distinct-bound-ids?-144
                                     (map car syntmp-pvars-1334)))
                              (syntax-error
                                syntmp-pat-1329
                                "duplicate pattern variable in syntax-case pattern"))
                             ((not (andmap
                                     (lambda (syntmp-x-1335)
                                       (not (syntmp-ellipsis?-163
                                              (car syntmp-x-1335)
                                              syntmp-r-1328)))
                                     syntmp-pvars-1334))
                              (syntax-error
                                syntmp-pat-1329
                                "misplaced ellipsis in syntax-case pattern"))
                             (else
                              (let ((syntmp-y-1336
                                      (syntmp-gen-var-166 (quote tmp))))
                                (list (list 'lambda
                                            (list syntmp-y-1336)
                                            (let ((syntmp-y-1337
                                                    syntmp-y-1336))
                                              (list 'if
                                                    ((lambda (syntmp-tmp-1338)
                                                       ((lambda (syntmp-tmp-1339)
                                                          (if syntmp-tmp-1339
                                                            (apply (lambda ()
                                                                     syntmp-y-1337)
                                                                   syntmp-tmp-1339)
                                                            ((lambda (syntmp-_-1340)
                                                               (list 'if
                                                                     syntmp-y-1337
                                                                     (syntmp-build-dispatch-call-1306
                                                                       syntmp-pvars-1334
                                                                       syntmp-fender-1330
                                                                       syntmp-y-1337
                                                                       syntmp-r-1328)
                                                                     (syntmp-build-data-98
                                                                       #f
                                                                       #f)))
                                                             syntmp-tmp-1338)))
                                                        (syntax-dispatch
                                                          syntmp-tmp-1338
                                                          '#(atom #t))))
                                                     syntmp-fender-1330)
                                                    (syntmp-build-dispatch-call-1306
                                                      syntmp-pvars-1334
                                                      syntmp-exp-1331
                                                      syntmp-y-1337
                                                      syntmp-r-1328)
                                                    (syntmp-gen-syntax-case-1308
                                                      syntmp-x-1325
                                                      syntmp-keys-1326
                                                      syntmp-clauses-1327
                                                      syntmp-r-1328))))
                                      (if (eq? syntmp-p-1333 (quote any))
                                        (list (quote list) syntmp-x-1325)
                                        (list 'syntax-dispatch
                                              syntmp-x-1325
                                              (syntmp-build-data-98
                                                #f
                                                syntmp-p-1333)))))))))))
               (syntmp-build-dispatch-call-1306
                 (lambda (syntmp-pvars-1341
                          syntmp-exp-1342
                          syntmp-y-1343
                          syntmp-r-1344)
                   (let ((syntmp-ids-1345 (map car syntmp-pvars-1341))
                         (syntmp-levels-1346 (map cdr syntmp-pvars-1341)))
                     (let ((syntmp-labels-1347
                             (syntmp-gen-labels-124 syntmp-ids-1345))
                           (syntmp-new-vars-1348
                             (map syntmp-gen-var-166 syntmp-ids-1345)))
                       (list 'apply
                             (list 'lambda
                                   syntmp-new-vars-1348
                                   (syntmp-chi-154
                                     syntmp-exp-1342
                                     (syntmp-extend-env-112
                                       syntmp-labels-1347
                                       (map (lambda (syntmp-var-1349
                                                     syntmp-level-1350)
                                              (cons 'syntax
                                                    (cons syntmp-var-1349
                                                          syntmp-level-1350)))
                                            syntmp-new-vars-1348
                                            (map cdr syntmp-pvars-1341))
                                       syntmp-r-1344)
                                     (syntmp-make-binding-wrap-135
                                       syntmp-ids-1345
                                       syntmp-labels-1347
                                       '(()))))
                             syntmp-y-1343)))))
               (syntmp-convert-pattern-1305
                 (lambda (syntmp-pattern-1351
                          syntmp-keys-1352
                          syntmp-ellipsis?-1353)
                   (let syntmp-cvt-1354 ((syntmp-p-1355 syntmp-pattern-1351)
                                         (syntmp-n-1356 0)
                                         (syntmp-ids-1357 (quote ())))
                     (if (syntmp-id?-118 syntmp-p-1355)
                       (if (syntmp-bound-id-member?-145
                             syntmp-p-1355
                             syntmp-keys-1352)
                         (values
                           (vector (quote free-id) syntmp-p-1355)
                           syntmp-ids-1357)
                         (values
                           'any
                           (cons (cons syntmp-p-1355 syntmp-n-1356)
                                 syntmp-ids-1357)))
                       ((lambda (syntmp-tmp-1358)
                          ((lambda (syntmp-tmp-1359)
                             (if (if syntmp-tmp-1359
                                   (apply (lambda (syntmp-x-1360
                                                   syntmp-dots-1361)
                                            (syntmp-ellipsis?-1353
                                              syntmp-dots-1361))
                                          syntmp-tmp-1359)
                                   #f)
                               (apply (lambda (syntmp-x-1362 syntmp-dots-1363)
                                        (call-with-values
                                          (lambda ()
                                            (syntmp-cvt-1354
                                              syntmp-x-1362
                                              (syntmp-fx+-88 syntmp-n-1356 1)
                                              syntmp-ids-1357))
                                          (lambda (syntmp-p-1364
                                                   syntmp-ids-1365)
                                            (values
                                              (if (eq? syntmp-p-1364
                                                       'any)
                                                'each-any
                                                (vector
                                                  'each
                                                  syntmp-p-1364))
                                              syntmp-ids-1365))))
                                      syntmp-tmp-1359)
                               ((lambda (syntmp-tmp-1366)
                                  (if syntmp-tmp-1366
                                    (apply (lambda (syntmp-x-1367
                                                    syntmp-y-1368)
                                             (call-with-values
                                               (lambda ()
                                                 (syntmp-cvt-1354
                                                   syntmp-y-1368
                                                   syntmp-n-1356
                                                   syntmp-ids-1357))
                                               (lambda (syntmp-y-1369
                                                        syntmp-ids-1370)
                                                 (call-with-values
                                                   (lambda ()
                                                     (syntmp-cvt-1354
                                                       syntmp-x-1367
                                                       syntmp-n-1356
                                                       syntmp-ids-1370))
                                                   (lambda (syntmp-x-1371
                                                            syntmp-ids-1372)
                                                     (values
                                                       (cons syntmp-x-1371
                                                             syntmp-y-1369)
                                                       syntmp-ids-1372))))))
                                           syntmp-tmp-1366)
                                    ((lambda (syntmp-tmp-1373)
                                       (if syntmp-tmp-1373
                                         (apply (lambda ()
                                                  (values
                                                    '()
                                                    syntmp-ids-1357))
                                                syntmp-tmp-1373)
                                         ((lambda (syntmp-tmp-1374)
                                            (if syntmp-tmp-1374
                                              (apply (lambda (syntmp-x-1375)
                                                       (call-with-values
                                                         (lambda ()
                                                           (syntmp-cvt-1354
                                                             syntmp-x-1375
                                                             syntmp-n-1356
                                                             syntmp-ids-1357))
                                                         (lambda (syntmp-p-1377
                                                                  syntmp-ids-1378)
                                                           (values
                                                             (vector
                                                               'vector
                                                               syntmp-p-1377)
                                                             syntmp-ids-1378))))
                                                     syntmp-tmp-1374)
                                              ((lambda (syntmp-x-1379)
                                                 (values
                                                   (vector
                                                     'atom
                                                     (syntmp-strip-165
                                                       syntmp-p-1355
                                                       '(())))
                                                   syntmp-ids-1357))
                                               syntmp-tmp-1358)))
                                          (syntax-dispatch
                                            syntmp-tmp-1358
                                            '#(vector each-any)))))
                                     (syntax-dispatch
                                       syntmp-tmp-1358
                                       '()))))
                                (syntax-dispatch
                                  syntmp-tmp-1358
                                  '(any . any)))))
                           (syntax-dispatch
                             syntmp-tmp-1358
                             '(any any))))
                        syntmp-p-1355))))))
        (lambda (syntmp-e-1380
                 syntmp-r-1381
                 syntmp-w-1382
                 syntmp-s-1383)
          (let ((syntmp-e-1384
                  (syntmp-source-wrap-147
                    syntmp-e-1380
                    syntmp-w-1382
                    syntmp-s-1383)))
            ((lambda (syntmp-tmp-1385)
               ((lambda (syntmp-tmp-1386)
                  (if syntmp-tmp-1386
                    (apply (lambda (syntmp-_-1387
                                    syntmp-val-1388
                                    syntmp-key-1389
                                    syntmp-m-1390)
                             (if (andmap
                                   (lambda (syntmp-x-1391)
                                     (and (syntmp-id?-118 syntmp-x-1391)
                                          (not (syntmp-ellipsis?-163
                                                 syntmp-x-1391
                                                 syntmp-r-1381))))
                                   syntmp-key-1389)
                               (let ((syntmp-x-1393
                                       (syntmp-gen-var-166 (quote tmp))))
                                 (list (list 'lambda
                                             (list syntmp-x-1393)
                                             (syntmp-gen-syntax-case-1308
                                               syntmp-x-1393
                                               syntmp-key-1389
                                               syntmp-m-1390
                                               syntmp-r-1381))
                                       (syntmp-chi-154
                                         syntmp-val-1388
                                         syntmp-r-1381
                                         '(()))))
                               (syntax-error
                                 syntmp-e-1384
                                 "invalid literals list in")))
                           syntmp-tmp-1386)
                    (syntax-error syntmp-tmp-1385)))
                (syntax-dispatch
                  syntmp-tmp-1385
                  '(any any each-any . each-any))))
             syntmp-e-1384)))))
    (set! sc-expand
      (let ((syntmp-m-1396 (quote e))
            (syntmp-esew-1397 (quote (eval))))
        (lambda (syntmp-x-1398)
          (if (and (pair? syntmp-x-1398)
                   (equal? (car syntmp-x-1398) syntmp-noexpand-87))
            (cadr syntmp-x-1398)
            (syntmp-chi-top-153
              syntmp-x-1398
              '()
              '((top))
              syntmp-m-1396
              syntmp-esew-1397)))))
    (set! sc-expand3
      (let ((syntmp-m-1399 (quote e))
            (syntmp-esew-1400 (quote (eval))))
        (lambda (syntmp-x-1402 . syntmp-rest-1401)
          (if (and (pair? syntmp-x-1402)
                   (equal? (car syntmp-x-1402) syntmp-noexpand-87))
            (cadr syntmp-x-1402)
            (syntmp-chi-top-153
              syntmp-x-1402
              '()
              '((top))
              (if (null? syntmp-rest-1401)
                syntmp-m-1399
                (car syntmp-rest-1401))
              (if (or (null? syntmp-rest-1401)
                      (null? (cdr syntmp-rest-1401)))
                syntmp-esew-1400
                (cadr syntmp-rest-1401)))))))
    (set! identifier?
      (lambda (syntmp-x-1403)
        (syntmp-nonsymbol-id?-117 syntmp-x-1403)))
    (set! datum->syntax-object
      (lambda (syntmp-id-1404 syntmp-datum-1405)
        (syntmp-make-syntax-object-103
          syntmp-datum-1405
          (syntmp-syntax-object-wrap-106 syntmp-id-1404))))
    (set! syntax-object->datum
      (lambda (syntmp-x-1406)
        (syntmp-strip-165 syntmp-x-1406 (quote (())))))
    (set! generate-temporaries
      (lambda (syntmp-ls-1407)
        (begin
          (let ((syntmp-x-1408 syntmp-ls-1407))
            (if (not (list? syntmp-x-1408))
              (syntmp-error-hook-95
                'generate-temporaries
                "invalid argument"
                syntmp-x-1408)))
          (map (lambda (syntmp-x-1409)
                 (syntmp-wrap-146 (gensym) (quote ((top)))))
               syntmp-ls-1407))))
    (set! free-identifier=?
      (lambda (syntmp-x-1410 syntmp-y-1411)
        (begin
          (let ((syntmp-x-1412 syntmp-x-1410))
            (if (not (syntmp-nonsymbol-id?-117 syntmp-x-1412))
              (syntmp-error-hook-95
                'free-identifier=?
                "invalid argument"
                syntmp-x-1412)))
          (let ((syntmp-x-1413 syntmp-y-1411))
            (if (not (syntmp-nonsymbol-id?-117 syntmp-x-1413))
              (syntmp-error-hook-95
                'free-identifier=?
                "invalid argument"
                syntmp-x-1413)))
          (syntmp-free-id=?-141
            syntmp-x-1410
            syntmp-y-1411))))
    (set! bound-identifier=?
      (lambda (syntmp-x-1414 syntmp-y-1415)
        (begin
          (let ((syntmp-x-1416 syntmp-x-1414))
            (if (not (syntmp-nonsymbol-id?-117 syntmp-x-1416))
              (syntmp-error-hook-95
                'bound-identifier=?
                "invalid argument"
                syntmp-x-1416)))
          (let ((syntmp-x-1417 syntmp-y-1415))
            (if (not (syntmp-nonsymbol-id?-117 syntmp-x-1417))
              (syntmp-error-hook-95
                'bound-identifier=?
                "invalid argument"
                syntmp-x-1417)))
          (syntmp-bound-id=?-142
            syntmp-x-1414
            syntmp-y-1415))))
    (set! syntax-error
      (lambda (syntmp-object-1419 . syntmp-messages-1418)
        (begin
          (for-each
            (lambda (syntmp-x-1420)
              (let ((syntmp-x-1421 syntmp-x-1420))
                (if (not (string? syntmp-x-1421))
                  (syntmp-error-hook-95
                    'syntax-error
                    "invalid argument"
                    syntmp-x-1421))))
            syntmp-messages-1418)
          (let ((syntmp-message-1422
                  (if (null? syntmp-messages-1418)
                    "invalid syntax"
                    (apply string-append syntmp-messages-1418))))
            (syntmp-error-hook-95
              #f
              syntmp-message-1422
              (syntmp-strip-165
                syntmp-object-1419
                '(())))))))
    (set! install-global-transformer
      (lambda (syntmp-sym-1423 syntmp-v-1424)
        (begin
          (let ((syntmp-x-1425 syntmp-sym-1423))
            (if (not (symbol? syntmp-x-1425))
              (syntmp-error-hook-95
                'define-syntax
                "invalid argument"
                syntmp-x-1425)))
          (let ((syntmp-x-1426 syntmp-v-1424))
            (if (not (procedure? syntmp-x-1426))
              (syntmp-error-hook-95
                'define-syntax
                "invalid argument"
                syntmp-x-1426)))
          (syntmp-global-extend-116
            'macro
            syntmp-sym-1423
            syntmp-v-1424))))
    (letrec ((syntmp-match-1431
               (lambda (syntmp-e-1432
                        syntmp-p-1433
                        syntmp-w-1434
                        syntmp-r-1435)
                 (cond ((not syntmp-r-1435) #f)
                       ((eq? syntmp-p-1433 (quote _)) syntmp-r-1435)
                       ((eq? syntmp-p-1433 (quote any))
                        (cons (syntmp-wrap-146 syntmp-e-1432 syntmp-w-1434)
                              syntmp-r-1435))
                       ((syntmp-syntax-object?-104 syntmp-e-1432)
                        (syntmp-match*-1430
                          (let ((syntmp-e-1436
                                  (syntmp-syntax-object-expression-105
                                    syntmp-e-1432)))
                            (if (syntmp-annotation?-92 syntmp-e-1436)
                              (annotation-expression syntmp-e-1436)
                              syntmp-e-1436))
                          syntmp-p-1433
                          (syntmp-join-wraps-137
                            syntmp-w-1434
                            (syntmp-syntax-object-wrap-106 syntmp-e-1432))
                          syntmp-r-1435))
                       (else
                        (syntmp-match*-1430
                          (let ((syntmp-e-1437 syntmp-e-1432))
                            (if (syntmp-annotation?-92 syntmp-e-1437)
                              (annotation-expression syntmp-e-1437)
                              syntmp-e-1437))
                          syntmp-p-1433
                          syntmp-w-1434
                          syntmp-r-1435)))))
             (syntmp-match*-1430
               (lambda (syntmp-e-1438
                        syntmp-p-1439
                        syntmp-w-1440
                        syntmp-r-1441)
                 (cond ((null? syntmp-p-1439)
                        (and (null? syntmp-e-1438) syntmp-r-1441))
                       ((pair? syntmp-p-1439)
                        (and (pair? syntmp-e-1438)
                             (syntmp-match-1431
                               (car syntmp-e-1438)
                               (car syntmp-p-1439)
                               syntmp-w-1440
                               (syntmp-match-1431
                                 (cdr syntmp-e-1438)
                                 (cdr syntmp-p-1439)
                                 syntmp-w-1440
                                 syntmp-r-1441))))
                       ((eq? syntmp-p-1439 (quote each-any))
                        (let ((syntmp-l-1442
                                (syntmp-match-each-any-1428
                                  syntmp-e-1438
                                  syntmp-w-1440)))
                          (and syntmp-l-1442
                               (cons syntmp-l-1442 syntmp-r-1441))))
                       (else
                        (let ((syntmp-t-1443 (vector-ref syntmp-p-1439 0)))
                          (if (memv syntmp-t-1443 (quote (each)))
                            (if (null? syntmp-e-1438)
                              (syntmp-match-empty-1429
                                (vector-ref syntmp-p-1439 1)
                                syntmp-r-1441)
                              (let ((syntmp-l-1444
                                      (syntmp-match-each-1427
                                        syntmp-e-1438
                                        (vector-ref syntmp-p-1439 1)
                                        syntmp-w-1440)))
                                (and syntmp-l-1444
                                     (let syntmp-collect-1445 ((syntmp-l-1446
                                                                 syntmp-l-1444))
                                       (if (null? (car syntmp-l-1446))
                                         syntmp-r-1441
                                         (cons (map car syntmp-l-1446)
                                               (syntmp-collect-1445
                                                 (map cdr syntmp-l-1446))))))))
                            (if (memv syntmp-t-1443 (quote (free-id)))
                              (and (syntmp-id?-118 syntmp-e-1438)
                                   (syntmp-free-id=?-141
                                     (syntmp-wrap-146
                                       syntmp-e-1438
                                       syntmp-w-1440)
                                     (vector-ref syntmp-p-1439 1))
                                   syntmp-r-1441)
                              (if (memv syntmp-t-1443 (quote (atom)))
                                (and (equal?
                                       (vector-ref syntmp-p-1439 1)
                                       (syntmp-strip-165
                                         syntmp-e-1438
                                         syntmp-w-1440))
                                     syntmp-r-1441)
                                (if (memv syntmp-t-1443 (quote (vector)))
                                  (and (vector? syntmp-e-1438)
                                       (syntmp-match-1431
                                         (vector->list syntmp-e-1438)
                                         (vector-ref syntmp-p-1439 1)
                                         syntmp-w-1440
                                         syntmp-r-1441)))))))))))
             (syntmp-match-empty-1429
               (lambda (syntmp-p-1447 syntmp-r-1448)
                 (cond ((null? syntmp-p-1447) syntmp-r-1448)
                       ((eq? syntmp-p-1447 (quote _)) syntmp-r-1448)
                       ((eq? syntmp-p-1447 (quote any))
                        (cons (quote ()) syntmp-r-1448))
                       ((pair? syntmp-p-1447)
                        (syntmp-match-empty-1429
                          (car syntmp-p-1447)
                          (syntmp-match-empty-1429
                            (cdr syntmp-p-1447)
                            syntmp-r-1448)))
                       ((eq? syntmp-p-1447 (quote each-any))
                        (cons (quote ()) syntmp-r-1448))
                       (else
                        (let ((syntmp-t-1449 (vector-ref syntmp-p-1447 0)))
                          (if (memv syntmp-t-1449 (quote (each)))
                            (syntmp-match-empty-1429
                              (vector-ref syntmp-p-1447 1)
                              syntmp-r-1448)
                            (if (memv syntmp-t-1449 (quote (free-id atom)))
                              syntmp-r-1448
                              (if (memv syntmp-t-1449 (quote (vector)))
                                (syntmp-match-empty-1429
                                  (vector-ref syntmp-p-1447 1)
                                  syntmp-r-1448)))))))))
             (syntmp-match-each-any-1428
               (lambda (syntmp-e-1450 syntmp-w-1451)
                 (cond ((syntmp-annotation?-92 syntmp-e-1450)
                        (syntmp-match-each-any-1428
                          (annotation-expression syntmp-e-1450)
                          syntmp-w-1451))
                       ((pair? syntmp-e-1450)
                        (let ((syntmp-l-1452
                                (syntmp-match-each-any-1428
                                  (cdr syntmp-e-1450)
                                  syntmp-w-1451)))
                          (and syntmp-l-1452
                               (cons (syntmp-wrap-146
                                       (car syntmp-e-1450)
                                       syntmp-w-1451)
                                     syntmp-l-1452))))
                       ((null? syntmp-e-1450) (quote ()))
                       ((syntmp-syntax-object?-104 syntmp-e-1450)
                        (syntmp-match-each-any-1428
                          (syntmp-syntax-object-expression-105
                            syntmp-e-1450)
                          (syntmp-join-wraps-137
                            syntmp-w-1451
                            (syntmp-syntax-object-wrap-106 syntmp-e-1450))))
                       (else #f))))
             (syntmp-match-each-1427
               (lambda (syntmp-e-1453 syntmp-p-1454 syntmp-w-1455)
                 (cond ((syntmp-annotation?-92 syntmp-e-1453)
                        (syntmp-match-each-1427
                          (annotation-expression syntmp-e-1453)
                          syntmp-p-1454
                          syntmp-w-1455))
                       ((pair? syntmp-e-1453)
                        (let ((syntmp-first-1456
                                (syntmp-match-1431
                                  (car syntmp-e-1453)
                                  syntmp-p-1454
                                  syntmp-w-1455
                                  '())))
                          (and syntmp-first-1456
                               (let ((syntmp-rest-1457
                                       (syntmp-match-each-1427
                                         (cdr syntmp-e-1453)
                                         syntmp-p-1454
                                         syntmp-w-1455)))
                                 (and syntmp-rest-1457
                                      (cons syntmp-first-1456
                                            syntmp-rest-1457))))))
                       ((null? syntmp-e-1453) (quote ()))
                       ((syntmp-syntax-object?-104 syntmp-e-1453)
                        (syntmp-match-each-1427
                          (syntmp-syntax-object-expression-105
                            syntmp-e-1453)
                          syntmp-p-1454
                          (syntmp-join-wraps-137
                            syntmp-w-1455
                            (syntmp-syntax-object-wrap-106 syntmp-e-1453))))
                       (else #f)))))
      (begin
        (set! syntax-dispatch
          (lambda (syntmp-e-1458 syntmp-p-1459)
            (cond ((eq? syntmp-p-1459 (quote any))
                   (list syntmp-e-1458))
                  ((eq? syntmp-p-1459 (quote _)) (quote ()))
                  ((syntmp-syntax-object?-104 syntmp-e-1458)
                   (syntmp-match*-1430
                     (let ((syntmp-e-1460
                             (syntmp-syntax-object-expression-105
                               syntmp-e-1458)))
                       (if (syntmp-annotation?-92 syntmp-e-1460)
                         (annotation-expression syntmp-e-1460)
                         syntmp-e-1460))
                     syntmp-p-1459
                     (syntmp-syntax-object-wrap-106 syntmp-e-1458)
                     '()))
                  (else
                   (syntmp-match*-1430
                     (let ((syntmp-e-1461 syntmp-e-1458))
                       (if (syntmp-annotation?-92 syntmp-e-1461)
                         (annotation-expression syntmp-e-1461)
                         syntmp-e-1461))
                     syntmp-p-1459
                     '(())
                     '())))))
        (set! sc-chi syntmp-chi-154)))))

(install-global-transformer
  'with-syntax
  (lambda (syntmp-x-1462)
    ((lambda (syntmp-tmp-1463)
       ((lambda (syntmp-tmp-1464)
          (if syntmp-tmp-1464
            (apply (lambda (syntmp-_-1465 syntmp-e1-1466 syntmp-e2-1467)
                     (cons '#(syntax-object
                              let
                              ((top)
                               #(ribcage
                                 #(_ e1 e2)
                                 #((top) (top) (top))
                                 #("i" "i" "i"))
                               #(ribcage () () ())
                               #(ribcage #(x) #((top)) #("i"))))
                           (cons '()
                                 (cons syntmp-e1-1466 syntmp-e2-1467))))
                   syntmp-tmp-1464)
            ((lambda (syntmp-tmp-1469)
               (if syntmp-tmp-1469
                 (apply (lambda (syntmp-_-1470
                                 syntmp-out-1471
                                 syntmp-in-1472
                                 syntmp-e1-1473
                                 syntmp-e2-1474)
                          (list '#(syntax-object
                                   syntax-case
                                   ((top)
                                    #(ribcage
                                      #(_ out in e1 e2)
                                      #((top) (top) (top) (top) (top))
                                      #("i" "i" "i" "i" "i"))
                                    #(ribcage () () ())
                                    #(ribcage #(x) #((top)) #("i"))))
                                syntmp-in-1472
                                '()
                                (list syntmp-out-1471
                                      (cons '#(syntax-object
                                               let
                                               ((top)
                                                #(ribcage
                                                  #(_ out in e1 e2)
                                                  #((top)
                                                    (top)
                                                    (top)
                                                    (top)
                                                    (top))
                                                  #("i" "i" "i" "i" "i"))
                                                #(ribcage () () ())
                                                #(ribcage
                                                  #(x)
                                                  #((top))
                                                  #("i"))))
                                            (cons '()
                                                  (cons syntmp-e1-1473
                                                        syntmp-e2-1474))))))
                        syntmp-tmp-1469)
                 ((lambda (syntmp-tmp-1476)
                    (if syntmp-tmp-1476
                      (apply (lambda (syntmp-_-1477
                                      syntmp-out-1478
                                      syntmp-in-1479
                                      syntmp-e1-1480
                                      syntmp-e2-1481)
                               (list '#(syntax-object
                                        syntax-case
                                        ((top)
                                         #(ribcage
                                           #(_ out in e1 e2)
                                           #((top) (top) (top) (top) (top))
                                           #("i" "i" "i" "i" "i"))
                                         #(ribcage () () ())
                                         #(ribcage #(x) #((top)) #("i"))))
                                     (cons '#(syntax-object
                                              list
                                              ((top)
                                               #(ribcage
                                                 #(_ out in e1 e2)
                                                 #((top)
                                                   (top)
                                                   (top)
                                                   (top)
                                                   (top))
                                                 #("i" "i" "i" "i" "i"))
                                               #(ribcage () () ())
                                               #(ribcage
                                                 #(x)
                                                 #((top))
                                                 #("i"))))
                                           syntmp-in-1479)
                                     '()
                                     (list syntmp-out-1478
                                           (cons '#(syntax-object
                                                    let
                                                    ((top)
                                                     #(ribcage
                                                       #(_ out in e1 e2)
                                                       #((top)
                                                         (top)
                                                         (top)
                                                         (top)
                                                         (top))
                                                       #("i" "i" "i" "i" "i"))
                                                     #(ribcage () () ())
                                                     #(ribcage
                                                       #(x)
                                                       #((top))
                                                       #("i"))))
                                                 (cons '()
                                                       (cons syntmp-e1-1480
                                                             syntmp-e2-1481))))))
                             syntmp-tmp-1476)
                      (syntax-error syntmp-tmp-1463)))
                  (syntax-dispatch
                    syntmp-tmp-1463
                    '(any #(each (any any)) any . each-any)))))
             (syntax-dispatch
               syntmp-tmp-1463
               '(any ((any any)) any . each-any)))))
        (syntax-dispatch
          syntmp-tmp-1463
          '(any () any . each-any))))
     syntmp-x-1462)))

(install-global-transformer
  'syntax-rules
  (lambda (syntmp-xx-1503)
    (letrec ((syntmp-expand-syntax-rules-1504
               (lambda (syntmp-dots-1505
                        syntmp-keys-1506
                        syntmp-docstrings-1507
                        syntmp-clauses-1508)
                 ((lambda (syntmp-tmp-1509)
                    ((lambda (syntmp-tmp-1510)
                       (if syntmp-tmp-1510
                         (apply (lambda (syntmp-k-1511
                                         syntmp-docstring-1512
                                         syntmp-keyword-1513
                                         syntmp-pattern-1514
                                         syntmp-template-1515)
                                  ((lambda (syntmp-tmp-1516)
                                     ((lambda (syntmp-form-1517)
                                        (if syntmp-dots-1505
                                          ((lambda (syntmp-tmp-1518)
                                             ((lambda (syntmp-dots-1519)
                                                (list '#(syntax-object
                                                         with-ellipsis
                                                         ((top)
                                                          #(ribcage () () ())
                                                          #(ribcage
                                                            #(dots)
                                                            #((top))
                                                            #("i"))
                                                          #(ribcage () () ())
                                                          #(ribcage
                                                            #(form)
                                                            #((top))
                                                            #("i"))
                                                          #(ribcage () () ())
                                                          #(ribcage () () ())
                                                          #(ribcage
                                                            #(k
                                                              docstring
                                                              keyword
                                                              pattern
                                                              template)
                                                            #((top)
                                                              (top)
                                                              (top)
                                                              (top)
                                                              (top))
                                                            #("i"
                                                              "i"
                                                              "i"
                                                              "i"
                                                              "i"))
                                                          #(ribcage () () ())
                                                          #(ribcage () () ())
                                                          #(ribcage
                                                            #(dots
                                                              keys
                                                              docstrings
                                                              clauses)
                                                            #((top)
                                                              (top)
                                                              (top)
                                                              (top))
                                                            #("i" "i" "i" "i"))
                                                          #(ribcage
                                                            (expand-syntax-rules)
                                                            ((top))
                                                            ("i"))
                                                          #(ribcage
                                                            #(xx)
                                                            #((top))
                                                            #("i"))))
                                                      syntmp-dots-1519
                                                      syntmp-form-1517))
                                              syntmp-tmp-1518))
                                           syntmp-dots-1505)
                                          syntmp-form-1517))
                                      syntmp-tmp-1516))
                                   (cons '#(syntax-object
                                            lambda
                                            ((top)
                                             #(ribcage () () ())
                                             #(ribcage () () ())
                                             #(ribcage
                                               #(k
                                                 docstring
                                                 keyword
                                                 pattern
                                                 template)
                                               #((top) (top) (top) (top) (top))
                                               #("i" "i" "i" "i" "i"))
                                             #(ribcage () () ())
                                             #(ribcage () () ())
                                             #(ribcage
                                               #(dots keys docstrings clauses)
                                               #((top) (top) (top) (top))
                                               #("i" "i" "i" "i"))
                                             #(ribcage
                                               (expand-syntax-rules)
                                               ((top))
                                               ("i"))
                                             #(ribcage #(xx) #((top)) #("i"))))
                                         (cons '(#(syntax-object
                                                   x
                                                   ((top)
                                                    #(ribcage () () ())
                                                    #(ribcage () () ())
                                                    #(ribcage
                                                      #(k
                                                        docstring
                                                        keyword
                                                        pattern
                                                        template)
                                                      #((top)
                                                        (top)
                                                        (top)
                                                        (top)
                                                        (top))
                                                      #("i" "i" "i" "i" "i"))
                                                    #(ribcage () () ())
                                                    #(ribcage () () ())
                                                    #(ribcage
                                                      #(dots
                                                        keys
                                                        docstrings
                                                        clauses)
                                                      #((top)
                                                        (top)
                                                        (top)
                                                        (top))
                                                      #("i" "i" "i" "i"))
                                                    #(ribcage
                                                      (expand-syntax-rules)
                                                      ((top))
                                                      ("i"))
                                                    #(ribcage
                                                      #(xx)
                                                      #((top))
                                                      #("i")))))
                                               (append
                                                 syntmp-docstring-1512
                                                 (list (cons '#(syntax-object
                                                                syntax-case
                                                                ((top)
                                                                 #(ribcage
                                                                   ()
                                                                   ()
                                                                   ())
                                                                 #(ribcage
                                                                   ()
                                                                   ()
                                                                   ())
                                                                 #(ribcage
                                                                   #(k
                                                                     docstring
                                                                     keyword
                                                                     pattern
                                                                     template)
                                                                   #((top)
                                                                     (top)
                                                                     (top)
                                                                     (top)
                                                                     (top))
                                                                   #("i"
                                                                     "i"
                                                                     "i"
                                                                     "i"
                                                                     "i"))
                                                                 #(ribcage
                                                                   ()
                                                                   ()
                                                                   ())
                                                                 #(ribcage
                                                                   ()
                                                                   ()
                                                                   ())
                                                                 #(ribcage
                                                                   #(dots
                                                                     keys
                                                                     docstrings
                                                                     clauses)
                                                                   #((top)
                                                                     (top)
                                                                     (top)
                                                                     (top))
                                                                   #("i"
                                                                     "i"
                                                                     "i"
                                                                     "i"))
                                                                 #(ribcage
                                                                   (expand-syntax-rules)
                                                                   ((top))
                                                                   ("i"))
                                                                 #(ribcage
                                                                   #(xx)
                                                                   #((top))
                                                                   #("i"))))
                                                             (cons '#(syntax-object
                                                                      x
                                                                      ((top)
                                                                       #(ribcage
                                                                         ()
                                                                         ()
                                                                         ())
                                                                       #(ribcage
                                                                         ()
                                                                         ()
                                                                         ())
                                                                       #(ribcage
                                                                         #(k
                                                                           docstring
                                                                           keyword
                                                                           pattern
                                                                           template)
                                                                         #((top)
                                                                           (top)
                                                                           (top)
                                                                           (top)
                                                                           (top))
                                                                         #("i"
                                                                           "i"
                                                                           "i"
                                                                           "i"
                                                                           "i"))
                                                                       #(ribcage
                                                                         ()
                                                                         ()
                                                                         ())
                                                                       #(ribcage
                                                                         ()
                                                                         ()
                                                                         ())
                                                                       #(ribcage
                                                                         #(dots
                                                                           keys
                                                                           docstrings
                                                                           clauses)
                                                                         #((top)
                                                                           (top)
                                                                           (top)
                                                                           (top))
                                                                         #("i"
                                                                           "i"
                                                                           "i"
                                                                           "i"))
                                                                       #(ribcage
                                                                         (expand-syntax-rules)
                                                                         ((top))
                                                                         ("i"))
                                                                       #(ribcage
                                                                         #(xx)
                                                                         #((top))
                                                                         #("i"))))
                                                                   (cons syntmp-k-1511
                                                                         (map (lambda (syntmp-tmp-1522
                                                                                       syntmp-tmp-1521)
                                                                                (list (cons '#(syntax-object
                                                                                               dummy
                                                                                               ((top)
                                                                                                #(ribcage
                                                                                                  ()
                                                                                                  ()
                                                                                                  ())
                                                                                                #(ribcage
                                                                                                  ()
                                                                                                  ()
                                                                                                  ())
                                                                                                #(ribcage
                                                                                                  #(k
                                                                                                    docstring
                                                                                                    keyword
                                                                                                    pattern
                                                                                                    template)
                                                                                                  #((top)
                                                                                                    (top)
                                                                                                    (top)
                                                                                                    (top)
                                                                                                    (top))
                                                                                                  #("i"
                                                                                                    "i"
                                                                                                    "i"
                                                                                                    "i"
                                                                                                    "i"))
                                                                                                #(ribcage
                                                                                                  ()
                                                                                                  ()
                                                                                                  ())
                                                                                                #(ribcage
                                                                                                  ()
                                                                                                  ()
                                                                                                  ())
                                                                                                #(ribcage
                                                                                                  #(dots
                                                                                                    keys
                                                                                                    docstrings
                                                                                                    clauses)
                                                                                                  #((top)
                                                                                                    (top)
                                                                                                    (top)
                                                                                                    (top))
                                                                                                  #("i"
                                                                                                    "i"
                                                                                                    "i"
                                                                                                    "i"))
                                                                                                #(ribcage
                                                                                                  (expand-syntax-rules)
                                                                                                  ((top))
                                                                                                  ("i"))
                                                                                                #(ribcage
                                                                                                  #(xx)
                                                                                                  #((top))
                                                                                                  #("i"))))
                                                                                            syntmp-tmp-1521)
                                                                                      (list '#(syntax-object
                                                                                               syntax
                                                                                               ((top)
                                                                                                #(ribcage
                                                                                                  ()
                                                                                                  ()
                                                                                                  ())
                                                                                                #(ribcage
                                                                                                  ()
                                                                                                  ()
                                                                                                  ())
                                                                                                #(ribcage
                                                                                                  #(k
                                                                                                    docstring
                                                                                                    keyword
                                                                                                    pattern
                                                                                                    template)
                                                                                                  #((top)
                                                                                                    (top)
                                                                                                    (top)
                                                                                                    (top)
                                                                                                    (top))
                                                                                                  #("i"
                                                                                                    "i"
                                                                                                    "i"
                                                                                                    "i"
                                                                                                    "i"))
                                                                                                #(ribcage
                                                                                                  ()
                                                                                                  ()
                                                                                                  ())
                                                                                                #(ribcage
                                                                                                  ()
                                                                                                  ()
                                                                                                  ())
                                                                                                #(ribcage
                                                                                                  #(dots
                                                                                                    keys
                                                                                                    docstrings
                                                                                                    clauses)
                                                                                                  #((top)
                                                                                                    (top)
                                                                                                    (top)
                                                                                                    (top))
                                                                                                  #("i"
                                                                                                    "i"
                                                                                                    "i"
                                                                                                    "i"))
                                                                                                #(ribcage
                                                                                                  (expand-syntax-rules)
                                                                                                  ((top))
                                                                                                  ("i"))
                                                                                                #(ribcage
                                                                                                  #(xx)
                                                                                                  #((top))
                                                                                                  #("i"))))
                                                                                            syntmp-tmp-1522)))
                                                                              syntmp-template-1515
                                                                              syntmp-pattern-1514))))))))))
                                syntmp-tmp-1510)
                         (syntax-error syntmp-tmp-1509)))
                     (syntax-dispatch
                       syntmp-tmp-1509
                       '(each-any each-any #(each ((any . any) any))))))
                  (list syntmp-keys-1506
                        syntmp-docstrings-1507
                        syntmp-clauses-1508)))))
      ((lambda (syntmp-tmp-1524)
         ((lambda (syntmp-tmp-1525)
            (if syntmp-tmp-1525
              (apply (lambda (syntmp-_-1526
                              syntmp-k-1527
                              syntmp-keyword-1528
                              syntmp-pattern-1529
                              syntmp-template-1530)
                       (syntmp-expand-syntax-rules-1504
                         #f
                         syntmp-k-1527
                         '()
                         (map (lambda (syntmp-tmp-1534
                                       syntmp-tmp-1533
                                       syntmp-tmp-1532)
                                (list (cons syntmp-tmp-1532 syntmp-tmp-1533)
                                      syntmp-tmp-1534))
                              syntmp-template-1530
                              syntmp-pattern-1529
                              syntmp-keyword-1528)))
                     syntmp-tmp-1525)
              ((lambda (syntmp-tmp-1535)
                 (if (if syntmp-tmp-1535
                       (apply (lambda (syntmp-_-1536
                                       syntmp-k-1537
                                       syntmp-docstring-1538
                                       syntmp-keyword-1539
                                       syntmp-pattern-1540
                                       syntmp-template-1541)
                                (string?
                                  (syntax-object->datum
                                    syntmp-docstring-1538)))
                              syntmp-tmp-1535)
                       #f)
                   (apply (lambda (syntmp-_-1542
                                   syntmp-k-1543
                                   syntmp-docstring-1544
                                   syntmp-keyword-1545
                                   syntmp-pattern-1546
                                   syntmp-template-1547)
                            (syntmp-expand-syntax-rules-1504
                              #f
                              syntmp-k-1543
                              (list syntmp-docstring-1544)
                              (map (lambda (syntmp-tmp-1551
                                            syntmp-tmp-1550
                                            syntmp-tmp-1549)
                                     (list (cons syntmp-tmp-1549
                                                 syntmp-tmp-1550)
                                           syntmp-tmp-1551))
                                   syntmp-template-1547
                                   syntmp-pattern-1546
                                   syntmp-keyword-1545)))
                          syntmp-tmp-1535)
                   ((lambda (syntmp-tmp-1552)
                      (if (if syntmp-tmp-1552
                            (apply (lambda (syntmp-_-1553
                                            syntmp-dots-1554
                                            syntmp-k-1555
                                            syntmp-keyword-1556
                                            syntmp-pattern-1557
                                            syntmp-template-1558)
                                     (identifier? syntmp-dots-1554))
                                   syntmp-tmp-1552)
                            #f)
                        (apply (lambda (syntmp-_-1559
                                        syntmp-dots-1560
                                        syntmp-k-1561
                                        syntmp-keyword-1562
                                        syntmp-pattern-1563
                                        syntmp-template-1564)
                                 (syntmp-expand-syntax-rules-1504
                                   syntmp-dots-1560
                                   syntmp-k-1561
                                   '()
                                   (map (lambda (syntmp-tmp-1568
                                                 syntmp-tmp-1567
                                                 syntmp-tmp-1566)
                                          (list (cons syntmp-tmp-1566
                                                      syntmp-tmp-1567)
                                                syntmp-tmp-1568))
                                        syntmp-template-1564
                                        syntmp-pattern-1563
                                        syntmp-keyword-1562)))
                               syntmp-tmp-1552)
                        ((lambda (syntmp-tmp-1569)
                           (if (if syntmp-tmp-1569
                                 (apply (lambda (syntmp-_-1570
                                                 syntmp-dots-1571
                                                 syntmp-k-1572
                                                 syntmp-docstring-1573
                                                 syntmp-keyword-1574
                                                 syntmp-pattern-1575
                                                 syntmp-template-1576)
                                          (and (identifier? syntmp-dots-1571)
                                               (string?
                                                 (syntax-object->datum
                                                   syntmp-docstring-1573))))
                                        syntmp-tmp-1569)
                                 #f)
                             (apply (lambda (syntmp-_-1577
                                             syntmp-dots-1578
                                             syntmp-k-1579
                                             syntmp-docstring-1580
                                             syntmp-keyword-1581
                                             syntmp-pattern-1582
                                             syntmp-template-1583)
                                      (syntmp-expand-syntax-rules-1504
                                        syntmp-dots-1578
                                        syntmp-k-1579
                                        (list syntmp-docstring-1580)
                                        (map (lambda (syntmp-tmp-1587
                                                      syntmp-tmp-1586
                                                      syntmp-tmp-1585)
                                               (list (cons syntmp-tmp-1585
                                                           syntmp-tmp-1586)
                                                     syntmp-tmp-1587))
                                             syntmp-template-1583
                                             syntmp-pattern-1582
                                             syntmp-keyword-1581)))
                                    syntmp-tmp-1569)
                             (syntax-error syntmp-tmp-1524)))
                         (syntax-dispatch
                           syntmp-tmp-1524
                           '(any any
                                 each-any
                                 any
                                 .
                                 #(each ((any . any) any)))))))
                    (syntax-dispatch
                      syntmp-tmp-1524
                      '(any any each-any . #(each ((any . any) any)))))))
               (syntax-dispatch
                 syntmp-tmp-1524
                 '(any each-any any . #(each ((any . any) any)))))))
          (syntax-dispatch
            syntmp-tmp-1524
            '(any each-any . #(each ((any . any) any))))))
       syntmp-xx-1503))))

(install-global-transformer
  'define-syntax-rule
  (lambda (syntmp-x-1667)
    ((lambda (syntmp-tmp-1668)
       ((lambda (syntmp-tmp-1669)
          (if syntmp-tmp-1669
            (apply (lambda (syntmp-_-1670
                            syntmp-name-1671
                            syntmp-pattern-1672
                            syntmp-template-1673)
                     (list '#(syntax-object
                              define-syntax
                              ((top)
                               #(ribcage
                                 #(_ name pattern template)
                                 #((top) (top) (top) (top))
                                 #("i" "i" "i" "i"))
                               #(ribcage () () ())
                               #(ribcage #(x) #((top)) #("i"))))
                           syntmp-name-1671
                           (list '#(syntax-object
                                    syntax-rules
                                    ((top)
                                     #(ribcage
                                       #(_ name pattern template)
                                       #((top) (top) (top) (top))
                                       #("i" "i" "i" "i"))
                                     #(ribcage () () ())
                                     #(ribcage #(x) #((top)) #("i"))))
                                 '()
                                 (list (cons syntmp-_-1670 syntmp-pattern-1672)
                                       syntmp-template-1673))))
                   syntmp-tmp-1669)
            ((lambda (syntmp-tmp-1674)
               (if (if syntmp-tmp-1674
                     (apply (lambda (syntmp-_-1675
                                     syntmp-name-1676
                                     syntmp-pattern-1677
                                     syntmp-docstring-1678
                                     syntmp-template-1679)
                              (string?
                                (syntax-object->datum syntmp-docstring-1678)))
                            syntmp-tmp-1674)
                     #f)
                 (apply (lambda (syntmp-_-1680
                                 syntmp-name-1681
                                 syntmp-pattern-1682
                                 syntmp-docstring-1683
                                 syntmp-template-1684)
                          (list '#(syntax-object
                                   define-syntax
                                   ((top)
                                    #(ribcage
                                      #(_ name pattern docstring template)
                                      #((top) (top) (top) (top) (top))
                                      #("i" "i" "i" "i" "i"))
                                    #(ribcage () () ())
                                    #(ribcage #(x) #((top)) #("i"))))
                                syntmp-name-1681
                                (list '#(syntax-object
                                         syntax-rules
                                         ((top)
                                          #(ribcage
                                            #(_
                                              name
                                              pattern
                                              docstring
                                              template)
                                            #((top) (top) (top) (top) (top))
                                            #("i" "i" "i" "i" "i"))
                                          #(ribcage () () ())
                                          #(ribcage #(x) #((top)) #("i"))))
                                      '()
                                      syntmp-docstring-1683
                                      (list (cons syntmp-_-1680
                                                  syntmp-pattern-1682)
                                            syntmp-template-1684))))
                        syntmp-tmp-1674)
                 (syntax-error syntmp-tmp-1668)))
             (syntax-dispatch
               syntmp-tmp-1668
               '(any (any . any) any any)))))
        (syntax-dispatch
          syntmp-tmp-1668
          '(any (any . any) any))))
     syntmp-x-1667)))

(install-global-transformer
  'let*
  (lambda (syntmp-x-1703)
    ((lambda (syntmp-tmp-1704)
       ((lambda (syntmp-tmp-1705)
          (if (if syntmp-tmp-1705
                (apply (lambda (syntmp-let*-1706
                                syntmp-x-1707
                                syntmp-v-1708
                                syntmp-e1-1709
                                syntmp-e2-1710)
                         (andmap identifier? syntmp-x-1707))
                       syntmp-tmp-1705)
                #f)
            (apply (lambda (syntmp-let*-1712
                            syntmp-x-1713
                            syntmp-v-1714
                            syntmp-e1-1715
                            syntmp-e2-1716)
                     (let syntmp-f-1717 ((syntmp-bindings-1718
                                           (map list
                                                syntmp-x-1713
                                                syntmp-v-1714)))
                       (if (null? syntmp-bindings-1718)
                         (cons '#(syntax-object
                                  let
                                  ((top)
                                   #(ribcage () () ())
                                   #(ribcage
                                     #(f bindings)
                                     #((top) (top))
                                     #("i" "i"))
                                   #(ribcage
                                     #(let* x v e1 e2)
                                     #((top) (top) (top) (top) (top))
                                     #("i" "i" "i" "i" "i"))
                                   #(ribcage () () ())
                                   #(ribcage #(x) #((top)) #("i"))))
                               (cons '()
                                     (cons syntmp-e1-1715 syntmp-e2-1716)))
                         ((lambda (syntmp-tmp-1722)
                            ((lambda (syntmp-tmp-1723)
                               (if syntmp-tmp-1723
                                 (apply (lambda (syntmp-body-1724
                                                 syntmp-binding-1725)
                                          (list '#(syntax-object
                                                   let
                                                   ((top)
                                                    #(ribcage () () ())
                                                    #(ribcage
                                                      #(body binding)
                                                      #((top) (top))
                                                      #("i" "i"))
                                                    #(ribcage () () ())
                                                    #(ribcage
                                                      #(f bindings)
                                                      #((top) (top))
                                                      #("i" "i"))
                                                    #(ribcage
                                                      #(let* x v e1 e2)
                                                      #((top)
                                                        (top)
                                                        (top)
                                                        (top)
                                                        (top))
                                                      #("i" "i" "i" "i" "i"))
                                                    #(ribcage () () ())
                                                    #(ribcage
                                                      #(x)
                                                      #((top))
                                                      #("i"))))
                                                (list syntmp-binding-1725)
                                                syntmp-body-1724))
                                        syntmp-tmp-1723)
                                 (syntax-error syntmp-tmp-1722)))
                             (syntax-dispatch
                               syntmp-tmp-1722
                               '(any any))))
                          (list (syntmp-f-1717 (cdr syntmp-bindings-1718))
                                (car syntmp-bindings-1718))))))
                   syntmp-tmp-1705)
            (syntax-error syntmp-tmp-1704)))
        (syntax-dispatch
          syntmp-tmp-1704
          '(any #(each (any any)) any . each-any))))
     syntmp-x-1703)))

(install-global-transformer
  'do
  (lambda (syntmp-orig-x-1745)
    ((lambda (syntmp-tmp-1746)
       ((lambda (syntmp-tmp-1747)
          (if syntmp-tmp-1747
            (apply (lambda (syntmp-_-1748
                            syntmp-var-1749
                            syntmp-init-1750
                            syntmp-step-1751
                            syntmp-e0-1752
                            syntmp-e1-1753
                            syntmp-c-1754)
                     ((lambda (syntmp-tmp-1755)
                        ((lambda (syntmp-tmp-1756)
                           (if syntmp-tmp-1756
                             (apply (lambda (syntmp-step-1757)
                                      ((lambda (syntmp-tmp-1758)
                                         ((lambda (syntmp-tmp-1759)
                                            (if syntmp-tmp-1759
                                              (apply (lambda ()
                                                       (list '#(syntax-object
                                                                let
                                                                ((top)
                                                                 #(ribcage
                                                                   ()
                                                                   ()
                                                                   ())
                                                                 #(ribcage
                                                                   #(step)
                                                                   #((top))
                                                                   #("i"))
                                                                 #(ribcage
                                                                   #(_
                                                                     var
                                                                     init
                                                                     step
                                                                     e0
                                                                     e1
                                                                     c)
                                                                   #((top)
                                                                     (top)
                                                                     (top)
                                                                     (top)
                                                                     (top)
                                                                     (top)
                                                                     (top))
                                                                   #("i"
                                                                     "i"
                                                                     "i"
                                                                     "i"
                                                                     "i"
                                                                     "i"
                                                                     "i"))
                                                                 #(ribcage
                                                                   ()
                                                                   ()
                                                                   ())
                                                                 #(ribcage
                                                                   #(orig-x)
                                                                   #((top))
                                                                   #("i"))))
                                                             '#(syntax-object
                                                                doloop
                                                                ((top)
                                                                 #(ribcage
                                                                   ()
                                                                   ()
                                                                   ())
                                                                 #(ribcage
                                                                   #(step)
                                                                   #((top))
                                                                   #("i"))
                                                                 #(ribcage
                                                                   #(_
                                                                     var
                                                                     init
                                                                     step
                                                                     e0
                                                                     e1
                                                                     c)
                                                                   #((top)
                                                                     (top)
                                                                     (top)
                                                                     (top)
                                                                     (top)
                                                                     (top)
                                                                     (top))
                                                                   #("i"
                                                                     "i"
                                                                     "i"
                                                                     "i"
                                                                     "i"
                                                                     "i"
                                                                     "i"))
                                                                 #(ribcage
                                                                   ()
                                                                   ()
                                                                   ())
                                                                 #(ribcage
                                                                   #(orig-x)
                                                                   #((top))
                                                                   #("i"))))
                                                             (map list
                                                                  syntmp-var-1749
                                                                  syntmp-init-1750)
                                                             (list '#(syntax-object
                                                                      if
                                                                      ((top)
                                                                       #(ribcage
                                                                         ()
                                                                         ()
                                                                         ())
                                                                       #(ribcage
                                                                         #(step)
                                                                         #((top))
                                                                         #("i"))
                                                                       #(ribcage
                                                                         #(_
                                                                           var
                                                                           init
                                                                           step
                                                                           e0
                                                                           e1
                                                                           c)
                                                                         #((top)
                                                                           (top)
                                                                           (top)
                                                                           (top)
                                                                           (top)
                                                                           (top)
                                                                           (top))
                                                                         #("i"
                                                                           "i"
                                                                           "i"
                                                                           "i"
                                                                           "i"
                                                                           "i"
                                                                           "i"))
                                                                       #(ribcage
                                                                         ()
                                                                         ()
                                                                         ())
                                                                       #(ribcage
                                                                         #(orig-x)
                                                                         #((top))
                                                                         #("i"))))
                                                                   (list '#(syntax-object
                                                                            not
                                                                            ((top)
                                                                             #(ribcage
                                                                               ()
                                                                               ()
                                                                               ())
                                                                             #(ribcage
                                                                               #(step)
                                                                               #((top))
                                                                               #("i"))
                                                                             #(ribcage
                                                                               #(_
                                                                                 var
                                                                                 init
                                                                                 step
                                                                                 e0
                                                                                 e1
                                                                                 c)
                                                                               #((top)
                                                                                 (top)
                                                                                 (top)
                                                                                 (top)
                                                                                 (top)
                                                                                 (top)
                                                                                 (top))
                                                                               #("i"
                                                                                 "i"
                                                                                 "i"
                                                                                 "i"
                                                                                 "i"
                                                                                 "i"
                                                                                 "i"))
                                                                             #(ribcage
                                                                               ()
                                                                               ()
                                                                               ())
                                                                             #(ribcage
                                                                               #(orig-x)
                                                                               #((top))
                                                                               #("i"))))
                                                                         syntmp-e0-1752)
                                                                   (cons '#(syntax-object
                                                                            begin
                                                                            ((top)
                                                                             #(ribcage
                                                                               ()
                                                                               ()
                                                                               ())
                                                                             #(ribcage
                                                                               #(step)
                                                                               #((top))
                                                                               #("i"))
                                                                             #(ribcage
                                                                               #(_
                                                                                 var
                                                                                 init
                                                                                 step
                                                                                 e0
                                                                                 e1
                                                                                 c)
                                                                               #((top)
                                                                                 (top)
                                                                                 (top)
                                                                                 (top)
                                                                                 (top)
                                                                                 (top)
                                                                                 (top))
                                                                               #("i"
                                                                                 "i"
                                                                                 "i"
                                                                                 "i"
                                                                                 "i"
                                                                                 "i"
                                                                                 "i"))
                                                                             #(ribcage
                                                                               ()
                                                                               ()
                                                                               ())
                                                                             #(ribcage
                                                                               #(orig-x)
                                                                               #((top))
                                                                               #("i"))))
                                                                         (append
                                                                           syntmp-c-1754
                                                                           (list (cons '#(syntax-object
                                                                                          doloop
                                                                                          ((top)
                                                                                           #(ribcage
                                                                                             ()
                                                                                             ()
                                                                                             ())
                                                                                           #(ribcage
                                                                                             #(step)
                                                                                             #((top))
                                                                                             #("i"))
                                                                                           #(ribcage
                                                                                             #(_
                                                                                               var
                                                                                               init
                                                                                               step
                                                                                               e0
                                                                                               e1
                                                                                               c)
                                                                                             #((top)
                                                                                               (top)
                                                                                               (top)
                                                                                               (top)
                                                                                               (top)
                                                                                               (top)
                                                                                               (top))
                                                                                             #("i"
                                                                                               "i"
                                                                                               "i"
                                                                                               "i"
                                                                                               "i"
                                                                                               "i"
                                                                                               "i"))
                                                                                           #(ribcage
                                                                                             ()
                                                                                             ()
                                                                                             ())
                                                                                           #(ribcage
                                                                                             #(orig-x)
                                                                                             #((top))
                                                                                             #("i"))))
                                                                                       syntmp-step-1757)))))))
                                                     syntmp-tmp-1759)
                                              ((lambda (syntmp-tmp-1764)
                                                 (if syntmp-tmp-1764
                                                   (apply (lambda (syntmp-e1-1765
                                                                   syntmp-e2-1766)
                                                            (list '#(syntax-object
                                                                     let
                                                                     ((top)
                                                                      #(ribcage
                                                                        #(e1
                                                                          e2)
                                                                        #((top)
                                                                          (top))
                                                                        #("i"
                                                                          "i"))
                                                                      #(ribcage
                                                                        ()
                                                                        ()
                                                                        ())
                                                                      #(ribcage
                                                                        #(step)
                                                                        #((top))
                                                                        #("i"))
                                                                      #(ribcage
                                                                        #(_
                                                                          var
                                                                          init
                                                                          step
                                                                          e0
                                                                          e1
                                                                          c)
                                                                        #((top)
                                                                          (top)
                                                                          (top)
                                                                          (top)
                                                                          (top)
                                                                          (top)
                                                                          (top))
                                                                        #("i"
                                                                          "i"
                                                                          "i"
                                                                          "i"
                                                                          "i"
                                                                          "i"
                                                                          "i"))
                                                                      #(ribcage
                                                                        ()
                                                                        ()
                                                                        ())
                                                                      #(ribcage
                                                                        #(orig-x)
                                                                        #((top))
                                                                        #("i"))))
                                                                  '#(syntax-object
                                                                     doloop
                                                                     ((top)
                                                                      #(ribcage
                                                                        #(e1
                                                                          e2)
                                                                        #((top)
                                                                          (top))
                                                                        #("i"
                                                                          "i"))
                                                                      #(ribcage
                                                                        ()
                                                                        ()
                                                                        ())
                                                                      #(ribcage
                                                                        #(step)
                                                                        #((top))
                                                                        #("i"))
                                                                      #(ribcage
                                                                        #(_
                                                                          var
                                                                          init
                                                                          step
                                                                          e0
                                                                          e1
                                                                          c)
                                                                        #((top)
                                                                          (top)
                                                                          (top)
                                                                          (top)
                                                                          (top)
                                                                          (top)
                                                                          (top))
                                                                        #("i"
                                                                          "i"
                                                                          "i"
                                                                          "i"
                                                                          "i"
                                                                          "i"
                                                                          "i"))
                                                                      #(ribcage
                                                                        ()
                                                                        ()
                                                                        ())
                                                                      #(ribcage
                                                                        #(orig-x)
                                                                        #((top))
                                                                        #("i"))))
                                                                  (map list
                                                                       syntmp-var-1749
                                                                       syntmp-init-1750)
                                                                  (list '#(syntax-object
                                                                           if
                                                                           ((top)
                                                                            #(ribcage
                                                                              #(e1
                                                                                e2)
                                                                              #((top)
                                                                                (top))
                                                                              #("i"
                                                                                "i"))
                                                                            #(ribcage
                                                                              ()
                                                                              ()
                                                                              ())
                                                                            #(ribcage
                                                                              #(step)
                                                                              #((top))
                                                                              #("i"))
                                                                            #(ribcage
                                                                              #(_
                                                                                var
                                                                                init
                                                                                step
                                                                                e0
                                                                                e1
                                                                                c)
                                                                              #((top)
                                                                                (top)
                                                                                (top)
                                                                                (top)
                                                                                (top)
                                                                                (top)
                                                                                (top))
                                                                              #("i"
                                                                                "i"
                                                                                "i"
                                                                                "i"
                                                                                "i"
                                                                                "i"
                                                                                "i"))
                                                                            #(ribcage
                                                                              ()
                                                                              ()
                                                                              ())
                                                                            #(ribcage
                                                                              #(orig-x)
                                                                              #((top))
                                                                              #("i"))))
                                                                        syntmp-e0-1752
                                                                        (cons '#(syntax-object
                                                                                 begin
                                                                                 ((top)
                                                                                  #(ribcage
                                                                                    #(e1
                                                                                      e2)
                                                                                    #((top)
                                                                                      (top))
                                                                                    #("i"
                                                                                      "i"))
                                                                                  #(ribcage
                                                                                    ()
                                                                                    ()
                                                                                    ())
                                                                                  #(ribcage
                                                                                    #(step)
                                                                                    #((top))
                                                                                    #("i"))
                                                                                  #(ribcage
                                                                                    #(_
                                                                                      var
                                                                                      init
                                                                                      step
                                                                                      e0
                                                                                      e1
                                                                                      c)
                                                                                    #((top)
                                                                                      (top)
                                                                                      (top)
                                                                                      (top)
                                                                                      (top)
                                                                                      (top)
                                                                                      (top))
                                                                                    #("i"
                                                                                      "i"
                                                                                      "i"
                                                                                      "i"
                                                                                      "i"
                                                                                      "i"
                                                                                      "i"))
                                                                                  #(ribcage
                                                                                    ()
                                                                                    ()
                                                                                    ())
                                                                                  #(ribcage
                                                                                    #(orig-x)
                                                                                    #((top))
                                                                                    #("i"))))
                                                                              (cons syntmp-e1-1765
                                                                                    syntmp-e2-1766))
                                                                        (cons '#(syntax-object
                                                                                 begin
                                                                                 ((top)
                                                                                  #(ribcage
                                                                                    #(e1
                                                                                      e2)
                                                                                    #((top)
                                                                                      (top))
                                                                                    #("i"
                                                                                      "i"))
                                                                                  #(ribcage
                                                                                    ()
                                                                                    ()
                                                                                    ())
                                                                                  #(ribcage
                                                                                    #(step)
                                                                                    #((top))
                                                                                    #("i"))
                                                                                  #(ribcage
                                                                                    #(_
                                                                                      var
                                                                                      init
                                                                                      step
                                                                                      e0
                                                                                      e1
                                                                                      c)
                                                                                    #((top)
                                                                                      (top)
                                                                                      (top)
                                                                                      (top)
                                                                                      (top)
                                                                                      (top)
                                                                                      (top))
                                                                                    #("i"
                                                                                      "i"
                                                                                      "i"
                                                                                      "i"
                                                                                      "i"
                                                                                      "i"
                                                                                      "i"))
                                                                                  #(ribcage
                                                                                    ()
                                                                                    ()
                                                                                    ())
                                                                                  #(ribcage
                                                                                    #(orig-x)
                                                                                    #((top))
                                                                                    #("i"))))
                                                                              (append
                                                                                syntmp-c-1754
                                                                                (list (cons '#(syntax-object
                                                                                               doloop
                                                                                               ((top)
                                                                                                #(ribcage
                                                                                                  #(e1
                                                                                                    e2)
                                                                                                  #((top)
                                                                                                    (top))
                                                                                                  #("i"
                                                                                                    "i"))
                                                                                                #(ribcage
                                                                                                  ()
                                                                                                  ()
                                                                                                  ())
                                                                                                #(ribcage
                                                                                                  #(step)
                                                                                                  #((top))
                                                                                                  #("i"))
                                                                                                #(ribcage
                                                                                                  #(_
                                                                                                    var
                                                                                                    init
                                                                                                    step
                                                                                                    e0
                                                                                                    e1
                                                                                                    c)
                                                                                                  #((top)
                                                                                                    (top)
                                                                                                    (top)
                                                                                                    (top)
                                                                                                    (top)
                                                                                                    (top)
                                                                                                    (top))
                                                                                                  #("i"
                                                                                                    "i"
                                                                                                    "i"
                                                                                                    "i"
                                                                                                    "i"
                                                                                                    "i"
                                                                                                    "i"))
                                                                                                #(ribcage
                                                                                                  ()
                                                                                                  ()
                                                                                                  ())
                                                                                                #(ribcage
                                                                                                  #(orig-x)
                                                                                                  #((top))
                                                                                                  #("i"))))
                                                                                            syntmp-step-1757)))))))
                                                          syntmp-tmp-1764)
                                                   (syntax-error
                                                     syntmp-tmp-1758)))
                                               (syntax-dispatch
                                                 syntmp-tmp-1758
                                                 '(any . each-any)))))
                                          (syntax-dispatch
                                            syntmp-tmp-1758
                                            '())))
                                       syntmp-e1-1753))
                                    syntmp-tmp-1756)
                             (syntax-error syntmp-tmp-1755)))
                         (syntax-dispatch
                           syntmp-tmp-1755
                           'each-any)))
                      (map (lambda (syntmp-v-1773 syntmp-s-1774)
                             ((lambda (syntmp-tmp-1775)
                                ((lambda (syntmp-tmp-1776)
                                   (if syntmp-tmp-1776
                                     (apply (lambda () syntmp-v-1773)
                                            syntmp-tmp-1776)
                                     ((lambda (syntmp-tmp-1777)
                                        (if syntmp-tmp-1777
                                          (apply (lambda (syntmp-e-1778)
                                                   syntmp-e-1778)
                                                 syntmp-tmp-1777)
                                          ((lambda (syntmp-_-1779)
                                             (syntax-error syntmp-orig-x-1745))
                                           syntmp-tmp-1775)))
                                      (syntax-dispatch
                                        syntmp-tmp-1775
                                        '(any)))))
                                 (syntax-dispatch syntmp-tmp-1775 (quote ()))))
                              syntmp-s-1774))
                           syntmp-var-1749
                           syntmp-step-1751)))
                   syntmp-tmp-1747)
            (syntax-error syntmp-tmp-1746)))
        (syntax-dispatch
          syntmp-tmp-1746
          '(any #(each (any any . any))
                (any . each-any)
                .
                each-any))))
     syntmp-orig-x-1745)))

(install-global-transformer
  'quasiquote
  (letrec ((syntmp-quasicons-1807
             (lambda (syntmp-x-1811 syntmp-y-1812)
               ((lambda (syntmp-tmp-1813)
                  ((lambda (syntmp-tmp-1814)
                     (if syntmp-tmp-1814
                       (apply (lambda (syntmp-x-1815 syntmp-y-1816)
                                ((lambda (syntmp-tmp-1817)
                                   ((lambda (syntmp-tmp-1818)
                                      (if syntmp-tmp-1818
                                        (apply (lambda (syntmp-dy-1819)
                                                 ((lambda (syntmp-tmp-1820)
                                                    ((lambda (syntmp-tmp-1821)
                                                       (if syntmp-tmp-1821
                                                         (apply (lambda (syntmp-dx-1822)
                                                                  (list '#(syntax-object
                                                                           quote
                                                                           ((top)
                                                                            #(ribcage
                                                                              #(dx)
                                                                              #((top))
                                                                              #("i"))
                                                                            #(ribcage
                                                                              #(dy)
                                                                              #((top))
                                                                              #("i"))
                                                                            #(ribcage
                                                                              ()
                                                                              ()
                                                                              ())
                                                                            #(ribcage
                                                                              #(x
                                                                                y)
                                                                              #((top)
                                                                                (top))
                                                                              #("i"
                                                                                "i"))
                                                                            #(ribcage
                                                                              ()
                                                                              ()
                                                                              ())
                                                                            #(ribcage
                                                                              ()
                                                                              ()
                                                                              ())
                                                                            #(ribcage
                                                                              #(x
                                                                                y)
                                                                              #((top)
                                                                                (top))
                                                                              #("i"
                                                                                "i"))
                                                                            #(ribcage
                                                                              #(quasicons
                                                                                quasiappend
                                                                                quasivector
                                                                                quasi)
                                                                              #((top)
                                                                                (top)
                                                                                (top)
                                                                                (top))
                                                                              #("i"
                                                                                "i"
                                                                                "i"
                                                                                "i"))))
                                                                        (cons syntmp-dx-1822
                                                                              syntmp-dy-1819)))
                                                                syntmp-tmp-1821)
                                                         ((lambda (syntmp-_-1823)
                                                            (if (null? syntmp-dy-1819)
                                                              (list '#(syntax-object
                                                                       list
                                                                       ((top)
                                                                        #(ribcage
                                                                          #(_)
                                                                          #((top))
                                                                          #("i"))
                                                                        #(ribcage
                                                                          #(dy)
                                                                          #((top))
                                                                          #("i"))
                                                                        #(ribcage
                                                                          ()
                                                                          ()
                                                                          ())
                                                                        #(ribcage
                                                                          #(x
                                                                            y)
                                                                          #((top)
                                                                            (top))
                                                                          #("i"
                                                                            "i"))
                                                                        #(ribcage
                                                                          ()
                                                                          ()
                                                                          ())
                                                                        #(ribcage
                                                                          ()
                                                                          ()
                                                                          ())
                                                                        #(ribcage
                                                                          #(x
                                                                            y)
                                                                          #((top)
                                                                            (top))
                                                                          #("i"
                                                                            "i"))
                                                                        #(ribcage
                                                                          #(quasicons
                                                                            quasiappend
                                                                            quasivector
                                                                            quasi)
                                                                          #((top)
                                                                            (top)
                                                                            (top)
                                                                            (top))
                                                                          #("i"
                                                                            "i"
                                                                            "i"
                                                                            "i"))))
                                                                    syntmp-x-1815)
                                                              (list '#(syntax-object
                                                                       cons
                                                                       ((top)
                                                                        #(ribcage
                                                                          #(_)
                                                                          #((top))
                                                                          #("i"))
                                                                        #(ribcage
                                                                          #(dy)
                                                                          #((top))
                                                                          #("i"))
                                                                        #(ribcage
                                                                          ()
                                                                          ()
                                                                          ())
                                                                        #(ribcage
                                                                          #(x
                                                                            y)
                                                                          #((top)
                                                                            (top))
                                                                          #("i"
                                                                            "i"))
                                                                        #(ribcage
                                                                          ()
                                                                          ()
                                                                          ())
                                                                        #(ribcage
                                                                          ()
                                                                          ()
                                                                          ())
                                                                        #(ribcage
                                                                          #(x
                                                                            y)
                                                                          #((top)
                                                                            (top))
                                                                          #("i"
                                                                            "i"))
                                                                        #(ribcage
                                                                          #(quasicons
                                                                            quasiappend
                                                                            quasivector
                                                                            quasi)
                                                                          #((top)
                                                                            (top)
                                                                            (top)
                                                                            (top))
                                                                          #("i"
                                                                            "i"
                                                                            "i"
                                                                            "i"))))
                                                                    syntmp-x-1815
                                                                    syntmp-y-1816)))
                                                          syntmp-tmp-1820)))
                                                     (syntax-dispatch
                                                       syntmp-tmp-1820
                                                       '(#(free-id
                                                           #(syntax-object
                                                             quote
                                                             ((top)
                                                              #(ribcage
                                                                #(dy)
                                                                #((top))
                                                                #("i"))
                                                              #(ribcage
                                                                ()
                                                                ()
                                                                ())
                                                              #(ribcage
                                                                #(x y)
                                                                #((top) (top))
                                                                #("i" "i"))
                                                              #(ribcage
                                                                ()
                                                                ()
                                                                ())
                                                              #(ribcage
                                                                ()
                                                                ()
                                                                ())
                                                              #(ribcage
                                                                #(x y)
                                                                #((top) (top))
                                                                #("i" "i"))
                                                              #(ribcage
                                                                #(quasicons
                                                                  quasiappend
                                                                  quasivector
                                                                  quasi)
                                                                #((top)
                                                                  (top)
                                                                  (top)
                                                                  (top))
                                                                #("i"
                                                                  "i"
                                                                  "i"
                                                                  "i")))))
                                                         any))))
                                                  syntmp-x-1815))
                                               syntmp-tmp-1818)
                                        ((lambda (syntmp-tmp-1824)
                                           (if syntmp-tmp-1824
                                             (apply (lambda (syntmp-stuff-1825)
                                                      (cons '#(syntax-object
                                                               list
                                                               ((top)
                                                                #(ribcage
                                                                  #(stuff)
                                                                  #((top))
                                                                  #("i"))
                                                                #(ribcage
                                                                  ()
                                                                  ()
                                                                  ())
                                                                #(ribcage
                                                                  #(x y)
                                                                  #((top)
                                                                    (top))
                                                                  #("i" "i"))
                                                                #(ribcage
                                                                  ()
                                                                  ()
                                                                  ())
                                                                #(ribcage
                                                                  ()
                                                                  ()
                                                                  ())
                                                                #(ribcage
                                                                  #(x y)
                                                                  #((top)
                                                                    (top))
                                                                  #("i" "i"))
                                                                #(ribcage
                                                                  #(quasicons
                                                                    quasiappend
                                                                    quasivector
                                                                    quasi)
                                                                  #((top)
                                                                    (top)
                                                                    (top)
                                                                    (top))
                                                                  #("i"
                                                                    "i"
                                                                    "i"
                                                                    "i"))))
                                                            (cons syntmp-x-1815
                                                                  syntmp-stuff-1825)))
                                                    syntmp-tmp-1824)
                                             ((lambda (syntmp-else-1826)
                                                (list '#(syntax-object
                                                         cons
                                                         ((top)
                                                          #(ribcage
                                                            #(else)
                                                            #((top))
                                                            #("i"))
                                                          #(ribcage () () ())
                                                          #(ribcage
                                                            #(x y)
                                                            #((top) (top))
                                                            #("i" "i"))
                                                          #(ribcage () () ())
                                                          #(ribcage () () ())
                                                          #(ribcage
                                                            #(x y)
                                                            #((top) (top))
                                                            #("i" "i"))
                                                          #(ribcage
                                                            #(quasicons
                                                              quasiappend
                                                              quasivector
                                                              quasi)
                                                            #((top)
                                                              (top)
                                                              (top)
                                                              (top))
                                                            #("i"
                                                              "i"
                                                              "i"
                                                              "i"))))
                                                      syntmp-x-1815
                                                      syntmp-y-1816))
                                              syntmp-tmp-1817)))
                                         (syntax-dispatch
                                           syntmp-tmp-1817
                                           '(#(free-id
                                               #(syntax-object
                                                 list
                                                 ((top)
                                                  #(ribcage () () ())
                                                  #(ribcage
                                                    #(x y)
                                                    #((top) (top))
                                                    #("i" "i"))
                                                  #(ribcage () () ())
                                                  #(ribcage () () ())
                                                  #(ribcage
                                                    #(x y)
                                                    #((top) (top))
                                                    #("i" "i"))
                                                  #(ribcage
                                                    #(quasicons
                                                      quasiappend
                                                      quasivector
                                                      quasi)
                                                    #((top) (top) (top) (top))
                                                    #("i" "i" "i" "i")))))
                                             .
                                             any)))))
                                    (syntax-dispatch
                                      syntmp-tmp-1817
                                      '(#(free-id
                                          #(syntax-object
                                            quote
                                            ((top)
                                             #(ribcage () () ())
                                             #(ribcage
                                               #(x y)
                                               #((top) (top))
                                               #("i" "i"))
                                             #(ribcage () () ())
                                             #(ribcage () () ())
                                             #(ribcage
                                               #(x y)
                                               #((top) (top))
                                               #("i" "i"))
                                             #(ribcage
                                               #(quasicons
                                                 quasiappend
                                                 quasivector
                                                 quasi)
                                               #((top) (top) (top) (top))
                                               #("i" "i" "i" "i")))))
                                        any))))
                                 syntmp-y-1816))
                              syntmp-tmp-1814)
                       (syntax-error syntmp-tmp-1813)))
                   (syntax-dispatch
                     syntmp-tmp-1813
                     '(any any))))
                (list syntmp-x-1811 syntmp-y-1812))))
           (syntmp-quasiappend-1808
             (lambda (syntmp-x-1827 syntmp-y-1828)
               ((lambda (syntmp-tmp-1829)
                  ((lambda (syntmp-tmp-1830)
                     (if syntmp-tmp-1830
                       (apply (lambda (syntmp-x-1831 syntmp-y-1832)
                                ((lambda (syntmp-tmp-1833)
                                   ((lambda (syntmp-tmp-1834)
                                      (if syntmp-tmp-1834
                                        (apply (lambda () syntmp-x-1831)
                                               syntmp-tmp-1834)
                                        ((lambda (syntmp-_-1835)
                                           (list '#(syntax-object
                                                    append
                                                    ((top)
                                                     #(ribcage
                                                       #(_)
                                                       #((top))
                                                       #("i"))
                                                     #(ribcage () () ())
                                                     #(ribcage
                                                       #(x y)
                                                       #((top) (top))
                                                       #("i" "i"))
                                                     #(ribcage () () ())
                                                     #(ribcage () () ())
                                                     #(ribcage
                                                       #(x y)
                                                       #((top) (top))
                                                       #("i" "i"))
                                                     #(ribcage
                                                       #(quasicons
                                                         quasiappend
                                                         quasivector
                                                         quasi)
                                                       #((top)
                                                         (top)
                                                         (top)
                                                         (top))
                                                       #("i" "i" "i" "i"))))
                                                 syntmp-x-1831
                                                 syntmp-y-1832))
                                         syntmp-tmp-1833)))
                                    (syntax-dispatch
                                      syntmp-tmp-1833
                                      '(#(free-id
                                          #(syntax-object
                                            quote
                                            ((top)
                                             #(ribcage () () ())
                                             #(ribcage
                                               #(x y)
                                               #((top) (top))
                                               #("i" "i"))
                                             #(ribcage () () ())
                                             #(ribcage () () ())
                                             #(ribcage
                                               #(x y)
                                               #((top) (top))
                                               #("i" "i"))
                                             #(ribcage
                                               #(quasicons
                                                 quasiappend
                                                 quasivector
                                                 quasi)
                                               #((top) (top) (top) (top))
                                               #("i" "i" "i" "i")))))
                                        ()))))
                                 syntmp-y-1832))
                              syntmp-tmp-1830)
                       (syntax-error syntmp-tmp-1829)))
                   (syntax-dispatch
                     syntmp-tmp-1829
                     '(any any))))
                (list syntmp-x-1827 syntmp-y-1828))))
           (syntmp-quasivector-1809
             (lambda (syntmp-x-1836)
               ((lambda (syntmp-tmp-1837)
                  ((lambda (syntmp-x-1838)
                     ((lambda (syntmp-tmp-1839)
                        ((lambda (syntmp-tmp-1840)
                           (if syntmp-tmp-1840
                             (apply (lambda (syntmp-x-1841)
                                      (list '#(syntax-object
                                               quote
                                               ((top)
                                                #(ribcage #(x) #((top)) #("i"))
                                                #(ribcage () () ())
                                                #(ribcage #(x) #((top)) #("i"))
                                                #(ribcage () () ())
                                                #(ribcage () () ())
                                                #(ribcage #(x) #((top)) #("i"))
                                                #(ribcage
                                                  #(quasicons
                                                    quasiappend
                                                    quasivector
                                                    quasi)
                                                  #((top) (top) (top) (top))
                                                  #("i" "i" "i" "i"))))
                                            (list->vector syntmp-x-1841)))
                                    syntmp-tmp-1840)
                             ((lambda (syntmp-tmp-1843)
                                (if syntmp-tmp-1843
                                  (apply (lambda (syntmp-x-1844)
                                           (cons '#(syntax-object
                                                    vector
                                                    ((top)
                                                     #(ribcage
                                                       #(x)
                                                       #((top))
                                                       #("i"))
                                                     #(ribcage () () ())
                                                     #(ribcage
                                                       #(x)
                                                       #((top))
                                                       #("i"))
                                                     #(ribcage () () ())
                                                     #(ribcage () () ())
                                                     #(ribcage
                                                       #(x)
                                                       #((top))
                                                       #("i"))
                                                     #(ribcage
                                                       #(quasicons
                                                         quasiappend
                                                         quasivector
                                                         quasi)
                                                       #((top)
                                                         (top)
                                                         (top)
                                                         (top))
                                                       #("i" "i" "i" "i"))))
                                                 syntmp-x-1844))
                                         syntmp-tmp-1843)
                                  ((lambda (syntmp-_-1846)
                                     (list '#(syntax-object
                                              list->vector
                                              ((top)
                                               #(ribcage #(_) #((top)) #("i"))
                                               #(ribcage () () ())
                                               #(ribcage #(x) #((top)) #("i"))
                                               #(ribcage () () ())
                                               #(ribcage () () ())
                                               #(ribcage #(x) #((top)) #("i"))
                                               #(ribcage
                                                 #(quasicons
                                                   quasiappend
                                                   quasivector
                                                   quasi)
                                                 #((top) (top) (top) (top))
                                                 #("i" "i" "i" "i"))))
                                           syntmp-x-1838))
                                   syntmp-tmp-1839)))
                              (syntax-dispatch
                                syntmp-tmp-1839
                                '(#(free-id
                                    #(syntax-object
                                      list
                                      ((top)
                                       #(ribcage () () ())
                                       #(ribcage #(x) #((top)) #("i"))
                                       #(ribcage () () ())
                                       #(ribcage () () ())
                                       #(ribcage #(x) #((top)) #("i"))
                                       #(ribcage
                                         #(quasicons
                                           quasiappend
                                           quasivector
                                           quasi)
                                         #((top) (top) (top) (top))
                                         #("i" "i" "i" "i")))))
                                  .
                                  each-any)))))
                         (syntax-dispatch
                           syntmp-tmp-1839
                           '(#(free-id
                               #(syntax-object
                                 quote
                                 ((top)
                                  #(ribcage () () ())
                                  #(ribcage #(x) #((top)) #("i"))
                                  #(ribcage () () ())
                                  #(ribcage () () ())
                                  #(ribcage #(x) #((top)) #("i"))
                                  #(ribcage
                                    #(quasicons quasiappend quasivector quasi)
                                    #((top) (top) (top) (top))
                                    #("i" "i" "i" "i")))))
                             each-any))))
                      syntmp-x-1838))
                   syntmp-tmp-1837))
                syntmp-x-1836)))
           (syntmp-quasi-1810
             (lambda (syntmp-p-1847 syntmp-lev-1848)
               ((lambda (syntmp-tmp-1849)
                  ((lambda (syntmp-tmp-1850)
                     (if syntmp-tmp-1850
                       (apply (lambda (syntmp-p-1851)
                                (if (= syntmp-lev-1848 0)
                                  syntmp-p-1851
                                  (syntmp-quasicons-1807
                                    '(#(syntax-object
                                        quote
                                        ((top)
                                         #(ribcage #(p) #((top)) #("i"))
                                         #(ribcage () () ())
                                         #(ribcage
                                           #(p lev)
                                           #((top) (top))
                                           #("i" "i"))
                                         #(ribcage
                                           #(quasicons
                                             quasiappend
                                             quasivector
                                             quasi)
                                           #((top) (top) (top) (top))
                                           #("i" "i" "i" "i"))))
                                      #(syntax-object
                                        unquote
                                        ((top)
                                         #(ribcage #(p) #((top)) #("i"))
                                         #(ribcage () () ())
                                         #(ribcage
                                           #(p lev)
                                           #((top) (top))
                                           #("i" "i"))
                                         #(ribcage
                                           #(quasicons
                                             quasiappend
                                             quasivector
                                             quasi)
                                           #((top) (top) (top) (top))
                                           #("i" "i" "i" "i")))))
                                    (syntmp-quasi-1810
                                      (list syntmp-p-1851)
                                      (- syntmp-lev-1848 1)))))
                              syntmp-tmp-1850)
                       ((lambda (syntmp-tmp-1852)
                          (if syntmp-tmp-1852
                            (apply (lambda (syntmp-p-1853 syntmp-q-1854)
                                     (if (= syntmp-lev-1848 0)
                                       (syntmp-quasiappend-1808
                                         syntmp-p-1853
                                         (syntmp-quasi-1810
                                           syntmp-q-1854
                                           syntmp-lev-1848))
                                       (syntmp-quasicons-1807
                                         (syntmp-quasicons-1807
                                           '(#(syntax-object
                                               quote
                                               ((top)
                                                #(ribcage
                                                  #(p q)
                                                  #((top) (top))
                                                  #("i" "i"))
                                                #(ribcage () () ())
                                                #(ribcage
                                                  #(p lev)
                                                  #((top) (top))
                                                  #("i" "i"))
                                                #(ribcage
                                                  #(quasicons
                                                    quasiappend
                                                    quasivector
                                                    quasi)
                                                  #((top) (top) (top) (top))
                                                  #("i" "i" "i" "i"))))
                                             #(syntax-object
                                               unquote-splicing
                                               ((top)
                                                #(ribcage
                                                  #(p q)
                                                  #((top) (top))
                                                  #("i" "i"))
                                                #(ribcage () () ())
                                                #(ribcage
                                                  #(p lev)
                                                  #((top) (top))
                                                  #("i" "i"))
                                                #(ribcage
                                                  #(quasicons
                                                    quasiappend
                                                    quasivector
                                                    quasi)
                                                  #((top) (top) (top) (top))
                                                  #("i" "i" "i" "i")))))
                                           (syntmp-quasi-1810
                                             (list syntmp-p-1853)
                                             (- syntmp-lev-1848 1)))
                                         (syntmp-quasi-1810
                                           syntmp-q-1854
                                           syntmp-lev-1848))))
                                   syntmp-tmp-1852)
                            ((lambda (syntmp-tmp-1855)
                               (if syntmp-tmp-1855
                                 (apply (lambda (syntmp-p-1856)
                                          (syntmp-quasicons-1807
                                            '(#(syntax-object
                                                quote
                                                ((top)
                                                 #(ribcage
                                                   #(p)
                                                   #((top))
                                                   #("i"))
                                                 #(ribcage () () ())
                                                 #(ribcage
                                                   #(p lev)
                                                   #((top) (top))
                                                   #("i" "i"))
                                                 #(ribcage
                                                   #(quasicons
                                                     quasiappend
                                                     quasivector
                                                     quasi)
                                                   #((top) (top) (top) (top))
                                                   #("i" "i" "i" "i"))))
                                              #(syntax-object
                                                quasiquote
                                                ((top)
                                                 #(ribcage
                                                   #(p)
                                                   #((top))
                                                   #("i"))
                                                 #(ribcage () () ())
                                                 #(ribcage
                                                   #(p lev)
                                                   #((top) (top))
                                                   #("i" "i"))
                                                 #(ribcage
                                                   #(quasicons
                                                     quasiappend
                                                     quasivector
                                                     quasi)
                                                   #((top) (top) (top) (top))
                                                   #("i" "i" "i" "i")))))
                                            (syntmp-quasi-1810
                                              (list syntmp-p-1856)
                                              (+ syntmp-lev-1848 1))))
                                        syntmp-tmp-1855)
                                 ((lambda (syntmp-tmp-1857)
                                    (if syntmp-tmp-1857
                                      (apply (lambda (syntmp-p-1858
                                                      syntmp-q-1859)
                                               (syntmp-quasicons-1807
                                                 (syntmp-quasi-1810
                                                   syntmp-p-1858
                                                   syntmp-lev-1848)
                                                 (syntmp-quasi-1810
                                                   syntmp-q-1859
                                                   syntmp-lev-1848)))
                                             syntmp-tmp-1857)
                                      ((lambda (syntmp-tmp-1860)
                                         (if syntmp-tmp-1860
                                           (apply (lambda (syntmp-x-1861)
                                                    (syntmp-quasivector-1809
                                                      (syntmp-quasi-1810
                                                        syntmp-x-1861
                                                        syntmp-lev-1848)))
                                                  syntmp-tmp-1860)
                                           ((lambda (syntmp-p-1863)
                                              (list '#(syntax-object
                                                       quote
                                                       ((top)
                                                        #(ribcage
                                                          #(p)
                                                          #((top))
                                                          #("i"))
                                                        #(ribcage () () ())
                                                        #(ribcage
                                                          #(p lev)
                                                          #((top) (top))
                                                          #("i" "i"))
                                                        #(ribcage
                                                          #(quasicons
                                                            quasiappend
                                                            quasivector
                                                            quasi)
                                                          #((top)
                                                            (top)
                                                            (top)
                                                            (top))
                                                          #("i" "i" "i" "i"))))
                                                    syntmp-p-1863))
                                            syntmp-tmp-1849)))
                                       (syntax-dispatch
                                         syntmp-tmp-1849
                                         '#(vector each-any)))))
                                  (syntax-dispatch
                                    syntmp-tmp-1849
                                    '(any . any)))))
                             (syntax-dispatch
                               syntmp-tmp-1849
                               '(#(free-id
                                   #(syntax-object
                                     quasiquote
                                     ((top)
                                      #(ribcage () () ())
                                      #(ribcage
                                        #(p lev)
                                        #((top) (top))
                                        #("i" "i"))
                                      #(ribcage
                                        #(quasicons
                                          quasiappend
                                          quasivector
                                          quasi)
                                        #((top) (top) (top) (top))
                                        #("i" "i" "i" "i")))))
                                 any)))))
                        (syntax-dispatch
                          syntmp-tmp-1849
                          '((#(free-id
                               #(syntax-object
                                 unquote-splicing
                                 ((top)
                                  #(ribcage () () ())
                                  #(ribcage #(p lev) #((top) (top)) #("i" "i"))
                                  #(ribcage
                                    #(quasicons quasiappend quasivector quasi)
                                    #((top) (top) (top) (top))
                                    #("i" "i" "i" "i")))))
                             any)
                            .
                            any)))))
                   (syntax-dispatch
                     syntmp-tmp-1849
                     '(#(free-id
                         #(syntax-object
                           unquote
                           ((top)
                            #(ribcage () () ())
                            #(ribcage #(p lev) #((top) (top)) #("i" "i"))
                            #(ribcage
                              #(quasicons quasiappend quasivector quasi)
                              #((top) (top) (top) (top))
                              #("i" "i" "i" "i")))))
                       any))))
                syntmp-p-1847))))
    (lambda (syntmp-x-1864)
      ((lambda (syntmp-tmp-1865)
         ((lambda (syntmp-tmp-1866)
            (if syntmp-tmp-1866
              (apply (lambda (syntmp-_-1867 syntmp-e-1868)
                       (syntmp-quasi-1810 syntmp-e-1868 0))
                     syntmp-tmp-1866)
              (syntax-error syntmp-tmp-1865)))
          (syntax-dispatch
            syntmp-tmp-1865
            '(any any))))
       syntmp-x-1864))))

(install-global-transformer
  'include
  (lambda (syntmp-x-1928)
    (letrec ((syntmp-read-file-1929
               (lambda (syntmp-fn-1930 syntmp-k-1931)
                 (let ((syntmp-p-1932 (open-input-file syntmp-fn-1930)))
                   (let syntmp-f-1933 ((syntmp-x-1934 (read syntmp-p-1932)))
                     (if (eof-object? syntmp-x-1934)
                       (begin
                         (close-input-port syntmp-p-1932)
                         '())
                       (cons (datum->syntax-object
                               syntmp-k-1931
                               syntmp-x-1934)
                             (syntmp-f-1933 (read syntmp-p-1932)))))))))
      ((lambda (syntmp-tmp-1935)
         ((lambda (syntmp-tmp-1936)
            (if syntmp-tmp-1936
              (apply (lambda (syntmp-k-1937 syntmp-filename-1938)
                       (let ((syntmp-fn-1939
                               (syntax-object->datum syntmp-filename-1938)))
                         ((lambda (syntmp-tmp-1940)
                            ((lambda (syntmp-tmp-1941)
                               (if syntmp-tmp-1941
                                 (apply (lambda (syntmp-exp-1942)
                                          (cons '#(syntax-object
                                                   begin
                                                   ((top)
                                                    #(ribcage () () ())
                                                    #(ribcage
                                                      #(exp)
                                                      #((top))
                                                      #("i"))
                                                    #(ribcage () () ())
                                                    #(ribcage () () ())
                                                    #(ribcage
                                                      #(fn)
                                                      #((top))
                                                      #("i"))
                                                    #(ribcage
                                                      #(k filename)
                                                      #((top) (top))
                                                      #("i" "i"))
                                                    #(ribcage
                                                      (read-file)
                                                      ((top))
                                                      ("i"))
                                                    #(ribcage
                                                      #(x)
                                                      #((top))
                                                      #("i"))))
                                                syntmp-exp-1942))
                                        syntmp-tmp-1941)
                                 (syntax-error syntmp-tmp-1940)))
                             (syntax-dispatch
                               syntmp-tmp-1940
                               'each-any)))
                          (syntmp-read-file-1929
                            syntmp-fn-1939
                            syntmp-k-1937))))
                     syntmp-tmp-1936)
              (syntax-error syntmp-tmp-1935)))
          (syntax-dispatch
            syntmp-tmp-1935
            '(any any))))
       syntmp-x-1928))))

(install-global-transformer
  'unquote
  (lambda (syntmp-x-1959)
    ((lambda (syntmp-tmp-1960)
       ((lambda (syntmp-tmp-1961)
          (if syntmp-tmp-1961
            (apply (lambda (syntmp-_-1962 syntmp-e-1963)
                     (error 'unquote
                            "expression ,~s not valid outside of quasiquote"
                            (syntax-object->datum syntmp-e-1963)))
                   syntmp-tmp-1961)
            (syntax-error syntmp-tmp-1960)))
        (syntax-dispatch
          syntmp-tmp-1960
          '(any any))))
     syntmp-x-1959)))

(install-global-transformer
  'unquote-splicing
  (lambda (syntmp-x-1969)
    ((lambda (syntmp-tmp-1970)
       ((lambda (syntmp-tmp-1971)
          (if syntmp-tmp-1971
            (apply (lambda (syntmp-_-1972 syntmp-e-1973)
                     (error 'unquote-splicing
                            "expression ,@~s not valid outside of quasiquote"
                            (syntax-object->datum syntmp-e-1973)))
                   syntmp-tmp-1971)
            (syntax-error syntmp-tmp-1970)))
        (syntax-dispatch
          syntmp-tmp-1970
          '(any any))))
     syntmp-x-1969)))

(install-global-transformer
  'case
  (lambda (syntmp-x-1979)
    ((lambda (syntmp-tmp-1980)
       ((lambda (syntmp-tmp-1981)
          (if syntmp-tmp-1981
            (apply (lambda (syntmp-_-1982
                            syntmp-e-1983
                            syntmp-m1-1984
                            syntmp-m2-1985)
                     ((lambda (syntmp-tmp-1986)
                        ((lambda (syntmp-body-1987)
                           (list '#(syntax-object
                                    let
                                    ((top)
                                     #(ribcage () () ())
                                     #(ribcage #(body) #((top)) #("i"))
                                     #(ribcage
                                       #(_ e m1 m2)
                                       #((top) (top) (top) (top))
                                       #("i" "i" "i" "i"))
                                     #(ribcage () () ())
                                     #(ribcage #(x) #((top)) #("i"))))
                                 (list (list '#(syntax-object
                                                t
                                                ((top)
                                                 #(ribcage () () ())
                                                 #(ribcage
                                                   #(body)
                                                   #((top))
                                                   #("i"))
                                                 #(ribcage
                                                   #(_ e m1 m2)
                                                   #((top) (top) (top) (top))
                                                   #("i" "i" "i" "i"))
                                                 #(ribcage () () ())
                                                 #(ribcage
                                                   #(x)
                                                   #((top))
                                                   #("i"))))
                                             syntmp-e-1983))
                                 syntmp-body-1987))
                         syntmp-tmp-1986))
                      (let syntmp-f-1988 ((syntmp-clause-1989 syntmp-m1-1984)
                                          (syntmp-clauses-1990 syntmp-m2-1985))
                        (if (null? syntmp-clauses-1990)
                          ((lambda (syntmp-tmp-1992)
                             ((lambda (syntmp-tmp-1993)
                                (if syntmp-tmp-1993
                                  (apply (lambda (syntmp-e1-1994
                                                  syntmp-e2-1995)
                                           (cons '#(syntax-object
                                                    begin
                                                    ((top)
                                                     #(ribcage
                                                       #(e1 e2)
                                                       #((top) (top))
                                                       #("i" "i"))
                                                     #(ribcage () () ())
                                                     #(ribcage
                                                       #(f clause clauses)
                                                       #((top) (top) (top))
                                                       #("i" "i" "i"))
                                                     #(ribcage
                                                       #(_ e m1 m2)
                                                       #((top)
                                                         (top)
                                                         (top)
                                                         (top))
                                                       #("i" "i" "i" "i"))
                                                     #(ribcage () () ())
                                                     #(ribcage
                                                       #(x)
                                                       #((top))
                                                       #("i"))))
                                                 (cons syntmp-e1-1994
                                                       syntmp-e2-1995)))
                                         syntmp-tmp-1993)
                                  ((lambda (syntmp-tmp-1997)
                                     (if syntmp-tmp-1997
                                       (apply (lambda (syntmp-k-1998
                                                       syntmp-e1-1999
                                                       syntmp-e2-2000)
                                                (list '#(syntax-object
                                                         if
                                                         ((top)
                                                          #(ribcage
                                                            #(k e1 e2)
                                                            #((top)
                                                              (top)
                                                              (top))
                                                            #("i" "i" "i"))
                                                          #(ribcage () () ())
                                                          #(ribcage
                                                            #(f clause clauses)
                                                            #((top)
                                                              (top)
                                                              (top))
                                                            #("i" "i" "i"))
                                                          #(ribcage
                                                            #(_ e m1 m2)
                                                            #((top)
                                                              (top)
                                                              (top)
                                                              (top))
                                                            #("i" "i" "i" "i"))
                                                          #(ribcage () () ())
                                                          #(ribcage
                                                            #(x)
                                                            #((top))
                                                            #("i"))))
                                                      (list '#(syntax-object
                                                               memv
                                                               ((top)
                                                                #(ribcage
                                                                  #(k e1 e2)
                                                                  #((top)
                                                                    (top)
                                                                    (top))
                                                                  #("i"
                                                                    "i"
                                                                    "i"))
                                                                #(ribcage
                                                                  ()
                                                                  ()
                                                                  ())
                                                                #(ribcage
                                                                  #(f
                                                                    clause
                                                                    clauses)
                                                                  #((top)
                                                                    (top)
                                                                    (top))
                                                                  #("i"
                                                                    "i"
                                                                    "i"))
                                                                #(ribcage
                                                                  #(_ e m1 m2)
                                                                  #((top)
                                                                    (top)
                                                                    (top)
                                                                    (top))
                                                                  #("i"
                                                                    "i"
                                                                    "i"
                                                                    "i"))
                                                                #(ribcage
                                                                  ()
                                                                  ()
                                                                  ())
                                                                #(ribcage
                                                                  #(x)
                                                                  #((top))
                                                                  #("i"))))
                                                            '#(syntax-object
                                                               t
                                                               ((top)
                                                                #(ribcage
                                                                  #(k e1 e2)
                                                                  #((top)
                                                                    (top)
                                                                    (top))
                                                                  #("i"
                                                                    "i"
                                                                    "i"))
                                                                #(ribcage
                                                                  ()
                                                                  ()
                                                                  ())
                                                                #(ribcage
                                                                  #(f
                                                                    clause
                                                                    clauses)
                                                                  #((top)
                                                                    (top)
                                                                    (top))
                                                                  #("i"
                                                                    "i"
                                                                    "i"))
                                                                #(ribcage
                                                                  #(_ e m1 m2)
                                                                  #((top)
                                                                    (top)
                                                                    (top)
                                                                    (top))
                                                                  #("i"
                                                                    "i"
                                                                    "i"
                                                                    "i"))
                                                                #(ribcage
                                                                  ()
                                                                  ()
                                                                  ())
                                                                #(ribcage
                                                                  #(x)
                                                                  #((top))
                                                                  #("i"))))
                                                            (list '#(syntax-object
                                                                     quote
                                                                     ((top)
                                                                      #(ribcage
                                                                        #(k
                                                                          e1
                                                                          e2)
                                                                        #((top)
                                                                          (top)
                                                                          (top))
                                                                        #("i"
                                                                          "i"
                                                                          "i"))
                                                                      #(ribcage
                                                                        ()
                                                                        ()
                                                                        ())
                                                                      #(ribcage
                                                                        #(f
                                                                          clause
                                                                          clauses)
                                                                        #((top)
                                                                          (top)
                                                                          (top))
                                                                        #("i"
                                                                          "i"
                                                                          "i"))
                                                                      #(ribcage
                                                                        #(_
                                                                          e
                                                                          m1
                                                                          m2)
                                                                        #((top)
                                                                          (top)
                                                                          (top)
                                                                          (top))
                                                                        #("i"
                                                                          "i"
                                                                          "i"
                                                                          "i"))
                                                                      #(ribcage
                                                                        ()
                                                                        ()
                                                                        ())
                                                                      #(ribcage
                                                                        #(x)
                                                                        #((top))
                                                                        #("i"))))
                                                                  syntmp-k-1998))
                                                      (cons '#(syntax-object
                                                               begin
                                                               ((top)
                                                                #(ribcage
                                                                  #(k e1 e2)
                                                                  #((top)
                                                                    (top)
                                                                    (top))
                                                                  #("i"
                                                                    "i"
                                                                    "i"))
                                                                #(ribcage
                                                                  ()
                                                                  ()
                                                                  ())
                                                                #(ribcage
                                                                  #(f
                                                                    clause
                                                                    clauses)
                                                                  #((top)
                                                                    (top)
                                                                    (top))
                                                                  #("i"
                                                                    "i"
                                                                    "i"))
                                                                #(ribcage
                                                                  #(_ e m1 m2)
                                                                  #((top)
                                                                    (top)
                                                                    (top)
                                                                    (top))
                                                                  #("i"
                                                                    "i"
                                                                    "i"
                                                                    "i"))
                                                                #(ribcage
                                                                  ()
                                                                  ()
                                                                  ())
                                                                #(ribcage
                                                                  #(x)
                                                                  #((top))
                                                                  #("i"))))
                                                            (cons syntmp-e1-1999
                                                                  syntmp-e2-2000))))
                                              syntmp-tmp-1997)
                                       ((lambda (syntmp-_-2003)
                                          (syntax-error syntmp-x-1979))
                                        syntmp-tmp-1992)))
                                   (syntax-dispatch
                                     syntmp-tmp-1992
                                     '(each-any any . each-any)))))
                              (syntax-dispatch
                                syntmp-tmp-1992
                                '(#(free-id
                                    #(syntax-object
                                      else
                                      ((top)
                                       #(ribcage () () ())
                                       #(ribcage
                                         #(f clause clauses)
                                         #((top) (top) (top))
                                         #("i" "i" "i"))
                                       #(ribcage
                                         #(_ e m1 m2)
                                         #((top) (top) (top) (top))
                                         #("i" "i" "i" "i"))
                                       #(ribcage () () ())
                                       #(ribcage #(x) #((top)) #("i")))))
                                  any
                                  .
                                  each-any))))
                           syntmp-clause-1989)
                          ((lambda (syntmp-tmp-2004)
                             ((lambda (syntmp-rest-2005)
                                ((lambda (syntmp-tmp-2006)
                                   ((lambda (syntmp-tmp-2007)
                                      (if syntmp-tmp-2007
                                        (apply (lambda (syntmp-k-2008
                                                        syntmp-e1-2009
                                                        syntmp-e2-2010)
                                                 (list '#(syntax-object
                                                          if
                                                          ((top)
                                                           #(ribcage
                                                             #(k e1 e2)
                                                             #((top)
                                                               (top)
                                                               (top))
                                                             #("i" "i" "i"))
                                                           #(ribcage () () ())
                                                           #(ribcage
                                                             #(rest)
                                                             #((top))
                                                             #("i"))
                                                           #(ribcage () () ())
                                                           #(ribcage
                                                             #(f
                                                               clause
                                                               clauses)
                                                             #((top)
                                                               (top)
                                                               (top))
                                                             #("i" "i" "i"))
                                                           #(ribcage
                                                             #(_ e m1 m2)
                                                             #((top)
                                                               (top)
                                                               (top)
                                                               (top))
                                                             #("i"
                                                               "i"
                                                               "i"
                                                               "i"))
                                                           #(ribcage () () ())
                                                           #(ribcage
                                                             #(x)
                                                             #((top))
                                                             #("i"))))
                                                       (list '#(syntax-object
                                                                memv
                                                                ((top)
                                                                 #(ribcage
                                                                   #(k e1 e2)
                                                                   #((top)
                                                                     (top)
                                                                     (top))
                                                                   #("i"
                                                                     "i"
                                                                     "i"))
                                                                 #(ribcage
                                                                   ()
                                                                   ()
                                                                   ())
                                                                 #(ribcage
                                                                   #(rest)
                                                                   #((top))
                                                                   #("i"))
                                                                 #(ribcage
                                                                   ()
                                                                   ()
                                                                   ())
                                                                 #(ribcage
                                                                   #(f
                                                                     clause
                                                                     clauses)
                                                                   #((top)
                                                                     (top)
                                                                     (top))
                                                                   #("i"
                                                                     "i"
                                                                     "i"))
                                                                 #(ribcage
                                                                   #(_ e m1 m2)
                                                                   #((top)
                                                                     (top)
                                                                     (top)
                                                                     (top))
                                                                   #("i"
                                                                     "i"
                                                                     "i"
                                                                     "i"))
                                                                 #(ribcage
                                                                   ()
                                                                   ()
                                                                   ())
                                                                 #(ribcage
                                                                   #(x)
                                                                   #((top))
                                                                   #("i"))))
                                                             '#(syntax-object
                                                                t
                                                                ((top)
                                                                 #(ribcage
                                                                   #(k e1 e2)
                                                                   #((top)
                                                                     (top)
                                                                     (top))
                                                                   #("i"
                                                                     "i"
                                                                     "i"))
                                                                 #(ribcage
                                                                   ()
                                                                   ()
                                                                   ())
                                                                 #(ribcage
                                                                   #(rest)
                                                                   #((top))
                                                                   #("i"))
                                                                 #(ribcage
                                                                   ()
                                                                   ()
                                                                   ())
                                                                 #(ribcage
                                                                   #(f
                                                                     clause
                                                                     clauses)
                                                                   #((top)
                                                                     (top)
                                                                     (top))
                                                                   #("i"
                                                                     "i"
                                                                     "i"))
                                                                 #(ribcage
                                                                   #(_ e m1 m2)
                                                                   #((top)
                                                                     (top)
                                                                     (top)
                                                                     (top))
                                                                   #("i"
                                                                     "i"
                                                                     "i"
                                                                     "i"))
                                                                 #(ribcage
                                                                   ()
                                                                   ()
                                                                   ())
                                                                 #(ribcage
                                                                   #(x)
                                                                   #((top))
                                                                   #("i"))))
                                                             (list '#(syntax-object
                                                                      quote
                                                                      ((top)
                                                                       #(ribcage
                                                                         #(k
                                                                           e1
                                                                           e2)
                                                                         #((top)
                                                                           (top)
                                                                           (top))
                                                                         #("i"
                                                                           "i"
                                                                           "i"))
                                                                       #(ribcage
                                                                         ()
                                                                         ()
                                                                         ())
                                                                       #(ribcage
                                                                         #(rest)
                                                                         #((top))
                                                                         #("i"))
                                                                       #(ribcage
                                                                         ()
                                                                         ()
                                                                         ())
                                                                       #(ribcage
                                                                         #(f
                                                                           clause
                                                                           clauses)
                                                                         #((top)
                                                                           (top)
                                                                           (top))
                                                                         #("i"
                                                                           "i"
                                                                           "i"))
                                                                       #(ribcage
                                                                         #(_
                                                                           e
                                                                           m1
                                                                           m2)
                                                                         #((top)
                                                                           (top)
                                                                           (top)
                                                                           (top))
                                                                         #("i"
                                                                           "i"
                                                                           "i"
                                                                           "i"))
                                                                       #(ribcage
                                                                         ()
                                                                         ()
                                                                         ())
                                                                       #(ribcage
                                                                         #(x)
                                                                         #((top))
                                                                         #("i"))))
                                                                   syntmp-k-2008))
                                                       (cons '#(syntax-object
                                                                begin
                                                                ((top)
                                                                 #(ribcage
                                                                   #(k e1 e2)
                                                                   #((top)
                                                                     (top)
                                                                     (top))
                                                                   #("i"
                                                                     "i"
                                                                     "i"))
                                                                 #(ribcage
                                                                   ()
                                                                   ()
                                                                   ())
                                                                 #(ribcage
                                                                   #(rest)
                                                                   #((top))
                                                                   #("i"))
                                                                 #(ribcage
                                                                   ()
                                                                   ()
                                                                   ())
                                                                 #(ribcage
                                                                   #(f
                                                                     clause
                                                                     clauses)
                                                                   #((top)
                                                                     (top)
                                                                     (top))
                                                                   #("i"
                                                                     "i"
                                                                     "i"))
                                                                 #(ribcage
                                                                   #(_ e m1 m2)
                                                                   #((top)
                                                                     (top)
                                                                     (top)
                                                                     (top))
                                                                   #("i"
                                                                     "i"
                                                                     "i"
                                                                     "i"))
                                                                 #(ribcage
                                                                   ()
                                                                   ()
                                                                   ())
                                                                 #(ribcage
                                                                   #(x)
                                                                   #((top))
                                                                   #("i"))))
                                                             (cons syntmp-e1-2009
                                                                   syntmp-e2-2010))
                                                       syntmp-rest-2005))
                                               syntmp-tmp-2007)
                                        ((lambda (syntmp-_-2013)
                                           (syntax-error syntmp-x-1979))
                                         syntmp-tmp-2006)))
                                    (syntax-dispatch
                                      syntmp-tmp-2006
                                      '(each-any any . each-any))))
                                 syntmp-clause-1989))
                              syntmp-tmp-2004))
                           (syntmp-f-1988
                             (car syntmp-clauses-1990)
                             (cdr syntmp-clauses-1990)))))))
                   syntmp-tmp-1981)
            (syntax-error syntmp-tmp-1980)))
        (syntax-dispatch
          syntmp-tmp-1980
          '(any any any . each-any))))
     syntmp-x-1979)))

(install-global-transformer
  'identifier-syntax
  (lambda (syntmp-x-2043)
    ((lambda (syntmp-tmp-2044)
       ((lambda (syntmp-tmp-2045)
          (if syntmp-tmp-2045
            (apply (lambda (syntmp-_-2046 syntmp-e-2047)
                     (list '#(syntax-object
                              lambda
                              ((top)
                               #(ribcage #(_ e) #((top) (top)) #("i" "i"))
                               #(ribcage () () ())
                               #(ribcage #(x) #((top)) #("i"))))
                           '(#(syntax-object
                               x
                               ((top)
                                #(ribcage #(_ e) #((top) (top)) #("i" "i"))
                                #(ribcage () () ())
                                #(ribcage #(x) #((top)) #("i")))))
                           (list '#(syntax-object
                                    syntax-case
                                    ((top)
                                     #(ribcage
                                       #(_ e)
                                       #((top) (top))
                                       #("i" "i"))
                                     #(ribcage () () ())
                                     #(ribcage #(x) #((top)) #("i"))))
                                 '#(syntax-object
                                    x
                                    ((top)
                                     #(ribcage
                                       #(_ e)
                                       #((top) (top))
                                       #("i" "i"))
                                     #(ribcage () () ())
                                     #(ribcage #(x) #((top)) #("i"))))
                                 '()
                                 (list '#(syntax-object
                                          id
                                          ((top)
                                           #(ribcage
                                             #(_ e)
                                             #((top) (top))
                                             #("i" "i"))
                                           #(ribcage () () ())
                                           #(ribcage #(x) #((top)) #("i"))))
                                       '(#(syntax-object
                                           identifier?
                                           ((top)
                                            #(ribcage
                                              #(_ e)
                                              #((top) (top))
                                              #("i" "i"))
                                            #(ribcage () () ())
                                            #(ribcage #(x) #((top)) #("i"))))
                                         (#(syntax-object
                                            syntax
                                            ((top)
                                             #(ribcage
                                               #(_ e)
                                               #((top) (top))
                                               #("i" "i"))
                                             #(ribcage () () ())
                                             #(ribcage #(x) #((top)) #("i"))))
                                          #(syntax-object
                                            id
                                            ((top)
                                             #(ribcage
                                               #(_ e)
                                               #((top) (top))
                                               #("i" "i"))
                                             #(ribcage () () ())
                                             #(ribcage
                                               #(x)
                                               #((top))
                                               #("i"))))))
                                       (list '#(syntax-object
                                                syntax
                                                ((top)
                                                 #(ribcage
                                                   #(_ e)
                                                   #((top) (top))
                                                   #("i" "i"))
                                                 #(ribcage () () ())
                                                 #(ribcage
                                                   #(x)
                                                   #((top))
                                                   #("i"))))
                                             syntmp-e-2047))
                                 (list (cons syntmp-_-2046
                                             '(#(syntax-object
                                                 x
                                                 ((top)
                                                  #(ribcage
                                                    #(_ e)
                                                    #((top) (top))
                                                    #("i" "i"))
                                                  #(ribcage () () ())
                                                  #(ribcage
                                                    #(x)
                                                    #((top))
                                                    #("i"))))
                                               #(syntax-object
                                                 ...
                                                 ((top)
                                                  #(ribcage
                                                    #(_ e)
                                                    #((top) (top))
                                                    #("i" "i"))
                                                  #(ribcage () () ())
                                                  #(ribcage
                                                    #(x)
                                                    #((top))
                                                    #("i"))))))
                                       (list '#(syntax-object
                                                syntax
                                                ((top)
                                                 #(ribcage
                                                   #(_ e)
                                                   #((top) (top))
                                                   #("i" "i"))
                                                 #(ribcage () () ())
                                                 #(ribcage
                                                   #(x)
                                                   #((top))
                                                   #("i"))))
                                             (cons syntmp-e-2047
                                                   '(#(syntax-object
                                                       x
                                                       ((top)
                                                        #(ribcage
                                                          #(_ e)
                                                          #((top) (top))
                                                          #("i" "i"))
                                                        #(ribcage () () ())
                                                        #(ribcage
                                                          #(x)
                                                          #((top))
                                                          #("i"))))
                                                     #(syntax-object
                                                       ...
                                                       ((top)
                                                        #(ribcage
                                                          #(_ e)
                                                          #((top) (top))
                                                          #("i" "i"))
                                                        #(ribcage () () ())
                                                        #(ribcage
                                                          #(x)
                                                          #((top))
                                                          #("i")))))))))))
                   syntmp-tmp-2045)
            (syntax-error syntmp-tmp-2044)))
        (syntax-dispatch
          syntmp-tmp-2044
          '(any any))))
     syntmp-x-2043)))

https://git.savannah.gnu.org/cgit/mes.git/tree/mes/module/mes/psyntax.pp.header?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/mes/module/mes/psyntax.pp.header used in:
;;; -*-scheme-*-
;;; GNU Mes --- Maxwell Equations of Software
;;; Copyright (C) 2016, 2017, 2018 Free Software Foundation, Inc.
;;;
;;; This file is part of GNU Mes.
;;;
;;; GNU Mes is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Mes is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.

;;; Commentary:

;;; This file is generated from psyntax.ss.

;;; Code:

https://git.savannah.gnu.org/cgit/mes.git/tree/mes/module/srfi/srfi-9-struct.mes?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/mes/module/srfi/srfi-9-struct.mes used in: Step 99
;;; -*-scheme-*-

;;; GNU Mes --- Maxwell Equations of Software
;;; Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
;;;
;;; This file is part of GNU Mes.
;;;
;;; GNU Mes is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Mes is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.

;;; Commentary:

;;; srfi-9.mes - records, based on struct.

(define-macro (define-record-type name constructor+params predicate . fields)
  (let ((type (make-record-type name (map car fields))))
   `(begin
      (define ,name ,type)
      (define ,(car constructor+params) ,(record-constructor type name (cdr constructor+params)))
      (define ,predicate ,(record-predicate type))
      (define-record-accessors ,type ,@fields))))

(define (make-record-type type fields . printer)
  (let ((printer (if (pair? printer) (car printer))))
    (make-struct '<record-type> (cons type (list fields)) printer)))

(define (record-type? o)
  (eq? (struct-vtable o) '<record-type>))

(define (struct-vtable o)
  (struct-ref o 0))

(define (record-type o)
  (struct-ref o 2))

(define (record-predicate type)
  (lambda (o)
    (and (record? o)
         (eq? (record-type o) (record-type type)))))

(define (record? o)
  (and (struct? o)
       (record-type? (struct-vtable o))))

(define (record-constructor type name params)
  (let ((fields (record-fields type))
        (record-type (record-type type)))
    (lambda (. o)
      (if (not (= (length o) (length params))) (error "wrong number of arguments for record-constructor")
          (let ((rest (make-list (- (length fields) (length params)))))
            (make-struct type (cons name (append o rest)) record-printer))))))

(define record-printer *unspecified*)   ; TODO
(define (record-printer o)
  (display "#<")
  (display (record-type o))
  (let* ((vtable (struct-vtable o))
         (fields (record-fields vtable)))
    (for-each (lambda (field)
                (display " ")
                (display field)
                (display ": ")
                (display ((record-getter vtable field) o)))
              fields))
  (display ">"))

(define (record-fields o)
  (struct-ref o 3))

(define-macro (define-record-accessors type . fields)
  `(begin
     ,@(map (lambda (field)
              `(define-record-accessor ,type ,field))
            fields)))

(define-macro (define-record-accessor type field)
  `(begin
     (define ,(cadr field) ,(record-getter type (car field)))
     (if ,(pair? (cddr field))
         (define ,(if (pair? (cddr field)) (caddr field)) ,(record-setter type (car field))))))

(define (record-getter type field)
  (let ((i (record-field-index type field)))
    (lambda (o . field?)
      (if (not (eq? (record-type o) (record-type type))) (error "record getter: record expected" type o)
          (if (pair? field?) field
              (struct-ref o i))))))

(define (record-setter type field)
  (let ((i (record-field-index type field)))
    (lambda (o v)
      (if (not (eq? (record-type o) (record-type type))) (error "record setter: record expected" type o)
          (struct-set! o i v)))))

(define (record-field-index type field)
  (+ 3 (or (lst-index (record-fields type) field)
           (error "no such field" type field))))

(define (lst-index lst o)
  (let loop ((lst lst) (i 0))
    (and (pair? lst)
         (if (eq? o (car lst)) i
             (loop (cdr lst) (1+ i))))))

;; (define-record-type <employee>
;;   (make-employee name age salary)
;;   employee?
;;   (name employe-name)
;;   (age employee-age set-employee-age!)
;;   (salary employee-salary))

;; (display <employee>)
;; (newline)

;; (display make-employee)
;; (newline)
;; (display "employee-age ")
;; (display employee-age)
;; (newline)

;; (display "set-employee-age! ")
;; (display set-employee-age!)
;; (newline)

;; (define janneke (make-employee "janneke" 49 42))
;; (display janneke)
;; (newline)

;; (display (employee-age janneke))
;; (newline)

;; (display (set-employee-age! janneke 33))
;; (newline)
;; (display (employee-age janneke))
;; (newline)

https://git.savannah.gnu.org/cgit/mes.git/tree/mes/module/srfi/srfi-9/gnu-struct.mes?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/mes/module/srfi/srfi-9/gnu-struct.mes used in: Step 100
;;; -*-scheme-*-

;;; GNU Mes --- Maxwell Equations of Software
;;; Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
;;;
;;; This file is part of GNU Mes.
;;;
;;; GNU Mes is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Mes is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.

;;; Commentary:

;;; srfi-9.mes - GNU immutable records.

(define-macro (define-immutable-record-type type constructor+params predicate . fields)
  `(define-record-type ,type ,constructor+params ,predicate ,@(map (lambda (f) (list-head f 2)) fields)))

(define-macro (set-field o getters value)
  `(let ((getter ,(car getters)))
     (let* ((type (struct-vtable ,o))
            (name (record-type ,o))
            (set (getter ,o #t)))
       (define (field->value field)
         (if (eq? set field) ,value
             ((record-getter type field) ,o)))
       (let* ((fields (record-fields type))
              (values (map field->value fields)))
         (apply (record-constructor type name fields) values)))))

https://git.savannah.gnu.org/cgit/mes.git/tree/include/m2/lib.h?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/include/m2/lib.h used in: Step 106
/*
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef __M2_LIB_H
#define __M2_LIB_H

char **environ;
int __stdin;
int __stdout;
int __stderr;
int errno;

// CONSTANT EOF 0xffffffff
// CONSTANT __FILEDES_MAX 512

char* cast_intp_to_charp (int *i);
char* cast_long_to_charp (long i);
long cast_charp_to_long (char const *);
long cast_int_to_long (int i);
long cast_voidp_to_long (void const *);

char *itoa (int number);
char *ltoa (long number);
int __ungetc_p (int filedes);
int eputs (char *s);
int oputs (char *s);
int puts (char *s);
size_t strlen (char *s);
ssize_t _write ();
ssize_t write (int filedes, void *buffer, size_t size);
void __ungetc_clear (int filedes);
void __ungetc_init ();
void __ungetc_set (int filedes, int c);

struct timezone
{
  int tz_minuteswest;
  int tz_dsttime;
};

struct timespec
{
  long tv_sec;
  long tv_nsec;
};

struct timeval
{
  long tv_sec;
  long tv_usec;
};

#endif /* __M2_LIB_H */

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-m2/crt1.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/x86-mes-m2/crt1.c used in: Step 106
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "mes/lib-mini.h"

int __stdin;
int __stdout;
int __stderr;
char **environ;
int main (int argc, char **argv, char **envp);

/* FIXME: this is going to be called `FUNCTION__start' */
//#int
//#_start ()
//#{
//# ..
//#}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-m2/_exit.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/x86-mes-m2/_exit.c used in: Step 106
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

void
_exit ()
{
  asm ("mov____$i32,%eax SYS_exit");
  asm ("mov____0x8(%ebp),%ebx !-4");
  asm ("int____$0x80");
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-m2/_write.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/x86-mes-m2/_write.c used in: Step 106
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

void
_write (int filedes, void *buffer, int size)
{
  asm ("mov____$i32,%eax SYS_write");
  asm ("mov____0x8(%ebp),%ebx !-4");
  asm ("mov____0x8(%ebp),%ecx !-8");
  asm ("mov____0x8(%ebp),%edx !-12");
  asm ("int____$0x80");
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/globals.c?h=v0.24.2

Files:
/*
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib-mini.h>

int errno;
char **environ;
int __stdin;
int __stdout;
int __stderr;

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/m2/cast.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/lib/m2/cast.c used in: Step 106
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>

char*
cast_intp_to_charp (int const *i)
{
  return i;
}

char*
cast_long_to_charp (long i)
{
  return i;
}

long
cast_charp_to_long (char const *i)
{
  return i;
}

long
cast_int_to_long (int i)
{
  return i;
}

long
cast_voidp_to_long (void const *i)
{
  return i;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/m2/exit.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/lib/m2/exit.c used in: Step 106
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>

void _exit (int code);

void
exit (int code)
{
  _exit (code);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/mini-write.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/lib/mes/mini-write.c used in: Step 106, Step 130
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <errno.h>

ssize_t
write (int filedes, void const *buffer, size_t size)
{
  int r = _write (filedes, buffer, size);
  if (r < 0)
    {
      errno = -r;
      r = -1;
    }
  else
    errno = 0;
  return r;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-m2/syscall.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/x86-mes-m2/syscall.c used in: Step 106
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <errno.h>
#include <linux/x86/syscall.h>

int errno;

int
__sys_call (int sys_call)
{
  asm ("mov____0x8(%ebp),%eax !-4");
  asm ("int____$0x80");
}

int
__sys_call1 (int sys_call, int one)
{
  asm ("mov____0x8(%ebp),%eax !-4");
  asm ("mov____0x8(%ebp),%ebx !-8");
  asm ("int____$0x80");
}

int
__sys_call2 (int sys_call, int one, int two)
{
  asm ("mov____0x8(%ebp),%eax !-4");
  asm ("mov____0x8(%ebp),%ebx !-8");
  asm ("mov____0x8(%ebp),%ecx !-12");
  asm ("int____$0x80");
}

int
__sys_call3 (int sys_call, int one, int two, int three)
{
  asm ("mov____0x8(%ebp),%eax !-4");
  asm ("mov____0x8(%ebp),%ebx !-8");
  asm ("mov____0x8(%ebp),%ecx !-12");
  asm ("mov____0x8(%ebp),%edx !-16");
  asm ("int____$0x80");
}

int
__sys_call4 (int sys_call, int one, int two, int three, int four)
{
  asm ("mov____0x8(%ebp),%eax !-4");
  asm ("mov____0x8(%ebp),%ebx !-8");
  asm ("mov____0x8(%ebp),%ecx !-12");
  asm ("mov____0x8(%ebp),%edx !-16");
  asm ("mov____0x8(%ebp),%esi !-20");
  asm ("int____$0x80");
}

int
_sys_call (int sys_call)
{
  int r = __sys_call (sys_call);
  if (r < 0)
    {
      errno = -r;
      r = -1;
    }
  else
    errno = 0;
  return r;
}

int
_sys_call1 (int sys_call, int one)
{
  int r = __sys_call1 (sys_call, one);
  if (r < 0)
    {
      errno = -r;
      r = -1;
    }
  else
    errno = 0;
  return r;
}

int
_sys_call2 (int sys_call, int one, int two)
{
  int r = __sys_call2 (sys_call, one, two);
  if (r < 0)
    {
      errno = -r;
      r = -1;
    }
  else
    errno = 0;
  return r;
}

int
_sys_call3 (int sys_call, int one, int two, int three)
{
  int r = __sys_call3 (sys_call, one, two, three);
  if (r < 0)
    {
      errno = -r;
      r = -1;
    }
  else
    errno = 0;
  return r;
}

int
_sys_call4 (int sys_call, int one, int two, int three, int four)
{
  int r = __sys_call4 (sys_call, one, two, three, four);
  if (r < 0)
    {
      errno = -r;
      r = -1;
    }
  else
    errno = 0;
  return r;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/__raise.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/lib/stub/__raise.c used in: Step 106
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

// CONSTANT SIGABRT 0

int
__raise (int signum)
{
  return -1;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/brk.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <linux/syscall.h>
#include <arch/syscall.h>

long
brk (void *addr)
{
  long long_addr = cast_voidp_to_long (addr);
  return _sys_call1 (SYS_brk, long_addr);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/m2/malloc.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/lib/m2/malloc.c used in: Step 106
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2021 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <string.h>

char *__brk = 0;

void *
malloc (size_t size)
{
  if (!__brk)
    __brk = cast_long_to_charp (brk (0));
  if (brk (__brk + size) == -1)
    return 0;
  char *p = __brk;
  __brk = __brk + size;
  return p;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/memset.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <string.h>

char *
_memset (char *s, int c, size_t n)
{
  char *p = s;
  while (n != 0)
    {
      n = n - 1;
      s[0] = c;
      s = s + 1;
    }
  return p;
}

void *
memset (void *s, int c, size_t n)
{
  return _memset (s, c, n);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/m2/read.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/lib/m2/read.c used in: Step 106
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2019,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <syscall.h>
#include <mes/lib.h>
#include <fcntl.h>

long
read (int filedes, void *buffer, long size)
{
  long bytes = _sys_call3 (SYS_read, filedes, buffer, size);
  return bytes;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/fdgetc.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <sys/resource.h>
#include <unistd.h>

int *__ungetc_buf;

int
__ungetc_p (int filedes)
{
  if (__ungetc_buf == 0)
    __ungetc_init ();
  return __ungetc_buf[filedes] >= 0;
}

void
__ungetc_init ()
{
  if (__ungetc_buf == 0)
    {
      int save_errno = errno;
      __ungetc_buf = malloc ((__FILEDES_MAX + 1) * sizeof (int));
      errno = save_errno;
      memset (__ungetc_buf, -1, (__FILEDES_MAX + 1) * sizeof (int));
    }
}

void
__ungetc_clear (int filedes)
{
  if (__ungetc_buf == 0)
    __ungetc_init ();
  __ungetc_buf[filedes] = -1;
}

void
__ungetc_set (int filedes, int c)
{
  if (__ungetc_buf == 0)
    __ungetc_init ();
  __ungetc_buf[filedes] = c;
}

int
fdgetc (int fd)
{
  if (__ungetc_buf == 0)
    __ungetc_init ();

  char c;
  int i = __ungetc_buf[fd];
  if (i >= 0)
    __ungetc_buf[fd] = -1;
  else
    {
      int r = read (fd, &c, 1);
      if (r < 1)
        return -1;
      i = c;
    }
  if (i < 0)
    i = i + 256;

  return i;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/getchar.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>

int
getchar ()
{
  return fdgetc (__stdin);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/putchar.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <stdio.h>

int
putchar (int c)
{
  char *p = cast_intp_to_charp (&c);
  write (__stdout, p, 1);
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/m2/open.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/lib/m2/open.c used in: Step 106
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <mes/lib.h>
#include <fcntl.h>
#include <stdarg.h>

int
open (char *file_name, int flags, int mask)
{
  int r = _sys_call3 (SYS_open, file_name, flags, mask);
  if (r > 2)
    __ungetc_clear (r);
  return r;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/m2/mes_open.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/lib/m2/mes_open.c used in: Step 106
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

int
mes_open (char *file_name, int flags, int mask)
{
  int filedes = open (file_name, flags, mask);
  if (filedes > 2)
    __ungetc_clear (filedes);
  return filedes;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strlen.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>

size_t
strlen (char const *s)
{
  int i = 0;

  while (s[i] != 0)
    i = i + 1;

  return i;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/eputs.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib-mini.h>
#include <string.h>

int
eputs (char const *s)
{
  int i = strlen (s);
  write (__stderr, s, i);
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/fdputc.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>

int
fdputc (int c, int fd)
{
  char *p = cast_intp_to_charp (&c);
  write (fd, p, 1);
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/eputc.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>

int
eputc (int c)
{
  return fdputc (c, __stderr);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/include/m2/types.h?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/include/m2/types.h used in: Step 106
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2022,2023 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __M2_TYPES_H
#define __M2_TYPES_H 1

/*
#ifndef __MES_CLOCK_T
#define __MES_CLOCK_T
#undef clock_t
typedef long clock_t;
#endif
*/

#ifndef __MES_DEV_T
#define __MES_DEV_T
#undef dev_t
typedef long dev_t;
#endif

/*
#if !defined (__MES_FILE_T) && ! defined (_FILE_T)
#define __MES_FILE_T
#define _FILE_T
typedef long FILE;
#endif
*/

#ifndef __MES_GID_T
#define __MES_GID_T
#undef gid_t
typedef unsigned gid_t;
#endif

#ifndef __MES_INO_T
#define __MES_INO_T
#undef ino_t
typedef unsigned ino_t;
#endif

#if __SIZEOF_LONG_LONG__ == 8
#ifndef __MES_INO64_T
#define __MES_INO64_T
#undef ino64_t
typedef unsigned ino64_t;
#endif
#endif // __SIZEOF_LONG_LONG__ == 8

#if !defined (__MES_INTPTR_T) && !defined (__intptr_t_defined)
#define __MES_INTPTR_T
#define __intptr_t_defined
#undef intptr_t
typedef long intptr_t;
#undef uintptr_t
typedef unsigned uintptr_t;
#endif

#ifndef __MES_OFF_T
#define __MES_OFF_T
#undef off_t
typedef long off_t;
#endif

#if __SIZEOF_LONG_LONG__ == 8
#ifndef __MES_OFF64_T
#define __MES_OFF64_T
#undef off64_t
typedef unsigned off64_t;
#endif
#endif // __SIZEOF_LONG_LONG__ == 8

#ifndef __MES_PID_T
#define __MES_PID_T
#undef pid_t
typedef int pid_t;
#endif

#ifndef __PTRDIFF_T
#define __PTRDIFF_T
#ifndef __MES_PTRDIFF_T
#define __MES_PTRDIFF_T
#undef ptrdiff_t
typedef long ptrdiff_t;
#endif
#endif

#ifndef __MES_SIGVAL_T
#define __MES_SIGVAL_T
#undef clock_t
typedef long sigval_t;
#endif

#ifndef __SIZE_T
#define __SIZE_T
#ifndef __MES_SIZE_T
#define __MES_SIZE_T
typedef unsigned size_t;
#endif
#endif

#ifndef __MES_SSIZE_T
#define __MES_SSIZE_T
#undef ssize_t
typedef long ssize_t;
#endif

#ifndef __MES_UID_T
#define __MES_UID_T
#undef uid_t
typedef unsigned uid_t;
#endif

#ifndef __WCHAR_T
#define __WCHAR_T
#ifndef __MES_WCHAR_T
#define __MES_WCHAR_T
#undef wchar_t
typedef int wchar_t;
#endif
#endif

#endif // __M2_TYPES_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/mes/mes.h?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/include/mes/mes.h used in: Step 106, Step 212, Step 213, Step 214, Step 215, Step 216, Step 217, Step 218, Step 219, Step 220, Step 221, Step 222, Step 223, Step 224, Step 225, Step 226, Step 227, Step 228, Step 229, Step 230, Step 347
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2020,2021 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef __MES_MES_H
#define __MES_MES_H

#include <sys/types.h>
#include "mes/cc.h"

struct scm
{
  long type;
  union
  {
    struct scm *car;
    long car_value;
    char *bytes;
    long length;
    struct scm *ref;
    struct scm *variable;
    struct scm *macro;
    long port;
  };
  union
  {
    struct scm *cdr;
    long cdr_value;
    struct scm *closure;
    struct scm *continuation;
    char *name;
    struct scm *string;
    struct scm *structure;
    long value;
    FUNCTION function;
    struct scm *vector;
  };
};

/* mes */
extern char *g_datadir;
extern int g_debug;
extern char *g_buf;
extern int g_continuations;
extern struct scm *g_symbols;
extern struct scm *g_symbol_max;
extern int g_mini;

/* a/env */
extern struct scm *R0;
/* param 1 */
extern struct scm *R1;
/* save 2 */
extern struct scm *R2;
/* continuation */
extern struct scm *R3;
/* current-module */
extern struct scm *M0;
/* macro */
extern struct scm *g_macros;
extern struct scm *g_ports;

/* gc */
extern size_t ARENA_SIZE;
extern size_t MAX_ARENA_SIZE;
extern size_t STACK_SIZE;
extern size_t JAM_SIZE;
extern size_t GC_SAFETY;
extern size_t MAX_STRING;
extern char *g_arena;
extern struct scm *cell_arena;
extern struct scm *cell_zero;

extern struct scm *g_free;
extern struct scm *g_symbol;

extern struct scm **g_stack_array;
extern struct scm *g_cells;
extern struct scm *g_news;
extern long g_stack;
extern size_t gc_count;
extern struct timespec *gc_start_time;
extern struct timespec *gc_end_time;
extern size_t gc_time;

extern char **__execl_c_argv;
extern char *__open_boot_buf;
extern char *__open_boot_file_name;
extern char *__setenv_buf;
extern char *__reader_read_char_buf;
extern struct timespec *g_start_time;
extern struct timeval *__gettimeofday_time;
extern struct timespec *__get_internal_run_time_ts;

struct scm *cast_charp_to_scmp (char const *i);
struct scm **cast_charp_to_scmpp (char const *i);
char *cast_voidp_to_charp (void const *i);
long cast_scmp_to_long (struct scm *i);
char *cast_scmp_to_charp (struct scm *i);

struct scm *alloc (long n);
struct scm *apply (struct scm *f, struct scm *x, struct scm *a);
struct scm *apply_builtin (struct scm *fn, struct scm *x);
struct scm *apply_builtin0 (struct scm *fn);
struct scm *apply_builtin1 (struct scm *fn, struct scm *x);
struct scm *apply_builtin2 (struct scm *fn, struct scm *x, struct scm *y);
struct scm *apply_builtin3 (struct scm *fn, struct scm *x, struct scm *y, struct scm *z);
struct scm *builtin_name (struct scm *builtin);
struct scm *cstring_to_list (char const *s);
struct scm *cstring_to_symbol (char const *s);
struct scm *cell_ref (struct scm *cell, long index);
struct scm *fdisplay_ (struct scm *, int, int);
struct scm *init_symbols ();
struct scm *init_time (struct scm *a);
struct scm *make_builtin_type ();
struct scm *make_bytes (char const *s, size_t length);
struct scm *make_cell (long type, struct scm *car, struct scm *cdr);
struct scm *make_pointer_cell (long type, long car, void *cdr);
struct scm *make_value_cell (long type, long car, long cdr);
struct scm *make_char (int n);
struct scm *make_continuation (long n);
struct scm *make_hash_table_ (long size);
struct scm *make_hashq_type ();
struct scm *make_initial_module (struct scm *a);
struct scm *make_macro (struct scm *name, struct scm *x);
struct scm *make_number (long n);
struct scm *make_ref (struct scm *x);
struct scm *make_string (char const *s, size_t length);
struct scm *make_string0 (char const *s);
struct scm *make_string_port (struct scm *x);
struct scm *make_vector_ (long k, struct scm *e);
struct scm *mes_builtins (struct scm *a);
struct scm *push_cc (struct scm *p1, struct scm *p2, struct scm *a, struct scm *c);
struct scm *struct_ref_ (struct scm *x, long i);
struct scm *struct_set_x_ (struct scm *x, long i, struct scm *e);
struct scm *vector_ref_ (struct scm *x, long i);
struct scm *vector_set_x_ (struct scm *x, long i, struct scm *e);
FUNCTION builtin_function (struct scm *builtin);
char *cell_bytes (struct scm *x);
int peekchar ();
int readchar ();
int unreadchar ();
long gc_free ();
long length__ (struct scm *x);
size_t bytes_cells (size_t length);
void assert_max_string (size_t i, char const *msg, char const *string);
void assert_msg (int check, char *msg);
void assert_number (char const *name, struct scm *x);
void copy_cell (struct scm *to, struct scm *from);
void gc_ ();
void gc_dump_arena (struct scm *cells, long size);
void gc_init ();
void gc_peek_frame ();
void gc_pop_frame ();
void gc_push_frame ();
void gc_stats_ (char const* where);
void init_symbols_ ();
long seconds_and_nanoseconds_to_long (long s, long ns);

#include "mes/builtins.h"
#include "mes/constants.h"
#include "mes/symbols.h"

#endif /* __MES_MES_H */

https://git.savannah.gnu.org/cgit/mes.git/tree/include/mes/builtins.h?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/include/mes/builtins.h used in: Step 106, Step 212, Step 213, Step 214, Step 215, Step 216, Step 217, Step 218, Step 219, Step 220, Step 221, Step 222, Step 223, Step 224, Step 225, Step 226, Step 227, Step 228, Step 229, Step 230, Step 341
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef __MES_BUILTINS_H
#define __MES_BUILTINS_H

/* src/builtins.c */
struct scm *make_builtin (struct scm *builtin_type, struct scm *name, struct scm *arity, struct scm *function);
struct scm *builtin_name (struct scm *builtin);
struct scm *builtin_arity (struct scm *builtin);
struct scm *builtin_p (struct scm *x);
struct scm *builtin_printer (struct scm *builtin);
/* src/core.c */
struct scm *car (struct scm *x);
struct scm *cdr (struct scm *x);
struct scm *list (struct scm *x);
struct scm *null_p (struct scm *x);
struct scm *eq_p (struct scm *x, struct scm *y);
struct scm *values (struct scm *x);
struct scm *acons (struct scm *key, struct scm *value, struct scm *alist);
struct scm *length (struct scm *x);
struct scm *error (struct scm *key, struct scm *x);
struct scm *append2 (struct scm *x, struct scm *y);
struct scm *append_reverse (struct scm *x, struct scm *y);
struct scm *reverse_x_ (struct scm *x, struct scm *t);
struct scm *assq (struct scm *x, struct scm *a);
struct scm *assoc (struct scm *x, struct scm *a);
/* src/display.c */
struct scm *display_ (struct scm *x);
struct scm *display_error_ (struct scm *x);
struct scm *display_port_ (struct scm *x, struct scm *p);
struct scm *write_ (struct scm *x);
struct scm *write_error_ (struct scm *x);
struct scm *write_port_ (struct scm *x, struct scm *p);
/* src/eval-apply.c */
struct scm *pairlis (struct scm *x, struct scm *y, struct scm *a);
struct scm *set_car_x (struct scm *x, struct scm *e);
struct scm *set_cdr_x (struct scm *x, struct scm *e);
struct scm *set_env_x (struct scm *x, struct scm *e, struct scm *a);
struct scm *add_formals (struct scm *formals, struct scm *x);
struct scm *eval_apply ();
/* src/gc.c */
struct scm *gc_stats ();
struct scm *cons (struct scm *x, struct scm *y);
struct scm *gc_check ();
struct scm *gc ();
/* src/hash.c */
struct scm *hashq (struct scm *x, struct scm *size);
struct scm *hash (struct scm *x, struct scm *size);
struct scm *hashq_get_handle (struct scm *table, struct scm *key, struct scm *dflt);
struct scm *hashq_ref (struct scm *table, struct scm *key, struct scm *dflt);
struct scm *hash_ref (struct scm *table, struct scm *key, struct scm *dflt);
struct scm *hashq_set_x (struct scm *table, struct scm *key, struct scm *value);
struct scm *hash_set_x (struct scm *table, struct scm *key, struct scm *value);
struct scm *hash_table_printer (struct scm *table);
struct scm *make_hash_table (struct scm *x);
/* src/lib.c */
struct scm *type_ (struct scm *x);
struct scm *car_ (struct scm *x);
struct scm *cdr_ (struct scm *x);
struct scm *xassq (struct scm *x, struct scm *a);
struct scm *memq (struct scm *x, struct scm *a);
struct scm *equal2_p (struct scm *a, struct scm *b);
struct scm *last_pair (struct scm *x);
struct scm *pair_p (struct scm *x);
struct scm *char_to_integer (struct scm *x);
struct scm *integer_to_char (struct scm *x);
/* src/math.c */
struct scm *greater_p (struct scm *x);
struct scm *less_p (struct scm *x);
struct scm *is_p (struct scm *x);
struct scm *minus (struct scm *x);
struct scm *plus (struct scm *x);
struct scm *divide (struct scm *x);
struct scm *modulo (struct scm *a, struct scm *b);
struct scm *multiply (struct scm *x);
struct scm *logand (struct scm *x);
struct scm *logior (struct scm *x);
struct scm *lognot (struct scm *x);
struct scm *logxor (struct scm *x);
struct scm *ash (struct scm *n, struct scm *count);
/* src/module.c */
struct scm *make_module_type ();
struct scm *module_printer (struct scm *module);
struct scm *module_variable (struct scm *module, struct scm *name);
struct scm *module_ref (struct scm *module, struct scm *name);
struct scm *module_define_x (struct scm *module, struct scm *name, struct scm *value);
/* src/posix.c */
struct scm *abort_ ();
struct scm *exit_ (struct scm *x);
struct scm *peek_byte ();
struct scm *read_byte ();
struct scm *unread_byte (struct scm *i);
struct scm *peek_char ();
struct scm *read_char (struct scm *port);
struct scm *unread_char (struct scm *i);
struct scm *write_char (struct scm *i);
struct scm *write_byte (struct scm *x);
struct scm *getenv_ (struct scm *s);
struct scm *setenv_ (struct scm *s, struct scm *v);
struct scm *access_p (struct scm *file_name, struct scm *mode);
struct scm *current_input_port ();
struct scm *open_input_file (struct scm *file_name);
struct scm *open_input_string (struct scm *string);
struct scm *set_current_input_port (struct scm *port);
struct scm *current_output_port ();
struct scm *current_error_port ();
struct scm *open_output_file (struct scm *x);
struct scm *set_current_output_port (struct scm *port);
struct scm *set_current_error_port (struct scm *port);
struct scm *chmod_ (struct scm *file_name, struct scm *mode);
struct scm *isatty_p (struct scm *port);
struct scm *primitive_fork ();
struct scm *execl_ (struct scm *file_name, struct scm *args);
struct scm *waitpid_ (struct scm *pid, struct scm *options);
struct scm *current_time ();
struct scm *gettimeofday_ ();
struct scm *get_internal_run_time ();
struct scm *getcwd_ ();
struct scm *dup_ (struct scm *port);
struct scm *dup2_ (struct scm *old, struct scm *new);
struct scm *delete_file (struct scm *file_name);
/* src/reader.c */
struct scm *read_input_file_env_ (struct scm *e, struct scm *a);
struct scm *read_input_file_env (struct scm *a);
struct scm *read_env (struct scm *a);
struct scm *reader_read_sexp (struct scm *c, struct scm *s, struct scm *a);
struct scm *reader_read_character ();
struct scm *reader_read_binary ();
struct scm *reader_read_octal ();
struct scm *reader_read_hex ();
struct scm *reader_read_string ();
/* src/stack.c */
struct scm *frame_printer (struct scm *frame);
struct scm *make_stack (struct scm *stack);
struct scm *stack_length (struct scm *stack);
struct scm *stack_ref (struct scm *stack, struct scm *index);
/* src/string.c */
struct scm *string_equal_p (struct scm *a, struct scm *b);
struct scm *symbol_to_string (struct scm *symbol);
struct scm *symbol_to_keyword (struct scm *symbol);
struct scm *keyword_to_string (struct scm *keyword);
struct scm *string_to_symbol (struct scm *string);
struct scm *make_symbol (struct scm *string);
struct scm *string_to_list (struct scm *string);
struct scm *list_to_string (struct scm *list);
struct scm *read_string (struct scm *port);
struct scm *string_append (struct scm *x);
struct scm *string_length (struct scm *string);
struct scm *string_ref (struct scm *str, struct scm *k);
/* src/struct.c */
struct scm *make_struct (struct scm *type, struct scm *fields, struct scm *printer);
struct scm *struct_length (struct scm *x);
struct scm *struct_ref (struct scm *x, struct scm *i);
struct scm *struct_set_x (struct scm *x, struct scm *i, struct scm *e);
/* src/vector.c */
struct scm *make_vector (struct scm *x);
struct scm *vector_length (struct scm *x);
struct scm *vector_ref (struct scm *x, struct scm *i);
struct scm *vector_entry (struct scm *x);
struct scm *vector_set_x (struct scm *x, struct scm *i, struct scm *e);
struct scm *list_to_vector (struct scm *x);
struct scm *vector_to_list (struct scm *v);

#endif /* __MES_BUILTINS_H */

https://git.savannah.gnu.org/cgit/mes.git/tree/include/mes/constants.h?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/include/mes/constants.h used in: Step 106, Step 212, Step 213, Step 214, Step 215, Step 216, Step 217, Step 218, Step 219, Step 220, Step 221, Step 222, Step 223, Step 224, Step 225, Step 226, Step 227, Step 228, Step 229, Step 230, Step 344
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef __MES_CONSTANTS_H
#define __MES_CONSTANTS_H

/* Cell types */

// CONSTANT TCHAR          0
#define TCHAR              0

// CONSTANT TBYTES         1
#define TBYTES             1
// CONSTANT TCLOSURE       2
#define TCLOSURE           2
// CONSTANT TCONTINUATION  3
#define TCONTINUATION      3
// CONSTANT TKEYWORD       4
#define TKEYWORD           4
// CONSTANT TMACRO         5
#define TMACRO             5
// CONSTANT TNUMBER        6
#define TNUMBER            6
// CONSTANT TPAIR          7
#define TPAIR              7
// CONSTANT TPORT          8
#define TPORT              8
// CONSTANT TREF           9
#define TREF               9
// CONSTANT TSPECIAL      10
#define TSPECIAL          10
// CONSTANT TSTRING       11
#define TSTRING           11
// CONSTANT TSTRUCT       12
#define TSTRUCT           12
// CONSTANT TSYMBOL       13
#define TSYMBOL           13
// CONSTANT TVALUES       14
#define TVALUES           14
// CONSTANT TVARIABLE     15
#define TVARIABLE         15
// CONSTANT TVECTOR       16
#define TVECTOR           16
// CONSTANT TBROKEN_HEART 17
#define TBROKEN_HEART     17

/* Struct types */

// CONSTANT STRUCT_TYPE 0
#define STRUCT_TYPE 0
// CONSTANT STRUCT_PRINTER 1
#define STRUCT_PRINTER 1

// CONSTANT GC_FRAME_SIZE 5
#define GC_FRAME_SIZE 5
// CONSTANT GC_FRAME_PROCEDURE 4
#define GC_FRAME_PROCEDURE 4

// CONSTANT STDIN 0
// CONSTANT STDOUT 1
// CONSTANT STDERR 2

/* Unknown type 1
// CONSTANT EOF -1
*/

// CONSTANT O_RDONLY 0
// CONSTANT O_WRONLY 1
// CONSTANT O_CREAT 0x40
// CONSTANT O_TRUNC 0x200

// CONSTANT PATH_MAX 1024
// CONSTANT __FILEDES_MAX 512

// CONSTANT S_IRUSR 00400
// CONSTANT S_IWUSR 00200

// CONSTANT CLOCK_PROCESS_CPUTIME_ID 2


#endif /* __MES_CONSTANTS_H */

https://git.savannah.gnu.org/cgit/mes.git/tree/include/mes/symbols.h?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/include/mes/symbols.h used in: Step 106, Step 212, Step 213, Step 214, Step 215, Step 216, Step 217, Step 218, Step 219, Step 220, Step 221, Step 222, Step 223, Step 224, Step 225, Step 226, Step 227, Step 228, Step 229, Step 230, Step 348
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2021 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef __MES_SYMBOLS_H
#define __MES_SYMBOLS_H

extern struct scm *cell_nil;
extern struct scm *cell_f;
extern struct scm *cell_t;
extern struct scm *cell_dot;
extern struct scm *cell_arrow;
extern struct scm *cell_undefined;
extern struct scm *cell_unspecified;
extern struct scm *cell_closure;
extern struct scm *cell_circular;

extern struct scm *cell_vm_apply;
extern struct scm *cell_vm_apply2;
extern struct scm *cell_vm_begin;
extern struct scm *cell_vm_begin_eval;
extern struct scm *cell_vm_begin_expand;
extern struct scm *cell_vm_begin_expand_eval;
extern struct scm *cell_vm_begin_expand_macro;
extern struct scm *cell_vm_begin_expand_primitive_load;
extern struct scm *cell_vm_begin_primitive_load;
extern struct scm *cell_vm_begin_read_input_file;
extern struct scm *cell_vm_call_with_current_continuation2;
extern struct scm *cell_vm_call_with_values2;
extern struct scm *cell_vm_eval;
extern struct scm *cell_vm_eval2;
extern struct scm *cell_vm_eval_check_func;
extern struct scm *cell_vm_eval_define;
extern struct scm *cell_vm_eval_macro_expand_eval;
extern struct scm *cell_vm_eval_macro_expand_expand;
extern struct scm *cell_vm_eval_pmatch_car;
extern struct scm *cell_vm_eval_pmatch_cdr;
extern struct scm *cell_vm_eval_set_x;
extern struct scm *cell_vm_evlis;
extern struct scm *cell_vm_evlis2;
extern struct scm *cell_vm_evlis3;
extern struct scm *cell_vm_if;
extern struct scm *cell_vm_if_expr;
extern struct scm *cell_vm_macro_expand;
extern struct scm *cell_vm_macro_expand_car;
extern struct scm *cell_vm_macro_expand_cdr;
extern struct scm *cell_vm_macro_expand_define;
extern struct scm *cell_vm_macro_expand_define_macro;
extern struct scm *cell_vm_macro_expand_lambda;
extern struct scm *cell_vm_macro_expand_set_x;
extern struct scm *cell_vm_return;

extern struct scm *cell_symbol_lambda;
extern struct scm *cell_symbol_begin;
extern struct scm *cell_symbol_if;
extern struct scm *cell_symbol_quote;
extern struct scm *cell_symbol_define;
extern struct scm *cell_symbol_define_macro;
extern struct scm *cell_symbol_quasiquote;
extern struct scm *cell_symbol_unquote;
extern struct scm *cell_symbol_unquote_splicing;
extern struct scm *cell_symbol_syntax;
extern struct scm *cell_symbol_quasisyntax;
extern struct scm *cell_symbol_unsyntax;
extern struct scm *cell_symbol_unsyntax_splicing;
extern struct scm *cell_symbol_set_x;
extern struct scm *cell_symbol_sc_expand;
extern struct scm *cell_symbol_macro_expand;
extern struct scm *cell_symbol_portable_macro_expand;
extern struct scm *cell_symbol_sc_expander_alist;
extern struct scm *cell_symbol_call_with_values;
extern struct scm *cell_symbol_call_with_current_continuation;
extern struct scm *cell_symbol_boot_module;
extern struct scm *cell_symbol_current_module;
extern struct scm *cell_symbol_primitive_load;
extern struct scm *cell_symbol_car;
extern struct scm *cell_symbol_cdr;
extern struct scm *cell_symbol_not_a_number;
extern struct scm *cell_symbol_not_a_pair;
extern struct scm *cell_symbol_system_error;
extern struct scm *cell_symbol_throw;
extern struct scm *cell_symbol_unbound_variable;
extern struct scm *cell_symbol_wrong_number_of_args;
extern struct scm *cell_symbol_wrong_type_arg;
extern struct scm *cell_symbol_buckets;
extern struct scm *cell_symbol_builtin;
extern struct scm *cell_symbol_frame;
extern struct scm *cell_symbol_hashq_table;
extern struct scm *cell_symbol_module;
extern struct scm *cell_symbol_procedure;
extern struct scm *cell_symbol_record_type;
extern struct scm *cell_symbol_size;
extern struct scm *cell_symbol_stack;
extern struct scm *cell_symbol_argv;
extern struct scm *cell_symbol_mes_datadir;
extern struct scm *cell_symbol_mes_version;
extern struct scm *cell_symbol_internal_time_units_per_second;
extern struct scm *cell_symbol_compiler;
extern struct scm *cell_symbol_arch;
extern struct scm *cell_symbol_pmatch_car;
extern struct scm *cell_symbol_pmatch_cdr;
extern struct scm *cell_type_bytes;
extern struct scm *cell_type_char;
extern struct scm *cell_type_closure;
extern struct scm *cell_type_continuation;
extern struct scm *cell_type_function;
extern struct scm *cell_type_keyword;
extern struct scm *cell_type_macro;
extern struct scm *cell_type_number;
extern struct scm *cell_type_pair;
extern struct scm *cell_type_port;
extern struct scm *cell_type_ref;
extern struct scm *cell_type_special;
extern struct scm *cell_type_string;
extern struct scm *cell_type_struct;
extern struct scm *cell_type_symbol;
extern struct scm *cell_type_values;
extern struct scm *cell_type_variable;
extern struct scm *cell_type_vector;
extern struct scm *cell_type_broken_heart;
extern struct scm *cell_symbol_program;
extern struct scm *cell_symbol_test;

// CONSTANT SYMBOL_MAX 114
#define SYMBOL_MAX 114

// CONSTANT CELL_UNSPECIFIED 7
#define CELL_UNSPECIFIED 7

// CONSTANT CELL_SYMBOL_RECORD_TYPE 82
#define CELL_SYMBOL_RECORD_TYPE 82


#endif /* __MES_SYMBOLS_H */

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/__assert_fail.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <assert.h>

void
__assert_fail (char const *msg, char const *file, unsigned line,
               char const *function)
{
  if (file && file[0])
    {
      eputs (file);
      eputs (":");
    }
  if (line)
    {
      eputs (itoa (line));
      eputs (":");
    }
  if (function && function[0])
    {
      eputs (function);
      eputs (":");
    }
  eputs ("assert fail: ");
  eputs (msg);
  eputs ("\n");
  char *fail = 0;
  fail[0] = 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/assert_msg.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2019 Jeremiah Orians <jeremiah@pdp10.guru>
 * Copyright © 2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <assert.h>
#include <stdlib.h>

void
assert_msg (int bool, char *msg)
{
  if (bool == 0)
    __assert_fail (msg, 0, 0, 0);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strncmp.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <string.h>

int
strncmp (char const *a, char const *b, size_t size)
{
  if (size == 0)
    return 0;

  while (a[0] != 0 && b[0] != 0 && a[0] == b[0] && size > 1)
    {
      size = size - 1;
      a = a + 1;
      b = b + 1;
    }

  return a[0] - b[0];
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/getenv.c?h=v0.24.2

Files:
/*
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <string.h>
#include <stdlib.h>

// CONSTANT M2_PTR_SIZE 4
#define M2_PTR_SIZE 1

char *
getenv (char const *s)
{
  /* eputs ("\ngetenv s="); eputs (s); eputs ("\n"); */
  char **p = environ;
  char *q;
  int length = strlen (s);

  while (p[0] != 0)
    {
      /* eputs ("getenv p[0]="); eputs (p[0]); eputs ("\n"); */
      if (strncmp (s, p[0], length) == 0)
        {
          /* eputs ("found!\n"); */
          q = p[0] + length;
          if (q[0] == '=')
            return q + 1;
        }
      /* else */
      /*   eputs ("not found!\n"); */
      p = p + M2_PTR_SIZE;
    }

  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/fdputs.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <string.h>

int
fdputs (char const *s, int fd)
{
  int i = strlen (s);
  write (fd, s, i);
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/ntoab.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2020,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>

#if __M2_PLANET__ || (!(__MESC__ && __arm__) && !(__TINYC__ && __arm__ && BOOTSTRAP))
size_t
__mesabi_uldiv (size_t a, size_t b, size_t *remainder)
{
  remainder[0] = a % b;
  return a / b;
}
#endif

char *__itoa_buf;

char *
ntoab (long x, unsigned base, int signed_p)
{
  if (__itoa_buf == 0)
    __itoa_buf = malloc (20);
  char *p = __itoa_buf + 11;

  p[0] = 0;
  p = p - 1;
  assert_msg (base > 0, "base > 0");

  int sign_p = 0;
  size_t i;
  size_t u;
  size_t b = base;
  if (signed_p != 0 && x < 0)
    {
      sign_p = 1;
      /* Avoid LONG_MIN */
      u = (-(x + 1));
      u = u + 1;
    }
  else
    u = x;

  do
    {
      u = __mesabi_uldiv (u, b, &i);
      if (i > 9)
        p[0] = 'a' + i - 10;
      else
        p[0] = '0' + i;
      p = p - 1;
    }
  while (u != 0);

  if (sign_p && p[1] != '0')
    {
      p[0] = '-';
      p = p - 1;
    }

  return p + 1;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isdigit.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 * Copyright © 2023 Rick Masters <grick23@gmail.com>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>

int
isdigit (int c)
{
  return c >= '0' && c <= '9';
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isxdigit.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <ctype.h>

int
isxdigit (int c)
{
  return isdigit (c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isspace.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>

int
isspace (int c)
{
  return (c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r' || c == ' ');
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isnumber.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <ctype.h>

int
isnumber (int c, int base)
{
  if (base == 2)
    return (c >= '0') && (c <= '1');
  if (base == 8)
    return (c >= '0') && (c <= '7');
  if (base == 10)
    return isdigit (c);
  if (base == 16)
    return isxdigit (c);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/abtol.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 * Copyright © 2022,2023 Rick Masters <grick23@gmail.com>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <ctype.h>

long
abtol (char const **p, int base)
{
  char const *s = p[0];
  int i = 0;
  int sign_p = 0;
  int m = '0';
  if (base == 0)
    base = 10;
  while (isspace (s[0]) != 0)
    s = s + 1;
  if (s[0] != 0 && s[0] == '+')
    s = s + 1;
  if (s[0] != 0 && s[0] == '-')
    {
      sign_p = 1;
      s = s + 1;
    }
  while (isnumber (s[0], base) != 0)
    {
      i = i * base;
      if (s[0] >= 'a')
        m = 'a' - 10;
      else
        {
          if (s[0] >= 'A')
            m = 'A' - 10;
          else
            m = '0';
        }
      i = i + s[0] - m;
      s = s + 1;
    }
  p[0] = s;
  if (sign_p != 0)
    return -i;

  return i;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/atoi.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>

int
atoi (char const *string)
{
  char const *p = string;
  return abtol (&p, 0);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/memcpy.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <string.h>

char *
_memcpy (char *dest, char const *src, size_t n)
{
  char *p = dest;

  while (n != 0)
    {
      n = n - 1;
      dest[0] = src[0];
      dest = dest + 1;
      src = src + 1;
    }

  return p;
}

void *
memcpy (void *dest, void const *src, size_t n)
{
  return _memcpy (dest, src, n);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/free.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdlib.h>

void
free (void *ptr)
{
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/realloc.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdlib.h>
#include <string.h>

void *
realloc (void *ptr, size_t size)
{
  void *new = malloc (size);
  if (ptr != 0 && new != 0)
    {
      memcpy (new, ptr, size);
      free (ptr);
    }
  return new;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strcpy.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <string.h>

char *
strcpy (char *dest, char const *src)
{
  char *p = dest;

  while (src[0] != 0)
    {
      p[0] = src[0];
      p = p + 1;
      src = src + 1;
    }
  p[0] = 0;

  return dest;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/itoa.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>

char *
itoa (int x)
{
  return ntoab (x, 10, 1);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/ltoa.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>

char *
ltoa (long x)
{
  return ntoab (x, 10, 1);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/fdungetc.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>

int
fdungetc (int c, int fd)
{
  if (c == -1)
    return c;
  else if (__ungetc_p (fd))
    {
      eputs (" ***MES C LIB*** fdungetc ungetc buffer overflow fd=");
      eputs (itoa (fd));
      eputs ("\n");
      assert_msg (0, "0");
    }
  __ungetc_set (fd, c);
  return c;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/setenv.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <string.h>
#include <stdlib.h>

// CONSTANT M2_PTR_SIZE 4
#define M2_PTR_SIZE 1

int
setenv (char const *s, char const *v, int overwrite_p)
{
  char **p = environ;
  int length = strlen (s);
  char* q;

  while (p[0] != 0)
    {
      if (strncmp (s, p[0], length) == 0)
        {
          q = p[0] + length;
          if (q[0] == '=')
            break;
        }
      p = p + M2_PTR_SIZE;
    }
  char *entry = malloc (length + strlen (v) + 2);
  int end_p = p[0] == 0;
  p[0] = entry;
  strcpy (entry, s);
  strcpy (entry + length, "=");
  strcpy (entry + length + 1, v);
  entry[length + strlen (v) + 2] = 0;
  if (end_p != 0)
    p[1] = 0;

  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/access.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <linux/syscall.h>
#include <arch/syscall.h>

int
access (char const *file_name, int how)
{
  long long_file_name = cast_charp_to_long (file_name);
  long long_how = cast_int_to_long (how);
  return _sys_call2 (SYS_access, long_file_name, long_how);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/include/linux/m2/kernel-stat.h?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/include/linux/m2/kernel-stat.h used in: Step 106
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __LINUX_M2_KERNEL_STAT_H
#define __LINUX_M2_KERNEL_STAT_H

/* https://github.com/torvalds/linux/blob/master/arch/x86/include/uapi/asm/stat.h */

/* *INDENT-OFF* */
struct stat
{
  unsigned st_dev;
  unsigned st_ino;
  char st_mode[2];
  char st_nlink[2];
  char st_uid[2];
  char st_gid[2];
  unsigned st_rdev;
  unsigned st_size;
  unsigned st_blksize;
  unsigned st_blocks;
  unsigned st_atime;
  unsigned st_atime_usec;
  unsigned st_mtime;
  unsigned st_mtime_usec;
  unsigned st_ctime;
  unsigned st_ctime_usec;
  unsigned __pad0;
  unsigned __pad1;
};
#endif /* __LINUX_M2_KERNEL_STAT_H */

https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/stat.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 * Copyright © 2022 Dor Askayo <dor.askayo@gmail.com>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_SYS_STAT_H
#define __MES_SYS_STAT_H 1

#if SYSTEM_LIBC
#undef __MES_SYS_STAT_H
#include_next <sys/stat.h>

#else // ! SYSTEM_LIBC

#include <time.h>
#include <sys/types.h>
#include <arch/kernel-stat.h>

#ifndef __MES_MODE_T
#define __MES_MODE_T
typedef int mode_t;
#endif

int chmod (char const *file_name, mode_t mode);
int fstat (int filedes, struct stat *buf);
int mkdir (char const *file_name, mode_t mode);
int mknod (char const *file_name, mode_t mode, dev_t dev);
int chown (char const *file_name, uid_t owner, gid_t group);
int rmdir (char const *file_name);
int stat (char const *file_name, struct stat *buf);

#define S_IFIFO 0010000
#define S_IFCHR 0020000
#define S_IFDIR 0040000
#define S_IFBLK 0060000
#define S_IFREG 0100000
#define S_IFLNK 0120000
#define S_IFMT  0170000

#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)

#define S_IRWXU 00700
#define S_IXUSR 00100
#define S_IWUSR 00200
#define S_IRUSR 00400

#define S_ISUID 04000
#define S_ISGID 02000
#define S_IXGRP 00010
#define S_IXOTH 00001
#define S_IRGRP 00040
#define S_IROTH 00004
#define S_IWGRP 00020
#define S_IWOTH 00002
#define S_IRWXG 00070
#define S_IRWXO 00007

#endif // ! SYSTEM_LIBC

#endif // __MES_SYS_STAT_H

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/m2/chmod.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/lib/m2/chmod.c used in: Step 106
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <syscall.h>
#include <sys/stat.h>

int
chmod (char const *file_name, int mask)
{
  long long_file_name = file_name;
  long long_mask = mask;
  return _sys_call2 (SYS_chmod, long_file_name, long_mask);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/ioctl3.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <mes/lib.h>

int
ioctl3 (int filedes, size_t command, long data)
{
  long long_filedes = cast_int_to_long (filedes);
  int r = _sys_call3 (SYS_ioctl, long_filedes, command, data);
  return r;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/m2/isatty.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/lib/m2/isatty.c used in: Step 106
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <string.h>
#include <termio.h>

// CONSTANT TCGETS 0x5401
#define TCGETS 0x5401

struct ktermios
{
  unsigned c_iflag;
  unsigned c_oflag;
  unsigned c_cflag;
  unsigned c_lflag;
  char c_line;
  char c_cc[19];
  unsigned c_ispeed;
  unsigned c_ospeed;
};

struct ktermios *__isatty_kernel_termios;

int
isatty (int filedes)
{
  if (__isatty_kernel_termios == 0)
    __isatty_kernel_termios = malloc (sizeof (struct ktermios));
  int r = ioctl3 (filedes, TCGETS, __isatty_kernel_termios);
  return r == 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/fork.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>

int
fork ()
{
  return _sys_call (SYS_fork);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/m2/execve.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/lib/m2/execve.c used in: Step 106
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>

int
execve (char const *file_name, char **argv, char **env)
{
  long long_file_name = file_name;
  long long_argv = argv;
  long long_env = env;
  return _sys_call3 (SYS_execve, file_name, argv, env);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/m2/execv.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/lib/m2/execv.c used in: Step 106
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

int
execv (char *file_name, char **argv)
{
  return execve (file_name, argv, environ);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/m2/waitpid.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/lib/m2/waitpid.c used in: Step 106
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2020,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <linux/syscall.h>
#include <arch/syscall.h>
#include <sys/types.h>

int
waitpid (int pid, int *status_ptr, int options)
{
  long long_pid = pid;
  long long_status_ptr = cast_voidp_to_long (status_ptr);
  long long_options = options;
//##if __i386__
//#  return _sys_call3 (SYS_waitpid, long_pid, long_status_ptr, long_options);
//##elif __x86_64__ || __arm__
  return _sys_call4 (SYS_wait4, long_pid, long_status_ptr, long_options, 0);
//##else
//##error arch not supported
//##endif
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/gettimeofday.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <linux/syscall.h>
#include <arch/syscall.h>
#include <sys/time.h>

int
gettimeofday (struct timeval *tv, struct timezone *tz)
{
  long long_tv = cast_voidp_to_long (tv);
  long long_tz = cast_voidp_to_long (tz);
  return _sys_call2 (SYS_gettimeofday, long_tv, long_tz);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/m2/clock_gettime.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/lib/m2/clock_gettime.c used in: Step 106
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <syscall.h>
#include <time.h>

int
clock_gettime (long clk_id, struct timespec *tp)
{
  long long_tp = tp;
  return _sys_call2 (SYS_clock_gettime, clk_id, tp);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/m2/time.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/lib/m2/time.c used in: Step 106
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019,2022,2023 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <time.h>

char *__tv;

long
time (long* result)
{
  int r;
  if (__tv == 0)
    __tv = malloc (sizeof (struct timeval));
  struct timeval *tv = __tv;
  r = _sys_call2 (SYS_gettimeofday, tv, 0);
  if (r != 0)
    return -1;
  if (result != 0)
    result[0] = tv->tv_sec;
  return tv->tv_sec;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/_getcwd.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <linux/syscall.h>
#include <arch/syscall.h>

char *
_getcwd (char *buffer, size_t size)
{
  long long_buffer = cast_charp_to_long (buffer);
  int r = _sys_call2 (SYS_getcwd, long_buffer, size);
  if (r >= 0)
    return buffer;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/m2/getcwd.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/lib/m2/getcwd.c used in: Step 106
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <mes/mes.h>
#include <limits.h>
#include <stdlib.h>
#include <sys/types.h>

// CONSTANT PATH_MAX 1024

char *__getcwd_buf;

char *
getcwd (char *buffer, int size)
{
  if (buffer == 0)
    buffer = __getcwd_buf;
  if (buffer == 0)
    {
      __getcwd_buf = malloc (PATH_MAX);
      buffer = __getcwd_buf;
    }
  return _getcwd (buffer, size);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/dup.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>

int
dup (int old)
{
  long long_old = old;
  return _sys_call1 (SYS_dup, long_old);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/dup2.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>

int
dup2 (int old, int new)
{
  long long_old = old;
  long long_new = new;
  return _sys_call2 (SYS_dup2, long_old, long_new);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strcmp.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <string.h>

int
strcmp (char const *a, char const *b)
{
  while (a[0] != 0 && b[0] != 0 && a[0] == b[0])
    {
      a = a + 1;
      b = b + 1;
    }

  return a[0] - b[0];
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/memcmp.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <string.h>

int
memcmp (void const *s1, void const *s2, size_t size)
{
  if (size == 0)
    return 0;

  char const *a = s1;
  char const *b = s2;

  while (a[0] == b[0] && size > 1)
    {
      size = size - 1;
      a = a + 1;
      b = b + 1;
    }

  return a[0] - b[0];
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/unlink.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <linux/syscall.h>
#include <arch/syscall.h>

int
unlink (char const *file_name)
{
  long long_file_name = cast_charp_to_long (file_name);
  return _sys_call1 (SYS_unlink, long_file_name);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/src/builtins.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/src/builtins.c used in: Step 106, Step 212
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "mes/lib.h"
#include "mes/mes.h"

struct scm *
make_builtin_type ()            /*:((internal)) */
{
  struct scm *record_type = cell_symbol_record_type;
  struct scm *fields = cell_nil;
  fields = cons (cstring_to_symbol ("address"), fields);
  fields = cons (cstring_to_symbol ("arity"), fields);
  fields = cons (cstring_to_symbol ("name"), fields);
  fields = cons (fields, cell_nil);
  fields = cons (cell_symbol_builtin, fields);
  return make_struct (record_type, fields, cell_unspecified);
}

struct scm *
make_builtin (struct scm *builtin_type, struct scm *name, struct scm *arity, struct scm *function)
{
  struct scm *values = cell_nil;
  values = cons (function, values);
  values = cons (arity, values);
  values = cons (name, values);
  values = cons (cell_symbol_builtin, values);
  return make_struct (builtin_type, values, cstring_to_symbol ("builtin-printer"));
}

struct scm *
builtin_name (struct scm *builtin)
{
  return struct_ref_ (builtin, 3);
}

struct scm *
builtin_arity (struct scm *builtin)
{
  return struct_ref_ (builtin, 4);
}

FUNCTION
builtin_function (struct scm *builtin)
{
  struct scm *x = struct_ref_ (builtin, 5);
  return x->function;
}

struct scm *
builtin_p (struct scm *x)
{
  if (x->type == TSTRUCT)
    if (struct_ref_ (x, 2) == cell_symbol_builtin)
      return cell_t;
  return cell_f;
}

struct scm *
builtin_printer (struct scm *builtin)
{
  fdputs ("#<procedure ", __stdout);
  display_ (builtin_name (builtin));
  fdputc (' ', __stdout);
  struct scm *x = builtin_arity (builtin);
  int arity = x->value;
  if (arity == -1)
    fdputc ('_', __stdout);
  else
    {
      fdputc ('(', __stdout);
      int i;
      for (i = 0; i < arity; i = i + 1)
        {
          if (i != 0)
            fdputc (' ', __stdout);
          fdputc ('_', __stdout);
        }
    }
  fdputc ('>', __stdout);
}

struct scm *
init_builtin (struct scm *builtin_type, char const *name, int arity, void* function, struct scm *a)
{
  struct scm *s = cstring_to_symbol (name);
  long n = cast_voidp_to_long (function);
  return acons (s,
                make_builtin (builtin_type, symbol_to_string (s), make_number (arity),
                              make_number (n)), a);
}

struct scm *
mes_builtins (struct scm *a)            /*:((internal)) */
{
  struct scm *builtin_type = make_builtin_type ();

  if (g_mini != 0)
    {
      a = init_builtin (builtin_type, "cons", 2, &cons, a);
      a = init_builtin (builtin_type, "car", 1, &car, a);
      a = init_builtin (builtin_type, "list", -1, &list, a);
      a = init_builtin (builtin_type, "eq?", 2, &eq_p, a);
      a = init_builtin (builtin_type, "-", -1, &minus, a);
      a = init_builtin (builtin_type, "+", -1, &plus, a);
      a = init_builtin (builtin_type, "core:display", 1, &display_, a);
      a = init_builtin (builtin_type, "core:write", 1, &write_, a);
      a = init_builtin (builtin_type, "core:display-error", 1, &display_error_, a);
      a = init_builtin (builtin_type, "getenv", 1, &getenv_, a);
      a = init_builtin (builtin_type, "gc", 0, &gc, a);
      a = init_builtin (builtin_type, ">", -1, &greater_p, a);
      a = init_builtin (builtin_type, "<", -1, &less_p, a);
      a = init_builtin (builtin_type, "make-vector", -1, &make_vector, a);
      return a;
    }

  /* src/builtins.c */
  a = init_builtin (builtin_type, "make-builtin", 4, &make_builtin, a);
  a = init_builtin (builtin_type, "builtin-name", 1, &builtin_name, a);
  a = init_builtin (builtin_type, "builtin-arity", 1, &builtin_arity, a);
  a = init_builtin (builtin_type, "builtin?", 1, &builtin_p, a);
  a = init_builtin (builtin_type, "builtin-printer", 1, &builtin_printer, a);
  /* src/core.c */
  a = init_builtin (builtin_type, "car", 1, &car, a);
  a = init_builtin (builtin_type, "cdr", 1, &cdr, a);
  a = init_builtin (builtin_type, "list", -1, &list, a);
  a = init_builtin (builtin_type, "null?", 1, &null_p, a);
  a = init_builtin (builtin_type, "eq?", 2, &eq_p, a);
  a = init_builtin (builtin_type, "values", -1, &values, a);
  a = init_builtin (builtin_type, "acons", 3, &acons, a);
  a = init_builtin (builtin_type, "length", 1, &length, a);
  a = init_builtin (builtin_type, "error", 2, &error, a);
  a = init_builtin (builtin_type, "append2", 2, &append2, a);
  a = init_builtin (builtin_type, "append-reverse", 2, &append_reverse, a);
  a = init_builtin (builtin_type, "core:reverse!", 2, &reverse_x_, a);
  a = init_builtin (builtin_type, "assq", 2, &assq, a);
  a = init_builtin (builtin_type, "assoc", 2, &assoc, a);
  /* src/display.c */
  a = init_builtin (builtin_type, "core:display", 1, &display_, a);
  a = init_builtin (builtin_type, "core:display-error", 1, &display_error_, a);
  a = init_builtin (builtin_type, "core:display-port", 2, &display_port_, a);
  a = init_builtin (builtin_type, "core:write", 1, &write_, a);
  a = init_builtin (builtin_type, "core:write-error", 1, &write_error_, a);
  a = init_builtin (builtin_type, "core:write-port", 2, &write_port_, a);
  /* src/eval-apply.c */
  a = init_builtin (builtin_type, "pairlis", 3, &pairlis, a);
  a = init_builtin (builtin_type, "set-car!", 2, &set_car_x, a);
  a = init_builtin (builtin_type, "set-cdr!", 2, &set_cdr_x, a);
  a = init_builtin (builtin_type, "set-env!", 3, &set_env_x, a);
  a = init_builtin (builtin_type, "add-formals", 2, &add_formals, a);
  a = init_builtin (builtin_type, "eval-apply", 0, &eval_apply, a);
  /* src/gc.c */
  a = init_builtin (builtin_type, "gc-stats", 0, &gc_stats, a);
  a = init_builtin (builtin_type, "cons", 2, &cons, a);
  a = init_builtin (builtin_type, "gc-check", 0, &gc_check, a);
  a = init_builtin (builtin_type, "gc", 0, &gc, a);
  /* src/hash.c */
  a = init_builtin (builtin_type, "hashq", 2, &hashq, a);
  a = init_builtin (builtin_type, "hash", 2, &hash, a);
  a = init_builtin (builtin_type, "hashq-get-handle", 3, &hashq_get_handle, a);
  a = init_builtin (builtin_type, "hashq-ref", 3, &hashq_ref, a);
  a = init_builtin (builtin_type, "hash-ref", 3, &hash_ref, a);
  a = init_builtin (builtin_type, "hashq-set!", 3, &hashq_set_x, a);
  a = init_builtin (builtin_type, "hash-set!", 3, &hash_set_x, a);
  a = init_builtin (builtin_type, "hash-table-printer", 1, &hash_table_printer, a);
  a = init_builtin (builtin_type, "make-hash-table", 1, &make_hash_table, a);
  /* src/lib.c */
  a = init_builtin (builtin_type, "core:type", 1, &type_, a);
  a = init_builtin (builtin_type, "core:car", 1, &car_, a);
  a = init_builtin (builtin_type, "core:cdr", 1, &cdr_, a);
  a = init_builtin (builtin_type, "xassq", 2, &xassq, a);
  a = init_builtin (builtin_type, "memq", 2, &memq, a);
  a = init_builtin (builtin_type, "equal2?", 2, &equal2_p, a);
  a = init_builtin (builtin_type, "last-pair", 1, &last_pair, a);
  a = init_builtin (builtin_type, "pair?", 1, &pair_p, a);
  a = init_builtin (builtin_type, "char->integer", 1, &char_to_integer, a);
  a = init_builtin (builtin_type, "integer->char", 1, &integer_to_char, a);
  /* src/math.c */
  a = init_builtin (builtin_type, ">", -1, &greater_p, a);
  a = init_builtin (builtin_type, "<", -1, &less_p, a);
  a = init_builtin (builtin_type, "=", -1, &is_p, a);
  a = init_builtin (builtin_type, "-", -1, &minus, a);
  a = init_builtin (builtin_type, "+", -1, &plus, a);
  a = init_builtin (builtin_type, "/", -1, &divide, a);
  a = init_builtin (builtin_type, "modulo", 2, &modulo, a);
  a = init_builtin (builtin_type, "*", -1, &multiply, a);
  a = init_builtin (builtin_type, "logand", -1, &logand, a);
  a = init_builtin (builtin_type, "logior", -1, &logior, a);
  a = init_builtin (builtin_type, "lognot", 1, &lognot, a);
  a = init_builtin (builtin_type, "logxor", -1, &logxor, a);
  a = init_builtin (builtin_type, "ash", 2, &ash, a);
  /* src/module.c */
  a = init_builtin (builtin_type, "make-module-type", 0, &make_module_type, a);
  a = init_builtin (builtin_type, "module-printer", 1, &module_printer, a);
  a = init_builtin (builtin_type, "module-variable", 2, &module_variable, a);
  a = init_builtin (builtin_type, "module-ref", 2, &module_ref, a);
  a = init_builtin (builtin_type, "module-define!", 3, &module_define_x, a);
  /* src/posix.c */
  a = init_builtin (builtin_type, "abort", 0, &abort_, a);
  a = init_builtin (builtin_type, "exit", 1, &exit_, a);
  a = init_builtin (builtin_type, "peek-byte", 0, &peek_byte, a);
  a = init_builtin (builtin_type, "read-byte", 0, &read_byte, a);
  a = init_builtin (builtin_type, "unread-byte", 1, &unread_byte, a);
  a = init_builtin (builtin_type, "peek-char", 0, &peek_char, a);
  a = init_builtin (builtin_type, "read-char", -1, &read_char, a);
  a = init_builtin (builtin_type, "unread-char", 1, &unread_char, a);
  a = init_builtin (builtin_type, "write-char", -1, &write_char, a);
  a = init_builtin (builtin_type, "write-byte", -1, &write_byte, a);
  a = init_builtin (builtin_type, "getenv", 1, &getenv_, a);
  a = init_builtin (builtin_type, "setenv", 2, &setenv_, a);
  a = init_builtin (builtin_type, "access?", 2, &access_p, a);
  a = init_builtin (builtin_type, "current-input-port", 0, &current_input_port, a);
  a = init_builtin (builtin_type, "open-input-file", 1, &open_input_file, a);
  a = init_builtin (builtin_type, "open-input-string", 1, &open_input_string, a);
  a = init_builtin (builtin_type, "set-current-input-port", 1, &set_current_input_port, a);
  a = init_builtin (builtin_type, "current-output-port", 0, &current_output_port, a);
  a = init_builtin (builtin_type, "current-error-port", 0, &current_error_port, a);
  a = init_builtin (builtin_type, "open-output-file", -1, &open_output_file, a);
  a = init_builtin (builtin_type, "set-current-output-port", 1, &set_current_output_port, a);
  a = init_builtin (builtin_type, "set-current-error-port", 1, &set_current_error_port, a);
  a = init_builtin (builtin_type, "chmod", 2, &chmod_, a);
  a = init_builtin (builtin_type, "isatty?", 1, &isatty_p, a);
  a = init_builtin (builtin_type, "primitive-fork", 0, &primitive_fork, a);
  a = init_builtin (builtin_type, "execl", 2, &execl_, a);
  a = init_builtin (builtin_type, "core:waitpid", 2, &waitpid_, a);
  a = init_builtin (builtin_type, "current-time", 0, &current_time, a);
  a = init_builtin (builtin_type, "gettimeofday", 0, &gettimeofday_, a);
  a = init_builtin (builtin_type, "get-internal-run-time", 0, &get_internal_run_time, a);
  a = init_builtin (builtin_type, "getcwd", 0, &getcwd_, a);
  a = init_builtin (builtin_type, "dup", 1, &dup_, a);
  a = init_builtin (builtin_type, "dup2", 2, &dup2_, a);
  a = init_builtin (builtin_type, "delete-file", 1, &delete_file, a);
  /* src/reader.c */
  a = init_builtin (builtin_type, "core:read-input-file-env", 2, &read_input_file_env_, a);
  a = init_builtin (builtin_type, "read-input-file-env", 1, &read_input_file_env, a);
  a = init_builtin (builtin_type, "read-env", 1, &read_env, a);
  a = init_builtin (builtin_type, "reader-read-sexp", 3, &reader_read_sexp, a);
  a = init_builtin (builtin_type, "reader-read-character", 0, &reader_read_character, a);
  a = init_builtin (builtin_type, "reader-read-binary", 0, &reader_read_binary, a);
  a = init_builtin (builtin_type, "reader-read-octal", 0, &reader_read_octal, a);
  a = init_builtin (builtin_type, "reader-read-hex", 0, &reader_read_hex, a);
  a = init_builtin (builtin_type, "reader-read-string", 0, &reader_read_string, a);
  /* src/stack.c */
  a = init_builtin (builtin_type, "frame-printer", 1, &frame_printer, a);
  a = init_builtin (builtin_type, "make-stack", -1, &make_stack, a);
  a = init_builtin (builtin_type, "stack-length", 1, &stack_length, a);
  a = init_builtin (builtin_type, "stack-ref", 2, &stack_ref, a);
  /* src/string.c */
  a = init_builtin (builtin_type, "string=?", 2, &string_equal_p, a);
  a = init_builtin (builtin_type, "symbol->string", 1, &symbol_to_string, a);
  a = init_builtin (builtin_type, "symbol->keyword", 1, &symbol_to_keyword, a);
  a = init_builtin (builtin_type, "keyword->string", 1, &keyword_to_string, a);
  a = init_builtin (builtin_type, "string->symbol", 1, &string_to_symbol, a);
  a = init_builtin (builtin_type, "make-symbol", 1, &make_symbol, a);
  a = init_builtin (builtin_type, "string->list", 1, &string_to_list, a);
  a = init_builtin (builtin_type, "list->string", 1, &list_to_string, a);
  a = init_builtin (builtin_type, "read-string", -1, &read_string, a);
  a = init_builtin (builtin_type, "string-append", -1, &string_append, a);
  a = init_builtin (builtin_type, "string-length", 1, &string_length, a);
  a = init_builtin (builtin_type, "string-ref", 2, &string_ref, a);
  /* src/struct.c */
  a = init_builtin (builtin_type, "make-struct", 3, &make_struct, a);
  a = init_builtin (builtin_type, "struct-length", 1, &struct_length, a);
  a = init_builtin (builtin_type, "struct-ref", 2, &struct_ref, a);
  a = init_builtin (builtin_type, "struct-set!", 3, &struct_set_x, a);
  /* src/vector.c */
  a = init_builtin (builtin_type, "make-vector", -1, &make_vector, a);
  a = init_builtin (builtin_type, "vector-length", 1, &vector_length, a);
  a = init_builtin (builtin_type, "vector-ref", 2, &vector_ref, a);
  a = init_builtin (builtin_type, "vector-entry", 1, &vector_entry, a);
  a = init_builtin (builtin_type, "vector-set!", 3, &vector_set_x, a);
  a = init_builtin (builtin_type, "list->vector", 1, &list_to_vector, a);
  a = init_builtin (builtin_type, "vector->list", 1, &vector_to_list, a);

  return a;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/src/core.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/src/core.c used in: Step 106, Step 214
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

/** Commentary:
    Essential functions, used by the eval/apply core.
 */

/** Code: */

#include "mes/lib.h"
#include "mes/mes.h"

#include <stdlib.h>

struct scm *
assoc_string (struct scm *x, struct scm *a)     /*:((internal)) */
{
  struct scm *b;
  while (a != cell_nil)
    {
      b = a->car;
      if (b->car->type == TSTRING)
        if (string_equal_p (x, b->car) == cell_t)
          return b;
      a = a->cdr;
    }
  if (a != cell_nil)
    return a->car;
  return cell_f;
}

struct scm *
car (struct scm *x)
{
#if !__MESC_MES__
  if (x->type != TPAIR)
    error (cell_symbol_not_a_pair, cons (x, cell_symbol_car));
#endif
  return x->car;
}

struct scm *
cdr (struct scm *x)
{
#if !__MESC_MES__
  if (x->type != TPAIR)
    error (cell_symbol_not_a_pair, cons (x, cell_symbol_cdr));
#endif
  return x->cdr;
}

struct scm *
list (struct scm *x)                    /*:((arity . n)) */
{
  return x;
}

struct scm *
null_p (struct scm *x)
{
  if (x == cell_nil)
    return cell_t;
  return cell_f;
}

struct scm *
eq_p (struct scm *x, struct scm *y)
{
  if (x == y)
    return cell_t;
  int t = x->type;
  if (t == TKEYWORD)
    {
      if (y->type == TKEYWORD)
        return string_equal_p (x, y);
      return cell_f;
    }
  if (t == TCHAR)
    {
      if (y->type != TCHAR)
        return cell_f;
      if (x->value == y->value)
        return cell_t;
      return cell_f;
    }
  if (t == TNUMBER)
    {
      if (y->type != TNUMBER)
        return cell_f;
      if (x->value == y->value)
        return cell_t;
      return cell_f;
    }
  return cell_f;
}

struct scm *
values (struct scm *x)                  /*:((arity . n)) */
{
  struct scm *v = cons (0, x);
  v->type = TVALUES;
  return v;
}

struct scm *
acons (struct scm *key, struct scm *value, struct scm *alist)
{
  return cons (cons (key, value), alist);
}

long
length__ (struct scm *x)                /*:((internal)) */
{
  long n = 0;
  while (x != cell_nil)
    {
      n = n + 1;
      if (x->type != TPAIR)
        return -1;
      x = x->cdr;
    }
  return n;
}

struct scm *
length (struct scm *x)
{
  return make_number (length__ (x));
}

struct scm *
error (struct scm *key, struct scm *x)
{
#if !__MESC_MES__ && !__M2_PLANET__
  struct scm *throw = module_ref (R0, cell_symbol_throw);
  if (throw != cell_undefined)
    return apply (throw, cons (key, cons (x, cell_nil)), R0);
#endif
  display_error_ (key);
  eputs (": ");
  write_error_ (x);
  eputs ("\n");
  assert_msg (0, "ERROR");
  exit (1);
}

struct scm *
append2 (struct scm *x, struct scm *y)
{
  if (x == cell_nil)
    return y;
  if (x->type != TPAIR)
    error (cell_symbol_not_a_pair, cons (x, cstring_to_symbol ("append2")));
  struct scm *r = cell_nil;
  while (x != cell_nil)
    {
      r = cons (x->car, r);
      x = x->cdr;
    }
  return reverse_x_ (r, y);
}

struct scm *
append_reverse (struct scm *x, struct scm *y)
{
  if (x == cell_nil)
    return y;
  if (x->type != TPAIR)
    error (cell_symbol_not_a_pair, cons (x, cstring_to_symbol ("append-reverse")));
  while (x != cell_nil)
    {
      y = cons (x->car, y);
      x = x->cdr;
    }
  return y;
}

struct scm *
reverse_x_ (struct scm *x, struct scm *t)
{
  if (x != cell_nil && x->type != TPAIR)
    error (cell_symbol_not_a_pair, cons (x, cstring_to_symbol ("core:reverse!")));
  struct scm *r = t;
  while (x != cell_nil)
    {
      t = x->cdr;
      x->cdr = r;
      r = x;
      x = t;
    }
  return r;
}

struct scm *
assq (struct scm *x, struct scm *a)
{
  if (a->type != TPAIR)
    return cell_f;
  int t = x->type;

  if (t == TSYMBOL || t == TSPECIAL)
    while (a != cell_nil)
      {
        if (x == a->car->car)
          return a->car;
        a = a->cdr;
      }
  else if (t == TCHAR || t == TNUMBER)
    {
      long v = x->value;
      while (a != cell_nil)
        {
          if (v == a->car->car->value)
            return a->car;
          a = a->cdr;
        }
    }
  else if (t == TKEYWORD)
    {
      while (a != cell_nil)
        {
          if (string_equal_p (x, a->car->car) == cell_t)
            return a->car;
          a = a->cdr;
        }
    }
  else
    /* pointer equality, e.g. on strings. */
    while (a != cell_nil)
      {
        if (x == a->car->car)
          return a->car;
        a = a->cdr;
      }
  return cell_f;
}

struct scm *
assoc (struct scm *x, struct scm *a)
{
  if (x->type == TSTRING)
    return assoc_string (x, a);
  while (a != cell_nil)
    {
      if (equal2_p (x, a->car->car) == cell_t)
        return a->car;
      a = a->cdr;
    }
  return cell_f;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/src/display.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/src/display.c used in: Step 106, Step 215
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "mes/lib.h"
#include "mes/mes.h"

#include <stdlib.h>

int g_depth;

void
fdwrite_char (char v, int fd)
{
  if (v == '\0')
    fdputs ("\\nul", fd);
  else if (v == '\a')
    fdputs ("\\alarm", fd);
  else if (v == '\b')
    fdputs ("\\backspace", fd);
  else if (v == '\t')
    fdputs ("\\tab", fd);
  else if (v == '\n')
    fdputs ("\\newline", fd);
  else if (v == '\v')
    fdputs ("\\vtab", fd);
  else if (v == '\f')
    fdputs ("\\page", fd);
  /* Nyacc bug
     else if (v == '\r') fdputs ("return", fd);
  */
  else if (v == 13)
    fdputs ("\\return", fd);
  else if (v == ' ')
    fdputs ("\\space", fd);
  else
    {
      if (v >= 32 && v <= 127)
        fdputc ('\\', fd);
      fdputc (v, fd);
    }
}

void
fdwrite_string_char (char v, int fd)
{
  if (v == '\0')
    fdputs ("\\0", fd);
  else if (v == '\a')
    fdputs ("\\a", fd);
  else if (v == '\b')
    fdputs ("\\b", fd);
  else if (v == '\t')
    fdputs ("\\t", fd);
  else if (v == '\v')
    fdputs ("\\v", fd);
  else if (v == '\n')
    fdputs ("\\n", fd);
  else if (v == '\f')
    fdputs ("\\f", fd);
  /* Nyacc bug
     else if (v == '\r') fdputs ("\\r", fd);
     else if (v == '\e') fdputs ("\\e", fd);
  */
  else if (v == 13)
    fdputs ("\\r", fd);
  else if (v == 27)
    fdputs ("\\e", fd);
  else if (v == '\\')
    fdputs ("\\\\", fd);
  else if (v == '"')
    fdputs ("\\\"", fd);
  else
    fdputc (v, fd);
}

void
fdwrite_string (char *s, int length, int fd)
{
  int i;
  for (i = 0; i < length; i = i + 1)
    fdwrite_string_char (s[i], fd);
}

struct scm *display_helper (struct scm *x, int cont, char *sep, int fd, int write_p);

struct scm *
display_helper (struct scm *x, int cont, char *sep, int fd, int write_p)
{
  fdputs (sep, fd);
  if (g_depth == 0)
    return cell_unspecified;
  g_depth = g_depth - 1;

  int t = x->type;
  if (t == TCHAR)
    {
      if (write_p == 0)
        fdputc (x->value, fd);
      else
        {
          fdputs ("#", fd);
          fdwrite_char (x->value, fd);
        }
    }
  else if (t == TCLOSURE)
    {
      fdputs ("#<closure ", fd);
      struct scm *circ = x->cdr->car;
      struct scm *name = circ->cdr->car;
      struct scm *args = x->cdr->cdr->car;
      display_helper (name->car, 0, "", fd, 0);
      fdputc (' ', fd);
      display_helper (args, 0, "", fd, 0);
      fdputs (">", fd);
    }
  else if (t == TMACRO)
    {
      fdputs ("#<macro ", fd);
      display_helper (x->cdr, cont, "", fd, 0);
      fdputs (">", fd);
    }
  else if (t == TVARIABLE)
    {
      fdputs ("#<variable ", fd);
      display_helper (x->variable->car, cont, "", fd, 0);
      fdputs (">", fd);
    }
  else if (t == TNUMBER)
    {
      fdputs (itoa (x->value), fd);
    }
  else if (t == TPAIR)
    {
      if (cont == 0)
        fdputs ("(", fd);
      if (x->car == cell_circular && x->cdr->car != cell_closure)
        {
          fdputs ("(*circ* . ", fd);
          int i = 0;
          x = x->cdr;
          while (x != cell_nil && i < 10)
            {
              i = i + 1;
              fdisplay_ (x->car->car, fd, write_p);
              fdputs (" ", fd);
              x = x->cdr;
            }
          fdputs (" ...)", fd);
        }
      else
        {
          if (x != 0 && x != cell_nil)
            fdisplay_ (x->car, fd, write_p);
          if (x->cdr != 0 && x->cdr->type == TPAIR)
            display_helper (x->cdr, 1, " ", fd, write_p);
          else if (x->cdr != 0 && x->cdr != cell_nil)
            {
              if (x->cdr->type != TPAIR)
                fdputs (" . ", fd);
              fdisplay_ (x->cdr, fd, write_p);
            }
        }
      if (cont == 0)
        fdputs (")", fd);
    }
  else if (t == TPORT)
    {
      fdputs ("#<port ", fd);
      fdputs (itoa (x->port), fd);
      fdputs (" ", fd);
      x = x->string;
      fdputc ('"', fd);
      fdwrite_string (cell_bytes (x->string), x->length, fd);
      fdputc ('"', fd);
      fdputs (">", fd);
    }
  else if (t == TKEYWORD)
    {
      fdputs ("#:", fd);
      fdwrite_string (cell_bytes (x->string), x->length, fd);
    }
  else if (t == TSTRING)
    {
      if (write_p == 1)
        {
          fdputc ('"', fd);
          fdwrite_string (cell_bytes (x->string), x->length, fd);
          fdputc ('"', fd);
        }
      else
        fdputs (cell_bytes (x->string), fd);
    }
  else if (t == TSPECIAL || t == TSYMBOL)
    fdwrite_string (cell_bytes (x->string), x->length, fd);
  else if (t == TREF)
    fdisplay_ (x->ref, fd, write_p);
  else if (t == TSTRUCT)
    {
      struct scm *printer = struct_ref_ (x, STRUCT_PRINTER);
      if (printer->type == TREF)
        printer = printer->ref;
      if (printer->type == TCLOSURE || builtin_p (printer) == cell_t)
        apply (printer, cons (x, cell_nil), R0);
      else
        {
          fdputs ("#<", fd);
          fdisplay_ (x->structure, fd, write_p);
          struct scm *t = x->car;
          long size = x->length;
          long i;
          for (i = 2; i < size; i = i + 1)
            {
              fdputc (' ', fd);
              fdisplay_ (cell_ref (x->structure, i), fd, write_p);
            }
          fdputc ('>', fd);
        }
    }
  else if (t == TVECTOR)
    {
      fdputs ("#(", fd);
      struct scm *t = x->car;
      long i;
      for (i = 0; i < x->length; i = i + 1)
        {
          if (i != 0)
            fdputc (' ', fd);
          fdisplay_ (cell_ref (x->vector, i), fd, write_p);
        }
      fdputc (')', fd);
    }
  else
    {
      fdputs ("<", fd);
      fdputs (itoa (t), fd);
      fdputs (":", fd);
      fdputs (ltoa (cast_voidp_to_long (x)), fd);
      fdputs (">", fd);
    }
  return cell_unspecified;
}

struct scm *
display_ (struct scm *x)
{
  g_depth = 5;
  return display_helper (x, 0, "", __stdout, 0);
}

struct scm *
display_error_ (struct scm *x)
{
  g_depth = 5;
  return display_helper (x, 0, "", __stderr, 0);
}

struct scm *
display_port_ (struct scm *x, struct scm *p)
{
  assert_msg (p->type == TNUMBER, "p->type == TNUMBER");
  return fdisplay_ (x, p->value, 0);
}

struct scm *
write_ (struct scm *x)
{
  g_depth = 5;
  return display_helper (x, 0, "", __stdout, 1);
}

struct scm *
write_error_ (struct scm *x)
{
  g_depth = 5;
  return display_helper (x, 0, "", __stderr, 1);
}

struct scm *
write_port_ (struct scm *x, struct scm *p)
{
  assert_msg (p->type == TNUMBER, "p->type == TNUMBER");
  return fdisplay_ (x, p->value, 1);
}

struct scm *
fdisplay_ (struct scm *x, int fd, int write_p)  /*:((internal)) */
{
  g_depth = 5;
  return display_helper (x, 0, "", fd, write_p);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/src/eval-apply.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/src/eval-apply.c used in: Step 106, Step 216
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "mes/lib.h"
#include "mes/mes.h"

#include <string.h>

struct scm *
assert_defined (struct scm *x, struct scm *e)   /*:((internal)) */
{
  if (e == cell_undefined)
    return error (cell_symbol_unbound_variable, x);
  return e;
}

struct scm *
check_formals (struct scm *f, struct scm *formals, struct scm *args)    /*:((internal)) */
{
  long flen;
  if (formals->type == TNUMBER)
    flen = formals->value;
  else
    flen = length__ (formals);
  long alen = length__ (args);
  if (alen != flen && alen != -1 && flen != -1)
    {
      char *s = "apply: wrong number of arguments; expected: ";
      eputs (s);
      eputs (itoa (flen));
      eputs (", got: ");
      eputs (itoa (alen));
      eputs ("\n");
      write_error_ (f);
      struct scm *e = make_string0 (s);
      return error (cell_symbol_wrong_number_of_args, cons (e, f));
    }
  return cell_unspecified;
}

struct scm *
check_apply (struct scm *f, struct scm *e)      /*:((internal)) */
{
  char *type = 0;
  if (f == cell_f || f == cell_t)
    type = "bool";
  if (f == cell_nil)
    type = "nil";
  if (f == cell_unspecified)
    type = "*unspecified*";
  if (f == cell_undefined)
    type = "*undefined*";
  if (f->type == TCHAR)
    type = "char";
  if (f->type == TNUMBER)
    type = "number";
  if (f->type == TSTRING)
    type = "string";
  if (f->type == TSTRUCT && builtin_p (f) == cell_f)
    type = "#<...>";
  if (f->type == TBROKEN_HEART)
    type = "<3";

  if (type != 0)
    {
      char *s = "cannot apply: ";
      eputs (s);
      eputs (type);
      eputs ("[");
      write_error_ (e);
      eputs ("]\n");
      struct scm *e = make_string0 (s);
      return error (cell_symbol_wrong_type_arg, cons (e, f));
    }
  return cell_unspecified;
}

struct scm *
pairlis (struct scm *x, struct scm *y, struct scm *a)
{
  if (x == cell_nil)
    return a;
  if (x->type != TPAIR)
    return cons (cons (x, y), a);
  return cons (cons (car (x), car (y)), pairlis (cdr (x), cdr (y), a));
}

struct scm *
set_car_x (struct scm *x, struct scm *e)
{
  if (x->type != TPAIR)
    error (cell_symbol_not_a_pair, cons (x, cstring_to_symbol ("set-car!")));
  x->car = e;
  return cell_unspecified;
}

struct scm *
set_cdr_x (struct scm *x, struct scm *e)
{
  if (x->type != TPAIR)
    error (cell_symbol_not_a_pair, cons (x, cstring_to_symbol ("set-cdr!")));
  x->cdr = e;
  return cell_unspecified;
}

struct scm *
set_env_x (struct scm *x, struct scm *e, struct scm *a)
{
  struct scm *p;
  if (x->type == TVARIABLE)
    p = x->variable;
  else
    p = assert_defined (x, module_variable (a, x));
  if (p->type != TPAIR)
    error (cell_symbol_not_a_pair, cons (p, x));
  return set_cdr_x (p, e);
}

struct scm *
call_lambda (struct scm *e, struct scm *x, struct scm *aa, struct scm *a)       /*:((internal)) */
{
  struct scm *cl = cons (cons (cell_closure, x), x);
  R1 = e;
  R0 = cl;
  return cell_unspecified;
}

struct scm *
make_closure_ (struct scm *args, struct scm *body, struct scm *a)       /*:((internal)) */
{
  return make_cell (TCLOSURE, cell_f, cons (cons (cell_circular, a), cons (args, body)));
}

struct scm *
make_variable_ (struct scm *var)        /*:((internal)) */
{
  return make_cell (TVARIABLE, var, 0);
}

struct scm *
macro_get_handle (struct scm *name)     /*:((internal)) */
{
  if (name->type == TSYMBOL)
    return hashq_get_handle (g_macros, name, cell_nil);
  return cell_f;
}

struct scm *
get_macro (struct scm *name)            /*:((internal)) */
{
  struct scm *m = macro_get_handle (name);
  if (m != cell_f)
    {
      struct scm *d = m->cdr;
      return d->macro;
    }
  return cell_f;
}

struct scm *
macro_set_x (struct scm *name, struct scm *value)       /*:((internal)) */
{
  return hashq_set_x (g_macros, name, value);
}

struct scm *
push_cc (struct scm *p1, struct scm *p2, struct scm *a, struct scm *c)  /*:((internal)) */
{
  struct scm *x = R3;
  R3 = c;
  R2 = p2;
  gc_push_frame ();
  R1 = p1;
  R0 = a;
  R3 = x;
  return cell_unspecified;
}

struct scm *
add_formals (struct scm *formals, struct scm *x)
{
  while (x->type == TPAIR)
    {
      formals = cons (x->car, formals);
      x = x->cdr;
    }
  if (x->type == TSYMBOL)
    formals = cons (x, formals);
  return formals;
}

int
formal_p (struct scm *x, struct scm *formals)   /*:((internal)) */
{
  if (formals->type == TSYMBOL)
    {
      if (x == formals)
        return 1;
      else
        return 0;
    }
  while (formals->type == TPAIR)
    {
      if (formals->car == x)
        break;
      formals = formals->cdr;
    }
  if (formals->type == TSYMBOL)
    return formals == x;
  return formals->type == TPAIR;
}

struct scm *
expand_variable_ (struct scm *x, struct scm *formals, int top_p)        /*:((internal)) */
{
  struct scm *a;
  struct scm *f;
  struct scm *v;
  while (x->type == TPAIR)
    {
      a = x->car;
      if (a->type == TPAIR)
        {
          if (a->car == cell_symbol_lambda)
            {
              f = a->cdr->car;
              formals = add_formals (formals, f);
            }
          else if (a->car == cell_symbol_define || a->car == cell_symbol_define_macro)
            {
              f = a->cdr->car;
              formals = add_formals (formals, f);
            }
          if (a->car != cell_symbol_quote)
            expand_variable_ (a, formals, 0);
        }
      else
        {
          if (a == cell_symbol_lambda)
            {
              f = x->cdr->car;
              formals = add_formals (formals, f);
              x = x->cdr;
            }
          else if (a == cell_symbol_define || a == cell_symbol_define_macro)
            {
              f = x->cdr->car;
              if (top_p != 0 && f->type == TPAIR)
                f = f->cdr;
              formals = add_formals (formals, f);
              x = x->cdr;
            }
          else if (a == cell_symbol_quote)
            return cell_unspecified;
          else if (a->type == TSYMBOL
                   && a != cell_symbol_boot_module
                   && a != cell_symbol_current_module
                   && a != cell_symbol_primitive_load
                   && formal_p (x->car, formals) == 0)
            {
              v = module_variable (R0, a);
              if (v != cell_f)
                x->car = make_variable_ (v);
            }
        }
      x = x->cdr;
      top_p = 0;
    }
  return cell_unspecified;
}

struct scm *
expand_variable (struct scm *x, struct scm *formals)    /*:((internal)) */
{
  return expand_variable_ (x, formals, 1);
}

struct scm *
apply_builtin (struct scm *fn, struct scm *x)   /*:((internal)) */
{
  struct scm *a = builtin_arity (fn);
  struct scm *d;
  int arity = a->value;
  if ((arity > 0 || arity == -1) && x != cell_nil)
    {
      a = x->car;
      if (a->type == TVALUES)
        x = cons (a->cdr->car, x->cdr);
    }
  if ((arity > 1 || arity == -1) && x != cell_nil)
    {
      a = x->car;
      d = x->cdr;
      if (d->type == TPAIR)
        if (d->car->type == TVALUES)
          x = cons (a, cons (d->car->cdr->car, d));
    }

  if (arity == 0)
    return apply_builtin0 (fn);
  if (arity == 1)
    return apply_builtin1 (fn, x->car);
  else if (arity == 2)
    return apply_builtin2 (fn, x->car, x->cdr->car);
  else if (arity == 3)
    return apply_builtin3 (fn, x->car, x->cdr->car, x->cdr->cdr->car);
  else if (arity == -1)
    return apply_builtin1 (fn, x);

  return cell_unspecified;
}

struct scm *
eval_apply ()
{
  struct scm *aa;
  struct scm *args;
  struct scm *body;
  struct scm *cl;
  struct scm *entry;
  struct scm *expanders;
  struct scm *formals;
  struct scm *input;
  struct scm *name;
  struct scm *macro;
  struct scm *p;
  struct scm *program;
  struct scm *sc_expand;
  struct scm *v;
  struct scm *x;
  int global_p;
  int macro_p;
  struct scm *a;
  struct scm *c;
  struct scm *d;
  int t;
  long i;

eval_apply:
  if (R3 == cell_vm_evlis2)
    goto evlis2;
  else if (R3 == cell_vm_evlis3)
    goto evlis3;
  else if (R3 == cell_vm_eval_check_func)
    goto eval_check_func;
  else if (R3 == cell_vm_eval2)
    goto eval2;
  else if (R3 == cell_vm_apply2)
    goto apply2;
  else if (R3 == cell_vm_if_expr)
    goto if_expr;
  else if (R3 == cell_vm_begin_eval)
    goto begin_eval;
  else if (R3 == cell_vm_eval_set_x)
    goto eval_set_x;
  else if (R3 == cell_vm_macro_expand_car)
    goto macro_expand_car;
  else if (R3 == cell_vm_return)
    goto vm_return;
  else if (R3 == cell_vm_macro_expand_cdr)
    goto macro_expand_cdr;
  else if (R3 == cell_vm_eval_define)
    goto eval_define;
  else if (R3 == cell_vm_macro_expand)
    goto macro_expand;
  else if (R3 == cell_vm_macro_expand_lambda)
    goto macro_expand_lambda;
  else if (R3 == cell_vm_eval_pmatch_car)
    goto eval_pmatch_car;
  else if (R3 == cell_vm_begin_expand_macro)
    goto begin_expand_macro;
  else if (R3 == cell_vm_macro_expand_define)
    goto macro_expand_define;
  else if (R3 == cell_vm_begin_expand_eval)
    goto begin_expand_eval;
  else if (R3 == cell_vm_call_with_current_continuation2)
    goto call_with_current_continuation2;
  else if (R3 == cell_vm_macro_expand_set_x)
    goto macro_expand_set_x;
  else if (R3 == cell_vm_eval_pmatch_cdr)
    goto eval_pmatch_cdr;
  else if (R3 == cell_vm_macro_expand_define_macro)
    goto macro_expand_define_macro;
  else if (R3 == cell_vm_begin_primitive_load)
    goto begin_primitive_load;

  else if (R3 == cell_vm_evlis)
    goto evlis;
  else if (R3 == cell_vm_apply)
    goto apply;
  else if (R3 == cell_vm_eval)
    goto eval;
  else if (R3 == cell_vm_eval_macro_expand_eval)
    goto eval_macro_expand_eval;
  else if (R3 == cell_vm_eval_macro_expand_expand)
    goto eval_macro_expand_expand;
  else if (R3 == cell_vm_begin)
    goto begin;
  else if (R3 == cell_vm_begin_expand)
    goto begin_expand;
  else if (R3 == cell_vm_begin_expand_primitive_load)
    goto begin_expand_primitive_load;
  else if (R3 == cell_vm_if)
    goto vm_if;
  else if (R3 == cell_vm_call_with_values2)
    goto call_with_values2;
  else if (R3 == cell_unspecified)
    return R1;
  else
    assert_msg (0, "eval/apply unknown continuation");

evlis:
  if (R1 == cell_nil)
    goto vm_return;
  if (R1->type != TPAIR)
    goto eval;
  push_cc (R1->car, R1, R0, cell_vm_evlis2);
  goto eval;
evlis2:
  push_cc (R2->cdr, R1, R0, cell_vm_evlis3);
  goto evlis;
evlis3:
  R1 = cons (R2, R1);
  goto vm_return;

apply:
  g_stack_array[g_stack + GC_FRAME_PROCEDURE] = R1->car;
  a = R1->car;
  t = a->type;
  if (t == TSTRUCT && builtin_p (R1->car) == cell_t)
    {
      check_formals (R1->car, builtin_arity (R1->car), R1->cdr);
      R1 = apply_builtin (R1->car, R1->cdr);
      goto vm_return;
    }
  else if (t == TCLOSURE)
    {
      cl = R1->car->closure;
      body = cl->cdr->cdr;
      formals = cl->cdr->car;
      args = R1->cdr;
      aa = cl->car->cdr;
      aa = aa->cdr;
      check_formals (R1->car, formals, R1->cdr);
      p = pairlis (formals, args, aa);
      call_lambda (body, p, aa, R0);
      goto begin;
    }
  else if (t == TCONTINUATION)
    {
      a = R1->car;
      v = a->continuation;
      if (v->length != 0)
        {
          for (i = 0; i < v->length; i = i + 1)
            g_stack_array[STACK_SIZE - v->length + i] = vector_ref_ (v, i);
          g_stack = STACK_SIZE - v->length;
        }
      x = R1;
      gc_pop_frame ();
      R1 = x->cdr->car;
      goto eval_apply;
    }
  else if (t == TSPECIAL)
    {
      c = R1->car;
      if (c == cell_vm_apply)
        {
          push_cc (cons (R1->cdr->car, R1->cdr->cdr->car), R1, R0, cell_vm_return);
          goto apply;
        }
      else if (c == cell_vm_eval)
        {
          push_cc (R1->cdr->car, R1, R1->cdr->cdr->car, cell_vm_return);
          goto eval;
        }
      else if (c == cell_vm_begin_expand)
        {
          push_cc (cons (R1->cdr->car, cell_nil), R1, R1->cdr->cdr->car, cell_vm_return);
          goto begin_expand;
        }
      else
        check_apply (cell_f, R1->car);
    }
  else if (t == TSYMBOL)
    {
      c = R1->car;
      if (c == cell_symbol_call_with_current_continuation)
        {
          R1 = R1->cdr;
          goto call_with_current_continuation;
        }
      if (c == cell_symbol_call_with_values)
        {
          R1 = R1->cdr;
          goto call_with_values;
        }
      if (c == cell_symbol_current_module)
        {
          R1 = R0;
          goto vm_return;
        }
      if (c == cell_symbol_boot_module)
        {
          R1 = M0;
          goto vm_return;
        }
    }
  else if (t == TPAIR)
    {
      if (R1->car->car == cell_symbol_lambda)
        {
          formals = R1->car->cdr->car;
          args = R1->cdr;
          body = R1->car->cdr->cdr;
          p = pairlis (formals, R1->cdr, R0);
          check_formals (R1, formals, args);
          call_lambda (body, p, p, R0);
          goto begin;
        }
    }
  push_cc (R1->car, R1, R0, cell_vm_apply2);
  goto eval;
apply2:
  check_apply (R1, R2->car);
  R1 = cons (R1, R2->cdr);
  goto apply;

eval:
  t = R1->type;
  if (t == TPAIR)
    {
      c = R1->car;
      if (c == cell_symbol_pmatch_car)
        {
          push_cc (R1->cdr->car, R1, R0, cell_vm_eval_pmatch_car);
          goto eval;
        eval_pmatch_car:
          x = R1;
          gc_pop_frame ();
          R1 = x->car;
          goto eval_apply;
        }
      else if (c == cell_symbol_pmatch_cdr)
        {
          push_cc (R1->cdr->car, R1, R0, cell_vm_eval_pmatch_cdr);
          goto eval;
        eval_pmatch_cdr:
          x = R1;
          gc_pop_frame ();
          R1 = x->cdr;
          goto eval_apply;
        }
      else if (c == cell_symbol_quote)
        {
          x = R1;
          gc_pop_frame ();
          R1 = x->cdr->car;
          goto eval_apply;
        }
      else if (c == cell_symbol_begin)
        goto begin;
      else if (c == cell_symbol_lambda)
        {
          R1 = make_closure_ (R1->cdr->car, R1->cdr->cdr, R0);
          goto vm_return;
        }
      else if (c == cell_symbol_if)
        {
          R1 = R1->cdr;
          goto vm_if;
        }
      else if (c == cell_symbol_set_x)
        {
          push_cc (R1->cdr->cdr->car, R1, R0, cell_vm_eval_set_x);
          goto eval;
        eval_set_x:
          R1 = set_env_x (R2->cdr->car, R1, R0);
          goto vm_return;
        }
      else if (c == cell_vm_macro_expand)
        {
          push_cc (R1->cdr->car, R1, R0, cell_vm_eval_macro_expand_eval);
          goto eval;
        eval_macro_expand_eval:
          push_cc (R1, R2, R0, cell_vm_eval_macro_expand_expand);
          goto macro_expand;
        eval_macro_expand_expand:
          goto vm_return;
        }
      else
        {
          if (R1->type == TPAIR)
            if (R1->car == cell_symbol_define || R1->car == cell_symbol_define_macro)
              {
                global_p = 0;
                if (R0->car->car != cell_closure)
                  global_p = 1;
                macro_p = 0;
                if (R1->car == cell_symbol_define_macro)
                  macro_p = 1;
                if (global_p != 0)
                  {
                    name = R1->cdr->car;
                    aa = R1->cdr->car;
                    if (aa->type == TPAIR)
                      name = name->car;
                    if (macro_p != 0)
                      {
                        entry = assq (name, g_macros);
                        if (entry == cell_f)
                          macro_set_x (name, cell_f);
                      }
                    else
                      {
                        entry = module_variable (R0, name);
                        if (entry == cell_f)
                          module_define_x (M0, name, cell_f);
                      }
                  }
                R2 = R1;
                aa = R1->cdr->car;
                if (aa->type != TPAIR)
                  {
                    push_cc (R1->cdr->cdr->car, R2, cons (cons (R1->cdr->car, R1->cdr->car), R0), cell_vm_eval_define);
                    goto eval;
                  }
                else
                  {
                    p = pairlis (R1->cdr->car, R1->cdr->car, R0);
                    formals = R1->cdr->car->cdr;
                    body = R1->cdr->cdr;

                    if (macro_p != 0 || global_p != 0)
                      expand_variable (body, formals);
                    R1 = cons (cell_symbol_lambda, cons (formals, body));
                    push_cc (R1, R2, p, cell_vm_eval_define);
                    goto eval;
                  }
              eval_define:
                name = R2->cdr->car;
                aa = R2->cdr->car;
                if (aa->type == TPAIR)
                  name = name->car;
                if (macro_p != 0)
                  {
                    entry = macro_get_handle (name);
                    R1 = make_macro (name, R1);
                    set_cdr_x (entry, R1);
                  }
                else if (global_p != 0)
                  {
                    entry = module_variable (R0, name);
                    set_cdr_x (entry, R1);
                  }
                else
                  {
                    entry = cons (name, R1);
                    aa = cons (entry, cell_nil);
                    set_cdr_x (aa, cdr (R0));
                    set_cdr_x (R0, aa);
                    cl = module_variable (R0, cell_closure);
                    set_cdr_x (cl, aa);
                  }
                R1 = cell_unspecified;
                goto vm_return;
              }
          push_cc (R1->car, R1, R0, cell_vm_eval_check_func);
          gc_check ();
          goto eval;
        eval_check_func:
          push_cc (R2->cdr, R2, R0, cell_vm_eval2);
          goto evlis;
        eval2:
          R1 = cons (R2->car, R1);
          goto apply;
        }
    }
  else if (t == TSYMBOL)
    {
      if (R1 == cell_symbol_boot_module)
        goto vm_return;
      if (R1 == cell_symbol_current_module)
        goto vm_return;
      if (R1 == cell_symbol_begin)
        goto vm_return;
      if (R1 == cell_symbol_call_with_current_continuation)
        goto vm_return;
      R1 = assert_defined (R1, module_ref (R0, R1));
      goto vm_return;
    }
  else if (t == TVARIABLE)
    {
      x = R1->variable;
      R1 = x->cdr;
      goto vm_return;
    }
  else if (t == TBROKEN_HEART)
    error (cell_symbol_system_error, R1);
  else
    goto vm_return;

macro_expand:
  if (R1->type != TPAIR || R1->car == cell_symbol_quote)
    goto vm_return;

  if (R1->car == cell_symbol_lambda)
    {
      push_cc (R1->cdr->cdr, R1, R0, cell_vm_macro_expand_lambda);
      goto macro_expand;
    macro_expand_lambda:
      R2->cdr->cdr = R1;
      R1 = R2;
      goto vm_return;
    }

  if (R1->type == TPAIR)
    {
      macro = get_macro (R1->car);
      if (macro != cell_f)
        {
          R1 = cons (macro, R1->cdr);
          push_cc (R1, cell_nil, R0, cell_vm_macro_expand);
          goto apply;
        }
    }

  if (R1->car == cell_symbol_define || R1->car == cell_symbol_define_macro)
    {
      push_cc (R1->cdr->cdr, R1, R0, cell_vm_macro_expand_define);
      goto macro_expand;
    macro_expand_define:
      R2->cdr->cdr = R1;
      R1 = R2;
      if (R1->car == cell_symbol_define_macro)
        {
          push_cc (R1, R1, R0, cell_vm_macro_expand_define_macro);
          goto eval;
        macro_expand_define_macro:
          R1 = R2;
        }
      goto vm_return;
    }

  if (R1->car == cell_symbol_set_x)
    {
      push_cc (R1->cdr->cdr, R1, R0, cell_vm_macro_expand_set_x);
      goto macro_expand;
    macro_expand_set_x:
      R2->cdr->cdr = R1;
      R1 = R2;
      goto vm_return;
    }

  if (R1->type == TPAIR)
    {
      a = R1->car;
      if (a->type == TSYMBOL && a != cell_symbol_begin)
        {
          macro = macro_get_handle (cell_symbol_portable_macro_expand);
          if (macro != cell_f)
            {
              expanders = module_ref (R0, cell_symbol_sc_expander_alist);
              if (expanders != cell_undefined)
                {
                  macro = assq (R1->car, expanders);
                  if (macro != cell_f)
                    {
                      sc_expand = module_ref (R0, cell_symbol_macro_expand);
                      R2 = R1;
                      if (sc_expand != cell_undefined && sc_expand != cell_f)
                        {
                          R1 = cons (sc_expand, cons (R1, cell_nil));
                          goto apply;
                        }
                    }
                }
            }
        }
    }

  push_cc (R1->car, R1, R0, cell_vm_macro_expand_car);
  goto macro_expand;

macro_expand_car:
  R2->car = R1;
  R1 = R2;
  if (R1->cdr == cell_nil)
    goto vm_return;

  push_cc (R1->cdr, R1, R0, cell_vm_macro_expand_cdr);
  goto macro_expand;

macro_expand_cdr:
  R2->cdr = R1;
  R1 = R2;

  goto vm_return;

begin:
  x = cell_unspecified;
  while (R1 != cell_nil)
    {
      gc_check ();
      if (R1->type == TPAIR)
        {
          if (R1->car->car == cell_symbol_primitive_load)
            {
              program = cons (R1->car, cell_nil);
              push_cc (program, R1, R0, cell_vm_begin_primitive_load);
              goto begin_expand;
            begin_primitive_load:
              R2->car = R1;
              R1 = R2;
            }
        }

      if (R1->type == TPAIR)
        {
          a = R1->car;
          if (a->type == TPAIR)
            {
              if (a->car == cell_symbol_begin)
                R1 = append2 (a->cdr, R1->cdr);
            }
        }
      if (R1->cdr == cell_nil)
        {
          R1 = R1->car;
          goto eval;
        }
      push_cc (R1->car, R1, R0, cell_vm_begin_eval);
      goto eval;
    begin_eval:
      x = R1;
      R1 = R2->cdr;
    }
  R1 = x;
  goto vm_return;


begin_expand:
  x = cell_unspecified;
  while (R1 != cell_nil)
    {
    begin_expand_while:
      gc_check ();

      if (R1->type == TPAIR)
        {
          a = R1->car;
          if (a->type == TPAIR)
            if (R1->car->car == cell_symbol_begin)
              R1 = append2 (R1->car->cdr, R1->cdr);
          if (R1->car->car == cell_symbol_primitive_load)
            {
              push_cc (R1->car->cdr->car, R1, R0, cell_vm_begin_expand_primitive_load);
              goto eval;
            begin_expand_primitive_load:
              if ((R1->type == TNUMBER) && R1->value == 0)
                0;
              else if (R1->type == TSTRING)
                input = set_current_input_port (open_input_file (R1));
              else if (R1->type == TPORT)
                input = set_current_input_port (R1);
              else
                {
                  eputs ("begin_expand failed, R1=");
                  display_error_ (R1);
                  assert_msg (0, "begin-expand-boom 0");
                }

              push_cc (input, R2, R0, cell_vm_return);
              x = read_input_file_env (R0);
              if (g_debug > 5)
                module_printer (M0);
              gc_pop_frame ();
              input = R1;
              R1 = x;
              set_current_input_port (input);
              R1 = cons (cell_symbol_begin, R1);
              R2->car = R1;
              R1 = R2;
              goto begin_expand_while;
              continue; /* FIXME: M2-PLanet */
            }
        }

      push_cc (R1->car, R1, R0, cell_vm_begin_expand_macro);
      goto macro_expand;
    begin_expand_macro:
      if (R1 != R2->car)
        {
          R2->car = R1;
          R1 = R2;
          goto begin_expand_while;
          continue; /* FIXME: M2-PLanet */
        }
      R1 = R2;
      expand_variable (R1->car, cell_nil);
      push_cc (R1->car, R1, R0, cell_vm_begin_expand_eval);
      goto eval;
    begin_expand_eval:
      x = R1;
      R1 = R2->cdr;
    }
  R1 = x;
  goto vm_return;

vm_if:
  push_cc (R1->car, R1, R0, cell_vm_if_expr);
  goto eval;
if_expr:
  x = R1;
  R1 = R2;
  if (x != cell_f)
    {
      R1 = R1->cdr->car;
      goto eval;
    }
  if (R1->cdr->cdr != cell_nil)
    {
      R1 = R1->cdr->cdr->car;
      goto eval;
    }
  R1 = cell_unspecified;
  goto vm_return;

call_with_current_continuation:
  gc_push_frame ();
  x = make_continuation (g_continuations);
  g_continuations = g_continuations + 1;
  v = make_vector_ (STACK_SIZE - g_stack, cell_unspecified);
  for (i = g_stack; i < STACK_SIZE; i = i + 1)
    vector_set_x_ (v, i - g_stack, g_stack_array[i]);
  x->continuation = v;
  gc_pop_frame ();
  push_cc (cons (R1->car, cons (x, cell_nil)), x, R0, cell_vm_call_with_current_continuation2);
  goto apply;
call_with_current_continuation2:
  v = make_vector_ (STACK_SIZE - g_stack, cell_unspecified);
  for (i = g_stack; i < STACK_SIZE; i = i + 1)
    vector_set_x_ (v, i - g_stack, g_stack_array[i]);
  R2->continuation = v;
  goto vm_return;

call_with_values:
  push_cc (cons (R1->car, cell_nil), R1, R0, cell_vm_call_with_values2);
  goto apply;
call_with_values2:
  if (R1->type == TVALUES)
    R1 = R1->cdr;
  R1 = cons (R2->cdr->car, R1);
  goto apply;

vm_return:
  x = R1;
  gc_pop_frame ();
  R1 = x;
  goto eval_apply;
}

struct scm *
apply (struct scm *f, struct scm *x, struct scm *a)     /*:((internal)) */
{
  push_cc (cons (f, x), cell_unspecified, R0, cell_unspecified);
  R3 = cell_vm_apply;
  return eval_apply ();
}

https://git.savannah.gnu.org/cgit/mes.git/tree/src/gc.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/src/gc.c used in: Step 106, Step 217
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2020,2021 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 * Copyright © 2022 Gabriel Wicki <gabriel@erlikon.ch>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "mes/lib.h"
#include "mes/mes.h"

#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>

int g_dump_filedes;

#define M2_CELL_SIZE 1U
// CONSTANT M2_CELL_SIZE 12

char *
cell_bytes (struct scm *x)
{
  char *p = cast_voidp_to_charp (x);
  return p + (2 * sizeof (long));
}

#define U10 10U
// CONSTANT U10 10
#define U100 100U
// CONSTANT U100 100
void
gc_init ()
{
#if SYSTEM_LIBC
  ARENA_SIZE = 100000000;       /* 2.3GiB */
#elif ! __M2_PLANET__
  ARENA_SIZE = 300000;          /* 32b: 3MiB, 64b: 6 MiB */
#else
  ARENA_SIZE = 20000000;
#endif
  STACK_SIZE = 20000;

  JAM_SIZE = 10;
  MAX_ARENA_SIZE = 10000000;
  GC_SAFETY = 2000;
  MAX_STRING = 524288;

  char *p;
  p = getenv ("MES_MAX_ARENA");
  if (p != 0)
    MAX_ARENA_SIZE = atoi (p);
  p = getenv ("MES_ARENA");
  if (p != 0)
    ARENA_SIZE = atoi (p);
  JAM_SIZE = ARENA_SIZE / U10;
  p = getenv ("MES_JAM");
  if (p != 0)
    JAM_SIZE = atoi (p);
  GC_SAFETY = ARENA_SIZE / U100;
  p = getenv ("MES_SAFETY");
  if (p != 0)
    GC_SAFETY = atoi (p);
  p = getenv ("MES_STACK");
  if (p != 0)
    STACK_SIZE = atoi (p);
  p = getenv ("MES_MAX_STRING");
  if (p != 0)
    MAX_STRING = atoi (p);

  long arena_bytes = (ARENA_SIZE + JAM_SIZE) * sizeof (struct scm);
  long alloc_bytes = arena_bytes + (STACK_SIZE * sizeof (struct scm));

  g_arena = malloc (alloc_bytes);
  g_cells = cast_charp_to_scmp (g_arena);
  g_stack_array = cast_charp_to_scmpp (g_arena + arena_bytes);

  /* The vector that holds the arenea. */
  cell_arena = g_cells;

  cell_zero = cell_arena + M2_CELL_SIZE;

  g_cells = g_cells + M2_CELL_SIZE; /* Hmm? */

  cell_arena->type = TVECTOR;
  cell_arena->length = 1000;
  cell_arena->vector = cell_zero;

  cell_zero->type = TCHAR;
  cell_zero->value = 'c';

  g_free = g_cells + M2_CELL_SIZE;

  /* FIXME: remove MES_MAX_STRING, grow dynamically. */
  g_buf = malloc (MAX_STRING);
}

long
gc_free ()
{
  return (g_free - g_cells) / M2_CELL_SIZE;
}

void
gc_stats_ (char const* where)
{
  size_t i = g_free - g_cells;
  i = i / M2_CELL_SIZE;
  if (where)
    {
      eputs (where);
      eputs (": ");
    }
  eputs ("[");
  eputs (ltoa (i));
  eputs ("]\n");
}

struct scm *
gc_stats ()
{
  gc_stats_ (0);
  size_t arena_used = g_free - g_cells;
  arena_used = arena_used / M2_CELL_SIZE;
  size_t arena_free = ARENA_SIZE - arena_used;
  struct scm *r = cell_nil;
  r =  acons (cstring_to_symbol ("gc-count"), make_number (gc_count), r);
  r =  acons (cstring_to_symbol ("gc-time"), make_number (gc_time), r);
  r =  acons (cstring_to_symbol ("arena-free"), make_number (arena_free), r);
  r =  acons (cstring_to_symbol ("arena-size"), make_number (ARENA_SIZE), r);
  return r;
}

struct scm *
alloc (long n)
{
  struct scm *x = g_free;
  g_free = g_free + (n * M2_CELL_SIZE);
  long i = g_free - g_cells;
  i = i / M2_CELL_SIZE;

  if (i > ARENA_SIZE)
    assert_msg (0, "alloc: out of memory");
  return x;
}

struct scm *
make_cell (long type, struct scm *car, struct scm *cdr)
{
  struct scm *x = g_free;
  g_free = g_free + M2_CELL_SIZE;
  long i = g_free - g_cells;
  i = i / M2_CELL_SIZE;
  if (i > ARENA_SIZE)
    assert_msg (0, "make_cell: out of memory");
  x->type = type;
  x->car = car;
  x->cdr = cdr;
  return x;
}

struct scm *
make_pointer_cell (long type, long car, void *cdr)
{
  struct scm *x = g_free;
  g_free = g_free + M2_CELL_SIZE;
  long i = g_free - g_cells;
  i = i / M2_CELL_SIZE;
  if (i > ARENA_SIZE)
    assert_msg (0, "make_pointer_cell: out of memory");
  x->type = type;
  x->length = car;
  x->cdr = cdr;
  return x;
}

struct scm *
make_value_cell (long type, long car, long cdr)
{
  struct scm *x = g_free;
  g_free = g_free + M2_CELL_SIZE;
  long i = g_free - g_cells;
  i = i / M2_CELL_SIZE;
  if (i > ARENA_SIZE)
    assert_msg (0, "make_value_cell: out of memory");
  x->type = type;
  x->length = car;
  x->value = cdr;
  return x;
}

void
copy_cell (struct scm *to, struct scm *from)
{
  to->type = from->type;
  to->car = from->car;
  to->cdr = from->cdr;
}

void
copy_stack (long index, struct scm *from)
{
  g_stack_array[index] = from;
}

struct scm *
cell_ref (struct scm *cell, long index)
{
  return cell + (index * M2_CELL_SIZE);
}

struct scm *
cons (struct scm *x, struct scm *y)
{
  return make_cell (TPAIR, x, y);
}

size_t
bytes_cells (size_t length)
{
  return (sizeof (long) + sizeof (long) + length - 1 + sizeof (struct scm *)) / sizeof (struct scm *);
}

struct scm *
make_bytes (char const *s, size_t length)
{
  size_t size = bytes_cells (length);
  struct scm *x = alloc (size);
  x->type = TBYTES;
  x->length = length;
  char *p = cell_bytes (x);
  if (length == 0)
    p[0] = 0;
  else
    memcpy (p, s, length);

  return x;
}

struct scm *
make_char (int n)
{
  return make_value_cell (TCHAR, 0, n);
}

struct scm *
make_continuation (long n)
{
  return make_value_cell (TCONTINUATION, n, g_stack);
}

struct scm *
make_macro (struct scm *name, struct scm *x)    /*:((internal)) */
{
  return make_cell (TMACRO, x, name->string);
}

struct scm *
make_number (long n)
{
  return make_value_cell (TNUMBER, 0, n);
}

struct scm *
make_ref (struct scm *x)                /*:((internal)) */
{
  return make_cell (TREF, x, 0);
}

struct scm *
make_string (char const *s, size_t length)
{
  if (length > MAX_STRING)
    assert_max_string (length, "make_string", s);
  struct scm *x = make_pointer_cell (TSTRING, length, 0);
  struct scm *v = make_bytes (s, length + 1);
  x->cdr = v;
  return x;
}

struct scm *
make_string0 (char const *s)
{
  return make_string (s, strlen (s));
}

struct scm *
make_string_port (struct scm *x)        /*:((internal)) */
{
  return make_pointer_cell (TPORT, -length__ (g_ports) - 2, x);
}

void
gc_init_news ()
{
  g_news = g_free;
  struct scm *ncell_arena = g_news;
  struct scm *ncell_zero = ncell_arena + M2_CELL_SIZE;

  g_news = g_news + M2_CELL_SIZE;

  ncell_arena->type = TVECTOR;
  ncell_arena->length = cell_arena->length;
  ncell_arena->vector = g_news;

  ncell_zero->type = TCHAR;
  ncell_zero->value = 'n';
}

void
gc_up_arena ()
{
  long old_arena_bytes = (ARENA_SIZE + JAM_SIZE) * sizeof (struct scm);
  if (ARENA_SIZE / 2 < MAX_ARENA_SIZE / 4)
    {
      ARENA_SIZE = ARENA_SIZE * 2;
      JAM_SIZE = JAM_SIZE * 2;
      GC_SAFETY = GC_SAFETY * 2;
    }
  else
    ARENA_SIZE = MAX_ARENA_SIZE - JAM_SIZE;
  long arena_bytes = (ARENA_SIZE + JAM_SIZE) * sizeof (struct scm);
  long stack_offset = (arena_bytes * 2);
  long realloc_bytes = (arena_bytes * 2) + (STACK_SIZE * sizeof (struct scm));
  void *p = realloc (g_cells - M2_CELL_SIZE, realloc_bytes);
  if (p == 0)
    {
      eputs ("realloc failed, g_free=");
      eputs (ltoa (cast_voidp_to_long (g_free)));
      eputs (":");
      long i = g_free - g_cells;
      i = i / M2_CELL_SIZE;
      eputs (ltoa (ARENA_SIZE - i));
      eputs ("\n");
      assert_msg (0, "0");
      exit (1);
    }
  g_cells = p;
  memcpy (p + stack_offset, p + old_arena_bytes, STACK_SIZE * sizeof (struct scm *));
  g_cells = g_cells + M2_CELL_SIZE;
}

/* A pointer relocating memcpy for pointer cells to avoid using only
   half of the allocated cells.

   For number based cells a simply memcpy could be used, as number
   references are relative.

   A simple stop and copy (SICP 5.3) garbage collector allocates twice
   the cell arena size only for the garbage collector.  The garbage
   collector switches back and forth between cells and news, thus
   utilizing only half the allocated memory. */
void
gc_cellcpy (struct scm *dest, struct scm *src, size_t n)
{
  void *p = src;
  void *q = dest;
  long dist = p - q;
  long t;
  long a;
  long d;
  int i;
  int c;
  while (n != 0)
    {
      t = src->type;
      a = src->car_value;
      d = src->cdr_value;
      dest->type = t;
      if (t == TBROKEN_HEART)
        assert_msg (0, "gc_cellcpy: broken heart");
      if (t == TMACRO
          || t == TPAIR
          || t == TREF
          || t == TVARIABLE)
        dest->car_value = a - dist;
      else
        dest->car_value = a;
      if (t == TBYTES
          || t == TCLOSURE
          || t == TCONTINUATION
          || t == TKEYWORD
          || t == TMACRO
          || t == TPAIR
          || t == TPORT
          || t == TSPECIAL
          || t == TSTRING
          || t == TSTRUCT
          || t == TSYMBOL
          || t == TVALUES
          || t == TVECTOR)
        dest->cdr_value = d - dist;
      else
        dest->cdr_value = d;
      if (t == TBYTES)
        {
          if (g_debug > 5)
            {
              eputs ("copying bytes[");
              eputs (ntoab (cast_voidp_to_long (cell_bytes (src)), 16, 0));
              eputs (", ");
              eputs (ntoab (a, 10, 0));
              eputs ("]: ");
              eputs (cell_bytes (src));
              eputs ("\n to [");
              eputs (ntoab (cast_voidp_to_long (cell_bytes (dest)), 16, 0));
            }
          memcpy (cell_bytes (dest), cell_bytes (src), a);
          if (g_debug > 5)
            {
              eputs ("]: ");
              eputs (cell_bytes (dest));
              eputs ("\n");
            }
          i = bytes_cells (a);
          n = n - i;
          c = i * M2_CELL_SIZE;
          dest = dest + c;
          src = src + c;
        }
      else
        {
          n = n - 1;
          dest = dest + M2_CELL_SIZE;
          src = src + M2_CELL_SIZE;
        }
    }
}

/* We do not actually flip cells and news, instead we move news back to
   cells. */
void
gc_flip ()
{
  if (g_free - g_news > JAM_SIZE)
    JAM_SIZE = ((g_free - g_news) * 3) / 2;

  cell_arena = g_cells - M2_CELL_SIZE; /* For debugging. */
  gc_cellcpy (g_cells, g_news, (g_free - g_news) / M2_CELL_SIZE);

  long dist = g_news - g_cells;
  g_free = g_free - dist;
  g_symbols = g_symbols - dist;
  g_macros = g_macros - dist;
  g_ports = g_ports - dist;
  M0 = M0 - dist;

  long i;
  for (i = g_stack; i < STACK_SIZE; i = i + 1)
    g_stack_array[i] = g_stack_array[i] - dist;

  if (g_debug > 2)
    gc_stats_ (";;; => jam");
}

struct scm *
gc_copy (struct scm *old)               /*:((internal)) */
{
  if (old->type == TBROKEN_HEART)
    return old->car;
  struct scm *new = g_free;
  g_free = g_free + M2_CELL_SIZE;
  copy_cell (new, old);
  if (new->type == TSTRUCT || new->type == TVECTOR)
    {
      new->vector = g_free;
      long i;
      for (i = 0; i < old->length; i = i + 1)
        {
          copy_cell (g_free, cell_ref (old->vector, i));
          g_free = g_free + M2_CELL_SIZE;
        }
    }
  else if (new->type == TBYTES)
    {
      char const *src = cell_bytes (old);
      char *dest = cell_bytes (new);
      size_t length = new->length;
      memcpy (dest, src, length);
      g_free = g_free + ((bytes_cells (length) - 1) * M2_CELL_SIZE);

      if (g_debug > 4)
        {
          eputs ("gc copy bytes: ");
          eputs (src);
          eputs ("\n");
          eputs ("    length: ");
          eputs (ltoa (old->length));
          eputs ("\n");
          eputs ("    nlength: ");
          eputs (ltoa (new->length));
          eputs ("\n");
          eputs ("        ==> ");
          eputs (dest);
          eputs ("\n");
        }
    }
  old->type = TBROKEN_HEART;
  old->car = new;
  return new;
}

struct scm *
gc_relocate_car (struct scm *new, struct scm *car)      /*:((internal)) */
{
  new->car = car;
  return cell_unspecified;
}

struct scm *
gc_relocate_cdr (struct scm *new, struct scm *cdr)      /*:((internal)) */
{
  new->cdr = cdr;
  return cell_unspecified;
}

void
gc_loop (struct scm *scan)
{
  struct scm *car;
  struct scm *cdr;
  long t;
  while (scan < g_free)
    {
      t = scan->type;
      if (t == TBROKEN_HEART)
        assert_msg (0, "gc_loop: broken heart");
      /* *INDENT-OFF* */
      if (t == TMACRO
          || t == TPAIR
          || t == TREF
          || t == TVARIABLE)
        /* *INDENT-ON* */
        {
          car = gc_copy (scan->car);
          gc_relocate_car (scan, car);
        }
      /* *INDENT-OFF* */
      if (t == TCLOSURE
          || t == TCONTINUATION
          || t == TKEYWORD
          || t == TMACRO
          || t == TPAIR
          || t == TPORT
          || t == TSPECIAL
          || t == TSTRING
          /*|| t == TSTRUCT handled by gc_copy */
          || t == TSYMBOL
          || t == TVALUES
          /*|| t == TVECTOR handled by gc_copy */
          )
        /* *INDENT-ON* */
        {
          cdr = gc_copy (scan->cdr);
          gc_relocate_cdr (scan, cdr);
        }
      if (t == TBYTES)
        scan = scan + (bytes_cells (scan->length) * M2_CELL_SIZE);
      else
        scan = scan + M2_CELL_SIZE;
    }
  gc_flip ();
}

struct scm *
gc_check ()
{
  long used = ((g_free - g_cells) / M2_CELL_SIZE) + GC_SAFETY;
  if (used >= ARENA_SIZE)
    return gc ();
  return cell_unspecified;
}

void
gc_ ()
{
  gc_init_news ();
  if (g_debug == 2)
    eputs (".");
  if (g_debug > 2)
    {
      gc_stats_ (";;; gc");
      eputs (";;; free: [");
      eputs (ltoa (ARENA_SIZE - gc_free ()));
      eputs ("]...");
    }
  g_free = g_news + M2_CELL_SIZE;

  if (ARENA_SIZE < MAX_ARENA_SIZE
      && cast_voidp_to_charp (g_cells) == g_arena + M2_CELL_SIZE)
    {
      if (g_debug == 2)
        eputs ("+");
      if (g_debug > 2)
        {
          eputs (" up[");
          eputs (ltoa (cast_voidp_to_long (g_cells)));
          eputs (",");
          eputs (ltoa (cast_voidp_to_long (g_news)));
          eputs (":");
          eputs (ltoa (ARENA_SIZE));
          eputs (",");
          eputs (ltoa (MAX_ARENA_SIZE));
          eputs ("]...");
        }
      gc_up_arena ();
    }

  struct scm *new_cell_nil = g_free;
  struct scm *s;
  for (s = cell_nil; s < g_symbol_max; s = s + M2_CELL_SIZE)
    gc_copy (s);

  g_symbols = gc_copy (g_symbols);
  g_macros = gc_copy (g_macros);
  g_ports = gc_copy (g_ports);
  M0 = gc_copy (M0);

  long i;
  for (i = g_stack; i < STACK_SIZE; i = i + 1)
    copy_stack (i, gc_copy (g_stack_array[i]));

  gc_loop (new_cell_nil);
}

struct scm *
gc ()
{
  if (getenv ("MES_DUMP") != 0)
    gc_dump_arena (g_cells, gc_free ());
  if (g_debug > 5)
    {
      eputs ("symbols: ");
      write_error_ (g_symbols);
      eputs ("\n");
      eputs ("R0: ");
      write_error_ (R0);
      eputs ("\n");
    }
  clock_gettime (CLOCK_PROCESS_CPUTIME_ID, gc_start_time);
  gc_push_frame ();
  gc_ ();
  gc_pop_frame ();
  clock_gettime (CLOCK_PROCESS_CPUTIME_ID, gc_end_time);
  long time = seconds_and_nanoseconds_to_long
    (gc_end_time->tv_sec - gc_start_time->tv_sec,
     gc_end_time->tv_nsec - gc_start_time->tv_nsec);
  gc_time = gc_time + time;
  gc_count = gc_count + 1;
  if (g_debug > 5)
    {
      eputs ("symbols: ");
      write_error_ (g_symbols);
      eputs ("\n");
      eputs ("R0: ");
      write_error_ (R0);
      eputs ("\n");
    }
  if (getenv ("MES_DUMP") != 0)
    gc_dump_arena (g_cells, gc_free ());
  return cell_unspecified;
}

void
gc_push_frame ()
{
  if (g_stack < GC_FRAME_SIZE)
    assert_msg (0, "STACK FULL");
  g_stack_array[g_stack - 1] = cell_f;
  g_stack_array[g_stack - 2] = R0;
  g_stack_array[g_stack - 3] = R1;
  g_stack_array[g_stack - 4] = R2;
  g_stack_array[g_stack - 5] = R3;
  g_stack = g_stack - GC_FRAME_SIZE;
}

void
gc_peek_frame ()
{
  R3 = g_stack_array[g_stack];
  R2 = g_stack_array[g_stack + 1];
  R1 = g_stack_array[g_stack + 2];
  R0 = g_stack_array[g_stack + 3];
  g_stack_array[g_stack + GC_FRAME_PROCEDURE];
}

void
gc_pop_frame ()
{
  gc_peek_frame ();
  g_stack = g_stack + GC_FRAME_SIZE;
}

void
dumpc (char c)
{
  fdputc (c, g_dump_filedes);
}

void
dumps (char const *s)
{
  fdputs (s, g_dump_filedes);
}

void
gc_dump_register (char const* n, struct scm *r)
{
  dumps (n); dumps (": ");
  long i = cast_scmp_to_long (r);
  long a = cast_charp_to_long (g_arena);
  i = i - a;
  i = i / M2_CELL_SIZE;
  dumps (ltoa (i));
  dumps ("\n");
}

void
gc_dump_state ()
{
  gc_dump_register ("R0", R0);
  gc_dump_register ("R1", R1);
  gc_dump_register ("R2", R2);
  gc_dump_register ("R3", R3);
  gc_dump_register ("M0", M0);
  gc_dump_register ("g_symbols", g_symbols);
  gc_dump_register ("g_symbol_max", g_symbol_max);
  gc_dump_register ("g_macros", g_macros);
  gc_dump_register ("g_ports", g_ports);
  gc_dump_register ("cell_zero", cell_zero);
  gc_dump_register ("cell_nil", cell_nil);
}

void
gc_dump_stack ()
{
  long i = g_stack;
  while (i < STACK_SIZE)
    {
      gc_dump_register (itoa (i), g_stack_array[i]);
      i = i + 1;
    }
}

void
gc_dump_arena (struct scm *cells, long size)
{
  struct scm *end = g_cells + (size * M2_CELL_SIZE);
  struct scm *dist = cells;
  int i;
  long t;
  long a;
  long d;
  int c;
  char* p;
  if (g_dump_filedes == 0)
    g_dump_filedes = mes_open ("dump.mo", O_CREAT|O_WRONLY, 0644);
  dumps ("stack="); dumps (ltoa (g_stack)); dumpc ('\n');
  dumps ("size="); dumps (ltoa (size)); dumpc ('\n');
  gc_dump_state ();
  gc_dump_stack ();
  while (end->type == 0 && end->car == 0 && end->cdr == 0)
    {
      end = end - M2_CELL_SIZE;
      size = size - 1;
    }
  while (size > 0)
    {
      for (i=0; i < 16; i = i + 1)
        {
          t = cells->type;
          a = cells->car_value;
          d = cells->cdr_value;
          if (size == 0)
            dumps ("0 0 0");
          else
            {
              dumps (ltoa (t));
              dumpc (' ');
              if (t == TMACRO
                  || t == TPAIR
                  || t == TREF
                  || t == TVARIABLE)
                {
                  dumps (ltoa ((cells->car - dist) / M2_CELL_SIZE));
                  /* dumps ("["); dumps (ltoa (a)); dumps ("]"); */
                }
              else
                dumps (ltoa (a));
              dumpc (' ');
              if (t != TBYTES)
                {
                  if (t == TCLOSURE
                      || t == TCONTINUATION
                      || t == TKEYWORD
                      || t == TMACRO
                      || t == TPAIR
                      || t == TPORT
                      || t == TSPECIAL
                      || t == TSTRING
                      || t == TSTRUCT
                      || t == TSYMBOL
                      || t == TVALUES
                      || t == TVECTOR)
                    {
                      dumps (ltoa ((cells->cdr - dist) / M2_CELL_SIZE));
                      /* dumps ("["); dumps (ltoa (d)); dumps ("]"); */
                    }
                  else if (t == TNUMBER && d > 1000)
                    dumps (ltoa (1001));
                  else
                    dumps (ltoa (d));
                }
              if (t == TBYTES)
                {
                  c = bytes_cells (a);
                  p = cell_bytes (cells);
                  size = size - c;
                  dumpc ('"');
                  while (a > 0)
                    {
                      if (p[0] != 0)
                        dumpc (p[0]);
                      p = p + 1;
                      a = a - 1;
                    }
                  dumpc ('"');
                  cells = cells + c * M2_CELL_SIZE;
                  size = size - c;
                }
              else
                {
                  cells = cells + M2_CELL_SIZE;
                  size = size - 1;
                }
            }
          if (i != 15)
            dumps ("  ");
          else
            dumpc ('\n');
        }
      dumpc ('\n');
    }
}

https://git.savannah.gnu.org/cgit/mes.git/tree/src/hash.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/src/hash.c used in: Step 106, Step 219
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "mes/lib.h"
#include "mes/mes.h"

#include <string.h>

int
hash_cstring (char const *s, long size)
{
  int hash = s[0] * 37;
  if (s[0] != 0)
    if (s[1] != 0)
      hash = hash + (s[1] * 43);
  assert_msg (size != 0, "size");
  hash = hash % size;
  return hash;
}

int
hashq_ (struct scm *x, long size)
{
  if (x->type == TSPECIAL || x->type == TSYMBOL)
    return hash_cstring (cell_bytes (x->string), size);    /* FIXME: hash x directly. */
  error (cell_symbol_system_error, cons (make_string0 ("hashq_: not a symbol"), x));
}

int
hash_ (struct scm *x, long size)
{
  if (x->type != TSTRING)
    {
      eputs ("hash_ failed, not a string:");
      display_error_ (x);
      assert_msg (0, "0");
    }
  return hash_cstring (cell_bytes (x->string), size);
}

struct scm *
hashq (struct scm *x, struct scm *size)
{
  eputs ("hashq not supporteed\n");
  assert_msg (0, "0");
}

struct scm *
hash (struct scm *x, struct scm *size)
{
  eputs ("hash not supporteed\n");
  assert_msg (0, "0");
}

struct scm *
hashq_get_handle (struct scm *table, struct scm *key, struct scm *dflt)
{
  struct scm *s = struct_ref_ (table, 3);
  long size = s->value;
  unsigned hash = hashq_ (key, size);
  struct scm *buckets = struct_ref_ (table, 4);
  struct scm *bucket = vector_ref_ (buckets, hash);
  struct scm *x = cell_f;
  if (dflt->type == TPAIR)
    x = dflt->car;
  if (bucket->type == TPAIR)
    x = assq (key, bucket);
  return x;
}

struct scm *
hashq_ref (struct scm *table, struct scm *key, struct scm *dflt)
{
  struct scm *x = hashq_get_handle (table, key, dflt);
  if (x != cell_f)
    x = x->cdr;
  return x;
}

struct scm *
hash_ref (struct scm *table, struct scm *key, struct scm *dflt)
{
  struct scm *s = struct_ref_ (table, 3);
  long size = s->value;
  unsigned hash = hash_ (key, size);
  struct scm *buckets = struct_ref_ (table, 4);
  struct scm *bucket = vector_ref_ (buckets, hash);
  struct scm *x = cell_f;
  if (dflt->type == TPAIR)
    x = dflt->car;
  if (bucket->type == TPAIR)
    {
      x = assoc (key, bucket);
      if (x != cell_f)
        x = x->cdr;
    }
  return x;
}

struct scm *
hash_set_x_ (struct scm *table, unsigned hash, struct scm *key, struct scm *value)
{
  struct scm *buckets = struct_ref_ (table, 4);
  struct scm *bucket = vector_ref_ (buckets, hash);
  if (bucket->type != TPAIR)
    bucket = cell_nil;
  bucket = acons (key, value, bucket);
  vector_set_x_ (buckets, hash, bucket);
  return value;
}

struct scm *
hashq_set_x (struct scm *table, struct scm *key, struct scm *value)
{
  struct scm *s = struct_ref_ (table, 3);
  long size = s->value;
  unsigned hash = hashq_ (key, size);
  return hash_set_x_ (table, hash, key, value);
}

struct scm *
hash_set_x (struct scm *table, struct scm *key, struct scm *value)
{
  struct scm *s = struct_ref_ (table, 3);
  long size = s->value;
  unsigned hash = hash_ (key, size);
  return hash_set_x_ (table, hash, key, value);
}

struct scm *
hash_table_printer (struct scm *table)
{
  fdputs ("#<", __stdout);
  display_ (struct_ref_ (table, 2));
  fdputc (' ', __stdout);
  fdputs ("size: ", __stdout);
  display_ (struct_ref_ (table, 3));
  fdputc (' ', __stdout);
  struct scm *buckets = struct_ref_ (table, 4);
  fdputs ("buckets: ", __stdout);
  int i;
  struct scm *e;
  for (i = 0; i < buckets->length; i = i + 1)
    {
      e = vector_ref_ (buckets, i);
      if (e != cell_unspecified)
        {
          fdputc ('[', __stdout);
          while (e->type == TPAIR)
            {
              write_ (e->car->car);
              e = e->cdr;
              if (e->type == TPAIR)
                fdputc (' ', __stdout);
            }
          fdputs ("]\n  ", __stdout);
        }
    }
  fdputc ('>', __stdout);
}

struct scm *
make_hashq_type ()              /*:((internal)) */
{
  struct scm *fields = cell_nil;
  fields = cons (cell_symbol_buckets, fields);
  fields = cons (cell_symbol_size, fields);
  fields = cons (fields, cell_nil);
  fields = cons (cell_symbol_hashq_table, fields);
  return make_struct (cell_symbol_record_type, fields, cell_unspecified);
}

struct scm *
make_hash_table_ (long size)
{
  if (size == 0)
    size = 100;
  struct scm *hashq_type = make_hashq_type ();

  struct scm *buckets = make_vector_ (size, cell_unspecified);
  struct scm *values = cell_nil;
  values = cons (buckets, values);
  values = cons (make_number (size), values);
  values = cons (cell_symbol_hashq_table, values);
  /*FIXME: symbol/printer
    return make_struct (hashq_type, values, cstring_to_symbol ("hash-table-printer");*/
  return make_struct (hashq_type, values, cell_unspecified);
}

struct scm *
make_hash_table (struct scm *x)
{
  long size = 0;
  if (x->type == TPAIR)
    {
      assert_msg (x->type == TNUMBER, "x->type == TNUMBER");
      size = x->value;
    }
  return make_hash_table_ (size);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/src/lib.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/src/lib.c used in: Step 106, Step 220
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

/** Commentary:
    Scheme library functions not used by the eval/apply core.
 */

/** Code: */

#include "mes/lib.h"
#include "mes/mes.h"

#include <stdlib.h>

struct scm *
type_ (struct scm *x)
{
  return make_number (x->type);
}

struct scm *
car_ (struct scm *x)
{
  struct scm *a = x->car;
  if (x->type == TPAIR)
    return a;
  return make_number (cast_scmp_to_long (a));
}

struct scm *
cdr_ (struct scm *x)
{
  struct scm *d = x->cdr;
  if (x->type == TPAIR || x->type == TCLOSURE)
    return d;
  return make_number (cast_scmp_to_long (d));
}

struct scm *
xassq (struct scm *x, struct scm *a)            /* For speed in core. */
{
  while (a != cell_nil)
    {
      if (x == a->car->cdr)
        return a->car;
      a = a->cdr;
    }
  return cell_f;
}

struct scm *
memq (struct scm *x, struct scm *a)
{
  int t = x->type;
  if (t == TCHAR || t == TNUMBER)
    {
      long v = x->value;
      while (a != cell_nil)
        {
          if (v == a->car->value)
            return a;
          a = a->cdr;
        }
      return cell_f;
    }
  if (t == TKEYWORD)
    {
      while (a != cell_nil)
        {
          if (a->car->type == TKEYWORD)
            if (string_equal_p (x, a->car) == cell_t)
              return a;
          a = a->cdr;
        }
      return cell_f;
    }
  while (a != cell_nil)
    {
      if (x == a->car)
        return a;
      a = a->cdr;
    }
  return cell_f;
}

struct scm *
equal2_p (struct scm *a, struct scm *b)
{
  long i;
  struct scm *ai;
  struct scm *bi;

equal2:
  if (a == b)
    return cell_t;
  if (a->type == TPAIR && b->type == TPAIR)
    {
      if (equal2_p (a->car, b->car) == cell_t)
        {
          a = a->cdr;
          b = b->cdr;
          goto equal2;
        }
      return cell_f;
    }
  if (a->type == TSTRING && b->type == TSTRING)
    return string_equal_p (a, b);
  if (a->type == TVECTOR && b->type == TVECTOR)
    {
      if (a->length != b->length)
        return cell_f;
      for (i = 0; i < a->length; i = i + 1)
        {
          ai = cell_ref (a->vector, i);
          bi = cell_ref (b->vector, i);
          if (ai->type == TREF)
            ai = ai->ref;
          if (bi->type == TREF)
            bi = bi->ref;
          if (equal2_p (ai, bi) == cell_f)
            return cell_f;
        }
      return cell_t;
    }
  return eq_p (a, b);
}

struct scm *
last_pair (struct scm *x)
{
  while (x != cell_nil)
    {
      if (x->cdr == cell_nil)
        return x;
      x = x->cdr;
    }
  return x;
}

struct scm *
pair_p (struct scm *x)
{
  if (x->type == TPAIR)
    return cell_t;
  return cell_f;
}

struct scm *
char_to_integer (struct scm *x)
{
  return make_number (x->value);
}

struct scm *
integer_to_char (struct scm *x)
{
  return make_char (x->value);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/src/m2.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/src/m2.c used in: Step 106
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "mes/lib.h"
#include "mes/mes.h"

struct scm *
apply_builtin0 (struct scm *fn)
{
  FUNCTION fp = builtin_function (fn);
  return fp ();
}

struct scm *
apply_builtin1 (struct scm *fn, struct scm *x)
{
  FUNCTION fp = builtin_function (fn);
  return fp (x);
}

struct scm *
apply_builtin2 (struct scm *fn, struct scm *x, struct scm *y)
{
  FUNCTION fp = builtin_function (fn);
  return fp (x, y);
}

struct scm *
apply_builtin3 (struct scm *fn, struct scm *x, struct scm *y, struct scm *z)
{
  FUNCTION fp = builtin_function (fn);
  return fp (x, y, z);
}

#undef cast_charp_to_scmp
#undef cast_charp_to_scmpp
#undef cast_voidp_to_charp
#undef cast_scmp_to_long
#undef cast_scmp_to_charp

struct scm *
cast_charp_to_scmp (char const *i)
{
  return i;
}

struct scm **
cast_charp_to_scmpp (char const *i)
{
  return i;
}

char*
cast_voidp_to_charp (void const *i)
{
  return i;
}

long
cast_scmp_to_long (struct scm *i)
{
  return i;
}

char*
cast_scmp_to_charp (struct scm *i)
{
  return i;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/src/math.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/src/math.c used in: Step 106, Step 221
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2020,2021 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 * Copyright © 2021 W. J. van der Laan <laanwj@protonmail.com>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "mes/lib.h"
#include "mes/mes.h"

#include <ctype.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>

void
assert_number (char const *name, struct scm *x)
{
  if (x->type != TNUMBER)
    {
      eputs (name);
      error (cell_symbol_not_a_number, x);
    }
}

struct scm *
greater_p (struct scm *x)               /*:((name . ">") (arity . n)) */
{
  if (x == cell_nil)
    return cell_t;
  assert_number ("greater_p", x->car);
  long n = x->car->value;
  x = x->cdr;
  struct scm *i;
  long v;
  while (x != cell_nil)
    {
      assert_number ("greater_p", x->car);
      i = car (x);
      v = i->value;
      if (v >= n)
        return cell_f;
      n = v;
      x = cdr (x);
    }
  return cell_t;
}

struct scm *
less_p (struct scm *x)                  /*:((name . "<") (arity . n)) */
{
  if (x == cell_nil)
    return cell_t;
  assert_number ("less_p", x->car);
  long n = x->car->value;
  x = x->cdr;
  struct scm *i;
  long v;
  while (x != cell_nil)
    {
      assert_number ("less_p", x->car);
      i = car (x);
      v = i->value;
      if (v <= n)
        return cell_f;
      n = v;
      x = cdr (x);
    }
  return cell_t;
}

struct scm *
is_p (struct scm *x)                    /*:((name . "=") (arity . n)) */
{
  if (x == cell_nil)
    return cell_t;
  assert_number ("is_p", x->car);
  long n = x->car->value;
  x = cdr (x);
  struct scm *i;
  long v;
  while (x != cell_nil)
    {
      i = car (x);
      v = i->value;
      if (v != n)
        return cell_f;
      x = cdr (x);
    }
  return cell_t;
}

struct scm *
minus (struct scm *x)                   /*:((name . "-") (arity . n)) */
{
  assert_number ("minus", x->car);
  long n = x->car->value;
  x = cdr (x);
  if (x == cell_nil)
    n = -n;
  struct scm *i;
  long v;
  while (x != cell_nil)
    {
      i = car (x);
      assert_number ("minus", i);
      v = i->value;
      n = n - v;
      x = cdr (x);
    }
  return make_number (n);
}

struct scm *
plus (struct scm *x)                    /*:((name . "+") (arity . n)) */
{
  long n = 0;
  struct scm *i;
  long v;
  while (x != cell_nil)
    {
      i = car (x);
      assert_number ("plus", i);
      v = i->value;
      n = n + v;
      x = cdr (x);
    }
  return make_number (n);
}

struct scm *
divide (struct scm *x)                  /*:((name . "/") (arity . n)) */
{
  long n = 1;
  struct scm *i;
  long v;
  if (x != cell_nil)
    {
      i = car (x);
      assert_number ("divide", i);
      v = i->value;
      n = v;
      x = cdr (x);
    }
  int sign_p = 0;
  size_t u = n;
  if (n < 0)
    {
      sign_p = 1;
      u = -n;
    }
  size_t w;
  while (x != cell_nil)
    {
      i = car (x);
      assert_number ("divide", i);
      v = i->value;
      sign_p = sign_p && v > 0 || !sign_p && v < 0;
      w = v;
      if (v == 0)
        error (cstring_to_symbol ("divide-by-zero"), x);
      if (u == 0)
        break;
      if (w != 1)
        u = u / w;
      x = cdr (x);
    }
  n = u;
  if (sign_p)
    n = -n;
  return make_number (n);
}

struct scm *
modulo (struct scm *a, struct scm *b)
{
  assert_number ("modulo", a);
  assert_number ("modulo", b);
  long n = a->value;
  long v = b->value;
  if (v == 0)
    error (cstring_to_symbol ("divide-by-zero"), a);
  int sign_p = 0;
  size_t w = v;
  if (v < 0)
    {
      sign_p = 1;
      w = -v;
    }
  while (n < 0)
    n = n + w;
  size_t u = n;
  if (u != 0)
    u = u % w;
  n = u;
  if (sign_p)
    n = -n;
  return make_number (n);
}

struct scm *
multiply (struct scm *x)                /*:((name . "*") (arity . n)) */
{
  long n = 1;
  struct scm *i;
  long v;
  while (x != cell_nil)
    {
      i = car (x);
      assert_number ("multiply", i);
      v = i->value;
      n = n * v;
      x = cdr (x);
    }
  return make_number (n);
}

struct scm *
logand (struct scm *x)                  /*:((arity . n)) */
{
  long n = -1;
  struct scm *i;
  long v;
  while (x != cell_nil)
    {
      i = car (x);
      assert_number ("multiply", i);
      v = i->value;
      n = n & v;
      x = cdr (x);
    }
  return make_number (n);
}

struct scm *
logior (struct scm *x)                  /*:((arity . n)) */
{
  long n = 0;
  struct scm *i;
  long v;
  while (x != cell_nil)
    {
      i = car (x);
      assert_number ("logior", i);
      v = i->value;
      n = n | v;
      x = cdr (x);
    }
  return make_number (n);
}

struct scm *
lognot (struct scm *x)
{
  assert_number ("lognot", x);
  long n = ~x->value;
  return make_number (n);
}

struct scm *
logxor (struct scm *x)                  /*:((arity . n)) */
{
  long n = 0;
  struct scm *i;
  long v;
  while (x != cell_nil)
    {
      i = car (x);
      assert_number ("logxor", i);
      v = i->value;
      n = n ^ v;
      x = cdr (x);
    }
  return make_number (n);
}

struct scm *
ash (struct scm *n, struct scm *count)
{
  assert_number ("ash", n);
  assert_number ("ash", count);
  long cn = n->value;
  long ccount = count->value;
  long result;
  if (ccount < 0)
    result = cn >> -ccount;
  else
    result = cn << ccount;
  return make_number (result);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/src/mes.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/src/mes.c used in: Step 106, Step 222
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2020,2021 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "mes/lib.h"
#include "mes/mes.h"

#include <fcntl.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>

struct scm *
mes_g_stack (struct scm *a)             /*:((internal)) */
{
  g_stack = STACK_SIZE;
  R0 = a;
  R1 = make_char (0);
  R2 = make_char (0);
  R3 = make_char (0);
  return R0;
}

struct scm *
mes_environment (int argc, char **argv)
{
  struct scm *a = init_symbols ();

  char *compiler = "gnuc";
#if __MESC__
  compiler = "mesc";
#elif __TINYC__
  compiler = "tcc";
#endif
  a = acons (cell_symbol_compiler, make_string0 (compiler), a);

  char *arch;
#if __i386__
  arch = "x86";
#elif __arm__
  arch = "arm";
#elif __x86_64__
  arch = "x86_64";
#else
#error arch not supported
#endif
  a = acons (cell_symbol_arch, make_string0 (arch), a);

#if !MES_MINI
  struct scm *lst = cell_nil;
  int i;
  for (i = argc - 1; i >= 0; i = i - 1)
    lst = cons (make_string0 (argv[i]), lst);
  a = acons (cell_symbol_argv, lst, a);
#endif

  return mes_g_stack (a);
}

int
try_open_boot (char *file_name, char const *boot, char const *location)
{
  strcpy (file_name + strlen (file_name), boot);
  if (g_debug > 1)
    {
      eputs ("mes: reading boot-0 [");
      eputs (location);
      eputs ("]: ");
      eputs (file_name);
      eputs ("\n");
    }
  int fd = mes_open (file_name, O_RDONLY, 0);
  if (g_debug != 0 && fd > 0)
    {
      eputs ("mes: read boot-0: ");
      eputs (file_name);
      eputs ("\n");
    }
  return fd;
}

void
open_boot ()
{
  __stdin = -1;
  char *boot = __open_boot_buf;
  char *file_name = __open_boot_file_name;
  strcpy (g_datadir, ".");
  if (getenv ("MES_BOOT") != 0)
    strcpy (boot, getenv ("MES_BOOT"));
  else
    strcpy (boot, "boot-0.scm");
  if (getenv ("MES_PREFIX") != 0)
    {
      strcpy (g_datadir, getenv ("MES_PREFIX"));
      strcpy (g_datadir + strlen (g_datadir), "/mes");
      strcpy (file_name, g_datadir);
      strcpy (file_name + strlen (file_name), "/module/mes/");
      __stdin = try_open_boot (file_name, boot, "MES_PREFIX");
      if (__stdin < 0)
        {
          strcpy (g_datadir, getenv ("MES_PREFIX"));
          strcpy (g_datadir + strlen (g_datadir), "/share/mes");
          strcpy (file_name, g_datadir);
          strcpy (file_name + strlen (file_name), "/module/mes/");
          __stdin = try_open_boot (file_name, boot, "MES_PREFIX/share/mes");
        }
    }
  if (__stdin < 0)
    {
      g_datadir[0] = 0;
      if (getenv ("srcdest") != 0)
        strcpy (g_datadir, getenv ("srcdest"));
      strcpy (g_datadir + strlen (g_datadir), "mes");
      strcpy (file_name, g_datadir);
      strcpy (file_name + strlen (file_name), "/module/mes/");
      __stdin = try_open_boot (file_name, boot, "${srcdest}mes");
    }
  if (__stdin < 0)
    {
      file_name[0] = 0;
      __stdin = try_open_boot (file_name, boot, "<boot>");
    }
  if (__stdin < 0)
    {
      eputs ("mes: boot failed: no such file: ");
      eputs (boot);
      eputs ("\n");
      exit (1);
    }
}

struct scm *
read_boot ()                    /*:((internal)) */
{
  R2 = read_input_file_env (R0);
  __stdin = STDIN;
  return R2;
}

void
init (char **envp)
{
  environ = envp;
  __execl_c_argv = malloc (1024 * sizeof (char *));     /* POSIX minimum: 4096 */
  __gettimeofday_time = malloc (sizeof (struct timeval));
  __get_internal_run_time_ts = malloc (sizeof (struct timespec));
  __open_boot_buf = malloc (PATH_MAX);
  __open_boot_file_name = malloc (PATH_MAX);
  __reader_read_char_buf = malloc (10);
  __setenv_buf = malloc (1024);
  g_datadir = malloc (1024);
  g_start_time = malloc (sizeof (struct timespec));
  memset (g_start_time, 0, sizeof (struct timespec));
  gc_start_time = malloc (sizeof (struct timespec));
  gc_end_time = malloc (sizeof (struct timespec));

  char *p = getenv ("MES_DEBUG");
  if (p != 0)
    g_debug = atoi (p);
  g_mini = cast_charp_to_long (getenv ("MES_MINI"));
  open_boot ();
  gc_init ();
}

int
main (int argc, char **argv, char **envp)
{
  init (envp);

  struct scm *a = mes_environment (argc, argv);
  a = mes_builtins (a);
  a = init_time (a);
  M0 = make_initial_module (a);
  g_macros = make_hash_table_ (0);

  if (g_debug > 5)
    module_printer (M0);

  struct scm *program = read_boot ();
  R0 = acons (cell_symbol_program, program, R0);
  push_cc (R2, cell_unspecified, R0, cell_unspecified);

  if (g_debug > 2)
    gc_stats_ ("\n gc boot");
  if (g_debug > 3)
    {
      eputs ("program: ");
      write_error_ (R1);
      eputs ("\n");
    }
  R3 = cell_vm_begin_expand;
  R1 = eval_apply ();
  if (g_debug != 0)
    {
      write_error_ (R1);
      eputs ("\n");
    }
  if (g_debug != 0)
    {
      if (g_debug > 5)
        module_printer (M0);

      if (g_debug < 3)
        gc_stats_ ("\ngc run");
      MAX_ARENA_SIZE = 0;

      gc (g_stack);
      if (g_debug < 3)
        gc_stats_ (" => ");

      if (g_debug > 5)
        {
          eputs ("\nports:");
          write_error_ (g_ports);
          eputs ("\n");
        }
      eputs ("\n");
    }

  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/src/module.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/src/module.c used in: Step 106, Step 223
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "mes/lib.h"
#include "mes/mes.h"

struct scm *
make_module_type ()             /*:(internal)) */
{
  struct scm *fields = cell_nil;
  fields = cons (cstring_to_symbol ("globals"), fields);
  fields = cons (cstring_to_symbol ("locals"), fields);
  fields = cons (cstring_to_symbol ("name"), fields);
  fields = cons (fields, cell_nil);
  fields = cons (cell_symbol_module, fields);
  return make_struct (cell_symbol_record_type, fields, cell_unspecified);
}

struct scm *
make_initial_module (struct scm *a)     /*:((internal)) */
{
  struct scm *module_type = make_module_type ();
  a = acons (cell_symbol_module, module_type, a);

  struct scm *hashq_type = make_hashq_type ();
  a = acons (cell_symbol_hashq_table, hashq_type, a);

  struct scm *name = cons (cstring_to_symbol ("boot"), cell_nil);
  struct scm *globals = make_hash_table_ (0);
  struct scm *locals = cell_nil;

  struct scm *values = cell_nil;
  values = cons (globals, values);
  values = cons (locals, values);
  values = cons (name, values);
  values = cons (cell_symbol_module, values);
  struct scm *module = make_struct (module_type, values, cstring_to_symbol ("module-printer"));
  R0 = cell_nil;
  R0 = cons (a->cdr->car, R0);
  R0 = cons (a->car, R0);
  M0 = module;
  while (a->type == TPAIR)
    {
      module_define_x (module, a->car->car, a->car->cdr);
      a = a->cdr;
    }

  return module;
}

struct scm *
module_printer (struct scm *module)
{
  fdputs ("#<", __stdout);
  display_ (struct_ref_ (module, 2));
  fdputc (' ', __stdout);
  fdputs ("name: ", __stdout);
  display_ (struct_ref_ (module, 3));
  fdputc (' ', __stdout);
  fdputs ("locals: ", __stdout);
  display_ (struct_ref_ (module, 4));
  fdputc (' ', __stdout);
  struct scm *table = struct_ref_ (module, 5);
  fdputs ("globals:\n  ", __stdout);
  display_ (table);
  fdputc ('>', __stdout);
}

struct scm *
module_variable (struct scm *module, struct scm *name)
{
  /*struct scm *locals = struct_ref_ (module, 3);*/
  struct scm *locals = module;
  struct scm *x = assq (name, locals);
  if (x == cell_f)
    {
      module = M0;
      struct scm *globals = struct_ref_ (module, 5);
      x = hashq_get_handle (globals, name, cell_f);
    }
  return x;
}

struct scm *
module_ref (struct scm *module, struct scm *name)
{
  struct scm *x = module_variable (module, name);
  if (x == cell_f)
    return cell_undefined;
  return x->cdr;
}

struct scm *
module_define_x (struct scm *module, struct scm *name, struct scm *value)
{
  module = M0;
  struct scm *globals = struct_ref_ (module, 5);
  return hashq_set_x (globals, name, value);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/src/posix.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/src/posix.c used in: Step 106, Step 224
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2020,2021 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "mes/lib.h"
#include "mes/mes.h"

#include <fcntl.h>
#include <limits.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#if SYSTEM_LIBC
#define __raise(x) -1
#endif

struct scm *
abort_ ()                   /*:((name . "abort")) */
{
  if (g_debug > 0)
    eputs ("abort!\n");
  if (__raise (SIGABRT) < 0) /* could not raise SIGABRT */
    {
      /* Fail in any way possible */
      char* x = 0;
      x[0] = 2;
    }
  return cell_unspecified;
}

struct scm *
exit_ (struct scm *x)                   /*:((name . "exit")) */
{
  assert_msg (x->type == TNUMBER, "x->type == TNUMBER");
  exit (x->value);
}

int
peekchar ()
{
  if (__stdin >= 0)
    {
      int c = readchar ();
      unreadchar (c);
      return c;
    }
  struct scm *port = current_input_port ();
  struct scm *string = port->string;
  size_t length = string->length;
  if (length == 0)
    return -1;
  char const *p = cell_bytes (string->string);
  return p[0];
}

int
readchar ()
{
  if (__stdin >= 0)
    return fdgetc (__stdin);
  struct scm *port = current_input_port ();
  struct scm *string = port->string;
  size_t length = string->length;
  if (length == 0)
    return -1;
  char const *p = cell_bytes (string->string);
  int c = p[0];
  p = p + 1;
  port->string = make_string (p, length - 1);
  return c;
}

int
unreadchar (int c)
{
  if (__stdin >= 0)
    return fdungetc (c, __stdin);
  if (c == EOF) /* can't unread EOF */
    return c;
  struct scm *port = current_input_port ();
  struct scm *string = port->string;
  size_t length = string->length;
  char *p = cell_bytes (string->string);
  p = p - 1;
  string = make_string (p, length + 1);
  p = cell_bytes (string->string);
  p[0] = c;
  port->string = string;
  return c;
}

struct scm *
peek_byte ()
{
  return make_number (peekchar ());
}

struct scm *
read_byte ()
{
  return make_number (readchar ());
}

struct scm *
unread_byte (struct scm *i)
{
  unreadchar (i->value);
  return i;
}

struct scm *
peek_char ()
{
  return make_char (peekchar ());
}

struct scm *
read_char (struct scm *port)            /*:((arity . n)) */
{
  int fd = __stdin;
  if (port->type == TPAIR)
    if (port->car->type == TNUMBER)
      __stdin = port->car->value;
  struct scm *c = make_char (readchar ());
  __stdin = fd;
  return c;
}

struct scm *
unread_char (struct scm *i)
{
  unreadchar (i->value);
  return i;
}

struct scm *
write_char (struct scm *i)              /*:((arity . n)) */
{
  write_byte (i);
  return i;
}

struct scm *
write_byte (struct scm *x)              /*:((arity . n)) */
{
  struct scm *c = car (x);
  struct scm *p = cdr (x);
  int fd = __stdout;
  if (p->type == TPAIR)
    {
      struct scm *f = p->car;
      if (f->type == TNUMBER)
        {
          long v = f->value;
          if (v != 1)
            fd = v;
          if (v == 2)
            fd = __stderr;
        }
    }
  char cc = c->value;
  write (fd, &cc, 1);
#if !__MESC__
  assert_msg (c->type == TNUMBER || c->type == TCHAR, "c->type == TNUMBER || c->type == TCHAR");
#endif
  return c;
}

struct scm *
getenv_ (struct scm *s)                 /*:((name . "getenv")) */
{
  char *p;
  p = getenv (cell_bytes (s->string));
  if (p != 0)
    return make_string0 (p);
  return cell_f;
}

struct scm *
setenv_ (struct scm *s, struct scm *v)          /*:((name . "setenv")) */
{
  char *buf = __setenv_buf;
  strcpy (buf, cell_bytes (s->string));
  setenv (buf, cell_bytes (v->string), 1);
  return cell_unspecified;
}

struct scm *
access_p (struct scm *file_name, struct scm *mode)
{
  int result = access (cell_bytes (file_name->string), mode->value);
  if (result == 0)
    return cell_t;
  return cell_f;
}

struct scm *
current_input_port ()
{
  if (__stdin >= 0)
    return make_number (__stdin);
  struct scm *x = g_ports;
  struct scm *a;
  while (x != 0)
    {
      a = x->car;
      if (a->port == __stdin)
        return a;
      x = x->cdr;
    }
  return x->car;
}

struct scm *
open_input_file (struct scm *file_name)
{
  int filedes = mes_open (cell_bytes (file_name->string), O_RDONLY, 0);
  if (filedes == -1)
    error (cell_symbol_system_error, cons (make_string0 ("No such file or directory"), file_name));
  return make_number (filedes);
}

struct scm *
open_input_string (struct scm *string)
{
  struct scm *port = make_string_port (string);
  g_ports = cons (port, g_ports);
  return port;
}

struct scm *
set_current_input_port (struct scm *port)
{
  struct scm *prev = current_input_port ();
  if (port->type == TNUMBER)
    {
      int p = port->value;
      if (p != 0)
        __stdin = p;
      else
        __stdin = STDIN;
    }
  else if (port->type == TPORT)
    __stdin = port->port;
  return prev;
}

struct scm *
current_output_port ()
{
  return make_number (__stdout);
}

struct scm *
current_error_port ()
{
  return make_number (__stderr);
}

struct scm *
open_output_file (struct scm *x)        /*:((arity . n)) */
{
  struct scm *file_name = car (x);
  x = cdr (x);
  int mode = S_IRUSR | S_IWUSR;
  if (x->type == TPAIR)
    {
      struct scm *i = car (x);
      if (i->type == TNUMBER)
        mode = i->value;
    }
  return make_number (mes_open (cell_bytes (file_name->string), O_WRONLY | O_CREAT | O_TRUNC, mode));
}

struct scm *
set_current_output_port (struct scm *port)
{
  if (port->value != 0)
    __stdout = port->value;
  else
    __stdout = STDOUT;
  return current_output_port ();
}

struct scm *
set_current_error_port (struct scm *port)
{
  if (port->value != 0)
    __stderr = port->value;
  else
    __stderr = STDERR;
  return current_error_port ();
}

struct scm *
chmod_ (struct scm *file_name, struct scm *mode)        /*:((name . "chmod")) */
{
  chmod (cell_bytes (file_name->string), mode->value);
  return cell_unspecified;
}

struct scm *
isatty_p (struct scm *port)
{
  if (isatty (port->value) != 0)
    return cell_t;
  return cell_f;
}

struct scm *
primitive_fork ()
{
  return make_number (fork ());
}

struct scm *
execl_ (struct scm *file_name, struct scm *args)        /*:((name . "execl")) */
{
  char **c_argv = __execl_c_argv;
  int i = 0;

  if (length__ (args) > 1000)
    error (cell_symbol_system_error,
           cons (file_name, cons (make_string0 ("too many arguments"), cons (file_name, args))));
  c_argv[i] = cell_bytes (file_name->string);
  i = i + 1;
  struct scm *arg;
  while (args != cell_nil)
    {
      assert_msg (args->car->type == TSTRING, "args->car->type == TSTRING");
      arg = args->car;
      c_argv[i] = cell_bytes (arg->string);
      i = i + 1;
      args = args->cdr;
      if (g_debug > 2)
        {
          eputs ("arg[");
          eputs (itoa (i));
          eputs ("]: ");
          eputs (c_argv[i - 1]);
          eputs ("\n");
        }
    }
  c_argv[i] = 0;
  return make_number (execv (c_argv[0], c_argv));
}

struct scm *
waitpid_ (struct scm *pid, struct scm *options)
{
  int status;
  int child = waitpid (pid->value, &status, options->value);
  return cons (make_number (child), make_number (status));
}

#if __x86_64__
/* Nanoseconds on 64-bit systems with POSIX timers.  */
// CONSTANT TIME_UNITS_PER_SECOND 1000000000
#define TIME_UNITS_PER_SECOND 1000000000U
#else
/* Milliseconds for everyone else.  */
// CONSTANT TIME_UNITS_PER_SECOND 1000
#define TIME_UNITS_PER_SECOND 1000U
#endif

struct scm *
init_time (struct scm *a)               /*:((internal)) */
{
  clock_gettime (CLOCK_PROCESS_CPUTIME_ID, g_start_time);
  a = acons (cell_symbol_internal_time_units_per_second, make_number (TIME_UNITS_PER_SECOND), a);
}

struct scm *
current_time ()
{
  return make_number (time (0));
}

struct scm *
gettimeofday_ ()                /*:((name . "gettimeofday")) */
{
  struct timeval *time = __gettimeofday_time;
  gettimeofday (time, 0);
  return cons (make_number (time->tv_sec), make_number (time->tv_usec));
}

#define UL1000000000 1000000000UL
// CONSTANT UL1000000000 1000000000
long
seconds_and_nanoseconds_to_long (long s, long ns)
{
  size_t uns = ns;
  if (ns < 0)
    {
      uns = - ns;
      return s * TIME_UNITS_PER_SECOND - uns / (UL1000000000 / TIME_UNITS_PER_SECOND);
    }
  return s * TIME_UNITS_PER_SECOND + uns / (UL1000000000 / TIME_UNITS_PER_SECOND);
}

struct scm *
get_internal_run_time ()
{
  struct timespec *ts = __get_internal_run_time_ts;
  clock_gettime (CLOCK_PROCESS_CPUTIME_ID, ts);
  long time = seconds_and_nanoseconds_to_long (ts->tv_sec - g_start_time->tv_sec,
                                               ts->tv_nsec - g_start_time->tv_nsec);
  return make_number (time);
}

struct scm *
getcwd_ ()                      /*:((name . "getcwd")) */
{
  return make_string0 (getcwd (0, PATH_MAX));
}

struct scm *
dup_ (struct scm *port)                 /*:((name . "dup")) */
{
  return make_number (dup (port->value));
}

struct scm *
dup2_ (struct scm *old, struct scm *new)        /*:((name . "dup2")) */
{
  dup2 (old->value, new->value);
  return cell_unspecified;
}

struct scm *
delete_file (struct scm *file_name)
{
  unlink (cell_bytes (file_name->string));
  return cell_unspecified;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/src/reader.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/src/reader.c used in: Step 106, Step 225
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 * Copyright © 2018 Jeremiah Orians <jeremiah@pdp10.guru>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "mes/lib.h"
#include "mes/mes.h"

#include <ctype.h>
#include <stdio.h>
#include <string.h>

struct scm *
read_input_file_env_ (struct scm *e, struct scm *a)
{
  if (e == cell_nil)
    return e;
  return cons (e, read_input_file_env_ (read_env (a), a));
}

struct scm *
read_input_file_env (struct scm *a)
{
  return read_input_file_env_ (read_env (cell_nil), cell_nil);
}

int
reader_read_line_comment (int c)
{
  while (c != EOF)
    {
      if (c == '\n')
        return c;
      c = readchar ();
    }
  error (cell_symbol_system_error, make_string0 ("reader_read_line_comment"));
}

struct scm *reader_read_block_comment (int s, int c);
struct scm *reader_read_hash (int c, struct scm *a);
struct scm *reader_read_list (int c, struct scm *a);

int
reader_identifier_p (int c)
{
  return (c > ' ' && c <= '~' && c != '"' && c != ';' && c != '(' && c != ')' && c != EOF);
}

int
reader_end_of_word_p (int c)
{
  return (c == '"' || c == ';' || c == '(' || c == ')' || isspace (c) || c == EOF);
}

struct scm *
reader_read_identifier_or_number (int c)
{
  int i = 0;
  long n = 0;
  int negative_p = 0;
  if (c == '+')
    if (isdigit (peekchar ()) != 0)
      c = readchar ();
  if (c == '-')
    if (isdigit (peekchar ()) != 0)
      {
        negative_p = 1;
        c = readchar ();
      }
  while (isdigit (c) != 0)
    {
      g_buf[i] = c;
      i = i + 1;
      n = n * 10;
      n = n + c - '0';
      c = readchar ();
    }
  if (reader_end_of_word_p (c) != 0)
    {
      unreadchar (c);
      if (negative_p != 0)
        n = 0 - n;
      return make_number (n);
    }
  /* Fallthrough: Note that `4a', `+1b' are identifiers */
  while (reader_end_of_word_p (c) == 0)
    {
      g_buf[i] = c;
      i = i + 1;
      c = readchar ();
    }
  unreadchar (c);
  g_buf[i] = 0;
  return cstring_to_symbol (g_buf);
}

struct scm *
reader_read_sexp_ (int c, struct scm *a)
{
reset_reader:
  if (c == EOF)
    return cell_nil;
  if (c == ';')
    {
      c = reader_read_line_comment (c);
      goto reset_reader;
    }
  if ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\f'))
    {
      c = readchar ();
      goto reset_reader;
    }
  if (c == '(')
    return reader_read_list (readchar (), a);
  if (c == ')')
    return cell_nil;
  if (c == '#')
    return reader_read_hash (readchar (), a);
  if (c == '`')
    return cons (cell_symbol_quasiquote, cons (reader_read_sexp_ (readchar (), a), cell_nil));
  if (c == ',')
    {
      if (peekchar () == '@')
        {
          readchar ();
          return cons (cell_symbol_unquote_splicing, cons (reader_read_sexp_ (readchar (), a), cell_nil));
        }
      return cons (cell_symbol_unquote, cons (reader_read_sexp_ (readchar (), a), cell_nil));
    }
  if (c == '\'')
    return cons (cell_symbol_quote, cons (reader_read_sexp_ (readchar (), a), cell_nil));
  if (c == '"')
    return reader_read_string ();
  if (c == '.')
    if (reader_identifier_p (peekchar ()) == 0)
      return cell_dot;
  return reader_read_identifier_or_number (c);
}

int
reader_eat_whitespace (int c)
{
  while (isspace (c) != 0)
    c = readchar ();
  if (c == ';')
    return reader_eat_whitespace (reader_read_line_comment (c));
  if (c == '#')
    {
      int p = peekchar ();
      if (p == '!' || p == '|')
        {
          c = readchar ();
          reader_read_block_comment (c, readchar ());
          return reader_eat_whitespace (readchar ());
        }
    }
  return c;
}

struct scm *
reader_read_list (int c, struct scm *a)
{
  c = reader_eat_whitespace (c);
  if (c == ')')
    return cell_nil;
  if (c == EOF)
    error (cell_symbol_not_a_pair, make_string0 ("EOF in list"));
  struct scm *s = reader_read_sexp_ (c, a);
  if (s == cell_dot)
    {
      s = reader_read_list (readchar (), a);
      return s->car;
    }
  return cons (s, reader_read_list (readchar (), a));
}

struct scm *
read_env (struct scm *a)
{
  return reader_read_sexp_ (readchar (), a);
}

struct scm *
reader_read_block_comment (int s, int c)
{
  if (c == s)
    if (peekchar () == '#')
      {
        readchar ();
        return cell_unspecified;
      }
  return reader_read_block_comment (s, readchar ());
}

struct scm *
reader_read_hash (int c, struct scm *a)
{
  if (c == '!')
    {
      reader_read_block_comment (c, readchar ());
      return reader_read_sexp_ (readchar (), a);
    }
  if (c == '|')
    {
      reader_read_block_comment (c, readchar ());
      return reader_read_sexp_ (readchar (), a);
    }
  if (c == 'f')
    return cell_f;
  if (c == 't')
    return cell_t;
  if (c == ',')
    {
      if (peekchar () == '@')
        {
          readchar ();
          return cons (cell_symbol_unsyntax_splicing, cons (reader_read_sexp_ (readchar (), a), cell_nil));
        }

      return cons (cell_symbol_unsyntax, cons (reader_read_sexp_ (readchar (), a), cell_nil));
    }
  if (c == '\'')
    return cons (cell_symbol_syntax, cons (reader_read_sexp_ (readchar (), a), cell_nil));
  if (c == '`')
    return cons (cell_symbol_quasisyntax, cons (reader_read_sexp_ (readchar (), a), cell_nil));
  if (c == ':')
    {
      struct scm *x = reader_read_identifier_or_number (readchar ());
      struct scm *msg = make_string0 ("keyword perifx ':' not followed by a symbol: ");
      if (x->type == TNUMBER)
        error (cell_symbol_system_error, cons (msg, x));
      return symbol_to_keyword (x);
    }
  if (c == 'b')
    return reader_read_binary ();
  if (c == 'o')
    return reader_read_octal ();
  if (c == 'x')
    return reader_read_hex ();
  if (c == '\\')
    return reader_read_character ();
  if (c == '(')
    return list_to_vector (reader_read_list (readchar (), a));
  if (c == ';')
    {
      reader_read_sexp_ (readchar (), a);
      return reader_read_sexp_ (readchar (), a);
    }
  return reader_read_sexp_ (readchar (), a);
}

struct scm *
reader_read_sexp (struct scm *c, struct scm *s, struct scm *a)
{
  return reader_read_sexp_ (c->value, a);
}

struct scm *
reader_read_character ()
{
  int c = readchar ();
  int p = peekchar ();
  int i = 0;
  if (c >= '0' && c <= '7' && p >= '0' && p <= '7')
    {
      c = c - '0';
      while (p >= '0' && p <= '7')
        {
          c = c << 3;
          c = c + readchar () - '0';
          p = peekchar ();
        }
    }
  else if (c == 'x' && ((p >= '0' && p <= '9') || (p >= 'a' && p <= 'f') || (p >= 'F' && p <= 'F')))
    {
      struct scm *n = reader_read_hex ();
      c = n->value;
      eputs ("reading hex c=");
      eputs (itoa (c));
      eputs ("\n");
    }
  else if (((c >= 'a' && c <= 'z') || c == '*') && ((p >= 'a' && p <= 'z') || p == '*'))
    {
      char *buf = __reader_read_char_buf;
      buf[i] = c;
      i = i + 1;
      while ((p >= 'a' && p <= 'z') || p == '*')
        {
          buf[i] = readchar ();
          i = i + 1;
          p = peekchar ();
        }
      buf[i] = 0;
      if (strcmp (buf, "*eof*") == 0)
        c = EOF;
      else if (strcmp (buf, "nul") == 0)
        c = '\0';
      else if (strcmp (buf, "alarm") == 0)
        c = '\a';
      else if (strcmp (buf, "backspace") == 0)
        c = '\b';
      else if (strcmp (buf, "tab") == 0)
        c = '\t';
      else if (strcmp (buf, "linefeed") == 0)
        c = '\n';
      else if (strcmp (buf, "newline") == 0)
        c = '\n';
      else if (strcmp (buf, "vtab") == 0)
        c = '\v';
      else if (strcmp (buf, "page") == 0)
        c = '\f';
      else if (strcmp (buf, "return") == 0)
        /* Nyacc bug
           c = '\r'; */
        c = 13;
      else if (strcmp (buf, "esc") == 0)
        c = 27;
      else if (strcmp (buf, "space") == 0)
        c = ' ';
      /* Nyacc uses old abbrevs */
      else if (strcmp (buf, "bel") == 0)
        c = '\a';
      else if (strcmp (buf, "bs") == 0)
        c = '\b';
      else if (strcmp (buf, "ht") == 0)
        c = '\t';
      else if (strcmp (buf, "vt") == 0)
        c = '\v';
      else if (strcmp (buf, "cr") == 0)
        /* Nyacc bug
           c = '\r'; */
        c = 13;
      else
        {
          eputs ("char not supported: ");
          eputs (buf);
          eputs ("\n");
          error (cell_symbol_system_error, make_string0 ("char not supported"));
        }
    }
  return make_char (c);
}

struct scm *
reader_read_binary ()
{
  long n = 0;
  int c = peekchar ();
  int negative_p = 0;
  if (c == '-')
    {
      negative_p = 1;
      readchar ();
      c = peekchar ();
    }
  while (c == '0' || c == '1')
    {
      n = n << 1;
      n = n + c - '0';
      readchar ();
      c = peekchar ();
    }
  if (negative_p != 0)
    n = 0 - n;
  return make_number (n);
}

struct scm *
reader_read_octal ()
{
  long n = 0;
  int c = peekchar ();
  int negative_p = 0;
  if (c == '-')
    {
      negative_p = 1;
      readchar ();
      c = peekchar ();
    }
  while (c >= '0' && c <= '7')
    {
      n = n << 3;
      n = n + c - '0';
      readchar ();
      c = peekchar ();
    }
  if (negative_p != 0)
    n = 0 - n;
  return make_number (n);
}

struct scm *
reader_read_hex ()
{
  long n = 0;
  int c = peekchar ();
  int negative_p = 0;
  if (c == '-')
    {
      negative_p = 1;
      readchar ();
      c = peekchar ();
    }
  while ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'))
    {
      n = n << 4;
      if (c >= 'a')
        n = n + c - 'a' + 10;
      else if (c >= 'A')
        n = n + c - 'A' + 10;
      else
        n = n + c - '0';
      readchar ();
      c = peekchar ();
    }
  if (negative_p != 0)
    n = 0 - n;
  return make_number (n);
}

struct scm *
reader_read_string ()
{
  size_t i = 0;
  int c;
  struct scm *n;
  do
    {
      if (i > MAX_STRING)
        assert_max_string (i, "reader_read_string", g_buf);
      c = readchar ();
      if (c == '"')
        break;
      if (c == '\\')
        {
          c = readchar ();
          if (c == '\\' || c == '"')
            0;
          else if (c == '0')
            c = '\0';
          else if (c == 'a')
            c = '\a';
          else if (c == 'b')
            c = '\b';
          else if (c == 't')
            c = '\t';
          else if (c == 'n')
            c = '\n';
          else if (c == 'v')
            c = '\v';
          else if (c == 'f')
            c = '\f';
          else if (c == 'r')
            /* Nyacc bug
               c = '\r'; */
            c = 13;
          else if (c == 'e')
            /* Nyacc bug
               c = '\e'; */
            c = 27;
          else if (c == 'x')
            {
              n = reader_read_hex ();
              c = n->value;
            }
        }
      g_buf[i] = c;
      i = i + 1;
    }
  while (1);
  g_buf[i] = 0;
  return make_string (g_buf, i);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/src/stack.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/src/stack.c used in: Step 106, Step 226
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 * Copyright © 2021 W. J. van der Laan <laanwj@protonmail.com>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "mes/lib.h"
#include "mes/mes.h"

#include <stdlib.h>

struct scm *
frame_printer (struct scm *frame)
{
  fdputs ("#<", __stdout);
  display_ (struct_ref_ (frame, 2));
  fdputc (' ', __stdout);
  fdputs ("procedure: ", __stdout);
  display_ (struct_ref_ (frame, 3));
  fdputc ('>', __stdout);
}

struct scm *
make_frame_type ()              /*:((internal)) */
{
  struct scm *fields = cell_nil;
  fields = cons (cell_symbol_procedure, fields);
  fields = cons (fields, cell_nil);
  fields = cons (cell_symbol_frame, fields);
  return make_struct (cell_symbol_record_type, fields, cell_unspecified);
}

struct scm *
make_frame (struct scm *stack, long index)
{
  struct scm *frame_type = make_frame_type ();
  long array_index = 0;
  struct scm *procedure = 0;
  if (index != 0)
    {
      array_index = (STACK_SIZE - (index * GC_FRAME_SIZE));
      procedure = g_stack_array[array_index + GC_FRAME_PROCEDURE];
    }
  if (procedure == 0)
    procedure = cell_f;
  struct scm *values = cell_nil;
  values = cons (procedure, values);
  values = cons (cell_symbol_frame, values);
  return make_struct (frame_type, values, cstring_to_symbol ("frame-printer"));
}

struct scm *
make_stack_type ()              /*:((internal)) */
{
  struct scm *fields = cell_nil;
  fields = cons (cstring_to_symbol ("frames"), fields);
  fields = cons (fields, cell_nil);
  fields = cons (cell_symbol_stack, fields);
  return make_struct (cell_symbol_record_type, fields, cell_unspecified);
}

struct scm *
make_stack (struct scm *stack)          /*:((arity . n)) */
{
  struct scm *stack_type = make_stack_type ();
  long size = (STACK_SIZE - g_stack) / GC_FRAME_SIZE;
  struct scm *frames = make_vector_ (size, cell_unspecified);
  long i;
  struct scm* frame;
  for (i = 0; i < size; i = i + 1)
    {
      frame = make_frame (stack, i);
      vector_set_x_ (frames, i, frame);
    }
  struct scm *values = cell_nil;
  values = cons (frames, values);
  values = cons (cell_symbol_stack, values);
  return make_struct (stack_type, values, cell_unspecified);
}

struct scm *
stack_length (struct scm *stack)
{
  struct scm *frames = struct_ref_ (stack, 3);
  return vector_length (frames);
}

struct scm *
stack_ref (struct scm *stack, struct scm *index)
{
  struct scm *frames = struct_ref_ (stack, 3);
  return vector_ref (frames, index);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/src/string.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/src/string.c used in: Step 106, Step 227
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "mes/lib.h"
#include "mes/mes.h"

#include <limits.h>
#include <string.h>

void
assert_max_string (size_t i, char const *msg, char const *string)
{
  if (i > MAX_STRING)
    {
      eputs (msg);
      eputs (":string too long[");
      eputs (itoa (i));
      eputs ("]:");
      char *p = cast_voidp_to_charp (string);
      p[MAX_STRING - 1] = 0;
      eputs (p);
      error (cell_symbol_system_error, cell_f);
    }
}

char const *
list_to_cstring (struct scm *list, size_t *size)
{
  size_t i = 0;
  char *p = g_buf;
  struct scm *x;
  while (list != cell_nil)
    {
      if (i > MAX_STRING)
        assert_max_string (i, "list_to_string", g_buf);
      x = car (list);
      g_buf[i] = x->value;
      i = i + 1;
      list = cdr (list);
    }
  g_buf[i] = 0;
  size[0] = i;

  return g_buf;
}

struct scm *
string_equal_p (struct scm *a, struct scm *b)   /*:((name . "string=?")) */
{
  if (!((a->type == TSTRING && b->type == TSTRING) || (a->type == TKEYWORD || b->type == TKEYWORD)))
    {
      eputs ("type a: ");
      eputs (itoa (a->type));
      eputs ("\n");
      eputs ("type b: ");
      eputs (itoa (b->type));
      eputs ("\n");
      eputs ("a= ");
      write_error_ (a);
      eputs ("\n");
      eputs ("b= ");
      write_error_ (b);
      eputs ("\n");
      assert_msg ((a->type == TSTRING && b->type == TSTRING) || (a->type == TKEYWORD || b->type == TKEYWORD), "(a->type == TSTRING && b->type == TSTRING) || (a->type == TKEYWORD || b->type == TKEYWORD)");
    }
  if (a == b)
    return cell_t;
  if (a->string == b->string)
    return cell_t;
  if (a->length == 0 && b->length == 0)
    return cell_t;
  if (a->length == b->length)
    if (memcmp (cell_bytes (a->string), cell_bytes (b->string), a->length) == 0)
      return cell_t;

  return cell_f;
}

struct scm *
symbol_to_string (struct scm *symbol)
{
  return make_cell (TSTRING, symbol->car, symbol->cdr);
}

struct scm *
symbol_to_keyword (struct scm *symbol)
{
  return make_cell (TKEYWORD, symbol->car, symbol->cdr);
}

struct scm *
keyword_to_string (struct scm *keyword)
{
  return make_cell (TSTRING, keyword->car, keyword->cdr);
}

struct scm *
string_to_symbol (struct scm *string)
{
  struct scm *x = hash_ref (g_symbols, string, cell_f);
  if (x == cell_f)
    x = make_symbol (string);
  return x;
}

struct scm *
make_symbol (struct scm *string)
{
  struct scm *x = make_pointer_cell (TSYMBOL, string->length, string->string);
  hash_set_x (g_symbols, string, x);
  return x;
}

struct scm *
bytes_to_list (char const *s, size_t i)
{
  struct scm *p = cell_nil;
  int c;
  while (i != 0)
    {
      i = i - 1;
      c = (0x100 + s[i]) % 0x100;
      p = cons (make_char (c), p);
    }
  return p;
}

struct scm *
cstring_to_list (char const *s)
{
  return bytes_to_list (s, strlen (s));
}

struct scm *
cstring_to_symbol (char const *s)
{
  struct scm *string = make_string0 (s);
  return string_to_symbol (string);
}

struct scm *
string_to_list (struct scm *string)
{
  return bytes_to_list (cell_bytes (string->string), string->length);
}

struct scm *
list_to_string (struct scm *list)
{
  size_t size;
  char const *s = list_to_cstring (list, &size);
  return make_string (s, size);
}

struct scm *
read_string (struct scm *port)          /*:((arity . n)) */
{
  int fd = __stdin;
  if (port->type == TPAIR)
    {
      struct scm *p = car (port);
      if (p->type == TNUMBER)
        __stdin = p->value;
    }
  int c = readchar ();
  size_t i = 0;
  while (c != -1)
    {
      if (i > MAX_STRING)
        assert_max_string (i, "read_string", g_buf);
      g_buf[i] = c;
      i = i + 1;
      c = readchar ();
    }
  g_buf[i] = 0;
  __stdin = fd;
  return make_string (g_buf, i);
}

struct scm *
string_append (struct scm *x)           /*:((arity . n)) */
{
  char *p = g_buf;
  g_buf[0] = 0;
  size_t size = 0;
  struct scm *string;
  while (x != cell_nil)
    {
      string = x->car;
      assert_msg (string->type == TSTRING, "string->type == TSTRING");
      memcpy (p, cell_bytes (string->string), string->length + 1);
      p = p + string->length;
      size = size + string->length;
      if (size > MAX_STRING)
        assert_max_string (size, "string_append", g_buf);
      x = x->cdr;
    }
  return make_string (g_buf, size);
}

struct scm *
string_length (struct scm *string)
{
  assert_msg (string->type == TSTRING, "string->type == TSTRING");
  return make_number (string->length);
}

struct scm *
string_ref (struct scm *str, struct scm *k)
{
  assert_msg (str->type == TSTRING, "str->type == TSTRING");
  assert_msg (k->type == TNUMBER, "k->type == TNUMBER");
  size_t size = str->length;
  size_t i = k->value;
  if (i > size)
    error (cell_symbol_system_error, cons (make_string0 ("value out of range"), k));
  char const *p = cell_bytes (str->string);
  return make_char (p[i]);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/src/struct.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/src/struct.c used in: Step 106, Step 228
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "mes/lib.h"
#include "mes/mes.h"

struct scm *
make_struct (struct scm *type, struct scm *fields, struct scm *printer)
{
  long size = 2 + length__ (fields);
  struct scm *x = alloc (1);
  struct scm *v = alloc (size);
  x->type = TSTRUCT;
  x->length = size;
  x->structure = v;
  copy_cell (v, vector_entry (type));
  copy_cell (cell_ref (v, 1), vector_entry (printer));
  long i;
  struct scm *e;
  for (i = 2; i < size; i = i + 1)
    {
      e = cell_unspecified;
      if (fields != cell_nil)
        {
          e = fields->car;
          fields = fields->cdr;
        }
      copy_cell (cell_ref (v, i), vector_entry (e));
    }
  return x;
}

struct scm *
struct_length (struct scm *x)
{
  assert_msg (x->type == TSTRUCT, "x->type == TSTRUCT");
  return make_number (x->length);
}

struct scm *
struct_ref_ (struct scm *x, long i)
{
  assert_msg (x->type == TSTRUCT, "x->type == TSTRUCT");
  assert_msg (i < x->length, "i < x->length");
  struct scm *e = cell_ref (x->structure, i);
  if (e->type == TREF)
    e = e->ref;
  if (e->type == TCHAR)
    e = make_char (e->value);
  if (e->type == TNUMBER)
    e = make_number (e->value);
  return e;
}

struct scm *
struct_set_x_ (struct scm *x, long i, struct scm *e)
{
  assert_msg (x->type == TSTRUCT, "x->type == TSTRUCT");
  assert_msg (i < x->length, "i < x->length");
  copy_cell (cell_ref (x->structure, i), vector_entry (e));
  return cell_unspecified;
}

struct scm *
struct_ref (struct scm *x, struct scm *i)
{
  return struct_ref_ (x, i->value);
}

struct scm *
struct_set_x (struct scm *x, struct scm *i, struct scm *e)
{
  return struct_set_x_ (x, i->value, e);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/src/symbol.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/src/symbol.c used in: Step 106, Step 229
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2020,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "mes/lib.h"
#include "mes/mes.h"

#include <string.h>

// char const *MES_VERSION = "0.24.2";

#if __M2_PLANET__
#define M2_CELL_SIZE 12
// CONSTANT M2_CELL_SIZE 12
#else
#define M2_CELL_SIZE 1
// CONSTANT M2_CELL_SIZE 12
#endif

struct scm *
init_symbol (struct scm *x, long type, char const *name)
{
  x->type = type;
  if (g_symbols == 0)
    g_free = g_free + M2_CELL_SIZE;
  else
    {
      int length = strlen (name);
      struct scm *string = make_string (name, length);
      x->car_value = length;
      x->cdr = string->string;
      hash_set_x (g_symbols, string, x);
    }
  g_symbol = g_symbol + M2_CELL_SIZE;
  return x;
}

void
init_symbols_ ()                  /*:((internal)) */
{
  g_symbol = cell_nil;
  cell_nil = init_symbol (g_symbol, TSPECIAL, "()");
  cell_f = init_symbol (g_symbol, TSPECIAL, "#f");
  cell_t = init_symbol (g_symbol, TSPECIAL, "#t");
  cell_dot = init_symbol (g_symbol, TSPECIAL, ".");
  cell_arrow = init_symbol (g_symbol, TSPECIAL, "=>");
  cell_undefined = init_symbol (g_symbol, TSPECIAL, "*undefined*");
  cell_unspecified = init_symbol (g_symbol, TSPECIAL, "*unspecified*");
  cell_closure = init_symbol (g_symbol, TSPECIAL, "*closure*");
  cell_circular = init_symbol (g_symbol, TSPECIAL, "*circular*");

  cell_vm_apply = init_symbol (g_symbol, TSPECIAL, "core:apply");
  cell_vm_apply2 = init_symbol (g_symbol, TSPECIAL, "*vm-apply2*");
  cell_vm_begin = init_symbol (g_symbol, TSPECIAL, "*vm-begin*");
  cell_vm_begin_eval = init_symbol (g_symbol, TSPECIAL, "*vm:begin-eval*");
  cell_vm_begin_expand = init_symbol (g_symbol, TSPECIAL, "core:eval");
  cell_vm_begin_expand_eval = init_symbol (g_symbol, TSPECIAL, "*vm:begin-expand-eval*");
  cell_vm_begin_expand_macro = init_symbol (g_symbol, TSPECIAL, "*vm:begin-expand-macro*");
  cell_vm_begin_expand_primitive_load = init_symbol (g_symbol, TSPECIAL, "*vm:core:begin-expand-primitive-load*");
  cell_vm_begin_primitive_load = init_symbol (g_symbol, TSPECIAL, "*vm:core:begin-primitive-load*");
  cell_vm_begin_read_input_file = init_symbol (g_symbol, TSPECIAL, "*vm-begin-read-input-file*");
  cell_vm_call_with_current_continuation2 = init_symbol (g_symbol, TSPECIAL, "*vm-call-with-current-continuation2*");
  cell_vm_call_with_values2 = init_symbol (g_symbol, TSPECIAL, "*vm-call-with-values2*");
  cell_vm_eval = init_symbol (g_symbol, TSPECIAL, "core:eval-expanded");
  cell_vm_eval2 = init_symbol (g_symbol, TSPECIAL, "*vm-eval2*");
  cell_vm_eval_check_func = init_symbol (g_symbol, TSPECIAL, "*vm-eval-check-func*");
  cell_vm_eval_define = init_symbol (g_symbol, TSPECIAL, "*vm-eval-define*");
  cell_vm_eval_macro_expand_eval = init_symbol (g_symbol, TSPECIAL, "*vm:eval-macro-expand-eval*");
  cell_vm_eval_macro_expand_expand = init_symbol (g_symbol, TSPECIAL, "*vm:eval-macro-expand-expand*");
  cell_vm_eval_pmatch_car = init_symbol (g_symbol, TSPECIAL, "*vm-eval-pmatch-car*");
  cell_vm_eval_pmatch_cdr = init_symbol (g_symbol, TSPECIAL, "*vm-eval-pmatch-cdr*");
  cell_vm_eval_set_x = init_symbol (g_symbol, TSPECIAL, "*vm-eval-set!*");
  cell_vm_evlis = init_symbol (g_symbol, TSPECIAL, "*vm-evlis*");
  cell_vm_evlis2 = init_symbol (g_symbol, TSPECIAL, "*vm-evlis2*");
  cell_vm_evlis3 = init_symbol (g_symbol, TSPECIAL, "*vm-evlis3*");
  cell_vm_if = init_symbol (g_symbol, TSPECIAL, "*vm-if*");
  cell_vm_if_expr = init_symbol (g_symbol, TSPECIAL, "*vm-if-expr*");
  cell_vm_macro_expand = init_symbol (g_symbol, TSPECIAL, "core:macro-expand");
  cell_vm_macro_expand_car = init_symbol (g_symbol, TSPECIAL, "*vm:core:macro-expand-car*");
  cell_vm_macro_expand_cdr = init_symbol (g_symbol, TSPECIAL, "*vm:macro-expand-cdr*");
  cell_vm_macro_expand_define = init_symbol (g_symbol, TSPECIAL, "*vm:core:macro-expand-define*");
  cell_vm_macro_expand_define_macro = init_symbol (g_symbol, TSPECIAL, "*vm:core:macro-expand-define-macro*");
  cell_vm_macro_expand_lambda = init_symbol (g_symbol, TSPECIAL, "*vm:core:macro-expand-lambda*");
  cell_vm_macro_expand_set_x = init_symbol (g_symbol, TSPECIAL, "*vm:core:macro-expand-set!*");
  cell_vm_return = init_symbol (g_symbol, TSPECIAL, "*vm-return*");

  cell_symbol_lambda = init_symbol (g_symbol, TSYMBOL, "lambda");
  cell_symbol_begin = init_symbol (g_symbol, TSYMBOL, "begin");
  cell_symbol_if = init_symbol (g_symbol, TSYMBOL, "if");
  cell_symbol_quote = init_symbol (g_symbol, TSYMBOL, "quote");
  cell_symbol_define = init_symbol (g_symbol, TSYMBOL, "define");
  cell_symbol_define_macro = init_symbol (g_symbol, TSYMBOL, "define-macro");
  cell_symbol_quasiquote = init_symbol (g_symbol, TSYMBOL, "quasiquote");
  cell_symbol_unquote = init_symbol (g_symbol, TSYMBOL, "unquote");
  cell_symbol_unquote_splicing = init_symbol (g_symbol, TSYMBOL, "unquote-splicing");
  cell_symbol_syntax = init_symbol (g_symbol, TSYMBOL, "syntax");
  cell_symbol_quasisyntax = init_symbol (g_symbol, TSYMBOL, "quasisyntax");
  cell_symbol_unsyntax = init_symbol (g_symbol, TSYMBOL, "unsyntax");
  cell_symbol_unsyntax_splicing = init_symbol (g_symbol, TSYMBOL, "unsyntax-splicing");
  cell_symbol_set_x = init_symbol (g_symbol, TSYMBOL, "set!");
  cell_symbol_sc_expand = init_symbol (g_symbol, TSYMBOL, "sc-expand");
  cell_symbol_macro_expand = init_symbol (g_symbol, TSYMBOL, "macro-expand");
  cell_symbol_portable_macro_expand = init_symbol (g_symbol, TSYMBOL, "portable-macro-expand");
  cell_symbol_sc_expander_alist = init_symbol (g_symbol, TSYMBOL, "*sc-expander-alist*");
  cell_symbol_call_with_values = init_symbol (g_symbol, TSYMBOL, "call-with-values");
  cell_symbol_call_with_current_continuation = init_symbol (g_symbol, TSYMBOL, "call-with-current-continuation");
  cell_symbol_boot_module = init_symbol (g_symbol, TSYMBOL, "boot-module");
  cell_symbol_current_module = init_symbol (g_symbol, TSYMBOL, "current-module");
  cell_symbol_primitive_load = init_symbol (g_symbol, TSYMBOL, "primitive-load");
  cell_symbol_car = init_symbol (g_symbol, TSYMBOL, "car");
  cell_symbol_cdr = init_symbol (g_symbol, TSYMBOL, "cdr");
  cell_symbol_not_a_number = init_symbol (g_symbol, TSYMBOL, "not-a-number");
  cell_symbol_not_a_pair = init_symbol (g_symbol, TSYMBOL, "not-a-pair");
  cell_symbol_system_error = init_symbol (g_symbol, TSYMBOL, "system-error");
  cell_symbol_throw = init_symbol (g_symbol, TSYMBOL, "throw");
  cell_symbol_unbound_variable = init_symbol (g_symbol, TSYMBOL, "unbound-variable");
  cell_symbol_wrong_number_of_args = init_symbol (g_symbol, TSYMBOL, "wrong-number-of-args");
  cell_symbol_wrong_type_arg = init_symbol (g_symbol, TSYMBOL, "wrong-type-arg");

  cell_symbol_buckets = init_symbol (g_symbol, TSYMBOL, "buckets");
  cell_symbol_builtin = init_symbol (g_symbol, TSYMBOL, "<builtin>");
  cell_symbol_frame = init_symbol (g_symbol, TSYMBOL, "<frame>");
  cell_symbol_hashq_table = init_symbol (g_symbol, TSYMBOL, "<hashq-table>");
  cell_symbol_module = init_symbol (g_symbol, TSYMBOL, "<module>");
  cell_symbol_procedure = init_symbol (g_symbol, TSYMBOL, "procedure");
  cell_symbol_record_type = init_symbol (g_symbol, TSYMBOL, "<record-type>");
  cell_symbol_size = init_symbol (g_symbol, TSYMBOL, "size");
  cell_symbol_stack = init_symbol (g_symbol, TSYMBOL, "<stack>");
  cell_symbol_argv = init_symbol (g_symbol, TSYMBOL, "%argv");
  cell_symbol_mes_datadir = init_symbol (g_symbol, TSYMBOL, "%datadir");
  cell_symbol_mes_version = init_symbol (g_symbol, TSYMBOL, "%version");
  cell_symbol_internal_time_units_per_second = init_symbol (g_symbol, TSYMBOL, "internal-time-units-per-second");
  cell_symbol_compiler = init_symbol (g_symbol, TSYMBOL, "%compiler");
  cell_symbol_arch = init_symbol (g_symbol, TSYMBOL, "%arch");
  cell_symbol_pmatch_car = init_symbol (g_symbol, TSYMBOL, "pmatch-car");
  cell_symbol_pmatch_cdr = init_symbol (g_symbol, TSYMBOL, "pmatch-cdr");

  cell_type_bytes = init_symbol (g_symbol, TSYMBOL, "<cell:bytes>");
  cell_type_char = init_symbol (g_symbol, TSYMBOL, "<cell:char>");
  cell_type_closure = init_symbol (g_symbol, TSYMBOL, "<cell:closure>");
  cell_type_continuation = init_symbol (g_symbol, TSYMBOL, "<cell:continuation>");
  cell_type_function = init_symbol (g_symbol, TSYMBOL, "<cell:function>");
  cell_type_keyword = init_symbol (g_symbol, TSYMBOL, "<cell:keyword>");
  cell_type_macro = init_symbol (g_symbol, TSYMBOL, "<cell:macro>");
  cell_type_number = init_symbol (g_symbol, TSYMBOL, "<cell:number>");
  cell_type_pair = init_symbol (g_symbol, TSYMBOL, "<cell:pair>");
  cell_type_port = init_symbol (g_symbol, TSYMBOL, "<cell:port>");
  cell_type_ref = init_symbol (g_symbol, TSYMBOL, "<cell:ref>");
  cell_type_special = init_symbol (g_symbol, TSYMBOL, "<cell:special>");
  cell_type_string = init_symbol (g_symbol, TSYMBOL, "<cell:string>");
  cell_type_struct = init_symbol (g_symbol, TSYMBOL, "<cell:struct>");
  cell_type_symbol = init_symbol (g_symbol, TSYMBOL, "<cell:symbol>");
  cell_type_values = init_symbol (g_symbol, TSYMBOL, "<cell:values>");
  cell_type_variable = init_symbol (g_symbol, TSYMBOL, "<cell:variable>");
  cell_type_vector = init_symbol (g_symbol, TSYMBOL, "<cell:vector>");
  cell_type_broken_heart = init_symbol (g_symbol, TSYMBOL, "<cell:broken-heart>");

  cell_symbol_program = init_symbol (g_symbol, TSYMBOL, "%program");
  cell_symbol_test = init_symbol (g_symbol, TSYMBOL, "%%test");
}

struct scm *
init_symbols ()                  /*:((internal)) */
{
  g_free = g_cells + M2_CELL_SIZE;

  g_symbols = 0;
  cell_nil = g_free;
  init_symbols_ ();
  g_symbol_max = g_symbol;
  g_symbols = make_hash_table_ (500);
  init_symbols_ ();
  g_ports = cell_nil;

  struct scm *a = cell_nil;
  a = acons (cell_symbol_call_with_values, cell_symbol_call_with_values, a);
  a = acons (cell_symbol_boot_module, cell_symbol_boot_module, a);
  a = acons (cell_symbol_current_module, cell_symbol_current_module, a);

  a = acons (cell_symbol_mes_version, make_string0 (MES_VERSION), a);
  a = acons (cell_symbol_mes_datadir, make_string0 (g_datadir), a);

  a = acons (cell_type_bytes, make_number (TBYTES), a);
  a = acons (cell_type_char, make_number (TCHAR), a);
  a = acons (cell_type_closure, make_number (TCLOSURE), a);
  a = acons (cell_type_continuation, make_number (TCONTINUATION), a);
  a = acons (cell_type_keyword, make_number (TKEYWORD), a);
  a = acons (cell_type_macro, make_number (TMACRO), a);
  a = acons (cell_type_number, make_number (TNUMBER), a);
  a = acons (cell_type_pair, make_number (TPAIR), a);
  a = acons (cell_type_port, make_number (TPORT), a);
  a = acons (cell_type_ref, make_number (TREF), a);
  a = acons (cell_type_special, make_number (TSPECIAL), a);
  a = acons (cell_type_string, make_number (TSTRING), a);
  a = acons (cell_type_struct, make_number (TSTRUCT), a);
  a = acons (cell_type_symbol, make_number (TSYMBOL), a);
  a = acons (cell_type_values, make_number (TVALUES), a);
  a = acons (cell_type_variable, make_number (TVARIABLE), a);
  a = acons (cell_type_vector, make_number (TVECTOR), a);
  a = acons (cell_type_broken_heart, make_number (TBROKEN_HEART), a);

  a = acons (cell_closure, a, a);

  return a;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/src/vector.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/src/vector.c used in: Step 106, Step 230
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "mes/lib.h"
#include "mes/mes.h"

#if __M2_PLANET__
#define M2_CELL_SIZE 12
// CONSTANT M2_CELL_SIZE 12
#else
#define M2_CELL_SIZE 1
// CONSTANT M2_CELL_SIZE 12
#endif

struct scm *
make_vector_ (long k, struct scm *e)
{
  struct scm *x = alloc (1);
  struct scm *v = alloc (k);
  x->type = TVECTOR;
  x->length = k;
  x->vector = v;
  long i;
  for (i = 0; i < k; i = i + 1)
    copy_cell (cell_ref (v, i), vector_entry (e));

  return x;
}

struct scm *
make_vector (struct scm *x)               /*:((arity . n)) */
{
  struct scm *k = x->car;
  assert_number ("make-vector", k);
  long n = k->value;
  struct scm *e = cell_unspecified;
  if (x->cdr != cell_nil)
    e = x->cdr->car;

  return make_vector_ (n, e);
}

struct scm *
vector_length (struct scm *x)
{
  assert_msg (x->type == TVECTOR, "x->type == TVECTOR");
  return make_number (x->length);
}

struct scm *
vector_ref_ (struct scm *x, long i)
{
  assert_msg (x->type == TVECTOR, "x->type == TVECTOR");
  assert_msg (i < x->length, "i < x->length");
  struct scm *e = cell_ref (x->vector, i);
  if (e->type == TREF)
    e = e->ref;
  if (e->type == TCHAR)
    e = make_char (e->value);
  if (e->type == TNUMBER)
    e = make_number (e->value);
  return e;
}

struct scm *
vector_ref (struct scm *x, struct scm *i)
{
  return vector_ref_ (x, i->value);
}

struct scm *
vector_entry (struct scm *x)
{
  if (x->type != TCHAR && x->type != TNUMBER)
    x = make_ref (x);
  return x;
}

struct scm *
vector_set_x_ (struct scm *x, long i, struct scm *e)
{
  assert_msg (x->type == TVECTOR, "x->type == TVECTOR");
  assert_msg (i < x->length, "i < x->length");
  copy_cell (cell_ref (x->vector, i), vector_entry (e));
  return cell_unspecified;
}

struct scm *
vector_set_x (struct scm *x, struct scm *i, struct scm *e)
{
  return vector_set_x_ (x, i->value, e);
}

struct scm *
list_to_vector (struct scm *x)
{
  struct scm *v = make_vector_ (length__ (x), cell_unspecified);
  struct scm *p = v->vector;
  while (x != cell_nil)
    {
      copy_cell (p, vector_entry (car (x)));
      p = p + M2_CELL_SIZE;
      x = cdr (x);
    }
  return v;
}

struct scm *
vector_to_list (struct scm *v)
{
  struct scm *x = cell_nil;
  long i;
  struct scm *e;
  for (i = v->length; i; i = i - 1)
    {
      e = cell_ref (v->vector, i - 1);
      if (e->type == TREF)
        e = e->ref;
      x = cons (e, x);
    }
  return x;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/x86-mes/x86.M1?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/lib/x86-mes/x86.M1 used in: Step 108, Step 296
### GNU Mes --- Maxwell Equations of Software
### Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
###
### This file is part of GNU Mes.
###
### Mes is free software# you can redistribute it and/or modify it
### under the terms of the GNU General Public License as published by
### the Free Software Foundation# either version 3 of the License, or (at
### your option) any later version.
###
### GNU Mes is distributed in the hope that it will be useful, but
### WITHOUT ANY WARRANTY# without even the implied warranty of
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
### GNU General Public License for more details.
###
### You should have received a copy of the GNU General Public License
### along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.

# reduced instruction set: eax, ebx (some ecx for shift, edx for mul, div)
# 193 instructions

DEFINE add____$i32,%eax 05
DEFINE add____$i32,%ebx 81c3
DEFINE add____$i32,(%eax) 8100
DEFINE add____$i32,(%ebx) 8103
DEFINE add____$i32,0x32(%eax) 8180
DEFINE add____$i32,0x32(%ebp) 8185
DEFINE add____$i8,%eax 83c0
DEFINE add____$i8,%ebx 83c3
DEFINE add____$i8,%esp 83c4
DEFINE add____$i8,(%eax) 8300
DEFINE add____$i8,(%ebx) 8303
DEFINE add____$i8,0x32 8305
DEFINE add____$i8,0x32(%eax) 8380
DEFINE add____$i8,0x32(%ebp) 8385
DEFINE add____$i8,0x8(%eax) 8340
DEFINE add____$i8,0x8(%ebp) 8345
DEFINE add____%eax,%eax 01c0
DEFINE add____%ebp,%eax 01e8
DEFINE add____%ebx,%eax 01d8
DEFINE add____%ebx,%ebx 01db
DEFINE addb___$i8,(%eax) 8000
DEFINE addb___$i8,(%ebx) 8003
DEFINE addw___$i8,(%eax) 668100
DEFINE addw___$i8,(%ebx) 668103
DEFINE and____$i32,%eax 25
DEFINE and____$i32,%ebx 81e3
DEFINE and____%ebx,%eax 21d8
DEFINE call32 e8
DEFINE call___*%eax ffd0
DEFINE call___*%ebx ffd3
DEFINE cltd 99
DEFINE cmp____$0x32,%eax 3d
DEFINE cmp____$i32,%eax 3d
DEFINE cmp____$i8,%eax 83f8
DEFINE cmp____$i8,%ebx 81fb
DEFINE div___%ebx f7f3
DEFINE hlt f4
DEFINE idiv___%ebx f7fb
DEFINE int cd
DEFINE int____$0x80 cd80
DEFINE ja32  0f87
DEFINE jae32 0f83
DEFINE jb32  0f82
DEFINE jbe32 0f86
DEFINE je32 0f84
DEFINE je8 74
DEFINE jg32 0f8f
DEFINE jge32 0f8d
DEFINE jl32 0f8c
DEFINE jle32 0f8e
DEFINE jmp32 e9
DEFINE jmp____*%ebx ffe3
DEFINE jne32 0f85
DEFINE lahf 9f
DEFINE lea____0x32(%ebp),%eax 8d85
DEFINE lea____0x8(%ebp),%eax 8d45
DEFINE leave c9
DEFINE mov____$i32,%eax b8
DEFINE mov____$i32,%ebx bb
DEFINE mov____$i32,(%eax) c700
DEFINE mov____$i32,0x32 c705
DEFINE mov____$i32,0x8(%eax) c740
DEFINE mov____$i32,0x8(%ebp) c745
DEFINE mov____$i8,%al b0
DEFINE mov____$i8,%eax b0
DEFINE mov____%al,(%ebx) 8803
DEFINE mov____%al,0x8(%ebp) 8845
DEFINE mov____%ax,(%ebx) 668903
DEFINE mov____%ax,0x8(%ebp) 668945
DEFINE mov____%bx,%bx 6689db
DEFINE mov____%cl,(%ebx) 8a08
DEFINE mov____%cx,(%ebx) 668b08
DEFINE mov____%dl,(%eax) 8810
DEFINE mov____%dl,0x8(%eax) 8850
DEFINE mov____%eax,%ebx 89c3
DEFINE mov____%eax,%ecx 89c1
DEFINE mov____%eax,(%ebx) 8903
DEFINE mov____%eax,0x32 a3
DEFINE mov____%eax,0x32(%ebp) 8985
DEFINE mov____%eax,0x8(%ebp) 8945
DEFINE mov____%ebp,%eax 89e8
DEFINE mov____%ebp,%ebx 89eb
DEFINE mov____%ebx,%eax 89d8
DEFINE mov____%ebx,%ecx 89d9
DEFINE mov____%ebx,0x32 891d
DEFINE mov____%ebx,0x32(%ebp) 899d
DEFINE mov____%ebx,0x8(%ebp) 895d
DEFINE mov____%ecx,(%ebx) 890b
DEFINE mov____%edi,%ebp 89fd
DEFINE mov____%edx,%eax 89d0
DEFINE mov____%edx,%ebx 89d3
DEFINE mov____%esp,%ebp 89e5
DEFINE mov____%esp,%edi 89e7
DEFINE mov____(%eax),%cl 8a08
DEFINE mov____(%eax),%cx 668b08
DEFINE mov____(%eax),%eax 8b00
DEFINE mov____(%eax),%ecx 8b08
DEFINE mov____(%ebx),%ebx 8b1b
DEFINE mov____0x32(%eax),%eax 8b80
DEFINE mov____0x32(%eax),%ebx 8b98
DEFINE mov____0x32(%ebp),%eax 8b85
DEFINE mov____0x32(%ebp),%ebx 8b9d
DEFINE mov____0x32,%eax a1
DEFINE mov____0x32,%ebx 8b1d
DEFINE mov____0x8(%eax),%eax 8b40
DEFINE mov____0x8(%eax),%ebx 8b58
DEFINE mov____0x8(%ebp),%eax 8b45
DEFINE mov____0x8(%ebp),%ebp 8b6d
DEFINE mov____0x8(%ebp),%ebx 8b5d
DEFINE mov____0x8(%ebp),%ecx 8b4d
DEFINE mov____0x8(%ebp),%edi 8b7d
DEFINE mov____0x8(%ebp),%edx 8b55
DEFINE mov____0x8(%ebp),%esi 8b75
DEFINE mov____0x8(%ebp),%esp 8b65
DEFINE movb___%al,0x32 a2
DEFINE movb___%bl,0x32 881d
DEFINE movsbl_%al,%eax 0fbec0
DEFINE movsbl_%bl,%ebx 0fbedb
DEFINE movswl_%ax,%eax 0fbfc0
DEFINE movswl_%bx,%ebx 0fbfdb
DEFINE movw___%ax,0x32 66a3
DEFINE movw___%bx,0x32 66891d
DEFINE movzbl_%al,%eax 0fb6c0
DEFINE movzbl_%bl,%ebx 0fb6db
DEFINE movzbl_(%eax),%eax 0fb600
DEFINE movzbl_(%ebx),%ebx 0fb61b
DEFINE movzbl_0x32(%eax),%eax 0fb680
DEFINE movzbl_0x8(%eax),%eax 0fb640
DEFINE movzbl_0x8(%ebp),%eax 0fb645
DEFINE movzwl_%ax,%eax 0fb7c0
DEFINE movzwl_%bx,%ebx 0fb7db
DEFINE movzwl_(%eax),%eax 0fb700
DEFINE movzwl_(%ebx),%ebx 0fb71b
DEFINE movzwl_0x32(%eax),%eax 0fb780
DEFINE movzwl_0x32(%ebp),%eax 0fb785
DEFINE movzwl_0x8(%eax),%eax 0fb740
DEFINE mul____%ebx f7e3
DEFINE mul_____%ebx f7e3
DEFINE nop 90
DEFINE not____%eax f7d0
DEFINE not____%ebx f7d3
DEFINE or_____%ebx,%eax 09d8
DEFINE pop____%eax 58
DEFINE pop____%ebx 5b
DEFINE pop____%edx 5a
DEFINE push___$i32 68
DEFINE push___%eax 50
DEFINE push___%ebp 55
DEFINE push___%ebx 53
DEFINE push___%edx 52
DEFINE push___(%eax) ff30
DEFINE push___0x32(%ebp) ffb5
DEFINE push___0x8(%ebp) ff75
DEFINE ret c3
DEFINE sahf 9e
DEFINE seta___%al 0f97c0
DEFINE seta___%bl 0f97c3
DEFINE setae__%al 0f93c0
DEFINE setae__%bl 0f93c3
DEFINE setb___%al 0f92c0
DEFINE setb___%bl 0f92c3
DEFINE setbe__%al 0f96c0
DEFINE setbe__%bl 0f96c3
DEFINE sete___%al 0f94c0
DEFINE sete___%bl 0f94c3
DEFINE setg___%al 0f9fc0
DEFINE setg___%bl 0f9fc3
DEFINE setge__%al 0f9dc0
DEFINE setge__%bl 0f9dc3
DEFINE setl___%al 0f9cc0
DEFINE setl___%bl 0f9cc3
DEFINE setle__%al 0f9ec0
DEFINE setle__%bl 0f9ec3
DEFINE setne__%al 0f95c0
DEFINE setne__%bl 0f95c3
DEFINE shl____$i8,%eax c1e0
DEFINE shl____$i8,%ebx c1e3
DEFINE shl____%cl,%eax d3e0
DEFINE shl____%cl,%ebx d3e3
DEFINE shr____%cl,%eax d3e8
DEFINE sub____$8,%esp 83ec
DEFINE sub____$i32,%esp 81ec
DEFINE sub____%al,%dl 28d0
DEFINE sub____%dl,%al 28c2
DEFINE sub____%ebx,%eax 29d8
DEFINE test___%al,%al 84c0
DEFINE test___%eax,%eax 85c0
DEFINE test___%ebx,%ebx 85db
DEFINE xchg___%eax,%ebx 93
DEFINE xchg___%eax,(%esp) 870424
DEFINE xchg___%ebx,(%esp) 871c24
DEFINE xor____$i32,%eax 35
DEFINE xor____$i8,%ah 80f4
DEFINE xor____%eax,%eax 31c0
DEFINE xor____%ebx,%eax 31d8
DEFINE xor____%ebx,%ebx 31db
DEFINE xor____%edx,%edx 31d2


# Enough for all of Mes + Mes C Libray when using all registers, i.e.,
# non-reduced instruction set
#DEFINE add____$i32,%ecx 81c1
#DEFINE add____$i32,%edx 81c2
#DEFINE add____$i32,%esi 81c6
#DEFINE add____$i8,%ecx 83c1
#DEFINE add____$i8,%edx 83c2
#DEFINE add____$i8,%esi 83c6
#DEFINE add____$i8,(%ecx) 8301
#DEFINE add____$i8,(%edx) 8302
#DEFINE add____%ecx,%ebx 01cb
#DEFINE add____%ecx,%ecx 01c9
#DEFINE add____%edx,%eax 01d0
#DEFINE add____%edx,%ecx 01d1
#DEFINE add____%edx,%edx 01d2
#DEFINE add____%esi,%edx 01f2
#DEFINE and____$i32,%ecx 81e1
#DEFINE and____$i32,%edx 81e2
#DEFINE and____%edx,%eax 21d0
#DEFINE and____(%edx),%eax 2302
#DEFINE cmp____%edx,%eax 39d0
#DEFINE idiv___%ecx f7f9
#DEFINE lea____0x32(%ebp),%edx 8d95
#DEFINE lea____0x8(%ebp),%edx 8d55
#DEFINE mov____$i32,%ecx b9
#DEFINE mov____$i32,%edx ba
#DEFINE mov____$i32,%esi be
#DEFINE mov____%al,(%edx) 8802
#DEFINE mov____%al,0x8(%edx) 8842
#DEFINE mov____%ax,(%edx) 668902
#DEFINE mov____%ax,0x32(%edx) 668982
#DEFINE mov____%ax,0x8(%edx) 668942
#DEFINE mov____%bl,(%ecx) 8819
#DEFINE mov____%eax,%edx 89c2
#DEFINE mov____%eax,%esi 89c6
#DEFINE mov____%eax,(%ecx) 8901
#DEFINE mov____%eax,(%edx) 8902
#DEFINE mov____%eax,0x32(%edx) 8982
#DEFINE mov____%eax,0x8(%edx) 8942
#DEFINE mov____%ebp,%ecx 89e9
#DEFINE mov____%ebp,%edx 89ea
#DEFINE mov____%ebp,%esi 89ee
#DEFINE mov____%ebx,(%ecx) 8919
#DEFINE mov____%ebx,0x8(%edx) 895a
#DEFINE mov____%ecx,%eax 89c8
#DEFINE mov____%ecx,%ecx 89c9
#DEFINE mov____%ecx,%edx 89ca
#DEFINE mov____%ecx,(%eax) 8908
#DEFINE mov____%ecx,(%edx) 890a
#DEFINE mov____%ecx,0x32(%ebp) 898d
#DEFINE mov____%ecx,0x8(%ebp) 894d
#DEFINE mov____%edi,%ebx 89fb
#DEFINE mov____%edx,%ecx 89d1
#DEFINE mov____%edx,(%eax) 8910
#DEFINE mov____%edx,0x32(%ebp) 8995
#DEFINE mov____%edx,0x8(%ebp) 8955
#DEFINE mov____%esi,%eax 89f0
#DEFINE mov____%esi,%ebx 89f3
#DEFINE mov____(%ecx),%ecx 8b09
#DEFINE mov____(%edx),%eax 8b02
#DEFINE mov____(%edx),%ecx 8b0a
#DEFINE mov____(%edx),%edx 8b12
#DEFINE mov____0x32(%eax),%ecx 8b88
#DEFINE mov____0x32(%ebp),%ecx 8b8d
#DEFINE mov____0x32(%ebp),%edx 8b95
#DEFINE mov____0x32,%ecx 8b0d
#DEFINE mov____0x32,%edx 8b15
#DEFINE mov____0x8(%eax),%ecx 8b48
#DEFINE movsbl_%cl,%ecx 0fbec9
#DEFINE movsbl_%dl,%edx 0fbed2
#DEFINE movswl_%cx,%ecx 0fbfc9
#DEFINE movzbl_%cl,%ecx 0fb6c9
#DEFINE movzbl_%dl,%edx 0fb6d2
#DEFINE movzbl_(%eax),%edx 0fb610
#DEFINE movzbl_(%ecx),%ecx 0fb609
#DEFINE movzbl_(%edx),%edx 0fb612
#DEFINE movzwl_(%ecx),%ecx 0fb709
#DEFINE mul____%ecx f7e1
#DEFINE mul____%edi f7e7
#DEFINE mul____%edx f7e2
#DEFINE mul____%esi f7e6
#DEFINE or_____%ecx,%ebx 09cb
#DEFINE or_____%edx,%eax 09d0
#DEFINE or_____(%edx),%eax 0b02
#DEFINE pop____%ecx 59
#DEFINE pop____%edi 5f
#DEFINE push___%ecx 51
#DEFINE push___%edi 57
#DEFINE push___%esi 56
#DEFINE shl____$i8,%ecx c1e1
#DEFINE shl____$i8,%edx c1e2
#DEFINE shl____%cl,%ecx d3e1
#DEFINE sub____%eax,%edx 29c2
#DEFINE sub____%ecx,%ebx 29cb
#DEFINE sub____%edx,%eax 29d0
#DEFINE sub____%edx,%ecx 29d1
#DEFINE xchg___%ebx,%ecx 87d9
#DEFINE xchg___%ecx,%edx 87ca
#DEFINE xor____%ecx,%ecx 31c9
#DEFINE xor____%edx,%eax 31d0


# deprecated, remove after 0.18
DEFINE sub____%esp,$i32 81ec
DEFINE sub____%esp,$i8 83ec

DEFINE SYS_exit   01000000
DEFINE SYS_fork   02000000
DEFINE SYS_read   03000000
DEFINE SYS_rmdir  28000000
DEFINE SYS_write  04000000
DEFINE SYS_open   05000000
DEFINE SYS_close  06000000
DEFINE SYS_waitpid 07000000
DEFINE SYS_unlink 0a000000
DEFINE SYS_execve 0b000000
DEFINE SYS_chmod  0f000000
DEFINE SYS_lseek  13000000
DEFINE SYS_access 21000000
DEFINE SYS_brk    2d000000
DEFINE SYS_ioctl  36000000
DEFINE SYS_stat   6a000000
DEFINE SYS_fsync  76000000
DEFINE SYS_getcwd b7000000

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-m2/crt1.M1?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/x86-mes-m2/crt1.M1 used in: Step 108
### GNU Mes --- Maxwell Equations of Software
### Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
###
### This file is part of GNU Mes.
###
### GNU Mes is free software; you can redistribute it and/or modify it
### under the terms of the GNU General Public License as published by
### the Free Software Foundation; either version 3 of the License, or (at
### your option) any later version.
###
### GNU Mes is distributed in the hope that it will be useful, but
### WITHOUT ANY WARRANTY; without even the implied warranty of
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
### GNU General Public License for more details.
###
### You should have received a copy of the GNU General Public License
### along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.

:_start
    push___%ebp
    mov____%esp,%ebp
    sub____$i32,%esp %0x1054
    mov____$i8,%eax !0
    mov____%eax,0x32 &GLOBAL___stdin
    mov____$i8,%eax !1
    mov____%eax,0x32 &GLOBAL___stdout
    mov____$i8,%eax !2
    mov____%eax,0x32 &GLOBAL___stderr
    mov____%ebp,%eax
    add____$i8,%eax !4
    mov____(%eax),%eax
    add____$i8,%eax !3
    shl____$i8,%eax !0x02
    add____%ebp,%eax
    mov____%eax,0x32 &GLOBAL_environ

    mov____%esp,%edi    ; M2-Planet calling convention pushes forward
    mov____%ebp,%eax    ; argc
    add____$i8,%eax !4
    mov____(%eax),%eax
    push___%eax

    mov____%ebp,%eax    ; argv
    add____$i8,%eax !8
    push___%eax

    mov____0x32,%eax &GLOBAL_environ
    push___%eax

    mov____%edi,%ebp        ; M2-Planet calling convention
    call32 %FUNCTION_main
    add____$i8,%esp !0x0
    test___%eax,%eax
    mov____%eax,%ebx
    mov____$i32,%eax %1
    int____$0x80
    hlt
    leave
    ret

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/m2/x86/ELF-x86.hex2?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/lib/m2/x86/ELF-x86.hex2 used in: Step 110
### Copyright (C) 2016 Jeremiah Orians
### Copyright (C) 2017 Jan Nieuwenhuizen <janneke@gnu.org>
### This file is part of M2-Planet.
###
### M2-Planet is free software: you can redistribute it and/or modify
### it under the terms of the GNU General Public License as published by
### the Free Software Foundation, either version 3 of the License, or
### (at your option) any later version.
###
### M2-Planet is distributed in the hope that it will be useful,
### but WITHOUT ANY WARRANTY; without even the implied warranty of
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
### GNU General Public License for more details.
###
### You should have received a copy of the GNU General Public License
### along with M2-Planet.  If not, see <http://www.gnu.org/licenses/>.

### stage0's hex2 format
###    !<label>          1 byte relative
###    $<label>          2 byte address
###    @<label>          2 byte relative
###    &<label>          4 byte address
###    %<label>          4 byte relative

### if you wish to use this header, you need to add :ELF_end to the end of your
### M1 or hex2 files.

## ELF Header

:ELF_base
7F 45 4C 46                    # e_ident[EI_MAG0-3] ELF's magic number

01                             # e_ident[EI_CLASS] Indicating 32 bit
01                             # e_ident[EI_DATA] Indicating little endianness
01                             # e_ident[EI_VERSION] Indicating original elf

03                             # e_ident[EI_OSABI] Set at 3 because FreeBSD is strict
00                             # e_ident[EI_ABIVERSION] See above

00 00 00 00 00 00 00           # e_ident[EI_PAD]

02 00                          # e_type Indicating Executable
03 00                          # e_machine Indicating 386
01 00 00 00                    # e_version Indicating original elf

&_start                        # e_entry Address of the entry point
%ELF_program_headers>ELF_base  # e_phoff Address of program header table
%ELF_section_headers>ELF_base  # e_shoff Address of section header table

00 00 00 00                    # e_flags

34 00                          # e_ehsize Indicating our 52 Byte header

20 00                          # e_phentsize size of a program header table
01 00                          # e_phnum number of entries in program table

28 00                          # e_shentsize size of a section header table
05 00                          # e_shnum number of entries in section table

02 00                          # e_shstrndx index of the section names


:ELF_program_headers
:ELF_program_header__text
01 00 00 00                    # ph_type: PT-LOAD = 1
00 00 00 00                    # ph_offset
&ELF_base                      # ph_vaddr
&ELF_base                      # ph_physaddr
%ELF_end>ELF_base              # ph_filesz
%ELF_end>ELF_base              # ph_memsz
07 00 00 00                    # ph_flags: PF-X|PF-W|PF-R = 7
01 00 00 00                    # ph_alignment

:ELF_text

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-mescc/crt1.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/x86-mes-mescc/crt1.c used in: Step 121
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018,2021 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "mes/lib-mini.h"

int main (int argc, char *argv[], char *envp[]);

int
_start ()
{
  asm ("mov____$i8,%eax !0");
  asm ("mov____%eax,0x32 &__stdin");

  asm ("mov____$i8,%eax !1");
  asm ("mov____%eax,0x32 &__stdout");

  asm ("mov____$i8,%eax !2");
  asm ("mov____%eax,0x32 &__stderr");

  asm ("mov____%ebp,%eax");
  asm ("add____$i8,%eax !4");

  asm ("mov____(%eax),%eax");
  asm ("add____$i8,%eax !3");

  asm ("shl____$i8,%eax !0x02");
  asm ("add____%ebp,%eax");
  asm ("mov____%eax,0x32 &environ");
  asm ("push___%eax");

  asm ("mov____%ebp,%eax");
  asm ("add____$i8,%eax !8");
  asm ("push___%eax");

  asm ("mov____%ebp,%eax");
  asm ("add____$i8,%eax !4");
  asm ("mov____(%eax),%eax");
  asm ("push___%eax");

  main ();

  asm ("mov____%eax,%ebx");
  asm ("mov____$i32,%eax %1");
  asm ("int____$0x80");
  asm ("hlt");
}

https://git.savannah.gnu.org/cgit/mes.git/tree/include/mes/lib-mini.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef __MES_LIB_MINI_H
#define __MES_LIB_MINI_H

#if HAVE_CONFIG_H
#include <mes/config.h>
#endif

// CONSTANT STDIN 0
#ifndef STDIN
#define STDIN 0
#endif

// CONSTANT STDOUT 1
#ifndef STDOUT
#define STDOUT 1
#endif

// CONSTANT STDERR 2
#ifndef STDERR
#define STDERR 2
#endif

extern char **environ;
extern int __stdin;
extern int __stdout;
extern int __stderr;

int eputs (char const *s);
int puts (char const *s);
int oputs (char const *s);

#if SYSTEM_LIBC

#include <sys/types.h>
#include <unistd.h>

#else //!SYSTEM_LIBC

#ifndef _SIZE_T
#define _SIZE_T
#ifndef __SIZE_T
#define __SIZE_T
#ifndef __MES_SIZE_T
#define __MES_SIZE_T
#undef size_t
typedef unsigned long size_t;
#endif
#endif
#endif

#ifndef _SSIZE_T
#define _SSIZE_T
#ifndef __SSIZE_T
#define __SSIZE_T
#ifndef __MES_SSIZE_T
#define __MES_SSIZE_T
#undef ssize_t
#if __i386__
typedef int ssize_t;
#else
typedef long ssize_t;
#endif
#endif
#endif
#endif

#ifndef __MES_ERRNO_T
#define __MES_ERRNO_T 1
typedef int error_t;
extern int errno;
#endif // !__MES_ERRNO_T

size_t strlen (char const *s);
ssize_t _write ();
ssize_t write (int filedes, void const *buffer, size_t size);
#endif // !SYSTEM_LIBC

#endif //__MES_LIB_MINI_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/string.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_STRING_H
#define __MES_STRING_H 1

#if SYSTEM_LIBC
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#undef __MES_STRING_H
#include_next <string.h>

#else // ! SYSTEM_LIBC

#include <sys/types.h>

void *memchr (void const *block, int c, size_t size);
void *memcpy (void *dest, void const *src, size_t n);
void *memmove (void *dest, void const *src, size_t n);
void *memset (void *s, int c, size_t n);
void *memchr (void const *block, int c, size_t size);
int memcmp (void const *s1, void const *s2, size_t n);
void *memmem (void const *haystack, int haystack_len, void const *needle, int needle_len);
char *strcat (char *dest, char const *src);
char *strchr (char const *s, int c);
int strcasecmp (char const *s1, char const *s2);
int strcmp (char const *, char const *);
char *strcpy (char *dest, char const *src);
size_t strlen (char const *);
char *strncpy (char *to, char const *from, size_t size);
int strncmp (char const *, char const *, size_t);
char *strrchr (char const *s, int c);
char *strstr (char const *haystack, char const *needle);
char *strlwr (char *string);
char *strupr (char *string);


char *strerror (int errnum);
void perror (char const *message);

#endif // ! SYSTEM_LIBC

#endif // __MES_STRING_H

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/oputs.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib-mini.h>
#include <string.h>

int
oputs (char const *s)
{
  int i = strlen (s);
  write (__stdout, s, i);
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/exit.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>

void (*__call_at_exit) (void);

void
exit (int code)
{
  if (__call_at_exit)
    (*__call_at_exit) ();
  _exit (code);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/include/mes/lib.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef __MES_LIB_H
#define __MES_LIB_H

#include <mes/lib-mini.h>

char *cast_intp_to_charp (int const *i);
char *cast_long_to_charp (long i);
long cast_charp_to_long (char const *);
long cast_int_to_long (int i);
long cast_voidp_to_long (void const *);

int __mes_debug ();
void __ungetc_init ();
void __ungetc_clear (int filedes);
void __ungetc_set (int filedes, int c);
int __ungetc_p (int filedes);
double abtod (char const **p, int base);
long abtol (char const **p, int base);
char *dtoab (double number, int base, int signed_p);
char *itoa (int number);
char *ltoa (long number);
char *ltoab (long x, int base);
char *ntoab (long number, unsigned base, int signed_p);
char *ultoa (unsigned long number);
char *utoa (unsigned number);
int eputc (int c);
int fdgetc (int fd);
char * fdgets (char *s, int count, int fd);
int fdputc (int c, int fd);
int fdputs (char const *s, int fd);
int fdungetc (int c, int fd);
char *_getcwd (char *buffer, size_t size);
int ioctl3 (int filedes, size_t command, long data);
int isnumber (int c, int base);
int mes_open (char const *file_name, int flags, int mask);
int _open2 (char const *file_name, int flags);
int _open3 (char const *file_name, int flags, int mask);
int oputc (int c);
int oputs (char const *s);
char *search_path (char const *file_name);
ssize_t _read (int fd, void *buffer, size_t size);
void assert_msg (int check, char *msg);

extern char *__brk;
extern void (*__call_at_exit) (void);

#define __FILEDES_MAX 512

#if !SYSTEM_LIBC
void __assert_fail (char const *s, char const *file, unsigned line,
                    char const *function);
ssize_t __buffered_read (int filedes, void *buffer, size_t size);
size_t __buffered_read_clear (int filedes);
void _exit (int code);
long brk (void *addr);
#endif // !SYSTEM_LIBC

long __mesabi_imod (long a, long b);
long __mesabi_idiv (long a, long b);
unsigned long __mesabi_umod (unsigned long a, unsigned long b);
unsigned long __mesabi_udiv (unsigned long a, unsigned long b);
unsigned long __mesabi_uldiv (unsigned long a, unsigned long b,
                              unsigned long *remainder);

void *__memcpy (void *dest, void const *src, size_t n);
void *__memmove (void *dest, void const *src, size_t n);
void *__memset (void *s, int c, size_t n);
int __raise (int signal);

#endif //__MES_LIB_H

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-mescc/_exit.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/x86-mes-mescc/_exit.c used in: Step 126
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

void
_exit ()
{
  asm ("mov____$i32,%eax SYS_exit");
  asm ("mov____0x8(%ebp),%ebx !8");
  asm ("int____$0x80");
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-mescc/_write.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/x86-mes-mescc/_write.c used in: Step 127
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

void
_write ()
{
  asm ("mov____$i32,%eax SYS_write");
  asm ("mov____0x8(%ebp),%ebx !8");
  asm ("mov____0x8(%ebp),%ecx !12");
  asm ("mov____0x8(%ebp),%edx !16");
  asm ("int____$0x80");
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/puts.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>

int
puts (char const *s)
{
  oputs (s);
  return oputs ("\n");
}

https://git.savannah.gnu.org/cgit/mes.git/tree/include/errno.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_ERRNO_H
#define __MES_ERRNO_H 1

#if SYSTEM_LIBC
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#undef __MES_ERRNO_H
#include_next <errno.h>
#else // ! SYSTEM_LIBC

#ifndef __MES_ERRNO_T
#define __MES_ERRNO_T 1
typedef int error_t;
#endif // !__MES_ERRNO_T

extern int errno;
#define ENOENT   2
#define EINTR    4
#define EIO      5
#define ENXIO    6
#define E2BIG    7
#define ENOEXEC  8
#define EBADF    9
#define ECHILD  10
#define EAGAIN  11
#define ENOMEM  12
#define EACCES  13
#define EEXIST  17
#define EXDEV   18
#define ENOTDIR 20
#define EISDIR  21
#define EINVAL  22
#define EMFILE  24
#define ENOSPC  28
#define ESPIPE  29
#define EPIPE   32
#define ERANGE  34

#define ENAMETOOLONG 36
#define ENOSYS  38
#define ELOOP   40

#if !__MESC__
//extern char const *const sys_errlist[];
extern char *sys_errlist[];
extern int sys_nerr;
#endif // !__MESC__

#endif // ! SYSTEM_LIBC

#endif // __MES_ERRNO_H

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-mescc/syscall-internal.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/x86-mes-mescc/syscall-internal.c used in: Step 133
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/x86/syscall.h>

static long
__sys_call_internal (long sys_call)
{
  asm ("mov____0x8(%ebp),%eax !8");
  asm ("int____$0x80");
}

static long
__sys_call2_internal (long sys_call, long one, long two)
{
  asm ("mov____0x8(%ebp),%eax !8");
  asm ("mov____0x8(%ebp),%ebx !12");
  asm ("mov____0x8(%ebp),%ecx !16");
  asm ("int____$0x80");
}

/* Return < 0 on error (errno-like value from kernel), or 0 on success */
int
__raise (int signum)
{
  int pid = (int) __sys_call_internal (SYS_getpid);
  if (pid < 0)
    return pid;
  else
    return (int) __sys_call2_internal (SYS_kill, pid, signum);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/include/ctype.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_CTYPE_H
#define __MES_CTYPE_H 1

#if SYSTEM_LIBC
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#undef __MES_CTYPE_H
#include_next <ctype.h>

#else // ! SYSTEM_LIBC
#include <endian.h>

int isalnum (int c);
int isalpha (int c);
int isascii (int c);
int iscntrl (int c);
int isdigit (int c);
int isgraph (int c);
int islower (int c);
int isnumber (int c, int base);
int isprint (int c);
int ispunct (int c);
int isspace (int c);
int isupper (int c);
int isxdigit (int c);
int tolower (int c);
int toupper (int c);

#endif // ! SYSTEM_LIBC

#endif // __MES_CTYPE_H

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/cast.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>

#undef cast_intp_to_charp
#undef cast_long_to_charp
#undef cast_charp_to_long
#undef cast_int_to_long
#undef cast_voidp_to_long

char*
cast_intp_to_charp (int const *i)
{
  return (char*)i;
}

char*
cast_long_to_charp (long i)
{
  return (char*)i;
}

long
cast_charp_to_long (char const *i)
{
  return (long)i;
}

long
cast_int_to_long (int i)
{
  return (long)i;
}

long
cast_voidp_to_long (void const *i)
{
  return (long)i;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/include/limits.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_LIMITS_H
#define __MES_LIMITS_H 1

#if SYSTEM_LIBC
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#undef __MES_LIMITS_H
#include_next <limits.h>

#else // ! SYSTEM_LIBC

#include <stdint.h>

#define MB_CUR_MAX 1
#define NAME_MAX 255
#define PATH_MAX 512
#define _POSIX_OPEN_MAX 16

#endif // ! SYSTEM_LIBC

#endif // __MES_LIMITS_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/stdlib.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_STDLIB_H
#define __MES_STDLIB_H 1

#ifndef __MES_COMPARISON_FN_T
#define __MES_COMPARISON_FN_T
typedef int (*comparison_fn_t) (void const *, void const *);
#endif

#if SYSTEM_LIBC
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#undef __MES_STDLIB_H
#include_next <stdlib.h>
#else // ! SYSTEM_LIBC

#include <sys/types.h>
#include <alloca.h>

void abort (void);
double atof (char const *s);
int atoi (char const *s);
int atexit (void (*function) (void));
void *calloc (size_t nmemb, size_t size);
void _exit (int status);
void exit (int status);
void free (void *ptr);
char *getenv (char const *s);
int setenv (char const *s, char const *v, int overwrite_p);
void unsetenv (char const *name);
void *malloc (size_t);
void qsort (void *base, size_t nmemb, size_t size, int (*compar) (void const *, void const *));
int rand (void);
void *realloc (void *p, size_t size);
double strtod (char const *string, char **tailptr);
float strtof (char const *string, char **tailptr);
long double strtold (char const *string, char **tailptr);
long strtol (char const *string, char **tailptr, int base);
long long strtoll (char const *string, char **tailptr, int base);
unsigned long strtoul (char const *string, char **tailptr, int base);
unsigned long long strtoull (char const *string, char **tailptr, int base);

#define EXIT_FAILURE 1
#define EXIT_SUCCESS 0

void *bsearch (void const *key, void const *array, size_t count, size_t size, comparison_fn_t compare);

#endif // ! SYSTEM_LIBC

#endif // __MES_STDLIB_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/resource.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_SYS_RESOURCE_H
#define __MES_SYS_RESOURCE_H 1

#if SYSTEM_LIBC
#undef __MES_SYS_RESOURCE_H
#include_next <sys/resource.h>

#else // ! SYSTEM_LIBC

#include <sys/time.h>

struct rusage
{
  struct timeval ru_utime;
  struct timeval ru_stime;
  long int ru_maxrss;
  long int ru_ixrss;
  long int ru_idrss;
  long int ru_isrss;
  long int ru_minflt;
  long int ru_majflt;
  long int ru_nswap;
  long int ru_inblock;
  long int ru_oublock;
  long int ru_msgsnd;
  long int ru_msgrcv;
  long int ru_nsignals;
  long int ru_nvcsw;
  long int ru_nivcsw;
};

#define RUSAGE_SELF 0
#define RUSAGE_CHILDREN -1
#define RLIMIT_NOFILE 1024
#define OPEN_MAX RLIMIT_NOFILE

int getrusage (int processes, struct rusage *rusage);

#endif // ! SYSTEM_LIBC

#endif // __MES_SYS_RESOURCE_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/unistd.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_UNISTD_H
#define __MES_UNISTD_H 1

#if SYSTEM_LIBC
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#undef __MES_UNISTD_H
#include_next <unistd.h>

#else // ! SYSTEM_LIBC

#if defined (BOOTSTRAP_WITH_POSIX)
#define _POSIX_VERSION 199009L
#endif

#include <sys/types.h>
#ifndef NULL
#define NULL 0
#endif

#ifndef STDIN_FILENO
#define STDIN_FILENO  0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#endif // STDIN_FILENO

#ifndef STDIN_FILE_NO
#define STDIN_FILE_NO  0
#define STDOUT_FILE_NO 1
#define STDERR_FILE_NO 2
#endif // STDIN_FILE_NO

#ifndef R_OK
#define F_OK 0
#define X_OK 1
#define W_OK 2
#define R_OK 4
#endif

int access (char const *s, int mode);
unsigned int alarm (unsigned int seconds);
int close (int fd);
int execv (char const *file_name, char *const argv[]);
int execl (char const *file_name, char const *arg, ...);
int execlp (char const *file_name, char const *arg, ...);
int execve (char const *file, char *const argv[], char *const env[]);
int execvp (char const *file, char *const argv[]);
int fork (void);
int fsync (int filedes);
char *getcwd (char *buf, size_t size);
uid_t getuid (void);
gid_t getgid (void);
int setgid (gid_t newgid);
int setuid (uid_t newuid);
uid_t geteuid (void);
gid_t getegid (void);
pid_t getpgrp (void);
pid_t getpid (void);
pid_t getppid (void);
int getpgid (pid_t pid);
int isatty (int fd);
int link (char const *old_name, char const *new_name);
off_t lseek (int fd, off_t offset, int whence);
ssize_t read (int fd, void *buffer, size_t size);
ssize_t readlink (char const *file_name, char *buffer, size_t size);
#if __SBRK_CHAR_PTRDIFF
/* xmalloc in binutils <= 2.10.1 uses this old prototype */
char *sbrk (ptrdiff_t delta);
#else
void *sbrk (intptr_t delta);
#endif
int symlink (char const *old_name, char const *new_name);
int unlink (char const *file_name);
ssize_t write (int filedes, void const *buffer, size_t size);

#endif // ! SYSTEM_LIBC

#endif // __MES_UNISTD_H

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/ltoab.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>

char *
ltoab (long x, int base)
{
  return ntoab (x, base, 1);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/mes_open.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <stdlib.h>

#if SYSTEM_LIBC
#include <fcntl.h>
#include <stdarg.h>
// The Mes C Library defines and initializes these in crt1
int __stdin = STDIN;
int __stdout = STDOUT;
int __stderr = STDERR;

int
mes_open (char const *file_name, int flags, int mask)
{
  int filedes = open (file_name, flags, mask);
  if (filedes > 2)
    __ungetc_clear (filedes);
  return filedes;
}

#else // !SYSTEM_LIBC

int
mes_open (char const *file_name, int flags, int mask)
{
  return _open3 (file_name, flags, mask);
}

#endif // !SYSTEM_LIBC

https://git.savannah.gnu.org/cgit/mes.git/tree/include/assert.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_ASSERT_H
#define __MES_ASSERT_H 1

#if SYSTEM_LIBC
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#undef __MES_ASSERT_H
#include_next <assert.h>
#else // ! SYSTEM_LIBC
#define assert(x) ((x) ? (void)0 : __assert_fail (#x, 0, 0, 0))
void __assert_fail (char const *s, char const *file, unsigned line,
                    char const *function);
#endif // ! SYSTEM_LIBC

#endif // __MES_ASSERT_H

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/oputc.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>

int
oputc (int c)
{
  return fdputc (c, __stdout);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/ultoa.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>

char *
ultoa (unsigned long x)
{
  return ntoab (x, 10, 1);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/utoa.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>

char *
utoa (unsigned x)
{
  return ntoab (x, 10, 0);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/write.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>

ssize_t
write (int filedes, void const *buffer, size_t size)
{
  size_t skip = __buffered_read_clear (filedes);
  if (skip)
    lseek (filedes, -skip, SEEK_CUR);
  int r = _write (filedes, buffer, size);
  if (r < 0)
    {
      errno = -r;
      r = -1;
    }
  else
    errno = 0;
  return r;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/include/stdio.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_STDIO_H
#define __MES_STDIO_H 1

#include <mes/lib.h>

#if SYSTEM_LIBC
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#undef __MES_STDIO_H
#include_next <stdio.h>

#else // ! SYSTEM_LIBC

#ifndef _IOFBF
#define _IOFBF 0                /* Fully buffered.  */
#define _IOLBF 1                /* Line buffered.  */
#define _IONBF 2                /* No buffering.  */
#endif

#ifndef BUFSIZ
#define BUFSIZ 256
#endif

#ifndef L_tmpnam
#define L_tmpnam 100
#endif

#include <sys/types.h>

#define stdin (FILE*)0
#define stdout (FILE*)1
#define stderr (FILE*)2

#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2

FILE *fdopen (int fd, char const *mode);
FILE *fopen (char const *file_name, char const *mode);
int eputc (int c);
int eputs (char const *s);
int fclose (FILE * stream);
int feof (FILE * stream);
int ferror (FILE * stream);
int fflush (FILE * stream);
int fgetc (FILE * stream);
char *fgets (char *s, int size, FILE * stream);
int fprintf (FILE * stream, char const *format, ...);
int fpurge (FILE * stream);
int fputc (int c, FILE * stream);
int fputs (char const *s, FILE * stream);
int fscanf (FILE * stream, char const *template, ...);
int fseek (FILE * stream, long offset, int whence);
int getc (FILE * stream);
int getchar (void);
char *getlogin (void);
int printf (char const *format, ...);
int putc (int c, FILE * stream);
int putchar (int c);
int puts (char const *s);
int remove (char const *file_name);
int setvbuf (FILE * stream, char *buf, int mode, size_t size);
int snprintf (char *str, size_t size, char const *format, ...);
int sprintf (char *str, char const *format, ...);
int sscanf (char const *str, char const *format, ...);
int ungetc (int c, FILE * stream);
long ftell (FILE * stream);
size_t fread (void *ptr, size_t size, size_t count, FILE * stream);
size_t freadahead (FILE * fp);
size_t fwrite (void const *ptr, size_t size, size_t count, FILE * stream);

#endif // ! SYSTEM_LIBC

#endif // __MES_STDIO_H

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/lseek.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <linux/syscall.h>
#include <arch/syscall.h>
#include <stdio.h>
#include <sys/types.h>

#if !__MESC__ /* FIXME: We want bin/mes-mescc's x86-linux sha256sum to stay the same. */
off_t
_lseek (int filedes, off_t offset, int whence)
{
  return _sys_call3 (SYS_lseek, (int) filedes, (long) offset, (int) whence);
}
#endif

off_t
lseek (int filedes, off_t offset, int whence)
{
#if !__MESC__ /* FIXME: We want bin/mes-mescc's x86-linux sha256sum to stay the same. */
  if (_lseek (filedes, 0, SEEK_CUR) == -1)
    return -1;
#endif
  size_t skip = __buffered_read_clear (filedes);
  if (whence == SEEK_CUR)
    offset -= skip;
  return _sys_call3 (SYS_lseek, (int) filedes, (long) offset, (int) whence);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/include/linux/syscall.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef __MES_SYSCALL_H
#define __MES_SYSCALL_H

long _sys_call (long sys_call);
long _sys_call1 (long sys_call, long one);
long _sys_call2 (long sys_call, long one, long two);
long _sys_call3 (long sys_call, long one, long two, long three);
long _sys_call4 (long sys_call, long one, long two, long three, long four);
long _sys_call6 (long sys_call, long one, long two, long three, long four, long five, long six);

#endif //__MES_SYSCALL_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/types.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_SYS_TYPES_H
#define __MES_SYS_TYPES_H 1

#if SYSTEM_LIBC
#undef __MES_SYS_TYPES_H
#include_next <sys/types.h>
#else // ! SYSTEM_LIBC

#include <endian.h>

#ifndef __MESCCLIB__
#define __MESCCLIB__ 15
#endif

#ifndef EOF
#define EOF -1
#endif

#ifndef NULL
#define NULL 0
#endif

#ifndef __MES_CLOCK_T
#define __MES_CLOCK_T
#undef clock_t
typedef long clock_t;
#endif

#ifndef __MES_DEV_T
#define __MES_DEV_T
#undef dev_t
typedef long dev_t;
#endif

#if !defined (__MES_FILE_T) && ! defined (_FILE_T)
#define __MES_FILE_T
#define _FILE_T
typedef long FILE;
#endif

#ifndef __MES_GID_T
#define __MES_GID_T
#undef gid_t
typedef unsigned gid_t;
#endif

#ifndef __MES_INO_T
#define __MES_INO_T
#undef ino_t
typedef unsigned long ino_t;
#endif

#if __SIZEOF_LONG_LONG__ == 8
#ifndef __MES_INO64_T
#define __MES_INO64_T
#undef ino64_t
typedef unsigned long long ino64_t;
#endif
#endif // __SIZEOF_LONG_LONG__ == 8

#if !defined (__MES_INTPTR_T) && !defined (__intptr_t_defined)
#define __MES_INTPTR_T
#define __intptr_t_defined
#undef intptr_t
typedef long intptr_t;
#undef uintptr_t
typedef unsigned long uintptr_t;
#endif

#ifndef __MES_OFF_T
#define __MES_OFF_T
#undef off_t
typedef long off_t;
#endif

#if __SIZEOF_LONG_LONG__ == 8
#ifndef __MES_OFF64_T
#define __MES_OFF64_T
#undef off64_t
typedef unsigned long long off64_t;
#endif
#endif // __SIZEOF_LONG_LONG__ == 8

#ifndef __MES_PID_T
#define __MES_PID_T
#undef pid_t
typedef int pid_t;
#endif

#ifndef __PTRDIFF_T
#define __PTRDIFF_T
#ifndef __MES_PTRDIFF_T
#define __MES_PTRDIFF_T
#undef ptrdiff_t
typedef long ptrdiff_t;
#endif
#endif

#ifndef __MES_SIGVAL_T
#define __MES_SIGVAL_T
#undef clock_t
typedef long sigval_t;
#endif

#ifndef __SIZE_T
#define __SIZE_T
#ifndef __MES_SIZE_T
#define __MES_SIZE_T
#undef size_t
typedef unsigned long size_t;
#endif
#endif

#ifndef __MES_SSIZE_T
#define __MES_SSIZE_T
#undef ssize_t
typedef long ssize_t;
#endif

#ifndef __MES_UID_T
#define __MES_UID_T
#undef uid_t
typedef unsigned uid_t;
#endif

#ifndef __WCHAR_T
#define __WCHAR_T
#ifndef __MES_WCHAR_T
#define __MES_WCHAR_T
#undef wchar_t
typedef int wchar_t;
#endif
#endif

#endif // ! SYSTEM_LIBC

#endif // __MES_SYS_TYPES_H

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/__buffered_read.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <stdlib.h>
#include <string.h>

#if !__MESC__
#define __READ_BUFFER_MAX 128
int __read_buffer_max;
#else /* FIXME: We want bin/mes-mescc's x86-linux sha256sum to stay the same. */
#define __READ_BUFFER_MAX 100
#define __read_buffer_max 100
#endif

struct __read_buffer
{
  ssize_t size;
  char string[__READ_BUFFER_MAX];
};

struct __read_buffer *__read_cache = 0;

void
__buffered_read_init (int filedes)
{
  if (!__read_cache)
    {
      __read_cache = (struct __read_buffer *) malloc (sizeof (struct __read_buffer) * __FILEDES_MAX);
#if !__MESC__
      __read_buffer_max = __READ_BUFFER_MAX;
      char *p = getenv ("MES_READ_BUFFER");
      if (p)
        {
          __read_buffer_max = atoi (p);
          if (__read_buffer_max < 0)
            __read_buffer_max = 0;
          if (__read_buffer_max > __READ_BUFFER_MAX)
            __read_buffer_max = __READ_BUFFER_MAX;
        }
#endif
    }
}

size_t
__buffered_read_clear (int filedes)
{
  __buffered_read_init (filedes);
  size_t size = __read_cache[filedes].size;
  __read_cache[filedes].size = 0;
  return size;
}

ssize_t
__buffered_read (int filedes, void *buffer, size_t size)
{
  size_t todo = size;
  __buffered_read_init (filedes);
  struct __read_buffer *cache = &__read_cache[filedes];
  char *p = buffer;
  if (!cache->size && size > __read_buffer_max)
    return _read (filedes, buffer, size);
  while (cache->size > 0 && todo)
    {
      todo--;
      *p++ = cache->string[__read_buffer_max - cache->size--];
    }
  if (todo)
    {
#if !__MESC__
      if (todo > __read_buffer_max)
        return size - todo + _read (filedes, p, todo);
      if (__mes_debug () > 4)
        {
          eputs ("__buffered_read: ");
          eputs (itoa (__read_buffer_max));
          eputs ("\n");
        }
#endif
      ssize_t bytes = _read (filedes, cache->string, __read_buffer_max);
      if (bytes < 0)
        return -1;
      if (bytes)
        {
          cache->size = bytes;
          if (bytes < __read_buffer_max)
            memmove (cache->string + __read_buffer_max - bytes, cache->string, bytes);
          return size - todo + __buffered_read (filedes, p, todo);
        }
    }
  return size - todo;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/__mes_debug.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "mes/lib.h"
#include <stdlib.h>

#define MAX(a, b) (((a) > (b)) ? (a) : (b))

int
__mes_debug ()
{
  static int __mes_debug = -1;
  if (__mes_debug == -1)
    {
      char *p = getenv ("MES_DEBUG");
      __mes_debug = p ? MAX (atoi (p), 1) : 0;
    }
  return __mes_debug;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/execv.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <unistd.h>

int
execv (char const *file_name, char *const argv[])
{
  return execve (file_name, argv, environ);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/getcwd.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2020,2021 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <limits.h>
#include <sys/types.h>
#include <mes/lib.h>

char *__getcwd_buf;

char *
getcwd (char *buffer, size_t size)
{
  static char buf[PATH_MAX];
  if (buffer == 0)
    buffer = buf;
  return _getcwd (buffer, size);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/isatty.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <string.h>
#include <termio.h>

#if !SYSTEM_LIBC
typedef unsigned char cc_t;
typedef unsigned int speed_t;
typedef unsigned int tcflag_t;

// Use termio, termios2?
#define NCCS 19
struct termios
{
  tcflag_t c_iflag;
  tcflag_t c_oflag;
  tcflag_t c_cflag;
  tcflag_t c_lflag;
  cc_t c_line;
  cc_t c_cc[NCCS];
};
#endif

struct ktermios
{
  tcflag_t c_iflag;
  tcflag_t c_oflag;
  tcflag_t c_cflag;
  tcflag_t c_lflag;
  cc_t c_line;
  cc_t c_cc[NCCS];
  speed_t c_ispeed;
  speed_t c_ospeed;
};

int
__tcgetattr (int filedes, struct termios *termios_p)
{
  struct ktermios kernel_termios;
  int r = ioctl3 (filedes, TCGETS, (long) &kernel_termios);

  termios_p->c_iflag = kernel_termios.c_iflag;
  termios_p->c_oflag = kernel_termios.c_oflag;
  termios_p->c_cflag = kernel_termios.c_cflag;
  termios_p->c_lflag = kernel_termios.c_lflag;
  termios_p->c_line = kernel_termios.c_line;
#if 0
  termios_p->c_ispeed = kernel_termios.c_ispeed;
  termios_p->c_ospeed = kernel_termios.c_ospeed;
#endif
  memcpy (&termios_p->c_cc[0], &kernel_termios.c_cc[0], NCCS * sizeof (cc_t));
  return r;
}

int
isatty (int filedes)
{
  struct termios term;
  return __tcgetattr (filedes, &term) == 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/ioctl.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_SYS_IOCTL_H
#define __MES_SYS_IOCTL_H 1

#if SYSTEM_LIBC
#undef __MES_SYS_IOCTL_H
#include_next <sys/ioctl.h>

#else // ! SYSTEM_LIBC

#define TCGETS 0x5401
#define TCGETA 0x5405
int ioctl (int fd, unsigned long request, ...);
int ioctl3 (int fd, unsigned long request, long data);

#endif // ! SYSTEM_LIBC

#endif // __MES_SYS_IOCTL_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/termio.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_TERMIO_H
#define __MES_TERMIO_H 1

#if SYSTEM_LIBC
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#undef __MES_TERMIO_H
#include_next <termio.h>

#else // ! SYSTEM_LIBC

#define TIOCGWINSZ  0x5413
#define TCGETA      0x5405
#define TCSETAW     0x5407

#define VTIME 5
#define VMIN 6

#define ISIG    0000001
#define ICANON  0000002
#define ECHO    0000010
#define ECHOK   0000040
#define ECHONL  0000100

#define ISTRIP  0000040
#define INLCR   0000100
#define ICRNL   0000400

#define   CS8   0000060
#define PARENB  0000400

struct winsize
{
  unsigned short ws_row;
  unsigned short ws_col;
  unsigned short ws_xpixel;
  unsigned short ws_ypixel;
};

struct termio
{
  unsigned short c_iflag;
  unsigned short c_oflag;
  unsigned short c_cflag;
  unsigned short c_lflag;
  unsigned char c_line;
  unsigned char c_cc[8];
};

#endif // ! SYSTEM_LIBC

#endif // __MES_TERMIO_H

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/open.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <fcntl.h>
#include <stdarg.h>

int
_open2 (char const *file_name, int flags)
{
  int mask = 0777;
  return _open3 (file_name, flags, mask);
}

int
open (char const *file_name, int flags, ...)
{
  if (flags & O_CREAT)
    {
      va_list ap;
      va_start (ap, flags);
      int mask = va_arg (ap, int);
      int r = _open3 (file_name, flags, mask);
      va_end (ap);
      return r;
    }
  else
    return _open2 (file_name, flags);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/include/fcntl.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_FCNTL_H
#define __MES_FCNTL_H 1

#if SYSTEM_LIBC
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#undef __MES_FCNTL_H
#include_next <fcntl.h>

#else // ! SYSTEM_LIBC

// *INDENT-OFF*
#if __linux__
#define O_RDONLY          0
#define O_WRONLY          1
#define O_RDWR            2
#define O_CREAT        0x40
#define O_EXCL         0x80
#define O_TRUNC       0x200
#define O_APPEND      0x400

#ifdef __arm__
#define O_DIRECTORY 0x4000
/*#define O_DIRECT 0x10000*/
#else
#define O_DIRECTORY 0x10000
#endif

#elif __GNU__
#define O_RDONLY      1
#define O_WRONLY      2
#define O_RDWR        3
#define O_CREAT        0x10
#define O_APPEND      0x100
#define O_TRUNC     0x10000
#else
#error platform not supported
#endif
// *INDENT-ON*

#define FD_CLOEXEC 1

#define F_DUPFD 0
#define F_GETFD 1
#define F_SETFD 2
#define F_GETFL 3
#define F_SETFL 4

#define creat(file_name, mode) open (file_name, O_WRONLY | O_CREAT | O_TRUNC, mode)
int dup (int old);
int dup2 (int old, int new);
int fcntl (int filedes, int command, ...);
int open (char const *s, int flags, ...);

#endif // ! SYSTEM_LIBC

#endif // __MES_FCNTL_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/stdarg.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_STDARG_H
#define __MES_STDARG_H 1

#if SYSTEM_LIBC
#undef __MES_STDARG_H
#include_next <stdarg.h>

#define va_arg8(ap, type) va_arg(ap, type)

#else // ! SYSTEM_LIBC

#include <sys/types.h>

#if __GNUC__ && __x86_64__
#define __FOO_VARARGS 1
#endif

typedef char *va_list;
#define va_start(ap, last) (void)((ap) = (char*)(&(last) + 1))
#define va_arg(ap, type) (type)(((long*)((ap) = ((ap) + sizeof (void*))))[-1])
#define va_align(ap, alignment) ((char*)((((unsigned long) (ap)) + (alignment) - 1) &~ ((alignment) - 1)))
#define va_arg8(ap, type) (type)(((double*)((ap) = (va_align((ap), 8) + sizeof(double))))[-1])
#define va_end(ap) (void)((ap) = 0)
#define va_copy(dest, src) dest = src

int vexec (char const *file_name, va_list ap);
int vfprintf (FILE * stream, char const *template, va_list ap);
int vfscanf (FILE * stream, char const *template, va_list ap);
int vprintf (char const *format, va_list ap);
int vsprintf (char *str, char const *format, va_list ap);
int vsnprintf (char *str, size_t size, char const *format, va_list ap);
int vsscanf (char const *s, char const *template, va_list ap);

#endif // ! SYSTEM_LIBC

#endif // __MES_STDARG_H

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/buffered-read.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <fcntl.h>

ssize_t
read (int filedes, void *buffer, size_t size)
{
  ssize_t bytes = __buffered_read (filedes, buffer, size);
  if (__mes_debug () > 4)
    {
      if (bytes == 1)
        {
          eputs ("read fd=");
          eputs (itoa ((int) filedes));
          eputs (" c=");
          eputc (*(char *) buffer);
          eputs ("\n");
        }
      else
        {
          eputs ("read fd=");
          eputs (itoa ((int) filedes));
          eputs (" bytes=");
          eputs (itoa (bytes));
          eputs ("\n");
        }
    }
  return bytes;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/wait.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <sys/wait.h>

pid_t
wait (int *status_ptr)
{
  return waitpid (-1, status_ptr, 0);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/wait.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_SYS_WAIT_H
#define __MES_SYS_WAIT_H 1

#if SYSTEM_LIBC
#undef __MES_SYS_WAIT_H
#include_next <sys/wait.h>
#else // ! SYSTEM_LIBC

#ifndef __MES_PID_T
#define __MES_PID_T
typedef int pid_t;
#endif

#define WNOHANG 1
#define W_EXITCODE(status, signal) ((status) << 8 | (signal))

pid_t waitpid (pid_t pid, int *status_ptr, int options);
pid_t wait (int *status_ptr);

#endif // ! SYSTEM_LIBC

#endif // __MES_SYS_WAIT_H

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fgetc.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>

int
fgetc (FILE * stream)
{
  return fdgetc ((long) stream);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fputc.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>

int
fputc (int c, FILE * stream)
{
  return fdputc (c, (long) stream);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fputs.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>

int
fputs (char const *s, FILE * stream)
{
  return fdputs (s, (long) stream);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/getc.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>

int
getc (FILE * stream)
{
  return fdgetc ((long) stream);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/putc.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>

int
putc (int c, FILE * stream)
{
  return fdputc (c, (long) stream);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/ungetc.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>

int
ungetc (int c, FILE * stream)
{
  return fdungetc (c, (long) stream);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/memchr.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <string.h>

void *
memchr (void const *block, int c, size_t size)
{
  char const *p = block;

  while (size != 0)
    {
      size = size - 1;
      if (c == p[0])
        return (void*) p;
      p = p + 1;
    }

  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/memmove.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <string.h>

void *
memmove (void *dest, void const *src, size_t n)
{
  if (dest < src)
    return memcpy (dest, src, n);
  char *p = dest + n;
  char const *q = src + n;
  while (n--)
    *--p = *--q;
  return dest;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/raise.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <signal.h>
#include <unistd.h>

int
raise (int signum)
{
  kill (getpid (), signum);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/include/signal.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_SIGNAL_H
#define __MES_SIGNAL_H 1

#if SYSTEM_LIBC
#undef __MES_SIGNAL_H
#include_next <signal.h>
#else //! SYSTEM_LIBC

#define _NSIG 64

#define _SIGSET_NITEMS (_NSIG / (8 * sizeof(unsigned long)))

typedef struct {
  unsigned long items[_SIGSET_NITEMS];
} sigset_t;
typedef long stack_t;

#include <sys/types.h>

// *INDENT-OFF*
#define NSIG 30
#define SIGHUP     1
#define SIGINT     2
#define SIGQUIT    3
#define SIGILL     4
#define SIGTRAP    5
#define SIGABRT    6
#define SIGIOT     6
#define SIGBUS     7
#define SIGFPE     8
#define SIGKILL    9
#define SIGUSR1   10
#define SIGSEGV   11
#define SIGUSR2   12
#define SIGPIPE   13
#define SIGALRM   14
#define SIGTERM   15
#define SIGSTKFLT 16
#define SIGCHLD   17
#define SIGCONT   18
#define SIGSTOP   19
#define SIGTSTP   20
#define SIGTTIN   21
#define SIGTTOU   22
#define SIGURG    23
#define SIGXCPU   24
#define SIGXFSZ   25
#define SIGVTALRM 26
#define SIGPROF   27
#define SIGWINCH  28
#define SIGIO     29
#define SIGPOLL   SIGIO

#define FPE_INTDIV 1
#define FPE_INTOVF 2
#define FPE_FLTDIV 3
#define FPE_FLTOVF 4
#define FPE_FLTUND 5
#define FPE_FLTRES 6
#define FPE_FLTINV 7
#define FPE_FLTSUB 8

#define SA_NOCLDSTOP 0x00000001
#define SA_NOCLDWAIT 0x00000002
#define SA_SIGINFO   0x00000004
#define SA_RESTORER  0x04000000
#define SA_ONSTACK   0x08000000
#define SA_RESTART   0x10000000
#define SA_NODEFER   0x40000000
#define SA_RESETHAND 0x80000000

#define SA_NOMASK  SA_NODEFER
#define SA_ONESHOT SA_RESETHAND

typedef struct siginfo_t
{
  int          si_signo;
  int          si_errno;
  int          si_code;
  int          si_trapno;
  pid_t        si_pid;
  uid_t        si_uid;
  int          si_status;
  clock_t      si_utime;
  clock_t      si_stime;
  sigval_t     si_value;
  int          si_int;
  void        *si_ptr;
  int          si_overrun;
  int          si_timerid;
  void        *si_addr;
  long         si_band;
  int          si_fd;
  short        si_addr_lsb;
  void        *si_lower;
  void        *si_upper;
  int          si_pkey;
  void        *si_call_addr;
  int          si_syscall;
  unsigned int si_arch;
} siginfo_t;
// *INDENT-ON*

#if __MESC__
typedef long sighandler_t;
#else
typedef void (*sighandler_t) (int);
#endif

#if __i386__ || __x86_64__
struct sigaction
{
  union
  {
    sighandler_t sa_handler;
    void (*sa_sigaction) (int signum, siginfo_t *, void *);
  };
  unsigned long sa_flags;
#if __x86_64__
  long _foo0;
#endif
  sigset_t sa_mask;
#if __x86_64__
  long _foo1[15];
#endif
  //unsigned long sa_flags; // x86?
  void (*sa_restorer) (void);
};
#else /* uapi */
struct sigaction
{
  union
  {
    sighandler_t sa_handler;
    void (*sa_sigaction) (int signum, siginfo_t *, void *);
  };
  unsigned long sa_flags;
  void (*sa_restorer) (void);
  sigset_t sa_mask;
};
#endif

#define SIG_DFL ((sighandler_t)0)
#define SIG_IGN ((sighandler_t)1)
#define SIG_ERR ((sighandler_t)-1)

#ifdef __i386__

#define EBX 0
#define ECX 1
#define EDX 2
#define ESI 3
#define EDI 4
#define EBP 5
#define EAX 6
#define DS 7
#define ES 8
#define FS 9
#define GS 10
#define ORIG_EAX 11
#define EIP 12
#define CS  13
#define EFL 14
#define UESP 15
#define SS   16
#define FRAME_SIZE 17

/* Type for general register.  */
typedef int greg_t;

/* Number of general registers.  */
#define NGREG        19

/* Container for all general registers.  */
typedef greg_t gregset_t[NGREG];

/* Definitions taken from the kernel headers.  */
struct _libc_fpreg
{
  unsigned short int significand[4];
  unsigned short int exponent;
};

struct _libc_fpstate
{
  unsigned long int cw;
  unsigned long int sw;
  unsigned long int tag;
  unsigned long int ipoff;
  unsigned long int cssel;
  unsigned long int dataoff;
  unsigned long int datasel;
  struct _libc_fpreg _st[8];
  unsigned long int status;
};

/* Structure to describe FPU registers.  */
typedef struct _libc_fpstate *fpregset_t;

typedef struct
{
  gregset_t gregs;
  /* Due to Linux's history we have to use a pointer here.  The SysV/i386
     ABI requires a struct with the values.  */
  fpregset_t fpregs;
  unsigned long int oldmask;
  unsigned long int cr2;
} mcontext_t;

/* Userlevel context.  */
typedef struct ucontext
{
  unsigned long int uc_flags;
  struct ucontext *uc_link;
  stack_t uc_stack;
  mcontext_t uc_mcontext;
  sigset_t uc_sigmask;
  struct _libc_fpstate __fpregs_mem;
} ucontext_t;
#endif // !__i386__

int kill (pid_t pid, int signum);
int raise (int);
int sigaction (int signum, struct sigaction const *act, struct sigaction *oldact);
int sigaddset (sigset_t * set, int signum);
#if __MESC__
void *signal (int signum, void *action);
#else
sighandler_t signal (int signum, sighandler_t action);
#endif
int sigemptyset (sigset_t * set);
#ifndef SIG_BLOCK
#define SIG_BLOCK 0
#define SIG_UNBLOCK 1
#define SIG_SETMASK 2
#endif
int sigprocmask (int how, sigset_t const *set, sigset_t * oldset);

#endif //! SYSTEM_LIBC

#endif // __MES_SIGNAL_H

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/chmod.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <linux/syscall.h>
#include <arch/syscall.h>
#include <sys/stat.h>

int
chmod (char const *file_name, mode_t mask)
{
  long long_file_name = cast_charp_to_long (file_name);
  long long_mask = cast_int_to_long (mask);
  return _sys_call2 (SYS_chmod, long_file_name, long_mask);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/clock_gettime.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <linux/syscall.h>
#include <arch/syscall.h>
#include <time.h>

int
clock_gettime (clockid_t clk_id, struct timespec *tp)
{
  long long_clk_id = cast_int_to_long (clk_id);
  long long_tp = cast_voidp_to_long (tp);
  return _sys_call2 (SYS_clock_gettime, long_clk_id, long_tp);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/include/time.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_TIME_H
#define __MES_TIME_H 1

#if SYSTEM_LIBC
#undef __MES_TIME_H
#include_next <time.h>
#else // ! SYSTEM_LIBC

#ifndef __MES_TIME_T
#define __MES_TIME_T 1
typedef long int clockid_t;
typedef long int time_t;
#endif

struct tm
{
  int tm_sec;
  int tm_min;
  int tm_hour;
  int tm_mday;
  int tm_mon;
  int tm_year;
  int tm_wday;
  int tm_yday;
  int tm_isdst;
};

#ifndef __MES_STRUCT_TIMESPEC
#define __MES_STRUCT_TIMESPEC

struct timespec
{
  long tv_sec;
  long tv_nsec;
};

#endif // __MES_STRUCT_TIMESPEC

#define CLOCK_PROCESS_CPUTIME_ID 2
int clock_gettime (clockid_t clk_id, struct timespec *tp);
struct tm *localtime (time_t const *timep);
struct tm *gmtime (time_t const *time);
time_t mktime (struct tm *broken_time);
int nanosleep (struct timespec const *requested_time, struct timespec const *remaining);
time_t time (time_t * tloc);

#endif // ! SYSTEM_LIBC

#endif // __MES_TIME_H

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/execve.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>

int
execve (char const *file_name, char *const argv[], char *const env[])
{
  return _sys_call3 (SYS_execve, (long) file_name, (long) argv, (long) env);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/fsync.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>

int
fsync (int filedes)
{
  return _sys_call1 (SYS_fsync, (int) filedes);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/time.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_SYS_TIME_H
#define __MES_SYS_TIME_H 1

#if SYSTEM_LIBC
#undef __MES_SYS_TIME_H
#include_next <sys/time.h>

#else // ! SYSTEM_LIBC

struct timeval
{
  long tv_sec;
  long tv_usec;
};

struct timezone
{
  int tz_minuteswest;
  int tz_dsttime;
};

struct itimerval
{
  struct timeval it_interval;
  struct timeval it_value;
};

#define ITIMER_REAL    0
#define ITIMER_VIRTUAL 1
#define ITIMER_PROF    2

int gettimeofday (struct timeval *tv, struct timezone *tz);
int setitimer (int which, struct itimerval const *new, struct itimerval *old);

#endif // ! SYSTEM_LIBC

#endif // __MES_SYS_TIME_H

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/malloc.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2021 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 * Copyright © 2021 Danny Milosavljevic <dannym@scratchpost.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <string.h>
#include <stddef.h>
#include <stdint.h>

char *__brk = 0;

void *
malloc (size_t size)
{
  if (!__brk)
    __brk = cast_long_to_charp (brk (0));
  /* align what we give back. */
  __brk = (char*) (((uintptr_t) __brk
                    + sizeof (max_align_t) - 1) & -sizeof (max_align_t));
  if (brk (__brk + size) == -1)
    return 0;
  char *p = __brk;
  __brk = __brk + size;
  return p;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/include/stddef.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 * Copyright © 2021 Danny Milosavljevic <dannym@scratchpost.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_STDDEF_H
#define __MES_STDDEF_H 1

#if SYSTEM_LIBC
#undef __MES_STDDEF_H
#include_next <stddef.h>
#else // ! SYSTEM_LIBC

#include <sys/types.h>
#include <stdint.h>
#include <unistd.h>

#ifndef offsetof
#if __MESC__
#define offsetof(type, field) (&((type *)0)->field)
#else // !__MESC__
#define offsetof(type, field) ((size_t)&((type *)0)->field)
#endif // !__MESC__
#endif // offsetof

/* Note: on banana gcc, max_align_t is 16 Byte big instead! */

typedef double max_align_t;

#endif // ! SYSTEM_LIBC

#endif // __MES_STDDEF_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/stdint.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 * Copyright © 2018 Peter De Wachter <pdewacht@gmail.com>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_STDINT_H
#define __MES_STDINT_H 1

#if SYSTEM_LIBC
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#undef __MES_STDINT_H
#include_next <stdint.h>

#else // ! SYSTEM_LIBC

#undef unsigned
#undef uint8_t
#undef int8_t

#undef uint16_t
#undef int16_t

#undef uint32_t
#undef int32_t

#undef uint64_t
#undef int64_t

#undef uintptr_t
#undef intmax_t
#undef intptr_t
#undef uintmax_t
#undef ptrdiff_t

typedef unsigned char uint8_t;
typedef char int8_t;
typedef unsigned short uint16_t;
typedef short int16_t;
typedef unsigned uint32_t;
typedef int int32_t;
#if __SIZEOF_LONG_LONG__ == 8
typedef unsigned long long uint64_t;
typedef long long int64_t;
#endif // __SIZEOF_LONG_LONG__ == 8

typedef int intmax_t;
typedef unsigned uintmax_t;

#include <sys/types.h>

#define CHAR_BIT 8
#define CHAR_MAX 255
#define UCHAR_MAX 255

#define INT8_MAX 127
#define INT8_MIN (-INT8_MAX-1)
#define UINT8_MAX 255

#define INT16_MAX 32767
#define INT16_MIN (-INT16_MAX-1)
#define UINT16_MAX 65535

#define INT32_MAX 2147483647
#define INT32_MIN (-INT32_MAX-1)
#define UINT32_MAX 4294967295U

#define INT64_MAX 9223372036854775807LL
#define INT64_MIN (-INT64_MAX-1)
#define UINT64_MAX 18446744073709551615ULL

#define INT_MIN -2147483648
#define INT_MAX 2147483647
#if __i386__ || __arm__
#define LONG_MIN INT_MIN
#define LONG_MAX INT_MAX
#define UINT_MAX UINT32_MAX
#define ULONG_MAX UINT32_MAX
#define LLONG_MIN INT64_MIN
#define LLONG_MAX INT64_MAX
#define SIZE_MAX UINT32_MAX
#elif __x86_64__
#define LONG_MIN INT64_MIN
#define LONG_MAX INT64_MAX
#define UINT_MAX UINT32_MAX
#define ULONG_MAX UINT64_MAX
#define LLONG_MIN INT64_MIN
#define LLONG_MAX INT64_MAX
#define SIZE_MAX UINT64_MAX
#endif

#endif // ! SYSTEM_LIBC

#endif // __MES_STDINT_H

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/_open3.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <mes/lib.h>
#include <fcntl.h>

int
_open3 (char const *file_name, int flags, int mask)
{
  int r = _sys_call3 (SYS_open, (long) file_name, (int) flags, (int) mask);
  if (r > 2)
    {
      __ungetc_clear (r);
      __buffered_read_clear (r);
    }
  return r;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/_read.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <mes/lib.h>
#include <fcntl.h>

ssize_t
_read (int filedes, void *buffer, size_t size)
{
  return _sys_call3 (SYS_read, (int) filedes, (long) buffer, (long) size);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/time.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <time.h>
#include <sys/time.h>
#include <stdlib.h>

time_t
time (time_t * result)
{
  struct timeval tv;
  struct timezone tz;
  if (gettimeofday (&tv, &tz) != 0)
    return (time_t) - 1;
  if (result)
    *result = tv.tv_sec;
  return tv.tv_sec;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/waitpid.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <sys/types.h>

pid_t
waitpid (pid_t pid, int *status_ptr, int options)
{
#if __i386__
  return _sys_call3 (SYS_waitpid, (long) pid, (long) status_ptr, (int) options);
#elif __x86_64__ || __arm__
  return _sys_call4 (SYS_wait4, (long) pid, (long) status_ptr, (int) options, 0);
#else
#error arch not supported
#endif
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-mescc/syscall.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/x86-mes-mescc/syscall.c used in: Step 207
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <errno.h>
#include <linux/x86/syscall.h>

long
__sys_call (long sys_call)
{
  asm ("mov____0x8(%ebp),%eax !8");
  asm ("int____$0x80");
}

long
__sys_call1 (long sys_call, long one)
{
  asm ("mov____0x8(%ebp),%eax !8");
  asm ("mov____0x8(%ebp),%ebx !12");
  asm ("int____$0x80");
}

long
__sys_call2 (long sys_call, long one, long two)
{
  asm ("mov____0x8(%ebp),%eax !8");
  asm ("mov____0x8(%ebp),%ebx !12");
  asm ("mov____0x8(%ebp),%ecx !16");
  asm ("int____$0x80");
}

long
__sys_call3 (long sys_call, long one, long two, long three)
{
  asm ("mov____0x8(%ebp),%eax !8");
  asm ("mov____0x8(%ebp),%ebx !12");
  asm ("mov____0x8(%ebp),%ecx !16");
  asm ("mov____0x8(%ebp),%edx !20");
  asm ("int____$0x80");
}

long
__sys_call4 (long sys_call, long one, long two, long three, long four)
{
  asm ("mov____0x8(%ebp),%eax !8");
  asm ("mov____0x8(%ebp),%ebx !12");
  asm ("mov____0x8(%ebp),%ecx !16");
  asm ("mov____0x8(%ebp),%edx !20");
  asm ("mov____0x8(%ebp),%esi !24");
  asm ("int____$0x80");
}

long
_sys_call (long sys_call)
{
  long r = __sys_call (sys_call);
  if (r < 0)
    {
      errno = -r;
      r = -1;
    }
  else
    errno = 0;
  return r;
}

long
_sys_call1 (long sys_call, long one)
{
  long r = __sys_call1 (sys_call, one);
  if (r < 0)
    {
      errno = -r;
      r = -1;
    }
  else
    errno = 0;
  return r;
}

long
_sys_call2 (long sys_call, long one, long two)
{
  long r = __sys_call2 (sys_call, one, two);
  if (r < 0)
    {
      errno = -r;
      r = -1;
    }
  else
    errno = 0;
  return r;
}

long
_sys_call3 (long sys_call, long one, long two, long three)
{
  long r = __sys_call3 (sys_call, one, two, three);
  if (r < 0)
    {
      errno = -r;
      r = -1;
    }
  else
    errno = 0;
  return r;
}

long
_sys_call4 (long sys_call, long one, long two, long three, long four)
{
  long r = __sys_call4 (sys_call, one, two, three, four);
  if (r < 0)
    {
      errno = -r;
      r = -1;
    }
  else
    errno = 0;
  return r;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/getpid.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <unistd.h>

pid_t
getpid ()
{
  return _sys_call (SYS_getpid);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/kill.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <unistd.h>

int
kill (pid_t pid, int signum)
{
  return _sys_call2 (SYS_kill, (long) pid, (long) signum);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/include/mes/cc.h?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/include/mes/cc.h used in: Step 212, Step 213, Step 214, Step 215, Step 216, Step 217, Step 218, Step 219, Step 220, Step 221, Step 222, Step 223, Step 224, Step 225, Step 226, Step 227, Step 228, Step 229, Step 230, Step 342
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef __MES_CC_H
#define __MES_CC_H

typedef struct scm* SCM;

#if __MESC__
typedef long FUNCTION;
typedef long function0_t;
typedef long function1_t;
typedef long function2_t;
typedef long function3_t;
typedef long functionn_t;
#else // !__MESC__
typedef SCM (*FUNCTION) (void);
typedef SCM (*function0_t) (void);
typedef SCM (*function1_t) (SCM);
typedef SCM (*function2_t) (SCM, SCM);
typedef SCM (*function3_t) (SCM, SCM, SCM);
typedef SCM (*functionn_t) (SCM);
#endif // !__MESC__

#endif //__MES_CC_H

https://git.savannah.gnu.org/cgit/mes.git/tree/src/cc.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/src/cc.c used in: Step 213
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "mes/lib.h"
#include "mes/mes.h"

struct scm *
apply_builtin0 (struct scm *fn)
{
  struct scm *(*fp) (void) = (function0_t) builtin_function (fn);
  return fp ();
}

struct scm *
apply_builtin1 (struct scm *fn, struct scm *x)
{
  struct scm *(*fp) (struct scm *) = (function1_t) builtin_function (fn);
  return fp (x);
}

struct scm *
apply_builtin2 (struct scm *fn, struct scm *x, struct scm *y)
{
  struct scm *(*fp) (struct scm *, struct scm *) = (function2_t) builtin_function (fn);
  return fp (x, y);
}

struct scm *
apply_builtin3 (struct scm *fn, struct scm *x, struct scm *y, struct scm *z)
{
  struct scm *(*fp) (struct scm *, struct scm *, struct scm *) = (function3_t) builtin_function (fn);
  return fp (x, y, z);
}

#undef cast_charp_to_scmp
#undef cast_charp_to_scmpp
#undef cast_voidp_to_charp
#undef cast_scmp_to_long
#undef cast_scmp_to_charp

struct scm *
cast_charp_to_scmp (char const *i)
{
  return (struct scm *)i;
}

struct scm **
cast_charp_to_scmpp (char const *i)
{
  return (struct scm **)i;
}

char*
cast_voidp_to_charp (void const *i)
{
  return (char*)i;
}

long
cast_scmp_to_long (struct scm *i)
{
  return (long)i;
}

char*
cast_scmp_to_charp (struct scm *i)
{
  return (char*)i;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/src/globals.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/src/globals.c used in: Step 218
/*
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2021 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib-mini.h>

#define extern
#include <mes/symbols.h>
#include <mes/mes.h>

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/islower.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <ctype.h>

int
islower (int c)
{
  return c >= 'a' && c <= 'z';
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isupper.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <ctype.h>

int
isupper (int c)
{
  return c >= 'A' && c <= 'Z';
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/tolower.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <ctype.h>

int
tolower (int c)
{
  if (isupper (c))
    return c + ('a' - 'A');
  return c;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/toupper.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <ctype.h>

int
toupper (int c)
{
  if (islower (c))
    return c - ('a' - 'A');
  return c;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/abtod.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>

double
abtod (char const **p, int base)
{
  char const *s = *p;
  double d = 0;
  int sign_p = 0;
  if (!base)
    base = 10;
  double dbase = base;
  long i = abtol (&s, base);
  long f = 0;
  long e = 0;
  if (*s == '.')
    {
      s++;
      f = abtol (&s, base);
    }
  if (*s == 'e')
    {
      s++;
      e = abtol (&s, base);
    }
  d = i + f / dbase;
  if (e < 0)
    while (e++)
      d = d / dbase;
  while (e--)
    d = d * dbase;
  *p = s;
  return sign_p ? -d : d;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/dtoab.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <limits.h>
#include <string.h>

char *
dtoab (double d, int base, int signed_p)
{
  static char dtoa_buf[40];
  long i = (long) d;
  char *p = ntoab (i, base, signed_p);
  strcpy (dtoa_buf, p);
  long f = (d - (double) i) * (double) 100000000;
  if (f)
    {
      if (f < 0)
        f = -f;
      strcat (dtoa_buf, ".");
      p = ntoab (f, base, 1);
      strcat (dtoa_buf, p);
      p = strchr (dtoa_buf, 0);
      p--;
      while (*p && *p == '0')
        *p-- = 0;
    }
  return dtoa_buf;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/search-path.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

char *
search_path (char const *file_name)
{
  static char buf[256];
  char *path = getenv ("PATH");
  if (__mes_debug ())
    {
      eputs ("\n search-path: ");
      eputs (file_name);
      eputs ("\n");
    }
  while (*path)
    {
      char *end = strchr (path, ':');
      if (!end)
        end = strchr (path, '\0');
      strncpy (buf, path, end - path);
      buf[end - path] = 0;
      if (__mes_debug ())
        {
          eputs (" dir: ");
          eputs (buf);
          eputs ("\n");
        }
      if (buf[end - path] != '/')
        strcat (buf, "/");
      strcat (buf, file_name);
      if (!access (buf, X_OK))
        {
          if (__mes_debug ())
            {
              eputs (" found: ");
              eputs (buf);
              eputs ("\n");
            }
          return buf;
        }
      path = end + 1;
    }
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/execvp.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>

int
execvp (char const *file_name, char *const argv[])
{
  if (!strchr (file_name, '/'))
    file_name = search_path (file_name);
  if (!file_name)
    {
      errno = ENOENT;
      return -1;
    }
  if (__mes_debug ())
    {
      eputs (" EXEC: ");
      eputs (file_name);
      eputs ("\n");
      int i = 0;
      while (argv[i])
        {
          eputs (" arg[");
          eputs (itoa (i));
          eputs ("]: ");
          eputs (argv[i]);
          eputs ("\n");
          i++;
        }
    }
  return execve (file_name, argv, environ);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fclose.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>
#include <unistd.h>

int
fclose (FILE * stream)
{
  int fd = (long) stream;
  return close (fd);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fdopen.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>

FILE *
fdopen (int fd, char const *mode)
{
  return (FILE *) (long) fd;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/ferror.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>

int
ferror (FILE * stream)
{
  int fd = (long) stream;
  if (fd == -1)
    return -1;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fflush.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>

int
fflush (FILE * stream)
{
  int filedes = (long) stream;
  if (filedes < 3)
    return 0;
  return fsync (filedes);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fopen.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 * Copyright © 2018 Jeremiah Orians <jeremiah@pdp10.guru>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <assert.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

FILE *
fopen (char const *file_name, char const *opentype)
{
  if (__mes_debug ())
    {
      eputs ("fopen ");
      eputs (file_name);
      eputs (" ");
      eputs (opentype);
      eputs ("\n");
    }

  int fd;
  int mode = 0600;
  if ((opentype[0] == 'a' || !strcmp (opentype, "r+")) && !access (file_name, O_RDONLY))
    {
      int flags = O_RDWR;
      if (opentype[0] == 'a')
        flags |= O_APPEND;
      fd = _open3 (file_name, flags, mode);
    }
  else if (opentype[0] == 'w' || opentype[0] == 'a' || !strcmp (opentype, "r+"))
    {
      char *plus_p = strchr (opentype, '+');
      int flags = plus_p ? O_RDWR | O_CREAT : O_WRONLY | O_CREAT | O_TRUNC;
      fd = _open3 (file_name, flags, mode);
    }
  else
    fd = _open3 (file_name, O_RDONLY, 0);

  if (__mes_debug ())
    {
      eputs (" => fd=");
      eputs (itoa (fd));
      eputs ("\n");
    }

  if (!fd)
    {
      eputs (" ***MES LIB C*** fopen of stdin: signal me in band\n");
      assert (0);
    }
  if (fd < 0)
    fd = 0;
  return (FILE *) (long) fd;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fprintf.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <stdarg.h>
#include <stdio.h>

int
fprintf (FILE * stream, char const *format, ...)
{
  va_list ap;
  va_start (ap, format);
  int r = vfprintf (stream, format, ap);
  va_end (ap);
  return r;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fread.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

int
__fungetc_p (FILE * stream)
{
  return __ungetc_p ((int) (long) stream);
}

size_t
fread (void *data, size_t size, size_t count, FILE * stream)
{
  if (!size || !count)
    return 0;

  size_t todo = size * count;
  char *buf = (char *) data;

  int bytes = 0;
  while (__fungetc_p (stream) && todo-- && ++bytes)
    *buf++ = fgetc (stream);
  int filedes = (long) stream;
  if (todo)
    {
      int r = read (filedes, buf, todo);
      if (r < 0 && !bytes)
        bytes = r;
      else
        bytes += r;
    }

  if (__mes_debug ())
    {
      static char debug_buf[4096];
      eputs ("fread fd=");
      eputs (itoa (filedes));
      eputs (" bytes=");
      eputs (itoa (bytes));
      eputs ("\n");
      if (bytes > 0 && bytes < sizeof (debug_buf))
        {
          strncpy (debug_buf, data, bytes);
          buf[bytes] = 0;
          eputs ("fread buf=");
          eputs (debug_buf);
          eputs ("\n");
        }
    }

  if (bytes > 0)
    return bytes / size;

  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fseek.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <stdio.h>
#include <unistd.h>

int
fseek (FILE * stream, long offset, int whence)
{
  int filedes = (long) stream;
  off_t pos = lseek (filedes, offset, whence);
  if (__mes_debug ())
    {
      eputs ("fread fd=");
      eputs (itoa (filedes));
      eputs ("  =>");
      eputs (itoa (pos));
      eputs ("\n");
    }
  if (pos >= 0)
    return 0;
  return -1;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/ftell.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

long
ftell (FILE * stream)
{
  return lseek ((int) (long) stream, 0, SEEK_CUR);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fwrite.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <stdio.h>
#include <unistd.h>

size_t
fwrite (void const *data, size_t size, size_t count, FILE * stream)
{
  if (__mes_debug () > 1)
    {
      eputs ("fwrite ");
      eputs (itoa ((int) (long) stream));
      eputs ("  ");
      eputs (itoa (size));
      eputs ("\n");
    }

  if (!size || !count)
    return 0;
  int filedes = (long) stream;
  int bytes = write (filedes, data, size * count);

  if (__mes_debug () > 2)
    {
      eputs (" => ");
      eputs (itoa (bytes));
      eputs ("\n");
    }

  if (bytes > 0)
    return bytes / size;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/printf.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <stdarg.h>
#include <stdio.h>

int
printf (char const *format, ...)
{
  va_list ap;
  int r;
#if __GNUC__ && __x86_64__ && !SYSTEM_LIBC
#define __FUNCTION_ARGS 1
  ap += (__FOO_VARARGS + (__FUNCTION_ARGS << 1)) << 3;
#undef __FUNCTION_ARGS
#endif
  va_start (ap, format);
  r = vprintf (format, ap);
  va_end (ap);
  return r;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/remove.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>

int
remove (char const *file_name)
{
  struct stat buf;
  if (stat (file_name, &buf) < 0)
    return -1;
  if (S_ISDIR (buf.st_mode))
    return rmdir (file_name);
  return unlink (file_name);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/snprintf.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <stdarg.h>
#include <stdio.h>

int
snprintf (char *str, size_t size, char const *format, ...)
{
  va_list ap;
  int r;
#if __GNUC__ && __x86_64__ && !SYSTEM_LIBC
#define __FUNCTION_ARGS 3
  ap += (__FOO_VARARGS + (__FUNCTION_ARGS << 1)) << 3;
#undef __FUNCTION_ARGS
#endif
  va_start (ap, format);
  r = vsnprintf (str, size, format, ap);
  va_end (ap);
  return r;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/sprintf.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <stdarg.h>
#include <stdio.h>

int
sprintf (char *str, char const *format, ...)
{
  va_list ap;
  int r;
#if __GNUC__ && __x86_64__ && !SYSTEM_LIBC
#define __FUNCTION_ARGS 2
  ap += (__FOO_VARARGS + (__FUNCTION_ARGS << 1)) << 3;
#undef __FUNCTION_ARGS
#endif
  va_start (ap, format);
  r = vsprintf (str, format, ap);
  va_end (ap);
  return r;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/sscanf.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <stdarg.h>
#include <stdio.h>

int
sscanf (char const *str, char const *template, ...)
{
  va_list ap;
  va_start (ap, template);
  int r = vsscanf (str, template, ap);
  va_end (ap);
  return r;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/vfprintf.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>

int
vfprintf (FILE * f, char const *format, va_list ap)
{
  int fd = (long) f;
  char const *p = format;
  int count = 0;
  while (*p)
    if (*p != '%')
      {
        count++;
        fputc (*p++, f);
      }
    else
      {
        p++;
        char c = *p;
        int left_p = 0;
        int precision = -1;
        int width = -1;
        if (c == '-')
          {
            left_p = 1;
            c = *++p;
          }
        char pad = ' ';
        if (c == ' ')
          {
            pad = c;
            c = *p++;
          }
        if (c == '0')
          {
            pad = c;
            c = *p++;
          }
        if (c >= '0' && c <= '9')
          {
            width = abtol (&p, 10);
            c = *p;
          }
        else if (c == '*')
          {
            width = va_arg (ap, int);
            c = *++p;
          }
        if (c == '.')
          {
            c = *++p;
            if (c >= '0' && c <= '9')
              {
                precision = abtol (&p, 10);
                c = *p;
              }
            else if (c == '*')
              {
                precision = va_arg (ap, int);
                c = *++p;
              }
          }
        if (c == 'l')
          c = *++p;
        if (c == 'l')
          {
            eputs ("vfprintf: skipping second: l\n");
            c = *++p;
          }
        switch (c)
          {
          case '%':
            {
              fputc (*p, f);
              count++;
              break;
            }
          case 'c':
            {
              char _c;
              _c = va_arg (ap, long);
              fputc (_c, f);
              break;
            }
          case 'd':
          case 'i':
          case 'o':
          case 'u':
          case 'x':
          case 'X':
            {
              long d = va_arg (ap, long);
              int base = c == 'o' ? 8 : c == 'x' || c == 'X' ? 16 : 10;
              char *s = ntoab (d, base, c != 'u' && c != 'x' && c != 'X');
              if (c == 'X')
                strupr (s);
              int length = strlen (s);
              if (precision == -1)
                precision = length;
              if (!left_p)
                {
                  while (width-- > precision)
                    {
                      fputc (pad, f);
                      count++;
                    }
                  while (precision > length)
                    {
                      fputc ('0', f);
                      precision--;
                      width--;
                      count++;
                    }
                }
              while (*s)
                {
                  if (precision-- <= 0)
                    break;
                  width--;
                  fputc (*s++, f);
                  count++;
                }
              while (width > 0)
                {
                  width--;
                  fputc (pad, f);
                  count++;
                }
              break;
            }
          case 's':
            {
              char *s = va_arg (ap, char *);
              int length = strlen (s);
              if (precision == -1)
                precision = length;
              if (!left_p)
                {
                  while (width-- > precision)
                    {
                      fputc (pad, f);
                      count++;
                    }
                  while (precision > length)
                    {
                      fputc (' ', f);
                      precision--;
                      width--;
                      count++;
                    }
                }
              while (*s)
                {
                  if (precision-- <= 0)
                    break;
                  width--;
                  fputc (*s++, f);
                  count++;
                }
              while (width > 0)
                {
                  width--;
                  fputc (pad, f);
                  count++;
                }
              break;
            }
          case 'f':
          case 'e':
          case 'E':
          case 'g':
          case 'G':
            {
              double d = va_arg8 (ap, double);
              char *s = dtoab (d, 10, 1);
              if (c == 'E' || c == 'G')
                strupr (s);
              int length = strlen (s);
              if (precision == -1)
                precision = length;
              if (!left_p)
                {
                  while (width-- > precision)
                    {
                      fputc (pad, f);
                      count++;
                    }
                  while (precision > length)
                    {
                      fputc (' ', f);
                      precision--;
                      width--;
                      count++;
                    }
                }
              while (*s)
                {
                  if (precision-- <= 0)
                    break;
                  width--;
                  fputc (*s++, f);
                  count++;
                }
              while (width > 0)
                {
                  width--;
                  fputc (pad, f);
                  count++;
                }
              break;
            }
          case 'n':
            {
              int *n = va_arg (ap, int *);
              *n = count;
              break;
            }
          default:
            {
              eputs ("vfprintf: not supported: %:");
              eputc (c);
              eputs ("\n");
              p++;
            }
          }
        p++;
      }
  va_end (ap);
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/vprintf.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <stdarg.h>
#include <stdio.h>

int
vprintf (char const *format, va_list ap)
{
  return vfprintf (stdout, format, ap);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/vsnprintf.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <ctype.h>
#include <stdarg.h>
#include <string.h>

int
vsnprintf (char *str, size_t size, char const *format, va_list ap)
{
  char const *p = format;
  int count = 0;
  char c;
  while (*p)
    if (*p != '%')
      {
        c = *p++;
        if (count < size)
          *str++ = c;
        count++;
      }
    else
      {
        p++;
        c = *p;
        int left_p = 0;
        int precision = -1;
        int width = -1;
        if (c == '-')
          {
            left_p = 1;
            c = *++p;
          }
        char pad = ' ';
        if (c == ' ')
          {
            pad = c;
            c = *p++;
          }
        if (c == '0')
          {
            pad = c;
            c = *p++;
          }
        if (c >= '0' && c <= '9')
          {
            width = abtol (&p, 10);
            c = *p;
          }
        else if (c == '*')
          {
            width = va_arg (ap, long);
            c = *++p;
          }
        if (c == '.')
          {
            c = *++p;
            if (c >= '0' && c <= '9')
              {
                precision = abtol (&p, 10);
                c = *p;
              }
            else if (c == '*')
              {
                precision = va_arg (ap, long);
                c = *++p;
              }
          }
        if (c == 'l')
          c = *++p;
        if (c == 'l')
          c = *++p;
        if (c == 'l')
          {
            eputs ("vsnprintf: skipping second: l\n");
            c = *++p;
          }
        switch (c)
          {
          case '%':
            {
              if (count < size)
                *str++ = *p;
              count++;
              break;
            }
          case 'c':
            {
              c = va_arg (ap, long);
              if (count < size)
                *str++ = c;
              count++;
              break;
            }
          case 'd':
          case 'i':
          case 'o':
          case 'u':
          case 'x':
          case 'X':
            {
              long d = va_arg (ap, long);
              int base = c == 'o' ? 8 : c == 'x' || c == 'X' ? 16 : 10;
              char *s = ntoab (d, base, c != 'u' && c != 'x' && c != 'X');
              if (c == 'X')
                strupr (s);
              int length = strlen (s);
              if (precision == -1)
                precision = length;
              if (!left_p)
                {
                  while (width-- > precision)
                    {
                      if (count < size)
                        *str++ = pad;
                      count++;
                    }
                  while (precision > length)
                    {
                      if (count < size)
                        *str++ = '0';
                      precision--;
                      width--;
                      count++;
                    }
                }
              while (*s)
                {
                  if (precision-- <= 0)
                    break;
                  width--;
                  c = *s++;
                  if (count < size)
                    *str++ = c;
                  count++;
                }
              while (width > 0)
                {
                  width--;
                  if (count < size)
                    *str++ = pad;
                  count++;
                }
              break;
            }
          case 's':
            {
              char *s = va_arg (ap, char *);
              int length = s ? strlen (s) : 0;
              if (precision == -1)
                precision = length;
              if (!left_p)
                {
                  while (width-- > precision)
                    {
                      if (count < size)
                        *str++ = pad;
                      count++;
                    }
                  while (width > length)
                    {
                      if (count < size)
                        *str++ = ' ';
                      precision--;
                      width--;
                      count++;
                    }
                }
              while (s && *s)
                {
                  if (precision-- <= 0)
                    break;
                  width--;
                  c = *s++;
                  if (count < size)
                    *str++ = c;
                  count++;
                }
              while (width > 0)
                {
                  width--;
                  if (count < size)
                    *str++ = pad;
                  count++;
                }
              break;
            }
          case 'f':
          case 'e':
          case 'E':
          case 'g':
          case 'G':
            {
              double d = va_arg8 (ap, double);
              char *s = dtoab (d, 10, 1);
              if (c == 'E' || c == 'G')
                strupr (s);
              int length = strlen (s);
              if (precision == -1)
                precision = length;
              if (!left_p)
                {
                  while (width-- > precision)
                    {
                      if (count < size)
                        *str++ = pad;
                      count++;
                    }
                  while (precision > length)
                    {
                      if (count < size)
                        *str++ = ' ';
                      precision--;
                      width--;
                      count++;
                    }
                }
              while (*s)
                {
                  if (precision-- <= 0)
                    break;
                  width--;
                  c = *s++;
                  if (count < size)
                    *str++ = c;
                  count++;
                }
              while (width > 0)
                {
                  width--;
                  if (count < size)
                    *str++ = pad;
                  count++;
                }
              break;
            }
          case 'n':
            {
              int *n = va_arg (ap, int *);
              *n = count;
              break;
            }
          default:
            {
              eputs ("vsnprintf: not supported: %:");
              eputc (c);
              eputs ("\n");
              p++;
            }
          }
        p++;
      }
  va_end (ap);
  if (count < size)
    *str = 0;
  return count;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/vsprintf.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <limits.h>
#include <stdarg.h>

int
vsprintf (char *str, char const *format, va_list ap)
{
  return vsnprintf (str, LONG_MAX, format, ap);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/vsscanf.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int
vsscanf (char const *s, char const *template, va_list ap)
{
  char *p = (char *) s;
  char const *t = template;
  int count = 0;
  while (*t && *p)
    if (*t != '%')
      {
        t++;
        p++;
      }
    else
      {
        t++;
        char c = *t;
        if (c == 'l')
          c = *++t;
        switch (c)
          {
          case '%':
            {
              p++;
              break;
            }
          case 'c':
            {
              char *c = va_arg (ap, char *);
              *c = *p++;
              count++;
              break;
            }
          case 'd':
          case 'i':
          case 'u':
            {
              int *d = va_arg (ap, int *);
              *d = abtol ((char const **)&p, 10);
              count++;
              break;
            }
          case 'e':
          case 'f':
          case 'g':
          case 'E':
          case 'G':
            {
              float *f = va_arg (ap, float *);
              *f = strtod (p, &p);
              count++;
              break;
            }
          default:
            {
              eputs ("vsscanf: not supported: %:");
              eputc (c);
              eputs ("\n");
              t++;
              p++;
            }
          }
        t++;
      }
  va_end (ap);
  return count;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/calloc.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdlib.h>
#include <string.h>

void *
calloc (size_t nmemb, size_t size)
{
  size_t count = nmemb * size;
  void *p = malloc (count);
  memset (p, 0, count);
  return p;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/qsort.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 * Copyright © 2021 Paul Dersey <pdersey@gmail.com>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdlib.h>
#include <string.h>

void
qswap (void *a, void *b, size_t size)
{
  char *pa = a;
  char *pb = b;
  do
  {
    char tmp = *pa;
    *pa++ = *pb;
    *pb++ = tmp;
  } while (--size > 0);
}

size_t
qpart (void *base, size_t count, size_t size, int (*compare) (void const *, void const *))
{
  void *p = base + count * size;
  size_t i = 0;
  for (size_t j = 0; j < count; j++)
    {
      int c = compare (base + j * size, p);
      if (c < 0)
        {
#if 1                           //__x86_64__
          qswap (base + i * size, base + j * size, size);
#else
          int p1 = base + i * size;
          int p2 = base + j * size;
          qswap (p1, p2, size);
#endif
          i++;
        }
      else if (c == 0)
        i++;
    }
  if (compare (base + count * size, base + i * size) < 0)
    qswap (base + i * size, base + count * size, size);
  return i;
}

void
qsort (void *base, size_t count, size_t size, int (*compare) (void const *, void const *))
{
  if (count > 1)
    {
      int p = qpart (base, count - 1, size, compare);
      qsort (base, p, size, compare);
#if 1                           //__x86_64__
      qsort (base + p * size, count - p, size, compare);
#else
      int p1 = base + p * size;
      int p2 = count - p;
      qsort (p1, p2, size, compare);
#endif
    }
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/strtod.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <stdlib.h>
#include <string.h>

double
strtod (char const *string, char **tailptr)
{
  int base = 10;
  if (!strncmp (string, "0x", 2))
    {
      string += 2;
      base = 16;
    }
  if (tailptr)
    {
      *tailptr = (char *) string;
      return abtod ((char const **) tailptr, base);
    }
  char **p = (char **) &string;
  return abtod ((char const **) p, base);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/strtof.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdlib.h>

float
strtof (char const *string, char **tailptr)
{
  return strtod (string, tailptr);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/strtol.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <stdlib.h>
#include <string.h>

long
strtol (char const *string, char **tailptr, int base)
{
  if (!strncmp (string, "0x", 2))
    {
      string += 2;
      base = 16;
    }
  if (tailptr)
    {
      *tailptr = (char *) string;
      return abtol ((char const **) tailptr, base);
    }
  char **p = (char **) &string;
  return abtol ((char const **) p, base);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/strtold.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdlib.h>

long double
strtold (char const *string, char **tailptr)
{
  return strtod (string, tailptr);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/strtoll.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdlib.h>

long long int
strtoll (char const *string, char **tailptr, int base)
{
  return strtol (string, tailptr, base);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/strtoul.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdlib.h>

unsigned long
strtoul (char const *string, char **tailptr, int base)
{
  return strtol (string, tailptr, base);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/strtoull.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdlib.h>

unsigned long long
strtoull (char const *string, char **tailptr, int base)
{
  return strtol (string, tailptr, base);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/memmem.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 1997--2015,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 * Copyright (C) 1997--2015,2018 Han-Wen Nienhuys <hanwen@xs4all.nl>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <string.h>

/** locate a substring. #memmem# finds the first occurrence of
    #needle# in #haystack#.  This is not ANSI-C.

    The prototype is not in accordance with the Linux Programmer's
    Manual v1.15, but it is with /usr/include/string.h   */

unsigned char *
_memmem (unsigned char const *haystack, int haystack_len, unsigned char const *needle, int needle_len)
{
  unsigned char const *end_haystack = haystack + haystack_len - needle_len + 1;
  unsigned char const *end_needle = needle + needle_len;

  /* Ahhh ... Some minimal lowlevel stuff. This *is* nice; Varation
     is the spice of life */
  while (haystack < end_haystack)
    {
      unsigned char const *subneedle = needle;
      unsigned char const *subhaystack = haystack;
      while (subneedle < end_needle)
        if (*subneedle++ != *subhaystack++)
          goto next;

      /* Completed the needle.  Gotcha.  */
      return (unsigned char *) haystack;
    next:
      haystack++;
    }
  return 0;
}

void *
memmem (void const *haystack, int haystack_len, void const *needle, int needle_len)
{
  unsigned char const *haystack_byte_c = (unsigned char const *) haystack;
  unsigned char const *needle_byte_c = (unsigned char const *) needle;
  return _memmem (haystack_byte_c, haystack_len, needle_byte_c, needle_len);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strcat.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <string.h>

char *
strcat (char *to, char const *from)
{
  char *p = strchr (to, '\0');
  while (*from)
    *p++ = *from++;
  *p = 0;
  return to;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strchr.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <string.h>

char *
strchr (char const *s, int c)
{
  char const *p = s;
  while (*p || !c)
    {
      if (c == *p)
        return (char *) p;
      p++;
    }
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strlwr.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <ctype.h>
#include <string.h>

char *
strlwr (char *string)
{
  char *p = string;
  while (*p)
    {
      *p = tolower (*p);
      p++;
    }
  return string;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strncpy.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <string.h>

char *
strncpy (char *to, char const *from, size_t size)
{
  if (size == 0)
    return to;
  char *p = to;
  while (*from && size--)
    *p++ = *from++;
  if (*from)
    size++;
  while (size--)
    *p++ = 0;
  return to;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strrchr.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <string.h>

char *
strrchr (char const *s, int c)
{
  int n = strlen (s);
  if (!n)
    return 0;
  char const *p = s + n;
  if (!*p && !c)
    return (char *) p;
  p--;
  while (n-- && (*p || !c))
    {
      if (c == *p)
        return (char *) p;
      p--;
    }
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strstr.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>

char *
strstr (char const *haystack, char const *needle)
{
  return memmem (haystack, strlen (haystack), needle, strlen (needle));
}

https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/mman.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_SYS_MMAN_H
#define __MES_SYS_MMAN_H 1

#if SYSTEM_LIBC
#undef __MES_SYS_MMAN_H
#include_next <sys/mman.h>
#else // ! SYSTEM_LIBC

#ifndef __MES_SIZE_T
#define __MES_SIZE_T
typedef unsigned long size_t;
#endif

#define PROT_NONE 0
#define PROT_READ 1
#define PROT_WRITE 2
#define PROT_EXEC 4

int mprotect (void *addr, size_t len, int prot);

#endif // ! SYSTEM_LIBC

#endif // __MES_SYS_MMAN_H

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strupr.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <ctype.h>
#include <string.h>

char *
strupr (char *string)
{
  char *p = string;
  while (*p)
    {
      *p = toupper (*p);
      p++;
    }
  return string;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/sigaction.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <signal.h>

int
sigaction (int signum, struct sigaction const *act, struct sigaction *oldact)
{
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/ldexp.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <math.h>

double
ldexp (double value, int exponent)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("ldexp stub\n");
  stub = 1;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/include/math.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_MATH_H
#define __MES_MATH_H 1

#if SYSTEM_LIBC
#undef __MES_MATH_H
#include_next <math.h>
#else // ! SYSTEM_LIBC

double atan2 (double y, double x);
double ceil (double x);
double cos (double x);
double exp (double x);
double fabs (double number);
double floor (double x);
double ldexp (double value, int exponent);
double log (double x);
double modf (double value, double *integer_part);
double pow (double base, double power);
double sin (double x);
double sqrt (double x);

#endif // ! SYSTEM_LIBC

#endif // __MES_MATH_H

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/mprotect.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <string.h>

int
mprotect (void *addr, size_t len, int prot)
{
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/localtime.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <errno.h>
#include <time.h>
#include <sys/time.h>

struct tm *
localtime (time_t const *timep)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("localtime stub\n");
  stub = 1;
  errno = 0;
  static struct tm zero = { 0 };
  return &zero;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/sigemptyset.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <signal.h>

int
sigemptyset (sigset_t * set)
{
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/x86-mes-mescc/setjmp.c?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/lib/x86-mes-mescc/setjmp.c used in: Step 282
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <setjmp.h>
#include <stdlib.h>

void
longjmp (jmp_buf env, int val)
{
  val = val == 0 ? 1 : val;
  ///asm ("mov____0x8(%ebp),%eax !0x0c"); // val
  asm ("mov____0x8(%ebp),%ebp !0x08");  // env*

  asm ("mov____0x8(%ebp),%ebx !0x4");   // env.__pc
  asm ("mov____0x8(%ebp),%esp !0x8");   // env.__sp
  asm ("mov____0x8(%ebp),%ebp !0x0");   // env.__bp
  asm ("jmp____*%ebx");
  // not reached
  exit (42);
}

int
setjmp (__jmp_buf * env)
{
  long *p = (long *) &env;
  env[0].__bp = p[-2];
  env[0].__pc = p[-1];
  env[0].__sp = (long) &env;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/include/setjmp.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 * Copyright © 2020 Danny Milosavljevic <dannym@scratchpost.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_SETJMP_H
#define __MES_SETJMP_H 1

#if SYSTEM_LIBC
#undef __MES_SETJMP_H
#include_next <setjmp.h>
#else // ! SYSTEM_LIBC

#if __arm__
#if __GNUC__ || __TINYC__
#warning "It is not supported to use mes' setjmp implementation together with GCC.  Continuing with best-effort implementation."
typedef struct
{
  long __sp;
  long __lr;
  long __registers[8]; /* Note: Keep in sync with lib/arm-mes-gcc/setjmp.c */
} __jmp_buf;
#else
typedef struct
{
  long __fp;
  long __lr;
  long __sp;
} __jmp_buf;
#endif
#else
typedef struct
{
  long __bp;
  long __pc;
  long __sp;
} __jmp_buf;
#endif
typedef __jmp_buf jmp_buf[1];

void longjmp (jmp_buf env, int val);
int setjmp (jmp_buf env);

#endif // ! SYSTEM_LIBC

#endif // __MES_SETJMP_H

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/close.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <mes/lib.h>

int
close (int filedes)
{
  __ungetc_clear (filedes);
  __buffered_read_clear (filedes);
  return _sys_call1 (SYS_close, (int) filedes);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/rmdir.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>

int
rmdir (char const *file_name)
{
  return _sys_call1 (SYS_rmdir, (long) file_name);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/stat.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <sys/stat.h>

int
stat (char const *file_name, struct stat *statbuf)
{
  return _sys_call2 (SYS_stat, (long) file_name, (long) statbuf);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/x86-mes/crt1.s?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/lib/x86-mes/crt1.s used in: Step 298

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes/elf32-footer-single-main.hex2?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/x86-mes/elf32-footer-single-main.hex2 used in: Step 299
### Copyright (C) 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
### This file is part of stage0.
###
### stage0 is free software: you can redistribute it and/or modify
### it under the terms of the GNU General Public License as published by
### the Free Software Foundation, either version 3 of the License, or
### (at your option) any later version.
###
### stage0 is distributed in the hope that it will be useful,
### but WITHOUT ANY WARRANTY; without even the implied warranty of
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
### GNU General Public License for more details.
###
### You should have received a copy of the GNU General Public License
### along with stage0.  If not, see <http://www.gnu.org/licenses/>.

### stage0's hex2 format for x86
###    !<label>          1 byte relative
###    $<label>          2 byte address
###    @<label>          2 byte relative
###    &<label>          4 byte address
###    %<label>          4 byte relative
###    local_<label>     function-local
###    string_<index>    string #<index>

### elf32-footer-single-main.hex2: 32 bit elf footer in hex2 for single main

# @230

:ELF_str
00                             # 0
:ELF_str__start
5f 73 74 61 72 74 00           # _start
:ELF_str__main
6d 61 69 6e 00                 # main

00 00 00

# @240
:ELF_sym
00 00 00 00                    # st-name
00 00 00 00                    # st-offset: &_start - BaseAddress
00 00 00 00                    # st-len   : &main - _start
00                             # st-info = stt-func= 2
00                             # st-other
01 00                          # st-shndx: 1

# _start
%ELF_str__start>ELF_str        # st-name
&_start
10 00 00 00                    # st-len   : &main - _start
02                             # st-info = stt-func= 2
00                             # st-other
01 00                          # st-shndx: 1

# main
%ELF_str__main>ELF_str         # st-name
&main
10 00 00 00                    # st-len   : &ELF_data - main
02                             # st-info = stt-func= 2
00                             # st-other
01 00                          # st-shndx: 1

:ELF_end

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes/elf32-header.hex2?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/lib/linux/x86-mes/elf32-header.hex2 used in: Step 300
### Copyright (C) 2016 Jeremiah Orians
### Copyright (C) 2017,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
###
### This file is part of GNU Mes.
###
### GNU Mes is free software; you can redistribute it and/or modify it
### under the terms of the GNU General Public License as published by
### the Free Software Foundation; either version 3 of the License, or (at
### your option) any later version.
###
### GNU Mes is distributed in the hope that it will be useful, but
### WITHOUT ANY WARRANTY; without even the implied warranty of
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
### GNU General Public License for more details.
###
### You should have received a copy of the GNU General Public License
### along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.

### Commentary:

# elf32-header.hex2: 32 bit elf header in hex2, with text segment, data
# segment and symbol tables.

# stage0's hex2 format for x86
#    !<label>          1 byte relative
#    $<label>          2 byte address
#    @<label>          2 byte relative
#    &<label>          4 byte address
#    %<label>          4 byte relative
#    local_<label>     function-local
#    string_<index>    string #<index>

### Code:

:ELF_base
7F 45 4C 46                    # e_ident[EI_MAG0-3] ELF's magic number

01                             # e_ident[EI_CLASS] Indicating 32 bit
01                             # e_ident[EI_DATA] Indicating little endianness
01                             # e_ident[EI_VERSION] Indicating original elf

00                             # e_ident[EI_OSABI] Set at 0 because none cares
00                             # e_ident[EI_ABIVERSION] See above

00 00 00 00 00 00 00           # e_ident[EI_PAD]

02 00                          # e_type Indicating Executable
03 00                          # e_machine Indicating 32bit x86
01 00 00 00                    # e_version Indicating original elf

&ELF_text                      # e_entry Address of the entry point
%ELF_program_headers>ELF_base  # e_phoff Address of program header table
%ELF_section_headers>ELF_base  # e_shoff Address of section header table

00 00 00 00                    # e_flags

34 00                          # e_ehsize Indicating our 52 Byte header

20 00                          # e_phentsize size of a program header table
01 00                          # e_phnum number of entries in program table

28 00                          # e_shentsize size of a section header table
07 00                          # e_shnum number of entries in section table

04 00                          # e_shstrndx index of the section names

# @34
00 00 00 00
00 00 00 00
00 00 00 00

# @40
:ELF_program_headers
:ELF_program_header__text
01 00 00 00                    # ph_type: PT-LOAD = 1
00 00 00 00                    # ph_offset
&ELF_base                      # ph_vaddr
&ELF_base                      # ph_physaddr
%ELF_end>ELF_base              # ph_filesz
%ELF_end>ELF_base              # ph_memsz
07 00 00 00                    # ph_flags: PF-X|PF-W|PF-R = 7
01 00 00 00                    # ph_align

# @60
#:ELF_program_header__data     # NOT USED
                               # FIXME: linux 4.17 does not allow this overlap
                               #    Uhuuh, elf segment at 0000000001000000
                               #    requested but the memory is mapped already
01 00 00 00                    # ph_type: PT-LOAD = 1
00 00 00 00                    # ph_offset
&ELF_base                      # ph_vaddr
&ELF_base                      # ph_physaddr
%ELF_end>ELF_base              # ph_filesz
%ELF_end>ELF_base              # ph_memsz
07 00 00 00                    # ph_flags: PF-X|PF-W|PF-R = 7
01 00 00 00                    # ph_align

# @80
:ELF_comment
4d 45 53 00                     # MES
00 00 00 00                     # align
00 00 00 00
00 00 00 00

4d 45 53 00                     # MES
00 00 00 00                     # align
00 00 00 00
00 00 00 00

# @a0
:ELF_shstr
00
:ELF_shstr__text
2e 74 65 78 74 00               # .text
:ELF_shstr__data
2e 64 61 74 61 00               # .data
:ELF_shstr__comment
2e 63 6f 6d 6d 65 6e 74 00      # .comment
:ELF_shstr__shstr
2e 73 68 73 74 72 74 61 62 00   # .shstrtab
:ELF_shstr__sym
2e 73 79 6d 74 61 62 00         # .symtab
:ELF_shstr__str
2e 73 74 72 74 61 62 00         # .strtab

# @d0

:ELF_section_headers
00 00 00 00                     # sh_name
00 00 00 00                     # sh_type
00 00 00 00                     # sh_flags
00 00 00 00                     # sh_addr
00 00 00 00                     # sh_offset
00 00 00 00                     # sh_length
00 00 00 00                     # sh_link
00 00 00 00                     # sh_info
01 00 00 00                     # sh_1?
00 00 00 00                     # sh_entsize

## FIXME: M0 for calculations?
:ELF_section_header_text
%ELF_shstr__text>ELF_shstr      # sh_name
01 00 00 00                     # sh_type = SHT_PROGBITS = 1
06 00 00 00                     # sh_flags = SHF-ALLOC|SHF-EXEC =2 | 4 = 6
&ELF_text                       # sh_addr
%ELF_text>ELF_base              # sh_offset
%ELF_data>ELF_text              # sh_length
00 00 00 00                     # sh_link
00 00 00 00                     # sh_info
01 00 00 00                     # sh_1?
00 00 00 00                     # sh_entsize

:ELF_section_header_data
%ELF_shstr__data>ELF_shstr     # sh_name
01 00 00 00                    # sh_type = SHT_PROGBITS = 1
03 00 00 00                    # sh_flags = SHF-WRITE|SHF-ALLOC = 1 | 2 = 3
&ELF_data                      # sh_addr
%ELF_data>ELF_base             # sh_offset
%ELF_sym>ELF_data              # sh_length
00 00 00 00                    # sh_link
00 00 00 00                    # sh_info
01 00 00 00                    # sh_1?
00 00 00 00                    # sh_entsize

:ELF_section_header_comment
%ELF_shstr__comment>ELF_shstr  # sh_name
01 00 00 00                    # sh_type = SHT_PROGBITS = 1
00 00 00 00                    # sh_flags
&ELF_comment                   # sh_addr
%ELF_comment>ELF_base          # sh_offset
%ELF_shstr>ELF_comment         # sh_length
00 00 00 00                    # sh_link
00 00 00 00                    # sh_info
01 00 00 00                    # sh_1?
00 00 00 00                    # sh_entsize

:ELF_section_header_shstr
%ELF_shstr__shstr>ELF_shstr    # sh_name
03 00 00 00                    # sh_type: str-sht-strtab
00 00 00 00                    # sh_flags
&ELF_shstr                     # sh_addr
%ELF_shstr>ELF_base            # sh_offset
%ELF_section_headers>ELF_shstr # sh_length
00 00 00 00                    # sh_link
00 00 00 00                    # sh_info
01 00 00 00                    # sh_1?
00 00 00 00                    # sh_entsize

:ELF_section_header_sym
%ELF_shstr__sym>ELF_shstr      # sh_name
02 00 00 00                    # sh_type: str-sht-symtab
00 00 00 00                    # sh_flags
&ELF_sym                       # sh_addr
%ELF_sym>ELF_base              # sh_offset
%ELF_end>ELF_sym               # sh_length
06 00 00 00                    # sh_link:6
00 00 00 00                    # sh_info
01 00 00 00                    # sh_1?
10 00 00 00                    # sh_entsize

:ELF_section_header_str
%ELF_shstr__str>ELF_shstr      # sh_name
03 00 00 00                    # sh_type: str-sht-strtab
00 00 00 00                    # sh_flags
&ELF_str                       # sh_addr
%ELF_str>ELF_base              # sh_offset
%ELF_sym>ELF_str               # sh_length
00 00 00 00                    # sh_link
00 00 00 00                    # sh_info
01 00 00 00                    # sh_1?
00 00 00 00                    # sh_entsize

# @1e8
00 00 00 00  # align
00 00 00 00

# @1f0

00 00 00 00  # align
00 00 00 00
00 00 00 00
00 00 00 00

# @200
:ELF_text

https://git.savannah.gnu.org/cgit/mes.git/tree/include/alloca.h?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/include/alloca.h used in: Step 301
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_ALLOCA_H
#define __MES_ALLOCA_H 1

#if SYSTEM_LIBC
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#undef __MES_ALLOCA_H
#include_next <alloca.h>

#else // ! SYSTEM_LIBC

#include <sys/types.h>

#if _ALLOCA_UNSIGNED
void *alloca (unsigned size);
#elif _ALLOCA_CHAR
char *alloca (int);
#else
void *alloca (size_t size);
#endif

#endif // ! SYSTEM_LIBC

#endif // __MES_ALLOCA_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/argz.h?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/include/argz.h used in: Step 302
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_ARGZ_H
#define __MES_ARGZ_H 1

#if SYSTEM_LIBC
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#undef __MES_ARGZ_H
#include_next <argz.h>

#else // ! SYSTEM_LIBC

#include <mes/lib-mini.h>

size_t __argz_count (char const *argz, size_t len);
void __argz_extract (char const *argz, size_t len, char **argv);
size_t __argz_extract_count (char const *argz, size_t len, char **argv);

#endif // ! SYSTEM_LIBC

#endif // __MES_ARGZ_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/ar.h?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/include/ar.h used in: Step 303
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright (C) 1996 Free Software Foundation, Inc.
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_AR_H
#define __MES_AR_H 1

#if SYSTEM_LIBC
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#undef __MES_AR_H
#include_next <ar.h>

#else // ! SYSTEM_LIBC

// Taken from GNU C Library 2.2.5

/* Archive files start with the ARMAG identifying string.  Then follows a
   `struct ar_hdr', and as many bytes of member file data as its `ar_size'
   member indicates, for each member file.  */

#define ARMAG   "!<arch>\n"     /* String that begins an archive file.  */
#define SARMAG  8               /* Size of that string.  */

#define ARFMAG  "`\n"           /* String in ar_fmag at end of each header.  */

struct ar_hdr
{
  char ar_name[16];             /* Member file name, sometimes / terminated. */
  char ar_date[12];             /* File date, decimal seconds since Epoch.  */
  char ar_uid[6], ar_gid[6];    /* User and group IDs, in ASCII decimal.  */
  char ar_mode[8];              /* File mode, in ASCII octal.  */
  char ar_size[10];             /* File size, in ASCII decimal.  */
  char ar_fmag[2];              /* Always contains ARFMAG.  */
};

#endif // ! SYSTEM_LIBC

#endif // __MES_ARGZ_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/dirent.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright (C) 1991, 1992 Free Software Foundation, Inc.
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef __MES_DIRENT_H
#define __MES_DIRENT_H 1

#if SYSTEM_LIBC
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#undef __MES_DIRENT_H
#include_next <dirent.h>

#else // ! SYSTEM_LIBC

#include <dirstream.h>

// Taken from GNU C Library 1.06.4, 2.2.5

/*
 *  POSIX Standard: 5.1.2 Directory Operations  <dirent.h>
 */

#include <stddef.h>

int __getdirentries (int filedes, char *buffer, size_t nbytes, off_t * basep);

struct dirent
{
  ino_t d_ino;
  off_t d_off;
  unsigned short int d_reclen;
#if 0
  unsigned char d_type;
#endif
  char d_name[256];             /* We must not include limits.h! */
};

/* Open a directory stream on NAME.
   Return a DIR stream on the directory, or NULL if it could not be opened.  */
DIR *opendir (char const *name);

/* Close the directory stream DIRP.
   Return 0 if successful, -1 if not.  */
int closedir (DIR * dirp);

/* Read a directory entry from DIRP.
   Return a pointer to a `struct dirent' describing the entry,
   or NULL for EOF or error.  The storage returned may be overwritten
   by a later readdir call on the same DIR stream.  */
struct dirent *readdir (DIR * dirp);

/* Rewind DIRP to the beginning of the directory.  */
extern void rewinddir (DIR * dirp);

#endif // ! SYSTEM_LIBC

#endif // __MES_DIRENT_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/dirstream.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 *Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc.
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef __MES_DIRSTREAM_H
#define __MES_DIRSTREAM_H 1

#if SYSTEM_LIBC && HAVE_DIRSTREAM_H
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#undef __MES_DIRSTREAM_H
#include_next <dirstream.h>

#else // ! SYSTEM_LIBC

#include <sys/types.h>

// Taken from GNU C Library 2.2.5

/* Directory stream type.  */
struct __dirstream
{
  int fd;                       /* File descriptor.  */

  char *data;                   /* Directory block.  */
  size_t allocation;            /* Space allocated for the block.  */
  size_t size;                  /* Total valid data in the block.  */
  size_t offset;                /* Current offset into the block.  */

  off_t filepos;                /* Position of next entry to read.  */
};

typedef struct __dirstream DIR;

#endif // ! SYSTEM_LIBC

#endif // __MES_DIRSTREAM_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/dlfcn.h?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/include/dlfcn.h used in: Step 308
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_DLFCN_H
#define __MES_DLFCN_H 1

#if SYSTEM_LIBC
#undef __MES_DLFCN_H
#include_next <dlfcn.h>

#else // ! SYSTEM_LIBC

#define RTLD_LAZY   0x00001
#define RTLD_NOW    0x00002
#define RTLD_BINDING_MASK   0x3
#define RTLD_NOLOAD 0x00004
#define RTLD_DEEPBIND   0x00008
#define RTLD_GLOBAL 0x00100
#define RTLD_LOCAL  0
#define RTLD_NODELETE   0x01000
#define RTLD_DEFAULT    0

void *dlopen (char const *filename, int flags);
int dlclose (void *handle);

#endif // ! SYSTEM_LIBC

#endif // __MES_DLFCN_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/endian.h?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/include/endian.h used in: Step 309
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_ENDIAN_H
#define __MES_ENDIAN_H 1

#if SYSTEM_LIBC
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#undef __MES_ENDIAN_H
#include_next <endian.h>

#else // ! SYSTEM_LIBC
#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321
#define __BYTE_ORDER __LITTLE_ENDIAN
#endif // ! SYSTEM_LIBC

#endif // __MES_ENDIAN_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/features.h?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/include/features.h used in: Step 312
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_FEATURES_H
#define __MES_FEATURES_H 1

#if SYSTEM_LIBC
#undef __MES_FEATURES_H
#include_next <features.h>
#endif // (SYSTEM_LIBC)

#endif // __MES_FEATURES_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/float.h?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/include/float.h used in: Step 313, Step 901
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_FLOAT_H
#define __MES_FLOAT_H 1

#if SYSTEM_LIBC
#undef __MES_FLOAT_H
#include_next <float.h>
#else // ! SYSTEM_LIBC

#define MIN_EXP -1021
#define DBL_MIN_EXP -1021
#define LDBL_MIN_EXP -1021

#endif // ! SYSTEM_LIBC

#endif // __MES_FLOAT_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/getopt.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_GETOPT_H
#define __MES_GETOPT_H 1

#if SYSTEM_LIBC
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#undef __MES_GETOPT_H
#include_next <getopt.h>

#else // ! SYSTEM_LIBC
#include <endian.h>
int isdigit (int);
int isxdigit (int);

char *optarg;
int optind;
int opterr;
struct option
{
  char const *name;
  int has_arg;
  int *flag;
  int val;
};

enum _argtype
{
  no_argument,
  required_argument,
  optional_argument
};

int getopt (int argc, char *const *argv, char const *options);
int getopt_long (int argc, char *const *argv, char const *options,
                 struct option const *long_options, int *opt_index);
int getopt_long_only (int argc, char *const *argv, char const *options,
                      struct option const *long_options, int *opt_index);

#endif // ! SYSTEM_LIBC

#endif // __MES_GETOPT_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/grp.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_GRP_H
#define __MES_GRP_H 1

#if SYSTEM_LIBC
#undef __MES_GRP_H
#include_next <grp.h>
#else // ! SYSTEM_LIBC

#include <sys/types.h>

struct group
{
  char *gr_name;
  gid_t gr_gid;
  char **gr_mem;
};

struct group *getgrent (void);
void endgrent (void);
void setgrent (void);
struct group *getgrgid (gid_t gid);
struct group *getgrnam (char const *name);

#endif // ! SYSTEM_LIBC

#endif // __MES_GRP_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/inttypes.h?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/include/inttypes.h used in: Step 316, Step 855, Step 867, Step 873, Step 875, Step 877, Step 883, Step 897, Step 899, Step 901, Step 907, Step 919, Step 923, Step 925, Step 929, Step 933, Step 939, Step 1005, Step 1006, Step 1007, Step 1009, Step 1012, Step 1136
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_INTTYPES_H
#define __MES_INTTYPES_H 1

#if SYSTEM_LIBC
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#undef __MES_INTTYPES_H
#include_next <inttypes.h>
#else // ! SYSTEM_LIBC

#include <stdint.h>
#endif // ! SYSTEM_LIBC

#endif // __MES_INTTYPES_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/libgen.h?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/include/libgen.h used in: Step 317
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_LIBGEN_H
#define __MES_LIBGEN_H 1

#if SYSTEM_LIBC
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#undef __MES_LIBGEN_H
#include_next <libgen.h>

#else // ! SYSTEM_LIBC
char *dirname (char *);
#endif // ! SYSTEM_LIBC

#endif // __MES_LIBGEN_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/locale.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_LOCALE_H
#define __MES_LOCALE_H 1

#if SYSTEM_LIBC
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#undef __MES_LOCALE_H
#include_next <locale.h>

#else // ! SYSTEM_LIBC

// *INDENT-OFF*
#ifndef LC_ALL
#define LC_CTYPE   0
#define LC_NUMERIC 1
#define LC_COLLATE 3
#define LC_ALL     6
#endif
// *INDENT-ON*

char *setlocale (int category, char const *locale);

#endif // ! SYSTEM_LIBC

#endif // __MES_LOCALE_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/memory.h?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/include/memory.h used in: Step 321, Step 600, Step 602, Step 606
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_MEMORY_H
#define __MES_MEMORY_H 1

#if SYSTEM_LIBC
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#undef __MES_MEMORY_H
#include_next <memory.h>

#else // ! SYSTEM_LIBC

#include <string.h>

#endif // ! SYSTEM_LIBC

#endif // __MES_MEMORY_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/pwd.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_PWD_H
#define __MES_PWD_H 1

#if SYSTEM_LIBC
#undef __MES_PWD_H
#include_next <pwd.h>
#else // ! SYSTEM_LIBC

#include <sys/types.h>

struct passwd
{
  char *pw_name;
  char *pw_passwd;
  uid_t pw_uid;
  gid_t pw_gid;
  char *pw_gecos;
  char *pw_dir;
  char *pw_shell;
};

struct passwd *getpwuid ();


#endif // ! SYSTEM_LIBC

#endif // __MES_PWD_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/stdbool.h?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/include/stdbool.h used in: Step 326, Step 566, Step 569, Step 570, Step 574, Step 575
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_STDBOOL_H
#define __MES_STDBOOL_H 1

#if SYSTEM_LIBC
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#undef __MES_STDBOOL_H
#include_next <stdbool.h>

#else // ! SYSTEM_LIBC
typedef int bool;
#define false 0
#define true 1
#endif // ! SYSTEM_LIBC

#endif // __MES_STDBOOL_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/stdnoreturn.h?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/include/stdnoreturn.h used in: Step 331
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_STDNORETURN_H
#define __MES_STDNORETURN_H 1

#if SYSTEM_LIBC
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#undef __MES_STDNORETURN_H
#include_next <stdnoreturn.h>

#else // ! SYSTEM_LIBC
// whut?
#endif // ! SYSTEM_LIBC

#endif // __MES_STDNORETURN_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/strings.h?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/include/strings.h used in: Step 333, Step 600, Step 602, Step 606
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_STRINGS_H
#define __MES_STRINGS_H 1

#if SYSTEM_LIBC
#undef __MES_STRINGS_H
#include_next <strings.h>
#endif // (SYSTEM_LIBC)

#endif // __MES_STRINGS_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/cdefs.h?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/include/sys/cdefs.h used in: Step 349
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_SYS_CDEFS_H
#define __MES_SYS_CDEFS_H 1

#if SYSTEM_LIBC
#undef __MES_SYS_CDEFS_H
#include_next <sys/cdefs.h>
#endif // (SYSTEM_LIBC)

#endif // __MES_SYS_CDEFS_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/dir.h?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/include/sys/dir.h used in: Step 350
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_SYS_DIR_H
#define __MES_SYS_DIR_H 1

#if SYSTEM_LIBC
#undef __MES_SYS_DIR_H
#include_next <sys/dir.h>

#else // ! SYSTEM_LIBC


#endif // ! SYSTEM_LIBC

#endif // __MES_SYS_DIR_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/file.h?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/include/sys/file.h used in: Step 351, Step 518, Step 530, Step 1112, Step 1126, Step 1189, Step 1202, Step 1207, Step 1225, Step 1241
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_SYS_FILE_H
#define __MES_SYS_FILE_H 1

#if SYSTEM_LIBC
#undef __MES_SYS_FILE_H
#include_next <sys/file.h>

#else // ! SYSTEM_LIBC


#endif // ! SYSTEM_LIBC

#endif // __MES_SYS_FILE_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/param.h?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/include/sys/param.h used in: Step 354, Step 992, Step 1124, Step 1151, Step 1154, Step 1171, Step 1172, Step 1181, Step 1206, Step 1220
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_SYS_PARAM_H
#define __MES_SYS_PARAM_H 1

#if SYSTEM_LIBC
#undef __MES_SYS_PARAM_H
#include_next <sys/param.h>

#else // ! SYSTEM_LIBC

#endif // ! SYSTEM_LIBC

#endif // __MES_SYS_PARAM_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/select.h?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/include/sys/select.h used in: Step 356
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_SYS_SELECT_H
#define __MES_SYS_SELECT_H 1

#if SYSTEM_LIBC
#undef __MES_SYS_SELECT_H
#include_next <sys/select.h>
#else //! SYSTEM_LIBC
typedef int fd_set;
#endif //! SYSTEM_LIBC

#endif // __MES_SYS_SELECT_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/timeb.h?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/include/sys/timeb.h used in: Step 358
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_SYS_TIMEB_H
#define __MES_SYS_TIMEB_H 1

#if SYSTEM_LIBC
#undef __MES_SYS_TIMEB_H
#include_next <sys/timeb.h>
#endif // (SYSTEM_LIBC)

#endif // __MES_SYS_TIMEB_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/times.h?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_SYS_TIMES_H
#define __MES_SYS_TIMES_H 1

#if SYSTEM_LIBC
#undef __MES_SYS_TIMES_H
#include_next <sys/times.h>

#else // ! SYSTEM_LIBC

#ifndef __MES_CLOCK_T
#define __MES_CLOCK_T
#undef clock_t
typedef long clock_t;
#endif

#ifndef CLOCKS_PER_SEC
#define CLOCKS_PER_SEC 1000000
#endif

#ifndef HZ
#define HZ 100
#endif

struct tms
{
  clock_t tms_utime;
  clock_t tms_stime;
  clock_t tms_cutime;
  clock_t tms_cstime;
};

#endif // ! SYSTEM_LIBC

#endif // __MES_SYS_TIMES_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/ucontext.h?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/include/sys/ucontext.h used in: Step 362
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_SYS_UCONTEXT_H
#define __MES_SYS_UCONTEXT_H 1

#if SYSTEM_LIBC
#undef __MES_SYS_UCONTEXT_H
#include_next <sys/ucontext.h>
#endif // (SYSTEM_LIBC)

#endif // __MES_SYS_UCONTEXT_H

https://git.savannah.gnu.org/cgit/mes.git/tree/include/sys/user.h?h=v0.24.2

File: /sysa/mes-0.24.2/build/mes-0.24.2/include/sys/user.h used in: Step 363
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __MES_SYS_USER_H
#define __MES_SYS_USER_H 1

#if SYSTEM_LIBC
#undef __MES_SYS_USER_H
#include_next <sys/user.h>

#else // ! SYSTEM_LIBC

/* These are the 32-bit x86 structures.  */
struct user_fpregs_struct
{
  long int cwd;
  long int swd;
  long int twd;
  long int fip;
  long int fcs;
  long int foo;
  long int fos;
  long int st_space[20];
};

struct user_fpxregs_struct
{
  unsigned short int cwd;
  unsigned short int swd;
  unsigned short int twd;
  unsigned short int fop;
  long int fip;
  long int fcs;
  long int foo;
  long int fos;
  long int mxcsr;
  long int reserved;
  long int st_space[32];        /* 8*16 bytes for each FP-reg = 128 bytes */
  long int xmm_space[32];       /* 8*16 bytes for each XMM-reg = 128 bytes */
  long int padding[56];
};

struct user_regs_struct
{
  long int ebx;
  long int ecx;
  long int edx;
  long int esi;
  long int edi;
  long int ebp;
  long int eax;
  long int xds;
  long int xes;
  long int xfs;
  long int xgs;
  long int orig_eax;
  long int eip;
  long int xcs;
  long int eflags;
  long int esp;
  long int xss;
};

// *INDENT-OFF*
struct user
{
  struct user_regs_struct    regs;
  int                        u_fpvalid;
  struct user_fpregs_struct  i387;
  unsigned long int          u_tsize;
  unsigned long int          u_dsize;
  unsigned long int          u_ssize;
  unsigned long int          start_code;
  unsigned long int          start_stack;
  long int                   signal;
  int                        reserved;
  struct user_regs_struct   *u_ar0;
  struct user_fpregs_struct *u_fpstate;
  unsigned long int          magic;
  char                       u_comm [32];
  int                        u_debugreg [8];
};

#define PAGE_SHIFT           12
#define PAGE_SIZE            (1UL << PAGE_SHIFT)
#define PAGE_MASK            (~(PAGE_SIZE-1))
#define NBPG                 PAGE_SIZE
#define UPAGES               1
#define HOST_TEXT_START_ADDR (u.start_code)
#define HOST_STACK_END_ADDR  (u.start_stack + u.u_ssize * NBPG)
// *INDENT-ON*

#endif // ! SYSTEM_LIBC

#endif // __MES_SYS_USER_H

https://github.com/fosslinux/live-bootstrap/blob/master/sysa/mes-0.24.2/mes-0.24.2.checksums

File: /sysa/mes-0.24.2/mes-0.24.2.checksums used in: Step 366
b2a48b2724a7b791df66efc2384a405a91d26579459a6797514dec89c2e76658  /usr/bin/mes
148ce096422535832802494f1128c26b6580cf3b66635e56abb33f7b3fc26043  /usr/bin/mes-m2
17c86665c2f925d88e3c1f827f312bbc7575b9e6006ef57833e895b6e73b8087  /usr/bin/mescc.scm
4feafab424611c976dc4628aa862e37b4e92b5869aebbcf7655e684c3f589041  /usr/lib/x86-mes/crt1.s
69e9ec2ee2ebf065575cdaf878629178b85330257dde0da790a428c0280d1ecb  /usr/lib/x86-mes/crt1.o
c9944a799d584abfa76f385c14ac0caf6f46d03b34bf2712493602b12826c6b2  /usr/lib/x86-mes/x86.M1
d8646707db6aa2a76fdc5dbb3521376439e357f9f1de1d67f02a1afeefd342ac  /usr/lib/x86-mes/libmescc.s
7ec49fbcbc70b49648150b021a2ff9ab2b27e89eb8815919a7ffabe375ab1edc  /usr/lib/x86-mes/libc+tcc.s
b935d4c30213b49d899ab8bccce33117057ea0f3a1a8d3afc5e07fb8ce4590db  /usr/lib/x86-mes/libc.s
52f697278ccdff5e457f27e10f465a91ab9858f0c6cee0683831cadb3109bbb7  /usr/lib/x86-mes/libmescc.a
840ee884db456e1982f40bce82209515a8e0b09bc404c4bc2a26d237bfa4d9ca  /usr/lib/x86-mes/libc+tcc.a
32be26479096c52dbffe9c8bf14765f753d6882c3ae43760eda03406c0cf2539  /usr/lib/x86-mes/libc.a
b16ab368bc4c7b8bd896d03cba565a60e97760dea4da9f5c8a1a3d2902a79df6  /usr/lib/linux/x86-mes/elf32-header.hex2
f9873d9aab12e70f24d97f8319e17a1e698ca60779ae9a6ab3ede648cd60fc61  /usr/lib/linux/x86-mes/elf32-footer-single-main.hex2

https://github.com/fosslinux/live-bootstrap/blob/master/sysa/tcc-0.9.26/sources

File: ../git/live-bootstrap/sysa/tcc-0.9.26/sources used in: Step 368
https://lilypond.org/janneke/tcc/tcc-0.9.26-1136-g5bba73cc.tar.gz 23cacd448cff2baf6ed76c2d1e2d654ff4e557046e311dfb6be7e1c631014ef8 tcc-0.9.26.tar.gz

https://gitlab.com/janneke/tinycc/-/blob/ff2210b308321f27ee07476d07f24b5095602b17/tcctools.c

File: ../git/live-bootstrap/sysa/tcc-0.9.26/build/tcc-0.9.26-1136-g5bba73cc/tcctools.c used in: Step 374, Step 375, Step 378, Step 395, Step 407, Step 419, Step 431, Step 443, Step 455
/* -------------------------------------------------------------- */
/*
 *  TCC - Tiny C Compiler
 *
 *  tcctools.c - extra tools and and -m32/64 support
 *
 */

/* -------------------------------------------------------------- */
/*
 * This program is for making libtcc1.a without ar
 * tiny_libmaker - tiny elf lib maker
 * usage: tiny_libmaker [lib] files...
 * Copyright (c) 2007 Timppa
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#ifndef _TCC_H
#include "tcc.h"
#endif

//#define ARMAG  "!<arch>\n"
#define ARFMAG "`\n"

typedef struct {
    char ar_name[16];
    char ar_date[12];
    char ar_uid[6];
    char ar_gid[6];
    char ar_mode[8];
    char ar_size[10];
    char ar_fmag[2];
} ArHdr;

static unsigned long le2belong(unsigned long ul) {
    return ((ul & 0xFF0000)>>8)+((ul & 0xFF000000)>>24) +
        ((ul & 0xFF)<<24)+((ul & 0xFF00)<<8);
}

/* Returns 1 if s contains any of the chars of list, else 0 */
static int contains_any(const char *s, const char *list) {
  const char *l;
  for (; *s; s++) {
      for (l = list; *l; l++) {
          if (*s == *l)
              return 1;
      }
  }
  return 0;
}

static int ar_usage(int ret) {
    fprintf(stderr, "usage: tcc -ar [rcsv] lib file...\n");
    fprintf(stderr, "create library ([abdioptxN] not supported).\n");
    return ret;
}

ST_FUNC int tcc_tool_ar(TCCState *s1, int argc, char **argv)
{
    static ArHdr arhdr = {
        "/               ",
        "            ",
        "0     ",
        "0     ",
        "0       ",
        "          ",
        ARFMAG
        };

    static ArHdr arhdro = {
        "                ",
        "            ",
        "0     ",
        "0     ",
        "0       ",
        "          ",
        ARFMAG
        };

    FILE *fi, *fh = NULL, *fo = NULL;
    ElfW(Ehdr) *ehdr;
    ElfW(Shdr) *shdr;
    ElfW(Sym) *sym;
    int i, fsize, i_lib, i_obj;
    char *buf, *shstr, *symtab = NULL, *strtab = NULL;
    int symtabsize = 0;//, strtabsize = 0;
    char *anames = NULL;
    int *afpos = NULL;
    int istrlen, strpos = 0, fpos = 0, funccnt = 0, funcmax, hofs;
    char tfile[260], stmp[20];
    char *file, *name;
    int ret = 2;
    const char *ops_conflict = "habdioptxN";  // unsupported but destructive if ignored.
    int verbose = 0;

    i_lib = 0; i_obj = 0;  // will hold the index of the lib and first obj
    for (i = 1; i < argc; i++) {
        const char *a = argv[i];
        if (*a == '-' && strstr(a, "."))
            ret = 1; // -x.y is always invalid (same as gnu ar)
        if ((*a == '-') || (i == 1 && !strstr(a, "."))) {  // options argument
            if (contains_any(a, ops_conflict))
                ret = 1;
            if (strstr(a, "v"))
                verbose = 1;
        } else {  // lib or obj files: don't abort - keep validating all args.
            if (!i_lib)  // first file is the lib
                i_lib = i;
            else if (!i_obj)  // second file is the first obj
                i_obj = i;
        }
    }

    if (!i_obj)  // i_obj implies also i_lib. we require both.
        ret = 1;

    if (ret == 1)
        return ar_usage(ret);

    if ((fh = fopen(argv[i_lib], "wb")) == NULL)
    {
        fprintf(stderr, "tcc: ar: can't open file %s \n", argv[i_lib]);
        goto the_end;
    }

    sprintf(tfile, "%s.tmp", argv[i_lib]);
    if ((fo = fopen(tfile, "wb+")) == NULL)
    {
        fprintf(stderr, "tcc: ar: can't create temporary file %s\n", tfile);
        goto the_end;
    }

    funcmax = 250;
    afpos = tcc_realloc(NULL, funcmax * sizeof *afpos); // 250 func
    memcpy(&arhdro.ar_mode, "100666", 6);

    // i_obj = first input object file
    while (i_obj < argc)
    {
        if (*argv[i_obj] == '-') {  // by now, all options start with '-'
            i_obj++;
            continue;
        }
        if ((fi = fopen(argv[i_obj], "rb")) == NULL) {
            fprintf(stderr, "tcc: ar: can't open file %s \n", argv[i_obj]);
            goto the_end;
        }
        if (verbose)
            printf("a - %s\n", argv[i_obj]);

        fseek(fi, 0, SEEK_END);
        fsize = ftell(fi);
        fseek(fi, 0, SEEK_SET);
        buf = tcc_malloc(fsize + 1);
        fread(buf, fsize, 1, fi);
        fclose(fi);

        // elf header
        ehdr = (ElfW(Ehdr) *)buf;
        if (ehdr->e_ident[4] != ELFCLASSW)
        {
            fprintf(stderr, "tcc: ar: Unsupported Elf Class: %s\n", argv[i_obj]);
            goto the_end;
        }

        shdr = (ElfW(Shdr) *) (buf + ehdr->e_shoff + ehdr->e_shstrndx * ehdr->e_shentsize);
        shstr = (char *)(buf + shdr->sh_offset);
        for (i = 0; i < ehdr->e_shnum; i++)
        {
            shdr = (ElfW(Shdr) *) (buf + ehdr->e_shoff + i * ehdr->e_shentsize);
            if (!shdr->sh_offset)
                continue;
            if (shdr->sh_type == SHT_SYMTAB)
            {
                symtab = (char *)(buf + shdr->sh_offset);
                symtabsize = shdr->sh_size;
            }
            if (shdr->sh_type == SHT_STRTAB)
            {
                if (!strcmp(shstr + shdr->sh_name, ".strtab"))
                {
                    strtab = (char *)(buf + shdr->sh_offset);
                    //strtabsize = shdr->sh_size;
                }
            }
        }

        if (symtab && symtabsize)
        {
            int nsym = symtabsize / sizeof(ElfW(Sym));
            //printf("symtab: info size shndx name\n");
            for (i = 1; i < nsym; i++)
            {
                sym = (ElfW(Sym) *) (symtab + i * sizeof(ElfW(Sym)));
                if (sym->st_shndx &&
                    (sym->st_info == 0x10
                    || sym->st_info == 0x11
                    || sym->st_info == 0x12
                    )) {
                    //printf("symtab: %2Xh %4Xh %2Xh %s\n", sym->st_info, sym->st_size, sym->st_shndx, strtab + sym->st_name);
                    istrlen = strlen(strtab + sym->st_name)+1;
                    anames = tcc_realloc(anames, strpos+istrlen);
                    strcpy(anames + strpos, strtab + sym->st_name);
                    strpos += istrlen;
                    if (++funccnt >= funcmax) {
                        funcmax += 250;
                        afpos = tcc_realloc(afpos, funcmax * sizeof *afpos); // 250 func more
                    }
                    afpos[funccnt] = fpos;
                }
            }
        }

        file = argv[i_obj];
        for (name = strchr(file, 0);
             name > file && name[-1] != '/' && name[-1] != '\\';
             --name);
        istrlen = strlen(name);
        if (istrlen >= sizeof(arhdro.ar_name))
            istrlen = sizeof(arhdro.ar_name) - 1;
        memset(arhdro.ar_name, ' ', sizeof(arhdro.ar_name));
        memcpy(arhdro.ar_name, name, istrlen);
        arhdro.ar_name[istrlen] = '/';
        sprintf(stmp, "%-10d", fsize);
        memcpy(&arhdro.ar_size, stmp, 10);
        fwrite(&arhdro, sizeof(arhdro), 1, fo);
        fwrite(buf, fsize, 1, fo);
        tcc_free(buf);
        i_obj++;
        fpos += (fsize + sizeof(arhdro));
    }
    hofs = 8 + sizeof(arhdr) + strpos + (funccnt+1) * sizeof(int);
    fpos = 0;
    if ((hofs & 1)) // align
        hofs++, fpos = 1;
    // write header
    fwrite("!<arch>\n", 8, 1, fh);
    sprintf(stmp, "%-10d", (int)(strpos + (funccnt+1) * sizeof(int)));
    memcpy(&arhdr.ar_size, stmp, 10);
    fwrite(&arhdr, sizeof(arhdr), 1, fh);
    afpos[0] = le2belong(funccnt);
    for (i=1; i<=funccnt; i++)
        afpos[i] = le2belong(afpos[i] + hofs);
    fwrite(afpos, (funccnt+1) * sizeof(int), 1, fh);
    fwrite(anames, strpos, 1, fh);
    if (fpos)
        fwrite("", 1, 1, fh);
    // write objects
    fseek(fo, 0, SEEK_END);
    fsize = ftell(fo);
    fseek(fo, 0, SEEK_SET);
    buf = tcc_malloc(fsize + 1);
    fread(buf, fsize, 1, fo);
    fwrite(buf, fsize, 1, fh);
    tcc_free(buf);
    ret = 0;
the_end:
    if (anames)
        tcc_free(anames);
    if (afpos)
        tcc_free(afpos);
    if (fh)
        fclose(fh);
    if (fo)
        fclose(fo), remove(tfile);
    return ret;
}

/* -------------------------------------------------------------- */
/*
 * tiny_impdef creates an export definition file (.def) from a dll
 * on MS-Windows. Usage: tiny_impdef library.dll [-o outputfile]"
 *
 *  Copyright (c) 2005,2007 grischka
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#ifdef TCC_TARGET_PE

ST_FUNC int tcc_tool_impdef(TCCState *s1, int argc, char **argv)
{
    int ret, v, i;
    char infile[260];
    char outfile[260];

    const char *file;
    char *p, *q;
    FILE *fp, *op;

#ifdef _WIN32
    char path[260];
#endif

    infile[0] = outfile[0] = 0;
    fp = op = NULL;
    ret = 1;
    p = NULL;
    v = 0;

    for (i = 1; i < argc; ++i) {
        const char *a = argv[i];
        if ('-' == a[0]) {
            if (0 == strcmp(a, "-v")) {
                v = 1;
            } else if (0 == strcmp(a, "-o")) {
                if (++i == argc)
                    goto usage;
                strcpy(outfile, argv[i]);
            } else
                goto usage;
        } else if (0 == infile[0])
            strcpy(infile, a);
        else
            goto usage;
    }

    if (0 == infile[0]) {
usage:
        fprintf(stderr,
            "usage: tcc -impdef library.dll [-v] [-o outputfile]\n"
            "create export definition file (.def) from dll\n"
            );
        goto the_end;
    }

    if (0 == outfile[0]) {
        strcpy(outfile, tcc_basename(infile));
        q = strrchr(outfile, '.');
        if (NULL == q)
            q = strchr(outfile, 0);
        strcpy(q, ".def");
    }

    file = infile;
#ifdef _WIN32
    if (SearchPath(NULL, file, ".dll", sizeof path, path, NULL))
        file = path;
#endif
    ret = tcc_get_dllexports(file, &p);
    if (ret || !p) {
        fprintf(stderr, "tcc: impdef: %s '%s'\n",
            ret == 32 ? "can't read symbols from 32bit" :
            ret == 64 ? "can't read symbols from 64bit" :
            ret == -1 ? "can't find file" :
            ret ==  0 ? "no symbols found in" :
            "unknown file type", file);
        ret = 1;
        goto the_end;
    }

    if (v)
        printf("-> %s\n", file);

    op = fopen(outfile, "w");
    if (NULL == op) {
        fprintf(stderr, "tcc: impdef: could not create output file: %s\n", outfile);
        goto the_end;
    }

    fprintf(op, "LIBRARY %s\n\nEXPORTS\n", tcc_basename(file));
    for (q = p, i = 0; *q; ++i) {
        fprintf(op, "%s\n", q);
        q += strlen(q) + 1;
    }

    if (v)
        printf("<- %s (%d symbol%s)\n", outfile, i, &"s"[i<2]);

    ret = 0;

the_end:
    /* cannot free memory received from tcc_get_dllexports
       if it came from a dll */
    /* if (p)
        tcc_free(p); */
    if (fp)
        fclose(fp);
    if (op)
        fclose(op);
    return ret;
}

#endif /* TCC_TARGET_PE */

/* -------------------------------------------------------------- */
/*
 *  TCC - Tiny C Compiler
 *
 *  Copyright (c) 2001-2004 Fabrice Bellard
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

/* re-execute the i386/x86_64 cross-compilers with tcc -m32/-m64: */

#if !defined TCC_TARGET_I386 && !defined TCC_TARGET_X86_64

ST_FUNC void tcc_tool_cross(TCCState *s, char **argv, int option)
{
    tcc_error("-m%d not implemented.", option);
}

#else
#ifdef _WIN32
#include <process.h>

static char *str_replace(const char *str, const char *p, const char *r)
{
    const char *s, *s0;
    char *d, *d0;
    int sl, pl, rl;

    sl = strlen(str);
    pl = strlen(p);
    rl = strlen(r);
    for (d0 = NULL;; d0 = tcc_malloc(sl + 1)) {
        for (d = d0, s = str; s0 = s, s = strstr(s, p), s; s += pl) {
            if (d) {
                memcpy(d, s0, sl = s - s0), d += sl;
                memcpy(d, r, rl), d += rl;
            } else
                sl += rl - pl;
        }
        if (d) {
            strcpy(d, s0);
            return d0;
        }
    }
}

static int execvp_win32(const char *prog, char **argv)
{
    int ret; char **p;
    /* replace all " by \" */
    for (p = argv; *p; ++p)
        if (strchr(*p, '"'))
            *p = str_replace(*p, "\"", "\\\"");
    ret = _spawnvp(P_NOWAIT, prog, (const char *const*)argv);
    if (-1 == ret)
        return ret;
    _cwait(&ret, ret, WAIT_CHILD);
    exit(ret);
}
#define execvp execvp_win32
#endif /* _WIN32 */

ST_FUNC void tcc_tool_cross(TCCState *s, char **argv, int target)
{
    char program[4096];
    char *a0 = argv[0];
    int prefix = tcc_basename(a0) - a0;

    snprintf(program, sizeof program,
        "%.*s%s"
#ifdef TCC_TARGET_PE
        "-win32"
#endif
        "-tcc"
#ifdef _WIN32
        ".exe"
#endif
        , prefix, a0, target == 64 ? "x86_64" : "i386");

    if (strcmp(a0, program))
        execvp(argv[0] = program, argv);
    tcc_error("could not run '%s'", program);
}

#endif /* TCC_TARGET_I386 && TCC_TARGET_X86_64 */
/* -------------------------------------------------------------- */
/* enable commandline wildcard expansion (tcc -o x.exe *.c) */

#ifdef _WIN32
int _CRT_glob = 1;
#ifndef _CRT_glob
int _dowildcard = 1;
#endif
#endif

/* -------------------------------------------------------------- */
/* generate xxx.d file */

ST_FUNC void gen_makedeps(TCCState *s, const char *target, const char *filename)
{
    FILE *depout;
    char buf[1024];
    int i;

    if (!filename) {
        /* compute filename automatically: dir/file.o -> dir/file.d */
        snprintf(buf, sizeof buf, "%.*s.d",
            (int)(tcc_fileextension(target) - target), target);
        filename = buf;
    }

    if (s->verbose)
        printf("<- %s\n", filename);

    /* XXX return err codes instead of error() ? */
    depout = fopen(filename, "w");
    if (!depout)
        tcc_error("could not open '%s'", filename);

    fprintf(depout, "%s: \\\n", target);
    for (i=0; i<s->nb_target_deps; ++i)
        fprintf(depout, " %s \\\n", s->target_deps[i]);
    fprintf(depout, "\n");
    fclose(depout);
}

/* -------------------------------------------------------------- */

https://github.com/fosslinux/live-bootstrap/blob/master/sysa/tcc-0.9.26/simple-patches/remove-fileopen.before

File: ../git/live-bootstrap/sysa/tcc-0.9.26/simple-patches/remove-fileopen.before used in: Step 374
    if (ret == 1)
        return ar_usage(ret);

    if ((fh = fopen(argv[i_lib], "wb")) == NULL)
    {
        fprintf(stderr, "tcc: ar: can't open file %s \n", argv[i_lib]);
        goto the_end;
    }

https://github.com/fosslinux/live-bootstrap/blob/master/sysa/tcc-0.9.26/simple-patches/remove-fileopen.after

File: ../git/live-bootstrap/sysa/tcc-0.9.26/simple-patches/remove-fileopen.after used in: Step 374
    if (ret == 1)
        return ar_usage(ret);

https://github.com/fosslinux/live-bootstrap/blob/master/sysa/tcc-0.9.26/simple-patches/addback-fileopen.before

File: ../git/live-bootstrap/sysa/tcc-0.9.26/simple-patches/addback-fileopen.before used in: Step 375
    // write header

https://github.com/fosslinux/live-bootstrap/blob/master/sysa/tcc-0.9.26/simple-patches/addback-fileopen.after

File: ../git/live-bootstrap/sysa/tcc-0.9.26/simple-patches/addback-fileopen.after used in: Step 375
    if ((fh = fopen(argv[i_lib], "wb")) == NULL)
    {
        fprintf(stderr, "tcc: ar: can't open file %s \n", argv[i_lib]);
        goto the_end;
    }

    // write header

https://gitlab.com/janneke/tinycc/-/blob/ff2210b308321f27ee07476d07f24b5095602b17/tcc.c

File: ../git/live-bootstrap/sysa/tcc-0.9.26/build/tcc-0.9.26-1136-g5bba73cc/tcc.c used in: Step 378, Step 395, Step 407, Step 419, Step 431, Step 443, Step 455
/*
 *  TCC - Tiny C Compiler
 * 
 *  Copyright (c) 2001-2004 Fabrice Bellard
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifdef ONE_SOURCE
#include "libtcc.c"
#else
#include "tcc.h"
#endif
#include "tcctools.c"

static const char help[] =
    "Tiny C Compiler "TCC_VERSION" - Copyright (C) 2001-2006 Fabrice Bellard\n"
    "Usage: tcc [options...] [-o outfile] [-c] infile(s)...\n"
    "       tcc [options...] -run infile [arguments...]\n"
    "General options:\n"
    "  -c          compile only - generate an object file\n"
    "  -o outfile  set output filename\n"
    "  -run        run compiled source\n"
    "  -fflag      set or reset (with 'no-' prefix) 'flag' (see tcc -hh)\n"
    "  -Wwarning   set or reset (with 'no-' prefix) 'warning' (see tcc -hh)\n"
    "  -w          disable all warnings\n"
    "  -v -vv      show version, show search paths or loaded files\n"
    "  -h -hh      show this, show more help\n"
    "  -bench      show compilation statistics\n"
    "  -           use stdin pipe as infile\n"
    "  @listfile   read arguments from listfile\n"
    "Preprocessor options:\n"
    "  -Idir       add include path 'dir'\n"
    "  -Dsym[=val] define 'sym' with value 'val'\n"
    "  -Usym       undefine 'sym'\n"
    "  -E          preprocess only\n"
    "Linker options:\n"
    "  -Ldir       add library path 'dir'\n"
    "  -llib       link with dynamic or static library 'lib'\n"
    "  -r          generate (relocatable) object file\n"
    "  -shared     generate a shared library/dll\n"
    "  -rdynamic   export all global symbols to dynamic linker\n"
    "  -soname     set name for shared library to be used at runtime\n"
    "  -Wl,-opt[=val]  set linker option (see tcc -hh)\n"
    "Debugger options:\n"
    "  -g          generate runtime debug info\n"
#ifdef CONFIG_TCC_BCHECK
    "  -b          compile with built-in memory and bounds checker (implies -g)\n"
#endif
#ifdef CONFIG_TCC_BACKTRACE
    "  -bt N       show N callers in stack traces\n"
#endif
    "Misc. options:\n"
    "  -x[c|a|n]   specify type of the next infile\n"
    "  -nostdinc   do not use standard system include paths\n"
    "  -nostdlib   do not link with standard crt and libraries\n"
    "  -Bdir       set tcc's private include/library dir\n"
    "  -MD         generate dependency file for make\n"
    "  -MF file    specify dependency file name\n"
    "  -m32/64     defer to i386/x86_64 cross compiler\n"
    "Tools:\n"
    "  create library  : tcc -ar [rcsv] lib.a files\n"
#ifdef TCC_TARGET_PE
    "  create def file : tcc -impdef lib.dll [-v] [-o lib.def]\n"
#endif
    ;

static const char help2[] =
    "Tiny C Compiler "TCC_VERSION" - More Options\n"
    "Special options:\n"
    "  -P -P1                        with -E: no/alternative #line output\n"
    "  -dD -dM                       with -E: output #define directives\n"
    "  -pthread                      same as -D_REENTRANT and -lpthread\n"
    "  -On                           same as -D__OPTIMIZE__ for n > 0\n"
    "  -Wp,-opt                      same as -opt\n"
    "  -include file                 include 'file' above each input file\n"
    "  -isystem dir                  add 'dir' to system include path\n"
    "  -iwithprefix dir              set tcc's private include/library subdir\n"
    "  -static                       link to static libraries (not recommended)\n"
    "  -dumpversion                  print version\n"
    "  -print-search-dirs            print search paths\n"
    "Ignored options:\n"
    "  --param  -pedantic  -pipe  -s  -std  -traditional\n"
    "-W... warnings:\n"
    "  all                           turn on some (*) warnings\n"
    "  error                         stop after first warning\n"
    "  unsupported                   warn about ignored options, pragmas, etc.\n"
    "  write-strings                 strings are const\n"
    "  implicit-function-declaration   warn for missing prototype (*)\n"
    "-f[no-]... flags:\n"
    "  unsigned-char                 default char is unsigned\n"
    "  signed-char                   default char is signed\n"
    "  common                        use common section instead of bss\n"
    "  leading-underscore            decorate extern symbols\n"
    "  ms-extensions                 allow anonymous struct in struct\n"
    "  dollars-in-identifiers        allow '$' in C symbols\n"
    "-m... target specific options:\n"
    "  ms-bitfields                  use MSVC bitfield layout\n"
#ifdef TCC_TARGET_ARM
    "  float-abi                     hard/softfp on arm\n"
#endif
#ifdef TCC_TARGET_X86_64
    "  no-sse                        disable floats on x86_64\n"
#endif
    "-Wl,... linker options:\n"
    "  -nostdlib                     do not link with standard crt/libs\n"
    "  -[no-]whole-archive           load lib(s) fully/only as needed\n"
    "  -export-all-symbols           same as -rdynamic\n"
    "  -image-base= -Ttext=          set base address of executable\n"
    "  -section-alignment=           set section alignment in executable\n"
#ifdef TCC_TARGET_PE
    "  -file-alignment=              set PE file alignment\n"
    "  -stack=                       set PE stack reserve\n"
    "  -large-address-aware          set related PE option\n"
    "  -subsystem=[console/windows]  set PE subsystem\n"
    "  -oformat=[pe-* binary]        set executable output format\n"
    "Predefined macros:\n"
    "  tcc -E -dM - < nul\n"
#else
    "  -rpath=                       set dynamic library search path\n"
    "  -enable-new-dtags             set DT_RUNPATH instead of DT_RPATH\n"
    "  -soname=                      set DT_SONAME elf tag\n"
    "  -Bsymbolic                    set DT_SYMBOLIC elf tag\n"
    "  -oformat=[elf32/64-* binary]  set executable output format\n"
    "  -init= -fini= -as-needed -O   (ignored)\n"
    "Predefined macros:\n"
    "  tcc -E -dM - < /dev/null\n"
#endif
    "See also the manual for more details.\n"
    ;

static const char version[] =
    "tcc version "TCC_VERSION" ("
#ifdef TCC_TARGET_I386
        "i386"
#elif defined TCC_TARGET_X86_64
        "x86_64"
#elif defined TCC_TARGET_C67
        "C67"
#elif defined TCC_TARGET_ARM
        "ARM"
#elif defined TCC_TARGET_ARM64
        "AArch64"
#endif
#ifdef TCC_ARM_HARDFLOAT
        " Hard Float"
#endif
#ifdef TCC_TARGET_PE
        " Windows"
#elif defined(TCC_TARGET_MACHO)
        " Darwin"
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
        " FreeBSD"
#else
        " Linux"
#endif
    ")\n"
    ;

static void print_dirs(const char *msg, char **paths, int nb_paths)
{
    int i;
    printf("%s:\n%s", msg, nb_paths ? "" : "  -\n");
    for(i = 0; i < nb_paths; i++)
        printf("  %s\n", paths[i]);
}

static void print_search_dirs(TCCState *s)
{
    printf("install: %s\n", s->tcc_lib_path);
    /* print_dirs("programs", NULL, 0); */
    print_dirs("include", s->sysinclude_paths, s->nb_sysinclude_paths);
    print_dirs("libraries", s->library_paths, s->nb_library_paths);
#ifndef TCC_TARGET_PE
    print_dirs("crt", s->crt_paths, s->nb_crt_paths);
    printf("libtcc1:\n  %s/"TCC_LIBTCC1"\n", s->tcc_lib_path);
    printf("elfinterp:\n  %s\n",  DEFAULT_ELFINTERP(s));
#endif
}

static void set_environment(TCCState *s)
{
    char * path;

    path = getenv("C_INCLUDE_PATH");
    if(path != NULL) {
        tcc_add_include_path(s, path);
    }
    path = getenv("CPATH");
    if(path != NULL) {
        tcc_add_include_path(s, path);
    }
    path = getenv("LIBRARY_PATH");
    if(path != NULL) {
        tcc_add_library_path(s, path);
    }
}

static char *default_outputfile(TCCState *s, const char *first_file)
{
    char buf[1024];
    char *ext;
    const char *name = "a";

    if (first_file && strcmp(first_file, "-"))
        name = tcc_basename(first_file);
    snprintf(buf, sizeof(buf), "%s", name);
    ext = tcc_fileextension(buf);
#ifdef TCC_TARGET_PE
    if (s->output_type == TCC_OUTPUT_DLL)
        strcpy(ext, ".dll");
    else
    if (s->output_type == TCC_OUTPUT_EXE)
        strcpy(ext, ".exe");
    else
#endif
    if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r && *ext)
        strcpy(ext, ".o");
    else
        strcpy(buf, "a.out");
    return tcc_strdup(buf);
}

static unsigned getclock_ms(void)
{
#ifdef _WIN32
    return GetTickCount();
#else
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return tv.tv_sec*1000 + (tv.tv_usec+500)/1000;
#endif
}

int main(int argc, char **argv)
{
    TCCState *s;
    int ret, opt, n = 0;
    unsigned start_time = 0;
    const char *first_file;

redo:
    s = tcc_new();
    opt = tcc_parse_args(s, &argc, &argv, 1);

    if (n == 0) {
        if (opt == OPT_HELP)
            return printf(help), 1;
        if (opt == OPT_HELP2)
            return printf(help2), 1;
        if (opt == OPT_M32 || opt == OPT_M64)
            tcc_tool_cross(s, argv, opt); /* never returns */
        if (s->verbose)
            printf(version);
        if (opt == OPT_AR)
            return tcc_tool_ar(s, argc, argv);
#ifdef TCC_TARGET_PE
        if (opt == OPT_IMPDEF)
            return tcc_tool_impdef(s, argc, argv);
#endif
        if (opt == OPT_V)
            return 0;
        if (opt == OPT_PRINT_DIRS) {
            /* initialize search dirs */
            tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
            print_search_dirs(s);
            return 0;
        }

        n = s->nb_files;
        if (n == 0)
            tcc_error("no input files\n");

        if (s->output_type == TCC_OUTPUT_PREPROCESS) {
            if (!s->outfile) {
                s->ppfp = stdout;
            } else {
                s->ppfp = fopen(s->outfile, "w");
                if (!s->ppfp)
                    tcc_error("could not write '%s'", s->outfile);
            }
        } else if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) {
            if (s->nb_libraries)
                tcc_error("cannot specify libraries with -c");
            if (n > 1 && s->outfile)
                tcc_error("cannot specify output file with -c many files");
        } else {
            if (s->option_pthread)
                tcc_set_options(s, "-lpthread");
        }

        if (s->do_bench)
            start_time = getclock_ms();
    }

    set_environment(s);
    if (s->output_type == 0)
        s->output_type = TCC_OUTPUT_EXE;
    tcc_set_output_type(s, s->output_type);

    /* compile or add each files or library */
    for (first_file = NULL, ret = 0;;) {
        struct filespec *f = s->files[s->nb_files - n];
        s->filetype = f->type;
        s->alacarte_link = f->alacarte;
        if (f->type == AFF_TYPE_LIB) {
            if (tcc_add_library_err(s, f->name) < 0)
                ret = 1;
        } else {
            if (1 == s->verbose)
                printf("-> %s\n", f->name);
            if (!first_file)
                first_file = f->name;
            if (tcc_add_file(s, f->name) < 0)
                ret = 1;
        }
        s->filetype = 0;
        s->alacarte_link = 1;
        if (ret || --n == 0
            || (s->output_type == TCC_OUTPUT_OBJ && !s->option_r))
            break;
    }

    if (s->output_type == TCC_OUTPUT_PREPROCESS) {
        if (s->outfile)
            fclose(s->ppfp);
    } else if (0 == ret) {
        if (s->output_type == TCC_OUTPUT_MEMORY) {
#ifdef TCC_IS_NATIVE
            ret = tcc_run(s, argc, argv);
#endif
        } else {
            if (!s->outfile)
                s->outfile = default_outputfile(s, first_file);
            if (tcc_output_file(s, s->outfile))
                ret = 1;
            else if (s->gen_deps)
                gen_makedeps(s, s->outfile, s->deps_outfile);
        }
    }

    if (s->do_bench && ret == 0 && n == 0)
        tcc_print_stats(s, getclock_ms() - start_time);
    tcc_delete(s);
    if (ret == 0 && n)
        goto redo; /* compile more files with -c */
    return ret;
}

https://gitlab.com/janneke/tinycc/-/blob/ff2210b308321f27ee07476d07f24b5095602b17/libtcc.c

File: ../git/live-bootstrap/sysa/tcc-0.9.26/build/tcc-0.9.26-1136-g5bba73cc/libtcc.c used in: Step 378, Step 395, Step 407, Step 419, Step 431, Step 443, Step 455
/*
 *  TCC - Tiny C Compiler
 *
 *  Copyright (c) 2001-2004 Fabrice Bellard
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef _TCC_H
#include "tcc.h"
#endif

/********************************************************/
/* global variables */

/* use GNU C extensions */
ST_DATA int gnu_ext = 1;

/* use TinyCC extensions */
ST_DATA int tcc_ext = 1;

/* XXX: get rid of this ASAP */
ST_DATA struct TCCState *tcc_state;

static int nb_states;

/********************************************************/

#ifdef ONE_SOURCE
#include "tccpp.c"
#include "tccgen.c"
#include "tccelf.c"
#include "tccrun.c"
#ifdef TCC_TARGET_I386
#include "i386-gen.c"
#include "i386-link.c"
#include "i386-asm.c"
#endif
#ifdef TCC_TARGET_ARM
#include "arm-gen.c"
#include "arm-link.c"
#include "arm-asm.c"
#endif
#ifdef TCC_TARGET_ARM64
#include "arm64-gen.c"
#include "arm64-link.c"
#endif
#ifdef TCC_TARGET_C67
#include "c67-gen.c"
#include "c67-link.c"
#endif
#ifdef TCC_TARGET_X86_64
#include "x86_64-gen.c"
#include "x86_64-link.c"
#include "i386-asm.c"
#endif
#ifdef CONFIG_TCC_ASM
#include "tccasm.c"
#endif
#ifdef TCC_TARGET_COFF
#include "tcccoff.c"
#endif
#ifdef TCC_TARGET_PE
#include "tccpe.c"
#endif
#endif /* ONE_SOURCE */

/********************************************************/
#ifndef CONFIG_TCC_ASM
ST_FUNC void asm_instr(void)
{
    tcc_error("inline asm() not supported");
}
ST_FUNC void asm_global_instr(void)
{
    tcc_error("inline asm() not supported");
}
#endif

/********************************************************/
#ifdef _WIN32
ST_FUNC char *normalize_slashes(char *path)
{
    char *p;
    for (p = path; *p; ++p)
        if (*p == '\\')
            *p = '/';
    return path;
}

static HMODULE tcc_module;

/* on win32, we suppose the lib and includes are at the location of 'tcc.exe' */
static void tcc_set_lib_path_w32(TCCState *s)
{
    char path[1024], *p;
    GetModuleFileNameA(tcc_module, path, sizeof path);
    p = tcc_basename(normalize_slashes(strlwr(path)));
    if (p - 5 > path && 0 == strncmp(p - 5, "/bin/", 5))
        p -= 5;
    else if (p > path)
        p--;
    *p = 0;
    tcc_set_lib_path(s, path);
}

#ifdef TCC_TARGET_PE
static void tcc_add_systemdir(TCCState *s)
{
    char buf[1000];
    GetSystemDirectory(buf, sizeof buf);
    tcc_add_library_path(s, normalize_slashes(buf));
}
#endif

#ifdef LIBTCC_AS_DLL
BOOL WINAPI DllMain (HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved)
{
    if (DLL_PROCESS_ATTACH == dwReason)
        tcc_module = hDll;
    return TRUE;
}
#endif
#endif

/********************************************************/
/* copy a string and truncate it. */
ST_FUNC char *pstrcpy(char *buf, int buf_size, const char *s)
{
    char *q, *q_end;
    int c;

    if (buf_size > 0) {
        q = buf;
        q_end = buf + buf_size - 1;
        while (q < q_end) {
            c = *s++;
            if (c == '\0')
                break;
            *q++ = c;
        }
        *q = '\0';
    }
    return buf;
}

/* strcat and truncate. */
ST_FUNC char *pstrcat(char *buf, int buf_size, const char *s)
{
    int len;
    len = strlen(buf);
    if (len < buf_size)
        pstrcpy(buf + len, buf_size - len, s);
    return buf;
}

ST_FUNC char *pstrncpy(char *out, const char *in, size_t num)
{
    memcpy(out, in, num);
    out[num] = '\0';
    return out;
}

/* extract the basename of a file */
PUB_FUNC char *tcc_basename(const char *name)
{
    char *p = strchr(name, 0);
    while (p > name && !IS_DIRSEP(p[-1]))
        --p;
    return p;
}

/* extract extension part of a file
 *
 * (if no extension, return pointer to end-of-string)
 */
PUB_FUNC char *tcc_fileextension (const char *name)
{
    char *b = tcc_basename(name);
    char *e = strrchr(b, '.');
    return e ? e : strchr(b, 0);
}

/********************************************************/
/* memory management */

#undef free
#undef malloc
#undef realloc

#ifndef MEM_DEBUG

PUB_FUNC void tcc_free(void *ptr)
{
    free(ptr);
}

PUB_FUNC void *tcc_malloc(unsigned long size)
{
    void *ptr;
    ptr = malloc(size);
    if (!ptr && size)
        tcc_error("memory full (malloc)");
    return ptr;
}

PUB_FUNC void *tcc_mallocz(unsigned long size)
{
    void *ptr;
    ptr = tcc_malloc(size);
    memset(ptr, 0, size);
    return ptr;
}

PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size)
{
    void *ptr1;
    ptr1 = realloc(ptr, size);
    if (!ptr1 && size)
        tcc_error("memory full (realloc)");
    return ptr1;
}

PUB_FUNC char *tcc_strdup(const char *str)
{
    char *ptr;
    ptr = tcc_malloc(strlen(str) + 1);
    strcpy(ptr, str);
    return ptr;
}

PUB_FUNC void tcc_memcheck(void)
{
}

#else

#define MEM_DEBUG_MAGIC1 0xFEEDDEB1
#define MEM_DEBUG_MAGIC2 0xFEEDDEB2
#define MEM_DEBUG_MAGIC3 0xFEEDDEB3
#define MEM_DEBUG_FILE_LEN 40
#define MEM_DEBUG_CHECK3(header) \
    ((mem_debug_header_t*)((char*)header + header->size))->magic3
#define MEM_USER_PTR(header) \
    ((char *)header + offsetof(mem_debug_header_t, magic3))
#define MEM_HEADER_PTR(ptr) \
    (mem_debug_header_t *)((char*)ptr - offsetof(mem_debug_header_t, magic3))

struct mem_debug_header {
    unsigned magic1;
    unsigned size;
    struct mem_debug_header *prev;
    struct mem_debug_header *next;
    int line_num;
    char file_name[MEM_DEBUG_FILE_LEN + 1];
    unsigned magic2;
    __attribute__((aligned(16))) unsigned magic3;
};

typedef struct mem_debug_header mem_debug_header_t;

static mem_debug_header_t *mem_debug_chain;
static unsigned mem_cur_size;
static unsigned mem_max_size;

static mem_debug_header_t *malloc_check(void *ptr, const char *msg)
{
    mem_debug_header_t * header = MEM_HEADER_PTR(ptr);
    if (header->magic1 != MEM_DEBUG_MAGIC1 ||
        header->magic2 != MEM_DEBUG_MAGIC2 ||
        MEM_DEBUG_CHECK3(header) != MEM_DEBUG_MAGIC3 ||
        header->size == (unsigned)-1) {
        fprintf(stderr, "%s check failed\n", msg);
        if (header->magic1 == MEM_DEBUG_MAGIC1)
            fprintf(stderr, "%s:%u: block allocated here.\n",
                header->file_name, header->line_num);
        exit(1);
    }
    return header;
}

PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line)
{
    int ofs;
    mem_debug_header_t *header;

    header = malloc(sizeof(mem_debug_header_t) + size);
    if (!header)
        tcc_error("memory full (malloc)");

    header->magic1 = MEM_DEBUG_MAGIC1;
    header->magic2 = MEM_DEBUG_MAGIC2;
    header->size = size;
    MEM_DEBUG_CHECK3(header) = MEM_DEBUG_MAGIC3;
    header->line_num = line;
    ofs = strlen(file) - MEM_DEBUG_FILE_LEN;
    strncpy(header->file_name, file + (ofs > 0 ? ofs : 0), MEM_DEBUG_FILE_LEN);
    header->file_name[MEM_DEBUG_FILE_LEN] = 0;

    header->next = mem_debug_chain;
    header->prev = NULL;
    if (header->next)
        header->next->prev = header;
    mem_debug_chain = header;

    mem_cur_size += size;
    if (mem_cur_size > mem_max_size)
        mem_max_size = mem_cur_size;

    return MEM_USER_PTR(header);
}

PUB_FUNC void tcc_free_debug(void *ptr)
{
    mem_debug_header_t *header;
    if (!ptr)
        return;
    header = malloc_check(ptr, "tcc_free");
    mem_cur_size -= header->size;
    header->size = (unsigned)-1;
    if (header->next)
        header->next->prev = header->prev;
    if (header->prev)
        header->prev->next = header->next;
    if (header == mem_debug_chain)
        mem_debug_chain = header->next;
    free(header);
}

PUB_FUNC void *tcc_mallocz_debug(unsigned long size, const char *file, int line)
{
    void *ptr;
    ptr = tcc_malloc_debug(size,file,line);
    memset(ptr, 0, size);
    return ptr;
}

PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file, int line)
{
    mem_debug_header_t *header;
    int mem_debug_chain_update = 0;
    if (!ptr)
        return tcc_malloc_debug(size, file, line);
    header = malloc_check(ptr, "tcc_realloc");
    mem_cur_size -= header->size;
    mem_debug_chain_update = (header == mem_debug_chain);
    header = realloc(header, sizeof(mem_debug_header_t) + size);
    if (!header)
        tcc_error("memory full (realloc)");
    header->size = size;
    MEM_DEBUG_CHECK3(header) = MEM_DEBUG_MAGIC3;
    if (header->next)
        header->next->prev = header;
    if (header->prev)
        header->prev->next = header;
    if (mem_debug_chain_update)
        mem_debug_chain = header;
    mem_cur_size += size;
    if (mem_cur_size > mem_max_size)
        mem_max_size = mem_cur_size;
    return MEM_USER_PTR(header);
}

PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line)
{
    char *ptr;
    ptr = tcc_malloc_debug(strlen(str) + 1, file, line);
    strcpy(ptr, str);
    return ptr;
}

PUB_FUNC void tcc_memcheck(void)
{
    if (mem_cur_size) {
        mem_debug_header_t *header = mem_debug_chain;
        fprintf(stderr, "MEM_DEBUG: mem_leak= %d bytes, mem_max_size= %d bytes\n",
            mem_cur_size, mem_max_size);
        while (header) {
            fprintf(stderr, "%s:%u: error: %u bytes leaked\n",
                header->file_name, header->line_num, header->size);
            header = header->next;
        }
#if MEM_DEBUG-0 == 2
        exit(2);
#endif
    }
}
#endif /* MEM_DEBUG */

#define free(p) use_tcc_free(p)
#define malloc(s) use_tcc_malloc(s)
#define realloc(p, s) use_tcc_realloc(p, s)

/********************************************************/
/* dynarrays */

ST_FUNC void dynarray_add(void *ptab, int *nb_ptr, void *data)
{
    int nb, nb_alloc;
    void **pp;

    nb = *nb_ptr;
    pp = *(void ***)ptab;
    /* every power of two we double array size */
    if ((nb & (nb - 1)) == 0) {
        if (!nb)
            nb_alloc = 1;
        else
            nb_alloc = nb * 2;
        pp = tcc_realloc(pp, nb_alloc * sizeof(void *));
        *(void***)ptab = pp;
    }
    pp[nb++] = data;
    *nb_ptr = nb;
}

ST_FUNC void dynarray_reset(void *pp, int *n)
{
    void **p;
    for (p = *(void***)pp; *n; ++p, --*n)
        if (*p)
            tcc_free(*p);
    tcc_free(*(void**)pp);
    *(void**)pp = NULL;
}

static void tcc_split_path(TCCState *s, void *p_ary, int *p_nb_ary, const char *in)
{
    const char *p;
    do {
        int c;
        CString str;

        cstr_new(&str);
        for (p = in; c = *p, c != '\0' && c != PATHSEP; ++p) {
            if (c == '{' && p[1] && p[2] == '}') {
                c = p[1], p += 2;
                if (c == 'B')
                    cstr_cat(&str, s->tcc_lib_path, -1);
            } else {
                cstr_ccat(&str, c);
            }
        }
        if (str.size) {
            cstr_ccat(&str, '\0');
            dynarray_add(p_ary, p_nb_ary, tcc_strdup(str.data));
        }
        cstr_free(&str);
        in = p+1;
    } while (*p);
}

/********************************************************/

static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap)
{
    int len;
    len = strlen(buf);
    vsnprintf(buf + len, buf_size - len, fmt, ap);
}

static void strcat_printf(char *buf, int buf_size, const char *fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    strcat_vprintf(buf, buf_size, fmt, ap);
    va_end(ap);
}

static void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
{
    char buf[2048];
    BufferedFile **pf, *f;

    buf[0] = '\0';
    /* use upper file if inline ":asm:" or token ":paste:" */
    for (f = file; f && f->filename[0] == ':'; f = f->prev)
     ;
    if (f) {
        for(pf = s1->include_stack; pf < s1->include_stack_ptr; pf++)
            strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n",
                (*pf)->filename, (*pf)->line_num);
        if (f->line_num > 0) {
            strcat_printf(buf, sizeof(buf), "%s:%d: ",
                f->filename, f->line_num - !!(tok_flags & TOK_FLAG_BOL));
        } else {
            strcat_printf(buf, sizeof(buf), "%s: ",
                f->filename);
        }
    } else {
        strcat_printf(buf, sizeof(buf), "tcc: ");
    }
    if (is_warning)
        strcat_printf(buf, sizeof(buf), "warning: ");
    else
        strcat_printf(buf, sizeof(buf), "error: ");
    strcat_vprintf(buf, sizeof(buf), fmt, ap);

    if (!s1->error_func) {
        /* default case: stderr */
        if (s1->ppfp) /* print a newline during tcc -E */
            fprintf(s1->ppfp, "\n"), fflush(s1->ppfp);
        fflush(stdout); /* flush -v output */
        fprintf(stderr, "%s\n", buf);
        fflush(stderr); /* print error/warning now (win32) */
    } else {
        s1->error_func(s1->error_opaque, buf);
    }
    if (!is_warning || s1->warn_error)
        s1->nb_errors++;
}

LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque,
                        void (*error_func)(void *opaque, const char *msg))
{
    s->error_opaque = error_opaque;
    s->error_func = error_func;
}

/* error without aborting current compilation */
PUB_FUNC void tcc_error_noabort(const char *fmt, ...)
{
    TCCState *s1 = tcc_state;
    va_list ap;

    va_start(ap, fmt);
    error1(s1, 0, fmt, ap);
    va_end(ap);
}

PUB_FUNC void tcc_error(const char *fmt, ...)
{
    TCCState *s1 = tcc_state;
    va_list ap;

    va_start(ap, fmt);
    error1(s1, 0, fmt, ap);
    va_end(ap);
    /* better than nothing: in some cases, we accept to handle errors */
    if (s1->error_set_jmp_enabled) {
        longjmp(s1->error_jmp_buf, 1);
    } else {
        /* XXX: eliminate this someday */
        exit(1);
    }
}

PUB_FUNC void tcc_warning(const char *fmt, ...)
{
    TCCState *s1 = tcc_state;
    va_list ap;

    if (s1->warn_none)
        return;

    va_start(ap, fmt);
    error1(s1, 1, fmt, ap);
    va_end(ap);
}

/********************************************************/
/* I/O layer */

ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen)
{
    BufferedFile *bf;
    int buflen = initlen ? initlen : IO_BUF_SIZE;

    bf = tcc_mallocz(sizeof(BufferedFile) + buflen);
    bf->buf_ptr = bf->buffer;
    bf->buf_end = bf->buffer + initlen;
    bf->buf_end[0] = CH_EOB; /* put eob symbol */
    pstrcpy(bf->filename, sizeof(bf->filename), filename);
    pstrcpy(bf->filename2, sizeof(bf->filename2), filename);
#ifdef _WIN32
    normalize_slashes(bf->filename);
#endif
    bf->line_num = 1;
    bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
    bf->fd = -1;
    bf->prev = file;
    file = bf;
}

ST_FUNC void tcc_close(void)
{
    BufferedFile *bf = file;
    if (bf->fd > 0) {
        close(bf->fd);
        total_lines += bf->line_num;
    }
    file = bf->prev;
    tcc_free(bf);
}

ST_FUNC int tcc_open(TCCState *s1, const char *filename)
{
    int fd;
    if (strcmp(filename, "-") == 0)
        fd = 0, filename = "<stdin>";
    else
        fd = open(filename, O_RDONLY | O_BINARY);
    if ((s1->verbose == 2 && fd >= 0) || s1->verbose == 3)
        printf("%s %*s%s\n", fd < 0 ? "nf":"->",
               (int)(s1->include_stack_ptr - s1->include_stack), "", filename);
    if (fd < 0)
        return -1;

    tcc_open_bf(s1, filename, 0);
    file->fd = fd;
    return fd;
}

/* compile the C file opened in 'file'. Return non zero if errors. */
static int tcc_compile(TCCState *s1)
{
    Sym *define_start;

    define_start = define_stack;
#if HAVE_SETJMP
    if (setjmp(s1->error_jmp_buf) == 0) {
#else
    if (1) {
#endif
        s1->nb_errors = 0;
        s1->error_set_jmp_enabled = 1;

        preprocess_start(s1);
        tccgen_start(s1);

#ifdef INC_DEBUG
        printf("%s: **** new file\n", file->filename);
#endif

        ch = file->buf_ptr[0];
        tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
        parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_TOK_STR;
        next();
        decl(VT_CONST);
        if (tok != TOK_EOF)
            expect("declaration");
        /* free defines here already on behalf of of M.M.'s possibly existing
           experimental preprocessor implementation. The normal call below
           is still there to free after error-longjmp */
        free_defines(define_start);
        tccgen_end(s1);
    }
    s1->error_set_jmp_enabled = 0;

    free_inline_functions(s1);
    /* reset define stack, but keep -D and built-ins */
    free_defines(define_start);
    sym_pop(&global_stack, NULL, 0);
    sym_pop(&local_stack, NULL, 0);
    return s1->nb_errors != 0 ? -1 : 0;
}

LIBTCCAPI int tcc_compile_string(TCCState *s, const char *str)
{
    int len, ret;

    len = strlen(str);
    tcc_open_bf(s, "<string>", len);
    memcpy(file->buffer, str, len);
    ret = tcc_compile(s);
    tcc_close();
    return ret;
}

/* define a preprocessor symbol. A value can also be provided with the '=' operator */
LIBTCCAPI void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
{
    int len1, len2;
    /* default value */
    if (!value)
        value = "1";
    len1 = strlen(sym);
    len2 = strlen(value);

    /* init file structure */
    tcc_open_bf(s1, "<define>", len1 + len2 + 1);
    memcpy(file->buffer, sym, len1);
    file->buffer[len1] = ' ';
    memcpy(file->buffer + len1 + 1, value, len2);

    /* parse with define parser */
    ch = file->buf_ptr[0];
    next_nomacro();
    parse_define();

    tcc_close();
}

/* undefine a preprocessor symbol */
LIBTCCAPI void tcc_undefine_symbol(TCCState *s1, const char *sym)
{
    TokenSym *ts;
    Sym *s;
    ts = tok_alloc(sym, strlen(sym));
    s = define_find(ts->tok);
    /* undefine symbol by putting an invalid name */
    if (s)
        define_undef(s);
}

/* cleanup all static data used during compilation */
static void tcc_cleanup(void)
{
    if (NULL == tcc_state)
        return;
    tccpp_delete(tcc_state);
    tcc_state = NULL;
    /* free sym_pools */
    dynarray_reset(&sym_pools, &nb_sym_pools);
    /* reset symbol stack */
    sym_free_first = NULL;
}

LIBTCCAPI TCCState *tcc_new(void)
{
    TCCState *s;

    tcc_cleanup();

    s = tcc_mallocz(sizeof(TCCState));
    if (!s)
        return NULL;
    tcc_state = s;
    ++nb_states;

#if BOOTSTRAP
    s->static_link = 1;
#endif
    s->alacarte_link = 1;
    s->nocommon = 1;
    s->warn_implicit_function_declaration = 1;

#ifdef CHAR_IS_UNSIGNED
    s->char_is_unsigned = 1;
#endif
#ifdef TCC_TARGET_I386
    s->seg_size = 32;
#endif
    /* enable this if you want symbols with leading underscore on windows: */
#if 0 /* def TCC_TARGET_PE */
    s->leading_underscore = 1;
#endif
#ifdef _WIN32
    tcc_set_lib_path_w32(s);
#else
    tcc_set_lib_path(s, CONFIG_TCCDIR);
#endif
    tccelf_new(s);
    tccpp_new(s);

    /* we add dummy defines for some special macros to speed up tests
       and to have working defined() */
    define_push(TOK___LINE__, MACRO_OBJ, NULL, NULL);
    define_push(TOK___FILE__, MACRO_OBJ, NULL, NULL);
    define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL);
    define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL);
    {
        /* define __TINYC__ 92X  */
        char buffer[32]; int a,b,c;
        sscanf(TCC_VERSION, "%d.%d.%d", &a, &b, &c);
        sprintf(buffer, "%d", a*10000 + b*100 + c);
        tcc_define_symbol(s, "__TINYC__", buffer);
    }

    /* standard defines */
    tcc_define_symbol(s, "__STDC__", NULL);
    tcc_define_symbol(s, "__STDC_VERSION__", "199901L");
    tcc_define_symbol(s, "__STDC_HOSTED__", NULL);

    tcc_define_symbol(s, "__SIZEOF_LONG_LONG__", "8");

    /* target defines */
#if defined(TCC_TARGET_I386)
    tcc_define_symbol(s, "__i386__", NULL);
    tcc_define_symbol(s, "__i386", NULL);
    tcc_define_symbol(s, "i386", NULL);
#elif defined(TCC_TARGET_X86_64)
    tcc_define_symbol(s, "__x86_64__", NULL);
#elif defined(TCC_TARGET_ARM)
    tcc_define_symbol(s, "__ARM_ARCH_4__", NULL);
    tcc_define_symbol(s, "__arm_elf__", NULL);
    tcc_define_symbol(s, "__arm_elf", NULL);
    tcc_define_symbol(s, "arm_elf", NULL);
    tcc_define_symbol(s, "__arm__", NULL);
    tcc_define_symbol(s, "__arm", NULL);
    tcc_define_symbol(s, "arm", NULL);
    tcc_define_symbol(s, "__APCS_32__", NULL);
    tcc_define_symbol(s, "__ARMEL__", NULL);
#if defined(TCC_ARM_EABI)
    tcc_define_symbol(s, "__ARM_EABI__", NULL);
#endif
#if defined(TCC_ARM_HARDFLOAT)
    s->float_abi = ARM_HARD_FLOAT;
    tcc_define_symbol(s, "__ARM_PCS_VFP", NULL);
#else
    s->float_abi = ARM_SOFTFP_FLOAT;
#endif
#elif defined(TCC_TARGET_ARM64)
    tcc_define_symbol(s, "__aarch64__", NULL);
#endif

#ifdef TCC_TARGET_PE
    tcc_define_symbol(s, "_WIN32", NULL);
# ifdef TCC_TARGET_X86_64
    tcc_define_symbol(s, "_WIN64", NULL);
# endif
#else
    tcc_define_symbol(s, "__unix__", NULL);
    tcc_define_symbol(s, "__unix", NULL);
    tcc_define_symbol(s, "unix", NULL);
# if defined(__linux__)
    tcc_define_symbol(s, "__linux__", NULL);
    tcc_define_symbol(s, "__linux", NULL);
# endif
# if defined(__FreeBSD__)
    tcc_define_symbol(s, "__FreeBSD__", "__FreeBSD__");
    /* No 'Thread Storage Local' on FreeBSD with tcc */
    tcc_define_symbol(s, "__NO_TLS", NULL);
# endif
# if defined(__FreeBSD_kernel__)
    tcc_define_symbol(s, "__FreeBSD_kernel__", NULL);
# endif
#endif
# if defined(__NetBSD__)
    tcc_define_symbol(s, "__NetBSD__", "__NetBSD__");
# endif
# if defined(__OpenBSD__)
    tcc_define_symbol(s, "__OpenBSD__", "__OpenBSD__");
# endif

    /* TinyCC & gcc defines */
#if defined(TCC_TARGET_PE) && PTR_SIZE == 8
    /* 64bit Windows. */
    tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned long long");
    tcc_define_symbol(s, "__PTRDIFF_TYPE__", "long long");
    tcc_define_symbol(s, "__LLP64__", NULL);
#elif PTR_SIZE == 8
    /* Other 64bit systems. */
    tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned long");
    tcc_define_symbol(s, "__PTRDIFF_TYPE__", "long");
    tcc_define_symbol(s, "__LP64__", NULL);
#else
    /* Other 32bit systems. */
    tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned long");
    tcc_define_symbol(s, "__PTRDIFF_TYPE__", "long");
    tcc_define_symbol(s, "__ILP32__", NULL);
#endif

#if defined(TCC_MUSL)
    tcc_define_symbol(s, "__builtin_va_list", "void *");
#endif /* TCC_MUSL */

#ifdef TCC_TARGET_PE
    tcc_define_symbol(s, "__WCHAR_TYPE__", "unsigned short");
    tcc_define_symbol(s, "__WINT_TYPE__", "unsigned short");
#else
    tcc_define_symbol(s, "__WCHAR_TYPE__", "int");
    /* wint_t is unsigned int by default, but (signed) int on BSDs
       and unsigned short on windows.  Other OSes might have still
       other conventions, sigh.  */
# if defined(__FreeBSD__) || defined (__FreeBSD_kernel__) \
  || defined(__NetBSD__) || defined(__OpenBSD__)
    tcc_define_symbol(s, "__WINT_TYPE__", "int");
#  ifdef __FreeBSD__
    /* define __GNUC__ to have some useful stuff from sys/cdefs.h
       that are unconditionally used in FreeBSDs other system headers :/ */
    tcc_define_symbol(s, "__GNUC__", "2");
    tcc_define_symbol(s, "__GNUC_MINOR__", "7");
    tcc_define_symbol(s, "__builtin_alloca", "alloca");
#  endif
# else
    tcc_define_symbol(s, "__WINT_TYPE__", "unsigned int");
    /* glibc defines */
    tcc_define_symbol(s, "__REDIRECT(name, proto, alias)",
        "name proto __asm__ (#alias)");
    tcc_define_symbol(s, "__REDIRECT_NTH(name, proto, alias)",
        "name proto __asm__ (#alias) __THROW");
# endif
    /* Some GCC builtins that are simple to express as macros.  */
    tcc_define_symbol(s, "__builtin_extract_return_addr(x)", "x");
#endif /* ndef TCC_TARGET_PE */
    return s;
}

LIBTCCAPI void tcc_delete(TCCState *s1)
{
    tcc_cleanup();

    /* free sections */
    tccelf_delete(s1);

    /* free library paths */
    dynarray_reset(&s1->library_paths, &s1->nb_library_paths);
    dynarray_reset(&s1->crt_paths, &s1->nb_crt_paths);

    /* free include paths */
    dynarray_reset(&s1->cached_includes, &s1->nb_cached_includes);
    dynarray_reset(&s1->include_paths, &s1->nb_include_paths);
    dynarray_reset(&s1->sysinclude_paths, &s1->nb_sysinclude_paths);
    dynarray_reset(&s1->cmd_include_files, &s1->nb_cmd_include_files);

    tcc_free(s1->tcc_lib_path);
    tcc_free(s1->soname);
    tcc_free(s1->rpath);
    tcc_free(s1->init_symbol);
    tcc_free(s1->fini_symbol);
    tcc_free(s1->outfile);
    tcc_free(s1->deps_outfile);
    dynarray_reset(&s1->files, &s1->nb_files);
    dynarray_reset(&s1->target_deps, &s1->nb_target_deps);
    dynarray_reset(&s1->pragma_libs, &s1->nb_pragma_libs);
    dynarray_reset(&s1->argv, &s1->argc);

#ifdef TCC_IS_NATIVE
    /* free runtime memory */
    tcc_run_free(s1);
#endif

    tcc_free(s1);
    if (0 == --nb_states)
        tcc_memcheck();
}

LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
{
    s->output_type = output_type;

    /* always elf for objects */
    if (output_type == TCC_OUTPUT_OBJ)
        s->output_format = TCC_OUTPUT_FORMAT_ELF;

    if (s->char_is_unsigned)
        tcc_define_symbol(s, "__CHAR_UNSIGNED__", NULL);

    if (!s->nostdinc) {
        /* default include paths */
        /* -isystem paths have already been handled */
        tcc_add_sysinclude_path(s, CONFIG_TCC_SYSINCLUDEPATHS);
    }

#ifdef CONFIG_TCC_BCHECK
    if (s->do_bounds_check) {
        /* if bound checking, then add corresponding sections */
        tccelf_bounds_new(s);
        /* define symbol */
        tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
    }
#endif
    if (s->do_debug) {
        /* add debug sections */
        tccelf_stab_new(s);
    }

    tcc_add_library_path(s, CONFIG_TCC_LIBPATHS);

#ifdef TCC_TARGET_PE
# ifdef _WIN32
    if (!s->nostdlib && output_type != TCC_OUTPUT_OBJ)
        tcc_add_systemdir(s);
# endif
#else
    /* paths for crt objects */
    tcc_split_path(s, &s->crt_paths, &s->nb_crt_paths, CONFIG_TCC_CRTPREFIX);
    /* add libc crt1/crti objects */
    if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) &&
        !s->nostdlib) {
        if (output_type != TCC_OUTPUT_DLL)
            tcc_add_crt(s, "crt1.o");
        tcc_add_crt(s, "crti.o");
    }
#endif
    return 0;
}

LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname)
{
    tcc_split_path(s, &s->include_paths, &s->nb_include_paths, pathname);
    return 0;
}

LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname)
{
    tcc_split_path(s, &s->sysinclude_paths, &s->nb_sysinclude_paths, pathname);
    return 0;
}

ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
{
    int ret, filetype;

    filetype = flags & 0x0F;
    if (filetype == 0) {
        /* use a file extension to detect a filetype */
        const char *ext = tcc_fileextension(filename);
        if (ext[0]) {
            ext++;
            if (!strcmp(ext, "S"))
                filetype = AFF_TYPE_ASMPP;
            else if (!strcmp(ext, "s"))
                filetype = AFF_TYPE_ASM;
            else if (!PATHCMP(ext, "c") || !PATHCMP(ext, "i"))
                filetype = AFF_TYPE_C;
            else
                filetype = AFF_TYPE_BIN;
        } else {
            filetype = AFF_TYPE_C;
        }
    }

    /* open the file */
    ret = tcc_open(s1, filename);
    if (ret < 0) {
        if (flags & AFF_PRINT_ERROR)
            tcc_error_noabort("file '%s' not found", filename);
        return ret;
    }

    /* update target deps */
    dynarray_add(&s1->target_deps, &s1->nb_target_deps,
            tcc_strdup(filename));

    parse_flags = 0;
    /* if .S file, define __ASSEMBLER__ like gcc does */
    if (filetype == AFF_TYPE_ASM || filetype == AFF_TYPE_ASMPP) {
        tcc_define_symbol(s1, "__ASSEMBLER__", NULL);
        parse_flags = PARSE_FLAG_ASM_FILE;
    }

    if (flags & AFF_PREPROCESS) {
        ret = tcc_preprocess(s1);
    } else if (filetype == AFF_TYPE_C) {
        ret = tcc_compile(s1);
#ifdef CONFIG_TCC_ASM
    } else if (filetype == AFF_TYPE_ASMPP) {
        /* non preprocessed assembler */
        ret = tcc_assemble(s1, 1);
    } else if (filetype == AFF_TYPE_ASM) {
        /* preprocessed assembler */
        ret = tcc_assemble(s1, 0);
#endif
    } else {
        ElfW(Ehdr) ehdr;
        int fd, obj_type;

        fd = file->fd;
        obj_type = tcc_object_type(fd, &ehdr);
        lseek(fd, 0, SEEK_SET);

        /* do not display line number if error */
        file->line_num = 0;

#ifdef TCC_TARGET_MACHO
        if (0 == obj_type && 0 == strcmp(tcc_fileextension(filename), "dylib"))
            obj_type = AFF_BINTYPE_DYN;
#endif

        switch (obj_type) {
        case AFF_BINTYPE_REL:
            ret = tcc_load_object_file(s1, fd, 0);
            break;
#ifndef TCC_TARGET_PE
        case AFF_BINTYPE_DYN:
            if (s1->output_type == TCC_OUTPUT_MEMORY) {
                ret = 0;
#ifdef TCC_IS_NATIVE
                if (NULL == dlopen(filename, RTLD_GLOBAL | RTLD_LAZY))
                    ret = -1;
#endif
            } else {
                ret = tcc_load_dll(s1, fd, filename,
                                   (flags & AFF_REFERENCED_DLL) != 0);
            }
            break;
#endif
        case AFF_BINTYPE_AR:
            ret = tcc_load_archive(s1, fd);
            break;
#ifdef TCC_TARGET_COFF
        case AFF_BINTYPE_C67:
            ret = tcc_load_coff(s1, fd);
            break;
#endif
        default:
#ifdef TCC_TARGET_PE
            ret = pe_load_file(s1, filename, fd);
#else
            /* as GNU ld, consider it is an ld script if not recognized */
            ret = tcc_load_ldscript(s1);
#endif
            if (ret < 0)
                tcc_error_noabort("unrecognized file type");
            break;
        }
    }
    tcc_close();
    return ret;
}

LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename)
{
    if (s->output_type == TCC_OUTPUT_PREPROCESS)
        return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR | AFF_PREPROCESS | s->filetype);
    else
        return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR | s->filetype);
}

LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname)
{
    tcc_split_path(s, &s->library_paths, &s->nb_library_paths, pathname);
    return 0;
}

static int tcc_add_library_internal(TCCState *s, const char *fmt,
    const char *filename, int flags, char **paths, int nb_paths)
{
    char buf[1024];
    int i;

    for(i = 0; i < nb_paths; i++) {
        snprintf(buf, sizeof(buf), fmt, paths[i], filename);
        if (tcc_add_file_internal(s, buf, flags | AFF_TYPE_BIN) == 0)
            return 0;
    }
    return -1;
}

/* find and load a dll. Return non zero if not found */
/* XXX: add '-rpath' option support ? */
ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags)
{
    return tcc_add_library_internal(s, "%s/%s", filename, flags,
        s->library_paths, s->nb_library_paths);
}

ST_FUNC int tcc_add_crt(TCCState *s, const char *filename)
{
    if (-1 == tcc_add_library_internal(s, "%s/%s",
        filename, 0, s->crt_paths, s->nb_crt_paths))
        tcc_error_noabort("file '%s' not found", filename);
    return 0;
}

/* the library name is the same as the argument of the '-l' option */
LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname)
{
#if defined TCC_TARGET_PE
    const char *libs[] = { "%s/%s.def", "%s/lib%s.def", "%s/%s.dll", "%s/lib%s.dll", "%s/lib%s.a", NULL };
    const char **pp = s->static_link ? libs + 4 : libs;
#elif defined TCC_TARGET_MACHO
    const char *libs[] = { "%s/lib%s.dylib", "%s/lib%s.a", NULL };
    const char **pp = s->static_link ? libs + 1 : libs;
#else
    const char *libs[] = { "%s/lib%s.so", "%s/lib%s.a", NULL };
    const char **pp = s->static_link ? libs + 1 : libs;
#endif
    while (*pp) {
        if (0 == tcc_add_library_internal(s, *pp,
            libraryname, 0, s->library_paths, s->nb_library_paths))
            return 0;
        ++pp;
    }
    return -1;
}

PUB_FUNC int tcc_add_library_err(TCCState *s, const char *libname)
{
    int ret = tcc_add_library(s, libname);
    if (ret < 0)
        tcc_error_noabort("library '%s' not found", libname);
    return ret;
}

/* handle #pragma comment(lib,) */
ST_FUNC void tcc_add_pragma_libs(TCCState *s1)
{
    int i;
    for (i = 0; i < s1->nb_pragma_libs; i++)
        tcc_add_library_err(s1, s1->pragma_libs[i]);
}

LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, const void *val)
{
#ifdef TCC_TARGET_PE
    /* On x86_64 'val' might not be reachable with a 32bit offset.
       So it is handled here as if it were in a DLL. */
    pe_putimport(s, 0, name, (uintptr_t)val);
#else
    set_elf_sym(symtab_section, (uintptr_t)val, 0,
        ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
        SHN_ABS, name);
#endif
    return 0;
}

LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path)
{
    tcc_free(s->tcc_lib_path);
    s->tcc_lib_path = tcc_strdup(path);
}

#define WD_ALL    0x0001 /* warning is activated when using -Wall */
#define FD_INVERT 0x0002 /* invert value before storing */

typedef struct FlagDef {
    uint16_t offset;
    uint16_t flags;
    const char *name;
} FlagDef;

static int no_flag(const char **pp)
{
    const char *p = *pp;
    if (*p != 'n' || *++p != 'o' || *++p != '-')
        return 0;
    *pp = p + 1;
    return 1;
}

ST_FUNC int set_flag(TCCState *s, const FlagDef *flags, const char *name)
{
    int value, ret;
    const FlagDef *p;
    const char *r;

    value = 1;
    r = name;
    if (no_flag(&r))
        value = 0;

    for (ret = -1, p = flags; p->name; ++p) {
        if (ret) {
            if (strcmp(r, p->name))
                continue;
        } else {
            if (0 == (p->flags & WD_ALL))
                continue;
        }
        if (p->offset) {
            *(int*)((char *)s + p->offset) =
                p->flags & FD_INVERT ? !value : value;
            if (ret)
                return 0;
        } else {
            ret = 0;
        }
    }
    return ret;
}

static int strstart(const char *val, const char **str)
{
    const char *p, *q;
    p = *str;
    q = val;
    while (*q) {
        if (*p != *q)
            return 0;
        p++;
        q++;
    }
    *str = p;
    return 1;
}

/* Like strstart, but automatically takes into account that ld options can
 *
 * - start with double or single dash (e.g. '--soname' or '-soname')
 * - arguments can be given as separate or after '=' (e.g. '-Wl,-soname,x.so'
 *   or '-Wl,-soname=x.so')
 *
 * you provide `val` always in 'option[=]' form (no leading -)
 */
static int link_option(const char *str, const char *val, const char **ptr)
{
    const char *p, *q;
    int ret;

    /* there should be 1 or 2 dashes */
    if (*str++ != '-')
        return 0;
    if (*str == '-')
        str++;

    /* then str & val should match (potentially up to '=') */
    p = str;
    q = val;

    ret = 1;
    if (q[0] == '?') {
        ++q;
        if (no_flag(&p))
            ret = -1;
    }

    while (*q != '\0' && *q != '=') {
        if (*p != *q)
            return 0;
        p++;
        q++;
    }

    /* '=' near eos means ',' or '=' is ok */
    if (*q == '=') {
        if (*p == 0)
            *ptr = p;
        if (*p != ',' && *p != '=')
            return 0;
        p++;
    } else if (*p) {
        return 0;
    }
    *ptr = p;
    return ret;
}

static const char *skip_linker_arg(const char **str)
{
    const char *s1 = *str;
    const char *s2 = strchr(s1, ',');
    *str = s2 ? s2++ : (s2 = s1 + strlen(s1));
    return s2;
}

static void copy_linker_arg(char **pp, const char *s, int sep)
{
    const char *q = s;
    char *p = *pp;
    int l = 0;
    if (p && sep)
        p[l = strlen(p)] = sep, ++l;
    skip_linker_arg(&q);
    pstrncpy(l + (*pp = tcc_realloc(p, q - s + l + 1)), s, q - s);
}

/* set linker options */
static int tcc_set_linker(TCCState *s, const char *option)
{
    while (*option) {

        const char *p = NULL;
        char *end = NULL;
        int ignoring = 0;
        int ret;

        if (link_option(option, "Bsymbolic", &p)) {
            s->symbolic = 1;
        } else if (link_option(option, "nostdlib", &p)) {
            s->nostdlib = 1;
        } else if (link_option(option, "fini=", &p)) {
            copy_linker_arg(&s->fini_symbol, p, 0);
            ignoring = 1;
        } else if (link_option(option, "image-base=", &p)
                || link_option(option, "Ttext=", &p)) {
            s->text_addr = strtoull(p, &end, 16);
            s->has_text_addr = 1;
        } else if (link_option(option, "init=", &p)) {
            copy_linker_arg(&s->init_symbol, p, 0);
            ignoring = 1;
        } else if (link_option(option, "oformat=", &p)) {
#if defined(TCC_TARGET_PE)
            if (strstart("pe-", &p)) {
#elif PTR_SIZE == 8
            if (strstart("elf64-", &p)) {
#else
            if (strstart("elf32-", &p)) {
#endif
                s->output_format = TCC_OUTPUT_FORMAT_ELF;
            } else if (!strcmp(p, "binary")) {
                s->output_format = TCC_OUTPUT_FORMAT_BINARY;
#ifdef TCC_TARGET_COFF
            } else if (!strcmp(p, "coff")) {
                s->output_format = TCC_OUTPUT_FORMAT_COFF;
#endif
            } else
                goto err;

        } else if (link_option(option, "as-needed", &p)) {
            ignoring = 1;
        } else if (link_option(option, "O", &p)) {
            ignoring = 1;
        } else if (link_option(option, "export-all-symbols", &p)) {
            s->rdynamic = 1;
        } else if (link_option(option, "rpath=", &p)) {
            copy_linker_arg(&s->rpath, p, ':');
        } else if (link_option(option, "enable-new-dtags", &p)) {
            s->enable_new_dtags = 1;
        } else if (link_option(option, "section-alignment=", &p)) {
            s->section_align = strtoul(p, &end, 16);
        } else if (link_option(option, "soname=", &p)) {
            copy_linker_arg(&s->soname, p, 0);
#ifdef TCC_TARGET_PE
        } else if (link_option(option, "large-address-aware", &p)) {
            s->pe_characteristics |= 0x20;
        } else if (link_option(option, "file-alignment=", &p)) {
            s->pe_file_align = strtoul(p, &end, 16);
        } else if (link_option(option, "stack=", &p)) {
            s->pe_stack_size = strtoul(p, &end, 10);
        } else if (link_option(option, "subsystem=", &p)) {
#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
            if (!strcmp(p, "native")) {
                s->pe_subsystem = 1;
            } else if (!strcmp(p, "console")) {
                s->pe_subsystem = 3;
            } else if (!strcmp(p, "gui") || !strcmp(p, "windows")) {
                s->pe_subsystem = 2;
            } else if (!strcmp(p, "posix")) {
                s->pe_subsystem = 7;
            } else if (!strcmp(p, "efiapp")) {
                s->pe_subsystem = 10;
            } else if (!strcmp(p, "efiboot")) {
                s->pe_subsystem = 11;
            } else if (!strcmp(p, "efiruntime")) {
                s->pe_subsystem = 12;
            } else if (!strcmp(p, "efirom")) {
                s->pe_subsystem = 13;
#elif defined(TCC_TARGET_ARM)
            if (!strcmp(p, "wince")) {
                s->pe_subsystem = 9;
#endif
            } else
                goto err;
#endif
        } else if (ret = link_option(option, "?whole-archive", &p), ret) {
            s->alacarte_link = ret < 0;
        } else if (p) {
            return 0;
        } else {
    err:
            tcc_error("unsupported linker option '%s'", option);
        }

        if (ignoring && s->warn_unsupported)
            tcc_warning("unsupported linker option '%s'", option);

        option = skip_linker_arg(&p);
    }
    return 1;
}

typedef struct TCCOption {
    const char *name;
    uint16_t index;
    uint16_t flags;
} TCCOption;

enum {
    TCC_OPTION_HELP,
    TCC_OPTION_HELP2,
    TCC_OPTION_v,
    TCC_OPTION_I,
    TCC_OPTION_D,
    TCC_OPTION_U,
    TCC_OPTION_P,
    TCC_OPTION_L,
    TCC_OPTION_B,
    TCC_OPTION_l,
    TCC_OPTION_bench,
    TCC_OPTION_bt,
    TCC_OPTION_b,
    TCC_OPTION_g,
    TCC_OPTION_c,
    TCC_OPTION_dumpversion,
    TCC_OPTION_d,
    TCC_OPTION_static,
    TCC_OPTION_std,
    TCC_OPTION_shared,
    TCC_OPTION_soname,
    TCC_OPTION_o,
    TCC_OPTION_r,
    TCC_OPTION_s,
    TCC_OPTION_traditional,
    TCC_OPTION_Wl,
    TCC_OPTION_Wp,
    TCC_OPTION_W,
    TCC_OPTION_O,
    TCC_OPTION_mfloat_abi,
    TCC_OPTION_m,
    TCC_OPTION_f,
    TCC_OPTION_isystem,
    TCC_OPTION_iwithprefix,
    TCC_OPTION_include,
    TCC_OPTION_nostdinc,
    TCC_OPTION_nostdlib,
    TCC_OPTION_print_search_dirs,
    TCC_OPTION_rdynamic,
    TCC_OPTION_param,
    TCC_OPTION_pedantic,
    TCC_OPTION_pthread,
    TCC_OPTION_run,
    TCC_OPTION_w,
    TCC_OPTION_pipe,
    TCC_OPTION_E,
    TCC_OPTION_MD,
    TCC_OPTION_MF,
    TCC_OPTION_x,
    TCC_OPTION_ar,
    TCC_OPTION_impdef
};

#define TCC_OPTION_HAS_ARG 0x0001
#define TCC_OPTION_NOSEP   0x0002 /* cannot have space before option and arg */

static const TCCOption tcc_options[] = {
    { "h", TCC_OPTION_HELP, 0 },
    { "-help", TCC_OPTION_HELP, 0 },
    { "?", TCC_OPTION_HELP, 0 },
    { "hh", TCC_OPTION_HELP2, 0 },
    { "v", TCC_OPTION_v, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
    { "I", TCC_OPTION_I, TCC_OPTION_HAS_ARG },
    { "D", TCC_OPTION_D, TCC_OPTION_HAS_ARG },
    { "U", TCC_OPTION_U, TCC_OPTION_HAS_ARG },
    { "P", TCC_OPTION_P, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
    { "L", TCC_OPTION_L, TCC_OPTION_HAS_ARG },
    { "B", TCC_OPTION_B, TCC_OPTION_HAS_ARG },
    { "l", TCC_OPTION_l, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
    { "bench", TCC_OPTION_bench, 0 },
#ifdef CONFIG_TCC_BACKTRACE
    { "bt", TCC_OPTION_bt, TCC_OPTION_HAS_ARG },
#endif
#ifdef CONFIG_TCC_BCHECK
    { "b", TCC_OPTION_b, 0 },
#endif
    { "g", TCC_OPTION_g, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
    { "c", TCC_OPTION_c, 0 },
    { "dumpversion", TCC_OPTION_dumpversion, 0},
    { "d", TCC_OPTION_d, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
    { "static", TCC_OPTION_static, 0 },
    { "std", TCC_OPTION_std, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
    { "shared", TCC_OPTION_shared, 0 },
    { "soname", TCC_OPTION_soname, TCC_OPTION_HAS_ARG },
    { "o", TCC_OPTION_o, TCC_OPTION_HAS_ARG },
    { "-param", TCC_OPTION_param, TCC_OPTION_HAS_ARG },
    { "pedantic", TCC_OPTION_pedantic, 0},
    { "pthread", TCC_OPTION_pthread, 0},
    { "run", TCC_OPTION_run, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
    { "rdynamic", TCC_OPTION_rdynamic, 0 },
    { "r", TCC_OPTION_r, 0 },
    { "s", TCC_OPTION_s, 0 },
    { "traditional", TCC_OPTION_traditional, 0 },
    { "Wl,", TCC_OPTION_Wl, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
    { "Wp,", TCC_OPTION_Wp, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
    { "W", TCC_OPTION_W, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
    { "O", TCC_OPTION_O, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
#ifdef TCC_TARGET_ARM
    { "mfloat-abi", TCC_OPTION_mfloat_abi, TCC_OPTION_HAS_ARG },
#endif
    { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
    { "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
    { "isystem", TCC_OPTION_isystem, TCC_OPTION_HAS_ARG },
    { "iwithprefix", TCC_OPTION_iwithprefix, TCC_OPTION_HAS_ARG },
    { "include", TCC_OPTION_include, TCC_OPTION_HAS_ARG },
    { "nostdinc", TCC_OPTION_nostdinc, 0 },
    { "nostdlib", TCC_OPTION_nostdlib, 0 },
    { "print-search-dirs", TCC_OPTION_print_search_dirs, 0 },
    { "w", TCC_OPTION_w, 0 },
    { "pipe", TCC_OPTION_pipe, 0},
    { "E", TCC_OPTION_E, 0},
    { "MD", TCC_OPTION_MD, 0},
    { "MF", TCC_OPTION_MF, TCC_OPTION_HAS_ARG },
    { "x", TCC_OPTION_x, TCC_OPTION_HAS_ARG },
    { "ar", TCC_OPTION_ar, 0},
#ifdef TCC_TARGET_PE
    { "impdef", TCC_OPTION_impdef, 0},
#endif
    { NULL, 0, 0 },
};

static const FlagDef options_W[] = {
    { 0, 0, "all" },
    { offsetof(TCCState, warn_unsupported), 0, "unsupported" },
    { offsetof(TCCState, warn_write_strings), 0, "write-strings" },
    { offsetof(TCCState, warn_error), 0, "error" },
    { offsetof(TCCState, warn_gcc_compat), 0, "gcc-compat" },
    { offsetof(TCCState, warn_implicit_function_declaration), WD_ALL,
      "implicit-function-declaration" },
    { 0, 0, NULL }
};

static const FlagDef options_f[] = {
    { offsetof(TCCState, char_is_unsigned), 0, "unsigned-char" },
    { offsetof(TCCState, char_is_unsigned), FD_INVERT, "signed-char" },
    { offsetof(TCCState, nocommon), FD_INVERT, "common" },
    { offsetof(TCCState, leading_underscore), 0, "leading-underscore" },
    { offsetof(TCCState, ms_extensions), 0, "ms-extensions" },
    { offsetof(TCCState, dollars_in_identifiers), 0, "dollars-in-identifiers" },
    { 0, 0, NULL }
};

static const FlagDef options_m[] = {
    { offsetof(TCCState, ms_bitfields), 0, "ms-bitfields" },
#ifdef TCC_TARGET_X86_64
    { offsetof(TCCState, nosse), FD_INVERT, "sse" },
#endif
    { 0, 0, NULL }
};

static void parse_option_D(TCCState *s1, const char *optarg)
{
    char *sym = tcc_strdup(optarg);
    char *value = strchr(sym, '=');
    if (value)
        *value++ = '\0';
    tcc_define_symbol(s1, sym, value);
    tcc_free(sym);
}

static void args_parser_add_file(TCCState *s, const char* filename, int filetype)
{
    struct filespec *f = tcc_malloc(sizeof *f + strlen(filename));
    f->type = filetype;
    f->alacarte = s->alacarte_link;
    strcpy(f->name, filename);
    dynarray_add(&s->files, &s->nb_files, f);
}

static int args_parser_make_argv(const char *r, int *argc, char ***argv)
{
    int ret = 0, q, c;
    CString str;
    for(;;) {
        while (c = (unsigned char)*r, c && c <= ' ')
        ++r;
        if (c == 0)
            break;
        q = 0;
        cstr_new(&str);
        while (c = (unsigned char)*r, c) {
            ++r;
            if (c == '\\' && (*r == '"' || *r == '\\')) {
                c = *r++;
            } else if (c == '"') {
                q = !q;
                continue;
            } else if (q == 0 && c <= ' ') {
                break;
            }
            cstr_ccat(&str, c);
        }
        cstr_ccat(&str, 0);
        //printf("<%s>\n", str.data), fflush(stdout);
        dynarray_add(argv, argc, tcc_strdup(str.data));
        cstr_free(&str);
        ++ret;
    }
    return ret;
}

/* read list file */
static void args_parser_listfile(TCCState *s,
    const char *filename, int optind, int *pargc, char ***pargv)
{
    int fd, i;
    size_t len;
    char *p;
    int argc = 0;
    char **argv = NULL;

    fd = open(filename, O_RDONLY | O_BINARY);
    if (fd < 0)
        tcc_error("listfile '%s' not found", filename);

    len = lseek(fd, 0, SEEK_END);
    p = tcc_malloc(len + 1), p[len] = 0;
    lseek(fd, 0, SEEK_SET), read(fd, p, len), close(fd);

    for (i = 0; i < *pargc; ++i)
        if (i == optind)
            args_parser_make_argv(p, &argc, &argv);
        else
            dynarray_add(&argv, &argc, tcc_strdup((*pargv)[i]));

    tcc_free(p);
    dynarray_reset(&s->argv, &s->argc);
    *pargc = s->argc = argc, *pargv = s->argv = argv;
}

PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind)
{
    const TCCOption *popt;
    const char *optarg, *r;
    const char *run = NULL;
    int last_o = -1;
    int x;
    CString linker_arg; /* collect -Wl options */
    char buf[1024];
    int tool = 0, arg_start = 0, noaction = optind;
    char **argv = *pargv;
    int argc = *pargc;

    cstr_new(&linker_arg);

    while (optind < argc) {
        r = argv[optind];
        if (r[0] == '@' && r[1] != '\0') {
            args_parser_listfile(s, r + 1, optind, &argc, &argv);
        continue;
        }
        optind++;
        if (tool) {
            if (r[0] == '-' && r[1] == 'v' && r[2] == 0)
                ++s->verbose;
            continue;
        }
reparse:
        if (r[0] != '-' || r[1] == '\0') {
            if (r[0] != '@') /* allow "tcc file(s) -run @ args ..." */
                args_parser_add_file(s, r, s->filetype);
            if (run) {
                tcc_set_options(s, run);
                arg_start = optind - 1;
                break;
            }
            continue;
        }

        /* find option in table */
        for(popt = tcc_options; ; ++popt) {
            const char *p1 = popt->name;
            const char *r1 = r + 1;
            if (p1 == NULL)
                tcc_error("invalid option -- '%s'", r);
            if (!strstart(p1, &r1))
                continue;
            optarg = r1;
            if (popt->flags & TCC_OPTION_HAS_ARG) {
                if (*r1 == '\0' && !(popt->flags & TCC_OPTION_NOSEP)) {
                    if (optind >= argc)
                arg_err:
                        tcc_error("argument to '%s' is missing", r);
                    optarg = argv[optind++];
                }
            } else if (*r1 != '\0')
                continue;
            break;
        }

        switch(popt->index) {
        case TCC_OPTION_HELP:
            return OPT_HELP;
        case TCC_OPTION_HELP2:
            return OPT_HELP2;
        case TCC_OPTION_I:
            tcc_add_include_path(s, optarg);
            break;
        case TCC_OPTION_D:
            parse_option_D(s, optarg);
            break;
        case TCC_OPTION_U:
            tcc_undefine_symbol(s, optarg);
            break;
        case TCC_OPTION_L:
            tcc_add_library_path(s, optarg);
            break;
        case TCC_OPTION_B:
            /* set tcc utilities path (mainly for tcc development) */
            tcc_set_lib_path(s, optarg);
            break;
        case TCC_OPTION_l:
            args_parser_add_file(s, optarg, AFF_TYPE_LIB);
            s->nb_libraries++;
            break;
        case TCC_OPTION_pthread:
            parse_option_D(s, "_REENTRANT");
            s->option_pthread = 1;
            break;
        case TCC_OPTION_bench:
            s->do_bench = 1;
            break;
#ifdef CONFIG_TCC_BACKTRACE
        case TCC_OPTION_bt:
            tcc_set_num_callers(atoi(optarg));
            break;
#endif
#ifdef CONFIG_TCC_BCHECK
        case TCC_OPTION_b:
            s->do_bounds_check = 1;
            s->do_debug = 1;
            break;
#endif
        case TCC_OPTION_g:
            s->do_debug = 1;
            break;
        case TCC_OPTION_c:
            x = TCC_OUTPUT_OBJ;
        set_output_type:
            if (s->output_type)
                tcc_warning("-%s: overriding compiler action already specified", popt->name);
            s->output_type = x;
            break;
        case TCC_OPTION_d:
            if (*optarg == 'D')
                s->dflag = 3;
            else if (*optarg == 'M')
                s->dflag = 7;
            else
                goto unsupported_option;
            break;
        case TCC_OPTION_static:
            s->static_link = 1;
            break;
        case TCC_OPTION_std:
            /* silently ignore, a current purpose:
               allow to use a tcc as a reference compiler for "make test" */
            break;
        case TCC_OPTION_shared:
            x = TCC_OUTPUT_DLL;
            goto set_output_type;
        case TCC_OPTION_soname:
            s->soname = tcc_strdup(optarg);
            break;
        case TCC_OPTION_o:
            if (s->outfile) {
                tcc_warning("multiple -o option");
                tcc_free(s->outfile);
            }
            s->outfile = tcc_strdup(optarg);
            break;
        case TCC_OPTION_r:
            /* generate a .o merging several output files */
            s->option_r = 1;
            x = TCC_OUTPUT_OBJ;
            goto set_output_type;
        case TCC_OPTION_isystem:
            tcc_add_sysinclude_path(s, optarg);
            break;
        case TCC_OPTION_iwithprefix:
            snprintf(buf, sizeof buf, "{B}/%s", optarg);
            tcc_add_sysinclude_path(s, buf);
            break;
    case TCC_OPTION_include:
        dynarray_add(&s->cmd_include_files,
             &s->nb_cmd_include_files, tcc_strdup(optarg));
        break;
        case TCC_OPTION_nostdinc:
            s->nostdinc = 1;
            break;
        case TCC_OPTION_nostdlib:
            s->nostdlib = 1;
            break;
        case TCC_OPTION_run:
#ifndef TCC_IS_NATIVE
            tcc_error("-run is not available in a cross compiler");
#endif
            run = optarg;
            x = TCC_OUTPUT_MEMORY;
            goto set_output_type;
        case TCC_OPTION_v:
            do ++s->verbose; while (*optarg++ == 'v');
            ++noaction;
            break;
        case TCC_OPTION_f:
            if (set_flag(s, options_f, optarg) < 0)
                goto unsupported_option;
            break;
#ifdef TCC_TARGET_ARM
        case TCC_OPTION_mfloat_abi:
            /* tcc doesn't support soft float yet */
            if (!strcmp(optarg, "softfp")) {
                s->float_abi = ARM_SOFTFP_FLOAT;
                tcc_undefine_symbol(s, "__ARM_PCS_VFP");
            } else if (!strcmp(optarg, "hard"))
                s->float_abi = ARM_HARD_FLOAT;
            else
                tcc_error("unsupported float abi '%s'", optarg);
            break;
#endif
        case TCC_OPTION_m:
            if (set_flag(s, options_m, optarg) < 0) {
                if (x = atoi(optarg), x != 32 && x != 64)
                    goto unsupported_option;
                if (PTR_SIZE != x/8)
                    return x;
                ++noaction;
            }
            break;
        case TCC_OPTION_W:
            if (set_flag(s, options_W, optarg) < 0)
                goto unsupported_option;
            break;
        case TCC_OPTION_w:
            s->warn_none = 1;
            break;
        case TCC_OPTION_rdynamic:
            s->rdynamic = 1;
            break;
        case TCC_OPTION_Wl:
            if (linker_arg.size)
                --linker_arg.size, cstr_ccat(&linker_arg, ',');
            cstr_cat(&linker_arg, optarg, 0);
            if (tcc_set_linker(s, linker_arg.data))
                cstr_free(&linker_arg);
            break;
    case TCC_OPTION_Wp:
        r = optarg;
        goto reparse;
        case TCC_OPTION_E:
            x = TCC_OUTPUT_PREPROCESS;
            goto set_output_type;
        case TCC_OPTION_P:
            s->Pflag = atoi(optarg) + 1;
            break;
        case TCC_OPTION_MD:
            s->gen_deps = 1;
            break;
        case TCC_OPTION_MF:
            s->deps_outfile = tcc_strdup(optarg);
            break;
        case TCC_OPTION_dumpversion:
            printf ("%s\n", TCC_VERSION);
            exit(0);
            break;
        case TCC_OPTION_x:
            if (*optarg == 'c')
                s->filetype = AFF_TYPE_C;
            else if (*optarg == 'a')
                s->filetype = AFF_TYPE_ASMPP;
            else if (*optarg == 'n')
                s->filetype = AFF_TYPE_NONE;
            else
                tcc_warning("unsupported language '%s'", optarg);
            break;
        case TCC_OPTION_O:
            last_o = atoi(optarg);
            break;
        case TCC_OPTION_print_search_dirs:
            x = OPT_PRINT_DIRS;
            goto extra_action;
        case TCC_OPTION_impdef:
            x = OPT_IMPDEF;
            goto extra_action;
        case TCC_OPTION_ar:
            x = OPT_AR;
        extra_action:
            arg_start = optind - 1;
            if (arg_start != noaction)
                tcc_error("cannot parse %s here", r);
            tool = x;
            break;
        case TCC_OPTION_traditional:
        case TCC_OPTION_pedantic:
        case TCC_OPTION_pipe:
        case TCC_OPTION_s:
            /* ignored */
            break;
        default:
unsupported_option:
            if (s->warn_unsupported)
                tcc_warning("unsupported option '%s'", r);
            break;
        }
    }
    if (last_o > 0)
        tcc_define_symbol(s, "__OPTIMIZE__", NULL);
    if (linker_arg.size) {
        r = linker_arg.data;
        goto arg_err;
    }
    *pargc = argc - arg_start;
    *pargv = argv + arg_start;
    if (tool)
        return tool;
    if (optind != noaction)
        return 0;
    if (s->verbose == 2)
        return OPT_PRINT_DIRS;
    if (s->verbose)
        return OPT_V;
    return OPT_HELP;
}

LIBTCCAPI void tcc_set_options(TCCState *s, const char *r)
{
    char **argv = NULL;
    int argc = 0;
    args_parser_make_argv(r, &argc, &argv);
    tcc_parse_args(s, &argc, &argv, 0);
    dynarray_reset(&argv, &argc);
}

PUB_FUNC void tcc_print_stats(TCCState *s, unsigned total_time)
{
    if (total_time < 1)
        total_time = 1;
    if (total_bytes < 1)
        total_bytes = 1;
    fprintf(stderr, "* %d idents, %d lines, %d bytes\n"
                    "* %0.3f s, %u lines/s, %0.1f MB/s\n",
           tok_ident - TOK_IDENT, total_lines, total_bytes,
           (double)total_time/1000,
           (unsigned)total_lines*1000/total_time,
           (double)total_bytes/1000/total_time);
#ifdef MEM_DEBUG
    fprintf(stderr, "* %d bytes memory used\n", mem_max_size);
#endif
}

https://gitlab.com/janneke/tinycc/-/blob/ff2210b308321f27ee07476d07f24b5095602b17/tcc.h

File: ../git/live-bootstrap/sysa/tcc-0.9.26/build/tcc-0.9.26-1136-g5bba73cc/tcc.h used in: Step 378, Step 395, Step 407, Step 419, Step 431, Step 443, Step 455
/*
 *  TCC - Tiny C Compiler
 * 
 *  Copyright (c) 2001-2004 Fabrice Bellard
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef _TCC_H
#define _TCC_H

#define _GNU_SOURCE
#include "config.h"

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <math.h>
#include <fcntl.h>
#include <setjmp.h>
#include <time.h>

#ifndef _WIN32
# include <unistd.h>
# include <sys/time.h>
# ifndef CONFIG_TCC_STATIC
#  include <dlfcn.h>
# endif
/* XXX: need to define this to use them in non ISOC99 context */
 extern float strtof (const char *__nptr, char **__endptr);
 extern long double strtold (const char *__nptr, char **__endptr);

#else /* on _WIN32: */
# include <windows.h>
# include <io.h> /* open, close etc. */
# include <direct.h> /* getcwd */
# ifdef __GNUC__
#  include <stdint.h>
# endif
# define inline __inline
# define inp next_inp /* inp is an intrinsic on msvc */
# define snprintf _snprintf
# define vsnprintf _vsnprintf
# ifndef __GNUC__
#  define strtold (long double)strtod
#  define strtof (float)strtod
#  define strtoll _strtoi64
#  define strtoull _strtoui64
# endif
# ifdef LIBTCC_AS_DLL
#  define LIBTCCAPI __declspec(dllexport)
#  define PUB_FUNC LIBTCCAPI
# endif
# ifdef _MSC_VER
#  pragma warning (disable : 4244)  // conversion from 'uint64_t' to 'int', possible loss of data
#  pragma warning (disable : 4267)  // conversion from 'size_t' to 'int', possible loss of data
#  pragma warning (disable : 4996)  // The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name
#  pragma warning (disable : 4018)  // signed/unsigned mismatch
#  pragma warning (disable : 4146)  // unary minus operator applied to unsigned type, result still unsigned
#  define ssize_t intptr_t
#  define __attribute__(x) __declspec x
#  define aligned align
# else
# endif
# undef CONFIG_TCC_STATIC
#endif

#ifndef O_BINARY
# define O_BINARY 0
#endif

#ifdef __GNUC__
# define NORETURN __attribute__ ((noreturn))
#elif defined _MSC_VER
# define NORETURN __declspec(noreturn)
#else
# define NORETURN
#endif

#ifdef _WIN32
# define IS_DIRSEP(c) (c == '/' || c == '\\')
# define IS_ABSPATH(p) (IS_DIRSEP(p[0]) || (p[0] && p[1] == ':' && IS_DIRSEP(p[2])))
# define PATHCMP stricmp
#else
# define IS_DIRSEP(c) (c == '/')
# define IS_ABSPATH(p) IS_DIRSEP(p[0])
# define PATHCMP strcmp
#endif

#ifdef TCC_TARGET_PE
#define PATHSEP ';'
#else
#define PATHSEP ':'
#endif

/* -------------------------------------------- */

/* parser debug */
/* #define PARSE_DEBUG */
/* preprocessor debug */
/* #define PP_DEBUG */
/* include file debug */
/* #define INC_DEBUG */
/* memory leak debug */
/* #define MEM_DEBUG */
/* assembler debug */
/* #define ASM_DEBUG */

/* target selection */
/* #define TCC_TARGET_I386   *//* i386 code generator */
/* #define TCC_TARGET_X86_64 *//* x86-64 code generator */
/* #define TCC_TARGET_ARM    *//* ARMv4 code generator */
/* #define TCC_TARGET_ARM64  *//* ARMv8 code generator */
/* #define TCC_TARGET_C67    *//* TMS320C67xx code generator */

/* default target is I386 */
#if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_ARM) && \
    !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_C67) && \
    !defined(TCC_TARGET_X86_64)
#define TCC_TARGET_I386
#endif

/* object format selection */
#if defined(TCC_TARGET_C67)
#define TCC_TARGET_COFF
#endif

/* only native compiler supports -run */
#if defined _WIN32 == defined TCC_TARGET_PE
# if (defined __i386__ || defined _X86_) && defined TCC_TARGET_I386
#  define TCC_IS_NATIVE
# elif (defined __x86_64__ || defined _AMD64_) && defined TCC_TARGET_X86_64
#  define TCC_IS_NATIVE
# elif defined __arm__ && defined TCC_TARGET_ARM
#  define TCC_IS_NATIVE
# elif defined __aarch64__ && defined TCC_TARGET_ARM64
#  define TCC_IS_NATIVE
# endif
#endif

#if defined TCC_IS_NATIVE && !defined CONFIG_TCCBOOT
# define CONFIG_TCC_BACKTRACE
# if (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64) \
  && !defined TCC_UCLIBC && !defined TCC_MUSL
# define CONFIG_TCC_BCHECK /* enable bound checking code */
# endif
#endif

/* ------------ path configuration ------------ */

#ifndef CONFIG_SYSROOT
# define CONFIG_SYSROOT ""
#endif
#ifndef CONFIG_TCCDIR
# define CONFIG_TCCDIR "."
#endif
#ifndef CONFIG_LDDIR
# define CONFIG_LDDIR "lib"
#endif
#ifdef CONFIG_TRIPLET
# define USE_TRIPLET(s) s "/" CONFIG_TRIPLET
# define ALSO_TRIPLET(s) USE_TRIPLET(s) ":" s
#else
# define USE_TRIPLET(s) s
# define ALSO_TRIPLET(s) s
#endif

/* path to find crt1.o, crti.o and crtn.o */
#ifndef CONFIG_TCC_CRTPREFIX
# define CONFIG_TCC_CRTPREFIX USE_TRIPLET(CONFIG_SYSROOT "/usr/" CONFIG_LDDIR)
#endif

/* Below: {B} is substituted by CONFIG_TCCDIR (rsp. -B option) */

/* system include paths */
#ifndef CONFIG_TCC_SYSINCLUDEPATHS
# ifdef TCC_TARGET_PE
#  define CONFIG_TCC_SYSINCLUDEPATHS "{B}/include;{B}/include/winapi"
# else
#  define CONFIG_TCC_SYSINCLUDEPATHS \
        "{B}/include" \
    ":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/local/include") \
    ":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/include")
# endif
#endif

/* library search paths */
#ifndef CONFIG_TCC_LIBPATHS
# ifdef TCC_TARGET_PE
#  define CONFIG_TCC_LIBPATHS "{B}/lib"
# else
#  define CONFIG_TCC_LIBPATHS \
        ALSO_TRIPLET(CONFIG_SYSROOT "/usr/" CONFIG_LDDIR) \
    ":" ALSO_TRIPLET(CONFIG_SYSROOT "/" CONFIG_LDDIR) \
    ":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/local/" CONFIG_LDDIR)
# endif
#endif

/* name of ELF interpreter */
#ifndef CONFIG_TCC_ELFINTERP
# if defined __FreeBSD__
#  define CONFIG_TCC_ELFINTERP "/libexec/ld-elf.so.1"
# elif defined __FreeBSD_kernel__
#  if defined(TCC_TARGET_X86_64)
#   define CONFIG_TCC_ELFINTERP "/lib/ld-kfreebsd-x86-64.so.1"
#  else
#   define CONFIG_TCC_ELFINTERP "/lib/ld.so.1"
#  endif
# elif defined __DragonFly__
#  define CONFIG_TCC_ELFINTERP "/usr/libexec/ld-elf.so.2"
# elif defined __NetBSD__
#  define CONFIG_TCC_ELFINTERP "/usr/libexec/ld.elf_so"
# elif defined __GNU__
#  define CONFIG_TCC_ELFINTERP "/lib/ld.so"
# elif defined(TCC_TARGET_PE)
#  define CONFIG_TCC_ELFINTERP "-"
# elif defined(TCC_UCLIBC)
#  define CONFIG_TCC_ELFINTERP "/lib/ld-uClibc.so.0" /* is there a uClibc for x86_64 ? */
# elif defined TCC_TARGET_ARM64
#  if defined(TCC_MUSL)
#   define CONFIG_TCC_ELFINTERP "/lib/ld-musl-aarch64.so.1"
#  else
#   define CONFIG_TCC_ELFINTERP "/lib/ld-linux-aarch64.so.1"
#  endif
# elif defined(TCC_TARGET_X86_64)
#  if defined(TCC_MUSL)
#   define CONFIG_TCC_ELFINTERP "/lib/ld-musl-x86_64.so.1"
#  else
#   define CONFIG_TCC_ELFINTERP "/lib64/ld-linux-x86-64.so.2"
#  endif
# elif !defined(TCC_ARM_EABI)
#  if defined(TCC_MUSL)
#   define CONFIG_TCC_ELFINTERP "/lib/ld-musl-arm.so.1"
#  else
#   define CONFIG_TCC_ELFINTERP "/lib/ld-linux.so.2"
#  endif
# endif
#endif

/* var elf_interp dans *-gen.c */
#ifdef CONFIG_TCC_ELFINTERP
# define DEFAULT_ELFINTERP(s) CONFIG_TCC_ELFINTERP
#else
# define DEFAULT_ELFINTERP(s) default_elfinterp(s)
#endif

/* (target specific) libtcc1.a */
#ifndef TCC_LIBTCC1
# define TCC_LIBTCC1 "libtcc1.a"
#endif

/* library to use with CONFIG_USE_LIBGCC instead of libtcc1.a */
#if defined CONFIG_USE_LIBGCC && !defined TCC_LIBGCC
#define TCC_LIBGCC USE_TRIPLET(CONFIG_SYSROOT "/" CONFIG_LDDIR) "/libgcc_s.so.1"
#endif

/* -------------------------------------------- */

#include "libtcc.h"
#include "elf.h"
#include "stab.h"

/* -------------------------------------------- */

#ifndef PUB_FUNC /* functions used by tcc.c but not in libtcc.h */
# define PUB_FUNC
#endif

#ifdef ONE_SOURCE
#define ST_INLN static inline
#define ST_FUNC static
#define ST_DATA static
#else
#define ST_INLN
#define ST_FUNC
#define ST_DATA extern
#endif

#ifdef TCC_PROFILE /* profile all functions */
# define static
#endif

/* -------------------------------------------- */
/* include the target specific definitions */

#define TARGET_DEFS_ONLY
#ifdef TCC_TARGET_I386
# include "i386-gen.c"
# include "i386-link.c"
#endif
#ifdef TCC_TARGET_X86_64
# include "x86_64-gen.c"
# include "x86_64-link.c"
#endif
#ifdef TCC_TARGET_ARM
# include "arm-gen.c"
# include "arm-link.c"
# include "arm-asm.c"
#endif
#ifdef TCC_TARGET_ARM64
# include "arm64-gen.c"
# include "arm64-link.c"
#endif
#ifdef TCC_TARGET_C67
# include "coff.h"
# include "c67-gen.c"
# include "c67-link.c"
#endif
#undef TARGET_DEFS_ONLY

/* -------------------------------------------- */

#if PTR_SIZE == 8
# define ELFCLASSW ELFCLASS64
# define ElfW(type) Elf##64##_##type
# define ELFW(type) ELF##64##_##type
# define ElfW_Rel ElfW(Rela)
# define SHT_RELX SHT_RELA
# define REL_SECTION_FMT ".rela%s"
#else
# define ELFCLASSW ELFCLASS32
# define ElfW(type) Elf##32##_##type
# define ELFW(type) ELF##32##_##type
# define ElfW_Rel ElfW(Rel)
# define SHT_RELX SHT_REL
# define REL_SECTION_FMT ".rel%s"
#endif
/* target address type */
#define addr_t ElfW(Addr)

/* -------------------------------------------- */

#define INCLUDE_STACK_SIZE  32
#define IFDEF_STACK_SIZE    64
#define VSTACK_SIZE         256
#define STRING_MAX_SIZE     1024
#define TOKSTR_MAX_SIZE     256
#define PACK_STACK_SIZE     8

#define TOK_HASH_SIZE       16384 /* must be a power of two */
#define TOK_ALLOC_INCR      512  /* must be a power of two */
#define TOK_MAX_SIZE        4 /* token max size in int unit when stored in string */

/* token symbol management */
typedef struct TokenSym {
    struct TokenSym *hash_next;
    struct Sym *sym_define; /* direct pointer to define */
    struct Sym *sym_label; /* direct pointer to label */
    struct Sym *sym_struct; /* direct pointer to structure */
    struct Sym *sym_identifier; /* direct pointer to identifier */
    int tok; /* token number */
    int len;
    char str[1];
} TokenSym;

#ifdef TCC_TARGET_PE
typedef unsigned short nwchar_t;
#else
typedef int nwchar_t;
#endif

typedef struct CString {
    int size; /* size in bytes */
    void *data; /* either 'char *' or 'nwchar_t *' */
    int size_allocated;
} CString;

/* type definition */
typedef struct CType {
    int t;
    struct Sym *ref;
} CType;

/* constant value */
typedef union CValue {
    long double ld;
    double d;
    float f;
#if HAVE_LONG_LONG_STUB || HAVE_LONG_LONG
    uint64_t i;
#else
    uint32_t i;
    uint32_t i_padding;
#endif
    struct {
        int size;
        const void *data;
    } str;
#if BOOTSTRAP && __arm__
    int tab[4];
#else
    int tab[LDOUBLE_SIZE/4];
#endif
} CValue;

/* value on stack */
typedef struct SValue {
    CType type;      /* type */
    unsigned short r;      /* register + flags */
    unsigned short r2;     /* second register, used for 'long long'
                              type. If not used, set to VT_CONST */
    CValue c;              /* constant, if VT_CONST */
    struct Sym *sym;       /* symbol, if (VT_SYM | VT_CONST), or if
                      result of unary() for an identifier. */
} SValue;

struct Attribute {
#if HAVE_BITFIELD
    unsigned
        func_call     : 3, /* calling convention (0..5), see below */
        aligned       : 5, /* alignment as log2+1 (0 == unspecified) */
        packed        : 1,
        func_export   : 1,
        func_import   : 1,
        func_args     : 5,
        func_body     : 1,
        mode          : 4,
        weak          : 1,
        visibility    : 2,
    unsigned_enum : 1,
        fill          : 7; // 7 bits left to fit well in union below
#else // !HAVE_BITFIELD
  struct {
    unsigned func_call;
    unsigned aligned;
    unsigned packed;
    unsigned func_export;
    unsigned func_import;
    unsigned func_args;
    unsigned func_body;
    unsigned mode;
    unsigned weak;
    unsigned visibility;
    unsigned unsigned_enum;
    unsigned fill;
  };
#endif // !HAVE_BITFIELD
};

/* GNUC attribute definition */
typedef struct AttributeDef {
    struct Attribute a;
    struct Section *section;
    int alias_target;    /* token */
    int asm_label;    /* associated asm label */
} AttributeDef;

/* symbol management */
typedef struct Sym {
    int v;    /* symbol token */
    union {
        int asm_label;    /* associated asm label */
        int scope;  /* scope level for locals */
    };
    union {
        long r;    /* associated register or VT_CONST/VT_LOCAL and LVAL type */
        struct Attribute a;
    };
    union {
        long c;    /* associated number */
        int *d;   /* define token stream */
    };
    CType type;    /* associated type */
    union {
        struct Sym *next; /* next related symbol (for fields and anoms) */
        long jnext; /* next jump label */
    };
    struct Sym *prev; /* prev symbol in stack */
    struct Sym *prev_tok; /* previous symbol for this token */
} Sym;

/* section definition */
/* XXX: use directly ELF structure for parameters ? */
/* special flag to indicate that the section should not be linked to
   the other ones */
#define SHF_PRIVATE 0x80000000

/* special flag, too */
#define SECTION_ABS ((void *)1)

typedef struct Section {
    unsigned long data_offset; /* current data offset */
    unsigned char *data;       /* section data */
    unsigned long data_allocated; /* used for realloc() handling */
    int sh_name;             /* elf section name (only used during output) */
    int sh_num;              /* elf section number */
    int sh_type;             /* elf section type */
    int sh_flags;            /* elf section flags */
    int sh_info;             /* elf section info */
    int sh_addralign;        /* elf section alignment */
    int sh_entsize;          /* elf entry size */
    unsigned long sh_size;   /* section size (only used during output) */
    addr_t sh_addr;          /* address at which the section is relocated */
    unsigned long sh_offset; /* file offset */
    int nb_hashed_syms;      /* used to resize the hash table */
    struct Section *link;    /* link to another section */
    struct Section *reloc;   /* corresponding section for relocation, if any */
    struct Section *hash;    /* hash table for symbols */
    struct Section *prev;    /* previous section on section stack */
    char name[1];           /* section name */
} Section;

typedef struct DLLReference {
    int level;
    void *handle;
    char name[1];
} DLLReference;

/* -------------------------------------------------- */

#define SYM_STRUCT     0x40000000 /* struct/union/enum symbol space */
#define SYM_FIELD      0x20000000 /* struct/union field symbol space */
#define SYM_FIRST_ANOM 0x10000000 /* first anonymous sym */

/* stored in 'Sym.c' field */
#define FUNC_NEW       1 /* ansi function prototype */
#define FUNC_OLD       2 /* old function prototype */
#define FUNC_ELLIPSIS  3 /* ansi function prototype with ... */

/* stored in 'Sym.r' field */
#define FUNC_CDECL     0 /* standard c call */
#define FUNC_STDCALL   1 /* pascal c call */
#define FUNC_FASTCALL1 2 /* first param in %eax */
#define FUNC_FASTCALL2 3 /* first parameters in %eax, %edx */
#define FUNC_FASTCALL3 4 /* first parameter in %eax, %edx, %ecx */
#define FUNC_FASTCALLW 5 /* first parameter in %ecx, %edx */

/* field 'Sym.t' for macros */
#define MACRO_OBJ      0 /* object like macro */
#define MACRO_FUNC     1 /* function like macro */

/* field 'Sym.r' for C labels */
#define LABEL_DEFINED  0 /* label is defined */
#define LABEL_FORWARD  1 /* label is forward defined */
#define LABEL_DECLARED 2 /* label is declared but never used */

/* type_decl() types */
#define TYPE_ABSTRACT  1 /* type without variable */
#define TYPE_DIRECT    2 /* type with variable */

#define IO_BUF_SIZE 8192

typedef struct BufferedFile {
    uint8_t *buf_ptr;
    uint8_t *buf_end;
    int fd;
    struct BufferedFile *prev;
    int line_num;    /* current line number - here to simplify code */
    int line_ref;    /* tcc -E: last printed line */
    int ifndef_macro;  /* #ifndef macro / #endif search */
    int ifndef_macro_saved; /* saved ifndef_macro */
    int *ifdef_stack_ptr; /* ifdef_stack value at the start of the file */
    int include_next_index; /* next search path */
    char filename[1024];    /* filename */
    char filename2[1024];    /* filename not modified by # line directive */
    unsigned char unget[4];
    unsigned char buffer[1]; /* extra size for CH_EOB char */
} BufferedFile;

#define CH_EOB   '\\'       /* end of buffer or '\0' char in file */
#define CH_EOF   (-1)   /* end of file */

/* parsing state (used to save parser state to reparse part of the
   source several times) */
typedef struct ParseState {
    const int *macro_ptr;
    int line_num;
    int tok;
    CValue tokc;
} ParseState;

/* used to record tokens */
typedef struct TokenString {
    int *str;
    int len;
    int allocated_len;
    int last_line_num;
    /* used to chain token-strings with begin/end_macro() */
    struct TokenString *prev;
    const int *prev_ptr;
    char alloc;
} TokenString;

/* inline functions */
typedef struct InlineFunc {
    TokenString *func_str;
    Sym *sym;
    char filename[1];
} InlineFunc;

/* include file cache, used to find files faster and also to eliminate
   inclusion if the include file is protected by #ifndef ... #endif */
typedef struct CachedInclude {
    int ifndef_macro;
    int once;
    int hash_next; /* -1 if none */
    char filename[1]; /* path specified in #include */
} CachedInclude;

#define CACHED_INCLUDES_HASH_SIZE 32

#ifdef CONFIG_TCC_ASM
typedef struct ExprValue {
#if HAVE_LONG_LONG_STUB || HAVE_LONG_LONG
    uint64_t v;
#else
    uint32_t v;
    uint32_t v_padding;
#endif
    Sym *sym;
    int pcrel;
} ExprValue;

#define MAX_ASM_OPERANDS 30
typedef struct ASMOperand {
    int id; /* GCC 3 optional identifier (0 if number only supported */
    char *constraint;
    char asm_str[16]; /* computed asm string for operand */
    SValue *vt; /* C value of the expression */
    int ref_index; /* if >= 0, gives reference to a output constraint */
    int input_index; /* if >= 0, gives reference to an input constraint */
    int priority; /* priority, used to assign registers */
    int reg; /* if >= 0, register number used for this operand */
    int is_llong; /* true if double register value */
    int is_memory; /* true if memory operand */
    int is_rw;     /* for '+' modifier */
} ASMOperand;
#endif

/* extra symbol attributes (not in symbol table) */
struct sym_attr {
    unsigned got_offset;
    unsigned plt_offset;
    int plt_sym;
    int dyn_index;
#ifdef TCC_TARGET_ARM
    unsigned char plt_thumb_stub:1;
#endif
};

struct TCCState {

    int verbose; /* if true, display some information during compilation */
    int nostdinc; /* if true, no standard headers are added */
    int nostdlib; /* if true, no standard libraries are added */
    int nocommon; /* if true, do not use common symbols for .bss data */
    int static_link; /* if true, static linking is performed */
    int rdynamic; /* if true, all symbols are exported */
    int symbolic; /* if true, resolve symbols in the current module first */
    int alacarte_link; /* if true, only link in referenced objects from archive */

    char *tcc_lib_path; /* CONFIG_TCCDIR or -B option */
    char *soname; /* as specified on the command line (-soname) */
    char *rpath; /* as specified on the command line (-Wl,-rpath=) */
    int enable_new_dtags; /* ditto, (-Wl,--enable-new-dtags) */

    /* output type, see TCC_OUTPUT_XXX */
    int output_type;
    /* output format, see TCC_OUTPUT_FORMAT_xxx */
    int output_format;

    /* C language options */
    int char_is_unsigned;
    int leading_underscore;
    int ms_extensions;  /* allow nested named struct w/o identifier behave like unnamed */
    int dollars_in_identifiers; /* allows '$' char in identifiers */
    int ms_bitfields; /* if true, emulate MS algorithm for aligning bitfields */

    /* warning switches */
    int warn_write_strings;
    int warn_unsupported;
    int warn_error;
    int warn_none;
    int warn_implicit_function_declaration;
    int warn_gcc_compat;

    /* compile with debug symbol (and use them if error during execution) */
    int do_debug;
#ifdef CONFIG_TCC_BCHECK
    /* compile with built-in memory and bounds checker */
    int do_bounds_check;
#endif
#ifdef TCC_TARGET_ARM
    enum float_abi float_abi; /* float ABI of the generated code*/
#endif

    addr_t text_addr; /* address of text section */
    int has_text_addr;

    unsigned section_align; /* section alignment */

    char *init_symbol; /* symbols to call at load-time (not used currently) */
    char *fini_symbol; /* symbols to call at unload-time (not used currently) */
    
#ifdef TCC_TARGET_I386
    int seg_size; /* 32. Can be 16 with i386 assembler (.code16) */
#endif
#ifdef TCC_TARGET_X86_64
    int nosse; /* For -mno-sse support. */
#endif

    /* array of all loaded dlls (including those referenced by loaded dlls) */
    DLLReference **loaded_dlls;
    int nb_loaded_dlls;

    /* include paths */
    char **include_paths;
    int nb_include_paths;

    char **sysinclude_paths;
    int nb_sysinclude_paths;

    /* library paths */
    char **library_paths;
    int nb_library_paths;

    /* crt?.o object path */
    char **crt_paths;
    int nb_crt_paths;

    /* -include files */
    char **cmd_include_files;
    int nb_cmd_include_files;

    /* error handling */
    void *error_opaque;
    void (*error_func)(void *opaque, const char *msg);
    int error_set_jmp_enabled;
    jmp_buf error_jmp_buf;
    int nb_errors;

    /* output file for preprocessing (-E) */
    FILE *ppfp;
    enum {
    LINE_MACRO_OUTPUT_FORMAT_GCC,
    LINE_MACRO_OUTPUT_FORMAT_NONE,
    LINE_MACRO_OUTPUT_FORMAT_STD,
    LINE_MACRO_OUTPUT_FORMAT_P10 = 11
    } Pflag; /* -P switch */
    char dflag; /* -dX value */

    /* for -MD/-MF: collected dependencies for this compilation */
    char **target_deps;
    int nb_target_deps;

    /* compilation */
    BufferedFile *include_stack[INCLUDE_STACK_SIZE];
    BufferedFile **include_stack_ptr;

    int ifdef_stack[IFDEF_STACK_SIZE];
    int *ifdef_stack_ptr;

    /* included files enclosed with #ifndef MACRO */
    int cached_includes_hash[CACHED_INCLUDES_HASH_SIZE];
    CachedInclude **cached_includes;
    int nb_cached_includes;

    /* #pragma pack stack */
    int pack_stack[PACK_STACK_SIZE];
    int *pack_stack_ptr;
    char **pragma_libs;
    int nb_pragma_libs;

    /* inline functions are stored as token lists and compiled last
       only if referenced */
    struct InlineFunc **inline_fns;
    int nb_inline_fns;

    /* sections */
    Section **sections;
    int nb_sections; /* number of sections, including first dummy section */

    Section **priv_sections;
    int nb_priv_sections; /* number of private sections */

    /* got & plt handling */
    Section *got;
    Section *plt;

    /* temporary dynamic symbol sections (for dll loading) */
    Section *dynsymtab_section;
    /* exported dynamic symbol section */
    Section *dynsym;
    /* copy of the global symtab_section variable */
    Section *symtab;
    /* extra attributes (eg. GOT/PLT value) for symtab symbols */
    struct sym_attr *sym_attrs;
    int nb_sym_attrs;
    /* tiny assembler state */
    Sym *asm_labels;

#ifdef TCC_TARGET_PE
    /* PE info */
    int pe_subsystem;
    unsigned pe_characteristics;
    unsigned pe_file_align;
    unsigned pe_stack_size;
# ifdef TCC_TARGET_X86_64
    Section *uw_pdata;
    int uw_sym;
    unsigned uw_offs;
# endif
#endif

#ifdef TCC_IS_NATIVE
    const char *runtime_main;
    void **runtime_mem;
    int nb_runtime_mem;
#endif

    /* used by main and tcc_parse_args only */
    struct filespec **files; /* files seen on command line */
    int nb_files; /* number thereof */
    int nb_libraries; /* number of libs thereof */
    int filetype;
    char *outfile; /* output filename */
    int option_r; /* option -r */
    int do_bench; /* option -bench */
    int gen_deps; /* option -MD  */
    char *deps_outfile; /* option -MF */
    int option_pthread; /* -pthread option */
    int argc;
    char **argv;
};

struct filespec {
    char type;
    char alacarte;
    char name[1];
};

/* The current value can be: */
#define VT_VALMASK   0x003f  /* mask for value location, register or: */
#define VT_CONST     0x0030  /* constant in vc (must be first non register value) */
#define VT_LLOCAL    0x0031  /* lvalue, offset on stack */
#define VT_LOCAL     0x0032  /* offset on stack */
#define VT_CMP       0x0033  /* the value is stored in processor flags (in vc) */
#define VT_JMP       0x0034  /* value is the consequence of jmp true (even) */
#define VT_JMPI      0x0035  /* value is the consequence of jmp false (odd) */
#define VT_LVAL      0x0100  /* var is an lvalue */
#define VT_SYM       0x0200  /* a symbol value is added */
#define VT_MUSTCAST  0x0400  /* value must be casted to be correct (used for
                                char/short stored in integer registers) */
#define VT_MUSTBOUND 0x0800  /* bound checking must be done before
                                dereferencing value */
#define VT_BOUNDED   0x8000  /* value is bounded. The address of the
                                bounding function call point is in vc */
#define VT_LVAL_BYTE     0x1000  /* lvalue is a byte */
#define VT_LVAL_SHORT    0x2000  /* lvalue is a short */
#define VT_LVAL_UNSIGNED 0x4000  /* lvalue is unsigned */
#define VT_LVAL_TYPE     (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)

/* types */
#define VT_BTYPE       0x000f  /* mask for basic type */
#define VT_INT              0  /* integer type */
#define VT_BYTE             1  /* signed byte type */
#define VT_SHORT            2  /* short type */
#define VT_VOID             3  /* void type */
#define VT_PTR              4  /* pointer */
#define VT_ENUM             5  /* enum definition */
#define VT_FUNC             6  /* function type */
#define VT_STRUCT           7  /* struct/union definition */
#define VT_FLOAT            8  /* IEEE float */
#define VT_DOUBLE           9  /* IEEE double */
#define VT_LDOUBLE         10  /* IEEE long double */
#define VT_BOOL            11  /* ISOC99 boolean type */
#define VT_LLONG           12  /* 64 bit integer */
#define VT_LONG            13  /* long integer (NEVER USED as type, only
                                  during parsing) */
#define VT_QLONG           14  /* 128-bit integer. Only used for x86-64 ABI */
#define VT_QFLOAT          15  /* 128-bit float. Only used for x86-64 ABI */
#define VT_UNSIGNED    0x0010  /* unsigned type */
#define VT_ARRAY       0x0020  /* array type (also has VT_PTR) */
#define VT_BITFIELD    0x0040  /* bitfield modifier */
#define VT_CONSTANT    0x0800  /* const modifier */
#define VT_VOLATILE    0x1000  /* volatile modifier */
#define VT_DEFSIGN     0x2000  /* signed type */
#define VT_VLA     0x00020000  /* VLA type (also has VT_PTR and VT_ARRAY) */

/* storage */
#define VT_EXTERN  0x00000080  /* extern definition */
#define VT_STATIC  0x00000100  /* static variable */
#define VT_TYPEDEF 0x00000200  /* typedef definition */
#define VT_INLINE  0x00000400  /* inline definition */
#define VT_IMPORT  0x00004000  /* win32: extern data imported from dll */
#define VT_EXPORT  0x00008000  /* win32: data exported from dll */
#define VT_WEAK    0x00010000  /* weak symbol */
#define VT_TLS     0x00040000  /* thread-local storage */
#define VT_VIS_SHIFT    19     /* shift for symbol visibility, overlapping
                  bitfield values, because bitfields never
                  have linkage and hence never have
                  visibility.  */
#define VT_VIS_SIZE      2     /* We have four visibilities.  */
#define VT_VIS_MASK (((1 << VT_VIS_SIZE)-1) << VT_VIS_SHIFT)

#define VT_STRUCT_SHIFT 19     /* shift for bitfield shift values (max: 32 - 2*6) */


/* type mask (except storage) */
#define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE | VT_IMPORT | VT_EXPORT | VT_WEAK | VT_VIS_MASK)
#define VT_TYPE (~(VT_STORAGE))

/* token values */

/* warning: the following compare tokens depend on i386 asm code */
#define TOK_ULT 0x92
#define TOK_UGE 0x93
#define TOK_EQ  0x94
#define TOK_NE  0x95
#define TOK_ULE 0x96
#define TOK_UGT 0x97
#define TOK_Nset 0x98
#define TOK_Nclear 0x99
#define TOK_LT  0x9c
#define TOK_GE  0x9d
#define TOK_LE  0x9e
#define TOK_GT  0x9f

#define TOK_LAND  0xa0
#define TOK_LOR   0xa1
#define TOK_DEC   0xa2
#define TOK_MID   0xa3 /* inc/dec, to void constant */
#define TOK_INC   0xa4
#define TOK_UDIV  0xb0 /* unsigned division */
#define TOK_UMOD  0xb1 /* unsigned modulo */
#define TOK_PDIV  0xb2 /* fast division with undefined rounding for pointers */

/* tokens that carry values (in additional token string space / tokc) --> */
#define TOK_CCHAR   0xb3 /* char constant in tokc */
#define TOK_LCHAR   0xb4
#define TOK_CINT    0xb5 /* number in tokc */
#define TOK_CUINT   0xb6 /* unsigned int constant */
#define TOK_CLLONG  0xb7 /* long long constant */
#define TOK_CULLONG 0xb8 /* unsigned long long constant */
#define TOK_STR     0xb9 /* pointer to string in tokc */
#define TOK_LSTR    0xba
#define TOK_CFLOAT  0xbb /* float constant */
#define TOK_CDOUBLE 0xbc /* double constant */
#define TOK_CLDOUBLE 0xbd /* long double constant */
#define TOK_PPNUM   0xbe /* preprocessor number */
#define TOK_PPSTR   0xbf /* preprocessor string */
#define TOK_LINENUM 0xc0 /* line number info */
/* <-- */

#define TOK_UMULL    0xc2 /* unsigned 32x32 -> 64 mul */
#define TOK_ADDC1    0xc3 /* add with carry generation */
#define TOK_ADDC2    0xc4 /* add with carry use */
#define TOK_SUBC1    0xc5 /* add with carry generation */
#define TOK_SUBC2    0xc6 /* add with carry use */
#define TOK_ARROW    0xc7
#define TOK_DOTS     0xc8 /* three dots */
#define TOK_SHR      0xc9 /* unsigned shift right */
#define TOK_TWOSHARPS 0xca /* ## preprocessing token */
#define TOK_PLCHLDR  0xcb /* placeholder token as defined in C99 */
#define TOK_NOSUBST  0xcc /* means following token has already been pp'd */
#define TOK_PPJOIN   0xce /* A '##' in the right position to mean pasting */

#define TOK_SHL   0x01 /* shift left */
#define TOK_SAR   0x02 /* signed shift right */
  
/* assignment operators : normal operator or 0x80 */
#define TOK_A_MOD 0xa5
#define TOK_A_AND 0xa6
#define TOK_A_MUL 0xaa
#define TOK_A_ADD 0xab
#define TOK_A_SUB 0xad
#define TOK_A_DIV 0xaf
#define TOK_A_XOR 0xde
#define TOK_A_OR  0xfc
#define TOK_A_SHL 0x81
#define TOK_A_SAR 0x82

#ifndef offsetof
#define offsetof(type, field) ((size_t) &((type *)0)->field)
#endif

#ifndef countof
#define countof(tab) (sizeof(tab) / sizeof((tab)[0]))
#endif

#define TOK_EOF       (-1)  /* end of file */
#define TOK_LINEFEED  10    /* line feed */

/* all identifiers and strings have token above that */
#define TOK_IDENT 256

#define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x)
#define TOK_ASM_int TOK_INT
#define DEF_ASMDIR(x) DEF(TOK_ASMDIR_ ## x, "." #x)
#define TOK_ASMDIR_FIRST TOK_ASMDIR_byte
#define TOK_ASMDIR_LAST TOK_ASMDIR_section

#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
/* only used for i386 asm opcodes definitions */
#define DEF_BWL(x) \
 DEF(TOK_ASM_ ## x ## b, #x "b") \
 DEF(TOK_ASM_ ## x ## w, #x "w") \
 DEF(TOK_ASM_ ## x ## l, #x "l") \
 DEF(TOK_ASM_ ## x, #x)
#define DEF_WL(x) \
 DEF(TOK_ASM_ ## x ## w, #x "w") \
 DEF(TOK_ASM_ ## x ## l, #x "l") \
 DEF(TOK_ASM_ ## x, #x)
#ifdef TCC_TARGET_X86_64
# define DEF_BWLQ(x) \
 DEF(TOK_ASM_ ## x ## b, #x "b") \
 DEF(TOK_ASM_ ## x ## w, #x "w") \
 DEF(TOK_ASM_ ## x ## l, #x "l") \
 DEF(TOK_ASM_ ## x ## q, #x "q") \
 DEF(TOK_ASM_ ## x, #x)
# define DEF_WLQ(x) \
 DEF(TOK_ASM_ ## x ## w, #x "w") \
 DEF(TOK_ASM_ ## x ## l, #x "l") \
 DEF(TOK_ASM_ ## x ## q, #x "q") \
 DEF(TOK_ASM_ ## x, #x)
# define DEF_BWLX DEF_BWLQ
# define DEF_WLX DEF_WLQ
/* number of sizes + 1 */
# define NBWLX 5
#else
# define DEF_BWLX DEF_BWL
# define DEF_WLX DEF_WL
/* number of sizes + 1 */
# define NBWLX 4
#endif

#define DEF_FP1(x) \
 DEF(TOK_ASM_ ## f ## x ## s, "f" #x "s") \
 DEF(TOK_ASM_ ## fi ## x ## l, "fi" #x "l") \
 DEF(TOK_ASM_ ## f ## x ## l, "f" #x "l") \
 DEF(TOK_ASM_ ## fi ## x ## s, "fi" #x "s")

#define DEF_FP(x) \
 DEF(TOK_ASM_ ## f ## x, "f" #x ) \
 DEF(TOK_ASM_ ## f ## x ## p, "f" #x "p") \
 DEF_FP1(x)

#define DEF_ASMTEST(x,suffix) \
 DEF_ASM(x ## o ## suffix) \
 DEF_ASM(x ## no ## suffix) \
 DEF_ASM(x ## b ## suffix) \
 DEF_ASM(x ## c ## suffix) \
 DEF_ASM(x ## nae ## suffix) \
 DEF_ASM(x ## nb ## suffix) \
 DEF_ASM(x ## nc ## suffix) \
 DEF_ASM(x ## ae ## suffix) \
 DEF_ASM(x ## e ## suffix) \
 DEF_ASM(x ## z ## suffix) \
 DEF_ASM(x ## ne ## suffix) \
 DEF_ASM(x ## nz ## suffix) \
 DEF_ASM(x ## be ## suffix) \
 DEF_ASM(x ## na ## suffix) \
 DEF_ASM(x ## nbe ## suffix) \
 DEF_ASM(x ## a ## suffix) \
 DEF_ASM(x ## s ## suffix) \
 DEF_ASM(x ## ns ## suffix) \
 DEF_ASM(x ## p ## suffix) \
 DEF_ASM(x ## pe ## suffix) \
 DEF_ASM(x ## np ## suffix) \
 DEF_ASM(x ## po ## suffix) \
 DEF_ASM(x ## l ## suffix) \
 DEF_ASM(x ## nge ## suffix) \
 DEF_ASM(x ## nl ## suffix) \
 DEF_ASM(x ## ge ## suffix) \
 DEF_ASM(x ## le ## suffix) \
 DEF_ASM(x ## ng ## suffix) \
 DEF_ASM(x ## nle ## suffix) \
 DEF_ASM(x ## g ## suffix)

#endif /* defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 */

enum tcc_token {
    TOK_LAST = TOK_IDENT - 1
#define DEF(id, str) ,id
#include "tcctok.h"
#undef DEF
};

/* keywords: tok >= TOK_IDENT && tok < TOK_UIDENT */
#define TOK_UIDENT TOK_DEFINE

/* ------------ libtcc.c ------------ */

/* use GNU C extensions */
ST_DATA int gnu_ext;
/* use Tiny C extensions */
ST_DATA int tcc_ext;
/* XXX: get rid of this ASAP */
ST_DATA struct TCCState *tcc_state;

/* public functions currently used by the tcc main function */
ST_FUNC char *pstrcpy(char *buf, int buf_size, const char *s);
ST_FUNC char *pstrcat(char *buf, int buf_size, const char *s);
ST_FUNC char *pstrncpy(char *out, const char *in, size_t num);
PUB_FUNC char *tcc_basename(const char *name);
PUB_FUNC char *tcc_fileextension (const char *name);

#ifndef MEM_DEBUG
PUB_FUNC void tcc_free(void *ptr);
PUB_FUNC void *tcc_malloc(unsigned long size);
PUB_FUNC void *tcc_mallocz(unsigned long size);
PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size);
PUB_FUNC char *tcc_strdup(const char *str);
#else
#define tcc_free(ptr)           tcc_free_debug(ptr)
#define tcc_malloc(size)        tcc_malloc_debug(size, __FILE__, __LINE__)
#define tcc_mallocz(size)       tcc_mallocz_debug(size, __FILE__, __LINE__)
#define tcc_realloc(ptr,size)   tcc_realloc_debug(ptr, size, __FILE__, __LINE__)
#define tcc_strdup(str)         tcc_strdup_debug(str, __FILE__, __LINE__)
PUB_FUNC void tcc_free_debug(void *ptr);
PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line);
PUB_FUNC void *tcc_mallocz_debug(unsigned long size, const char *file, int line);
PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file, int line);
PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line);
#endif

#define free(p) use_tcc_free(p)
#define malloc(s) use_tcc_malloc(s)
#define realloc(p, s) use_tcc_realloc(p, s)
#undef strdup
#define strdup(s) use_tcc_strdup(s)
PUB_FUNC void tcc_memcheck(void);
PUB_FUNC void tcc_error_noabort(const char *fmt, ...);
PUB_FUNC NORETURN void tcc_error(const char *fmt, ...);
PUB_FUNC void tcc_warning(const char *fmt, ...);

/* other utilities */
ST_FUNC void dynarray_add(void *ptab, int *nb_ptr, void *data);
ST_FUNC void dynarray_reset(void *pp, int *n);
ST_INLN void cstr_ccat(CString *cstr, int ch);
ST_FUNC void cstr_cat(CString *cstr, const char *str, int len);
ST_FUNC void cstr_wccat(CString *cstr, int ch);
ST_FUNC void cstr_new(CString *cstr);
ST_FUNC void cstr_free(CString *cstr);
ST_FUNC void cstr_reset(CString *cstr);

ST_INLN void sym_free(Sym *sym);
ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c);
ST_FUNC Sym *sym_find2(Sym *s, int v);
ST_FUNC Sym *sym_push(int v, CType *type, int r, long c);
ST_FUNC void sym_pop(Sym **ptop, Sym *b, int keep);
ST_INLN Sym *struct_find(int v);
ST_INLN Sym *sym_find(int v);
ST_FUNC Sym *global_identifier_push(int v, int t, long c);

ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen);
ST_FUNC int tcc_open(TCCState *s1, const char *filename);
ST_FUNC void tcc_close(void);

ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags);
/* flags: */
#define AFF_PRINT_ERROR     0x10 /* print error if file not found */
#define AFF_REFERENCED_DLL  0x20 /* load a referenced dll from another dll */
#define AFF_PREPROCESS      0x40 /* preprocess file */
/* combined with: */
#define AFF_TYPE_NONE   0
#define AFF_TYPE_C      1
#define AFF_TYPE_ASM    2
#define AFF_TYPE_ASMPP  3
#define AFF_TYPE_BIN    4
#define AFF_TYPE_LIB    5
/* values from tcc_object_type(...) */
#define AFF_BINTYPE_REL 1
#define AFF_BINTYPE_DYN 2
#define AFF_BINTYPE_AR  3
#define AFF_BINTYPE_C67 4


ST_FUNC int tcc_add_crt(TCCState *s, const char *filename);
ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags);
ST_FUNC void tcc_add_pragma_libs(TCCState *s1);
PUB_FUNC int tcc_add_library_err(TCCState *s, const char *f);
PUB_FUNC void tcc_print_stats(TCCState *s, unsigned total_time);
PUB_FUNC int tcc_parse_args(TCCState *s, int *argc, char ***argv, int optind);
#ifdef _WIN32
ST_FUNC char *normalize_slashes(char *path);
#endif

/* tcc_parse_args return codes: */
#define OPT_HELP 1
#define OPT_HELP2 2
#define OPT_V 3
#define OPT_PRINT_DIRS 4
#define OPT_AR 5
#define OPT_IMPDEF 6
#define OPT_M32 32
#define OPT_M64 64

/* ------------ tccpp.c ------------ */

ST_DATA struct BufferedFile *file;
ST_DATA int ch, tok;
ST_DATA CValue tokc;
ST_DATA const int *macro_ptr;
ST_DATA int parse_flags;
ST_DATA int tok_flags;
ST_DATA CString tokcstr; /* current parsed string, if any */

/* display benchmark infos */
ST_DATA int total_lines;
ST_DATA int total_bytes;
ST_DATA int tok_ident;
ST_DATA TokenSym **table_ident;

#define TOK_FLAG_BOL   0x0001 /* beginning of line before */
#define TOK_FLAG_BOF   0x0002 /* beginning of file before */
#define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */
#define TOK_FLAG_EOF   0x0008 /* end of file */

#define PARSE_FLAG_PREPROCESS 0x0001 /* activate preprocessing */
#define PARSE_FLAG_TOK_NUM    0x0002 /* return numbers instead of TOK_PPNUM */
#define PARSE_FLAG_LINEFEED   0x0004 /* line feed is returned as a
                                        token. line feed is also
                                        returned at eof */
#define PARSE_FLAG_ASM_FILE 0x0008 /* we processing an asm file: '#' can be used for line comment, etc. */
#define PARSE_FLAG_SPACES     0x0010 /* next() returns space tokens (for -E) */
#define PARSE_FLAG_ACCEPT_STRAYS 0x0020 /* next() returns '\\' token */
#define PARSE_FLAG_TOK_STR    0x0040 /* return parsed strings instead of TOK_PPSTR */

/* isidnum_table flags: */
#define IS_SPC 1
#define IS_ID  2
#define IS_NUM 4

ST_FUNC TokenSym *tok_alloc(const char *str, int len);
ST_FUNC const char *get_tok_str(int v, CValue *cv);
ST_FUNC void begin_macro(TokenString *str, int alloc);
ST_FUNC void end_macro(void);
ST_FUNC void set_idnum(int c, int val);
ST_FUNC void save_parse_state(ParseState *s);
ST_FUNC void restore_parse_state(ParseState *s);
ST_INLN void tok_str_new(TokenString *s);
ST_FUNC TokenString *tok_str_alloc(void);
ST_FUNC void tok_str_free(TokenString *s);
ST_FUNC void tok_str_free_str(int *str);
ST_FUNC void tok_str_add(TokenString *s, int t);
ST_FUNC void tok_str_add_tok(TokenString *s);
ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg);
ST_FUNC void define_undef(Sym *s);
ST_INLN Sym *define_find(int v);
ST_FUNC void free_defines(Sym *b);
ST_FUNC Sym *label_find(int v);
ST_FUNC Sym *label_push(Sym **ptop, int v, int flags);
ST_FUNC void label_pop(Sym **ptop, Sym *slast);
ST_FUNC void parse_define(void);
ST_FUNC void preprocess(int is_bof);
ST_FUNC void next_nomacro(void);
ST_FUNC void next(void);
ST_INLN void unget_tok(int last_tok);
ST_FUNC void preprocess_start(TCCState *s1);
ST_FUNC void tccpp_new(TCCState *s);
ST_FUNC void tccpp_delete(TCCState *s);
ST_FUNC int tcc_preprocess(TCCState *s1);
ST_FUNC void skip(int c);
ST_FUNC NORETURN void expect(const char *msg);

/* space excluding newline */
static inline int is_space(int ch) {
    return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';
}
static inline int isid(int c) {
    return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_';
}
static inline int isnum(int c) {
    return c >= '0' && c <= '9';
}
static inline int isoct(int c) {
    return c >= '0' && c <= '7';
}
static inline int toup(int c) {
    return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c;
}

/* ------------ tccgen.c ------------ */

#define SYM_POOL_NB (8192 / sizeof(Sym))
ST_DATA Sym *sym_free_first;
ST_DATA void **sym_pools;
ST_DATA int nb_sym_pools;

ST_DATA Sym *global_stack;
ST_DATA Sym *local_stack;
ST_DATA Sym *local_label_stack;
ST_DATA Sym *global_label_stack;
ST_DATA Sym *define_stack;
ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
ST_DATA SValue __vstack[1+/*to make bcheck happy*/ VSTACK_SIZE], *vtop, *pvtop;
#define vstack  (__vstack + 1)
ST_DATA int rsym, anon_sym, ind, loc;

ST_DATA int const_wanted; /* true if constant wanted */
ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
ST_DATA int global_expr;  /* true if compound literals must be allocated globally (used during initializers parsing */
ST_DATA CType func_vt; /* current function return type (used by return instruction) */
ST_DATA int func_var; /* true if current function is variadic */
ST_DATA int func_vc;
ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
ST_DATA const char *funcname;

ST_FUNC void tcc_debug_start(TCCState *s1);
ST_FUNC void tcc_debug_end(TCCState *s1);
ST_FUNC void tcc_debug_funcstart(TCCState *s1, Sym *sym);
ST_FUNC void tcc_debug_funcend(TCCState *s1, int size);
ST_FUNC void tcc_debug_line(TCCState *s1);

ST_FUNC void tccgen_start(TCCState *s1);
ST_FUNC void tccgen_end(TCCState *s1);

ST_FUNC void free_inline_functions(TCCState *s);
ST_FUNC void check_vstack(void);

ST_INLN int is_float(int t);
ST_FUNC int ieee_finite(double d);
ST_FUNC void test_lvalue(void);
ST_FUNC void vpushi(int v);
ST_FUNC Sym *external_global_sym(int v, CType *type, int r);
ST_FUNC void vset(CType *type, int r, long v);
ST_FUNC void vswap(void);
ST_FUNC void vpush_global_sym(CType *type, int v);
ST_FUNC void vrote(SValue *e, int n);
ST_FUNC void vrott(int n);
ST_FUNC void vrotb(int n);
#ifdef TCC_TARGET_ARM
ST_FUNC int get_reg_ex(int rc, int rc2);
ST_FUNC void lexpand_nr(void);
#endif
ST_FUNC void vpushv(SValue *v);
ST_FUNC void save_reg(int r);
ST_FUNC void save_reg_upstack(int r, int n);
ST_FUNC int get_reg(int rc);
ST_FUNC void save_regs(int n);
ST_FUNC void gaddrof(void);
ST_FUNC int gv(int rc);
ST_FUNC void gv2(int rc1, int rc2);
ST_FUNC void vpop(void);
ST_FUNC void gen_op(int op);
ST_FUNC int type_size(CType *type, int *a);
ST_FUNC void mk_pointer(CType *type);
ST_FUNC void vstore(void);
ST_FUNC void inc(int post, int c);
ST_FUNC void parse_mult_str (CString *astr, const char *msg);
ST_FUNC void parse_asm_str(CString *astr);
ST_FUNC int lvalue_type(int t);
ST_FUNC void indir(void);
ST_FUNC void unary(void);
ST_FUNC void expr_prod(void);
ST_FUNC void expr_sum(void);
ST_FUNC void gexpr(void);
ST_FUNC int expr_const(void);
ST_FUNC void decl(int l);
#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_C67
ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size);
#endif
#if defined TCC_TARGET_X86_64 && !defined TCC_TARGET_PE
ST_FUNC int classify_x86_64_va_arg(CType *ty);
#endif

/* ------------ tccelf.c ------------ */

#define TCC_OUTPUT_FORMAT_ELF    0 /* default output format: ELF */
#define TCC_OUTPUT_FORMAT_BINARY 1 /* binary image output */
#define TCC_OUTPUT_FORMAT_COFF   2 /* COFF */

#define ARMAG  "!<arch>\012"    /* For COFF and a.out archives */

typedef struct {
    unsigned int n_strx;         /* index into string table of name */
    unsigned char n_type;         /* type of symbol */
    unsigned char n_other;        /* misc info (usually empty) */
    unsigned short n_desc;        /* description field */
    unsigned int n_value;        /* value of symbol */
} Stab_Sym;

ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
ST_DATA Section *common_section;
ST_DATA Section *cur_text_section; /* current section where function code is generated */
#ifdef CONFIG_TCC_ASM
ST_DATA Section *last_text_section; /* to handle .previous asm directive */
#endif
#ifdef CONFIG_TCC_BCHECK
/* bound check related sections */
ST_DATA Section *bounds_section; /* contains global data bound description */
ST_DATA Section *lbounds_section; /* contains local data bound description */
ST_FUNC void tccelf_bounds_new(TCCState *s);
#endif
/* symbol sections */
ST_DATA Section *symtab_section, *strtab_section;
/* debug sections */
ST_DATA Section *stab_section, *stabstr_section;

ST_FUNC void tccelf_new(TCCState *s);
ST_FUNC void tccelf_delete(TCCState *s);
ST_FUNC void tccelf_stab_new(TCCState *s);

ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags);
ST_FUNC void section_realloc(Section *sec, unsigned long new_size);
ST_FUNC size_t section_add(Section *sec, addr_t size, int align);
ST_FUNC void *section_ptr_add(Section *sec, addr_t size);
ST_FUNC void section_reserve(Section *sec, unsigned long size);
ST_FUNC Section *find_section(TCCState *s1, const char *name);
ST_FUNC Section *new_symtab(TCCState *s1, const char *symtab_name, int sh_type, int sh_flags, const char *strtab_name, const char *hash_name, int hash_sh_flags);

ST_FUNC void put_extern_sym2(Sym *sym, Section *section, addr_t value, unsigned long size, int can_add_underscore);
ST_FUNC void put_extern_sym(Sym *sym, Section *section, addr_t value, unsigned long size);
#if PTR_SIZE == 4
ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type);
#endif
ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type, addr_t addend);

ST_FUNC int put_elf_str(Section *s, const char *sym);
ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int shndx, const char *name);
ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int shndx, const char *name);
ST_FUNC int find_elf_sym(Section *s, const char *name);
ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, int type, int symbol);
ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset, int type, int symbol, addr_t addend);

ST_FUNC void put_stabs(const char *str, int type, int other, int desc, unsigned long value);
ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc, unsigned long value, Section *sec, int sym_index);
ST_FUNC void put_stabn(int type, int other, int desc, int value);
ST_FUNC void put_stabd(int type, int other, int desc);

ST_FUNC void relocate_common_syms(void);
ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve);
ST_FUNC void relocate_section(TCCState *s1, Section *s);

ST_FUNC void tcc_add_linker_symbols(TCCState *s1);
ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h);
ST_FUNC int tcc_load_object_file(TCCState *s1, int fd, unsigned long file_offset);
ST_FUNC int tcc_load_archive(TCCState *s1, int fd);
ST_FUNC void tcc_add_bcheck(TCCState *s1);
ST_FUNC void tcc_add_runtime(TCCState *s1);

ST_FUNC void build_got_entries(TCCState *s1);
ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc);
ST_FUNC void squeeze_multi_relocs(Section *sec, size_t oldrelocoffset);

ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err);
#if defined TCC_IS_NATIVE || defined TCC_TARGET_PE
ST_FUNC void *tcc_get_symbol_err(TCCState *s, const char *name);
#endif

#ifndef TCC_TARGET_PE
ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level);
ST_FUNC int tcc_load_ldscript(TCCState *s1);
ST_FUNC uint8_t *parse_comment(uint8_t *p);
ST_FUNC void minp(void);
ST_INLN void inp(void);
ST_FUNC int handle_eob(void);
#endif

/* ------------ xxx-link.c ------------ */

/* Wether to generate a GOT/PLT entry and when. NO_GOTPLT_ENTRY is first so
   that unknown relocation don't create a GOT or PLT entry */
enum gotplt_entry {
    NO_GOTPLT_ENTRY,    /* never generate (eg. GLOB_DAT & JMP_SLOT relocs) */
    BUILD_GOT_ONLY, /* only build GOT (eg. TPOFF relocs) */
    AUTO_GOTPLT_ENTRY,  /* generate if sym is UNDEF */
    ALWAYS_GOTPLT_ENTRY /* always generate (eg. PLTOFF relocs) */
};

ST_FUNC int code_reloc (int reloc_type);
ST_FUNC int gotplt_entry_type (int reloc_type);
ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr);
ST_FUNC void relocate_init(Section *sr);
ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val);
ST_FUNC void relocate_plt(TCCState *s1);

/* ------------ xxx-gen.c ------------ */

ST_DATA const int reg_classes[NB_REGS];

ST_FUNC void gsym_addr(int t, int a);
ST_FUNC void gsym(int t);
ST_FUNC void load(int r, SValue *sv);
ST_FUNC void store(int r, SValue *v);
ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *align, int *regsize);
ST_FUNC void gfunc_call(int nb_args);
ST_FUNC void gfunc_prolog(CType *func_type);
ST_FUNC void gfunc_epilog(void);
ST_FUNC int gjmp(int t);
ST_FUNC void gjmp_addr(int a);
ST_FUNC int gtst(int inv, int t);
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
ST_FUNC void gtst_addr(int inv, int a);
#else
#define gtst_addr(inv, a) gsym_addr(gtst(inv, 0), a)
#endif
ST_FUNC void gen_opi(int op);
ST_FUNC void gen_opf(int op);
ST_FUNC void gen_cvt_ftoi(int t);
ST_FUNC void gen_cvt_ftof(int t);
ST_FUNC void ggoto(void);
#ifndef TCC_TARGET_C67
ST_FUNC void o(unsigned int c);
#endif
#ifndef TCC_TARGET_ARM
ST_FUNC void gen_cvt_itof(int t);
#endif
ST_FUNC void gen_vla_sp_save(int addr);
ST_FUNC void gen_vla_sp_restore(int addr);
ST_FUNC void gen_vla_alloc(CType *type, int align);

static inline uint16_t read16le(unsigned char *p) {
    return p[0] | (uint16_t)p[1] << 8;
}
static inline void write16le(unsigned char *p, uint16_t x) {
    p[0] = x & 255, p[1] = x >> 8 & 255;
}
static inline uint32_t read32le(unsigned char *p) {
  return read16le(p) | (uint32_t)read16le(p + 2) << 16;
}
static inline void write32le(unsigned char *p, uint32_t x) {
    write16le(p, x), write16le(p + 2, x >> 16);
}
static inline void add32le(unsigned char *p, int32_t x) {
    write32le(p, read32le(p) + x);
}
#if HAVE_LONG_LONG
static inline uint64_t read64le(unsigned char *p) {
  return read32le(p) | (uint64_t)read32le(p + 4) << 32;
}
static inline void write64le(unsigned char *p, uint64_t x) {
    write32le(p, x), write32le(p + 4, x >> 32);
}
static inline void add64le(unsigned char *p, int64_t x) {
    write64le(p, read64le(p) + x);
}
#endif
/* ------------ i386-gen.c ------------ */
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
ST_FUNC void g(int c);
ST_FUNC void gen_le16(int c);
ST_FUNC void gen_le32(int c);
ST_FUNC void gen_addr32(int r, Sym *sym, long c);
ST_FUNC void gen_addrpc32(int r, Sym *sym, long c);
#endif

#ifdef CONFIG_TCC_BCHECK
ST_FUNC void gen_bounded_ptr_add(void);
ST_FUNC void gen_bounded_ptr_deref(void);
#endif

/* ------------ x86_64-gen.c ------------ */
#ifdef TCC_TARGET_X86_64
ST_FUNC void gen_addr64(int r, Sym *sym, int64_t c);
ST_FUNC void gen_opl(int op);
#endif

/* ------------ arm-gen.c ------------ */
#ifdef TCC_TARGET_ARM
#if defined(TCC_ARM_EABI) && !defined(CONFIG_TCC_ELFINTERP)
PUB_FUNC const char *default_elfinterp(struct TCCState *s);
#endif
ST_FUNC void arm_init(struct TCCState *s);
ST_FUNC void gen_cvt_itof1(int t);
#endif

/* ------------ arm64-gen.c ------------ */
#ifdef TCC_TARGET_ARM64
ST_FUNC void gen_cvt_sxtw(void);
ST_FUNC void gen_opl(int op);
ST_FUNC void gfunc_return(CType *func_type);
ST_FUNC void gen_va_start(void);
ST_FUNC void gen_va_arg(CType *t);
ST_FUNC void gen_clear_cache(void);
#endif

/* ------------ c67-gen.c ------------ */
#ifdef TCC_TARGET_C67
#endif

/* ------------ tcccoff.c ------------ */

#ifdef TCC_TARGET_COFF
ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f);
ST_FUNC int tcc_load_coff(TCCState * s1, int fd);
#endif

/* ------------ tccasm.c ------------ */
ST_FUNC void asm_instr(void);
ST_FUNC void asm_global_instr(void);
#ifdef CONFIG_TCC_ASM
ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands, const char *name, const char **pp);
ST_FUNC Sym* get_asm_sym(int name, Sym *csym);
ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe);
ST_FUNC int asm_int_expr(TCCState *s1);
ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess);
/* ------------ i386-asm.c ------------ */
ST_FUNC void gen_expr32(ExprValue *pe);
#ifdef TCC_TARGET_X86_64
ST_FUNC void gen_expr64(ExprValue *pe);
#endif
ST_FUNC void asm_opcode(TCCState *s1, int opcode);
ST_FUNC int asm_parse_regvar(int t);
ST_FUNC void asm_compute_constraints(ASMOperand *operands, int nb_operands, int nb_outputs, const uint8_t *clobber_regs, int *pout_reg);
ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier);
ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, int nb_outputs, int is_output, uint8_t *clobber_regs, int out_reg);
ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str);
#endif

/* ------------ tccpe.c -------------- */
#ifdef TCC_TARGET_PE
ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, int fd);
ST_FUNC int pe_output_file(TCCState * s1, const char *filename);
ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t value);
#ifndef TCC_TARGET_ARM
ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2);
#endif
#ifdef TCC_TARGET_X86_64
ST_FUNC void pe_add_unwind_data(unsigned start, unsigned end, unsigned stack);
#endif
PUB_FUNC int tcc_get_dllexports(const char *filename, char **pp);
/* symbol properties stored in Elf32_Sym->st_other */
# define ST_PE_EXPORT 0x10
# define ST_PE_IMPORT 0x20
# define ST_PE_STDCALL 0x40
#endif

/* ------------ tccrun.c ----------------- */
#ifdef TCC_IS_NATIVE
#ifdef CONFIG_TCC_STATIC
#define RTLD_LAZY       0x001
#define RTLD_NOW        0x002
#define RTLD_GLOBAL     0x100
#define RTLD_DEFAULT    NULL
/* dummy function for profiling */
ST_FUNC void *dlopen(const char *filename, int flag);
ST_FUNC void dlclose(void *p);
ST_FUNC const char *dlerror(void);
ST_FUNC void *dlsym(void *handle, const char *symbol);
#endif
#ifdef CONFIG_TCC_BACKTRACE
ST_DATA int rt_num_callers;
ST_DATA const char **rt_bound_error_msg;
ST_DATA void *rt_prog_main;
ST_FUNC void tcc_set_num_callers(int n);
#endif
ST_FUNC void tcc_run_free(TCCState *s1);
#endif

/* ------------ tcctools.c ----------------- */
#if 0 /* included in tcc.c */
ST_FUNC int tcc_tool_ar(TCCState *s, int argc, char **argv);
#ifdef TCC_TARGET_PE
ST_FUNC int tcc_tool_impdef(TCCState *s, int argc, char **argv);
#endif
ST_FUNC void tcc_tool_cross(TCCState *s, char **argv, int option);
ST_FUNC void gen_makedeps(TCCState *s, const char *target, const char *filename);
#endif

/********************************************************/
#undef ST_DATA
#ifdef ONE_SOURCE
#define ST_DATA static
#else
#define ST_DATA
#endif
/********************************************************/
#endif /* _TCC_H */

https://gitlab.com/janneke/tinycc/-/blob/ff2210b308321f27ee07476d07f24b5095602b17/tccpp.c

File: ../git/live-bootstrap/sysa/tcc-0.9.26/build/tcc-0.9.26-1136-g5bba73cc/tccpp.c used in: Step 378, Step 395, Step 407, Step 419, Step 431, Step 443, Step 455
/*
 *  TCC - Tiny C Compiler
 * 
 *  Copyright (c) 2001-2004 Fabrice Bellard
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef _TCC_H
#include "tcc.h"
#endif

#if BOOTSTRAP && __arm__
void
tccpp_ok ()
{
}
#endif

/********************************************************/
/* global variables */

ST_DATA int tok_flags;
ST_DATA int parse_flags;

ST_DATA struct BufferedFile *file;
ST_DATA int ch, tok;
ST_DATA CValue tokc;
ST_DATA const int *macro_ptr;
ST_DATA CString tokcstr; /* current parsed string, if any */

/* display benchmark infos */
ST_DATA int total_lines;
ST_DATA int total_bytes;
ST_DATA int tok_ident;
ST_DATA TokenSym **table_ident;

/* ------------------------------------------------------------------------- */

static TokenSym *hash_ident[TOK_HASH_SIZE];
static char token_buf[STRING_MAX_SIZE + 1];
static CString cstr_buf;
static CString macro_equal_buf;
static TokenString tokstr_buf;
static unsigned char isidnum_table[256 - CH_EOF];
static int pp_debug_tok, pp_debug_symv;
static int pp_once;
static void tok_print(const char *msg, const int *str);

static struct TinyAlloc *toksym_alloc;
static struct TinyAlloc *tokstr_alloc;
static struct TinyAlloc *cstr_alloc;

static TokenString *macro_stack;

static const char tcc_keywords[] = 
#define DEF(id, str) str "\0"
#include "tcctok.h"
#undef DEF
;

/* WARNING: the content of this string encodes token numbers */
static const unsigned char tok_two_chars[] =
/* outdated -- gr
    "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253"
    "-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
*/{
    '<','=', TOK_LE,
    '>','=', TOK_GE,
    '!','=', TOK_NE,
    '&','&', TOK_LAND,
    '|','|', TOK_LOR,
    '+','+', TOK_INC,
    '-','-', TOK_DEC,
    '=','=', TOK_EQ,
    '<','<', TOK_SHL,
    '>','>', TOK_SAR,
    '+','=', TOK_A_ADD,
    '-','=', TOK_A_SUB,
    '*','=', TOK_A_MUL,
    '/','=', TOK_A_DIV,
    '%','=', TOK_A_MOD,
    '&','=', TOK_A_AND,
    '^','=', TOK_A_XOR,
    '|','=', TOK_A_OR,
    '-','>', TOK_ARROW,
    '.','.', 0xa8, // C++ token ?
    '#','#', TOK_TWOSHARPS,
    0
};

static void next_nomacro_spc(void);

ST_FUNC void skip(int c)
{
    if (tok != c)
        tcc_error("'%c' expected (got \"%s\")", c, get_tok_str(tok, &tokc));
    next();
}

ST_FUNC void expect(const char *msg)
{
    tcc_error("%s expected", msg);
}

/* ------------------------------------------------------------------------- */
/* Custom allocator for tiny objects */

#define USE_TAL

#ifndef USE_TAL
#define tal_free(al, p) tcc_free(p)
#define tal_realloc(al, p, size) tcc_realloc(p, size)
#define tal_new(a,b,c)
#define tal_delete(a)
#else
#if !defined(MEM_DEBUG)
#define tal_free(al, p) tal_free_impl(al, p)
#define tal_realloc(al, p, size) tal_realloc_impl(&al, p, size)
#define TAL_DEBUG_PARAMS
#else
#define TAL_DEBUG 1
//#define TAL_INFO 1 /* collect and dump allocators stats */
#define tal_free(al, p) tal_free_impl(al, p, __FILE__, __LINE__)
#define tal_realloc(al, p, size) tal_realloc_impl(&al, p, size, __FILE__, __LINE__)
#define TAL_DEBUG_PARAMS , const char *file, int line
#define TAL_DEBUG_FILE_LEN 15
#endif

#define TOKSYM_TAL_SIZE     (768 * 1024) /* allocator for tiny TokenSym in table_ident */
#define TOKSTR_TAL_SIZE     (768 * 1024) /* allocator for tiny TokenString instances */
#define CSTR_TAL_SIZE       (256 * 1024) /* allocator for tiny CString instances */
#define TOKSYM_TAL_LIMIT    256 /* prefer unique limits to distinguish allocators debug msgs */
#define TOKSTR_TAL_LIMIT    128 /* 32 * sizeof(int) */
#define CSTR_TAL_LIMIT      1024

typedef struct TinyAlloc {
    unsigned  limit;
    unsigned  size;
    uint8_t *buffer;
    uint8_t *p;
    unsigned  nb_allocs;
    struct TinyAlloc *next, *top;
#ifdef TAL_INFO
    unsigned  nb_peak;
    unsigned  nb_total;
    unsigned  nb_missed;
    uint8_t *peak_p;
#endif
} TinyAlloc;

typedef struct tal_header_t {
    unsigned  size;
#ifdef TAL_DEBUG
    int     line_num; /* negative line_num used for double free check */
    char    file_name[TAL_DEBUG_FILE_LEN + 1];
#endif
} tal_header_t;

/* ------------------------------------------------------------------------- */

static TinyAlloc *tal_new(TinyAlloc **pal, unsigned limit, unsigned size)
{
    TinyAlloc *al = tcc_mallocz(sizeof(TinyAlloc));
    al->p = al->buffer = tcc_malloc(size);
    al->limit = limit;
    al->size = size;
    if (pal) *pal = al;
    return al;
}

static void tal_delete(TinyAlloc *al)
{
    TinyAlloc *next;

tail_call:
    if (!al)
        return;
#ifdef TAL_INFO
    fprintf(stderr, "limit=%5d, size=%5g MB, nb_peak=%6d, nb_total=%8d, nb_missed=%6d, usage=%5.1f%%\n",
            al->limit, al->size / 1024.0 / 1024.0, al->nb_peak, al->nb_total, al->nb_missed,
            (al->peak_p - al->buffer) * 100.0 / al->size);
#endif
#ifdef TAL_DEBUG
    if (al->nb_allocs > 0) {
        uint8_t *p;
        fprintf(stderr, "TAL_DEBUG: memory leak %d chunk(s) (limit= %d)\n",
                al->nb_allocs, al->limit);
        p = al->buffer;
        while (p < al->p) {
            tal_header_t *header = (tal_header_t *)p;
            if (header->line_num > 0) {
                fprintf(stderr, "%s:%d: chunk of %d bytes leaked\n",
                        header->file_name, header->line_num, header->size);
            }
            p += header->size + sizeof(tal_header_t);
        }
#if MEM_DEBUG-0 == 2
        exit(2);
#endif
    }
#endif
    next = al->next;
    tcc_free(al->buffer);
    tcc_free(al);
    al = next;
    goto tail_call;
}

static void tal_free_impl(TinyAlloc *al, void *p TAL_DEBUG_PARAMS)
{
    if (!p)
        return;
tail_call:
    if (al->buffer <= (uint8_t *)p && (uint8_t *)p < al->buffer + al->size) {
#ifdef TAL_DEBUG
        tal_header_t *header = (((tal_header_t *)p) - 1);
        if (header->line_num < 0) {
            fprintf(stderr, "%s:%d: TAL_DEBUG: double frees chunk from\n",
                    file, line);
            fprintf(stderr, "%s:%d: %d bytes\n",
                    header->file_name, (int)-header->line_num, (int)header->size);
        } else
            header->line_num = -header->line_num;
#endif
        al->nb_allocs--;
        if (!al->nb_allocs)
            al->p = al->buffer;
    } else if (al->next) {
        al = al->next;
        goto tail_call;
    }
    else
        tcc_free(p);
}

static void *tal_realloc_impl(TinyAlloc **pal, void *p, unsigned size TAL_DEBUG_PARAMS)
{
    tal_header_t *header;
    void *ret;
    int is_own;
    unsigned adj_size = (size + 3) & -4;
    TinyAlloc *al = *pal;

tail_call:
    is_own = (al->buffer <= (uint8_t *)p && (uint8_t *)p < al->buffer + al->size);
    if ((!p || is_own) && size <= al->limit) {
        if (al->p + adj_size + sizeof(tal_header_t) < al->buffer + al->size) {
            header = (tal_header_t *)al->p;
            header->size = adj_size;
#ifdef TAL_DEBUG
            { int ofs = strlen(file) - TAL_DEBUG_FILE_LEN;
            strncpy(header->file_name, file + (ofs > 0 ? ofs : 0), TAL_DEBUG_FILE_LEN);
            header->file_name[TAL_DEBUG_FILE_LEN] = 0;
            header->line_num = line; }
#endif
            ret = al->p + sizeof(tal_header_t);
            al->p += adj_size + sizeof(tal_header_t);
            if (is_own) {
                header = (((tal_header_t *)p) - 1);
                memcpy(ret, p, header->size);
#ifdef TAL_DEBUG
                header->line_num = -header->line_num;
#endif
            } else {
                al->nb_allocs++;
            }
#ifdef TAL_INFO
            if (al->nb_peak < al->nb_allocs)
                al->nb_peak = al->nb_allocs;
            if (al->peak_p < al->p)
                al->peak_p = al->p;
            al->nb_total++;
#endif
            return ret;
        } else if (is_own) {
            al->nb_allocs--;
            ret = tal_realloc(*pal, 0, size);
            header = (((tal_header_t *)p) - 1);
            memcpy(ret, p, header->size);
#ifdef TAL_DEBUG
            header->line_num = -header->line_num;
#endif
            return ret;
        }
        if (al->next) {
            al = al->next;
        } else {
            TinyAlloc *bottom = al, *next = al->top ? al->top : al;

            al = tal_new(pal, next->limit, next->size * 2);
            al->next = next;
            bottom->top = al;
        }
        goto tail_call;
    }
    if (is_own) {
        al->nb_allocs--;
        ret = tcc_malloc(size);
        header = (((tal_header_t *)p) - 1);
        memcpy(ret, p, header->size);
#ifdef TAL_DEBUG
        header->line_num = -header->line_num;
#endif
    } else if (al->next) {
        al = al->next;
        goto tail_call;
    } else
        ret = tcc_realloc(p, size);
#ifdef TAL_INFO
    al->nb_missed++;
#endif
    return ret;
}

#endif /* USE_TAL */

/* ------------------------------------------------------------------------- */
/* CString handling */
static void cstr_realloc(CString *cstr, int new_size)
{
    int size;

    size = cstr->size_allocated;
    if (size < 8)
        size = 8; /* no need to allocate a too small first string */
    while (size < new_size)
        size = size * 2;
    cstr->data = tal_realloc(cstr_alloc, cstr->data, size);
    cstr->size_allocated = size;
}

/* add a byte */
ST_INLN void cstr_ccat(CString *cstr, int ch)
{
    int size;
    size = cstr->size + 1;
    if (size > cstr->size_allocated)
        cstr_realloc(cstr, size);
    ((unsigned char *)cstr->data)[size - 1] = ch;
    cstr->size = size;
}

ST_FUNC void cstr_cat(CString *cstr, const char *str, int len)
{
    int size;
    if (len <= 0)
        len = strlen(str) + 1 + len;
    size = cstr->size + len;
    if (size > cstr->size_allocated)
        cstr_realloc(cstr, size);
    memmove(((unsigned char *)cstr->data) + cstr->size, str, len);
    cstr->size = size;
}

/* add a wide char */
ST_FUNC void cstr_wccat(CString *cstr, int ch)
{
    int size;
    size = cstr->size + sizeof(nwchar_t);
    if (size > cstr->size_allocated)
        cstr_realloc(cstr, size);
    *(nwchar_t *)(((unsigned char *)cstr->data) + size - sizeof(nwchar_t)) = ch;
    cstr->size = size;
}

ST_FUNC void cstr_new(CString *cstr)
{
    memset(cstr, 0, sizeof(CString));
}

/* free string and reset it to NULL */
ST_FUNC void cstr_free(CString *cstr)
{
    tal_free(cstr_alloc, cstr->data);
    cstr_new(cstr);
}

/* reset string to empty */
ST_FUNC void cstr_reset(CString *cstr)
{
    cstr->size = 0;
}

/* XXX: unicode ? */
static void add_char(CString *cstr, int c)
{
    if (c == '\'' || c == '\"' || c == '\\') {
        /* XXX: could be more precise if char or string */
        cstr_ccat(cstr, '\\');
    }
    if (c >= 32 && c <= 126) {
        cstr_ccat(cstr, c);
    } else {
        cstr_ccat(cstr, '\\');
        if (c == '\n') {
            cstr_ccat(cstr, 'n');
        } else {
            cstr_ccat(cstr, '0' + ((c >> 6) & 7));
            cstr_ccat(cstr, '0' + ((c >> 3) & 7));
            cstr_ccat(cstr, '0' + (c & 7));
        }
    }
}

/* ------------------------------------------------------------------------- */
/* allocate a new token */
static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
{
    TokenSym *ts, **ptable;
    int i;

    if (tok_ident >= SYM_FIRST_ANOM) 
        tcc_error("memory full (symbols)");

    /* expand token table if needed */
    i = tok_ident - TOK_IDENT;
    if ((i % TOK_ALLOC_INCR) == 0) {
        ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
        table_ident = ptable;
    }

    ts = tal_realloc(toksym_alloc, 0, sizeof(TokenSym) + len);
    table_ident[i] = ts;
    ts->tok = tok_ident++;
    ts->sym_define = NULL;
    ts->sym_label = NULL;
    ts->sym_struct = NULL;
    ts->sym_identifier = NULL;
    ts->len = len;
    ts->hash_next = NULL;
    memcpy(ts->str, str, len);
    ts->str[len] = '\0';
    *pts = ts;
    return ts;
}

#define TOK_HASH_INIT 1
#define TOK_HASH_FUNC(h, c) ((h) + ((h) << 5) + ((h) >> 27) + (c))


/* find a token and add it if not found */
ST_FUNC TokenSym *tok_alloc(const char *str, int len)
{
    TokenSym *ts, **pts;
    int i;
    unsigned int h;
    
    h = TOK_HASH_INIT;
    for(i=0;i<len;i++)
        h = TOK_HASH_FUNC(h, ((unsigned char *)str)[i]);
    h &= (TOK_HASH_SIZE - 1);

    pts = &hash_ident[h];
    for(;;) {
        ts = *pts;
        if (!ts)
            break;
        if (ts->len == len && !memcmp(ts->str, str, len))
            return ts;
        pts = &(ts->hash_next);
    }
    return tok_alloc_new(pts, str, len);
}

/* XXX: buffer overflow */
/* XXX: float tokens */
ST_FUNC const char *get_tok_str(int v, CValue *cv)
{
    char *p;
    int i, len;

    cstr_reset(&cstr_buf);
    p = cstr_buf.data;

    switch(v) {
    case TOK_CINT:
    case TOK_CUINT:
    case TOK_CLLONG:
    case TOK_CULLONG:
        /* XXX: not quite exact, but only useful for testing  */
#ifdef _WIN32
        sprintf(p, "%u", (unsigned)cv->i);
#else
        sprintf(p, "%llu", (unsigned long long)cv->i);
#endif
        break;
    case TOK_LCHAR:
        cstr_ccat(&cstr_buf, 'L');
    case TOK_CCHAR:
        cstr_ccat(&cstr_buf, '\'');
        add_char(&cstr_buf, cv->i);
        cstr_ccat(&cstr_buf, '\'');
        cstr_ccat(&cstr_buf, '\0');
        break;
    case TOK_PPNUM:
    case TOK_PPSTR:
        return (char*)cv->str.data;
    case TOK_LSTR:
        cstr_ccat(&cstr_buf, 'L');
    case TOK_STR:
        cstr_ccat(&cstr_buf, '\"');
        if (v == TOK_STR) {
            len = cv->str.size - 1;
            for(i=0;i<len;i++)
                add_char(&cstr_buf, ((unsigned char *)cv->str.data)[i]);
        } else {
            len = (cv->str.size / sizeof(nwchar_t)) - 1;
            for(i=0;i<len;i++)
                add_char(&cstr_buf, ((nwchar_t *)cv->str.data)[i]);
        }
        cstr_ccat(&cstr_buf, '\"');
        cstr_ccat(&cstr_buf, '\0');
        break;

    case TOK_CFLOAT:
        cstr_cat(&cstr_buf, "<float>", 0);
        break;
    case TOK_CDOUBLE:
    cstr_cat(&cstr_buf, "<double>", 0);
    break;
    case TOK_CLDOUBLE:
    cstr_cat(&cstr_buf, "<long double>", 0);
    break;
    case TOK_LINENUM:
    cstr_cat(&cstr_buf, "<linenumber>", 0);
    break;

    /* above tokens have value, the ones below don't */

    case TOK_LT:
        v = '<';
        goto addv;
    case TOK_GT:
        v = '>';
        goto addv;
    case TOK_DOTS:
        return strcpy(p, "...");
    case TOK_A_SHL:
        return strcpy(p, "<<=");
    case TOK_A_SAR:
        return strcpy(p, ">>=");
    default:
        if (v < TOK_IDENT) {
            /* search in two bytes table */
            const unsigned char *q = tok_two_chars;
            while (*q) {
                if (q[2] == v) {
                    *p++ = q[0];
                    *p++ = q[1];
                    *p = '\0';
                    return cstr_buf.data;
                }
                q += 3;
            }
        if (v >= 127) {
            sprintf(cstr_buf.data, "<%02x>", v);
            return cstr_buf.data;
        }
        addv:
            *p++ = v;
            *p = '\0';
        } else if (v < tok_ident) {
            return table_ident[v - TOK_IDENT]->str;
        } else if (v >= SYM_FIRST_ANOM) {
            /* special name for anonymous symbol */
            sprintf(p, "L.%u", v - SYM_FIRST_ANOM);
        } else {
            /* should never happen */
            return NULL;
        }
        break;
    }
    return cstr_buf.data;
}

/* return the current character, handling end of block if necessary
   (but not stray) */
ST_FUNC int handle_eob(void)
{
    BufferedFile *bf = file;
    int len;

    /* only tries to read if really end of buffer */
    if (bf->buf_ptr >= bf->buf_end) {
        if (bf->fd != -1) {
#if defined(PARSE_DEBUG)
            len = 1;
#else
            len = IO_BUF_SIZE;
#endif
            len = read(bf->fd, bf->buffer, len);
            if (len < 0)
                len = 0;
        } else {
            len = 0;
        }
        total_bytes += len;
        bf->buf_ptr = bf->buffer;
        bf->buf_end = bf->buffer + len;
        *bf->buf_end = CH_EOB;
    }
    if (bf->buf_ptr < bf->buf_end) {
        return bf->buf_ptr[0];
    } else {
        bf->buf_ptr = bf->buf_end;
        return CH_EOF;
    }
}

/* read next char from current input file and handle end of input buffer */
ST_INLN void inp(void)
{
    ch = *(++(file->buf_ptr));
    /* end of buffer/file handling */
    if (ch == CH_EOB)
        ch = handle_eob();
}

/* handle '\[\r]\n' */
static int handle_stray_noerror(void)
{
    while (ch == '\\') {
        inp();
        if (ch == '\n') {
            file->line_num++;
            inp();
        } else if (ch == '\r') {
            inp();
            if (ch != '\n')
                goto fail;
            file->line_num++;
            inp();
        } else {
        fail:
            return 1;
        }
    }
    return 0;
}

static void handle_stray(void)
{
    if (handle_stray_noerror())
        tcc_error("stray '\\' in program");
}

/* skip the stray and handle the \\n case. Output an error if
   incorrect char after the stray */
static int handle_stray1(uint8_t *p)
{
    int c;

    file->buf_ptr = p;
    if (p >= file->buf_end) {
        c = handle_eob();
        if (c != '\\')
            return c;
        p = file->buf_ptr;
    }
    ch = *p;
    if (handle_stray_noerror()) {
        if (!(parse_flags & PARSE_FLAG_ACCEPT_STRAYS))
            tcc_error("stray '\\' in program");
        *--file->buf_ptr = '\\';
    }
    p = file->buf_ptr;
    c = *p;
    return c;
}

/* handle just the EOB case, but not stray */
#define PEEKC_EOB(c, p)\
{\
    p++;\
    c = *p;\
    if (c == '\\') {\
        file->buf_ptr = p;\
        c = handle_eob();\
        p = file->buf_ptr;\
    }\
}

/* handle the complicated stray case */
#define PEEKC(c, p)\
{\
    p++;\
    c = *p;\
    if (c == '\\') {\
        c = handle_stray1(p);\
        p = file->buf_ptr;\
    }\
}

/* input with '\[\r]\n' handling. Note that this function cannot
   handle other characters after '\', so you cannot call it inside
   strings or comments */
ST_FUNC void minp(void)
{
    inp();
    if (ch == '\\') 
        handle_stray();
}

/* single line C++ comments */
static uint8_t *parse_line_comment(uint8_t *p)
{
    int c;

    p++;
    for(;;) {
        c = *p;
    redo:
        if (c == '\n' || c == CH_EOF) {
            break;
        } else if (c == '\\') {
            file->buf_ptr = p;
            c = handle_eob();
            p = file->buf_ptr;
            if (c == '\\') {
                PEEKC_EOB(c, p);
                if (c == '\n') {
                    file->line_num++;
                    PEEKC_EOB(c, p);
                } else if (c == '\r') {
                    PEEKC_EOB(c, p);
                    if (c == '\n') {
                        file->line_num++;
                        PEEKC_EOB(c, p);
                    }
                }
            } else {
                goto redo;
            }
        } else {
            p++;
        }
    }
    return p;
}

/* C comments */
ST_FUNC uint8_t *parse_comment(uint8_t *p)
{
    int c;

    p++;
    for(;;) {
        /* fast skip loop */
        for(;;) {
            c = *p;
            if (c == '\n' || c == '*' || c == '\\')
                break;
            p++;
            c = *p;
            if (c == '\n' || c == '*' || c == '\\')
                break;
            p++;
        }
        /* now we can handle all the cases */
        if (c == '\n') {
            file->line_num++;
            p++;
        } else if (c == '*') {
            p++;
            for(;;) {
                c = *p;
                if (c == '*') {
                    p++;
                } else if (c == '/') {
                    goto end_of_comment;
                } else if (c == '\\') {
                    file->buf_ptr = p;
                    c = handle_eob();
                    p = file->buf_ptr;
                    if (c == CH_EOF)
                        tcc_error("unexpected end of file in comment");
                    if (c == '\\') {
                        /* skip '\[\r]\n', otherwise just skip the stray */
                        while (c == '\\') {
                            PEEKC_EOB(c, p);
                            if (c == '\n') {
                                file->line_num++;
                                PEEKC_EOB(c, p);
                            } else if (c == '\r') {
                                PEEKC_EOB(c, p);
                                if (c == '\n') {
                                    file->line_num++;
                                    PEEKC_EOB(c, p);
                                }
                            } else {
                                goto after_star;
                            }
                        }
                    }
                } else {
                    break;
                }
            }
        after_star: ;
        } else {
            /* stray, eob or eof */
            file->buf_ptr = p;
            c = handle_eob();
            p = file->buf_ptr;
            if (c == CH_EOF) {
                tcc_error("unexpected end of file in comment");
            } else if (c == '\\') {
                p++;
            }
        }
    }
 end_of_comment:
    p++;
    return p;
}

ST_FUNC void set_idnum(int c, int val)
{
    isidnum_table[c - CH_EOF] = val;
}

#define cinp minp

static inline void skip_spaces(void)
{
    while (isidnum_table[ch - CH_EOF] & IS_SPC)
        cinp();
}

static inline int check_space(int t, int *spc) 
{
    if (t < 256 && (isidnum_table[t - CH_EOF] & IS_SPC)) {
        if (*spc) 
            return 1;
        *spc = 1;
    } else 
        *spc = 0;
    return 0;
}

/* parse a string without interpreting escapes */
static uint8_t *parse_pp_string(uint8_t *p,
                                int sep, CString *str)
{
    int c;
    p++;
    for(;;) {
        c = *p;
        if (c == sep) {
            break;
        } else if (c == '\\') {
            file->buf_ptr = p;
            c = handle_eob();
            p = file->buf_ptr;
            if (c == CH_EOF) {
            unterminated_string:
                /* XXX: indicate line number of start of string */
                tcc_error("missing terminating %c character", sep);
            } else if (c == '\\') {
                /* escape : just skip \[\r]\n */
                PEEKC_EOB(c, p);
                if (c == '\n') {
                    file->line_num++;
                    p++;
                } else if (c == '\r') {
                    PEEKC_EOB(c, p);
                    if (c != '\n')
                        expect("'\n' after '\r'");
                    file->line_num++;
                    p++;
                } else if (c == CH_EOF) {
                    goto unterminated_string;
                } else {
                    if (str) {
                        cstr_ccat(str, '\\');
                        cstr_ccat(str, c);
                    }
                    p++;
                }
            }
        } else if (c == '\n') {
            file->line_num++;
            goto add_char;
        } else if (c == '\r') {
            PEEKC_EOB(c, p);
            if (c != '\n') {
                if (str)
                    cstr_ccat(str, '\r');
            } else {
                file->line_num++;
                goto add_char;
            }
        } else {
        add_char:
            if (str)
                cstr_ccat(str, c);
            p++;
        }
    }
    p++;
    return p;
}

/* skip block of text until #else, #elif or #endif. skip also pairs of
   #if/#endif */
static void preprocess_skip(void)
{
    int a, start_of_line, c, in_warn_or_error;
    uint8_t *p;

    p = file->buf_ptr;
    a = 0;
redo_start:
    start_of_line = 1;
    in_warn_or_error = 0;
    for(;;) {
    redo_no_start:
        c = *p;
        switch(c) {
        case ' ':
        case '\t':
        case '\f':
        case '\v':
        case '\r':
            p++;
            goto redo_no_start;
        case '\n':
            file->line_num++;
            p++;
            goto redo_start;
        case '\\':
            file->buf_ptr = p;
            c = handle_eob();
            if (c == CH_EOF) {
                expect("#endif");
            } else if (c == '\\') {
                ch = file->buf_ptr[0];
                handle_stray_noerror();
            }
            p = file->buf_ptr;
            goto redo_no_start;
        /* skip strings */
        case '\"':
        case '\'':
            if (in_warn_or_error)
                goto _default;
            p = parse_pp_string(p, c, NULL);
            break;
        /* skip comments */
        case '/':
            if (in_warn_or_error)
                goto _default;
            file->buf_ptr = p;
            ch = *p;
            minp();
            p = file->buf_ptr;
            if (ch == '*') {
                p = parse_comment(p);
            } else if (ch == '/') {
                p = parse_line_comment(p);
            }
            break;
        case '#':
            p++;
            if (start_of_line) {
                file->buf_ptr = p;
                next_nomacro();
                p = file->buf_ptr;
                if (a == 0 && 
                    (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
                    goto the_end;
                if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
                    a++;
                else if (tok == TOK_ENDIF)
                    a--;
                else if( tok == TOK_ERROR || tok == TOK_WARNING)
                    in_warn_or_error = 1;
                else if (tok == TOK_LINEFEED)
                    goto redo_start;
                else if (parse_flags & PARSE_FLAG_ASM_FILE)
                    p = parse_line_comment(p - 1);
            } else if (parse_flags & PARSE_FLAG_ASM_FILE)
                p = parse_line_comment(p - 1);
            break;
_default:
        default:
            p++;
            break;
        }
        start_of_line = 0;
    }
 the_end: ;
    file->buf_ptr = p;
}

/* ParseState handling */

/* XXX: currently, no include file info is stored. Thus, we cannot display
   accurate messages if the function or data definition spans multiple
   files */

/* save current parse state in 's' */
ST_FUNC void save_parse_state(ParseState *s)
{
    s->line_num = file->line_num;
    s->macro_ptr = macro_ptr;
    s->tok = tok;
    s->tokc = tokc;
}

/* restore parse state from 's' */
ST_FUNC void restore_parse_state(ParseState *s)
{
    file->line_num = s->line_num;
    macro_ptr = s->macro_ptr;
    tok = s->tok;
    tokc = s->tokc;
}

#if 0
/* return the number of additional 'ints' necessary to store the
   token */
static inline int tok_size(const int *p)
{
    switch(*p) {
        /* 4 bytes */
    case TOK_CINT:
    case TOK_CUINT:
    case TOK_CCHAR:
    case TOK_LCHAR:
    case TOK_CFLOAT:
    case TOK_LINENUM:
        return 1 + 1;
    case TOK_STR:
    case TOK_LSTR:
    case TOK_PPNUM:
    case TOK_PPSTR:
        return 1 + ((sizeof(CString) + ((CString *)(p+1))->size + 3) >> 2);
    case TOK_CDOUBLE:
    case TOK_CLLONG:
    case TOK_CULLONG:
        return 1 + 2;
    case TOK_CLDOUBLE:
        return 1 + LDOUBLE_SIZE / 4;
    default:
        return 1 + 0;
    }
}
#endif

/* token string handling */
ST_INLN void tok_str_new(TokenString *s)
{
    s->str = NULL;
    s->len = 0;
    s->allocated_len = 0;
    s->last_line_num = -1;
}

ST_FUNC TokenString *tok_str_alloc(void)
{
    TokenString *str = tal_realloc(tokstr_alloc, 0, sizeof *str);
    tok_str_new(str);
    return str;
}

ST_FUNC int *tok_str_dup(TokenString *s)
{
    int *str;

    str = tal_realloc(tokstr_alloc, 0, s->len * sizeof(int));
    memcpy(str, s->str, s->len * sizeof(int));
    return str;
}

ST_FUNC void tok_str_free_str(int *str)
{
    tal_free(tokstr_alloc, str);
}

ST_FUNC void tok_str_free(TokenString *str)
{
    tok_str_free_str(str->str);
    tal_free(tokstr_alloc, str);
}

ST_FUNC int *tok_str_realloc(TokenString *s, int new_size)
{
    int *str, size;

    size = s->allocated_len;
    if (size < 16)
        size = 16;
    while (size < new_size)
        size = size * 2;
    if (size > s->allocated_len) {
        str = tal_realloc(tokstr_alloc, s->str, size * sizeof(int));
        s->allocated_len = size;
        s->str = str;
    }
    return s->str;
}

ST_FUNC void tok_str_add(TokenString *s, int t)
{
    int len, *str;

    len = s->len;
    str = s->str;
    if (len >= s->allocated_len)
        str = tok_str_realloc(s, len + 1);
    str[len++] = t;
    s->len = len;
}

ST_FUNC void begin_macro(TokenString *str, int alloc)
{
    str->alloc = alloc;
    str->prev = macro_stack;
    str->prev_ptr = macro_ptr;
    macro_ptr = str->str;
    macro_stack = str;
}

ST_FUNC void end_macro(void)
{
    TokenString *str = macro_stack;
    macro_stack = str->prev;
    macro_ptr = str->prev_ptr;
    if (str->alloc == 2) {
        str->alloc = 3; /* just mark as finished */
    } else {
        tok_str_free(str);
    }
}

static void tok_str_add2(TokenString *s, int t, CValue *cv)
{
    int len, *str;

    len = s->len;
    str = s->str;

    /* allocate space for worst case */
    if (len + TOK_MAX_SIZE >= s->allocated_len)
        str = tok_str_realloc(s, len + TOK_MAX_SIZE + 1);
    str[len++] = t;
    switch(t) {
    case TOK_CINT:
    case TOK_CUINT:
    case TOK_CCHAR:
    case TOK_LCHAR:
    case TOK_CFLOAT:
    case TOK_LINENUM:
        str[len++] = cv->tab[0];
        break;
    case TOK_PPNUM:
    case TOK_PPSTR:
    case TOK_STR:
    case TOK_LSTR:
        {
            /* Insert the string into the int array. */
            size_t nb_words =
                1 + (cv->str.size + sizeof(int) - 1) / sizeof(int);
            if (len + nb_words >= s->allocated_len)
                str = tok_str_realloc(s, len + nb_words + 1);
            str[len] = cv->str.size;
            memcpy(&str[len + 1], cv->str.data, cv->str.size);
            len += nb_words;
        }
        break;
    case TOK_CDOUBLE:
    case TOK_CLLONG:
    case TOK_CULLONG:
#if LDOUBLE_SIZE == 8
    case TOK_CLDOUBLE:
#endif
        str[len++] = cv->tab[0];
        str[len++] = cv->tab[1];
        break;
#if LDOUBLE_SIZE == 12
    case TOK_CLDOUBLE:
        str[len++] = cv->tab[0];
        str[len++] = cv->tab[1];
        str[len++] = cv->tab[2];
#elif LDOUBLE_SIZE == 16
    case TOK_CLDOUBLE:
        str[len++] = cv->tab[0];
        str[len++] = cv->tab[1];
        str[len++] = cv->tab[2];
        str[len++] = cv->tab[3];
#elif LDOUBLE_SIZE != 8
#error add long double size support
#endif
        break;
    default:
        break;
    }
    s->len = len;
}

/* add the current parse token in token string 's' */
ST_FUNC void tok_str_add_tok(TokenString *s)
{
    CValue cval;

    /* save line number info */
    if (file->line_num != s->last_line_num) {
        s->last_line_num = file->line_num;
        cval.i = s->last_line_num;
        tok_str_add2(s, TOK_LINENUM, &cval);
    }
    tok_str_add2(s, tok, &tokc);
}

/* get a token from an integer array and increment pointer
   accordingly. we code it as a macro to avoid pointer aliasing. */
static inline void TOK_GET(int *t, const int **pp, CValue *cv)
{
    const int *p = *pp;
    int n, *tab;

    tab = cv->tab;
    switch(*t = *p++) {
    case TOK_CINT:
    case TOK_CUINT:
    case TOK_CCHAR:
    case TOK_LCHAR:
    case TOK_LINENUM:
        tab[0] = *p++;
    cv->i = (*t == TOK_CUINT) ? (unsigned)cv->i : (int)cv->i;
        break;
    case TOK_CFLOAT:
    tab[0] = *p++;
    break;
    case TOK_STR:
    case TOK_LSTR:
    case TOK_PPNUM:
    case TOK_PPSTR:
        cv->str.size = *p++;
        cv->str.data = p;
        p += (cv->str.size + sizeof(int) - 1) / sizeof(int);
        break;
    case TOK_CDOUBLE:
    case TOK_CLLONG:
    case TOK_CULLONG:
        n = 2;
        goto copy;
    case TOK_CLDOUBLE:
#if LDOUBLE_SIZE == 16
        n = 4;
#elif LDOUBLE_SIZE == 12
        n = 3;
#elif LDOUBLE_SIZE == 8
        n = 2;
#else
# error add long double size support
#endif
    copy:
        do
            *tab++ = *p++;
        while (--n);
        break;
    default:
        break;
    }
    *pp = p;
}

/* Calling this function is expensive, but it is not possible
   to read a token string backwards. */
static int tok_last(const int *str0, const int *str1)
{
    const int *str = str0;
    int tok = 0;
    CValue cval;

    while (str < str1)
        TOK_GET(&tok, &str, &cval);
    return tok;
}

static int macro_is_equal(const int *a, const int *b)
{
    CValue cv;
    int t;

    if (!a || !b)
        return 1;

    while (*a && *b) {
        /* first time preallocate macro_equal_buf, next time only reset position to start */
        cstr_reset(&macro_equal_buf);
        TOK_GET(&t, &a, &cv);
        cstr_cat(&macro_equal_buf, get_tok_str(t, &cv), 0);
        TOK_GET(&t, &b, &cv);
        if (strcmp(macro_equal_buf.data, get_tok_str(t, &cv)))
            return 0;
    }
    return !(*a || *b);
}

/* defines handling */
ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg)
{
    Sym *s, *o;

    o = define_find(v);
    s = sym_push2(&define_stack, v, macro_type, 0);
    s->d = str;
    s->next = first_arg;
    table_ident[v - TOK_IDENT]->sym_define = s;

    if (o && !macro_is_equal(o->d, s->d))
    tcc_warning("%s redefined", get_tok_str(v, NULL));
}

/* undefined a define symbol. Its name is just set to zero */
ST_FUNC void define_undef(Sym *s)
{
    int v = s->v;
    if (v >= TOK_IDENT && v < tok_ident)
        table_ident[v - TOK_IDENT]->sym_define = NULL;
}

ST_INLN Sym *define_find(int v)
{
    v -= TOK_IDENT;
    if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
        return NULL;
    return table_ident[v]->sym_define;
}

/* free define stack until top reaches 'b' */
ST_FUNC void free_defines(Sym *b)
{
    while (define_stack != b) {
        Sym *top = define_stack;
        define_stack = top->prev;
        tok_str_free_str(top->d);
        define_undef(top);
        sym_free(top);
    }

    /* restore remaining (-D or predefined) symbols if they were
       #undef'd in the file */
    while (b) {
        int v = b->v;
        if (v >= TOK_IDENT && v < tok_ident) {
            Sym **d = &table_ident[v - TOK_IDENT]->sym_define;
            if (!*d)
                *d = b;
        }
        b = b->prev;
    }
}

/* label lookup */
ST_FUNC Sym *label_find(int v)
{
    v -= TOK_IDENT;
    if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
        return NULL;
    return table_ident[v]->sym_label;
}

ST_FUNC Sym *label_push(Sym **ptop, int v, int flags)
{
    Sym *s, **ps;
    s = sym_push2(ptop, v, 0, 0);
    s->r = flags;
    ps = &table_ident[v - TOK_IDENT]->sym_label;
    if (ptop == &global_label_stack) {
        /* modify the top most local identifier, so that
           sym_identifier will point to 's' when popped */
        while (*ps != NULL)
            ps = &(*ps)->prev_tok;
    }
    s->prev_tok = *ps;
    *ps = s;
    return s;
}

/* pop labels until element last is reached. Look if any labels are
   undefined. Define symbols if '&&label' was used. */
ST_FUNC void label_pop(Sym **ptop, Sym *slast)
{
    Sym *s, *s1;
    for(s = *ptop; s != slast; s = s1) {
        s1 = s->prev;
        if (s->r == LABEL_DECLARED) {
            tcc_warning("label '%s' declared but not used", get_tok_str(s->v, NULL));
        } else if (s->r == LABEL_FORWARD) {
                tcc_error("label '%s' used but not defined",
                      get_tok_str(s->v, NULL));
        } else {
            if (s->c) {
                /* define corresponding symbol. A size of
                   1 is put. */
                put_extern_sym(s, cur_text_section, s->jnext, 1);
            }
        }
        /* remove label */
        table_ident[s->v - TOK_IDENT]->sym_label = s->prev_tok;
        sym_free(s);
    }
    *ptop = slast;
}

/* eval an expression for #if/#elif */
static int expr_preprocess(void)
{
    int c, t;
    TokenString *str;
    
    str = tok_str_alloc();
    while (tok != TOK_LINEFEED && tok != TOK_EOF) {
        next(); /* do macro subst */
        if (tok == TOK_DEFINED) {
            next_nomacro();
            t = tok;
            if (t == '(') 
                next_nomacro();
            c = define_find(tok) != 0;
            if (t == '(')
                next_nomacro();
            tok = TOK_CINT;
            tokc.i = c;
        } else if (tok >= TOK_IDENT) {
            /* if undefined macro */
            tok = TOK_CINT;
            tokc.i = 0;
        }
        tok_str_add_tok(str);
    }
    tok_str_add(str, -1); /* simulate end of file */
    tok_str_add(str, 0);
    /* now evaluate C constant expression */
    begin_macro(str, 1);
    next();
    c = expr_const();
    end_macro();
    return c != 0;
}


/* parse after #define */
ST_FUNC void parse_define(void)
{
    Sym *s, *first, **ps;
    int v, t, varg, is_vaargs, spc;
    int saved_parse_flags = parse_flags;

    v = tok;
    if (v < TOK_IDENT)
        tcc_error("invalid macro name '%s'", get_tok_str(tok, &tokc));
    /* XXX: should check if same macro (ANSI) */
    first = NULL;
    t = MACRO_OBJ;
    /* We have to parse the whole define as if not in asm mode, in particular
       no line comment with '#' must be ignored.  Also for function
       macros the argument list must be parsed without '.' being an ID
       character.  */
    parse_flags = ((parse_flags & ~PARSE_FLAG_ASM_FILE) | PARSE_FLAG_SPACES);
    /* '(' must be just after macro definition for MACRO_FUNC */
    next_nomacro_spc();
    if (tok == '(') {
        set_idnum('.', 0);
        next_nomacro();
        ps = &first;
        if (tok != ')') for (;;) {
            varg = tok;
            next_nomacro();
            is_vaargs = 0;
            if (varg == TOK_DOTS) {
                varg = TOK___VA_ARGS__;
                is_vaargs = 1;
            } else if (tok == TOK_DOTS && gnu_ext) {
                is_vaargs = 1;
                next_nomacro();
            }
            if (varg < TOK_IDENT)
        bad_list:
                tcc_error("bad macro parameter list");
            s = sym_push2(&define_stack, varg | SYM_FIELD, is_vaargs, 0);
            *ps = s;
            ps = &s->next;
            if (tok == ')')
                break;
            if (tok != ',' || is_vaargs)
                goto bad_list;
            next_nomacro();
        }
        next_nomacro_spc();
        t = MACRO_FUNC;
    }

    tokstr_buf.len = 0;
    spc = 2;
    parse_flags |= PARSE_FLAG_ACCEPT_STRAYS | PARSE_FLAG_SPACES | PARSE_FLAG_LINEFEED;
    /* The body of a macro definition should be parsed such that identifiers
       are parsed like the file mode determines (i.e. with '.' being an
       ID character in asm mode).  But '#' should be retained instead of
       regarded as line comment leader, so still don't set ASM_FILE
       in parse_flags. */
    set_idnum('.', (saved_parse_flags & PARSE_FLAG_ASM_FILE) ? IS_ID : 0);
    while (tok != TOK_LINEFEED && tok != TOK_EOF) {
        /* remove spaces around ## and after '#' */
        if (TOK_TWOSHARPS == tok) {
            if (2 == spc)
                goto bad_twosharp;
            if (1 == spc)
                --tokstr_buf.len;
            spc = 3;
        tok = TOK_PPJOIN;
        } else if ('#' == tok) {
            spc = 4;
        } else if (check_space(tok, &spc)) {
            goto skip;
        }
        tok_str_add2(&tokstr_buf, tok, &tokc);
    skip:
        next_nomacro_spc();
    }

    parse_flags = saved_parse_flags;
    if (spc == 1)
        --tokstr_buf.len; /* remove trailing space */
    tok_str_add(&tokstr_buf, 0);
    if (3 == spc)
bad_twosharp:
        tcc_error("'##' cannot appear at either end of macro");
    define_push(v, t, tok_str_dup(&tokstr_buf), first);
}

static CachedInclude *search_cached_include(TCCState *s1, const char *filename, int add)
{
    const unsigned char *s;
    unsigned int h;
    CachedInclude *e;
    int i;

    h = TOK_HASH_INIT;
    s = (unsigned char *) filename;
    while (*s) {
#ifdef _WIN32
        h = TOK_HASH_FUNC(h, toup(*s));
#else
        h = TOK_HASH_FUNC(h, *s);
#endif
        s++;
    }
    h &= (CACHED_INCLUDES_HASH_SIZE - 1);

    i = s1->cached_includes_hash[h];
    for(;;) {
        if (i == 0)
            break;
        e = s1->cached_includes[i - 1];
        if (0 == PATHCMP(e->filename, filename))
            return e;
        i = e->hash_next;
    }
    if (!add)
        return NULL;

    e = tcc_malloc(sizeof(CachedInclude) + strlen(filename));
    strcpy(e->filename, filename);
    e->ifndef_macro = e->once = 0;
    dynarray_add(&s1->cached_includes, &s1->nb_cached_includes, e);
    /* add in hash table */
    e->hash_next = s1->cached_includes_hash[h];
    s1->cached_includes_hash[h] = s1->nb_cached_includes;
#ifdef INC_DEBUG
    printf("adding cached '%s'\n", filename);
#endif
    return e;
}

static void pragma_parse(TCCState *s1)
{
    next_nomacro();
    if (tok == TOK_push_macro || tok == TOK_pop_macro) {
        int t = tok, v;
        Sym *s;

        if (next(), tok != '(')
            goto pragma_err;
        if (next(), tok != TOK_STR)
            goto pragma_err;
        v = tok_alloc(tokc.str.data, tokc.str.size - 1)->tok;
        if (next(), tok != ')')
            goto pragma_err;
        if (t == TOK_push_macro) {
            while (NULL == (s = define_find(v)))
                define_push(v, 0, NULL, NULL);
            s->type.ref = s; /* set push boundary */
        } else {
            for (s = define_stack; s; s = s->prev)
                if (s->v == v && s->type.ref == s) {
                    s->type.ref = NULL;
                    break;
                }
        }
        if (s)
            table_ident[v - TOK_IDENT]->sym_define = s->d ? s : NULL;
        else
            tcc_warning("unbalanced #pragma pop_macro");
        pp_debug_tok = t, pp_debug_symv = v;

    } else if (tok == TOK_once) {
        search_cached_include(s1, file->filename, 1)->once = pp_once;

    } else if (s1->ppfp) {
        /* tcc -E: keep pragmas below unchanged */
        unget_tok(' ');
        unget_tok(TOK_PRAGMA);
        unget_tok('#');
        unget_tok(TOK_LINEFEED);

    } else if (tok == TOK_pack) {
        /* This may be:
           #pragma pack(1) // set
           #pragma pack() // reset to default
           #pragma pack(push,1) // push & set
           #pragma pack(pop) // restore previous */
        next();
        skip('(');
        if (tok == TOK_ASM_pop) {
            next();
            if (s1->pack_stack_ptr <= s1->pack_stack) {
            stk_error:
                tcc_error("out of pack stack");
            }
            s1->pack_stack_ptr--;
        } else {
            int val = 0;
            if (tok != ')') {
                if (tok == TOK_ASM_push) {
                    next();
                    if (s1->pack_stack_ptr >= s1->pack_stack + PACK_STACK_SIZE - 1)
                        goto stk_error;
                    s1->pack_stack_ptr++;
                    skip(',');
                }
                if (tok != TOK_CINT)
                    goto pragma_err;
                val = tokc.i;
                if (val < 1 || val > 16 || (val & (val - 1)) != 0)
                    goto pragma_err;
                next();
            }
            *s1->pack_stack_ptr = val;
        }
        if (tok != ')')
            goto pragma_err;

    } else if (tok == TOK_comment) {
        char *file;
        next();
        skip('(');
        if (tok != TOK_lib)
            goto pragma_warn;
        next();
        skip(',');
        if (tok != TOK_STR)
            goto pragma_err;
        file = tcc_strdup((char *)tokc.str.data);
        dynarray_add(&s1->pragma_libs, &s1->nb_pragma_libs, file);
        next();
        if (tok != ')')
            goto pragma_err;
    } else {
pragma_warn:
        if (s1->warn_unsupported)
            tcc_warning("#pragma %s is ignored", get_tok_str(tok, &tokc));
    }
    return;

pragma_err:
    tcc_error("malformed #pragma directive");
    return;
}

/* is_bof is true if first non space token at beginning of file */
ST_FUNC void preprocess(int is_bof)
{
    TCCState *s1 = tcc_state;
    int i, c, n, saved_parse_flags;
    char buf[1024], *q;
    Sym *s;

    saved_parse_flags = parse_flags;
    parse_flags = PARSE_FLAG_PREPROCESS
        | PARSE_FLAG_TOK_NUM
        | PARSE_FLAG_TOK_STR
        | PARSE_FLAG_LINEFEED
        | (parse_flags & PARSE_FLAG_ASM_FILE)
        ;

    next_nomacro();
 redo:
    switch(tok) {
    case TOK_DEFINE:
        pp_debug_tok = tok;
        next_nomacro();
        pp_debug_symv = tok;
        parse_define();
        break;
    case TOK_UNDEF:
        pp_debug_tok = tok;
        next_nomacro();
        pp_debug_symv = tok;
        s = define_find(tok);
        /* undefine symbol by putting an invalid name */
        if (s)
            define_undef(s);
        break;
    case TOK_INCLUDE:
    case TOK_INCLUDE_NEXT:
        ch = file->buf_ptr[0];
        /* XXX: incorrect if comments : use next_nomacro with a special mode */
        skip_spaces();
        if (ch == '<') {
            c = '>';
            goto read_name;
        } else if (ch == '\"') {
            c = ch;
        read_name:
            inp();
            q = buf;
            while (ch != c && ch != '\n' && ch != CH_EOF) {
                if ((q - buf) < sizeof(buf) - 1)
                    *q++ = ch;
                if (ch == '\\') {
                    if (handle_stray_noerror() == 0)
                        --q;
                } else
                    inp();
            }
            *q = '\0';
            minp();
#if 0
            /* eat all spaces and comments after include */
            /* XXX: slightly incorrect */
            while (ch1 != '\n' && ch1 != CH_EOF)
                inp();
#endif
        } else {
        int len;
            /* computed #include : concatenate everything up to linefeed,
           the result must be one of the two accepted forms.
           Don't convert pp-tokens to tokens here.  */
        parse_flags = (PARSE_FLAG_PREPROCESS
               | PARSE_FLAG_LINEFEED
               | (parse_flags & PARSE_FLAG_ASM_FILE));
            next();
            buf[0] = '\0';
        while (tok != TOK_LINEFEED) {
        pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc));
        next();
        }
        len = strlen(buf);
        /* check syntax and remove '<>|""' */
        if ((len < 2 || ((buf[0] != '"' || buf[len-1] != '"') &&
                 (buf[0] != '<' || buf[len-1] != '>'))))
            tcc_error("'#include' expects \"FILENAME\" or <FILENAME>");
        c = buf[len-1];
        memmove(buf, buf + 1, len - 2);
        buf[len - 2] = '\0';
        }

        if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)
            tcc_error("#include recursion too deep");
        /* store current file in stack, but increment stack later below */
        *s1->include_stack_ptr = file;
        i = tok == TOK_INCLUDE_NEXT ? file->include_next_index : 0;
        n = 2 + s1->nb_include_paths + s1->nb_sysinclude_paths;
        for (; i < n; ++i) {
            char buf1[sizeof file->filename];
            CachedInclude *e;
            const char *path;

            if (i == 0) {
                /* check absolute include path */
                if (!IS_ABSPATH(buf))
                    continue;
                buf1[0] = 0;

            } else if (i == 1) {
                /* search in file's dir if "header.h" */
                if (c != '\"')
                    continue;
                /* https://savannah.nongnu.org/bugs/index.php?50847 */
                path = file->filename2;
                pstrncpy(buf1, path, tcc_basename(path) - path);

            } else {
                /* search in all the include paths */
                int j = i - 2, k = j - s1->nb_include_paths;
                path = k < 0 ? s1->include_paths[j] : s1->sysinclude_paths[k];
                pstrcpy(buf1, sizeof(buf1), path);
                pstrcat(buf1, sizeof(buf1), "/");
            }

            pstrcat(buf1, sizeof(buf1), buf);
            e = search_cached_include(s1, buf1, 0);
            if (e && (define_find(e->ifndef_macro) || e->once == pp_once)) {
                /* no need to parse the include because the 'ifndef macro'
                   is defined (or had #pragma once) */
#ifdef INC_DEBUG
                printf("%s: skipping cached %s\n", file->filename, buf1);
#endif
                goto include_done;
            }

            if (tcc_open(s1, buf1) < 0)
                continue;

            file->include_next_index = i + 1;
#ifdef INC_DEBUG
            printf("%s: including %s\n", file->prev->filename, file->filename);
#endif
            /* update target deps */
            dynarray_add(&s1->target_deps, &s1->nb_target_deps,
                    tcc_strdup(buf1));
            /* push current file in stack */
            ++s1->include_stack_ptr;
            /* add include file debug info */
            if (s1->do_debug)
                put_stabs(file->filename, N_BINCL, 0, 0, 0);
            tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL;
            ch = file->buf_ptr[0];
            goto the_end;
        }
        tcc_error("include file '%s' not found", buf);
include_done:
        break;
    case TOK_IFNDEF:
        c = 1;
        goto do_ifdef;
    case TOK_IF:
        c = expr_preprocess();
        goto do_if;
    case TOK_IFDEF:
        c = 0;
    do_ifdef:
        next_nomacro();
        if (tok < TOK_IDENT)
            tcc_error("invalid argument for '#if%sdef'", c ? "n" : "");
        if (is_bof) {
            if (c) {
#ifdef INC_DEBUG
                printf("#ifndef %s\n", get_tok_str(tok, NULL));
#endif
                file->ifndef_macro = tok;
            }
        }
        c = (define_find(tok) != 0) ^ c;
    do_if:
        if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
            tcc_error("memory full (ifdef)");
        *s1->ifdef_stack_ptr++ = c;
        goto test_skip;
    case TOK_ELSE:
        if (s1->ifdef_stack_ptr == s1->ifdef_stack)
            tcc_error("#else without matching #if");
        if (s1->ifdef_stack_ptr[-1] & 2)
            tcc_error("#else after #else");
        c = (s1->ifdef_stack_ptr[-1] ^= 3);
        goto test_else;
    case TOK_ELIF:
        if (s1->ifdef_stack_ptr == s1->ifdef_stack)
            tcc_error("#elif without matching #if");
        c = s1->ifdef_stack_ptr[-1];
        if (c > 1)
            tcc_error("#elif after #else");
        /* last #if/#elif expression was true: we skip */
        if (c == 1) {
            c = 0;
        } else {
            c = expr_preprocess();
            s1->ifdef_stack_ptr[-1] = c;
        }
    test_else:
        if (s1->ifdef_stack_ptr == file->ifdef_stack_ptr + 1)
            file->ifndef_macro = 0;
    test_skip:
        if (!(c & 1)) {
            preprocess_skip();
            is_bof = 0;
            goto redo;
        }
        break;
    case TOK_ENDIF:
        if (s1->ifdef_stack_ptr <= file->ifdef_stack_ptr)
            tcc_error("#endif without matching #if");
        s1->ifdef_stack_ptr--;
        /* '#ifndef macro' was at the start of file. Now we check if
           an '#endif' is exactly at the end of file */
        if (file->ifndef_macro &&
            s1->ifdef_stack_ptr == file->ifdef_stack_ptr) {
            file->ifndef_macro_saved = file->ifndef_macro;
            /* need to set to zero to avoid false matches if another
               #ifndef at middle of file */
            file->ifndef_macro = 0;
            while (tok != TOK_LINEFEED)
                next_nomacro();
            tok_flags |= TOK_FLAG_ENDIF;
            goto the_end;
        }
        break;
    case TOK_PPNUM:
        n = strtoul((char*)tokc.str.data, &q, 10);
        goto _line_num;
    case TOK_LINE:
        next();
        if (tok != TOK_CINT)
    _line_err:
            tcc_error("wrong #line format");
        n = tokc.i;
    _line_num:
        next();
        if (tok != TOK_LINEFEED) {
            if (tok == TOK_STR)
                pstrcpy(file->filename, sizeof(file->filename), (char *)tokc.str.data);
            else if (parse_flags & PARSE_FLAG_ASM_FILE)
                break;
            else
                goto _line_err;
            --n;
        }
        if (file->fd > 0)
            total_lines += file->line_num - n;
        file->line_num = n;
        if (s1->do_debug)
            put_stabs(file->filename, N_BINCL, 0, 0, 0);
        break;
    case TOK_ERROR:
    case TOK_WARNING:
        c = tok;
        ch = file->buf_ptr[0];
        skip_spaces();
        q = buf;
        while (ch != '\n' && ch != CH_EOF) {
            if ((q - buf) < sizeof(buf) - 1)
                *q++ = ch;
            if (ch == '\\') {
                if (handle_stray_noerror() == 0)
                    --q;
            } else
                inp();
        }
        *q = '\0';
        if (c == TOK_ERROR)
            tcc_error("#error %s", buf);
        else
            tcc_warning("#warning %s", buf);
        break;
    case TOK_PRAGMA:
        pragma_parse(s1);
        break;
    case TOK_LINEFEED:
        goto the_end;
    default:
        /* ignore gas line comment in an 'S' file. */
        if (saved_parse_flags & PARSE_FLAG_ASM_FILE)
            goto ignore;
        if (tok == '!' && is_bof)
            /* '!' is ignored at beginning to allow C scripts. */
            goto ignore;
        tcc_warning("Ignoring unknown preprocessing directive #%s", get_tok_str(tok, &tokc));
    ignore:
        file->buf_ptr = parse_line_comment(file->buf_ptr - 1);
        goto the_end;
    }
    /* ignore other preprocess commands or #! for C scripts */
    while (tok != TOK_LINEFEED)
        next_nomacro();
 the_end:
    parse_flags = saved_parse_flags;
}

/* evaluate escape codes in a string. */
static void parse_escape_string(CString *outstr, const uint8_t *buf, int is_long)
{
    int c, n;
    const uint8_t *p;

    p = buf;
    for(;;) {
        c = *p;
        if (c == '\0')
            break;
        if (c == '\\') {
            p++;
            /* escape */
            c = *p;
            switch(c) {
            case '0': case '1': case '2': case '3':
            case '4': case '5': case '6': case '7':
                /* at most three octal digits */
                n = c - '0';
                p++;
                c = *p;
                if (isoct(c)) {
                    n = n * 8 + c - '0';
                    p++;
                    c = *p;
                    if (isoct(c)) {
                        n = n * 8 + c - '0';
                        p++;
                    }
                }
                c = n;
                goto add_char_nonext;
            case 'x':
            case 'u':
            case 'U':
                p++;
                n = 0;
                for(;;) {
                    c = *p;
                    if (c >= 'a' && c <= 'f')
                        c = c - 'a' + 10;
                    else if (c >= 'A' && c <= 'F')
                        c = c - 'A' + 10;
                    else if (isnum(c))
                        c = c - '0';
                    else
                        break;
                    n = n * 16 + c;
                    p++;
                }
                c = n;
                goto add_char_nonext;
            case 'a':
                c = '\a';
                break;
            case 'b':
                c = '\b';
                break;
            case 'f':
                c = '\f';
                break;
            case 'n':
                c = '\n';
                break;
            case 'r':
                c = '\r';
                break;
            case 't':
                c = '\t';
                break;
            case 'v':
                c = '\v';
                break;
            case 'e':
                if (!gnu_ext)
                    goto invalid_escape;
                c = 27;
                break;
            case '\'':
            case '\"':
            case '\\': 
            case '?':
                break;
            default:
            invalid_escape:
                if (c >= '!' && c <= '~')
                    tcc_warning("unknown escape sequence: \'\\%c\'", c);
                else
                    tcc_warning("unknown escape sequence: \'\\x%x\'", c);
                break;
            }
        }
        p++;
    add_char_nonext:
        if (!is_long)
            cstr_ccat(outstr, c);
        else
            cstr_wccat(outstr, c);
    }
    /* add a trailing '\0' */
    if (!is_long)
        cstr_ccat(outstr, '\0');
    else
        cstr_wccat(outstr, '\0');
}

static void parse_string(const char *s, int len)
{
    uint8_t buf[1000], *p = buf;
    int is_long, sep;

    if ((is_long = *s == 'L'))
        ++s, --len;
    sep = *s++;
    len -= 2;
    if (len >= sizeof buf)
        p = tcc_malloc(len + 1);
    memcpy(p, s, len);
    p[len] = 0;

    cstr_reset(&tokcstr);
    parse_escape_string(&tokcstr, p, is_long);
    if (p != buf)
        tcc_free(p);

    if (sep == '\'') {
        int char_size;
        /* XXX: make it portable */
        if (!is_long)
            char_size = 1;
        else
            char_size = sizeof(nwchar_t);
        if (tokcstr.size <= char_size)
            tcc_error("empty character constant");
        if (tokcstr.size > 2 * char_size)
            tcc_warning("multi-character character constant");
        if (!is_long) {
            tokc.i = *(int8_t *)tokcstr.data;
            tok = TOK_CCHAR;
        } else {
            tokc.i = *(nwchar_t *)tokcstr.data;
            tok = TOK_LCHAR;
        }
    } else {
        tokc.str.size = tokcstr.size;
        tokc.str.data = tokcstr.data;
        if (!is_long)
            tok = TOK_STR;
        else
            tok = TOK_LSTR;
    }
}

/* we use 64 bit numbers */
#define BN_SIZE 2

/* bn = (bn << shift) | or_val */
static void bn_lshift(unsigned int *bn, int shift, int or_val)
{
    int i;
    unsigned int v;
    for(i=0;i<BN_SIZE;i++) {
        v = bn[i];
        bn[i] = (v << shift) | or_val;
        or_val = v >> (32 - shift);
    }
}

static void bn_zero(unsigned int *bn)
{
    int i;
    for(i=0;i<BN_SIZE;i++) {
        bn[i] = 0;
    }
}

/* parse number in null terminated string 'p' and return it in the
   current token */
static void parse_number(const char *p)
{
    int b, t, shift, frac_bits, s, exp_val, ch;
    char *q;
    unsigned int bn[BN_SIZE];
    double d;

    /* number */
    q = token_buf;
    ch = *p++;
    t = ch;
    ch = *p++;
    *q++ = t;
    b = 10;
    if (t == '.') {
        goto float_frac_parse;
    } else if (t == '0') {
        if (ch == 'x' || ch == 'X') {
            q--;
            ch = *p++;
            b = 16;
        } else if (tcc_ext && (ch == 'b' || ch == 'B')) {
            q--;
            ch = *p++;
            b = 2;
        }
    }
    /* parse all digits. cannot check octal numbers at this stage
       because of floating point constants */
    while (1) {
        if (ch >= 'a' && ch <= 'f')
            t = ch - 'a' + 10;
        else if (ch >= 'A' && ch <= 'F')
            t = ch - 'A' + 10;
        else if (isnum(ch))
            t = ch - '0';
        else
            break;
        if (t >= b)
            break;
        if (q >= token_buf + STRING_MAX_SIZE) {
        num_too_long:
            tcc_error("number too long");
        }
        *q++ = ch;
        ch = *p++;
    }
    if (ch == '.' ||
        ((ch == 'e' || ch == 'E') && b == 10) ||
        ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
        if (b != 10) {
            /* NOTE: strtox should support that for hexa numbers, but
               non ISOC99 libcs do not support it, so we prefer to do
               it by hand */
            /* hexadecimal or binary floats */
            /* XXX: handle overflows */
            *q = '\0';
            if (b == 16)
                shift = 4;
            else 
                shift = 1;
            bn_zero(bn);
            q = token_buf;
            while (1) {
                t = *q++;
                if (t == '\0') {
                    break;
                } else if (t >= 'a') {
                    t = t - 'a' + 10;
                } else if (t >= 'A') {
                    t = t - 'A' + 10;
                } else {
                    t = t - '0';
                }
                bn_lshift(bn, shift, t);
            }
            frac_bits = 0;
            if (ch == '.') {
                ch = *p++;
                while (1) {
                    t = ch;
                    if (t >= 'a' && t <= 'f') {
                        t = t - 'a' + 10;
                    } else if (t >= 'A' && t <= 'F') {
                        t = t - 'A' + 10;
                    } else if (t >= '0' && t <= '9') {
                        t = t - '0';
                    } else {
                        break;
                    }
                    if (t >= b)
                        tcc_error("invalid digit");
                    bn_lshift(bn, shift, t);
                    frac_bits += shift;
                    ch = *p++;
                }
            }
            if (ch != 'p' && ch != 'P')
                expect("exponent");
            ch = *p++;
            s = 1;
            exp_val = 0;
            if (ch == '+') {
                ch = *p++;
            } else if (ch == '-') {
                s = -1;
                ch = *p++;
            }
            if (ch < '0' || ch > '9')
                expect("exponent digits");
            while (ch >= '0' && ch <= '9') {
                exp_val = exp_val * 10 + ch - '0';
                ch = *p++;
            }
            exp_val = exp_val * s;
            
            /* now we can generate the number */
            /* XXX: should patch directly float number */
#if HAVE_FLOAT
            d = (double)bn[1] * 4294967296.0 + (double)bn[0];
#endif
            d = ldexp(d, exp_val - frac_bits);
            t = toup(ch);
            if (t == 'F') {
                ch = *p++;
                tok = TOK_CFLOAT;
                /* float : should handle overflow */
                tokc.f = (float)d;
            } else if (t == 'L') {
                ch = *p++;
#ifdef TCC_TARGET_PE
                tok = TOK_CDOUBLE;
                tokc.d = d;
#else
                tok = TOK_CLDOUBLE;
                /* XXX: not large enough */
                tokc.ld = (long double)d;
#endif
            } else {
                tok = TOK_CDOUBLE;
                tokc.d = d;
            }
        } else {
            /* decimal floats */
            if (ch == '.') {
                if (q >= token_buf + STRING_MAX_SIZE)
                    goto num_too_long;
                *q++ = ch;
                ch = *p++;
            float_frac_parse:
                while (ch >= '0' && ch <= '9') {
                    if (q >= token_buf + STRING_MAX_SIZE)
                        goto num_too_long;
                    *q++ = ch;
                    ch = *p++;
                }
            }
            if (ch == 'e' || ch == 'E') {
                if (q >= token_buf + STRING_MAX_SIZE)
                    goto num_too_long;
                *q++ = ch;
                ch = *p++;
                if (ch == '-' || ch == '+') {
                    if (q >= token_buf + STRING_MAX_SIZE)
                        goto num_too_long;
                    *q++ = ch;
                    ch = *p++;
                }
                if (ch < '0' || ch > '9')
                    expect("exponent digits");
                while (ch >= '0' && ch <= '9') {
                    if (q >= token_buf + STRING_MAX_SIZE)
                        goto num_too_long;
                    *q++ = ch;
                    ch = *p++;
                }
            }
            *q = '\0';
            t = toup(ch);
            errno = 0;
            if (t == 'F') {
                ch = *p++;
                tok = TOK_CFLOAT;
                tokc.f = strtof(token_buf, NULL);
            } else if (t == 'L') {
                ch = *p++;
#ifdef TCC_TARGET_PE
                tok = TOK_CDOUBLE;
                tokc.d = strtod(token_buf, NULL);
#else
                tok = TOK_CLDOUBLE;
#if HAVE_FLOAT
                tokc.ld = strtold(token_buf, NULL);
#endif
#endif
            } else {
                tok = TOK_CDOUBLE;
#if HAVE_FLOAT
                tokc.d = strtod(token_buf, NULL);
#endif
            }
        }
    } else {
        unsigned long long n, n1;
        int lcount, ucount, must_64bit;
        const char *p1;

        /* integer number */
        *q = '\0';
        q = token_buf;
        if (b == 10 && *q == '0') {
            b = 8;
            q++;
        }
        n = 0;
        while(1) {
            t = *q++;
            /* no need for checks except for base 10 / 8 errors */
            if (t == '\0')
                break;
            else if (t >= 'a')
                t = t - 'a' + 10;
            else if (t >= 'A')
                t = t - 'A' + 10;
            else
                t = t - '0';
            if (t >= b)
                tcc_error("invalid digit");
            n1 = n;
            n = n * b + t;
#if HAVE_LONG_LONG
            /* detect overflow */
            /* XXX: this test is not reliable */
            if (n < n1)
                tcc_error("integer constant overflow");
#endif
        }

        /* Determine the characteristics (unsigned and/or 64bit) the type of
           the constant must have according to the constant suffix(es) */
        lcount = ucount = must_64bit = 0;
        p1 = p;
        for(;;) {
            t = toup(ch);
            if (t == 'L') {
                if (lcount >= 2)
                    tcc_error("three 'l's in integer constant");
                if (lcount && *(p - 1) != ch)
                    tcc_error("incorrect integer suffix: %s", p1);
                lcount++;
#if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE
                if (lcount == 2)
#endif
                    must_64bit = 1;
                ch = *p++;
            } else if (t == 'U') {
                if (ucount >= 1)
                    tcc_error("two 'u's in integer constant");
                ucount++;
                ch = *p++;
            } else {
                break;
            }
        }

#if HAVE_LONG_LONG
        /* Whether 64 bits are needed to hold the constant's value */
        if (n & 0xffffffff00000000LL || must_64bit) {
            tok = TOK_CLLONG;
            n1 = n >> 32;
    } else
#endif
        {
            tok = TOK_CINT;
            n1 = n;
        }

        /* Whether type must be unsigned to hold the constant's value */
        if (ucount || ((n1 >> 31) && (b != 10))) {
            if (tok == TOK_CLLONG)
                tok = TOK_CULLONG;
            else
                tok = TOK_CUINT;
        /* If decimal and no unsigned suffix, bump to 64 bits or throw error */
        } else if (n1 >> 31) {
            if (tok == TOK_CINT)
                tok = TOK_CLLONG;
            else
                tcc_error("integer constant overflow");
        }

        tokc.i = n;
    }
    if (ch)
        tcc_error("invalid number\n");
}


#define PARSE2(c1, tok1, c2, tok2)              \
    case c1:                                    \
        PEEKC(c, p);                            \
        if (c == c2) {                          \
            p++;                                \
            tok = tok2;                         \
        } else {                                \
            tok = tok1;                         \
        }                                       \
        break;

/* return next token without macro substitution */
static inline void next_nomacro1(void)
{
    int t, c, is_long, len;
    TokenSym *ts;
    uint8_t *p, *p1;
    unsigned int h;

    p = file->buf_ptr;
 redo_no_start:
    c = *p;
    switch(c) {
    case ' ':
    case '\t':
        tok = c;
        p++;
        if (parse_flags & PARSE_FLAG_SPACES)
            goto keep_tok_flags;
        while (isidnum_table[*p - CH_EOF] & IS_SPC)
            ++p;
        goto redo_no_start;
    case '\f':
    case '\v':
    case '\r':
        p++;
        goto redo_no_start;
    case '\\':
        /* first look if it is in fact an end of buffer */
        c = handle_stray1(p);
        p = file->buf_ptr;
        if (c == '\\')
            goto parse_simple;
        if (c != CH_EOF)
            goto redo_no_start;
        {
            TCCState *s1 = tcc_state;
            if ((parse_flags & PARSE_FLAG_LINEFEED)
                && !(tok_flags & TOK_FLAG_EOF)) {
                tok_flags |= TOK_FLAG_EOF;
                tok = TOK_LINEFEED;
                goto keep_tok_flags;
            } else if (!(parse_flags & PARSE_FLAG_PREPROCESS)) {
                tok = TOK_EOF;
            } else if (s1->ifdef_stack_ptr != file->ifdef_stack_ptr) {
                tcc_error("missing #endif");
            } else if (s1->include_stack_ptr == s1->include_stack) {
                /* no include left : end of file. */
                tok = TOK_EOF;
            } else {
                tok_flags &= ~TOK_FLAG_EOF;
                /* pop include file */
                
                /* test if previous '#endif' was after a #ifdef at
                   start of file */
                if (tok_flags & TOK_FLAG_ENDIF) {
#ifdef INC_DEBUG
                    printf("#endif %s\n", get_tok_str(file->ifndef_macro_saved, NULL));
#endif
                    search_cached_include(s1, file->filename, 1)
                        ->ifndef_macro = file->ifndef_macro_saved;
                    tok_flags &= ~TOK_FLAG_ENDIF;
                }

                /* add end of include file debug info */
                if (tcc_state->do_debug) {
                    put_stabd(N_EINCL, 0, 0);
                }
                /* pop include stack */
                tcc_close();
                s1->include_stack_ptr--;
                p = file->buf_ptr;
                goto redo_no_start;
            }
        }
        break;

    case '\n':
        file->line_num++;
        tok_flags |= TOK_FLAG_BOL;
        p++;
maybe_newline:
        if (0 == (parse_flags & PARSE_FLAG_LINEFEED))
            goto redo_no_start;
        tok = TOK_LINEFEED;
        goto keep_tok_flags;

    case '#':
        /* XXX: simplify */
        PEEKC(c, p);
        if ((tok_flags & TOK_FLAG_BOL) && 
            (parse_flags & PARSE_FLAG_PREPROCESS)) {
            file->buf_ptr = p;
            preprocess(tok_flags & TOK_FLAG_BOF);
            p = file->buf_ptr;
            goto maybe_newline;
        } else {
            if (c == '#') {
                p++;
                tok = TOK_TWOSHARPS;
            } else {
                if (parse_flags & PARSE_FLAG_ASM_FILE) {
                    p = parse_line_comment(p - 1);
                    goto redo_no_start;
                } else {
                    tok = '#';
                }
            }
        }
        break;
    
    /* dollar is allowed to start identifiers when not parsing asm */
    case '$':
        if (!(isidnum_table[c - CH_EOF] & IS_ID)
         || (parse_flags & PARSE_FLAG_ASM_FILE))
            goto parse_simple;

    case 'a': case 'b': case 'c': case 'd':
    case 'e': case 'f': case 'g': case 'h':
    case 'i': case 'j': case 'k': case 'l':
    case 'm': case 'n': case 'o': case 'p':
    case 'q': case 'r': case 's': case 't':
    case 'u': case 'v': case 'w': case 'x':
    case 'y': case 'z': 
    case 'A': case 'B': case 'C': case 'D':
    case 'E': case 'F': case 'G': case 'H':
    case 'I': case 'J': case 'K': 
    case 'M': case 'N': case 'O': case 'P':
    case 'Q': case 'R': case 'S': case 'T':
    case 'U': case 'V': case 'W': case 'X':
    case 'Y': case 'Z': 
    case '_':
    parse_ident_fast:
        p1 = p;
        h = TOK_HASH_INIT;
        h = TOK_HASH_FUNC(h, c);
        while (c = *++p, isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM))
            h = TOK_HASH_FUNC(h, c);
        len = p - p1;
        if (c != '\\') {
            TokenSym **pts;

            /* fast case : no stray found, so we have the full token
               and we have already hashed it */
            h &= (TOK_HASH_SIZE - 1);
            pts = &hash_ident[h];
            for(;;) {
                ts = *pts;
                if (!ts)
                    break;
                if (ts->len == len && !memcmp(ts->str, p1, len))
                    goto token_found;
                pts = &(ts->hash_next);
            }
            ts = tok_alloc_new(pts, (char *) p1, len);
        token_found: ;
        } else {
            /* slower case */
            cstr_reset(&tokcstr);
            cstr_cat(&tokcstr, (char *) p1, len);
            p--;
            PEEKC(c, p);
        parse_ident_slow:
            while (isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM))
            {
                cstr_ccat(&tokcstr, c);
                PEEKC(c, p);
            }
            ts = tok_alloc(tokcstr.data, tokcstr.size);
        }
        tok = ts->tok;
        break;
    case 'L':
        t = p[1];
        if (t != '\\' && t != '\'' && t != '\"') {
            /* fast case */
            goto parse_ident_fast;
        } else {
            PEEKC(c, p);
            if (c == '\'' || c == '\"') {
                is_long = 1;
                goto str_const;
            } else {
                cstr_reset(&tokcstr);
                cstr_ccat(&tokcstr, 'L');
                goto parse_ident_slow;
            }
        }
        break;

    case '0': case '1': case '2': case '3':
    case '4': case '5': case '6': case '7':
    case '8': case '9':
        t = c;
        PEEKC(c, p);
        /* after the first digit, accept digits, alpha, '.' or sign if
           prefixed by 'eEpP' */
    parse_num:
        cstr_reset(&tokcstr);
        for(;;) {
            cstr_ccat(&tokcstr, t);
            if (!((isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM))
                  || c == '.'
                  || ((c == '+' || c == '-')
                      && (((t == 'e' || t == 'E')
                            && !(parse_flags & PARSE_FLAG_ASM_FILE
                                /* 0xe+1 is 3 tokens in asm */
                                && ((char*)tokcstr.data)[0] == '0'
                                && toup(((char*)tokcstr.data)[1]) == 'X'))
                          || t == 'p' || t == 'P'))))
                break;
            t = c;
            PEEKC(c, p);
        }
        /* We add a trailing '\0' to ease parsing */
        cstr_ccat(&tokcstr, '\0');
        tokc.str.size = tokcstr.size;
        tokc.str.data = tokcstr.data;
        tok = TOK_PPNUM;
        break;

    case '.':
        /* special dot handling because it can also start a number */
        PEEKC(c, p);
        if (isnum(c)) {
            t = '.';
            goto parse_num;
        } else if ((isidnum_table['.' - CH_EOF] & IS_ID)
                   && (isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM))) {
            *--p = c = '.';
            goto parse_ident_fast;
        } else if (c == '.') {
            PEEKC(c, p);
            if (c == '.') {
                p++;
                tok = TOK_DOTS;
            } else {
                *--p = '.'; /* may underflow into file->unget[] */
                tok = '.';
            }
        } else {
            tok = '.';
        }
        break;
    case '\'':
    case '\"':
        is_long = 0;
    str_const:
        cstr_reset(&tokcstr);
        if (is_long)
            cstr_ccat(&tokcstr, 'L');
        cstr_ccat(&tokcstr, c);
        p = parse_pp_string(p, c, &tokcstr);
        cstr_ccat(&tokcstr, c);
        cstr_ccat(&tokcstr, '\0');
        tokc.str.size = tokcstr.size;
        tokc.str.data = tokcstr.data;
        tok = TOK_PPSTR;
        break;

    case '<':
        PEEKC(c, p);
        if (c == '=') {
            p++;
            tok = TOK_LE;
        } else if (c == '<') {
            PEEKC(c, p);
            if (c == '=') {
                p++;
                tok = TOK_A_SHL;
            } else {
                tok = TOK_SHL;
            }
        } else {
            tok = TOK_LT;
        }
        break;
    case '>':
        PEEKC(c, p);
        if (c == '=') {
            p++;
            tok = TOK_GE;
        } else if (c == '>') {
            PEEKC(c, p);
            if (c == '=') {
                p++;
                tok = TOK_A_SAR;
            } else {
                tok = TOK_SAR;
            }
        } else {
            tok = TOK_GT;
        }
        break;
        
    case '&':
        PEEKC(c, p);
        if (c == '&') {
            p++;
            tok = TOK_LAND;
        } else if (c == '=') {
            p++;
            tok = TOK_A_AND;
        } else {
            tok = '&';
        }
        break;
        
    case '|':
        PEEKC(c, p);
        if (c == '|') {
            p++;
            tok = TOK_LOR;
        } else if (c == '=') {
            p++;
            tok = TOK_A_OR;
        } else {
            tok = '|';
        }
        break;

    case '+':
        PEEKC(c, p);
        if (c == '+') {
            p++;
            tok = TOK_INC;
        } else if (c == '=') {
            p++;
            tok = TOK_A_ADD;
        } else {
            tok = '+';
        }
        break;
        
    case '-':
        PEEKC(c, p);
        if (c == '-') {
            p++;
            tok = TOK_DEC;
        } else if (c == '=') {
            p++;
            tok = TOK_A_SUB;
        } else if (c == '>') {
            p++;
            tok = TOK_ARROW;
        } else {
            tok = '-';
        }
        break;

    PARSE2('!', '!', '=', TOK_NE)
    PARSE2('=', '=', '=', TOK_EQ)
    PARSE2('*', '*', '=', TOK_A_MUL)
    PARSE2('%', '%', '=', TOK_A_MOD)
    PARSE2('^', '^', '=', TOK_A_XOR)
        
        /* comments or operator */
    case '/':
        PEEKC(c, p);
        if (c == '*') {
            p = parse_comment(p);
            /* comments replaced by a blank */
            tok = ' ';
            goto keep_tok_flags;
        } else if (c == '/') {
            p = parse_line_comment(p);
            tok = ' ';
            goto keep_tok_flags;
        } else if (c == '=') {
            p++;
            tok = TOK_A_DIV;
        } else {
            tok = '/';
        }
        break;
        
        /* simple tokens */
    case '(':
    case ')':
    case '[':
    case ']':
    case '{':
    case '}':
    case ',':
    case ';':
    case ':':
    case '?':
    case '~':
    case '@': /* only used in assembler */
    parse_simple:
        tok = c;
        p++;
        break;
    default:
        if (c >= 0x80 && c <= 0xFF) /* utf8 identifiers */
        goto parse_ident_fast;
        if (parse_flags & PARSE_FLAG_ASM_FILE)
            goto parse_simple;
        tcc_error("unrecognized character \\x%02x", c);
        break;
    }
    tok_flags = 0;
keep_tok_flags:
    file->buf_ptr = p;
#if defined(PARSE_DEBUG)
    printf("token = %s\n", get_tok_str(tok, &tokc));
#endif
}

/* return next token without macro substitution. Can read input from
   macro_ptr buffer */
static void next_nomacro_spc(void)
{
    if (macro_ptr) {
    redo:
        tok = *macro_ptr;
        if (tok) {
            TOK_GET(&tok, &macro_ptr, &tokc);
            if (tok == TOK_LINENUM) {
                file->line_num = tokc.i;
                goto redo;
            }
        }
    } else {
        next_nomacro1();
    }
}

ST_FUNC void next_nomacro(void)
{
    do {
        next_nomacro_spc();
    } while (tok < 256 && (isidnum_table[tok - CH_EOF] & IS_SPC));
}
 

static void macro_subst(
    TokenString *tok_str,
    Sym **nested_list,
    const int *macro_str,
    int can_read_stream
    );

/* substitute arguments in replacement lists in macro_str by the values in
   args (field d) and return allocated string */
static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args)
{
    int t, t0, t1, spc;
    const int *st;
    Sym *s;
    CValue cval;
    TokenString str;
    CString cstr;

    tok_str_new(&str);
    t0 = t1 = 0;
    while(1) {
        TOK_GET(&t, &macro_str, &cval);
        if (!t)
            break;
        if (t == '#') {
            /* stringize */
            TOK_GET(&t, &macro_str, &cval);
            if (!t)
                goto bad_stringy;
            s = sym_find2(args, t);
            if (s) {
                cstr_new(&cstr);
                cstr_ccat(&cstr, '\"');
                st = s->d;
                spc = 0;
                while (*st) {
                    TOK_GET(&t, &st, &cval);
                    if (t != TOK_PLCHLDR
                     && t != TOK_NOSUBST
                     && 0 == check_space(t, &spc)) {
                        const char *s = get_tok_str(t, &cval);
                        while (*s) {
                            if (t == TOK_PPSTR && *s != '\'')
                                add_char(&cstr, *s);
                            else
                                cstr_ccat(&cstr, *s);
                            ++s;
                        }
                    }
                }
                cstr.size -= spc;
                cstr_ccat(&cstr, '\"');
                cstr_ccat(&cstr, '\0');
#ifdef PP_DEBUG
                printf("\nstringize: <%s>\n", (char *)cstr.data);
#endif
                /* add string */
                cval.str.size = cstr.size;
                cval.str.data = cstr.data;
                tok_str_add2(&str, TOK_PPSTR, &cval);
                cstr_free(&cstr);
            } else {
        bad_stringy:
                expect("macro parameter after '#'");
            }
        } else if (t >= TOK_IDENT) {
            s = sym_find2(args, t);
            if (s) {
                int l0 = str.len;
                st = s->d;
                /* if '##' is present before or after, no arg substitution */
                if (*macro_str == TOK_PPJOIN || t1 == TOK_PPJOIN) {
                    /* special case for var arg macros : ## eats the ','
                       if empty VA_ARGS variable. */
                    if (t1 == TOK_PPJOIN && t0 == ',' && gnu_ext && s->type.t) {
                        if (*st == 0) {
                            /* suppress ',' '##' */
                            str.len -= 2;
                        } else {
                            /* suppress '##' and add variable */
                            str.len--;
                            goto add_var;
                        }
                    } else {
                        for(;;) {
                            int t1;
                            TOK_GET(&t1, &st, &cval);
                            if (!t1)
                                break;
                            tok_str_add2(&str, t1, &cval);
                        }
                    }

                } else {
            add_var:
                    /* NOTE: the stream cannot be read when macro
                       substituting an argument */
                    macro_subst(&str, nested_list, st, 0);
                }
                if (str.len == l0) /* expanded to empty string */
                    tok_str_add(&str, TOK_PLCHLDR);
            } else {
                tok_str_add(&str, t);
            }
        } else {
            tok_str_add2(&str, t, &cval);
        }
        t0 = t1, t1 = t;
    }
    tok_str_add(&str, 0);
    return str.str;
}

static char const ab_month_name[12][4] =
{
    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};

/* peek or read [ws_str == NULL] next token from function macro call,
   walking up macro levels up to the file if necessary */
static int next_argstream(Sym **nested_list, int can_read_stream, TokenString *ws_str)
{
    int t;
    const int *p;
    Sym *sa;

    for (;;) {
        if (macro_ptr) {
            p = macro_ptr, t = *p;
            if (ws_str) {
                while (is_space(t) || TOK_LINEFEED == t || TOK_PLCHLDR == t)
                    tok_str_add(ws_str, t), t = *++p;
            }
            if (t == 0 && can_read_stream) {
                end_macro();
                /* also, end of scope for nested defined symbol */
                sa = *nested_list;
                while (sa && sa->v == 0)
                    sa = sa->prev;
                if (sa)
                    sa->v = 0;
                continue;
            }
        } else {
            ch = handle_eob();
            if (ws_str) {
                while (is_space(ch) || ch == '\n' || ch == '/') {
                    if (ch == '/') {
                        int c;
                        uint8_t *p = file->buf_ptr;
                        PEEKC(c, p);
                        if (c == '*') {
                            p = parse_comment(p);
                            file->buf_ptr = p - 1;
                        } else if (c == '/') {
                            p = parse_line_comment(p);
                            file->buf_ptr = p - 1;
                        } else
                            break;
                        ch = ' ';
                    }
                    if (!(ch == '\f' || ch == '\v' || ch == '\r'))
                        tok_str_add(ws_str, ch);
                    cinp();
                }
            }
            t = ch;
        }

        if (ws_str)
            return t;
        next_nomacro_spc();
        return tok;
    }
}

/* do macro substitution of current token with macro 's' and add
   result to (tok_str,tok_len). 'nested_list' is the list of all
   macros we got inside to avoid recursing. Return non zero if no
   substitution needs to be done */
static int macro_subst_tok(
    TokenString *tok_str,
    Sym **nested_list,
    Sym *s,
    int can_read_stream)
{
    Sym *args, *sa, *sa1;
    int parlevel, *mstr, t, t1, spc;
    TokenString str;
    char *cstrval;
    CValue cval;
    CString cstr;
    char buf[32];
    
    /* if symbol is a macro, prepare substitution */
    /* special macros */
    if (tok == TOK___LINE__) {
        snprintf(buf, sizeof(buf), "%d", file->line_num);
        cstrval = buf;
        t1 = TOK_PPNUM;
        goto add_cstr1;
    } else if (tok == TOK___FILE__) {
        cstrval = file->filename;
        goto add_cstr;
    } else if (tok == TOK___DATE__ || tok == TOK___TIME__) {
        time_t ti;
        struct tm *tm;

        time(&ti);
        tm = localtime(&ti);
        if (tok == TOK___DATE__) {
            snprintf(buf, sizeof(buf), "%s %2d %d", 
                     ab_month_name[tm->tm_mon], tm->tm_mday, tm->tm_year + 1900);
        } else {
            snprintf(buf, sizeof(buf), "%02d:%02d:%02d", 
                     tm->tm_hour, tm->tm_min, tm->tm_sec);
        }
        cstrval = buf;
    add_cstr:
        t1 = TOK_STR;
    add_cstr1:
        cstr_new(&cstr);
        cstr_cat(&cstr, cstrval, 0);
        cval.str.size = cstr.size;
        cval.str.data = cstr.data;
        tok_str_add2(tok_str, t1, &cval);
        cstr_free(&cstr);
    } else {
        int saved_parse_flags = parse_flags;

        mstr = s->d;
        if (s->type.t == MACRO_FUNC) {
            /* whitespace between macro name and argument list */
            TokenString ws_str;
            tok_str_new(&ws_str);

            spc = 0;
            parse_flags |= PARSE_FLAG_SPACES | PARSE_FLAG_LINEFEED
                | PARSE_FLAG_ACCEPT_STRAYS;

            /* get next token from argument stream */
            t = next_argstream(nested_list, can_read_stream, &ws_str);
            if (t != '(') {
                /* not a macro substitution after all, restore the
                 * macro token plus all whitespace we've read.
                 * whitespace is intentionally not merged to preserve
                 * newlines. */
                parse_flags = saved_parse_flags;
                tok_str_add(tok_str, tok);
                if (parse_flags & PARSE_FLAG_SPACES) {
                    int i;
                    for (i = 0; i < ws_str.len; i++)
                        tok_str_add(tok_str, ws_str.str[i]);
                }
                tok_str_free_str(ws_str.str);
                return 0;
            } else {
                tok_str_free_str(ws_str.str);
            }
        do {
        next_nomacro(); /* eat '(' */
        } while (tok == TOK_PLCHLDR);

            /* argument macro */
            args = NULL;
            sa = s->next;
            /* NOTE: empty args are allowed, except if no args */
            for(;;) {
                do {
                    next_argstream(nested_list, can_read_stream, NULL);
                } while (is_space(tok) || TOK_LINEFEED == tok);
    empty_arg:
                /* handle '()' case */
                if (!args && !sa && tok == ')')
                    break;
                if (!sa)
                    tcc_error("macro '%s' used with too many args",
                          get_tok_str(s->v, 0));
                tok_str_new(&str);
                parlevel = spc = 0;
                /* NOTE: non zero sa->t indicates VA_ARGS */
                while ((parlevel > 0 || 
                        (tok != ')' && 
                         (tok != ',' || sa->type.t)))) {
                    if (tok == TOK_EOF || tok == 0)
                        break;
                    if (tok == '(')
                        parlevel++;
                    else if (tok == ')')
                        parlevel--;
                    if (tok == TOK_LINEFEED)
                        tok = ' ';
                    if (!check_space(tok, &spc))
                        tok_str_add2(&str, tok, &tokc);
                    next_argstream(nested_list, can_read_stream, NULL);
                }
                if (parlevel)
                    expect(")");
                str.len -= spc;
                tok_str_add(&str, 0);
                sa1 = sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, 0);
                sa1->d = str.str;
                sa = sa->next;
                if (tok == ')') {
                    /* special case for gcc var args: add an empty
                       var arg argument if it is omitted */
                    if (sa && sa->type.t && gnu_ext)
                        goto empty_arg;
                    break;
                }
                if (tok != ',')
                    expect(",");
            }
            if (sa) {
                tcc_error("macro '%s' used with too few args",
                      get_tok_str(s->v, 0));
            }

            parse_flags = saved_parse_flags;

            /* now subst each arg */
            mstr = macro_arg_subst(nested_list, mstr, args);
            /* free memory */
            sa = args;
            while (sa) {
                sa1 = sa->prev;
                tok_str_free_str(sa->d);
                sym_free(sa);
                sa = sa1;
            }
        }

        sym_push2(nested_list, s->v, 0, 0);
        parse_flags = saved_parse_flags;
        macro_subst(tok_str, nested_list, mstr, can_read_stream | 2);

        /* pop nested defined symbol */
        sa1 = *nested_list;
        *nested_list = sa1->prev;
        sym_free(sa1);
        if (mstr != s->d)
            tok_str_free_str(mstr);
    }
    return 0;
}

static int paste_tokens(int t1, CValue *v1, int t2, CValue *v2)
{
    CString cstr;
    int n, ret = 1;

    cstr_new(&cstr);
    if (t1 != TOK_PLCHLDR)
        cstr_cat(&cstr, get_tok_str(t1, v1), -1);
    n = cstr.size;
    if (t2 != TOK_PLCHLDR)
        cstr_cat(&cstr, get_tok_str(t2, v2), -1);
    cstr_ccat(&cstr, '\0');

    tcc_open_bf(tcc_state, ":paste:", cstr.size);
    memcpy(file->buffer, cstr.data, cstr.size);
    for (;;) {
        next_nomacro1();
        if (0 == *file->buf_ptr)
            break;
        if (is_space(tok))
            continue;
        tcc_warning("pasting \"%.*s\" and \"%s\" does not give a valid"
            " preprocessing token", n, cstr.data, (char*)cstr.data + n);
        ret = 0;
        break;
    }
    tcc_close();
    //printf("paste <%s>\n", (char*)cstr.data);
    cstr_free(&cstr);
    return ret;
}

/* handle the '##' operator. Return NULL if no '##' seen. Otherwise
   return the resulting string (which must be freed). */
static inline int *macro_twosharps(const int *ptr0)
{
    int t;
    CValue cval;
    TokenString macro_str1;
    int start_of_nosubsts = -1;
    const int *ptr;

    /* we search the first '##' */
    for (ptr = ptr0;;) {
        TOK_GET(&t, &ptr, &cval);
        if (t == TOK_PPJOIN)
            break;
        if (t == 0)
            return NULL;
    }

    tok_str_new(&macro_str1);

    //tok_print(" $$$", ptr0);
    for (ptr = ptr0;;) {
        TOK_GET(&t, &ptr, &cval);
        if (t == 0)
            break;
        if (t == TOK_PPJOIN)
            continue;
        while (*ptr == TOK_PPJOIN) {
            int t1; CValue cv1;
            /* given 'a##b', remove nosubsts preceding 'a' */
            if (start_of_nosubsts >= 0)
                macro_str1.len = start_of_nosubsts;
            /* given 'a##b', remove nosubsts preceding 'b' */
            while ((t1 = *++ptr) == TOK_NOSUBST)
                ;
            if (t1 && t1 != TOK_PPJOIN) {
                TOK_GET(&t1, &ptr, &cv1);
                if (t != TOK_PLCHLDR || t1 != TOK_PLCHLDR) {
                    if (paste_tokens(t, &cval, t1, &cv1)) {
                        t = tok, cval = tokc;
                    } else {
                        tok_str_add2(&macro_str1, t, &cval);
                        t = t1, cval = cv1;
                    }
                }
            }
        }
        if (t == TOK_NOSUBST) {
            if (start_of_nosubsts < 0)
                start_of_nosubsts = macro_str1.len;
        } else {
            start_of_nosubsts = -1;
        }
        tok_str_add2(&macro_str1, t, &cval);
    }
    tok_str_add(&macro_str1, 0);
    //tok_print(" ###", macro_str1.str);
    return macro_str1.str;
}

/* do macro substitution of macro_str and add result to
   (tok_str,tok_len). 'nested_list' is the list of all macros we got
   inside to avoid recursing. */
static void macro_subst(
    TokenString *tok_str,
    Sym **nested_list,
    const int *macro_str,
    int can_read_stream
    )
{
    Sym *s;
    const int *ptr;
    int t, spc, nosubst;
    CValue cval;
    int *macro_str1 = NULL;
    
    /* first scan for '##' operator handling */
    ptr = macro_str;
    spc = nosubst = 0;

    /* first scan for '##' operator handling */
    if (can_read_stream) {
        macro_str1 = macro_twosharps(ptr);
        if (macro_str1)
            ptr = macro_str1;
    }

    while (1) {
        TOK_GET(&t, &ptr, &cval);
        if (t == 0)
            break;

        if (t >= TOK_IDENT && 0 == nosubst) {
            s = define_find(t);
            if (s == NULL)
                goto no_subst;

            /* if nested substitution, do nothing */
            if (sym_find2(*nested_list, t)) {
                /* and mark it as TOK_NOSUBST, so it doesn't get subst'd again */
                tok_str_add2(tok_str, TOK_NOSUBST, NULL);
                goto no_subst;
            }

            {
                TokenString str;
                str.str = (int*)ptr;
                begin_macro(&str, 2);

                tok = t;
                macro_subst_tok(tok_str, nested_list, s, can_read_stream);

                if (str.alloc == 3) {
                    /* already finished by reading function macro arguments */
                    break;
                }

                ptr = macro_ptr;
                end_macro ();
            }

            spc = (tok_str->len &&
                   is_space(tok_last(tok_str->str,
                                     tok_str->str + tok_str->len)));

        } else {

            if (t == '\\' && !(parse_flags & PARSE_FLAG_ACCEPT_STRAYS))
                tcc_error("stray '\\' in program");

no_subst:
            if (!check_space(t, &spc))
                tok_str_add2(tok_str, t, &cval);
            nosubst = 0;
            if (t == TOK_NOSUBST)
                nosubst = 1;
        }
    }
    if (macro_str1)
        tok_str_free_str(macro_str1);

}

/* return next token with macro substitution */
ST_FUNC void next(void)
{
 redo:
    if (parse_flags & PARSE_FLAG_SPACES)
        next_nomacro_spc();
    else
        next_nomacro();

    if (macro_ptr) {
        if (tok == TOK_NOSUBST || tok == TOK_PLCHLDR) {
        /* discard preprocessor markers */
            goto redo;
        } else if (tok == 0) {
            /* end of macro or unget token string */
            end_macro();
            goto redo;
        }
    } else if (tok >= TOK_IDENT && (parse_flags & PARSE_FLAG_PREPROCESS)) {
        Sym *s;
        /* if reading from file, try to substitute macros */
        s = define_find(tok);
        if (s) {
            Sym *nested_list = NULL;
            tokstr_buf.len = 0;
            macro_subst_tok(&tokstr_buf, &nested_list, s, 1);
            tok_str_add(&tokstr_buf, 0);
            begin_macro(&tokstr_buf, 2);
            goto redo;
        }
    }
    /* convert preprocessor tokens into C tokens */
    if (tok == TOK_PPNUM) {
        if  (parse_flags & PARSE_FLAG_TOK_NUM)
            parse_number((char *)tokc.str.data);
    } else if (tok == TOK_PPSTR) {
        if (parse_flags & PARSE_FLAG_TOK_STR)
            parse_string((char *)tokc.str.data, tokc.str.size - 1);
    }
}

/* push back current token and set current token to 'last_tok'. Only
   identifier case handled for labels. */
ST_INLN void unget_tok(int last_tok)
{

    TokenString *str = tok_str_alloc();
    tok_str_add2(str, tok, &tokc);
    tok_str_add(str, 0);
    begin_macro(str, 1);
    tok = last_tok;
}

ST_FUNC void preprocess_start(TCCState *s1)
{
    char *buf;

    s1->include_stack_ptr = s1->include_stack;
    s1->ifdef_stack_ptr = s1->ifdef_stack;
    file->ifdef_stack_ptr = s1->ifdef_stack_ptr;
    pp_once++;
    pvtop = vtop = vstack - 1;
    s1->pack_stack[0] = 0;
    s1->pack_stack_ptr = s1->pack_stack;

    set_idnum('$', s1->dollars_in_identifiers ? IS_ID : 0);
    set_idnum('.', (parse_flags & PARSE_FLAG_ASM_FILE) ? IS_ID : 0);

    buf = tcc_malloc(3 + strlen(file->filename));
    sprintf(buf, "\"%s\"", file->filename);
    tcc_define_symbol(s1, "__BASE_FILE__", buf);
    tcc_free(buf);

    if (s1->nb_cmd_include_files) {
    CString cstr;
    int i;
    cstr_new(&cstr);
    for (i = 0; i < s1->nb_cmd_include_files; i++) {
        cstr_cat(&cstr, "#include \"", -1);
        cstr_cat(&cstr, s1->cmd_include_files[i], -1);
        cstr_cat(&cstr, "\"\n", -1);
    }
        *s1->include_stack_ptr++ = file;
    tcc_open_bf(s1, "<command line>", cstr.size);
    memcpy(file->buffer, cstr.data, cstr.size);
    cstr_free(&cstr);
    }
}

ST_FUNC void tccpp_new(TCCState *s)
{
    int i, c;
    const char *p, *r;

    /* might be used in error() before preprocess_start() */
    s->include_stack_ptr = s->include_stack;

    /* init isid table */
    for(i = CH_EOF; i<128; i++)
        set_idnum(i,
            is_space(i) ? IS_SPC
            : isid(i) ? IS_ID
            : isnum(i) ? IS_NUM
            : 0);

    for(i = 128; i<256; i++)
        set_idnum(i, IS_ID);

    /* init allocators */
    tal_new(&toksym_alloc, TOKSYM_TAL_LIMIT, TOKSYM_TAL_SIZE);
    tal_new(&tokstr_alloc, TOKSTR_TAL_LIMIT, TOKSTR_TAL_SIZE);
    tal_new(&cstr_alloc, CSTR_TAL_LIMIT, CSTR_TAL_SIZE);

    memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
    cstr_new(&cstr_buf);
    cstr_realloc(&cstr_buf, STRING_MAX_SIZE);
    tok_str_new(&tokstr_buf);
    tok_str_realloc(&tokstr_buf, TOKSTR_MAX_SIZE);
    
    tok_ident = TOK_IDENT;
    p = tcc_keywords;
    while (*p) {
        r = p;
        for(;;) {
            c = *r++;
            if (c == '\0')
                break;
        }
        tok_alloc(p, r - p - 1);
        p = r;
    }
}

ST_FUNC void tccpp_delete(TCCState *s)
{
    int i, n;

    /* free -D and compiler defines */
    free_defines(NULL);

    /* cleanup from error/setjmp */
    while (macro_stack)
        end_macro();
    macro_ptr = NULL;

    while (file)
        tcc_close();

    /* free tokens */
    n = tok_ident - TOK_IDENT;
    for(i = 0; i < n; i++)
        tal_free(toksym_alloc, table_ident[i]);
    tcc_free(table_ident);
    table_ident = NULL;

    /* free static buffers */
    cstr_free(&tokcstr);
    cstr_free(&cstr_buf);
    cstr_free(&macro_equal_buf);
    tok_str_free_str(tokstr_buf.str);

    /* free allocators */
    tal_delete(toksym_alloc);
    toksym_alloc = NULL;
    tal_delete(tokstr_alloc);
    tokstr_alloc = NULL;
    tal_delete(cstr_alloc);
    cstr_alloc = NULL;
}

/* ------------------------------------------------------------------------- */
/* tcc -E [-P[1]] [-dD} support */

static void tok_print(const char *msg, const int *str)
{
    FILE *fp;
    int t;
    CValue cval;

    fp = tcc_state->ppfp;
    if (!fp || !tcc_state->dflag)
        fp = stdout;

    fprintf(fp, "%s ", msg);
    while (str) {
    TOK_GET(&t, &str, &cval);
    if (!t)
        break;
    fprintf(fp,"%s", get_tok_str(t, &cval));
    }
    fprintf(fp, "\n");
}

static void pp_line(TCCState *s1, BufferedFile *f, int level)
{
    int d = f->line_num - f->line_ref;

    if (s1->dflag & 4)
    return;

    if (s1->Pflag == LINE_MACRO_OUTPUT_FORMAT_NONE) {
        ;
    } else if (level == 0 && f->line_ref && d < 8) {
    while (d > 0)
        fputs("\n", s1->ppfp), --d;
    } else if (s1->Pflag == LINE_MACRO_OUTPUT_FORMAT_STD) {
    fprintf(s1->ppfp, "#line %d \"%s\"\n", f->line_num, f->filename);
    } else {
    fprintf(s1->ppfp, "# %d \"%s\"%s\n", f->line_num, f->filename,
        level > 0 ? " 1" : level < 0 ? " 2" : "");
    }
    f->line_ref = f->line_num;
}

static void define_print(TCCState *s1, int v)
{
    FILE *fp;
    Sym *s;

    s = define_find(v);
    if (NULL == s || NULL == s->d)
        return;

    fp = s1->ppfp;
    fprintf(fp, "#define %s", get_tok_str(v, NULL));
    if (s->type.t == MACRO_FUNC) {
        Sym *a = s->next;
        fprintf(fp,"(");
        if (a)
            for (;;) {
                fprintf(fp,"%s", get_tok_str(a->v & ~SYM_FIELD, NULL));
                if (!(a = a->next))
                    break;
                fprintf(fp,",");
            }
        fprintf(fp,")");
    }
    tok_print("", s->d);
}

static void pp_debug_defines(TCCState *s1)
{
    int v, t;
    const char *vs;
    FILE *fp;

    t = pp_debug_tok;
    if (t == 0)
        return;

    file->line_num--;
    pp_line(s1, file, 0);
    file->line_ref = ++file->line_num;

    fp = s1->ppfp;
    v = pp_debug_symv;
    vs = get_tok_str(v, NULL);
    if (t == TOK_DEFINE) {
        define_print(s1, v);
    } else if (t == TOK_UNDEF) {
        fprintf(fp, "#undef %s\n", vs);
    } else if (t == TOK_push_macro) {
        fprintf(fp, "#pragma push_macro(\"%s\")\n", vs);
    } else if (t == TOK_pop_macro) {
        fprintf(fp, "#pragma pop_macro(\"%s\")\n", vs);
    }
    pp_debug_tok = 0;
}

static void pp_debug_builtins(TCCState *s1)
{
    int v;
    for (v = TOK_IDENT; v < tok_ident; ++v)
        define_print(s1, v);
}

/* Add a space between tokens a and b to avoid unwanted textual pasting */
static int pp_need_space(int a, int b)
{
    return 'E' == a ? '+' == b || '-' == b
        : '+' == a ? TOK_INC == b || '+' == b
        : '-' == a ? TOK_DEC == b || '-' == b
        : a >= TOK_IDENT ? b >= TOK_IDENT
        : 0;
}

/* maybe hex like 0x1e */
static int pp_check_he0xE(int t, const char *p)
{
    if (t == TOK_PPNUM && toup(strchr(p, 0)[-1]) == 'E')
        return 'E';
    return t;
}

/* Preprocess the current file */
ST_FUNC int tcc_preprocess(TCCState *s1)
{
    BufferedFile **iptr;
    int token_seen, spcs, level;
    const char *p;
    Sym *define_start;

    define_start = define_stack;
    preprocess_start(s1);

    ch = file->buf_ptr[0];
    tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
    parse_flags = PARSE_FLAG_PREPROCESS
                | (parse_flags & PARSE_FLAG_ASM_FILE)
                | PARSE_FLAG_LINEFEED
                | PARSE_FLAG_SPACES
                | PARSE_FLAG_ACCEPT_STRAYS
                ;

    /* Credits to Fabrice Bellard's initial revision to demonstrate its
       capability to compile and run itself, provided all numbers are
       given as decimals. tcc -E -P10 will do. */
    if (s1->Pflag == LINE_MACRO_OUTPUT_FORMAT_P10)
        parse_flags |= PARSE_FLAG_TOK_NUM, s1->Pflag = 1;

#ifdef PP_BENCH
    /* for PP benchmarks */
    do next(); while (tok != TOK_EOF);
    free_defines(define_start);
    return 0;
#endif

    if (s1->dflag & 1) {
        pp_debug_builtins(s1);
        s1->dflag &= ~1;
    }

    token_seen = TOK_LINEFEED, spcs = 0;
    pp_line(s1, file, 0);

    for (;;) {
        iptr = s1->include_stack_ptr;
        next();
        if (tok == TOK_EOF)
            break;
        level = s1->include_stack_ptr - iptr;
        if (level) {
            if (level > 0)
                pp_line(s1, *iptr, 0);
            pp_line(s1, file, level);
        }

        if (s1->dflag) {
            pp_debug_defines(s1);
            if (s1->dflag & 4)
                continue;
        }

        if (token_seen == TOK_LINEFEED) {
            if (tok == ' ') {
                ++spcs;
                continue;
            }
            if (tok == TOK_LINEFEED) {
                spcs = 0;
                continue;
            }
            pp_line(s1, file, 0);
        } else if (tok == TOK_LINEFEED) {
            ++file->line_ref;
        } else {
            spcs = pp_need_space(token_seen, tok);
        }

        while (spcs)
            fputs(" ", s1->ppfp), --spcs;
        fputs(p = get_tok_str(tok, &tokc), s1->ppfp);
        token_seen = pp_check_he0xE(tok, p);;
    }
    /* reset define stack, but keep -D and built-ins */
    free_defines(define_start);
    return 0;
}

/* ------------------------------------------------------------------------- */

https://gitlab.com/janneke/tinycc/-/blob/ff2210b308321f27ee07476d07f24b5095602b17/tccgen.c

File: ../git/live-bootstrap/sysa/tcc-0.9.26/build/tcc-0.9.26-1136-g5bba73cc/tccgen.c used in: Step 378, Step 395, Step 407, Step 419, Step 431, Step 443, Step 455
/*
 *  TCC - Tiny C Compiler
 * 
 *  Copyright (c) 2001-2004 Fabrice Bellard
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef _TCC_H
#include "tcc.h"
#endif

#if BOOTSTRAP && __arm__
void
tccgen_ok ()
{
}
#endif

/********************************************************/
/* global variables */

/* loc : local variable index
   ind : output code index
   rsym: return symbol
   anon_sym: anonymous symbol index
*/
ST_DATA int rsym, anon_sym, ind, loc;

ST_DATA Sym *sym_free_first;
ST_DATA void **sym_pools;
ST_DATA int nb_sym_pools;

ST_DATA Sym *global_stack;
ST_DATA Sym *local_stack;
ST_DATA Sym *define_stack;
ST_DATA Sym *global_label_stack;
ST_DATA Sym *local_label_stack;
static int local_scope;
static int in_sizeof;
static int section_sym;

ST_DATA int vlas_in_scope; /* number of VLAs that are currently in scope */
ST_DATA int vla_sp_root_loc; /* vla_sp_loc for SP before any VLAs were pushed */
ST_DATA int vla_sp_loc; /* Pointer to variable holding location to store stack pointer on the stack when modifying stack pointer */

ST_DATA SValue __vstack[1+VSTACK_SIZE], *vtop, *pvtop;

ST_DATA int const_wanted; /* true if constant wanted */
ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
ST_DATA int global_expr;  /* true if compound literals must be allocated globally (used during initializers parsing */
ST_DATA CType func_vt; /* current function return type (used by return instruction) */
ST_DATA int func_var; /* true if current function is variadic (used by return instruction) */
ST_DATA int func_vc;
ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
ST_DATA const char *funcname;

ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;

ST_DATA struct switch_t {
    struct case_t {
#if HAVE_LONG_LONG_STUB || HAVE_LONG_LONG
        int64_t v1, v2;
#else
      int32_t v1, v1_padding, v2, v2_padding;
#endif
    int sym;
    } **p; int n; /* list of case ranges */
    int def_sym; /* default symbol */
} *cur_switch; /* current switch */

/* ------------------------------------------------------------------------- */

static void gen_cast(CType *type);
static inline CType *pointed_type(CType *type);
static int is_compatible_types(CType *type1, CType *type2);
static int parse_btype(CType *type, AttributeDef *ad);
static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td);
static void parse_expr_type(CType *type);
static void init_putv(CType *type, Section *sec, unsigned long c);
static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only);
static void block(int *bsym, int *csym, int is_expr);
static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope);
static int decl0(int l, int is_for_loop_init, Sym *);
static void expr_eq(void);
static void vla_runtime_type_size(CType *type, int *a);
static void vla_sp_restore(void);
static void vla_sp_restore_root(void);
static int is_compatible_parameter_types(CType *type1, CType *type2);
#if HAVE_LONG_LONG
static inline int64_t expr_const64(void);
ST_FUNC void vpush64(int ty, unsigned long long v);
#else
static inline int32_t expr_const32(void);
#endif
ST_FUNC void vpush(CType *type);
ST_FUNC int gvtst(int inv, int t);
ST_FUNC int is_btype_size(int bt);
static void gen_inline_functions(TCCState *s);

ST_INLN int is_float(int t)
{
    int bt;
    bt = t & VT_BTYPE;
    return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT || bt == VT_QFLOAT;
}

/* we use our own 'finite' function to avoid potential problems with
   non standard math libs */
/* XXX: endianness dependent */
ST_FUNC int ieee_finite(double d)
{
    int p[4];
    memcpy(p, &d, sizeof(double));
    return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
}

ST_FUNC void test_lvalue(void)
{
    if (!(vtop->r & VT_LVAL))
        expect("lvalue");
}

ST_FUNC void check_vstack(void)
{
    if (pvtop != vtop)
        tcc_error("internal compiler error: vstack leak (%d)", vtop - pvtop);
}

/* ------------------------------------------------------------------------- */
/* vstack debugging aid */

#if 0
void pv (const char *lbl, int a, int b)
{
    int i;
    for (i = a; i < a + b; ++i) {
        SValue *p = &vtop[-i];
        printf("%s vtop[-%d] : type.t:%04x  r:%04x  r2:%04x  c.i:%d\n",
            lbl, i, p->type.t, p->r, p->r2, (int)p->c.i);
    }
}
#endif

/* ------------------------------------------------------------------------- */
/* start of translation unit info */
ST_FUNC void tcc_debug_start(TCCState *s1)
{
    if (s1->do_debug) {
        char buf[512];

        /* file info: full path + filename */
        section_sym = put_elf_sym(symtab_section, 0, 0,
                                  ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
                                  text_section->sh_num, NULL);
        getcwd(buf, sizeof(buf));
#ifdef _WIN32
        normalize_slashes(buf);
#endif
        pstrcat(buf, sizeof(buf), "/");
        put_stabs_r(buf, N_SO, 0, 0,
                    text_section->data_offset, text_section, section_sym);
        put_stabs_r(file->filename, N_SO, 0, 0,
                    text_section->data_offset, text_section, section_sym);
        last_ind = 0;
        last_line_num = 0;
    }

    /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
       symbols can be safely used */
    put_elf_sym(symtab_section, 0, 0,
                ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0,
                SHN_ABS, file->filename);
}

/* put end of translation unit info */
ST_FUNC void tcc_debug_end(TCCState *s1)
{
    if (!s1->do_debug)
        return;
    put_stabs_r(NULL, N_SO, 0, 0,
        text_section->data_offset, text_section, section_sym);

}

/* generate line number info */
ST_FUNC void tcc_debug_line(TCCState *s1)
{
    if (!s1->do_debug)
        return;
    if ((last_line_num != file->line_num || last_ind != ind)) {
        put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
        last_ind = ind;
        last_line_num = file->line_num;
    }
}

/* put function symbol */
ST_FUNC void tcc_debug_funcstart(TCCState *s1, Sym *sym)
{
    char buf[512];

    if (!s1->do_debug)
        return;

    /* stabs info */
    /* XXX: we put here a dummy type */
    snprintf(buf, sizeof(buf), "%s:%c1",
             funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
    put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
                cur_text_section, sym->c);
    /* //gr gdb wants a line at the function */
    put_stabn(N_SLINE, 0, file->line_num, 0);

    last_ind = 0;
    last_line_num = 0;
}

/* put function size */
ST_FUNC void tcc_debug_funcend(TCCState *s1, int size)
{
    if (!s1->do_debug)
        return;
    put_stabn(N_FUN, 0, 0, size);
}

/* ------------------------------------------------------------------------- */
ST_FUNC void tccgen_start(TCCState *s1)
{
    cur_text_section = NULL;
    funcname = "";
    anon_sym = SYM_FIRST_ANOM;
    section_sym = 0;
    const_wanted = 0;
    nocode_wanted = 1;

    /* define some often used types */
    int_type.t = VT_INT;
    char_pointer_type.t = VT_BYTE;
    mk_pointer(&char_pointer_type);
#if PTR_SIZE == 4
    size_type.t = VT_INT;
#else
    size_type.t = VT_LLONG;
#endif
    func_old_type.t = VT_FUNC;
    func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD);

    tcc_debug_start(s1);

#ifdef TCC_TARGET_ARM
    arm_init(s1);
#endif
}

ST_FUNC void tccgen_end(TCCState *s1)
{
    gen_inline_functions(s1);
    check_vstack();
    /* end of translation unit info */
    tcc_debug_end(s1);
}

/* ------------------------------------------------------------------------- */
/* apply storage attributes to Elf symbol */

static void update_storage(Sym *sym)
{
    int t;
    ElfW(Sym) *esym;

    if (0 == sym->c)
        return;

    t = sym->type.t;
    esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];

#if !__MESC__ // Nyacc 0.80.40 cpp-bug
    if (t & VT_VIS_MASK)
        esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
            | ((t & VT_VIS_MASK) >> VT_VIS_SHIFT);

    if (t & VT_WEAK)
        esym->st_info = ELFW(ST_INFO)(STB_WEAK, ELFW(ST_TYPE)(esym->st_info));
#else //__MESC__
    // #warning work around Nyacc 0.80.42 bug.
#endif // __MESC__
#ifdef TCC_TARGET_PE
    if (t & VT_EXPORT)
        esym->st_other |= ST_PE_EXPORT;
#endif
}

/* ------------------------------------------------------------------------- */
/* update sym->c so that it points to an external symbol in section
   'section' with value 'value' */

ST_FUNC void put_extern_sym2(Sym *sym, Section *section,
                            addr_t value, unsigned long size,
                            int can_add_underscore)
{
    int sym_type, sym_bind, sh_num, info, other, t;
    ElfW(Sym) *esym;
    const char *name;
    char buf1[256];
#ifdef CONFIG_TCC_BCHECK
    char buf[32];
#endif

    if (section == NULL)
        sh_num = SHN_UNDEF;
    else if (section == SECTION_ABS)
        sh_num = SHN_ABS;
    else
        sh_num = section->sh_num;

    if (!sym->c) {
        name = get_tok_str(sym->v, NULL);
#ifdef CONFIG_TCC_BCHECK
        if (tcc_state->do_bounds_check) {
            /* XXX: avoid doing that for statics ? */
            /* if bound checking is activated, we change some function
               names by adding the "__bound" prefix */
            switch(sym->v) {
#ifdef TCC_TARGET_PE
            /* XXX: we rely only on malloc hooks */
            case TOK_malloc:
            case TOK_free:
            case TOK_realloc:
            case TOK_memalign:
            case TOK_calloc:
#endif
            case TOK_memcpy:
            case TOK_memmove:
            case TOK_memset:
            case TOK_strlen:
            case TOK_strcpy:
            case TOK_alloca:
                strcpy(buf, "__bound_");
                strcat(buf, name);
                name = buf;
                break;
            }
        }
#endif
        t = sym->type.t;
        if ((t & VT_BTYPE) == VT_FUNC) {
            sym_type = STT_FUNC;
        } else if ((t & VT_BTYPE) == VT_VOID) {
            sym_type = STT_NOTYPE;
        } else {
            sym_type = STT_OBJECT;
        }
        if (t & VT_STATIC)
            sym_bind = STB_LOCAL;
        else
            sym_bind = STB_GLOBAL;
        other = 0;
#ifdef TCC_TARGET_PE
        if (sym_type == STT_FUNC && sym->type.ref) {
            Sym *ref = sym->type.ref;
            if (ref->a.func_call == FUNC_STDCALL && can_add_underscore) {
                sprintf(buf1, "_%s@%d", name, ref->a.func_args * PTR_SIZE);
                name = buf1;
                other |= ST_PE_STDCALL;
                can_add_underscore = 0;
            }
        }
        if (t & VT_IMPORT)
            other |= ST_PE_IMPORT;
#endif
        if (tcc_state->leading_underscore && can_add_underscore) {
            buf1[0] = '_';
            pstrcpy(buf1 + 1, sizeof(buf1) - 1, name);
            name = buf1;
        }
        if (sym->asm_label)
            name = get_tok_str(sym->asm_label, NULL);
        info = ELFW(ST_INFO)(sym_bind, sym_type);
        sym->c = set_elf_sym(symtab_section, value, size, info, other, sh_num, name);
    } else {
        esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
        esym->st_value = value;
        esym->st_size = size;
        esym->st_shndx = sh_num;
    }
    update_storage(sym);
}

ST_FUNC void put_extern_sym(Sym *sym, Section *section,
                           addr_t value, unsigned long size)
{
    put_extern_sym2(sym, section, value, size, 1);
}

/* add a new relocation entry to symbol 'sym' in section 's' */
ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type,
                     addr_t addend)
{
    int c = 0;

    if (nocode_wanted && s == cur_text_section)
        return;

    if (sym) {
        if (0 == sym->c)
            put_extern_sym(sym, NULL, 0, 0);
        c = sym->c;
    }

    /* now we can add ELF relocation info */
    put_elf_reloca(symtab_section, s, offset, type, c, addend);
}

#if PTR_SIZE == 4
ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type)
{
    greloca(s, sym, offset, type, 0);
}
#endif

/* ------------------------------------------------------------------------- */
/* symbol allocator */
static Sym *__sym_malloc(void)
{
    Sym *sym_pool, *sym, *last_sym;
    int i;

    sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
    dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);

    last_sym = sym_free_first;
    sym = sym_pool;
    for(i = 0; i < SYM_POOL_NB; i++) {
        sym->next = last_sym;
        last_sym = sym;
        sym++;
    }
    sym_free_first = last_sym;
    return last_sym;
}

static inline Sym *sym_malloc(void)
{
    Sym *sym;
#ifndef SYM_DEBUG
    sym = sym_free_first;
    if (!sym)
        sym = __sym_malloc();
    sym_free_first = sym->next;
    return sym;
#else
    sym = tcc_malloc(sizeof(Sym));
    return sym;
#endif
}

ST_INLN void sym_free(Sym *sym)
{
#ifndef SYM_DEBUG
    sym->next = sym_free_first;
    sym_free_first = sym;
#else
    tcc_free(sym);
#endif
}

/* push, without hashing */
ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
{
    Sym *s;

    s = sym_malloc();
    s->scope = 0;
    s->v = v;
    s->type.t = t;
    s->type.ref = NULL;
#ifdef _WIN64
    s->d = NULL;
#endif
    s->c = c;
    s->next = NULL;
    /* add in stack */
    s->prev = *ps;
    *ps = s;
    return s;
}

/* find a symbol and return its associated structure. 's' is the top
   of the symbol stack */
ST_FUNC Sym *sym_find2(Sym *s, int v)
{
    while (s) {
        if (s->v == v)
            return s;
        else if (s->v == -1)
            return NULL;
        s = s->prev;
    }
    return NULL;
}

/* structure lookup */
ST_INLN Sym *struct_find(int v)
{
    v -= TOK_IDENT;
    if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
        return NULL;
    return table_ident[v]->sym_struct;
}

/* find an identifier */
ST_INLN Sym *sym_find(int v)
{
    v -= TOK_IDENT;
    if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
        return NULL;
    return table_ident[v]->sym_identifier;
}

/* push a given symbol on the symbol stack */
ST_FUNC Sym *sym_push(int v, CType *type, int r, long c)
{
    Sym *s, **ps;
    TokenSym *ts;

    if (local_stack)
        ps = &local_stack;
    else
        ps = &global_stack;
    s = sym_push2(ps, v, type->t, c);
    s->type.ref = type->ref;
    s->r = r;
    /* don't record fields or anonymous symbols */
    /* XXX: simplify */
    if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
        /* record symbol in token array */
        ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
        if (v & SYM_STRUCT)
            ps = &ts->sym_struct;
        else
            ps = &ts->sym_identifier;
        s->prev_tok = *ps;
        *ps = s;
        s->scope = local_scope;
        if (s->prev_tok && s->prev_tok->scope == s->scope)
            tcc_error("redeclaration of '%s'",
                get_tok_str(v & ~SYM_STRUCT, NULL));
    }
    return s;
}

/* push a global identifier */
ST_FUNC Sym *global_identifier_push(int v, int t, long c)
{
    Sym *s, **ps;
    s = sym_push2(&global_stack, v, t, c);
    /* don't record anonymous symbol */
    if (v < SYM_FIRST_ANOM) {
        ps = &table_ident[v - TOK_IDENT]->sym_identifier;
        /* modify the top most local identifier, so that
           sym_identifier will point to 's' when popped */
        while (*ps != NULL)
            ps = &(*ps)->prev_tok;
        s->prev_tok = NULL;
        *ps = s;
    }
    return s;
}

/* pop symbols until top reaches 'b'.  If KEEP is non-zero don't really
   pop them yet from the list, but do remove them from the token array.  */
ST_FUNC void sym_pop(Sym **ptop, Sym *b, int keep)
{
    Sym *s, *ss, **ps;
    TokenSym *ts;
    int v;

    s = *ptop;
    while(s != b) {
        ss = s->prev;
        v = s->v;
        /* remove symbol in token array */
        /* XXX: simplify */
        if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
            ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
            if (v & SYM_STRUCT)
                ps = &ts->sym_struct;
            else
                ps = &ts->sym_identifier;
            *ps = s->prev_tok;
        }
    if (!keep)
        sym_free(s);
        s = ss;
    }
    if (!keep)
    *ptop = b;
}

/* ------------------------------------------------------------------------- */

static void vsetc(CType *type, int r, CValue *vc)
{
    int v;

    if (vtop >= vstack + (VSTACK_SIZE - 1))
        tcc_error("memory full (vstack)");
    /* cannot let cpu flags if other instruction are generated. Also
       avoid leaving VT_JMP anywhere except on the top of the stack
       because it would complicate the code generator.

       Don't do this when nocode_wanted.  vtop might come from
       !nocode_wanted regions (see 88_codeopt.c) and transforming
       it to a register without actually generating code is wrong
       as their value might still be used for real.  All values
       we push under nocode_wanted will eventually be popped
       again, so that the VT_CMP/VT_JMP value will be in vtop
       when code is unsuppressed again.

       Same logic below in vswap(); */
    if (vtop >= vstack && !nocode_wanted) {
        v = vtop->r & VT_VALMASK;
        if (v == VT_CMP || (v & ~1) == VT_JMP)
            gv(RC_INT);
    }

    vtop++;
    vtop->type = *type;
    vtop->r = r;
    vtop->r2 = VT_CONST;
    vtop->c = *vc;
    vtop->sym = NULL;
}

ST_FUNC void vswap(void)
{
    SValue tmp;
    /* cannot vswap cpu flags. See comment at vsetc() above */
    if (vtop >= vstack && !nocode_wanted) {
        int v = vtop->r & VT_VALMASK;
        if (v == VT_CMP || (v & ~1) == VT_JMP)
            gv(RC_INT);
    }
    tmp = vtop[0];
    vtop[0] = vtop[-1];
    vtop[-1] = tmp;
}

/* pop stack value */
ST_FUNC void vpop(void)
{
    int v;
    v = vtop->r & VT_VALMASK;
#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
    /* for x86, we need to pop the FP stack */
    if (v == TREG_ST0) {
        o(0xd8dd); /* fstp %st(0) */
    } else
#endif
    if (v == VT_JMP || v == VT_JMPI) {
        /* need to put correct jump if && or || without test */
        gsym(vtop->c.i);
    }
    vtop--;
}

/* push constant of type "type" with useless value */
ST_FUNC void vpush(CType *type)
{
    CValue cval;
    vsetc(type, VT_CONST, &cval);
}

/* push integer constant */
ST_FUNC void vpushi(int v)
{
    CValue cval;
    cval.i = v;
    vsetc(&int_type, VT_CONST, &cval);
}

/* push a pointer sized constant */
static void vpushs(addr_t v)
{
  CValue cval;
  cval.i = v;
  vsetc(&size_type, VT_CONST, &cval);
}

/* push arbitrary 64bit constant */
ST_FUNC void vpush64(int ty, unsigned long long v)
{
    CValue cval;
    CType ctype;
    ctype.t = ty;
    ctype.ref = NULL;
    cval.i = v;
    vsetc(&ctype, VT_CONST, &cval);
}

/* push long long constant */
static inline void vpushll(long long v)
{
    vpush64(VT_LLONG, v);
}

ST_FUNC void vset(CType *type, int r, long v)
{
    CValue cval;

    cval.i = v;
    vsetc(type, r, &cval);
}

static void vseti(int r, int v)
{
    CType type;
    type.t = VT_INT;
    type.ref = 0;
    vset(&type, r, v);
}

ST_FUNC void vpushv(SValue *v)
{
    if (vtop >= vstack + (VSTACK_SIZE - 1))
        tcc_error("memory full (vstack)");
    vtop++;
    *vtop = *v;
}

static void vdup(void)
{
    vpushv(vtop);
}

/* rotate n first stack elements to the bottom
   I1 ... In -> I2 ... In I1 [top is right]
*/
ST_FUNC void vrotb(int n)
{
    int i;
    SValue tmp;

    tmp = vtop[-n + 1];
    for(i=-n+1;i!=0;i++)
        vtop[i] = vtop[i+1];
    vtop[0] = tmp;
}

/* rotate the n elements before entry e towards the top
   I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
 */
ST_FUNC void vrote(SValue *e, int n)
{
    int i;
    SValue tmp;

    tmp = *e;
    for(i = 0;i < n - 1; i++)
        e[-i] = e[-i - 1];
    e[-n + 1] = tmp;
}

/* rotate n first stack elements to the top
   I1 ... In -> In I1 ... I(n-1)  [top is right]
 */
ST_FUNC void vrott(int n)
{
    vrote(vtop, n);
}

/* push a symbol value of TYPE */
static inline void vpushsym(CType *type, Sym *sym)
{
    CValue cval;
    cval.i = 0;
    vsetc(type, VT_CONST | VT_SYM, &cval);
    vtop->sym = sym;
}

/* Return a static symbol pointing to a section */
ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
{
    int v;
    Sym *sym;

    v = anon_sym++;
    sym = global_identifier_push(v, type->t | VT_STATIC, 0);
    sym->type.ref = type->ref;
    sym->r = VT_CONST | VT_SYM;
    put_extern_sym(sym, sec, offset, size);
    return sym;
}

/* push a reference to a section offset by adding a dummy symbol */
static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
{
    vpushsym(type, get_sym_ref(type, sec, offset, size));  
}

/* define a new external reference to a symbol 'v' of type 'u' */
ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
{
    Sym *s;

    s = sym_find(v);
    if (!s) {
        /* push forward reference */
        s = global_identifier_push(v, type->t | VT_EXTERN, 0);
        s->type.ref = type->ref;
        s->r = r | VT_CONST | VT_SYM;
    }
    return s;
}

/* Merge some storage attributes.  */
static void patch_storage(Sym *sym, CType *type)
{
    int t;
    if (!is_compatible_types(&sym->type, type))
        tcc_error("incompatible types for redefinition of '%s'",
              get_tok_str(sym->v, NULL));
    t = type->t;
#ifdef TCC_TARGET_PE
    if ((sym->type.t ^ t) & VT_IMPORT)
        tcc_error("incompatible dll linkage for redefinition of '%s'",
            get_tok_str(sym->v, NULL));
#endif
    sym->type.t |= t & (VT_EXPORT|VT_WEAK);
    if (t & VT_VIS_MASK) {
        int vis = sym->type.t & VT_VIS_MASK;
        int vis2 = t & VT_VIS_MASK;
        if (vis == (STV_DEFAULT << VT_VIS_SHIFT))
            vis = vis2;
        else if (vis2 != (STV_DEFAULT << VT_VIS_SHIFT))
            vis = (vis < vis2) ? vis : vis2;
        sym->type.t = (sym->type.t & ~VT_VIS_MASK) | vis;
    }
}

/* define a new external reference to a symbol 'v' */
static Sym *external_sym(int v, CType *type, int r)
{
    Sym *s;
    s = sym_find(v);
    if (!s) {
        /* push forward reference */
        s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
        s->type.t |= VT_EXTERN;
    } else {
        if (s->type.ref == func_old_type.ref) {
            s->type.ref = type->ref;
            s->r = r | VT_CONST | VT_SYM;
            s->type.t |= VT_EXTERN;
        }
        patch_storage(s, type);
        update_storage(s);
    }
    return s;
}

/* push a reference to global symbol v */
ST_FUNC void vpush_global_sym(CType *type, int v)
{
    vpushsym(type, external_global_sym(v, type, 0));
}

/* save registers up to (vtop - n) stack entry */
ST_FUNC void save_regs(int n)
{
    SValue *p, *p1;
    for(p = vstack, p1 = vtop - n; p <= p1; p++)
        save_reg(p->r);
}

/* save r to the memory stack, and mark it as being free */
ST_FUNC void save_reg(int r)
{
    save_reg_upstack(r, 0);
}

/* save r to the memory stack, and mark it as being free,
   if seen up to (vtop - n) stack entry */
ST_FUNC void save_reg_upstack(int r, int n)
{
    int l, saved, size, align;
    SValue *p, *p1, sv;
    CType *type;

    if ((r &= VT_VALMASK) >= VT_CONST)
        return;
    if (nocode_wanted)
        return;

    /* modify all stack values */
    saved = 0;
    l = 0;
    for(p = vstack, p1 = vtop - n; p <= p1; p++) {
        if ((p->r & VT_VALMASK) == r ||
            ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
            /* must save value on stack if not already done */
            if (!saved) {
                /* NOTE: must reload 'r' because r might be equal to r2 */
                r = p->r & VT_VALMASK;
                /* store register in the stack */
                type = &p->type;
                if ((p->r & VT_LVAL) ||
                    (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
#if PTR_SIZE == 8
                    type = &char_pointer_type;
#else
                    type = &int_type;
#endif
                size = type_size(type, &align);
                loc = (loc - size) & -align;
                sv.type.t = type->t;
                sv.r = VT_LOCAL | VT_LVAL;
                sv.c.i = loc;
                store(r, &sv);
#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
                /* x86 specific: need to pop fp register ST0 if saved */
                if (r == TREG_ST0) {
                    o(0xd8dd); /* fstp %st(0) */
                }
#endif
#if PTR_SIZE == 4
                /* special long long case */
                if ((type->t & VT_BTYPE) == VT_LLONG) {
                    sv.c.i += 4;
                    store(p->r2, &sv);
                }
#endif
                l = loc;
                saved = 1;
            }
            /* mark that stack entry as being saved on the stack */
            if (p->r & VT_LVAL) {
                /* also clear the bounded flag because the
                   relocation address of the function was stored in
                   p->c.i */
                p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
            } else {
                p->r = lvalue_type(p->type.t) | VT_LOCAL;
            }
            p->r2 = VT_CONST;
            p->c.i = l;
        }
    }
}

#ifdef TCC_TARGET_ARM
/* find a register of class 'rc2' with at most one reference on stack.
 * If none, call get_reg(rc) */
ST_FUNC int get_reg_ex(int rc, int rc2)
{
    int r;
    SValue *p;
    
    for(r=0;r<NB_REGS;r++) {
        if (reg_classes[r] & rc2) {
            int n;
            n=0;
            for(p = vstack; p <= vtop; p++) {
                if ((p->r & VT_VALMASK) == r ||
                    (p->r2 & VT_VALMASK) == r)
                    n++;
            }
            if (n <= 1)
                return r;
        }
    }
    return get_reg(rc);
}
#endif

/* find a free register of class 'rc'. If none, save one register */
ST_FUNC int get_reg(int rc)
{
    int r;
    SValue *p;

    /* find a free register */
    for(r=0;r<NB_REGS;r++) {
        if (reg_classes[r] & rc) {
            if (nocode_wanted)
                return r;
            for(p=vstack;p<=vtop;p++) {
                if ((p->r & VT_VALMASK) == r ||
                    (p->r2 & VT_VALMASK) == r)
                    goto notfound;
            }
            return r;
        }
    notfound: ;
    }
    
    /* no register left : free the first one on the stack (VERY
       IMPORTANT to start from the bottom to ensure that we don't
       spill registers used in gen_opi()) */
    for(p=vstack;p<=vtop;p++) {
        /* look at second register (if long long) */
        r = p->r2 & VT_VALMASK;
        if (r < VT_CONST && (reg_classes[r] & rc))
            goto save_found;
        r = p->r & VT_VALMASK;
        if (r < VT_CONST && (reg_classes[r] & rc)) {
        save_found:
            save_reg(r);
            return r;
        }
    }
    /* Should never comes here */
    return -1;
}

/* move register 's' (of type 't') to 'r', and flush previous value of r to memory
   if needed */
static void move_reg(int r, int s, int t)
{
    SValue sv;

    if (r != s) {
        save_reg(r);
        sv.type.t = t;
        sv.type.ref = NULL;
        sv.r = s;
        sv.c.i = 0;
        load(r, &sv);
    }
}

/* get address of vtop (vtop MUST BE an lvalue) */
ST_FUNC void gaddrof(void)
{
    vtop->r &= ~VT_LVAL;
    /* tricky: if saved lvalue, then we can go back to lvalue */
    if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
        vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;


}

#ifdef CONFIG_TCC_BCHECK
/* generate lvalue bound code */
static void gbound(void)
{
    int lval_type;
    CType type1;

    vtop->r &= ~VT_MUSTBOUND;
    /* if lvalue, then use checking code before dereferencing */
    if (vtop->r & VT_LVAL) {
        /* if not VT_BOUNDED value, then make one */
        if (!(vtop->r & VT_BOUNDED)) {
            lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
            /* must save type because we must set it to int to get pointer */
            type1 = vtop->type;
            vtop->type.t = VT_PTR;
            gaddrof();
            vpushi(0);
            gen_bounded_ptr_add();
            vtop->r |= lval_type;
            vtop->type = type1;
        }
        /* then check for dereferencing */
        gen_bounded_ptr_deref();
    }
}
#endif

/* store vtop a register belonging to class 'rc'. lvalues are
   converted to values. Cannot be used if cannot be converted to
   register value (such as structures). */
ST_FUNC int gv(int rc)
{
    int r, bit_pos, bit_size, size, align;
    int rc2;

    /* NOTE: get_reg can modify vstack[] */
    if (vtop->type.t & VT_BITFIELD) {
        CType type;
        int bits = 32;
        bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
        bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
        /* remove bit field info to avoid loops */
        vtop->type.t &= ~VT_BITFIELD & ((1 << VT_STRUCT_SHIFT) - 1);
        /* cast to int to propagate signedness in following ops */
        if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
            type.t = VT_LLONG;
            bits = 64;
        } else
            type.t = VT_INT;
        if((vtop->type.t & VT_UNSIGNED) ||
           (vtop->type.t & VT_BTYPE) == VT_BOOL ||
       (((vtop->type.t & VT_BTYPE) == VT_ENUM) &&
        vtop->type.ref->a.unsigned_enum))
            type.t |= VT_UNSIGNED;
        gen_cast(&type);
        /* generate shifts */
        vpushi(bits - (bit_pos + bit_size));
        gen_op(TOK_SHL);
        vpushi(bits - bit_size);
        /* NOTE: transformed to SHR if unsigned */
        gen_op(TOK_SAR);
        r = gv(rc);
    } else {
        if (is_float(vtop->type.t) && 
            (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
            unsigned long offset;
            /* CPUs usually cannot use float constants, so we store them
               generically in data segment */
            size = type_size(&vtop->type, &align);
        offset = section_add(data_section, size, align);
            vpush_ref(&vtop->type, data_section, offset, size);
        vswap();
        init_putv(&vtop->type, data_section, offset);
        vtop->r |= VT_LVAL;
        }
#ifdef CONFIG_TCC_BCHECK
        if (vtop->r & VT_MUSTBOUND) 
            gbound();
#endif

        r = vtop->r & VT_VALMASK;
        rc2 = (rc & RC_FLOAT) ? RC_FLOAT : RC_INT;
#ifndef TCC_TARGET_ARM64
        if (rc == RC_IRET)
            rc2 = RC_LRET;
#ifdef TCC_TARGET_X86_64
        else if (rc == RC_FRET)
            rc2 = RC_QRET;
#endif
#endif
        /* need to reload if:
           - constant
           - lvalue (need to dereference pointer)
           - already a register, but not in the right class */
        if (r >= VT_CONST
         || (vtop->r & VT_LVAL)
         || !(reg_classes[r] & rc)
#if PTR_SIZE == 8
         || ((vtop->type.t & VT_BTYPE) == VT_QLONG && !(reg_classes[vtop->r2] & rc2))
         || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT && !(reg_classes[vtop->r2] & rc2))
#else
         || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
#endif
            )
        {
            r = get_reg(rc);
#if PTR_SIZE == 8
            if (((vtop->type.t & VT_BTYPE) == VT_QLONG) || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT)) {
                int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
#else
            if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
                int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
                unsigned long long ll;
#endif
                int r2, original_type;
                original_type = vtop->type.t;
                /* two register type load : expand to two words
                   temporarily */
#if PTR_SIZE == 4
                if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
                    /* load constant */
                    ll = vtop->c.i;
                    vtop->c.i = ll; /* first word */
                    load(r, vtop);
                    vtop->r = r; /* save register value */
                    vpushi(ll >> 32); /* second word */
                } else
#endif
                if (vtop->r & VT_LVAL) {
                    /* We do not want to modifier the long long
                       pointer here, so the safest (and less
                       efficient) is to save all the other registers
                       in the stack. XXX: totally inefficient. */
               #if 0
                    save_regs(1);
               #else
                    /* lvalue_save: save only if used further down the stack */
                    save_reg_upstack(vtop->r, 1);
               #endif
                    /* load from memory */
                    vtop->type.t = load_type;
                    load(r, vtop);
                    vdup();
                    vtop[-1].r = r; /* save register value */
                    /* increment pointer to get second word */
                    vtop->type.t = addr_type;
                    gaddrof();
                    vpushi(load_size);
                    gen_op('+');
                    vtop->r |= VT_LVAL;
                    vtop->type.t = load_type;
                } else {
                    /* move registers */
                    load(r, vtop);
                    vdup();
                    vtop[-1].r = r; /* save register value */
                    vtop->r = vtop[-1].r2;
                }
                /* Allocate second register. Here we rely on the fact that
                   get_reg() tries first to free r2 of an SValue. */
                r2 = get_reg(rc2);
                load(r2, vtop);
                vpop();
                /* write second register */
                vtop->r2 = r2;
                vtop->type.t = original_type;
            } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
                int t1, t;
                /* lvalue of scalar type : need to use lvalue type
                   because of possible cast */
                t = vtop->type.t;
                t1 = t;
                /* compute memory access type */
                if (vtop->r & VT_LVAL_BYTE)
                    t = VT_BYTE;
                else if (vtop->r & VT_LVAL_SHORT)
                    t = VT_SHORT;
                if (vtop->r & VT_LVAL_UNSIGNED)
                    t |= VT_UNSIGNED;
                vtop->type.t = t;
                load(r, vtop);
                /* restore wanted type */
                vtop->type.t = t1;
            } else {
                /* one register type load */
                load(r, vtop);
            }
        }
        vtop->r = r;
#ifdef TCC_TARGET_C67
        /* uses register pairs for doubles */
        if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) 
            vtop->r2 = r+1;
#endif
    }
    return r;
}

/* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
ST_FUNC void gv2(int rc1, int rc2)
{
    int v;

    /* generate more generic register first. But VT_JMP or VT_CMP
       values must be generated first in all cases to avoid possible
       reload errors */
    v = vtop[0].r & VT_VALMASK;
    if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
        vswap();
        gv(rc1);
        vswap();
        gv(rc2);
        /* test if reload is needed for first register */
        if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
            vswap();
            gv(rc1);
            vswap();
        }
    } else {
        gv(rc2);
        vswap();
        gv(rc1);
        vswap();
        /* test if reload is needed for first register */
        if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
            gv(rc2);
        }
    }
}

#ifndef TCC_TARGET_ARM64
/* wrapper around RC_FRET to return a register by type */
static int rc_fret(int t)
{
#ifdef TCC_TARGET_X86_64
    if (t == VT_LDOUBLE) {
        return RC_ST0;
    }
#endif
    return RC_FRET;
}
#endif

/* wrapper around REG_FRET to return a register by type */
static int reg_fret(int t)
{
#ifdef TCC_TARGET_X86_64
    if (t == VT_LDOUBLE) {
        return TREG_ST0;
    }
#endif
    return REG_FRET;
}

#if PTR_SIZE == 4
/* expand 64bit on stack in two ints */
static void lexpand(void)
{
    int u, v;
    u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
    v = vtop->r & (VT_VALMASK | VT_LVAL);
    if (v == VT_CONST) {
        vdup();
#if HAVE_LONG_LONG_STUB || HAVE_LONG_LONG
        vtop[0].c.i >>= 32;
#endif
    } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
        vdup();
        vtop[0].c.i += 4;
    } else {
        gv(RC_INT);
        vdup();
        vtop[0].r = vtop[-1].r2;
        vtop[0].r2 = vtop[-1].r2 = VT_CONST;
    }
    vtop[0].type.t = vtop[-1].type.t = VT_INT | u;
}
#endif

#ifdef TCC_TARGET_ARM
/* expand long long on stack */
ST_FUNC void lexpand_nr(void)
{
    int u,v;

    u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
    vdup();
    vtop->r2 = VT_CONST;
    vtop->type.t = VT_INT | u;
    v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
    if (v == VT_CONST) {
      vtop[-1].c.i = vtop->c.i;
#if HAVE_LONG_LONG_STUB || HAVE_LONG_LONG
      vtop->c.i = vtop->c.i >> 32;
#endif
      vtop->r = VT_CONST;
    } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
      vtop->c.i += 4;
      vtop->r = vtop[-1].r;
    } else if (v > VT_CONST) {
      vtop--;
      lexpand();
    } else
      vtop->r = vtop[-1].r2;
    vtop[-1].r2 = VT_CONST;
    vtop[-1].type.t = VT_INT | u;
}
#endif

#if PTR_SIZE == 4
/* build a long long from two ints */
static void lbuild(int t)
{
    gv2(RC_INT, RC_INT);
    vtop[-1].r2 = vtop[0].r;
    vtop[-1].type.t = t;
    vpop();
}
#endif

/* convert stack entry to register and duplicate its value in another
   register */
static void gv_dup(void)
{
    int rc, t, r, r1;
    SValue sv;

    t = vtop->type.t;
#if PTR_SIZE == 4
    if ((t & VT_BTYPE) == VT_LLONG) {
        lexpand();
        gv_dup();
        vswap();
        vrotb(3);
        gv_dup();
        vrotb(4);
        /* stack: H L L1 H1 */
        lbuild(t);
        vrotb(3);
        vrotb(3);
        vswap();
        lbuild(t);
        vswap();
    } else
#endif
    {
        /* duplicate value */
        rc = RC_INT;
        sv.type.t = VT_INT;
        if (is_float(t)) {
            rc = RC_FLOAT;
#ifdef TCC_TARGET_X86_64
            if ((t & VT_BTYPE) == VT_LDOUBLE) {
                rc = RC_ST0;
            }
#endif
            sv.type.t = t;
        }
        r = gv(rc);
        r1 = get_reg(rc);
        sv.r = r;
        sv.c.i = 0;
        load(r1, &sv); /* move r to r1 */
        vdup();
        /* duplicates value */
        if (r != r1)
            vtop->r = r1;
    }
}

/* Generate value test
 *
 * Generate a test for any value (jump, comparison and integers) */
ST_FUNC int gvtst(int inv, int t)
{
    int v = vtop->r & VT_VALMASK;
    if (v != VT_CMP && v != VT_JMP && v != VT_JMPI) {
        vpushi(0);
        gen_op(TOK_NE);
    }
    if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
        /* constant jmp optimization */
        if ((vtop->c.i != 0) != inv)
            t = gjmp(t);
        vtop--;
        return t;
    }
    return gtst(inv, t);
}

#if PTR_SIZE == 4
/* generate CPU independent (unsigned) long long operations */
static void gen_opl(int op)
{
    int t, a, b, op1, c, i;
    int func;
    unsigned short reg_iret = REG_IRET;
    unsigned short reg_lret = REG_LRET;
    SValue tmp;

    switch(op) {
    case '/':
    case TOK_PDIV:
        func = TOK___divdi3;
        goto gen_func;
    case TOK_UDIV:
        func = TOK___udivdi3;
        goto gen_func;
    case '%':
        func = TOK___moddi3;
        goto gen_mod_func;
    case TOK_UMOD:
        func = TOK___umoddi3;
    gen_mod_func:
#ifdef TCC_ARM_EABI
        reg_iret = TREG_R2;
        reg_lret = TREG_R3;
#endif
    gen_func:
        /* call generic long long function */
        vpush_global_sym(&func_old_type, func);
        vrott(3);
        gfunc_call(2);
        vpushi(0);
        vtop->r = reg_iret;
        vtop->r2 = reg_lret;
        break;
    case '^':
    case '&':
    case '|':
    case '*':
    case '+':
    case '-':
        //pv("gen_opl A",0,2);
        t = vtop->type.t;
        vswap();
        lexpand();
        vrotb(3);
        lexpand();
        /* stack: L1 H1 L2 H2 */
        tmp = vtop[0];
        vtop[0] = vtop[-3];
        vtop[-3] = tmp;
        tmp = vtop[-2];
        vtop[-2] = vtop[-3];
        vtop[-3] = tmp;
        vswap();
        /* stack: H1 H2 L1 L2 */
        //pv("gen_opl B",0,4);
        if (op == '*') {
            vpushv(vtop - 1);
            vpushv(vtop - 1);
            gen_op(TOK_UMULL);
            lexpand();
            /* stack: H1 H2 L1 L2 ML MH */
            for(i=0;i<4;i++)
                vrotb(6);
            /* stack: ML MH H1 H2 L1 L2 */
            tmp = vtop[0];
            vtop[0] = vtop[-2];
            vtop[-2] = tmp;
            /* stack: ML MH H1 L2 H2 L1 */
            gen_op('*');
            vrotb(3);
            vrotb(3);
            gen_op('*');
            /* stack: ML MH M1 M2 */
            gen_op('+');
            gen_op('+');
        } else if (op == '+' || op == '-') {
            /* XXX: add non carry method too (for MIPS or alpha) */
            if (op == '+')
                op1 = TOK_ADDC1;
            else
                op1 = TOK_SUBC1;
            gen_op(op1);
            /* stack: H1 H2 (L1 op L2) */
            vrotb(3);
            vrotb(3);
            gen_op(op1 + 1); /* TOK_xxxC2 */
        } else {
            gen_op(op);
            /* stack: H1 H2 (L1 op L2) */
            vrotb(3);
            vrotb(3);
            /* stack: (L1 op L2) H1 H2 */
            gen_op(op);
            /* stack: (L1 op L2) (H1 op H2) */
        }
        /* stack: L H */
        lbuild(t);
        break;
    case TOK_SAR:
    case TOK_SHR:
    case TOK_SHL:
        if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
            t = vtop[-1].type.t;
            vswap();
            lexpand();
            vrotb(3);
            /* stack: L H shift */
            c = (int)vtop->c.i;
            /* constant: simpler */
            /* NOTE: all comments are for SHL. the other cases are
               done by swapping words */
            vpop();
            if (op != TOK_SHL)
                vswap();
            if (c >= 32) {
                /* stack: L H */
                vpop();
                if (c > 32) {
                    vpushi(c - 32);
                    gen_op(op);
                }
                if (op != TOK_SAR) {
                    vpushi(0);
                } else {
                    gv_dup();
                    vpushi(31);
                    gen_op(TOK_SAR);
                }
                vswap();
            } else {
                vswap();
                gv_dup();
                /* stack: H L L */
                vpushi(c);
                gen_op(op);
                vswap();
                vpushi(32 - c);
                if (op == TOK_SHL)
                    gen_op(TOK_SHR);
                else
                    gen_op(TOK_SHL);
                vrotb(3);
                /* stack: L L H */
                vpushi(c);
                if (op == TOK_SHL)
                    gen_op(TOK_SHL);
                else
                    gen_op(TOK_SHR);
                gen_op('|');
            }
            if (op != TOK_SHL)
                vswap();
            lbuild(t);
        } else {
            /* XXX: should provide a faster fallback on x86 ? */
            switch(op) {
            case TOK_SAR:
                func = TOK___ashrdi3;
                goto gen_func;
            case TOK_SHR:
                func = TOK___lshrdi3;
                goto gen_func;
            case TOK_SHL:
                func = TOK___ashldi3;
                goto gen_func;
            }
        }
        break;
    default:
        /* compare operations */
        t = vtop->type.t;
        vswap();
        lexpand();
        vrotb(3);
        lexpand();
        /* stack: L1 H1 L2 H2 */
        tmp = vtop[-1];
        vtop[-1] = vtop[-2];
        vtop[-2] = tmp;
        /* stack: L1 L2 H1 H2 */
        /* compare high */
        op1 = op;
        /* when values are equal, we need to compare low words. since
           the jump is inverted, we invert the test too. */
        if (op1 == TOK_LT)
            op1 = TOK_LE;
        else if (op1 == TOK_GT)
            op1 = TOK_GE;
        else if (op1 == TOK_ULT)
            op1 = TOK_ULE;
        else if (op1 == TOK_UGT)
            op1 = TOK_UGE;
        a = 0;
        b = 0;
        gen_op(op1);
        if (op == TOK_NE) {
            b = gvtst(0, 0);
        } else {
            a = gvtst(1, 0);
            if (op != TOK_EQ) {
                /* generate non equal test */
                vpushi(TOK_NE);
                vtop->r = VT_CMP;
                b = gvtst(0, 0);
            }
        }
        /* compare low. Always unsigned */
        op1 = op;
        if (op1 == TOK_LT)
            op1 = TOK_ULT;
        else if (op1 == TOK_LE)
            op1 = TOK_ULE;
        else if (op1 == TOK_GT)
            op1 = TOK_UGT;
        else if (op1 == TOK_GE)
            op1 = TOK_UGE;
        gen_op(op1);
        a = gvtst(1, a);
        gsym(b);
        vseti(VT_JMPI, a);
        break;
    }
}
#endif

#if HAVE_LONG_LONG_STUB || HAVE_LONG_LONG
static uint64_t gen_opic_sdiv(uint64_t a, uint64_t b)
{
#if HAVE_LONG_LONG
    uint64_t x = (a >> 63 ? -a : a) / (b >> 63 ? -b : b);
    return (a ^ b) >> 63 ? -x : x;
#else
    uint32_t x = (a >> 31 ? -a : a) / (b >> 31 ? -b : b);
    return (a ^ b) >> 31 ? -x : x;
#endif
}

static int gen_opic_lt(uint64_t a, uint64_t b)
{
#if HAVE_LONG_LONG
    return (a ^ (uint64_t)1 << 63) < (b ^ (uint64_t)1 << 63);
#else
    return (a ^ (uint32_t)1 << 31) < (b ^ (uint32_t)1 << 31);
#endif
}
#else
static uint32_t gen_opic_sdiv(uint32_t a, uint32_t b)
{
    uint32_t x = (a >> 31 ? -a : a) / (b >> 31 ? -b : b);
    return (a ^ b) >> 31 ? -x : x;
}

static int gen_opic_lt(uint32_t a, uint32_t b)
{
    return (a ^ (uint32_t)1 << 31) < (b ^ (uint32_t)1 << 31);
}
#endif

/* handle integer constant optimizations and various machine
   independent opt */
static void gen_opic(int op)
{
    SValue *v1 = vtop - 1;
    SValue *v2 = vtop;
    int t1 = v1->type.t & VT_BTYPE;
    int t2 = v2->type.t & VT_BTYPE;
    int c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
    int c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
#if HAVE_LONG_LONG
    uint64_t l1 = c1 ? v1->c.i : 0;
    uint64_t l2 = c2 ? v2->c.i : 0;
    int shm = (t1 == VT_LLONG) ? 63 : 31;
#else
    uint32_t l1 = c1 ? v1->c.i : 0;
    uint32_t l2 = c2 ? v2->c.i : 0;
    int shm = 31;
#endif
    if (t1 != VT_LLONG && (PTR_SIZE != 8 || t1 != VT_PTR))
        l1 = ((uint32_t)l1 |
              (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000)));
    if (t2 != VT_LLONG && (PTR_SIZE != 8 || t2 != VT_PTR))
        l2 = ((uint32_t)l2 |
              (v2->type.t & VT_UNSIGNED ? 0 : -(l2 & 0x80000000)));

    if (c1 && c2) {
        switch(op) {
        case '+': l1 += l2; break;
        case '-': l1 -= l2; break;
        case '&': l1 &= l2; break;
        case '^': l1 ^= l2; break;
        case '|': l1 |= l2; break;
        case '*': l1 *= l2; break;

        case TOK_PDIV:
        case '/':
        case '%':
        case TOK_UDIV:
        case TOK_UMOD:
            /* if division by zero, generate explicit division */
            if (l2 == 0) {
                if (const_wanted)
                    tcc_error("division by zero in constant");
                goto general_case;
            }
            switch(op) {
            default: l1 = gen_opic_sdiv(l1, l2); break;
            case '%': l1 = l1 - l2 * gen_opic_sdiv(l1, l2); break;
            case TOK_UDIV: l1 = l1 / l2; break;
            case TOK_UMOD: l1 = l1 % l2; break;
            }
            break;
        case TOK_SHL: l1 <<= (l2 & shm); break;
        case TOK_SHR: l1 >>= (l2 & shm); break;
        case TOK_SAR:
#if HAVE_LONG_LONG
            l1 = (l1 >> 63) ? ~(~l1 >> (l2 & shm)) : l1 >> (l2 & shm);
#else
            l1 = (l1 >> 31) ? ~(~l1 >> (l2 & shm)) : l1 >> (l2 & shm);
#endif
            break;
            /* tests */
        case TOK_ULT: l1 = l1 < l2; break;
        case TOK_UGE: l1 = l1 >= l2; break;
        case TOK_EQ: l1 = l1 == l2; break;
        case TOK_NE: l1 = l1 != l2; break;
        case TOK_ULE: l1 = l1 <= l2; break;
        case TOK_UGT: l1 = l1 > l2; break;
        case TOK_LT: l1 = gen_opic_lt(l1, l2); break;
        case TOK_GE: l1 = !gen_opic_lt(l1, l2); break;
        case TOK_LE: l1 = !gen_opic_lt(l2, l1); break;
        case TOK_GT: l1 = gen_opic_lt(l2, l1); break;
            /* logical */
        case TOK_LAND: l1 = l1 && l2; break;
        case TOK_LOR: l1 = l1 || l2; break;
        default:
            goto general_case;
        }
    if (t1 != VT_LLONG && (PTR_SIZE != 8 || t1 != VT_PTR))
        l1 = ((uint32_t)l1 |
        (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000)));
        v1->c.i = l1;
        vtop--;
    } else {
        /* if commutative ops, put c2 as constant */
        if (c1 && (op == '+' || op == '&' || op == '^' || 
                   op == '|' || op == '*')) {
            vswap();
            c2 = c1; //c = c1, c1 = c2, c2 = c;
            l2 = l1; //l = l1, l1 = l2, l2 = l;
        }
        if (!const_wanted &&
            c1 && ((l1 == 0 &&
                    (op == TOK_SHL || op == TOK_SHR || op == TOK_SAR)) ||
                   (l1 == -1 && op == TOK_SAR))) {
            /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */
            vtop--;
        } else if (!const_wanted &&
                   c2 && ((l2 == 0 && (op == '&' || op == '*')) ||
                          (l2 == -1 && op == '|') ||
                          (l2 == 0xffffffff && t2 != VT_LLONG && op == '|') ||
                          (l2 == 1 && (op == '%' || op == TOK_UMOD)))) {
            /* treat (x & 0), (x * 0), (x | -1) and (x % 1) as constant */
            if (l2 == 1)
                vtop->c.i = 0;
            vswap();
            vtop--;
        } else if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
                          op == TOK_PDIV) &&
                           l2 == 1) ||
                          ((op == '+' || op == '-' || op == '|' || op == '^' ||
                            op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
                           l2 == 0) ||
                          (op == '&' &&
                           l2 == -1))) {
            /* filter out NOP operations like x*1, x-0, x&-1... */
            vtop--;
        } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
            /* try to use shifts instead of muls or divs */
            if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
                int n = -1;
                while (l2) {
                    l2 >>= 1;
                    n++;
                }
                vtop->c.i = n;
                if (op == '*')
                    op = TOK_SHL;
                else if (op == TOK_PDIV)
                    op = TOK_SAR;
                else
                    op = TOK_SHR;
            }
            goto general_case;
        } else if (c2 && (op == '+' || op == '-') &&
                   (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))
                    || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
            /* symbol + constant case */
            if (op == '-')
                l2 = -l2;
        l2 += vtop[-1].c.i;
        /* The backends can't always deal with addends to symbols
           larger than +-1<<31.  Don't construct such.  */
        if ((int)l2 != l2)
            goto general_case;
            vtop--;
            vtop->c.i = l2;
        } else {
        general_case:
                /* call low level op generator */
                if (t1 == VT_LLONG || t2 == VT_LLONG ||
                    (PTR_SIZE == 8 && (t1 == VT_PTR || t2 == VT_PTR)))
                    gen_opl(op);
                else
                    gen_opi(op);
        }
    }
}

/* generate a floating point operation with constant propagation */
static void gen_opif(int op)
{
    int c1, c2;
    SValue *v1, *v2;
    long double f1, f2;

    v1 = vtop - 1;
    v2 = vtop;
    /* currently, we cannot do computations with forward symbols */
    c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
    c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
    if (c1 && c2) {
        if (v1->type.t == VT_FLOAT) {
            f1 = v1->c.f;
            f2 = v2->c.f;
        } else if (v1->type.t == VT_DOUBLE) {
            f1 = v1->c.d;
            f2 = v2->c.d;
        } else {
            f1 = v1->c.ld;
            f2 = v2->c.ld;
        }

        /* NOTE: we only do constant propagation if finite number (not
           NaN or infinity) (ANSI spec) */
        if (!ieee_finite(f1) || !ieee_finite(f2))
            goto general_case;

        switch(op) {
        case '+': f1 += f2; break;
        case '-': f1 -= f2; break;
        case '*': f1 *= f2; break;
        case '/': 
#if HAVE_FLOAT
            if (f2 == 0.0) {
                if (const_wanted)
                    tcc_error("division by zero in constant");
                goto general_case;
            }
#endif
            f1 /= f2; 
            break;
            /* XXX: also handles tests ? */
        default:
            goto general_case;
        }
        /* XXX: overflow test ? */
        if (v1->type.t == VT_FLOAT) {
            v1->c.f = f1;
        } else if (v1->type.t == VT_DOUBLE) {
            v1->c.d = f1;
        } else {
            v1->c.ld = f1;
        }
        vtop--;
    } else {
    general_case:
        gen_opf(op);
    }
}

static int pointed_size(CType *type)
{
    int align;
    return type_size(pointed_type(type), &align);
}

static void vla_runtime_pointed_size(CType *type)
{
    int align;
    vla_runtime_type_size(pointed_type(type), &align);
}

static inline int is_null_pointer(SValue *p)
{
    if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
        return 0;
    return ((p->type.t & VT_BTYPE) == VT_INT && (uint32_t)p->c.i == 0) ||
        ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.i == 0) ||
        ((p->type.t & VT_BTYPE) == VT_PTR &&
         (PTR_SIZE == 4 ? (uint32_t)p->c.i == 0 : p->c.i == 0));
}

static inline int is_integer_btype(int bt)
{
    return (bt == VT_BYTE || bt == VT_SHORT || 
            bt == VT_INT || bt == VT_LLONG);
}

/* check types for comparison or subtraction of pointers */
static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
{
    CType *type1, *type2, tmp_type1, tmp_type2;
    int bt1, bt2;
    
    /* null pointers are accepted for all comparisons as gcc */
    if (is_null_pointer(p1) || is_null_pointer(p2))
        return;
    type1 = &p1->type;
    type2 = &p2->type;
    bt1 = type1->t & VT_BTYPE;
    bt2 = type2->t & VT_BTYPE;
    /* accept comparison between pointer and integer with a warning */
    if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
        if (op != TOK_LOR && op != TOK_LAND )
            tcc_warning("comparison between pointer and integer");
        return;
    }

    /* both must be pointers or implicit function pointers */
    if (bt1 == VT_PTR) {
        type1 = pointed_type(type1);
    } else if (bt1 != VT_FUNC) 
        goto invalid_operands;

    if (bt2 == VT_PTR) {
        type2 = pointed_type(type2);
    } else if (bt2 != VT_FUNC) { 
    invalid_operands:
        tcc_error("invalid operands to binary %s", get_tok_str(op, NULL));
    }
    if ((type1->t & VT_BTYPE) == VT_VOID || 
        (type2->t & VT_BTYPE) == VT_VOID)
        return;
    tmp_type1 = *type1;
    tmp_type2 = *type2;
    tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
    tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
    if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
        /* gcc-like error if '-' is used */
        if (op == '-')
            goto invalid_operands;
        else
            tcc_warning("comparison of distinct pointer types lacks a cast");
    }
}

/* generic gen_op: handles types problems */
ST_FUNC void gen_op(int op)
{
    int u, t1, t2, bt1, bt2, t;
    CType type1;

redo:
    t1 = vtop[-1].type.t;
    t2 = vtop[0].type.t;
    bt1 = t1 & VT_BTYPE;
    bt2 = t2 & VT_BTYPE;
        
    if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
        tcc_error("operation on a struct");
    } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
    if (bt2 == VT_FUNC) {
        mk_pointer(&vtop->type);
        gaddrof();
    }
    if (bt1 == VT_FUNC) {
        vswap();
        mk_pointer(&vtop->type);
        gaddrof();
        vswap();
    }
    goto redo;
    } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
        /* at least one operand is a pointer */
        /* relational op: must be both pointers */
        if (op >= TOK_ULT && op <= TOK_LOR) {
            check_comparison_pointer_types(vtop - 1, vtop, op);
            /* pointers are handled are unsigned */
#if PTR_SIZE == 8
            t = VT_LLONG | VT_UNSIGNED;
#else
            t = VT_INT | VT_UNSIGNED;
#endif
            goto std_op;
        }
        /* if both pointers, then it must be the '-' op */
        if (bt1 == VT_PTR && bt2 == VT_PTR) {
            if (op != '-')
                tcc_error("cannot use pointers here");
            check_comparison_pointer_types(vtop - 1, vtop, op);
            /* XXX: check that types are compatible */
            if (vtop[-1].type.t & VT_VLA) {
                vla_runtime_pointed_size(&vtop[-1].type);
            } else {
                vpushi(pointed_size(&vtop[-1].type));
            }
            vrott(3);
            gen_opic(op);
            /* set to integer type */
#if PTR_SIZE == 8
            vtop->type.t = VT_LLONG;
#else
            vtop->type.t = VT_INT; 
#endif
            vswap();
            gen_op(TOK_PDIV);
        } else {
            /* exactly one pointer : must be '+' or '-'. */
            if (op != '-' && op != '+')
                tcc_error("cannot use pointers here");
            /* Put pointer as first operand */
            if (bt2 == VT_PTR) {
                vswap();
                t = t1, t1 = t2, t2 = t;
            }
#if PTR_SIZE == 4
            if ((vtop[0].type.t & VT_BTYPE) == VT_LLONG)
                /* XXX: truncate here because gen_opl can't handle ptr + long long */
                gen_cast(&int_type);
#endif
            type1 = vtop[-1].type;
            type1.t &= ~VT_ARRAY;
            if (vtop[-1].type.t & VT_VLA)
                vla_runtime_pointed_size(&vtop[-1].type);
            else {
                u = pointed_size(&vtop[-1].type);
                if (u < 0)
                    tcc_error("unknown array element size");
#if PTR_SIZE == 8
                vpushll(u);
#else
                /* XXX: cast to int ? (long long case) */
                vpushi(u);
#endif
            }
            gen_op('*');
#if 0
/* #ifdef CONFIG_TCC_BCHECK
    The main reason to removing this code:
    #include <stdio.h>
    int main ()
    {
        int v[10];
        int i = 10;
        int j = 9;
        fprintf(stderr, "v+i-j  = %p\n", v+i-j);
        fprintf(stderr, "v+(i-j)  = %p\n", v+(i-j));
    }
    When this code is on. then the output looks like 
    v+i-j = 0xfffffffe
    v+(i-j) = 0xbff84000
    */
            /* if evaluating constant expression, no code should be
               generated, so no bound check */
            if (tcc_state->do_bounds_check && !const_wanted) {
                /* if bounded pointers, we generate a special code to
                   test bounds */
                if (op == '-') {
                    vpushi(0);
                    vswap();
                    gen_op('-');
                }
                gen_bounded_ptr_add();
            } else
#endif
            {
                gen_opic(op);
            }
            /* put again type if gen_opic() swaped operands */
            vtop->type = type1;
        }
    } else if (is_float(bt1) || is_float(bt2)) {
        /* compute bigger type and do implicit casts */
        if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
            t = VT_LDOUBLE;
        } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
            t = VT_DOUBLE;
        } else {
            t = VT_FLOAT;
        }
        /* floats can only be used for a few operations */
        if (op != '+' && op != '-' && op != '*' && op != '/' &&
            (op < TOK_ULT || op > TOK_GT))
            tcc_error("invalid operands for binary operation");
        goto std_op;
    } else if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) {
        t = bt1 == VT_LLONG ? VT_LLONG : VT_INT;
        if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (t | VT_UNSIGNED))
          t |= VT_UNSIGNED;
        goto std_op;
    } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
        /* cast to biggest op */
        t = VT_LLONG;
        /* convert to unsigned if it does not fit in a long long */
        if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED) ||
            (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED))
            t |= VT_UNSIGNED;
        goto std_op;
    } else {
        /* integer operations */
        t = VT_INT;
        /* convert to unsigned if it does not fit in an integer */
        if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED) ||
            (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED))
            t |= VT_UNSIGNED;
    std_op:
        /* XXX: currently, some unsigned operations are explicit, so
           we modify them here */
        if (t & VT_UNSIGNED) {
            if (op == TOK_SAR)
                op = TOK_SHR;
            else if (op == '/')
                op = TOK_UDIV;
            else if (op == '%')
                op = TOK_UMOD;
            else if (op == TOK_LT)
                op = TOK_ULT;
            else if (op == TOK_GT)
                op = TOK_UGT;
            else if (op == TOK_LE)
                op = TOK_ULE;
            else if (op == TOK_GE)
                op = TOK_UGE;
        }
        vswap();
        type1.t = t;
        gen_cast(&type1);
        vswap();
        /* special case for shifts and long long: we keep the shift as
           an integer */
        if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
            type1.t = VT_INT;
        gen_cast(&type1);
        if (is_float(t))
            gen_opif(op);
        else
            gen_opic(op);
        if (op >= TOK_ULT && op <= TOK_GT) {
            /* relational op: the result is an int */
            vtop->type.t = VT_INT;
        } else {
            vtop->type.t = t;
        }
    }
    // Make sure that we have converted to an rvalue:
    if (vtop->r & VT_LVAL)
        gv(is_float(vtop->type.t & VT_BTYPE) ? RC_FLOAT : RC_INT);
}

#ifndef TCC_TARGET_ARM
/* generic itof for unsigned long long case */
static void gen_cvt_itof1(int t)
{
#ifdef TCC_TARGET_ARM64
    gen_cvt_itof(t);
#else
    if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == 
        (VT_LLONG | VT_UNSIGNED)) {

        if (t == VT_FLOAT)
            vpush_global_sym(&func_old_type, TOK___floatundisf);
#if LDOUBLE_SIZE != 8
        else if (t == VT_LDOUBLE)
            vpush_global_sym(&func_old_type, TOK___floatundixf);
#endif
        else
            vpush_global_sym(&func_old_type, TOK___floatundidf);
        vrott(2);
        gfunc_call(1);
        vpushi(0);
        vtop->r = reg_fret(t);
    } else {
        gen_cvt_itof(t);
    }
#endif
}
#endif

/* generic ftoi for unsigned long long case */
static void gen_cvt_ftoi1(int t)
{
#ifdef TCC_TARGET_ARM64
    gen_cvt_ftoi(t);
#else
    int st;

    if (t == (VT_LLONG | VT_UNSIGNED)) {
        /* not handled natively */
        st = vtop->type.t & VT_BTYPE;
        if (st == VT_FLOAT)
            vpush_global_sym(&func_old_type, TOK___fixunssfdi);
#if LDOUBLE_SIZE != 8
        else if (st == VT_LDOUBLE)
            vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
#endif
        else
            vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
        vrott(2);
        gfunc_call(1);
        vpushi(0);
        vtop->r = REG_IRET;
        vtop->r2 = REG_LRET;
    } else {
        gen_cvt_ftoi(t);
    }
#endif
}

/* force char or short cast */
static void force_charshort_cast(int t)
{
    int bits, dbt;
    dbt = t & VT_BTYPE;
    /* XXX: add optimization if lvalue : just change type and offset */
    if (dbt == VT_BYTE)
        bits = 8;
    else
        bits = 16;
    if (t & VT_UNSIGNED) {
        vpushi((1 << bits) - 1);
        gen_op('&');
    } else {
        if ((vtop->type.t & VT_BTYPE) == VT_LLONG)
            bits = 64 - bits;
        else
            bits = 32 - bits;
        vpushi(bits);
        gen_op(TOK_SHL);
        /* result must be signed or the SAR is converted to an SHL
           This was not the case when "t" was a signed short
           and the last value on the stack was an unsigned int */
        vtop->type.t &= ~VT_UNSIGNED;
        vpushi(bits);
        gen_op(TOK_SAR);
    }
}

/* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
static void gen_cast(CType *type)
{
    int sbt, dbt, sf, df, c, p;

    /* special delayed cast for char/short */
    /* XXX: in some cases (multiple cascaded casts), it may still
       be incorrect */
    if (vtop->r & VT_MUSTCAST) {
        vtop->r &= ~VT_MUSTCAST;
        force_charshort_cast(vtop->type.t);
    }

    /* bitfields first get cast to ints */
    if (vtop->type.t & VT_BITFIELD) {
        gv(RC_INT);
    }

    dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
    sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);

    if (sbt != dbt) {
        sf = is_float(sbt);
        df = is_float(dbt);
        c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
        p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
        if (c) {
            /* constant case: we can do it now */
            /* XXX: in ISOC, cannot do it if error in convert */
#if HAVE_FLOAT
            if (sbt == VT_FLOAT)
                vtop->c.ld = vtop->c.f;
            else if (sbt == VT_DOUBLE)
                vtop->c.ld = vtop->c.d;

            if (df) {
                if ((sbt & VT_BTYPE) == VT_LLONG) {
                    if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 63))
                        vtop->c.ld = vtop->c.i;
                    else
                        vtop->c.ld = -(long double)-vtop->c.i;
                } else if(!sf) {
                    if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 31))
                        vtop->c.ld = (uint32_t)vtop->c.i;
                    else
                        vtop->c.ld = -(long double)-(uint32_t)vtop->c.i;
                }

                if (dbt == VT_FLOAT)
                    vtop->c.f = (float)vtop->c.ld;
                else if (dbt == VT_DOUBLE)
                    vtop->c.d = (double)vtop->c.ld;
            }
              else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
                vtop->c.i = vtop->c.ld;
            } else if (sf && dbt == VT_BOOL) {
                vtop->c.i = (vtop->c.ld != 0);
            } else
#endif
                   {
#if HAVE_FLOAT
                if(sf)
                    vtop->c.i = vtop->c.ld;
                else
#endif
                  if (sbt == (VT_LLONG|VT_UNSIGNED))
                    ;
                else if (sbt & VT_UNSIGNED)
                    vtop->c.i = (uint32_t)vtop->c.i;
#if PTR_SIZE == 8
                else if (sbt == VT_PTR)
                    ;
#endif
                else if (sbt != VT_LLONG)
                    vtop->c.i = ((uint32_t)vtop->c.i |
                                  -(vtop->c.i & 0x80000000));

                if (dbt == (VT_LLONG|VT_UNSIGNED))
                    ;
                else if (dbt == VT_BOOL)
                    vtop->c.i = (vtop->c.i != 0);
#if PTR_SIZE == 8
                else if (dbt == VT_PTR)
                    ;
#endif
                else if (dbt != VT_LLONG) {
                    uint32_t m = ((dbt & VT_BTYPE) == VT_BYTE ? 0xff :
                                  (dbt & VT_BTYPE) == VT_SHORT ? 0xffff :
                                  0xffffffff);
                    vtop->c.i &= m;
                    if (!(dbt & VT_UNSIGNED))
                        vtop->c.i |= -(vtop->c.i & ((m >> 1) + 1));
                }
            }
        } else if (p && dbt == VT_BOOL) {
            vtop->r = VT_CONST;
            vtop->c.i = 1;
        } else {
            /* non constant case: generate code */
            if (sf && df) {
                /* convert from fp to fp */
                gen_cvt_ftof(dbt);
            } else if (df) {
                /* convert int to fp */
                gen_cvt_itof1(dbt);
            } else if (sf) {
                /* convert fp to int */
                if (dbt == VT_BOOL) {
                     vpushi(0);
                     gen_op(TOK_NE);
                } else {
                    /* we handle char/short/etc... with generic code */
                    if (dbt != (VT_INT | VT_UNSIGNED) &&
                        dbt != (VT_LLONG | VT_UNSIGNED) &&
                        dbt != VT_LLONG)
                        dbt = VT_INT;
                    gen_cvt_ftoi1(dbt);
                    if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
                        /* additional cast for char/short... */
                        vtop->type.t = dbt;
                        gen_cast(type);
                    }
                }
#if PTR_SIZE == 4
            } else if ((dbt & VT_BTYPE) == VT_LLONG) {
                if ((sbt & VT_BTYPE) != VT_LLONG) {
                    /* scalar to long long */
                    /* machine independent conversion */
                    gv(RC_INT);
                    /* generate high word */
                    if (sbt == (VT_INT | VT_UNSIGNED)) {
                        vpushi(0);
                        gv(RC_INT);
                    } else {
                        if (sbt == VT_PTR) {
                            /* cast from pointer to int before we apply
                               shift operation, which pointers don't support*/
                            gen_cast(&int_type);
                        }
                        gv_dup();
                        vpushi(31);
                        gen_op(TOK_SAR);
                    }
                    /* patch second register */
                    vtop[-1].r2 = vtop->r;
                    vpop();
                }
#else
            } else if ((dbt & VT_BTYPE) == VT_LLONG ||
                       (dbt & VT_BTYPE) == VT_PTR ||
                       (dbt & VT_BTYPE) == VT_FUNC) {
                if ((sbt & VT_BTYPE) != VT_LLONG &&
                    (sbt & VT_BTYPE) != VT_PTR &&
                    (sbt & VT_BTYPE) != VT_FUNC) {
                    /* need to convert from 32bit to 64bit */
                    gv(RC_INT);
                    if (sbt != (VT_INT | VT_UNSIGNED)) {
#if defined(TCC_TARGET_ARM64)
                        gen_cvt_sxtw();
#elif defined(TCC_TARGET_X86_64)
                        int r = gv(RC_INT);
                        /* x86_64 specific: movslq */
                        o(0x6348);
                        o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
#else
#error
#endif
                    }
                }
#endif
            } else if (dbt == VT_BOOL) {
                /* scalar to bool */
                vpushi(0);
                gen_op(TOK_NE);
            } else if ((dbt & VT_BTYPE) == VT_BYTE || 
                       (dbt & VT_BTYPE) == VT_SHORT) {
                if (sbt == VT_PTR) {
                    vtop->type.t = VT_INT;
                    tcc_warning("nonportable conversion from pointer to char/short");
                }
                force_charshort_cast(dbt);
#if PTR_SIZE == 4
            } else if ((dbt & VT_BTYPE) == VT_INT) {
                /* scalar to int */
                if ((sbt & VT_BTYPE) == VT_LLONG) {
                    /* from long long: just take low order word */
                    lexpand();
                    vpop();
                } 
                /* if lvalue and single word type, nothing to do because
                   the lvalue already contains the real type size (see
                   VT_LVAL_xxx constants) */
#endif
            }
        }
    } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
        /* if we are casting between pointer types,
           we must update the VT_LVAL_xxx size */
        vtop->r = (vtop->r & ~VT_LVAL_TYPE)
                  | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
    }
    vtop->type = *type;
}

/* return type size as known at compile time. Put alignment at 'a' */
ST_FUNC int type_size(CType *type, int *a)
{
    Sym *s;
    int bt;

    bt = type->t & VT_BTYPE;
    if (bt == VT_STRUCT) {
        /* struct/union */
        s = type->ref;
        *a = s->r;
        return s->c;
    } else if (bt == VT_PTR) {
        if (type->t & VT_ARRAY) {
            int ts;

            s = type->ref;
            ts = type_size(&s->type, a);

            if (ts < 0 && s->c < 0)
                ts = -ts;

            return ts * s->c;
        } else {
            *a = PTR_SIZE;
            return PTR_SIZE;
        }
    } else if (bt == VT_LDOUBLE) {
        *a = LDOUBLE_ALIGN;
        return LDOUBLE_SIZE;
    } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
#ifdef TCC_TARGET_I386
#ifdef TCC_TARGET_PE
        *a = 8;
#else
        *a = 4;
#endif
#elif defined(TCC_TARGET_ARM)
#ifdef TCC_ARM_EABI
        *a = 8; 
#else
        *a = 4;
#endif
#else
        *a = 8;
#endif
        return 8;
    } else if (bt == VT_INT || bt == VT_FLOAT) {
        *a = 4;
        return 4;
    } else if (bt == VT_SHORT) {
        *a = 2;
        return 2;
    } else if (bt == VT_QLONG || bt == VT_QFLOAT) {
        *a = 8;
        return 16;
    } else if (bt == VT_ENUM) {
    *a = 4;
    /* Enums might be incomplete, so don't just return '4' here.  */
    return type->ref->c;
    } else {
        /* char, void, function, _Bool */
        *a = 1;
        return 1;
    }
}

/* push type size as known at runtime time on top of value stack. Put
   alignment at 'a' */
ST_FUNC void vla_runtime_type_size(CType *type, int *a)
{
    if (type->t & VT_VLA) {
        type_size(&type->ref->type, a);
        vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
    } else {
        vpushi(type_size(type, a));
    }
}

static void vla_sp_restore(void) {
    if (vlas_in_scope) {
        gen_vla_sp_restore(vla_sp_loc);
    }
}

static void vla_sp_restore_root(void) {
    if (vlas_in_scope) {
        gen_vla_sp_restore(vla_sp_root_loc);
    }
}

/* return the pointed type of t */
static inline CType *pointed_type(CType *type)
{
    return &type->ref->type;
}

/* modify type so that its it is a pointer to type. */
ST_FUNC void mk_pointer(CType *type)
{
    Sym *s;
    s = sym_push(SYM_FIELD, type, 0, -1);
    type->t = VT_PTR | (type->t & ~VT_TYPE);
    type->ref = s;
}

/* compare function types. OLD functions match any new functions */
static int is_compatible_func(CType *type1, CType *type2)
{
    Sym *s1, *s2;

    s1 = type1->ref;
    s2 = type2->ref;
    if (!is_compatible_types(&s1->type, &s2->type))
        return 0;
    /* check func_call */
    if (s1->a.func_call != s2->a.func_call)
        return 0;
    /* XXX: not complete */
    if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
        return 1;
    if (s1->c != s2->c)
        return 0;
    while (s1 != NULL) {
        if (s2 == NULL)
            return 0;
        if (!is_compatible_parameter_types(&s1->type, &s2->type))
            return 0;
        s1 = s1->next;
        s2 = s2->next;
    }
    if (s2)
        return 0;
    return 1;
}

/* return true if type1 and type2 are the same.  If unqualified is
   true, qualifiers on the types are ignored.

   - enums are not checked as gcc __builtin_types_compatible_p () 
 */
static int compare_types(CType *type1, CType *type2, int unqualified)
{
    int bt1, t1, t2;

    t1 = type1->t & VT_TYPE;
    t2 = type2->t & VT_TYPE;
    if (unqualified) {
        /* strip qualifiers before comparing */
        t1 &= ~(VT_CONSTANT | VT_VOLATILE);
        t2 &= ~(VT_CONSTANT | VT_VOLATILE);
    }
    /* Default Vs explicit signedness only matters for char */
    if ((t1 & VT_BTYPE) != VT_BYTE) {
        t1 &= ~VT_DEFSIGN;
        t2 &= ~VT_DEFSIGN;
    }
    /* An enum is compatible with (unsigned) int.  Ideally we would
       store the enums signedness in type->ref.a.<some_bit> and
       only accept unsigned enums with unsigned int and vice versa.
       But one of our callers (gen_assign_cast) always strips VT_UNSIGNED
       from pointer target types, so we can't add it here either.  */
    if ((t1 & VT_BTYPE) == VT_ENUM) {
    t1 = VT_INT;
    if (type1->ref->a.unsigned_enum)
        t1 |= VT_UNSIGNED;
    }
    if ((t2 & VT_BTYPE) == VT_ENUM) {
    t2 = VT_INT;
    if (type2->ref->a.unsigned_enum)
        t2 |= VT_UNSIGNED;
    }
    /* XXX: bitfields ? */
    if (t1 != t2)
        return 0;
    /* test more complicated cases */
    bt1 = t1 & VT_BTYPE;
    if (bt1 == VT_PTR) {
        type1 = pointed_type(type1);
        type2 = pointed_type(type2);
        return is_compatible_types(type1, type2);
    } else if (bt1 == VT_STRUCT) {
        return (type1->ref == type2->ref);
    } else if (bt1 == VT_FUNC) {
        return is_compatible_func(type1, type2);
    } else {
        return 1;
    }
}

/* return true if type1 and type2 are exactly the same (including
   qualifiers). 
*/
static int is_compatible_types(CType *type1, CType *type2)
{
    return compare_types(type1,type2,0);
}

/* return true if type1 and type2 are the same (ignoring qualifiers).
*/
static int is_compatible_parameter_types(CType *type1, CType *type2)
{
    return compare_types(type1,type2,1);
}

/* print a type. If 'varstr' is not NULL, then the variable is also
   printed in the type */
/* XXX: union */
/* XXX: add array and function pointers */
static void type_to_str(char *buf, int buf_size, 
                 CType *type, const char *varstr)
{
    int bt, v, t;
    Sym *s, *sa;
    char buf1[256];
    const char *tstr;

    t = type->t;
    bt = t & VT_BTYPE;
    buf[0] = '\0';
    if (t & VT_CONSTANT)
        pstrcat(buf, buf_size, "const ");
    if (t & VT_VOLATILE)
        pstrcat(buf, buf_size, "volatile ");
    if ((t & (VT_DEFSIGN | VT_UNSIGNED)) == (VT_DEFSIGN | VT_UNSIGNED))
        pstrcat(buf, buf_size, "unsigned ");
    else if (t & VT_DEFSIGN)
        pstrcat(buf, buf_size, "signed ");
    if (t & VT_EXTERN)
        pstrcat(buf, buf_size, "extern ");
    if (t & VT_STATIC)
        pstrcat(buf, buf_size, "static ");
    if (t & VT_TYPEDEF)
        pstrcat(buf, buf_size, "typedef ");
    if (t & VT_INLINE)
        pstrcat(buf, buf_size, "inline ");
    buf_size -= strlen(buf);
    buf += strlen(buf);
    switch(bt) {
    case VT_VOID:
        tstr = "void";
        goto add_tstr;
    case VT_BOOL:
        tstr = "_Bool";
        goto add_tstr;
    case VT_BYTE:
        tstr = "char";
        goto add_tstr;
    case VT_SHORT:
        tstr = "short";
        goto add_tstr;
    case VT_INT:
        tstr = "int";
        goto add_tstr;
    case VT_LONG:
        tstr = "long";
        goto add_tstr;
    case VT_LLONG:
        tstr = "long long";
        goto add_tstr;
    case VT_FLOAT:
        tstr = "float";
        goto add_tstr;
    case VT_DOUBLE:
        tstr = "double";
        goto add_tstr;
    case VT_LDOUBLE:
        tstr = "long double";
    add_tstr:
        pstrcat(buf, buf_size, tstr);
        break;
    case VT_ENUM:
    case VT_STRUCT:
        if (bt == VT_STRUCT)
            tstr = "struct ";
        else
            tstr = "enum ";
        pstrcat(buf, buf_size, tstr);
        v = type->ref->v & ~SYM_STRUCT;
        if (v >= SYM_FIRST_ANOM)
            pstrcat(buf, buf_size, "<anonymous>");
        else
            pstrcat(buf, buf_size, get_tok_str(v, NULL));
        break;
    case VT_FUNC:
        s = type->ref;
        type_to_str(buf, buf_size, &s->type, varstr);
        pstrcat(buf, buf_size, "(");
        sa = s->next;
        while (sa != NULL) {
            type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
            pstrcat(buf, buf_size, buf1);
            sa = sa->next;
            if (sa)
                pstrcat(buf, buf_size, ", ");
        }
        pstrcat(buf, buf_size, ")");
        goto no_var;
    case VT_PTR:
        s = type->ref;
        if (t & VT_ARRAY) {
            snprintf(buf1, sizeof(buf1), "%s[%ld]", varstr ? varstr : "", s->c);
            type_to_str(buf, buf_size, &s->type, buf1);
            goto no_var;
        }
        pstrcpy(buf1, sizeof(buf1), "*");
        if (t & VT_CONSTANT)
            pstrcat(buf1, buf_size, "const ");
        if (t & VT_VOLATILE)
            pstrcat(buf1, buf_size, "volatile ");
        if (varstr)
            pstrcat(buf1, sizeof(buf1), varstr);
        type_to_str(buf, buf_size, &s->type, buf1);
        goto no_var;
    }
    if (varstr) {
        pstrcat(buf, buf_size, " ");
        pstrcat(buf, buf_size, varstr);
    }
 no_var: ;
}

/* verify type compatibility to store vtop in 'dt' type, and generate
   casts if needed. */
static void gen_assign_cast(CType *dt)
{
    CType *st, *type1, *type2, tmp_type1, tmp_type2;
    char buf1[256], buf2[256];
    int dbt, sbt;

    st = &vtop->type; /* source type */
    dbt = dt->t & VT_BTYPE;
    sbt = st->t & VT_BTYPE;
    if (sbt == VT_VOID || dbt == VT_VOID) {
    if (sbt == VT_VOID && dbt == VT_VOID)
        ; /*
          It is Ok if both are void
          A test program:
            void func1() {}
        void func2() {
          return func1();
        }
          gcc accepts this program
          */
    else
            tcc_error("cannot cast from/to void");
    }
    if (dt->t & VT_CONSTANT)
        tcc_warning("assignment of read-only location");
    switch(dbt) {
    case VT_PTR:
        /* special cases for pointers */
        /* '0' can also be a pointer */
        if (is_null_pointer(vtop))
            goto type_ok;
        /* accept implicit pointer to integer cast with warning */
        if (is_integer_btype(sbt)) {
            tcc_warning("assignment makes pointer from integer without a cast");
            goto type_ok;
        }
        type1 = pointed_type(dt);
        /* a function is implicitly a function pointer */
        if (sbt == VT_FUNC) {
            if ((type1->t & VT_BTYPE) != VT_VOID &&
                !is_compatible_types(pointed_type(dt), st))
                tcc_warning("assignment from incompatible pointer type");
            goto type_ok;
        }
        if (sbt != VT_PTR)
            goto error;
        type2 = pointed_type(st);
        if ((type1->t & VT_BTYPE) == VT_VOID || 
            (type2->t & VT_BTYPE) == VT_VOID) {
            /* void * can match anything */
        } else {
            /* exact type match, except for qualifiers */
            tmp_type1 = *type1;
            tmp_type2 = *type2;
            tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
            tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
            if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
        /* Like GCC don't warn by default for merely changes
           in pointer target signedness.  Do warn for different
           base types, though, in particular for unsigned enums
           and signed int targets.  */
        if ((tmp_type1.t & (VT_DEFSIGN | VT_UNSIGNED)) !=
            (tmp_type2.t & (VT_DEFSIGN | VT_UNSIGNED)) &&
            (tmp_type1.t & VT_BTYPE) == (tmp_type2.t & VT_BTYPE))
            ;
        else
            tcc_warning("assignment from incompatible pointer type");
        }
        }
        /* check const and volatile */
        if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
            (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
            tcc_warning("assignment discards qualifiers from pointer target type");
        break;
    case VT_BYTE:
    case VT_SHORT:
    case VT_INT:
    case VT_LLONG:
        if (sbt == VT_PTR || sbt == VT_FUNC) {
            tcc_warning("assignment makes integer from pointer without a cast");
        } else if (sbt == VT_STRUCT) {
            goto case_VT_STRUCT;
        }
        /* XXX: more tests */
        break;
    case VT_STRUCT:
    case_VT_STRUCT:
        tmp_type1 = *dt;
        tmp_type2 = *st;
        tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
        tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
        if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
        error:
            type_to_str(buf1, sizeof(buf1), st, NULL);
            type_to_str(buf2, sizeof(buf2), dt, NULL);
            tcc_error("cannot cast '%s' to '%s'", buf1, buf2);
        }
        break;
    }
 type_ok:
    gen_cast(dt);
}

/* store vtop in lvalue pushed on stack */
ST_FUNC void vstore(void)
{
    int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;

    ft = vtop[-1].type.t;
    sbt = vtop->type.t & VT_BTYPE;
    dbt = ft & VT_BTYPE;
    if ((((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
         (sbt == VT_INT && dbt == VT_SHORT))
    && !(vtop->type.t & VT_BITFIELD)) {
        /* optimize char/short casts */
        delayed_cast = VT_MUSTCAST;
        vtop->type.t = (ft & VT_TYPE & ~VT_BITFIELD &
                        ((1 << VT_STRUCT_SHIFT) - 1));
        /* XXX: factorize */
        if (ft & VT_CONSTANT)
            tcc_warning("assignment of read-only location");
    } else {
        delayed_cast = 0;
        if (!(ft & VT_BITFIELD))
            gen_assign_cast(&vtop[-1].type);
    }

    if (sbt == VT_STRUCT) {
        /* if structure, only generate pointer */
        /* structure assignment : generate memcpy */
        /* XXX: optimize if small size */
            size = type_size(&vtop->type, &align);

            /* destination */
            vswap();
            vtop->type.t = VT_PTR;
            gaddrof();

            /* address of memcpy() */
#ifdef TCC_ARM_EABI
            if(!(align & 7))
                vpush_global_sym(&func_old_type, TOK_memcpy8);
            else if(!(align & 3))
                vpush_global_sym(&func_old_type, TOK_memcpy4);
            else
#endif
            /* Use memmove, rather than memcpy, as dest and src may be same: */
#if BOOTSTRAP && __arm__
            vpush_global_sym(&func_old_type, TOK___memmove);
#else
            vpush_global_sym(&func_old_type, TOK_memmove);
#endif

            vswap();
            /* source */
            vpushv(vtop - 2);
            vtop->type.t = VT_PTR;
            gaddrof();
            /* type size */
            vpushi(size);
            gfunc_call(3);

        /* leave source on stack */
    } else if (ft & VT_BITFIELD) {
        /* bitfield store handling */

        /* save lvalue as expression result (example: s.b = s.a = n;) */
        vdup(), vtop[-1] = vtop[-2];

        bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
        bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
        /* remove bit field info to avoid loops */
        vtop[-1].type.t = ft & ~VT_BITFIELD & ((1 << VT_STRUCT_SHIFT) - 1);

        if((ft & VT_BTYPE) == VT_BOOL) {
            gen_cast(&vtop[-1].type);
            vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
        }

        /* duplicate destination */
        vdup();
        vtop[-1] = vtop[-2];

        /* mask and shift source */
        if((ft & VT_BTYPE) != VT_BOOL) {
            if((ft & VT_BTYPE) == VT_LLONG) {
                vpushll((1ULL << bit_size) - 1ULL);
            } else {
                vpushi((1 << bit_size) - 1);
            }
            gen_op('&');
        }
        vpushi(bit_pos);
        gen_op(TOK_SHL);
        /* load destination, mask and or with source */
        vswap();
        if((ft & VT_BTYPE) == VT_LLONG) {
            vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos));
        } else {
            vpushi(~(((1 << bit_size) - 1) << bit_pos));
        }
        gen_op('&');
        gen_op('|');
        /* store result */
        vstore();
        /* ... and discard */
        vpop();

    } else {
#ifdef CONFIG_TCC_BCHECK
            /* bound check case */
            if (vtop[-1].r & VT_MUSTBOUND) {
                vswap();
                gbound();
                vswap();
            }
#endif
            rc = RC_INT;
            if (is_float(ft)) {
                rc = RC_FLOAT;
#ifdef TCC_TARGET_X86_64
                if ((ft & VT_BTYPE) == VT_LDOUBLE) {
                    rc = RC_ST0;
                } else if ((ft & VT_BTYPE) == VT_QFLOAT) {
                    rc = RC_FRET;
                }
#endif
            }
            r = gv(rc);  /* generate value */
            /* if lvalue was saved on stack, must read it */
            if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
                SValue sv;
                t = get_reg(RC_INT);
#if PTR_SIZE == 8
                sv.type.t = VT_PTR;
#else
                sv.type.t = VT_INT;
#endif
                sv.r = VT_LOCAL | VT_LVAL;
                sv.c.i = vtop[-1].c.i;
                load(t, &sv);
                vtop[-1].r = t | VT_LVAL;
            }
            /* two word case handling : store second register at word + 4 (or +8 for x86-64)  */
#if PTR_SIZE == 8
            if (((ft & VT_BTYPE) == VT_QLONG) || ((ft & VT_BTYPE) == VT_QFLOAT)) {
                int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
#else
            if ((ft & VT_BTYPE) == VT_LLONG) {
                int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
#endif
                vtop[-1].type.t = load_type;
                store(r, vtop - 1);
                vswap();
                /* convert to int to increment easily */
                vtop->type.t = addr_type;
                gaddrof();
                vpushi(load_size);
                gen_op('+');
                vtop->r |= VT_LVAL;
                vswap();
                vtop[-1].type.t = load_type;
                /* XXX: it works because r2 is spilled last ! */
                store(vtop->r2, vtop - 1);
            } else {
                store(r, vtop - 1);
            }

        vswap();
        vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
        vtop->r |= delayed_cast;
    }
}

/* post defines POST/PRE add. c is the token ++ or -- */
ST_FUNC void inc(int post, int c)
{
    test_lvalue();
    vdup(); /* save lvalue */
    if (post) {
        gv_dup(); /* duplicate value */
        vrotb(3);
        vrotb(3);
    }
    /* add constant */
    vpushi(c - TOK_MID); 
    gen_op('+');
    vstore(); /* store value */
    if (post)
        vpop(); /* if post op, return saved value */
}

ST_FUNC void parse_mult_str (CString *astr, const char *msg)
{
    /* read the string */
    if (tok != TOK_STR)
        expect(msg);
    cstr_new(astr);
    while (tok == TOK_STR) {
        /* XXX: add \0 handling too ? */
        cstr_cat(astr, tokc.str.data, -1);
        next();
    }
    cstr_ccat(astr, '\0');
}

/* If I is >= 1 and a power of two, returns log2(i)+1.
   If I is 0 returns 0.  */
static int exact_log2p1(int i)
{
  int ret;
  if (!i)
    return 0;
  for (ret = 1; i >= 1 << 8; ret += 8)
    i >>= 8;
  if (i >= 1 << 4)
    ret += 4, i >>= 4;
  if (i >= 1 << 2)
    ret += 2, i >>= 2;
  if (i >= 1 << 1)
    ret++;
  return ret;
}

/* Parse GNUC __attribute__ extension. Currently, the following
   extensions are recognized:
   - aligned(n) : set data/function alignment.
   - packed : force data alignment to 1
   - section(x) : generate data/code in this section.
   - unused : currently ignored, but may be used someday.
   - regparm(n) : pass function parameters in registers (i386 only)
 */
static void parse_attribute(AttributeDef *ad)
{
    int t, n;
    CString astr;
    
    while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
    next();
    skip('(');
    skip('(');
    while (tok != ')') {
        if (tok < TOK_IDENT)
            expect("attribute name");
        t = tok;
        next();
        switch(t) {
        case TOK_SECTION1:
        case TOK_SECTION2:
            skip('(');
        parse_mult_str(&astr, "section name");
            ad->section = find_section(tcc_state, (char *)astr.data);
            skip(')');
        cstr_free(&astr);
            break;
        case TOK_ALIAS1:
        case TOK_ALIAS2:
            skip('(');
        parse_mult_str(&astr, "alias(\"target\")");
            ad->alias_target = /* save string as token, for later */
              tok_alloc((char*)astr.data, astr.size-1)->tok;
            skip(')');
        cstr_free(&astr);
            break;
    case TOK_VISIBILITY1:
    case TOK_VISIBILITY2:
            skip('(');
        parse_mult_str(&astr,
               "visibility(\"default|hidden|internal|protected\")");
        if (!strcmp (astr.data, "default"))
            ad->a.visibility = STV_DEFAULT;
        else if (!strcmp (astr.data, "hidden"))
            ad->a.visibility = STV_HIDDEN;
        else if (!strcmp (astr.data, "internal"))
            ad->a.visibility = STV_INTERNAL;
        else if (!strcmp (astr.data, "protected"))
            ad->a.visibility = STV_PROTECTED;
        else
                expect("visibility(\"default|hidden|internal|protected\")");
            skip(')');
        cstr_free(&astr);
            break;
        case TOK_ALIGNED1:
        case TOK_ALIGNED2:
            if (tok == '(') {
                next();
                n = expr_const();
                if (n <= 0 || (n & (n - 1)) != 0) 
                    tcc_error("alignment must be a positive power of two");
                skip(')');
            } else {
                n = MAX_ALIGN;
            }
            ad->a.aligned = exact_log2p1(n);
        if (n != 1 << (ad->a.aligned - 1))
          tcc_error("alignment of %d is larger than implemented", n);
            break;
        case TOK_PACKED1:
        case TOK_PACKED2:
            ad->a.packed = 1;
            break;
        case TOK_WEAK1:
        case TOK_WEAK2:
            ad->a.weak = 1;
            break;
        case TOK_UNUSED1:
        case TOK_UNUSED2:
            /* currently, no need to handle it because tcc does not
               track unused objects */
            break;
        case TOK_NORETURN1:
        case TOK_NORETURN2:
            /* currently, no need to handle it because tcc does not
               track unused objects */
            break;
        case TOK_CDECL1:
        case TOK_CDECL2:
        case TOK_CDECL3:
            ad->a.func_call = FUNC_CDECL;
            break;
        case TOK_STDCALL1:
        case TOK_STDCALL2:
        case TOK_STDCALL3:
            ad->a.func_call = FUNC_STDCALL;
            break;
#ifdef TCC_TARGET_I386
        case TOK_REGPARM1:
        case TOK_REGPARM2:
            skip('(');
            n = expr_const();
            if (n > 3) 
                n = 3;
            else if (n < 0)
                n = 0;
            if (n > 0)
                ad->a.func_call = FUNC_FASTCALL1 + n - 1;
            skip(')');
            break;
        case TOK_FASTCALL1:
        case TOK_FASTCALL2:
        case TOK_FASTCALL3:
            ad->a.func_call = FUNC_FASTCALLW;
            break;            
#endif
        case TOK_MODE:
            skip('(');
            switch(tok) {
                case TOK_MODE_DI:
                    ad->a.mode = VT_LLONG + 1;
                    break;
                case TOK_MODE_QI:
                    ad->a.mode = VT_BYTE + 1;
                    break;
                case TOK_MODE_HI:
                    ad->a.mode = VT_SHORT + 1;
                    break;
                case TOK_MODE_SI:
                case TOK_MODE_word:
                    ad->a.mode = VT_INT + 1;
                    break;
                default:
                    tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
                    break;
            }
            next();
            skip(')');
            break;
        case TOK_DLLEXPORT:
            ad->a.func_export = 1;
            break;
        case TOK_DLLIMPORT:
            ad->a.func_import = 1;
            break;
        default:
            if (tcc_state->warn_unsupported)
                tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL));
            /* skip parameters */
            if (tok == '(') {
                int parenthesis = 0;
                do {
                    if (tok == '(') 
                        parenthesis++;
                    else if (tok == ')') 
                        parenthesis--;
                    next();
                } while (parenthesis && tok != -1);
            }
            break;
        }
        if (tok != ',')
            break;
        next();
    }
    skip(')');
    skip(')');
    }
}

static Sym * find_field (CType *type, int v)
{
    Sym *s = type->ref;
    v |= SYM_FIELD;
    while ((s = s->next) != NULL) {
    if ((s->v & SYM_FIELD) &&
        (s->type.t & VT_BTYPE) == VT_STRUCT &&
        (s->v & ~SYM_FIELD) >= SYM_FIRST_ANOM) {
        Sym *ret = find_field (&s->type, v);
        if (ret)
            return ret;
    }
    if (s->v == v)
      break;
    }
    return s;
}

static void struct_add_offset (Sym *s, int offset)
{
    while ((s = s->next) != NULL) {
    if ((s->v & SYM_FIELD) &&
        (s->type.t & VT_BTYPE) == VT_STRUCT &&
        (s->v & ~SYM_FIELD) >= SYM_FIRST_ANOM) {
        struct_add_offset(s->type.ref, offset);
    } else
      s->c += offset;
    }
}

static void struct_layout(CType *type, AttributeDef *ad)
{
    int align, maxalign, offset, c, bit_pos, bt, prevbt, prev_bit_size;
    int pcc = !tcc_state->ms_bitfields;
    int packwarn = tcc_state->warn_gcc_compat;
    int typealign, bit_size, size;

    Sym *f;
    if (ad->a.aligned)
      maxalign = 1 << (ad->a.aligned - 1);
    else
      maxalign = 1;
    offset = 0;
    c = 0;
    bit_pos = 0;
    prevbt = VT_STRUCT; /* make it never match */
    prev_bit_size = 0;
    size = 0;

    for (f = type->ref->next; f; f = f->next) {
    size = type_size(&f->type, &typealign);
    if (f->type.t & VT_BITFIELD)
      bit_size = (f->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
    else
      bit_size = -1;
    if (bit_size == 0 && pcc) {
        /* Zero-width bit-fields in PCC mode aren't affected
           by any packing (attribute or pragma).  */
        align = typealign;
    } else if (f->r > 1) {
        align = f->r;
    } else if (ad->a.packed || f->r == 1) {
        align = 1;
        /* Packed fields or packed records don't let the base type
           influence the records type alignment.  */
        typealign = 1;
    } else {
        align = typealign;
    }
    if (type->ref->type.t != TOK_STRUCT) {
        if (pcc && bit_size >= 0)
          size = (bit_size + 7) >> 3;
        /* Bit position is already zero from our caller.  */
        offset = 0;
        if (size > c)
          c = size;
    } else if (bit_size < 0) {
        int addbytes = pcc ? (bit_pos + 7) >> 3 : 0;
        prevbt = VT_STRUCT;
        prev_bit_size = 0;
        c = (c + addbytes + align - 1) & -align;
        offset = c;
        if (size > 0)
          c += size;
        bit_pos = 0;
    } else {
        /* A bit-field.  Layout is more complicated.  There are two
           options TCC implements: PCC compatible and MS compatible
           (PCC compatible is what GCC uses for almost all targets).
           In PCC layout the overall size of the struct (in c) is
           _excluding_ the current run of bit-fields (that is,
           there's at least additional bit_pos bits after c).  In
           MS layout c does include the current run of bit-fields.
           
           This matters for calculating the natural alignment buckets
           in PCC mode.  */

        /* 'align' will be used to influence records alignment,
           so it's the max of specified and type alignment, except
           in certain cases that depend on the mode.  */
        if (align < typealign)
          align = typealign;
        if (pcc) {
        /* In PCC layout a non-packed bit-field is placed adjacent
           to the preceding bit-fields, except if it would overflow
           its container (depending on base type) or it's a zero-width
           bit-field.  Packed non-zero-width bit-fields always are
           placed adjacent.  */
        int ofs = (c * 8 + bit_pos) % (typealign * 8);
        int ofs2 = ofs + bit_size + (typealign * 8) - 1;
        if (bit_size == 0 ||
            (typealign != 1 &&
             (ofs2 / (typealign * 8)) > (size/typealign))) {
            c = (c + ((bit_pos + 7) >> 3) + typealign - 1) & -typealign;
            bit_pos = 0;
        } else if (bit_pos + bit_size > size * 8) {
            c += bit_pos >> 3;
            bit_pos &= 7;
                    if (bit_pos + bit_size > size * 8) {
                        c += 1, bit_pos = 0;
                        if ((ad->a.packed || f->r) && packwarn) {
                            tcc_warning("struct layout not compatible with GCC (internal limitation)");
                            packwarn = 0;
                        }
                    }
        }
        offset = c;
        /* In PCC layout named bit-fields influence the alignment
           of the containing struct using the base types alignment,
           except for packed fields (which here have correct
           align/typealign).  */
        if ((f->v & SYM_FIRST_ANOM))
          align = 1;
        } else {
        bt = f->type.t & VT_BTYPE;
        if ((bit_pos + bit_size > size * 8) ||
            (bit_size > 0) == (bt != prevbt)) {
            c = (c + typealign - 1) & -typealign;
            offset = c;
            bit_pos = 0;
            /* In MS bitfield mode a bit-field run always uses
               at least as many bits as the underlying type.
               To start a new run it's also required that this
               or the last bit-field had non-zero width.  */
            if (bit_size || prev_bit_size)
              c += size;
        }
        /* In MS layout the records alignment is normally
           influenced by the field, except for a zero-width
           field at the start of a run (but by further zero-width
           fields it is again).  */
        if (bit_size == 0 && prevbt != bt)
          align = 1;
        prevbt = bt;
        prev_bit_size = bit_size;
        }
        f->type.t = (f->type.t & ~(0x3f << VT_STRUCT_SHIFT))
                | (bit_pos << VT_STRUCT_SHIFT);
        bit_pos += bit_size;
        if (pcc && bit_pos >= size * 8) {
        c += size;
        bit_pos -= size * 8;
        }
    }
    if (align > maxalign)
      maxalign = align;
#if 0
    printf("set field %s offset=%d",
           get_tok_str(f->v & ~SYM_FIELD, NULL), offset);
    if (f->type.t & VT_BITFIELD) {
        printf(" pos=%d size=%d",
           (f->type.t >> VT_STRUCT_SHIFT) & 0x3f,
           (f->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
    }
    printf("\n");
#endif

    if (f->v & SYM_FIRST_ANOM && (f->type.t & VT_BTYPE) == VT_STRUCT) {
        Sym *ass;
        /* An anonymous struct/union.  Adjust member offsets
           to reflect the real offset of our containing struct.
           Also set the offset of this anon member inside
           the outer struct to be zero.  Via this it
           works when accessing the field offset directly
           (from base object), as well as when recursing
           members in initializer handling.  */
        int v2 = f->type.ref->v;
        if (!(v2 & SYM_FIELD) &&
        (v2 & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
        Sym **pps;
        /* This happens only with MS extensions.  The
           anon member has a named struct type, so it
           potentially is shared with other references.
           We need to unshare members so we can modify
           them.  */
        ass = f->type.ref;
        f->type.ref = sym_push(anon_sym++ | SYM_FIELD,
                       &f->type.ref->type, 0,
                       f->type.ref->c);
        pps = &f->type.ref->next;
        while ((ass = ass->next) != NULL) {
            *pps = sym_push(ass->v, &ass->type, 0, ass->c);
            pps = &((*pps)->next);
        }
        *pps = NULL;
        }
        struct_add_offset(f->type.ref, offset);
        f->c = 0;
    } else {
        f->c = offset;
    }

    f->r = 0;
    }
    /* store size and alignment */
    type->ref->c = (c + (pcc ? (bit_pos + 7) >> 3 : 0)
            + maxalign - 1) & -maxalign;
    type->ref->r = maxalign;
    if (offset + size > type->ref->c)
        tcc_warning("will touch memory past end of the struct (internal limitation)");
}

/* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
static void struct_decl(CType *type, AttributeDef *ad, int u)
{
    int a, v, size, align, flexible, alignoverride;
    long c;
    int bit_size, bsize, bt;
    Sym *s, *ss, **ps;
    AttributeDef ad1;
    CType type1, btype;

    a = tok; /* save decl type */
    next();
    if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
        parse_attribute(ad);
    if (tok != '{') {
        v = tok;
        next();
        /* struct already defined ? return it */
        if (v < TOK_IDENT)
            expect("struct/union/enum name");
        s = struct_find(v);
        if (s && (s->scope == local_scope || (tok != '{' && tok != ';'))) {
            if (s->type.t != a)
                tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
            goto do_decl;
        }
    } else {
        v = anon_sym++;
    }
    /* Record the original enum/struct/union token.  */
    type1.t = a;
    type1.ref = NULL;
    /* we put an undefined size for struct/union */
    s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
    s->r = 0; /* default alignment is zero as gcc */
    /* put struct/union/enum name in type */
 do_decl:
    type->t = u;
    type->ref = s;
    
    if (tok == '{') {
        next();
        if (s->c != -1)
            tcc_error("struct/union/enum already defined");
        /* cannot be empty */
        c = 0;
        /* non empty enums are not allowed */
        if (a == TOK_ENUM) {
        int seen_neg = 0;
        int seen_wide = 0;
            for(;;) {
        CType *t = &int_type;
                v = tok;
                if (v < TOK_UIDENT)
                    expect("identifier");
                ss = sym_find(v);
                if (ss && !local_stack)
                    tcc_error("redefinition of enumerator '%s'",
                              get_tok_str(v, NULL));
                next();
                if (tok == '=') {
                    next();
#if PTR_SIZE == 8
            c = expr_const64();
#else
            /* We really want to support long long enums
               on i386 as well, but the Sym structure only
               holds a 'long' for associated constants,
               and enlarging it would bump its size (no
               available padding).  So punt for now.  */
                    c = expr_const();
#endif
                }
        if (c < 0)
            seen_neg = 1;
        if (c != (int)c && (unsigned long)c != (unsigned int)c)
            seen_wide = 1, t = &size_type;
                /* enum symbols have static storage */
                ss = sym_push(v, t, VT_CONST, c);
                ss->type.t |= VT_STATIC;
                if (tok != ',')
                    break;
                next();
                c++;
                /* NOTE: we accept a trailing comma */
                if (tok == '}')
                    break;
            }
        if (!seen_neg)
            s->a.unsigned_enum = 1;
            s->c = type_size(seen_wide ? &size_type : &int_type, &align);
            skip('}');
        } else {
            ps = &s->next;
            flexible = 0;
            while (tok != '}') {
                if (!parse_btype(&btype, &ad1)) {
            skip(';');
            continue;
        }
                while (1) {
            if (flexible)
                tcc_error("flexible array member '%s' not at the end of struct",
                              get_tok_str(v, NULL));
                    bit_size = -1;
                    v = 0;
                    type1 = btype;
                    if (tok != ':') {
            if (tok != ';')
                            type_decl(&type1, &ad1, &v, TYPE_DIRECT);
                        if (v == 0) {
                            if ((type1.t & VT_BTYPE) != VT_STRUCT)
                            expect("identifier");
                            else {
                int v = btype.ref->v;
                if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
                    if (tcc_state->ms_extensions == 0)
                                expect("identifier");
                }
                            }
                        }
                        if (type_size(&type1, &align) < 0) {
                if ((a == TOK_STRUCT) && (type1.t & VT_ARRAY) && c)
                    flexible = 1;
                else
                    tcc_error("field '%s' has incomplete type",
                                      get_tok_str(v, NULL));
                        }
                        if ((type1.t & VT_BTYPE) == VT_FUNC ||
                            (type1.t & VT_STORAGE))
                            tcc_error("invalid type for '%s'", 
                                  get_tok_str(v, NULL));
                    }
                    if (tok == ':') {
                        next();
                        bit_size = expr_const();
                        /* XXX: handle v = 0 case for messages */
                        if (bit_size < 0)
                            tcc_error("negative width in bit-field '%s'", 
                                  get_tok_str(v, NULL));
                        if (v && bit_size == 0)
                            tcc_error("zero width for bit-field '%s'", 
                                  get_tok_str(v, NULL));
            if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
                parse_attribute(&ad1);
                    }
                    size = type_size(&type1, &align);
            /* Only remember non-default alignment.  */
            alignoverride = 0;
                    if (ad1.a.aligned) {
            int speca = 1 << (ad1.a.aligned - 1);
            alignoverride = speca;
                    } else if (ad1.a.packed || ad->a.packed) {
                        alignoverride = 1;
                    } else if (*tcc_state->pack_stack_ptr) {
                        if (align >= *tcc_state->pack_stack_ptr)
                            alignoverride = *tcc_state->pack_stack_ptr;
                    }
                    if (bit_size >= 0) {
                        bt = type1.t & VT_BTYPE;
                        if (bt != VT_INT && 
                            bt != VT_BYTE && 
                            bt != VT_SHORT &&
                            bt != VT_BOOL &&
                            bt != VT_ENUM &&
                            bt != VT_LLONG)
                            tcc_error("bitfields must have scalar type");
                        bsize = size * 8;
                        if (bit_size > bsize) {
                            tcc_error("width of '%s' exceeds its type",
                                  get_tok_str(v, NULL));
                        } else if (bit_size == bsize) {
                            /* no need for bit fields */
                            ;
                        } else {
                            type1.t |= VT_BITFIELD | 
                                (0 << VT_STRUCT_SHIFT) |
                                (bit_size << (VT_STRUCT_SHIFT + 6));
                        }
                    }
                    if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
                        /* Remember we've seen a real field to check
               for placement of flexible array member. */
            c = 1;
                    }
            /* If member is a struct or bit-field, enforce
               placing into the struct (as anonymous).  */
                    if (v == 0 &&
            ((type1.t & VT_BTYPE) == VT_STRUCT ||
             bit_size >= 0)) {
                v = anon_sym++;
            }
                    if (v) {
                        ss = sym_push(v | SYM_FIELD, &type1, alignoverride, 0);
                        *ps = ss;
                        ps = &ss->next;
                    }
                    if (tok == ';' || tok == TOK_EOF)
                        break;
                    skip(',');
                }
                skip(';');
            }
            skip('}');
        if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
            parse_attribute(ad);
        struct_layout(type, ad);
        }
    }
}

/* return 1 if basic type is a type size (short, long, long long) */
ST_FUNC int is_btype_size(int bt)
{
  return bt == VT_SHORT || bt == VT_LONG || bt == VT_LLONG;
}

/* Add type qualifiers to a type. If the type is an array then the qualifiers
   are added to the element type, copied because it could be a typedef. */
static void parse_btype_qualify(CType *type, int qualifiers)
{
    while (type->t & VT_ARRAY) {
        type->ref = sym_push(SYM_FIELD, &type->ref->type, 0, type->ref->c);
        type = &type->ref->type;
    }
    type->t |= qualifiers;
}

/* return 0 if no type declaration. otherwise, return the basic type
   and skip it. 
 */
static int parse_btype(CType *type, AttributeDef *ad)
{
    int t, u, bt_size, complete, type_found, typespec_found, g;
    Sym *s;
    CType type1;

    memset(ad, 0, sizeof(AttributeDef));
    complete = 0;
    type_found = 0;
    typespec_found = 0;
    t = 0;
    while(1) {
        switch(tok) {
        case TOK_EXTENSION:
            /* currently, we really ignore extension */
            next();
            continue;

            /* basic types */
        case TOK_CHAR:
            u = VT_BYTE;
        basic_type:
            next();
        basic_type1:
            if (complete)
                tcc_error("too many basic types");
            t |= u;
            bt_size = is_btype_size (u & VT_BTYPE);
            if (u == VT_INT || (!bt_size && !(t & VT_TYPEDEF)))
                complete = 1;
            typespec_found = 1;
            break;
        case TOK_VOID:
            u = VT_VOID;
            goto basic_type;
        case TOK_SHORT:
            u = VT_SHORT;
            goto basic_type;
        case TOK_INT:
            u = VT_INT;
            goto basic_type;
        case TOK_LONG:
            next();
            if ((t & VT_BTYPE) == VT_DOUBLE) {
#ifndef TCC_TARGET_PE
                t = (t & ~VT_BTYPE) | VT_LDOUBLE;
#endif
            } else if ((t & VT_BTYPE) == VT_LONG) {
                t = (t & ~VT_BTYPE) | VT_LLONG;
            } else {
                u = VT_LONG;
                goto basic_type1;
            }
            break;
#ifdef TCC_TARGET_ARM64
        case TOK_UINT128:
            /* GCC's __uint128_t appears in some Linux header files. Make it a
               synonym for long double to get the size and alignment right. */
            u = VT_LDOUBLE;
            goto basic_type;
#endif
        case TOK_BOOL:
            u = VT_BOOL;
            goto basic_type;
        case TOK_FLOAT:
            u = VT_FLOAT;
            goto basic_type;
        case TOK_DOUBLE:
            next();
            if ((t & VT_BTYPE) == VT_LONG) {
#ifdef TCC_TARGET_PE
                t = (t & ~VT_BTYPE) | VT_DOUBLE;
#else
                t = (t & ~VT_BTYPE) | VT_LDOUBLE;
#endif
            } else {
                u = VT_DOUBLE;
                goto basic_type1;
            }
            break;
        case TOK_ENUM:
            struct_decl(&type1, ad, VT_ENUM);
        basic_type2:
            u = type1.t;
            type->ref = type1.ref;
            goto basic_type1;
        case TOK_STRUCT:
        case TOK_UNION:
            struct_decl(&type1, ad, VT_STRUCT);
            goto basic_type2;

            /* type modifiers */
        case TOK_CONST1:
        case TOK_CONST2:
        case TOK_CONST3:
            type->t = t;
            parse_btype_qualify(type, VT_CONSTANT);
            t = type->t;
            next();
            break;
        case TOK_VOLATILE1:
        case TOK_VOLATILE2:
        case TOK_VOLATILE3:
            type->t = t;
            parse_btype_qualify(type, VT_VOLATILE);
            t = type->t;
            next();
            break;
        case TOK_SIGNED1:
        case TOK_SIGNED2:
        case TOK_SIGNED3:
            if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == (VT_DEFSIGN|VT_UNSIGNED))
                tcc_error("signed and unsigned modifier");
            typespec_found = 1;
            t |= VT_DEFSIGN;
            next();
            break;
        case TOK_REGISTER:
        case TOK_AUTO:
        case TOK_RESTRICT1:
        case TOK_RESTRICT2:
        case TOK_RESTRICT3:
            next();
            break;
        case TOK_UNSIGNED:
            if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == VT_DEFSIGN)
                tcc_error("signed and unsigned modifier");
            t |= VT_DEFSIGN | VT_UNSIGNED;
            next();
            typespec_found = 1;
            break;

            /* storage */
        case TOK_EXTERN:
            g = VT_EXTERN;
            goto storage;
        case TOK_STATIC:
            g = VT_STATIC;
            goto storage;
        case TOK_TYPEDEF:
            g = VT_TYPEDEF;
            goto storage;
       storage:
            if (t & (VT_EXTERN|VT_STATIC|VT_TYPEDEF) & ~g)
                tcc_error("multiple storage classes");
            t |= g;
            next();
            break;
        case TOK_INLINE1:
        case TOK_INLINE2:
        case TOK_INLINE3:
            t |= VT_INLINE;
            next();
            break;

            /* GNUC attribute */
        case TOK_ATTRIBUTE1:
        case TOK_ATTRIBUTE2:
            parse_attribute(ad);
            if (ad->a.mode) {
                u = ad->a.mode -1;
                t = (t & ~VT_BTYPE) | u;
            }
            break;
            /* GNUC typeof */
        case TOK_TYPEOF1:
        case TOK_TYPEOF2:
        case TOK_TYPEOF3:
            next();
            parse_expr_type(&type1);
            /* remove all storage modifiers except typedef */
            type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
            goto basic_type2;
        default:
            if (typespec_found)
                goto the_end;
            s = sym_find(tok);
            if (!s || !(s->type.t & VT_TYPEDEF))
                goto the_end;

            type->t = ((s->type.t & ~VT_TYPEDEF) |
                       (t & ~(VT_CONSTANT | VT_VOLATILE)));
            type->ref = s->type.ref;
            if (t & (VT_CONSTANT | VT_VOLATILE))
                parse_btype_qualify(type, t & (VT_CONSTANT | VT_VOLATILE));
            t = type->t;

            if (s->r) {
                /* get attributes from typedef */
                if (0 == ad->a.aligned)
                    ad->a.aligned = s->a.aligned;
                if (0 == ad->a.func_call)
                    ad->a.func_call = s->a.func_call;
                ad->a.packed |= s->a.packed;
            }
            next();
            typespec_found = 1;
            break;
        }
        type_found = 1;
    }
the_end:
    if (tcc_state->char_is_unsigned) {
        if ((t & (VT_DEFSIGN|VT_BTYPE)) == VT_BYTE)
            t |= VT_UNSIGNED;
    }

    /* long is never used as type */
    if ((t & VT_BTYPE) == VT_LONG)
#if PTR_SIZE == 8 && !defined TCC_TARGET_PE
        t = (t & ~VT_BTYPE) | VT_LLONG;
#else
        t = (t & ~VT_BTYPE) | VT_INT;
#endif
    type->t = t;
    return type_found;
}

/* convert a function parameter type (array to pointer and function to
   function pointer) */
static inline void convert_parameter_type(CType *pt)
{
    /* remove const and volatile qualifiers (XXX: const could be used
       to indicate a const function parameter */
    pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
    /* array must be transformed to pointer according to ANSI C */
    pt->t &= ~VT_ARRAY;
    if ((pt->t & VT_BTYPE) == VT_FUNC) {
        mk_pointer(pt);
    }
}

ST_FUNC void parse_asm_str(CString *astr)
{
    skip('(');
    parse_mult_str(astr, "string constant");
}

/* Parse an asm label and return the token */
static int asm_label_instr(void)
{
    int v;
    CString astr;

    next();
    parse_asm_str(&astr);
    skip(')');
#ifdef ASM_DEBUG
    printf("asm_alias: \"%s\"\n", (char *)astr.data);
#endif
    v = tok_alloc(astr.data, astr.size - 1)->tok;
    cstr_free(&astr);
    return v;
}

static int post_type(CType *type, AttributeDef *ad, int storage, int td)
{
    int n, l, t1, arg_size, align;
    Sym **plast, *s, *first;
    AttributeDef ad1;
    CType pt;

    if (tok == '(') {
        /* function type, or recursive declarator (return if so) */
        next();
    if (td && !(td & TYPE_ABSTRACT))
      return 0;
    if (tok == ')')
      l = 0;
    else if (parse_btype(&pt, &ad1))
      l = FUNC_NEW;
    else if (td)
      return 0;
    else
      l = FUNC_OLD;
        first = NULL;
        plast = &first;
        arg_size = 0;
        if (l) {
            for(;;) {
                /* read param name and compute offset */
                if (l != FUNC_OLD) {
                    if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
                        break;
                    type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
                    if ((pt.t & VT_BTYPE) == VT_VOID)
                        tcc_error("parameter declared as void");
                    arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
                } else {
                    n = tok;
                    if (n < TOK_UIDENT)
                        expect("identifier");
                    pt.t = VT_VOID; /* invalid type */
                    next();
                }
                convert_parameter_type(&pt);
                s = sym_push(n | SYM_FIELD, &pt, 0, 0);
                *plast = s;
                plast = &s->next;
                if (tok == ')')
                    break;
                skip(',');
                if (l == FUNC_NEW && tok == TOK_DOTS) {
                    l = FUNC_ELLIPSIS;
                    next();
                    break;
                }
        if (l == FUNC_NEW && !parse_btype(&pt, &ad1))
            tcc_error("invalid type");
            }
        } else
            /* if no parameters, then old type prototype */
            l = FUNC_OLD;
        skip(')');
        /* NOTE: const is ignored in returned type as it has a special
           meaning in gcc / C++ */
        type->t &= ~VT_CONSTANT; 
        /* some ancient pre-K&R C allows a function to return an array
           and the array brackets to be put after the arguments, such 
           that "int c()[]" means something like "int[] c()" */
        if (tok == '[') {
            next();
            skip(']'); /* only handle simple "[]" */
            mk_pointer(type);
        }
        /* we push a anonymous symbol which will contain the function prototype */
        ad->a.func_args = arg_size;
        s = sym_push(SYM_FIELD, type, 0, l);
        s->a = ad->a;
        s->next = first;
        type->t = VT_FUNC;
        type->ref = s;
    } else if (tok == '[') {
    int saved_nocode_wanted = nocode_wanted;
        /* array definition */
        next();
        if (tok == TOK_RESTRICT1)
            next();
        n = -1;
        t1 = 0;
        if (tok != ']') {
            if (!local_stack || (storage & VT_STATIC))
                vpushi(expr_const());
            else {
        /* VLAs (which can only happen with local_stack && !VT_STATIC)
           length must always be evaluated, even under nocode_wanted,
           so that its size slot is initialized (e.g. under sizeof
           or typeof).  */
        nocode_wanted = 0;
        gexpr();
        }
            if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
                n = vtop->c.i;
                if (n < 0)
                    tcc_error("invalid array size");
            } else {
                if (!is_integer_btype(vtop->type.t & VT_BTYPE))
                    tcc_error("size of variable length array should be an integer");
                t1 = VT_VLA;
            }
        }
        skip(']');
        /* parse next post type */
        post_type(type, ad, storage, 0);
        if (type->t == VT_FUNC)
            tcc_error("declaration of an array of functions");
        t1 |= type->t & VT_VLA;
        
        if (t1 & VT_VLA) {
            loc -= type_size(&int_type, &align);
            loc &= -align;
            n = loc;

            vla_runtime_type_size(type, &align);
            gen_op('*');
            vset(&int_type, VT_LOCAL|VT_LVAL, n);
            vswap();
            vstore();
        }
        if (n != -1)
            vpop();
    nocode_wanted = saved_nocode_wanted;
                
        /* we push an anonymous symbol which will contain the array
           element type */
        s = sym_push(SYM_FIELD, type, 0, n);
        type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
        type->ref = s;
    }
    return 1;
}

/* Parse a type declarator (except basic type), and return the type
   in 'type'. 'td' is a bitmask indicating which kind of type decl is
   expected. 'type' should contain the basic type. 'ad' is the
   attribute definition of the basic type. It can be modified by
   type_decl().  If this (possibly abstract) declarator is a pointer chain
   it returns the innermost pointed to type (equals *type, but is a different
   pointer), otherwise returns type itself, that's used for recursive calls.  */
static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td)
{
    CType *post, *ret;
    int qualifiers, storage;

    /* recursive type, remove storage bits first, apply them later again */
    storage = type->t & VT_STORAGE;
    type->t &= ~VT_STORAGE;
    post = ret = type;
    while (tok == '*') {
        qualifiers = 0;
    redo:
        next();
        switch(tok) {
        case TOK_CONST1:
        case TOK_CONST2:
        case TOK_CONST3:
            qualifiers |= VT_CONSTANT;
            goto redo;
        case TOK_VOLATILE1:
        case TOK_VOLATILE2:
        case TOK_VOLATILE3:
            qualifiers |= VT_VOLATILE;
            goto redo;
        case TOK_RESTRICT1:
        case TOK_RESTRICT2:
        case TOK_RESTRICT3:
            goto redo;
    /* XXX: clarify attribute handling */
    case TOK_ATTRIBUTE1:
    case TOK_ATTRIBUTE2:
        parse_attribute(ad);
        break;
        }
        mk_pointer(type);
        type->t |= qualifiers;
    if (ret == type)
        /* innermost pointed to type is the one for the first derivation */
        ret = pointed_type(type);
    }

    if (tok == '(') {
    /* This is possibly a parameter type list for abstract declarators
       ('int ()'), use post_type for testing this.  */
    if (!post_type(type, ad, 0, td)) {
        /* It's not, so it's a nested declarator, and the post operations
           apply to the innermost pointed to type (if any).  */
        /* XXX: this is not correct to modify 'ad' at this point, but
           the syntax is not clear */
        if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
          parse_attribute(ad);
        post = type_decl(type, ad, v, td);
        skip(')');
    }
    } else if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
    /* type identifier */
    *v = tok;
    next();
    } else {
    if (!(td & TYPE_ABSTRACT))
      expect("identifier");
    *v = 0;
    }
    post_type(post, ad, storage, 0);
    if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
        parse_attribute(ad);
    type->t |= storage;
    return ret;
}

/* compute the lvalue VT_LVAL_xxx needed to match type t. */
ST_FUNC int lvalue_type(int t)
{
    int bt, r;
    r = VT_LVAL;
    bt = t & VT_BTYPE;
    if (bt == VT_BYTE || bt == VT_BOOL)
        r |= VT_LVAL_BYTE;
    else if (bt == VT_SHORT)
        r |= VT_LVAL_SHORT;
    else
        return r;
    if (t & VT_UNSIGNED)
        r |= VT_LVAL_UNSIGNED;
    return r;
}

/* indirection with full error checking and bound check */
ST_FUNC void indir(void)
{
    if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
        if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
            return;
        expect("pointer");
    }
    if (vtop->r & VT_LVAL)
        gv(RC_INT);
    vtop->type = *pointed_type(&vtop->type);
    /* Arrays and functions are never lvalues */
    if (!(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_VLA)
        && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
        vtop->r |= lvalue_type(vtop->type.t);
        /* if bound checking, the referenced pointer must be checked */
#ifdef CONFIG_TCC_BCHECK
        if (tcc_state->do_bounds_check)
            vtop->r |= VT_MUSTBOUND;
#endif
    }
}

/* pass a parameter to a function and do type checking and casting */
static void gfunc_param_typed(Sym *func, Sym *arg)
{
    int func_type;
    CType type;

    func_type = func->c;
    if (func_type == FUNC_OLD ||
        (func_type == FUNC_ELLIPSIS && arg == NULL)) {
        /* default casting : only need to convert float to double */
        if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
            type.t = VT_DOUBLE;
            gen_cast(&type);
        } else if (vtop->type.t & VT_BITFIELD) {
            type.t = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
        type.ref = vtop->type.ref;
            gen_cast(&type);
        }
    } else if (arg == NULL) {
        tcc_error("too many arguments to function");
    } else {
        type = arg->type;
        type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
        gen_assign_cast(&type);
    }
}

/* parse an expression and return its type without any side effect.
   If UNRY we parse an unary expression, otherwise a full one.  */
static void expr_type(CType *type, int unry)
{
    nocode_wanted++;
    if (unry)
        unary();
    else
        gexpr();
    *type = vtop->type;
    vpop();
    nocode_wanted--;
}

/* parse an expression of the form '(type)' or '(expr)' and return its
   type */
static void parse_expr_type(CType *type)
{
    int n;
    AttributeDef ad;

    skip('(');
    if (parse_btype(type, &ad)) {
        type_decl(type, &ad, &n, TYPE_ABSTRACT);
    } else {
        expr_type(type, 0);
    }
    skip(')');
}

static void parse_type(CType *type)
{
    AttributeDef ad;
    int n;

    if (!parse_btype(type, &ad)) {
        expect("type");
    }
    type_decl(type, &ad, &n, TYPE_ABSTRACT);
}

static void parse_builtin_params(int nc, const char *args)
{
    char c, sep = '(';
    CType t;
    if (nc)
        nocode_wanted++;
    next();
    while ((c = *args++)) {
    skip(sep);
    sep = ',';
    switch (c) {
        case 'e': expr_eq(); continue;
        case 't': parse_type(&t); vpush(&t); continue;
        default: tcc_error("internal error"); break;
    }
    }
    skip(')');
    if (nc)
        nocode_wanted--;
}

ST_FUNC void unary(void)
{
    int n, t, align, size, r, sizeof_caller;
    CType type;
    Sym *s;
    AttributeDef ad;

    sizeof_caller = in_sizeof;
    in_sizeof = 0;
    /* XXX: GCC 2.95.3 does not generate a table although it should be
       better here */
 tok_next:
    switch(tok) {
    case TOK_EXTENSION:
        next();
        goto tok_next;
    case TOK_CINT:
    case TOK_CCHAR: 
    case TOK_LCHAR:
    t = VT_INT;
 push_tokc:
    type.t = t;
    type.ref = 0;
    vsetc(&type, VT_CONST, &tokc);
        next();
        break;
    case TOK_CUINT:
        t = VT_INT | VT_UNSIGNED;
        goto push_tokc;
    case TOK_CLLONG:
        t = VT_LLONG;
    goto push_tokc;
    case TOK_CULLONG:
        t = VT_LLONG | VT_UNSIGNED;
    goto push_tokc;
    case TOK_CFLOAT:
        t = VT_FLOAT;
    goto push_tokc;
    case TOK_CDOUBLE:
        t = VT_DOUBLE;
    goto push_tokc;
    case TOK_CLDOUBLE:
        t = VT_LDOUBLE;
    goto push_tokc;

    case TOK___FUNCTION__:
        if (!gnu_ext)
            goto tok_identifier;
        /* fall thru */
    case TOK___FUNC__:
        {
            void *ptr;
            int len;
            /* special function name identifier */
            len = strlen(funcname) + 1;
            /* generate char[len] type */
            type.t = VT_BYTE;
            mk_pointer(&type);
            type.t |= VT_ARRAY;
            type.ref->c = len;
            vpush_ref(&type, data_section, data_section->data_offset, len);
            ptr = section_ptr_add(data_section, len);
            memcpy(ptr, funcname, len);
            next();
        }
        break;
    case TOK_LSTR:
#ifdef TCC_TARGET_PE
        t = VT_SHORT | VT_UNSIGNED;
#else
        t = VT_INT;
#endif
        goto str_init;
    case TOK_STR:
        /* string parsing */
        t = VT_BYTE;
    str_init:
        if (tcc_state->warn_write_strings)
            t |= VT_CONSTANT;
        type.t = t;
        mk_pointer(&type);
        type.t |= VT_ARRAY;
        memset(&ad, 0, sizeof(AttributeDef));
        decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
        break;
    case '(':
        next();
        /* cast ? */
        if (parse_btype(&type, &ad)) {
            type_decl(&type, &ad, &n, TYPE_ABSTRACT);
            skip(')');
            /* check ISOC99 compound literal */
            if (tok == '{') {
                    /* data is allocated locally by default */
                if (global_expr)
                    r = VT_CONST;
                else
                    r = VT_LOCAL;
                /* all except arrays are lvalues */
                if (!(type.t & VT_ARRAY))
                    r |= lvalue_type(type.t);
                memset(&ad, 0, sizeof(AttributeDef));
                decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
            } else {
                if (sizeof_caller) {
                    vpush(&type);
                    return;
                }
                unary();
                gen_cast(&type);
            }
        } else if (tok == '{') {
        int saved_nocode_wanted = nocode_wanted;
            if (const_wanted)
                tcc_error("expected constant");
            /* save all registers */
            save_regs(0);
            /* statement expression : we do not accept break/continue
               inside as GCC does.  We do retain the nocode_wanted state,
           as statement expressions can't ever be entered from the
           outside, so any reactivation of code emission (from labels
           or loop heads) can be disabled again after the end of it. */
            block(NULL, NULL, 1);
        nocode_wanted = saved_nocode_wanted;
            skip(')');
        } else {
            gexpr();
            skip(')');
        }
        break;
    case '*':
        next();
        unary();
        indir();
        break;
    case '&':
        next();
        unary();
        /* functions names must be treated as function pointers,
           except for unary '&' and sizeof. Since we consider that
           functions are not lvalues, we only have to handle it
           there and in function calls. */
        /* arrays can also be used although they are not lvalues */
        if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
            !(vtop->type.t & VT_ARRAY))
            test_lvalue();
        mk_pointer(&vtop->type);
        gaddrof();
        break;
    case '!':
        next();
        unary();
        if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
            CType boolean;
            boolean.t = VT_BOOL;
            gen_cast(&boolean);
            vtop->c.i = !vtop->c.i;
        } else if ((vtop->r & VT_VALMASK) == VT_CMP)
            vtop->c.i ^= 1;
        else {
            save_regs(1);
            vseti(VT_JMP, gvtst(1, 0));
        }
        break;
    case '~':
        next();
        unary();
        vpushi(-1);
        gen_op('^');
        break;
    case '+':
        next();
        unary();
        if ((vtop->type.t & VT_BTYPE) == VT_PTR)
            tcc_error("pointer not accepted for unary plus");
        /* In order to force cast, we add zero, except for floating point
       where we really need an noop (otherwise -0.0 will be transformed
       into +0.0).  */
    if (!is_float(vtop->type.t)) {
        vpushi(0);
        gen_op('+');
    }
        break;
    case TOK_SIZEOF:
    case TOK_ALIGNOF1:
    case TOK_ALIGNOF2:
        t = tok;
        next();
        in_sizeof++;
        expr_type(&type, 1); // Perform a in_sizeof = 0;
        size = type_size(&type, &align);
        if (t == TOK_SIZEOF) {
            if (!(type.t & VT_VLA)) {
                if (size < 0)
                    tcc_error("sizeof applied to an incomplete type");
                vpushs(size);
            } else {
                vla_runtime_type_size(&type, &align);
            }
        } else {
            vpushs(align);
        }
        vtop->type.t |= VT_UNSIGNED;
        break;

    case TOK_builtin_expect:
    /* __builtin_expect is a no-op for now */
    parse_builtin_params(0, "ee");
    vpop();
        break;
    case TOK_builtin_types_compatible_p:
    parse_builtin_params(0, "tt");
    vtop[-1].type.t &= ~(VT_CONSTANT | VT_VOLATILE);
    vtop[0].type.t &= ~(VT_CONSTANT | VT_VOLATILE);
    n = is_compatible_types(&vtop[-1].type, &vtop[0].type);
    vtop -= 2;
    vpushi(n);
        break;
    case TOK_builtin_choose_expr:
    {
#if HAVE_LONG_LONG_STUB || HAVE_LONG_LONG
        int64_t c;
#else
        int32_t c;
#endif
        next();
        skip('(');
#if HAVE_LONG_LONG
        c = expr_const64();
#else
        c = expr_const32();
#endif
        skip(',');
        if (!c) {
        nocode_wanted++;
        }
        expr_eq();
        if (!c) {
        vpop();
        nocode_wanted--;
        }
        skip(',');
        if (c) {
        nocode_wanted++;
        }
        expr_eq();
        if (c) {
        vpop();
        nocode_wanted--;
        }
        skip(')');
    }
        break;
    case TOK_builtin_constant_p:
    parse_builtin_params(1, "e");
    n = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
    vtop--;
    vpushi(n);
        break;
    case TOK_builtin_frame_address:
    case TOK_builtin_return_address:
        {
            int tok1 = tok;
            int level;
            CType type;
            next();
            skip('(');
            if (tok != TOK_CINT) {
                tcc_error("%s only takes positive integers",
                          tok1 == TOK_builtin_return_address ?
                          "__builtin_return_address" :
                          "__builtin_frame_address");
            }
            level = (uint32_t)tokc.i;
            next();
            skip(')');
            type.t = VT_VOID;
            mk_pointer(&type);
            vset(&type, VT_LOCAL, 0);       /* local frame */
            while (level--) {
                mk_pointer(&vtop->type);
                indir();                    /* -> parent frame */
            }
            if (tok1 == TOK_builtin_return_address) {
                // assume return address is just above frame pointer on stack
                vpushi(PTR_SIZE);
                gen_op('+');
                mk_pointer(&vtop->type);
                indir();
            }
        }
        break;
#ifdef TCC_TARGET_X86_64
#ifdef TCC_TARGET_PE
    case TOK_builtin_va_start:
    parse_builtin_params(0, "ee");
        r = vtop->r & VT_VALMASK;
        if (r == VT_LLOCAL)
            r = VT_LOCAL;
        if (r != VT_LOCAL)
            tcc_error("__builtin_va_start expects a local variable");
        vtop->r = r;
    vtop->type = char_pointer_type;
    vtop->c.i += 8;
    vstore();
        break;
#else
    case TOK_builtin_va_arg_types:
    parse_builtin_params(0, "t");
    vpushi(classify_x86_64_va_arg(&vtop->type));
    vswap();
    vpop();
        break;
#endif
#endif

#ifdef TCC_TARGET_ARM64
    case TOK___va_start: {
    parse_builtin_params(0, "ee");
        //xx check types
        gen_va_start();
        vpushi(0);
        vtop->type.t = VT_VOID;
        break;
    }
    case TOK___va_arg: {
        CType type;
    parse_builtin_params(0, "et");
    type = vtop->type;
    vpop();
        //xx check types
        gen_va_arg(&type);
        vtop->type = type;
        break;
    }
    case TOK___arm64_clear_cache: {
    parse_builtin_params(0, "ee");
        gen_clear_cache();
        vpushi(0);
        vtop->type.t = VT_VOID;
        break;
    }
#endif
    /* pre operations */
    case TOK_INC:
    case TOK_DEC:
        t = tok;
        next();
        unary();
        inc(0, t);
        break;
    case '-':
        next();
        unary();
        t = vtop->type.t & VT_BTYPE;
    if (is_float(t)) {
            /* In IEEE negate(x) isn't subtract(0,x), but rather
           subtract(-0, x).  */
        vpush(&vtop->type);
#if HAVE_FLOAT
        if (t == VT_FLOAT)
            vtop->c.f = -1.0 * 0.0;
        else if (t == VT_DOUBLE)
            vtop->c.d = -1.0 * 0.0;
        else
            vtop->c.ld = -1.0 * 0.0;
#endif
    } else
        vpushi(0);
    vswap();
    gen_op('-');
        break;
    case TOK_LAND:
        if (!gnu_ext)
            goto tok_identifier;
        next();
        /* allow to take the address of a label */
        if (tok < TOK_UIDENT)
            expect("label identifier");
        s = label_find(tok);
        if (!s) {
            s = label_push(&global_label_stack, tok, LABEL_FORWARD);
        } else {
            if (s->r == LABEL_DECLARED)
                s->r = LABEL_FORWARD;
        }
        if (!s->type.t) {
            s->type.t = VT_VOID;
            mk_pointer(&s->type);
            s->type.t |= VT_STATIC;
        }
        vpushsym(&s->type, s);
        next();
        break;

    // special qnan , snan and infinity values
    case TOK___NAN__:
#if HAVE_LONG_LONG
        vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
#else
        vpush64(VT_DOUBLE, 0x7ff80000);
        vtop->c.i = vtop->c.i << 32;
#endif
        next();
        break;
    case TOK___SNAN__:
#if HAVE_LONG_LONG
        vpush64(VT_DOUBLE, 0x7ff0000000000001ULL);
#else
        vpush64(VT_DOUBLE, 0x7ff00000);
        vtop->c.i = vtop->c.i << 32;
        vtop->c.i = vtop->c.i | 1;
#endif
        next();
        break;
    case TOK___INF__:
#if HAVE_LONG_LONG
        vpush64(VT_DOUBLE, 0x7ff0000000000000ULL);
#else
        vpush64(VT_DOUBLE, 0x7ff00000);
        vtop->c.i = vtop->c.i << 32;
#endif
        next();
        break;

    default:
    tok_identifier:
        t = tok;
        next();
        if (t < TOK_UIDENT)
            expect("identifier");
        s = sym_find(t);
        if (!s) {
            const char *name = get_tok_str(t, NULL);
            if (tok != '(')
                tcc_error("'%s' undeclared", name);
            /* for simple function calls, we tolerate undeclared
               external reference to int() function */
            if (tcc_state->warn_implicit_function_declaration
#ifdef TCC_TARGET_PE
                /* people must be warned about using undeclared WINAPI functions
                   (which usually start with uppercase letter) */
                || (name[0] >= 'A' && name[0] <= 'Z')
#endif
            )
                tcc_warning("implicit declaration of function '%s'", name);
            s = external_global_sym(t, &func_old_type, 0); 
        }

        r = s->r;
        /* A symbol that has a register is a local register variable,
           which starts out as VT_LOCAL value.  */
        if ((r & VT_VALMASK) < VT_CONST)
            r = (r & ~VT_VALMASK) | VT_LOCAL;

        vset(&s->type, r, s->c);
        /* Point to s as backpointer (even without r&VT_SYM).
       Will be used by at least the x86 inline asm parser for
       regvars.  */
    vtop->sym = s;
        if (vtop->r & VT_SYM) {
            vtop->c.i = 0;
        }
        break;
    }
    
    /* post operations */
    while (1) {
        if (tok == TOK_INC || tok == TOK_DEC) {
            inc(1, tok);
            next();
        } else if (tok == '.' || tok == TOK_ARROW || tok == TOK_CDOUBLE) {
            int qualifiers;
            /* field */ 
            if (tok == TOK_ARROW) 
                indir();
            qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
            test_lvalue();
            gaddrof();
            /* expect pointer on structure */
            if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
                expect("struct or union");
            if (tok == TOK_CDOUBLE)
                expect("field name");
            next();
            if (tok == TOK_CINT || tok == TOK_CUINT)
                expect("field name");
        s = find_field(&vtop->type, tok);
            if (!s)
                tcc_error("field not found: %s",  get_tok_str(tok & ~SYM_FIELD, &tokc));
            /* add field offset to pointer */
            vtop->type = char_pointer_type; /* change type to 'char *' */
            vpushi(s->c);
            gen_op('+');
            /* change type to field type, and set to lvalue */
            vtop->type = s->type;
            vtop->type.t |= qualifiers;
            /* an array is never an lvalue */
            if (!(vtop->type.t & VT_ARRAY)) {
                vtop->r |= lvalue_type(vtop->type.t);
#ifdef CONFIG_TCC_BCHECK
                /* if bound checking, the referenced pointer must be checked */
                if (tcc_state->do_bounds_check && (vtop->r & VT_VALMASK) != VT_LOCAL)
                    vtop->r |= VT_MUSTBOUND;
#endif
            }
            next();
        } else if (tok == '[') {
            next();
            gexpr();
            gen_op('+');
            indir();
            skip(']');
        } else if (tok == '(') {
            SValue ret;
            Sym *sa;
            int nb_args, ret_nregs, ret_align, regsize, variadic;

            /* function call  */
            if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
                /* pointer test (no array accepted) */
                if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
                    vtop->type = *pointed_type(&vtop->type);
                    if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
                        goto error_func;
                } else {
                error_func:
                    expect("function pointer");
                }
            } else {
                vtop->r &= ~VT_LVAL; /* no lvalue */
            }
            /* get return type */
            s = vtop->type.ref;
            next();
            sa = s->next; /* first parameter */
            nb_args = regsize = 0;
            ret.r2 = VT_CONST;
            /* compute first implicit argument if a structure is returned */
            if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
                variadic = (s->c == FUNC_ELLIPSIS);
                ret_nregs = gfunc_sret(&s->type, variadic, &ret.type,
                                       &ret_align, &regsize);
                if (!ret_nregs) {
                    /* get some space for the returned structure */
                    size = type_size(&s->type, &align);
#ifdef TCC_TARGET_ARM64
                /* On arm64, a small struct is return in registers.
                   It is much easier to write it to memory if we know
                   that we are allowed to write some extra bytes, so
                   round the allocated space up to a power of 2: */
                if (size < 16)
                    while (size & (size - 1))
                        size = (size | (size - 1)) + 1;
#endif
                    loc = (loc - size) & -align;
                    ret.type = s->type;
                    ret.r = VT_LOCAL | VT_LVAL;
                    /* pass it as 'int' to avoid structure arg passing
                       problems */
                    vseti(VT_LOCAL, loc);
                    ret.c = vtop->c;
                    nb_args++;
                }
            } else {
                ret_nregs = 1;
                ret.type = s->type;
            }

            if (ret_nregs) {
                /* return in register */
                if (is_float(ret.type.t)) {
                    ret.r = reg_fret(ret.type.t);
#ifdef TCC_TARGET_X86_64
                    if ((ret.type.t & VT_BTYPE) == VT_QFLOAT)
                      ret.r2 = REG_QRET;
#endif
                } else {
#ifndef TCC_TARGET_ARM64
#ifdef TCC_TARGET_X86_64
                    if ((ret.type.t & VT_BTYPE) == VT_QLONG)
#else
                    if ((ret.type.t & VT_BTYPE) == VT_LLONG)
#endif
                        ret.r2 = REG_LRET;
#endif
                    ret.r = REG_IRET;
                }
                ret.c.i = 0;
            }
            if (tok != ')') {
                for(;;) {
                    expr_eq();
                    gfunc_param_typed(s, sa);
                    nb_args++;
                    if (sa)
                        sa = sa->next;
                    if (tok == ')')
                        break;
                    skip(',');
                }
            }
            if (sa)
                tcc_error("too few arguments to function");
            skip(')');
            gfunc_call(nb_args);

            /* return value */
            for (r = ret.r + ret_nregs + !ret_nregs; r-- > ret.r;) {
                vsetc(&ret.type, r, &ret.c);
                vtop->r2 = ret.r2; /* Loop only happens when r2 is VT_CONST */
            }

            /* handle packed struct return */
            if (((s->type.t & VT_BTYPE) == VT_STRUCT) && ret_nregs) {
                int addr, offset;

                size = type_size(&s->type, &align);
        /* We're writing whole regs often, make sure there's enough
           space.  Assume register size is power of 2.  */
        if (regsize > align)
          align = regsize;
                loc = (loc - size) & -align;
                addr = loc;
                offset = 0;
                for (;;) {
                    vset(&ret.type, VT_LOCAL | VT_LVAL, addr + offset);
                    vswap();
                    vstore();
                    vtop--;
                    if (--ret_nregs == 0)
                        break;
                    offset += regsize;
                }
                vset(&s->type, VT_LOCAL | VT_LVAL, addr);
            }
        } else {
            break;
        }
    }
}

ST_FUNC void expr_prod(void)
{
    int t;

    unary();
    while (tok == '*' || tok == '/' || tok == '%') {
        t = tok;
        next();
        unary();
        gen_op(t);
    }
}

ST_FUNC void expr_sum(void)
{
    int t;

    expr_prod();
    while (tok == '+' || tok == '-') {
        t = tok;
        next();
        expr_prod();
        gen_op(t);
    }
}

static void expr_shift(void)
{
    int t;

    expr_sum();
    while (tok == TOK_SHL || tok == TOK_SAR) {
        t = tok;
        next();
        expr_sum();
        gen_op(t);
    }
}

static void expr_cmp(void)
{
    int t;

    expr_shift();
    while ((tok >= TOK_ULE && tok <= TOK_GT) ||
           tok == TOK_ULT || tok == TOK_UGE) {
        t = tok;
        next();
        expr_shift();
        gen_op(t);
    }
}

static void expr_cmpeq(void)
{
    int t;

    expr_cmp();
    while (tok == TOK_EQ || tok == TOK_NE) {
        t = tok;
        next();
        expr_cmp();
        gen_op(t);
    }
}

static void expr_and(void)
{
    expr_cmpeq();
    while (tok == '&') {
        next();
        expr_cmpeq();
        gen_op('&');
    }
}

static void expr_xor(void)
{
    expr_and();
    while (tok == '^') {
        next();
        expr_and();
        gen_op('^');
    }
}

static void expr_or(void)
{
    expr_xor();
    while (tok == '|') {
        next();
        expr_xor();
        gen_op('|');
    }
}

static void expr_land(void)
{
    expr_or();
    if (tok == TOK_LAND) {
    int t = 0;
    for(;;) {
        if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
        CType ctb;
        ctb.t = VT_BOOL;
        gen_cast(&ctb);
        if (vtop->c.i) {
            vpop();
        } else {
            nocode_wanted++;
            while (tok == TOK_LAND) {
            next();
            expr_or();
            vpop();
            }
            nocode_wanted--;
            if (t)
              gsym(t);
            gen_cast(&int_type);
            break;
        }
        } else {
        if (!t)
          save_regs(1);
        t = gvtst(1, t);
        }
        if (tok != TOK_LAND) {
        if (t)
          vseti(VT_JMPI, t);
        else
          vpushi(1);
        break;
        }
        next();
        expr_or();
    }
    }
}

static void expr_lor(void)
{
    expr_land();
    if (tok == TOK_LOR) {
    int t = 0;
    for(;;) {
        if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
        CType ctb;
        ctb.t = VT_BOOL;
        gen_cast(&ctb);
        if (!vtop->c.i) {
            vpop();
        } else {
            nocode_wanted++;
            while (tok == TOK_LOR) {
            next();
            expr_land();
            vpop();
            }
            nocode_wanted--;
            if (t)
              gsym(t);
            gen_cast(&int_type);
            break;
        }
        } else {
        if (!t)
          save_regs(1);
        t = gvtst(0, t);
        }
        if (tok != TOK_LOR) {
        if (t)
          vseti(VT_JMP, t);
        else
          vpushi(0);
        break;
        }
        next();
        expr_land();
    }
    }
}

/* Assuming vtop is a value used in a conditional context
   (i.e. compared with zero) return 0 if it's false, 1 if
   true and -1 if it can't be statically determined.  */
static int condition_3way(void)
{
    int c = -1;
    if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
    (!(vtop->r & VT_SYM) ||
     !(vtop->sym->type.t & VT_WEAK))) {
    CType boolean;
    boolean.t = VT_BOOL;
    vdup();
    gen_cast(&boolean);
    c = vtop->c.i;
    vpop();
    }
    return c;
}

static void expr_cond(void)
{
    int tt, u, r1, r2, rc, t1, t2, bt1, bt2, islv, c, g;
    SValue sv;
    CType type, type1, type2;

    expr_lor();
    if (tok == '?') {
        next();
    c = condition_3way();
        g = (tok == ':' && gnu_ext);
        if (c < 0) {
            /* needed to avoid having different registers saved in
               each branch */
            if (is_float(vtop->type.t)) {
                rc = RC_FLOAT;
#ifdef TCC_TARGET_X86_64
                if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
                    rc = RC_ST0;
                }
#endif
            } else
                rc = RC_INT;
            gv(rc);
            save_regs(1);
            if (g)
                gv_dup();
            tt = gvtst(1, 0);

        } else {
            if (!g)
                vpop();
            tt = 0;
        }

        if (1) {
            if (c == 0)
                nocode_wanted++;
            if (!g)
                gexpr();

            type1 = vtop->type;
            sv = *vtop; /* save value to handle it later */
            vtop--; /* no vpop so that FP stack is not flushed */
            skip(':');

            u = 0;
            if (c < 0)
                u = gjmp(0);
            gsym(tt);

            if (c == 0)
                nocode_wanted--;
            if (c == 1)
                nocode_wanted++;
            expr_cond();
            if (c == 1)
                nocode_wanted--;

            type2 = vtop->type;
            t1 = type1.t;
            bt1 = t1 & VT_BTYPE;
            t2 = type2.t;
            bt2 = t2 & VT_BTYPE;
            /* cast operands to correct type according to ISOC rules */
            if (is_float(bt1) || is_float(bt2)) {
                if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
                    type.t = VT_LDOUBLE;

                } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
                    type.t = VT_DOUBLE;
                } else {
                    type.t = VT_FLOAT;
                }
            } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
                /* cast to biggest op */
                type.t = VT_LLONG;
                /* convert to unsigned if it does not fit in a long long */
                if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED) ||
                    (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED))
                    type.t |= VT_UNSIGNED;
            } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
        /* If one is a null ptr constant the result type
           is the other.  */
        if (is_null_pointer (vtop))
          type = type1;
        else if (is_null_pointer (&sv))
          type = type2;
                /* XXX: test pointer compatibility, C99 has more elaborate
           rules here.  */
        else
          type = type1;
            } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
                /* XXX: test function pointer compatibility */
                type = bt1 == VT_FUNC ? type1 : type2;
            } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
                /* XXX: test structure compatibility */
                type = bt1 == VT_STRUCT ? type1 : type2;
            } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
                /* NOTE: as an extension, we accept void on only one side */
                type.t = VT_VOID;
            } else {
                /* integer operations */
                type.t = VT_INT;
                /* convert to unsigned if it does not fit in an integer */
                if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED) ||
                    (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED))
                    type.t |= VT_UNSIGNED;
            }
            /* keep structs lvalue by transforming `(expr ? a : b)` to `*(expr ? &a : &b)` so
               that `(expr ? a : b).mem` does not error  with "lvalue expected" */
            islv = (vtop->r & VT_LVAL) && (sv.r & VT_LVAL) && VT_STRUCT == (type.t & VT_BTYPE);
            islv &= c < 0;

            /* now we convert second operand */
            if (c != 1) {
                gen_cast(&type);
                if (islv) {
                    mk_pointer(&vtop->type);
                    gaddrof();
                } else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
                    gaddrof();
            }

            rc = RC_INT;
            if (is_float(type.t)) {
                rc = RC_FLOAT;
#ifdef TCC_TARGET_X86_64
                if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
                    rc = RC_ST0;
                }
#endif
            } else if ((type.t & VT_BTYPE) == VT_LLONG) {
                /* for long longs, we use fixed registers to avoid having
                   to handle a complicated move */
                rc = RC_IRET;
            }

            tt = r2 = 0;
            if (c < 0) {
                r2 = gv(rc);
                tt = gjmp(0);
            }
            gsym(u);

            /* this is horrible, but we must also convert first
               operand */
            if (c != 0) {
                *vtop = sv;
                gen_cast(&type);
                if (islv) {
                    mk_pointer(&vtop->type);
                    gaddrof();
                } else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
                    gaddrof();
            }

            if (c < 0) {
                r1 = gv(rc);
                move_reg(r2, r1, type.t);
                vtop->r = r2;
                gsym(tt);
                if (islv)
                    indir();
            }
        }
    }
}

static void expr_eq(void)
{
    int t;
    
    expr_cond();
    if (tok == '=' ||
        (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
        tok == TOK_A_XOR || tok == TOK_A_OR ||
        tok == TOK_A_SHL || tok == TOK_A_SAR) {
        test_lvalue();
        t = tok;
        next();
        if (t == '=') {
            expr_eq();
        } else {
            vdup();
            expr_eq();
            gen_op(t & 0x7f);
        }
        vstore();
    }
}

ST_FUNC void gexpr(void)
{
    while (1) {
        expr_eq();
        if (tok != ',')
            break;
        vpop();
        next();
    }
}

/* parse a constant expression and return value in vtop.  */
static void expr_const1(void)
{
    const_wanted++;
    expr_cond();
    const_wanted--;
}

#if HAVE_LONG_LONG
/* parse an integer constant and return its value. */
static inline int64_t expr_const64(void)
{
    int64_t c;
    expr_const1();
    if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
        expect("constant expression");
    c = vtop->c.i;
    vpop();
    return c;
}
#else
/* parse an integer constant and return its value. */
static inline int32_t expr_const32(void)
{
    int32_t c;
    expr_const1();
    if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
        expect("constant expression");
    c = vtop->c.i;
    vpop();
    return c;
}
#endif

/* parse an integer constant and return its value.
   Complain if it doesn't fit 32bit (signed or unsigned).  */
ST_FUNC int expr_const(void)
{
    int c;
#if HAVE_LONG_LONG
    int64_t wc = expr_const64();
#else
    int32_t wc = expr_const32();
#endif
    c = wc;
    if (c != wc && (unsigned)c != wc)
        tcc_error("constant exceeds 32 bit");
    return c;
}

/* return the label token if current token is a label, otherwise
   return zero */
static int is_label(void)
{
    int last_tok;

    /* fast test first */
    if (tok < TOK_UIDENT)
        return 0;
    /* no need to save tokc because tok is an identifier */
    last_tok = tok;
    next();
    if (tok == ':') {
        return last_tok;
    } else {
        unget_tok(last_tok);
        return 0;
    }
}

#ifndef TCC_TARGET_ARM64
static void gfunc_return(CType *func_type)
{
    if ((func_type->t & VT_BTYPE) == VT_STRUCT) {
        CType type, ret_type;
        int ret_align, ret_nregs, regsize;
        ret_nregs = gfunc_sret(func_type, func_var, &ret_type,
                               &ret_align, &regsize);
        if (0 == ret_nregs) {
            /* if returning structure, must copy it to implicit
               first pointer arg location */
            type = *func_type;
            mk_pointer(&type);
            vset(&type, VT_LOCAL | VT_LVAL, func_vc);
            indir();
            vswap();
            /* copy structure value to pointer */
            vstore();
        } else {
            /* returning structure packed into registers */
            int r, size, addr, align;
            size = type_size(func_type,&align);
            if ((vtop->r != (VT_LOCAL | VT_LVAL) ||
                 (vtop->c.i & (ret_align-1)))
                && (align & (ret_align-1))) {
                loc = (loc - size) & -ret_align;
                addr = loc;
                type = *func_type;
                vset(&type, VT_LOCAL | VT_LVAL, addr);
                vswap();
                vstore();
                vpop();
                vset(&ret_type, VT_LOCAL | VT_LVAL, addr);
            }
            vtop->type = ret_type;
            if (is_float(ret_type.t))
                r = rc_fret(ret_type.t);
            else
                r = RC_IRET;

            if (ret_nregs == 1)
                gv(r);
            else {
                for (;;) {
                    vdup();
                    gv(r);
                    vpop();
                    if (--ret_nregs == 0)
                      break;
                    /* We assume that when a structure is returned in multiple
                       registers, their classes are consecutive values of the
                       suite s(n) = 2^n */
                    r <<= 1;
                    vtop->c.i += regsize;
                }
            }
        }
    } else if (is_float(func_type->t)) {
        gv(rc_fret(func_type->t));
    } else {
        gv(RC_IRET);
    }
    vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
}
#endif

static int case_cmp(const void *pa, const void *pb)
{
#if HAVE_LONG_LONG
    int64_t a = (*(struct case_t**) pa)->v1;
    int64_t b = (*(struct case_t**) pb)->v1;
#else
    int32_t a = (*(struct case_t**) pa)->v1;
    int32_t b = (*(struct case_t**) pb)->v1;
#endif
    return a < b ? -1 : a > b;
}

static void gcase(struct case_t **base, int len, int *bsym)
{
    struct case_t *p;
    int e;
    int ll = (vtop->type.t & VT_BTYPE) == VT_LLONG;
    gv(RC_INT);
    while (len > 4) {
        /* binary search */
        p = base[len/2];
        vdup();
    if (ll)
        vpushll(p->v2);
    else
        vpushi(p->v2);
        gen_op(TOK_LE);
        e = gtst(1, 0);
        vdup();
    if (ll)
        vpushll(p->v1);
    else
        vpushi(p->v1);
        gen_op(TOK_GE);
        gtst_addr(0, p->sym); /* v1 <= x <= v2 */
        /* x < v1 */
        gcase(base, len/2, bsym);
        if (cur_switch->def_sym)
            gjmp_addr(cur_switch->def_sym);
        else
            *bsym = gjmp(*bsym);
        /* x > v2 */
        gsym(e);
        e = len/2 + 1;
        base += e; len -= e;
    }
    /* linear scan */
    while (len--) {
        p = *base++;
        vdup();
    if (ll)
        vpushll(p->v2);
    else
        vpushi(p->v2);
        if (p->v1 == p->v2) {
            gen_op(TOK_EQ);
            gtst_addr(0, p->sym);
        } else {
            gen_op(TOK_LE);
            e = gtst(1, 0);
            vdup();
        if (ll)
            vpushll(p->v1);
        else
            vpushi(p->v1);
            gen_op(TOK_GE);
            gtst_addr(0, p->sym);
            gsym(e);
        }
    }
}

static void block(int *bsym, int *csym, int is_expr)
{
    int a, b, c, d, cond;
    Sym *s;

    /* generate line number info */
    if (tcc_state->do_debug)
        tcc_debug_line(tcc_state);

    if (is_expr) {
        /* default return value is (void) */
        vpushi(0);
        vtop->type.t = VT_VOID;
    }

    if (tok == TOK_IF) {
        /* if test */
    int saved_nocode_wanted = nocode_wanted;
        next();
        skip('(');
        gexpr();
        skip(')');
    cond = condition_3way();
        if (cond == 1)
            a = 0, vpop();
        else
            a = gvtst(1, 0);
        if (cond == 0)
        nocode_wanted |= 0x20000000;
        block(bsym, csym, 0);
    if (cond != 1)
        nocode_wanted = saved_nocode_wanted;
        c = tok;
        if (c == TOK_ELSE) {
            next();
            d = gjmp(0);
            gsym(a);
        if (cond == 1)
            nocode_wanted |= 0x20000000;
            block(bsym, csym, 0);
            gsym(d); /* patch else jmp */
        if (cond != 0)
        nocode_wanted = saved_nocode_wanted;
        } else
            gsym(a);
    } else if (tok == TOK_WHILE) {
    int saved_nocode_wanted;
    nocode_wanted &= ~0x20000000;
        next();
        d = ind;
        vla_sp_restore();
        skip('(');
        gexpr();
        skip(')');
        a = gvtst(1, 0);
        b = 0;
        ++local_scope;
    saved_nocode_wanted = nocode_wanted;
        block(&a, &b, 0);
    nocode_wanted = saved_nocode_wanted;
        --local_scope;
        gjmp_addr(d);
        gsym(a);
        gsym_addr(b, d);
    } else if (tok == '{') {
        Sym *llabel;
        int block_vla_sp_loc = vla_sp_loc, saved_vlas_in_scope = vlas_in_scope;

        next();
        /* record local declaration stack position */
        s = local_stack;
        llabel = local_label_stack;
        ++local_scope;
        
        /* handle local labels declarations */
        if (tok == TOK_LABEL) {
            next();
            for(;;) {
                if (tok < TOK_UIDENT)
                    expect("label identifier");
                label_push(&local_label_stack, tok, LABEL_DECLARED);
                next();
                if (tok == ',') {
                    next();
                } else {
                    skip(';');
                    break;
                }
            }
        }
        while (tok != '}') {
        if ((a = is_label()))
        unget_tok(a);
        else
            decl(VT_LOCAL);
            if (tok != '}') {
                if (is_expr)
                    vpop();
                block(bsym, csym, is_expr);
            }
        }
        /* pop locally defined labels */
        label_pop(&local_label_stack, llabel);
        /* pop locally defined symbols */
        --local_scope;
    /* In the is_expr case (a statement expression is finished here),
       vtop might refer to symbols on the local_stack.  Either via the
       type or via vtop->sym.  We can't pop those nor any that in turn
       might be referred to.  To make it easier we don't roll back
       any symbols in that case; some upper level call to block() will
       do that.  We do have to remove such symbols from the lookup
       tables, though.  sym_pop will do that.  */
    sym_pop(&local_stack, s, is_expr);

        /* Pop VLA frames and restore stack pointer if required */
        if (vlas_in_scope > saved_vlas_in_scope) {
            vla_sp_loc = saved_vlas_in_scope ? block_vla_sp_loc : vla_sp_root_loc;
            vla_sp_restore();
        }
        vlas_in_scope = saved_vlas_in_scope;
        
        next();
    } else if (tok == TOK_RETURN) {
        next();
        if (tok != ';') {
            gexpr();
            gen_assign_cast(&func_vt);
            gfunc_return(&func_vt);
        }
        skip(';');
        /* jump unless last stmt in top-level block */
        if (tok != '}' || local_scope != 1)
            rsym = gjmp(rsym);
    nocode_wanted |= 0x20000000;
    } else if (tok == TOK_BREAK) {
        /* compute jump */
        if (!bsym)
            tcc_error("cannot break");
        *bsym = gjmp(*bsym);
        next();
        skip(';');
    nocode_wanted |= 0x20000000;
    } else if (tok == TOK_CONTINUE) {
        /* compute jump */
        if (!csym)
            tcc_error("cannot continue");
        vla_sp_restore_root();
        *csym = gjmp(*csym);
        next();
        skip(';');
    } else if (tok == TOK_FOR) {
        int e;
    int saved_nocode_wanted;
    nocode_wanted &= ~0x20000000;
        next();
        skip('(');
        s = local_stack;
        ++local_scope;
        if (tok != ';') {
            /* c99 for-loop init decl? */
            if (!decl0(VT_LOCAL, 1, NULL)) {
                /* no, regular for-loop init expr */
                gexpr();
                vpop();
            }
        }
        skip(';');
        d = ind;
        c = ind;
        vla_sp_restore();
        a = 0;
        b = 0;
        if (tok != ';') {
            gexpr();
            a = gvtst(1, 0);
        }
        skip(';');
        if (tok != ')') {
            e = gjmp(0);
            c = ind;
            vla_sp_restore();
            gexpr();
            vpop();
            gjmp_addr(d);
            gsym(e);
        }
        skip(')');
    saved_nocode_wanted = nocode_wanted;
        block(&a, &b, 0);
    nocode_wanted = saved_nocode_wanted;
        gjmp_addr(c);
        gsym(a);
        gsym_addr(b, c);
        --local_scope;
        sym_pop(&local_stack, s, 0);

    } else 
    if (tok == TOK_DO) {
    int saved_nocode_wanted;
    nocode_wanted &= ~0x20000000;
        next();
        a = 0;
        b = 0;
        d = ind;
        vla_sp_restore();
    saved_nocode_wanted = nocode_wanted;
        block(&a, &b, 0);
        skip(TOK_WHILE);
        skip('(');
        gsym(b);
    gexpr();
    c = gvtst(0, 0);
    gsym_addr(c, d);
    nocode_wanted = saved_nocode_wanted;
        skip(')');
        gsym(a);
        skip(';');
    } else
    if (tok == TOK_SWITCH) {
        struct switch_t *saved, sw;
    int saved_nocode_wanted = nocode_wanted;
    SValue switchval;
        next();
        skip('(');
        gexpr();
        skip(')');
    switchval = *vtop--;
        a = 0;
        b = gjmp(0); /* jump to first case */
        sw.p = NULL; sw.n = 0; sw.def_sym = 0;
        saved = cur_switch;
        cur_switch = &sw;
        block(&a, csym, 0);
    nocode_wanted = saved_nocode_wanted;
        a = gjmp(a); /* add implicit break */
        /* case lookup */
        gsym(b);
        qsort(sw.p, sw.n, sizeof(void*), case_cmp);
        for (b = 1; b < sw.n; b++)
            if (sw.p[b - 1]->v2 >= sw.p[b]->v1)
                tcc_error("duplicate case value");
        /* Our switch table sorting is signed, so the compared
           value needs to be as well when it's 64bit.  */
        if ((switchval.type.t & VT_BTYPE) == VT_LLONG)
            switchval.type.t &= ~VT_UNSIGNED;
        vpushv(&switchval);
        gcase(sw.p, sw.n, &a);
        vpop();
        if (sw.def_sym)
          gjmp_addr(sw.def_sym);
        dynarray_reset(&sw.p, &sw.n);
        cur_switch = saved;
        /* break label */
        gsym(a);
    } else
    if (tok == TOK_CASE) {
        struct case_t *cr = tcc_malloc(sizeof(struct case_t));
        if (!cur_switch)
            expect("switch");
    nocode_wanted &= ~0x20000000;
        next();
#if HAVE_LONG_LONG
        cr->v1 = cr->v2 = expr_const64();
#else
        cr->v1 = cr->v2 = expr_const32();
#endif
        if (gnu_ext && tok == TOK_DOTS) {
            next();
#if HAVE_LONG_LONG
            cr->v2 = expr_const64();
#else
            cr->v2 = expr_const32();
#endif
            if (cr->v2 < cr->v1)
                tcc_warning("empty case range");
        }
        cr->sym = ind;
        dynarray_add(&cur_switch->p, &cur_switch->n, cr);
        skip(':');
        is_expr = 0;
        goto block_after_label;
    } else 
    if (tok == TOK_DEFAULT) {
        next();
        skip(':');
        if (!cur_switch)
            expect("switch");
        if (cur_switch->def_sym)
            tcc_error("too many 'default'");
        cur_switch->def_sym = ind;
        is_expr = 0;
        goto block_after_label;
    } else
    if (tok == TOK_GOTO) {
        next();
        if (tok == '*' && gnu_ext) {
            /* computed goto */
            next();
            gexpr();
            if ((vtop->type.t & VT_BTYPE) != VT_PTR)
                expect("pointer");
            ggoto();
        } else if (tok >= TOK_UIDENT) {
            s = label_find(tok);
            /* put forward definition if needed */
            if (!s) {
                s = label_push(&global_label_stack, tok, LABEL_FORWARD);
            } else {
                if (s->r == LABEL_DECLARED)
                    s->r = LABEL_FORWARD;
            }
            vla_sp_restore_root();
        if (s->r & LABEL_FORWARD)
                s->jnext = gjmp(s->jnext);
            else
                gjmp_addr(s->jnext);
            next();
        } else {
            expect("label identifier");
        }
        skip(';');
    } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
        asm_instr();
    } else {
        b = is_label();
        if (b) {
            /* label case */
        next();
            s = label_find(b);
            if (s) {
                if (s->r == LABEL_DEFINED)
                    tcc_error("duplicate label '%s'", get_tok_str(s->v, NULL));
                gsym(s->jnext);
                s->r = LABEL_DEFINED;
            } else {
                s = label_push(&global_label_stack, b, LABEL_DEFINED);
            }
            s->jnext = ind;
            vla_sp_restore();
            /* we accept this, but it is a mistake */
        block_after_label:
        nocode_wanted &= ~0x20000000;
            if (tok == '}') {
                tcc_warning("deprecated use of label at end of compound statement");
            } else {
                if (is_expr)
                    vpop();
                block(bsym, csym, is_expr);
            }
        } else {
            /* expression case */
            if (tok != ';') {
                if (is_expr) {
                    vpop();
                    gexpr();
                } else {
                    gexpr();
                    vpop();
                }
            }
            skip(';');
        }
    }
}

/* This skips over a stream of tokens containing balanced {} and ()
   pairs, stopping at outer ',' ';' and '}'.  If STR then allocates
   and stores the skipped tokens in *STR.  This doesn't check if
   () and {} are nested correctly, i.e. "({)}" is accepted.  */
static void skip_or_save_block(TokenString **str)
{
    int level = 0;
    if (str)
      *str = tok_str_alloc();

    while ((level > 0 || (tok != '}' && tok != ',' && tok != ';'))) {
    int t;
    if (tok == TOK_EOF) {
         if (str || level > 0)
           tcc_error("unexpected end of file");
         else
           break;
    }
    if (str)
      tok_str_add_tok(*str);
    t = tok;
    next();
    if (t == '{' || t == '(') {
        level++;
    } else if (t == '}' || t == ')') {
        level--;
        if (level == 0)
          break;
    }
    }
    if (str) {
    tok_str_add(*str, -1);
    tok_str_add(*str, 0);
    }
}

#define EXPR_CONST 1
#define EXPR_ANY   2

static void parse_init_elem(int expr_type)
{
    int saved_global_expr;
    switch(expr_type) {
    case EXPR_CONST:
        /* compound literals must be allocated globally in this case */
        saved_global_expr = global_expr;
        global_expr = 1;
        expr_const1();
        global_expr = saved_global_expr;
        /* NOTE: symbols are accepted, as well as lvalue for anon symbols
       (compound literals).  */
        if (((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST
         && ((vtop->r & (VT_SYM|VT_LVAL)) != (VT_SYM|VT_LVAL)
         || vtop->sym->v < SYM_FIRST_ANOM))
#ifdef TCC_TARGET_PE
            || (vtop->type.t & VT_IMPORT)
#endif
        )
            tcc_error("initializer element is not constant");
        break;
    case EXPR_ANY:
        expr_eq();
        break;
    }
}

/* put zeros for variable based init */
static void init_putz(Section *sec, unsigned long c, int size)
{
    if (sec) {
        /* nothing to do because globals are already set to zero */
    } else {
#if BOOTSTRAP && __arm__
        vpush_global_sym(&func_old_type, TOK___memset);
#else
        vpush_global_sym(&func_old_type, TOK_memset);
#endif
        vseti(VT_LOCAL, c);
#ifdef TCC_TARGET_ARM
        vpushs(size);
        vpushi(0);
#else
        vpushi(0);
        vpushs(size);
#endif
        gfunc_call(3);
    }
}

/* t is the array or struct type. c is the array or struct
   address. cur_field is the pointer to the current
   field, for arrays the 'c' member contains the current start
   index.  'size_only' is true if only size info is needed (only used
   in arrays).  al contains the already initialized length of the
   current container (starting at c).  This returns the new length of that.  */
static int decl_designator(CType *type, Section *sec, unsigned long c,
                           Sym **cur_field, int size_only, int al)
{
    Sym *s, *f;
    int index, index_last, align, l, nb_elems, elem_size;
    unsigned long corig = c;

    elem_size = 0;
    nb_elems = 1;
    if (gnu_ext && (l = is_label()) != 0)
        goto struct_field;
    /* NOTE: we only support ranges for last designator */
    while (nb_elems == 1 && (tok == '[' || tok == '.')) {
        if (tok == '[') {
            if (!(type->t & VT_ARRAY))
                expect("array type");
            next();
            index = index_last = expr_const();
            if (tok == TOK_DOTS && gnu_ext) {
                next();
                index_last = expr_const();
            }
            skip(']');
            s = type->ref;
        if (index < 0 || (s->c >= 0 && index_last >= s->c) ||
        index_last < index)
            tcc_error("invalid index");
            if (cur_field)
        (*cur_field)->c = index_last;
            type = pointed_type(type);
            elem_size = type_size(type, &align);
            c += index * elem_size;
            nb_elems = index_last - index + 1;
        } else {
            next();
            l = tok;
        struct_field:
            next();
            if ((type->t & VT_BTYPE) != VT_STRUCT)
                expect("struct/union type");
        f = find_field(type, l);
            if (!f)
                expect("field");
            if (cur_field)
                *cur_field = f;
        type = &f->type;
            c += f->c;
        }
        cur_field = NULL;
    }
    if (!cur_field) {
        if (tok == '=') {
            next();
        } else if (!gnu_ext) {
        expect("=");
        }
    } else {
        if (type->t & VT_ARRAY) {
        index = (*cur_field)->c;
        if (type->ref->c >= 0 && index >= type->ref->c)
            tcc_error("index too large");
            type = pointed_type(type);
            c += index * type_size(type, &align);
        } else {
            f = *cur_field;
        while (f && (f->v & SYM_FIRST_ANOM) && (f->type.t & VT_BITFIELD))
            *cur_field = f = f->next;
            if (!f)
                tcc_error("too many field init");
        type = &f->type;
            c += f->c;
        }
    }
    /* must put zero in holes (note that doing it that way
       ensures that it even works with designators) */
    if (!size_only && c - corig > al)
    init_putz(sec, corig + al, c - corig - al);
    decl_initializer(type, sec, c, 0, size_only);

    /* XXX: make it more general */
    if (!size_only && nb_elems > 1) {
        unsigned long c_end;
        uint8_t *src, *dst;
        int i;

        if (!sec) {
        vset(type, VT_LOCAL|VT_LVAL, c);
        for (i = 1; i < nb_elems; i++) {
        vset(type, VT_LOCAL|VT_LVAL, c + elem_size * i);
        vswap();
        vstore();
        }
        vpop();
    } else {
        c_end = c + nb_elems * elem_size;
        if (c_end > sec->data_allocated)
            section_realloc(sec, c_end);
        src = sec->data + c;
        dst = src;
        for(i = 1; i < nb_elems; i++) {
        dst += elem_size;
        memcpy(dst, src, elem_size);
        }
    }
    }
    c += nb_elems * type_size(type, &align);
    if (c - corig > al)
      al = c - corig;
    return al;
}

#if BOOTSTRAP && HAVE_FLOAT
struct long_double
{
  int one;
  int two;
  int three;
};
#endif

/* store a value or an expression directly in global data or in local array */
static void init_putv(CType *type, Section *sec, unsigned long c)
{
    int bt, bit_pos, bit_size;
    void *ptr;
    unsigned long long bit_mask;
    CType dtype;

    dtype = *type;
    dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */

    if (sec) {
    int size, align;
        /* XXX: not portable */
        /* XXX: generate error if incorrect relocation */
        gen_assign_cast(&dtype);
        bt = type->t & VT_BTYPE;
    size = type_size(type, &align);
    section_reserve(sec, c + size);
        ptr = sec->data + c;
        /* XXX: make code faster ? */
        if (!(type->t & VT_BITFIELD)) {
            bit_pos = 0;
            bit_size = PTR_SIZE * 8;
            bit_mask = -1LL;
        } else {
            bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
            bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
            bit_mask = (1LL << bit_size) - 1;
        }
    if ((vtop->r & (VT_SYM|VT_CONST)) == (VT_SYM|VT_CONST) &&
        vtop->sym->v >= SYM_FIRST_ANOM &&
        /* XXX This rejects compound literals like
           '(void *){ptr}'.  The problem is that '&sym' is
           represented the same way, which would be ruled out
           by the SYM_FIRST_ANOM check above, but also '"string"'
           in 'char *p = "string"' is represented the same
           with the type being VT_PTR and the symbol being an
           anonymous one.  That is, there's no difference in vtop
           between '(void *){x}' and '&(void *){x}'.  Ignore
           pointer typed entities here.  Hopefully no real code
           will every use compound literals with scalar type.  */
        (vtop->type.t & VT_BTYPE) != VT_PTR) {
        /* These come from compound literals, memcpy stuff over.  */
        Section *ssec;
        ElfW(Sym) *esym;
        ElfW_Rel *rel;
        esym = &((ElfW(Sym) *)symtab_section->data)[vtop->sym->c];
        ssec = tcc_state->sections[esym->st_shndx];
        memmove (ptr, ssec->data + esym->st_value, size);
        if (ssec->reloc) {
        /* We need to copy over all memory contents, and that
           includes relocations.  Use the fact that relocs are
           created it order, so look from the end of relocs
           until we hit one before the copied region.  */
        int num_relocs = ssec->reloc->data_offset / sizeof(*rel);
        rel = (ElfW_Rel*)(ssec->reloc->data + ssec->reloc->data_offset);
        while (num_relocs--) {
            rel--;
            if (rel->r_offset >= esym->st_value + size)
              continue;
            if (rel->r_offset < esym->st_value)
              break;
            /* Note: if the same fields are initialized multiple
               times (possible with designators) then we possibly
               add multiple relocations for the same offset here.
               That would lead to wrong code, the last reloc needs
               to win.  We clean this up later after the whole
               initializer is parsed.  */
            put_elf_reloca(symtab_section, sec,
                   c + rel->r_offset - esym->st_value,
                   ELFW(R_TYPE)(rel->r_info),
                   ELFW(R_SYM)(rel->r_info),
#if PTR_SIZE == 8
                   rel->r_addend
#else
                   0
#endif
                  );
        }
        }
    } else {
        if ((vtop->r & VT_SYM) &&
        (bt == VT_BYTE ||
         bt == VT_SHORT ||
         bt == VT_DOUBLE ||
         bt == VT_LDOUBLE ||
#if PTR_SIZE == 8
         (bt == VT_LLONG && bit_size != 64) ||
         bt == VT_INT
#else
         bt == VT_LLONG ||
         (bt == VT_INT && bit_size != 32)
#endif
        ))
          tcc_error("initializer element is not computable at load time");
        switch(bt) {
        /* XXX: when cross-compiling we assume that each type has the
           same representation on host and target, which is likely to
           be wrong in the case of long double */
        case VT_BOOL:
        vtop->c.i = (vtop->c.i != 0);
        case VT_BYTE:
        *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
        break;
        case VT_SHORT:
        *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
        break;
        case VT_FLOAT:
#if HAVE_FLOAT
#if !(BOOTSTRAP && __arm__)
        *(float*)ptr = vtop->c.f;
#else
                {
                  long *lptr = ptr;
                  *lptr = vtop->c.f;
                }
#endif
#endif
        break;
        case VT_DOUBLE:
#if HAVE_FLOAT
#if !(BOOTSTRAP && __arm__)
        *(double *)ptr = vtop->c.d;
#else
                {
                  long long *llptr = ptr;
                  *llptr = vtop->c.d;
                }
#endif
#endif
        break;
        case VT_LDOUBLE:
#if HAVE_FLOAT
                if (sizeof(long double) == LDOUBLE_SIZE)
#if !(BOOTSTRAP && __arm__)
            *(long double *)ptr = vtop->c.ld;
#else
                {
                  // XXX TODO: breaks on mescc/mes-tcc based build
                  // maybe disable with HAVE_LONG_DOUBLE?
                  //struct long_double *ldptr = ptr;
                  //struct long_double tmp = (struct long_double)vtop->c.ld;
                  //*ldptr = (struct long_double)tmp;
                }
#endif
        else if (sizeof(double) == LDOUBLE_SIZE)
            *(double *)ptr = (double)vtop->c.ld;
#if (defined __i386__ || defined __x86_64__) && (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64)
                else if (sizeof (long double) >= 10)
                    memcpy(memset(ptr, 0, LDOUBLE_SIZE), &vtop->c.ld, 10);
#if defined (__TINYC__)
                else if (sizeof (long double) == sizeof (double))
                    __asm__("fldl %1\nfstpt %0\n" : "=m"
                        (memset(ptr, 0, LDOUBLE_SIZE), ptr) : "m" (vtop->c.ld));
#endif
#endif
        else
                    tcc_error("can't cross compile long double constants");
#endif
        break;
#if PTR_SIZE != 8
        case VT_LLONG:
        *(long long *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
        break;
#else
        case VT_LLONG:
#endif
        case VT_PTR:
        {
            addr_t val = (vtop->c.i & bit_mask) << bit_pos;
#if PTR_SIZE == 8
            if (vtop->r & VT_SYM)
              greloca(sec, vtop->sym, c, R_DATA_PTR, val);
            else
              *(addr_t *)ptr |= val;
#else
            if (vtop->r & VT_SYM)
              greloc(sec, vtop->sym, c, R_DATA_PTR);
            *(addr_t *)ptr |= val;
#endif
            break;
        }
        default:
        {
            int val = (vtop->c.i & bit_mask) << bit_pos;
#if PTR_SIZE == 8
            if (vtop->r & VT_SYM)
              greloca(sec, vtop->sym, c, R_DATA_PTR, val);
            else
              *(int *)ptr |= val;
#else
            if (vtop->r & VT_SYM)
              greloc(sec, vtop->sym, c, R_DATA_PTR);
            *(int *)ptr |= val;
#endif
            break;
        }
        }
    }
        vtop--;
    } else {
        vset(&dtype, VT_LOCAL|VT_LVAL, c);
        vswap();
        vstore();
        vpop();
    }
}

/* 't' contains the type and storage info. 'c' is the offset of the
   object in section 'sec'. If 'sec' is NULL, it means stack based
   allocation. 'first' is true if array '{' must be read (multi
   dimension implicit array init handling). 'size_only' is true if
   size only evaluation is wanted (only for arrays). */
static void decl_initializer(CType *type, Section *sec, unsigned long c, 
                             int first, int size_only)
{
    int len, n, no_oblock, nb, i;
    int size1, align1;
    int have_elem;
    Sym *s, *f;
    Sym indexsym;
    CType *t1;

    /* If we currently are at an '}' or ',' we have read an initializer
       element in one of our callers, and not yet consumed it.  */
    have_elem = tok == '}' || tok == ',';
    if (!have_elem && tok != '{' &&
    /* In case of strings we have special handling for arrays, so
       don't consume them as initializer value (which would commit them
       to some anonymous symbol).  */
    tok != TOK_LSTR && tok != TOK_STR &&
    !size_only) {
    parse_init_elem(!sec ? EXPR_ANY : EXPR_CONST);
    have_elem = 1;
    }

    if (have_elem &&
    !(type->t & VT_ARRAY) &&
    /* Use i_c_parameter_t, to strip toplevel qualifiers.
       The source type might have VT_CONSTANT set, which is
       of course assignable to non-const elements.  */
    is_compatible_parameter_types(type, &vtop->type)) {
        init_putv(type, sec, c);
    } else if (type->t & VT_ARRAY) {
        s = type->ref;
        n = s->c;
        t1 = pointed_type(type);
        size1 = type_size(t1, &align1);

        no_oblock = 1;
        if ((first && tok != TOK_LSTR && tok != TOK_STR) || 
            tok == '{') {
            if (tok != '{')
                tcc_error("character array initializer must be a literal,"
                    " optionally enclosed in braces");
            skip('{');
            no_oblock = 0;
        }

        /* only parse strings here if correct type (otherwise: handle
           them as ((w)char *) expressions */
        if ((tok == TOK_LSTR && 
#ifdef TCC_TARGET_PE
             (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
#else
             (t1->t & VT_BTYPE) == VT_INT
#endif
            ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
        len = 0;
            while (tok == TOK_STR || tok == TOK_LSTR) {
                int cstr_len, ch;

                /* compute maximum number of chars wanted */
                if (tok == TOK_STR)
                    cstr_len = tokc.str.size;
                else
                    cstr_len = tokc.str.size / sizeof(nwchar_t);
                cstr_len--;
                nb = cstr_len;
                if (n >= 0 && nb > (n - len))
                    nb = n - len;
                if (!size_only) {
                    if (cstr_len > nb)
                        tcc_warning("initializer-string for array is too long");
                    /* in order to go faster for common case (char
                       string in global variable, we handle it
                       specifically */
                    if (sec && tok == TOK_STR && size1 == 1) {
                        memcpy(sec->data + c + len, tokc.str.data, nb);
                    } else {
                        for(i=0;i<nb;i++) {
                            if (tok == TOK_STR)
                                ch = ((unsigned char *)tokc.str.data)[i];
                            else
                                ch = ((nwchar_t *)tokc.str.data)[i];
                vpushi(ch);
                            init_putv(t1, sec, c + (len + i) * size1);
                        }
                    }
                }
                len += nb;
                next();
            }
            /* only add trailing zero if enough storage (no
               warning in this case since it is standard) */
            if (n < 0 || len < n) {
                if (!size_only) {
            vpushi(0);
                    init_putv(t1, sec, c + (len * size1));
                }
                len++;
            }
        len *= size1;
        } else {
        indexsym.c = 0;
        f = &indexsym;

          do_init_list:
        len = 0;
        while (tok != '}' || have_elem) {
        len = decl_designator(type, sec, c, &f, size_only, len);
        have_elem = 0;
        if (type->t & VT_ARRAY) {
            ++indexsym.c;
            /* special test for multi dimensional arrays (may not
               be strictly correct if designators are used at the
               same time) */
            if (no_oblock && len >= n*size1)
                break;
        } else {
            if (s->type.t == TOK_UNION)
                f = NULL;
            else
                f = f->next;
            if (no_oblock && f == NULL)
                break;
        }

        if (tok == '}')
            break;
        skip(',');
        }
        }
        /* put zeros at the end */
    if (!size_only && len < n*size1)
        init_putz(sec, c + len, n*size1 - len);
        if (!no_oblock)
            skip('}');
        /* patch type size if needed, which happens only for array types */
        if (n < 0)
            s->c = size1 == 1 ? len : ((len + size1 - 1)/size1);
    } else if ((type->t & VT_BTYPE) == VT_STRUCT) {
    size1 = 1;
        no_oblock = 1;
        if (first || tok == '{') {
            skip('{');
            no_oblock = 0;
        }
        s = type->ref;
        f = s->next;
        n = s->c;
    goto do_init_list;
    } else if (tok == '{') {
        next();
        decl_initializer(type, sec, c, first, size_only);
        skip('}');
    } else if (size_only) {
    /* If we supported only ISO C we wouldn't have to accept calling
       this on anything than an array size_only==1 (and even then
       only on the outermost level, so no recursion would be needed),
       because initializing a flex array member isn't supported.
       But GNU C supports it, so we need to recurse even into
       subfields of structs and arrays when size_only is set.  */
        /* just skip expression */
    do {
        skip_or_save_block(NULL);
    } while (tok != '}' && tok != ',' && tok != -1);
    } else {
    if (!have_elem) {
        /* This should happen only when we haven't parsed
           the init element above for fear of committing a
           string constant to memory too early.  */
        if (tok != TOK_STR && tok != TOK_LSTR)
          expect("string constant");
        parse_init_elem(!sec ? EXPR_ANY : EXPR_CONST);
    }
        init_putv(type, sec, c);
    }
}

/* parse an initializer for type 't' if 'has_init' is non zero, and
   allocate space in local or global data space ('r' is either
   VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
   variable 'v' of scope 'scope' is declared before initializers
   are parsed. If 'v' is zero, then a reference to the new object
   is put in the value stack. If 'has_init' is 2, a special parsing
   is done to handle string constants. */
static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, 
                                   int has_init, int v, int scope)
{
    int size, align, addr;
    ParseState saved_parse_state = {0};
    TokenString *init_str = NULL;
    Section *sec;
    Sym *flexible_array;

    flexible_array = NULL;
    if ((type->t & VT_BTYPE) == VT_STRUCT) {
        Sym *field = type->ref->next;
        if (field) {
            while (field->next)
                field = field->next;
            if (field->type.t & VT_ARRAY && field->type.ref->c < 0)
                flexible_array = field;
        }
    }

    size = type_size(type, &align);
    /* If unknown size, we must evaluate it before
       evaluating initializers because
       initializers can generate global data too
       (e.g. string pointers or ISOC99 compound
       literals). It also simplifies local
       initializers handling */
    if (size < 0 || (flexible_array && has_init)) {
        if (!has_init) 
            tcc_error("unknown type size");
        /* get all init string */
        if (has_init == 2) {
        init_str = tok_str_alloc();
            /* only get strings */
            while (tok == TOK_STR || tok == TOK_LSTR) {
                tok_str_add_tok(init_str);
                next();
            }
        tok_str_add(init_str, -1);
        tok_str_add(init_str, 0);
        } else {
        skip_or_save_block(&init_str);
        }
        
        /* compute size */
        save_parse_state(&saved_parse_state);

        begin_macro(init_str, 1);
        next();
        decl_initializer(type, NULL, 0, 1, 1);
        /* prepare second initializer parsing */
        macro_ptr = init_str->str;
        next();
        
        /* if still unknown size, error */
        size = type_size(type, &align);
        if (size < 0) 
            tcc_error("unknown type size");
    }
    /* If there's a flex member and it was used in the initializer
       adjust size.  */
    if (flexible_array &&
    flexible_array->type.ref->c > 0)
        size += flexible_array->type.ref->c
            * pointed_size(&flexible_array->type);
    /* take into account specified alignment if bigger */
    if (ad->a.aligned) {
    int speca = 1 << (ad->a.aligned - 1);
        if (speca > align)
            align = speca;
    } else if (ad->a.packed) {
        align = 1;
    }
    if ((r & VT_VALMASK) == VT_LOCAL) {
        sec = NULL;
#ifdef CONFIG_TCC_BCHECK
        if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
            loc--;
        }
#endif
        loc = (loc - size) & -align;
        addr = loc;
#ifdef CONFIG_TCC_BCHECK
        /* handles bounds */
        /* XXX: currently, since we do only one pass, we cannot track
           '&' operators, so we add only arrays */
        if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
            addr_t *bounds_ptr;
            /* add padding between regions */
            loc--;
            /* then add local bound info */
            bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(addr_t));
            bounds_ptr[0] = addr;
            bounds_ptr[1] = size;
        }
#endif
        if (v) {
            /* local variable */
#ifdef CONFIG_TCC_ASM
        if (ad->asm_label) {
        int reg = asm_parse_regvar(ad->asm_label);
        if (reg >= 0)
            r = (r & ~VT_VALMASK) | reg;
        }
#endif
            sym_push(v, type, r, addr);
        } else {
            /* push local reference */
            vset(type, r, addr);
        }
    } else {
        Sym *sym = NULL;
        if (v && scope == VT_CONST) {
            /* see if the symbol was already defined */
            sym = sym_find(v);
            if (sym) {
                patch_storage(sym, type);
                if (sym->type.t & VT_EXTERN) {
                    /* if the variable is extern, it was not allocated */
                    sym->type.t &= ~VT_EXTERN;
                    /* set array size if it was omitted in extern
                       declaration */
                    if ((sym->type.t & VT_ARRAY) && 
                        sym->type.ref->c < 0 &&
                        type->ref->c >= 0)
                        sym->type.ref->c = type->ref->c;
                } else if (!has_init) {
                    /* we accept several definitions of the same
                       global variable. this is tricky, because we
                       must play with the SHN_COMMON type of the symbol */
                    /* no init data, we won't add more to the symbol */
                    update_storage(sym);
                    goto no_alloc;
                } else if (sym->c) {
                    ElfW(Sym) *esym;
                    esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
                    if (esym->st_shndx == data_section->sh_num)
                        tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
                }
            }
        }

        /* allocate symbol in corresponding section */
        sec = ad->section;
        if (!sec) {
            if (has_init)
                sec = data_section;
            else if (tcc_state->nocommon)
                sec = bss_section;
        }

        if (sec) {
        addr = section_add(sec, size, align);
#ifdef CONFIG_TCC_BCHECK
            /* add padding if bound check */
            if (tcc_state->do_bounds_check)
                section_add(sec, 1, 1);
#endif
        } else {
            addr = align; /* SHN_COMMON is special, symbol value is align */
        sec = common_section;
        }

        if (v) {
            if (!sym) {
                sym = sym_push(v, type, r | VT_SYM, 0);
                sym->asm_label = ad->asm_label;
            }
            /* update symbol definition */
        put_extern_sym(sym, sec, addr, size);
        } else {
            /* push global reference */
            sym = get_sym_ref(type, sec, addr, size);
        vpushsym(type, sym);
        vtop->r |= r;
        }

#ifdef CONFIG_TCC_BCHECK
        /* handles bounds now because the symbol must be defined
           before for the relocation */
        if (tcc_state->do_bounds_check) {
            addr_t *bounds_ptr;

            greloca(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR, 0);
            /* then add global bound info */
            bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(addr_t));
            bounds_ptr[0] = 0; /* relocated */
            bounds_ptr[1] = size;
        }
#endif
    }

    if (type->t & VT_VLA) {
        int a;

        /* save current stack pointer */
        if (vlas_in_scope == 0) {
            if (vla_sp_root_loc == -1)
                vla_sp_root_loc = (loc -= PTR_SIZE);
            gen_vla_sp_save(vla_sp_root_loc);
        }

        vla_runtime_type_size(type, &a);
        gen_vla_alloc(type, a);
        gen_vla_sp_save(addr);
        vla_sp_loc = addr;
        vlas_in_scope++;

    } else if (has_init) {
    size_t oldreloc_offset = 0;
    if (sec && sec->reloc)
      oldreloc_offset = sec->reloc->data_offset;
        decl_initializer(type, sec, addr, 1, 0);
    if (sec && sec->reloc)
      squeeze_multi_relocs(sec, oldreloc_offset);
        /* patch flexible array member size back to -1, */
        /* for possible subsequent similar declarations */
        if (flexible_array)
            flexible_array->type.ref->c = -1;
    }

 no_alloc:
    /* restore parse state if needed */
    if (init_str) {
        end_macro();
        restore_parse_state(&saved_parse_state);
    }
}

/* parse a function defined by symbol 'sym' and generate its code in
   'cur_text_section' */
static void gen_function(Sym *sym)
{
    nocode_wanted = 0;
    ind = cur_text_section->data_offset;
    /* NOTE: we patch the symbol size later */
    put_extern_sym(sym, cur_text_section, ind, 0);
    funcname = get_tok_str(sym->v, NULL);
    func_ind = ind;
    /* Initialize VLA state */
    vla_sp_loc = -1;
    vla_sp_root_loc = -1;
    /* put debug symbol */
    tcc_debug_funcstart(tcc_state, sym);
    /* push a dummy symbol to enable local sym storage */
    sym_push2(&local_stack, SYM_FIELD, 0, 0);
    local_scope = 1; /* for function parameters */
    gfunc_prolog(&sym->type);
    local_scope = 0;
    rsym = 0;
    block(NULL, NULL, 0);
    nocode_wanted = 0;
    gsym(rsym);
    gfunc_epilog();
    cur_text_section->data_offset = ind;
    label_pop(&global_label_stack, NULL);
    /* reset local stack */
    local_scope = 0;
    sym_pop(&local_stack, NULL, 0);
    /* end of function */
    /* patch symbol size */
    ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size = 
        ind - func_ind;
    tcc_debug_funcend(tcc_state, ind - func_ind);
    /* It's better to crash than to generate wrong code */
    cur_text_section = NULL;
    funcname = ""; /* for safety */
    func_vt.t = VT_VOID; /* for safety */
    func_var = 0; /* for safety */
    ind = 0; /* for safety */
    nocode_wanted = 1;
    check_vstack();
}

static void gen_inline_functions(TCCState *s)
{
    Sym *sym;
    int inline_generated, i, ln;
    struct InlineFunc *fn;

    ln = file->line_num;
    /* iterate while inline function are referenced */
    for(;;) {
        inline_generated = 0;
        for (i = 0; i < s->nb_inline_fns; ++i) {
            fn = s->inline_fns[i];
            sym = fn->sym;
            if (sym && sym->c) {
                /* the function was used: generate its code and
                   convert it to a normal function */
                fn->sym = NULL;
                if (file)
                    pstrcpy(file->filename, sizeof file->filename, fn->filename);
                sym->type.t &= ~VT_INLINE;

                begin_macro(fn->func_str, 1);
                next();
                cur_text_section = text_section;
                gen_function(sym);
                end_macro();

                inline_generated = 1;
            }
        }
        if (!inline_generated)
            break;
    }
    file->line_num = ln;
}

ST_FUNC void free_inline_functions(TCCState *s)
{
    int i;
    /* free tokens of unused inline functions */
    for (i = 0; i < s->nb_inline_fns; ++i) {
        struct InlineFunc *fn = s->inline_fns[i];
        if (fn->sym)
            tok_str_free(fn->func_str);
    }
    dynarray_reset(&s->inline_fns, &s->nb_inline_fns);
}

/* 'l' is VT_LOCAL or VT_CONST to define default storage type, or VT_CMP
   if parsing old style parameter decl list (and FUNC_SYM is set then) */
static int decl0(int l, int is_for_loop_init, Sym *func_sym)
{
    int v, has_init, r;
    CType type, btype;
    Sym *sym;
    AttributeDef ad;

    while (1) {
        if (!parse_btype(&btype, &ad)) {
            if (is_for_loop_init)
                return 0;
            /* skip redundant ';' if not in old parameter decl scope */
            if (tok == ';' && l != VT_CMP) {
                next();
                continue;
            }
            if (l == VT_CONST &&
                (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
                /* global asm block */
                asm_global_instr();
                continue;
            }
            /* special test for old K&R protos without explicit int
               type. Only accepted when defining global data */
            if (l != VT_CONST || tok < TOK_UIDENT)
                break;
            btype.t = VT_INT;
        }
        if (((btype.t & VT_BTYPE) == VT_ENUM ||
             (btype.t & VT_BTYPE) == VT_STRUCT) && 
            tok == ';') {
        if ((btype.t & VT_BTYPE) == VT_STRUCT) {
        int v = btype.ref->v;
        if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) >= SYM_FIRST_ANOM)
                tcc_warning("unnamed struct/union that defines no instances");
        }
            next();
            continue;
        }
        while (1) { /* iterate thru each declaration */
            type = btype;
        /* If the base type itself was an array type of unspecified
           size (like in 'typedef int arr[]; arr x = {1};') then
           we will overwrite the unknown size by the real one for
           this decl.  We need to unshare the ref symbol holding
           that size.  */
        if ((type.t & VT_ARRAY) && type.ref->c < 0) {
        type.ref = sym_push(SYM_FIELD, &type.ref->type, 0, type.ref->c);
        }
            type_decl(&type, &ad, &v, TYPE_DIRECT);
#if 0
            {
                char buf[500];
                type_to_str(buf, sizeof(buf), &type, get_tok_str(v, NULL));
                printf("type = '%s'\n", buf);
            }
#endif
            if ((type.t & VT_BTYPE) == VT_FUNC) {
                if ((type.t & VT_STATIC) && (l == VT_LOCAL)) {
                    tcc_error("function without file scope cannot be static");
                }
                /* if old style function prototype, we accept a
                   declaration list */
                sym = type.ref;
                if (sym->c == FUNC_OLD && l == VT_CONST)
                    decl0(VT_CMP, 0, sym);
            }

            if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
                ad.asm_label = asm_label_instr();
                /* parse one last attribute list, after asm label */
                parse_attribute(&ad);
                if (tok == '{')
                    expect(";");
            }

            if (ad.a.weak)
                type.t |= VT_WEAK;
#ifdef TCC_TARGET_PE
            if (ad.a.func_import || ad.a.func_export) {
                if (type.t & (VT_STATIC|VT_TYPEDEF))
                    tcc_error("cannot have dll linkage with static or typedef");
                if (ad.a.func_export)
                    type.t |= VT_EXPORT;
                else if ((type.t & VT_BTYPE) != VT_FUNC)
                    type.t |= VT_IMPORT|VT_EXTERN;
            }
#endif
        type.t |= ad.a.visibility << VT_VIS_SHIFT;

            if (tok == '{') {
                if (l != VT_CONST)
                    tcc_error("cannot use local functions");
                if ((type.t & VT_BTYPE) != VT_FUNC)
                    expect("function definition");

                /* reject abstract declarators in function definition
           make old style params without decl have int type */
                sym = type.ref;
                while ((sym = sym->next) != NULL) {
                    if (!(sym->v & ~SYM_FIELD))
                        expect("identifier");
            if (sym->type.t == VT_VOID)
                sym->type = int_type;
        }
                
                /* XXX: cannot do better now: convert extern line to static inline */
                if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
                    type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
                
                sym = sym_find(v);
                if (sym) {
                    Sym *ref;
                    if ((sym->type.t & VT_BTYPE) != VT_FUNC)
                        goto func_error1;

                    ref = sym->type.ref;

                    /* use func_call from prototype if not defined */
                    if (ref->a.func_call != FUNC_CDECL
                     && type.ref->a.func_call == FUNC_CDECL)
                        type.ref->a.func_call = ref->a.func_call;

                    /* use static from prototype */
                    if (sym->type.t & VT_STATIC)
                        type.t = (type.t & ~VT_EXTERN) | VT_STATIC;

            /* If the definition has no visibility use the
               one from prototype.  */
            if (! (type.t & VT_VIS_MASK))
                type.t |= sym->type.t & VT_VIS_MASK;

                    /* apply other storage attributes from prototype */
                    type.t |= sym->type.t & (VT_EXPORT|VT_WEAK);

                    if (!is_compatible_types(&sym->type, &type)) {
                    func_error1:
                        tcc_error("incompatible types for redefinition of '%s'", 
                              get_tok_str(v, NULL));
                    }
                    if (ref->a.func_body)
                        tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
                    /* if symbol is already defined, then put complete type */
                    sym->type = type;

                } else {
                    /* put function symbol */
                    sym = global_identifier_push(v, type.t, 0);
                    sym->type.ref = type.ref;
                }

                sym->type.ref->a.func_body = 1;
                sym->r = VT_SYM | VT_CONST;

                /* static inline functions are just recorded as a kind
                   of macro. Their code will be emitted at the end of
                   the compilation unit only if they are used */
                if ((type.t & (VT_INLINE | VT_STATIC)) == 
                    (VT_INLINE | VT_STATIC)) {
                    struct InlineFunc *fn;
                    const char *filename;
                           
                    filename = file ? file->filename : "";
                    fn = tcc_malloc(sizeof *fn + strlen(filename));
                    strcpy(fn->filename, filename);
                    fn->sym = sym;
            skip_or_save_block(&fn->func_str);
                    dynarray_add(&tcc_state->inline_fns,
                 &tcc_state->nb_inline_fns, fn);
                } else {
                    /* compute text section */
                    cur_text_section = ad.section;
                    if (!cur_text_section)
                        cur_text_section = text_section;
                    gen_function(sym);
                }
                break;
            } else {
        if (l == VT_CMP) {
            /* find parameter in function parameter list */
            for (sym = func_sym->next; sym; sym = sym->next)
            if ((sym->v & ~SYM_FIELD) == v)
                goto found;
            tcc_error("declaration for parameter '%s' but no such parameter",
                  get_tok_str(v, NULL));
found:
            if (type.t & VT_STORAGE) /* 'register' is okay */
                tcc_error("storage class specified for '%s'",
                  get_tok_str(v, NULL));
            if (sym->type.t != VT_VOID)
                tcc_error("redefinition of parameter '%s'",
                  get_tok_str(v, NULL));
            convert_parameter_type(&type);
            sym->type = type;
        } else if (type.t & VT_TYPEDEF) {
                    /* save typedefed type  */
                    /* XXX: test storage specifiers ? */
                    sym = sym_find(v);
                    if (sym && sym->scope == local_scope) {
                        if (!is_compatible_types(&sym->type, &type)
                            || !(sym->type.t & VT_TYPEDEF))
                            tcc_error("incompatible redefinition of '%s'",
                                get_tok_str(v, NULL));
                        sym->type = type;
                    } else {
                        sym = sym_push(v, &type, 0, 0);
                    }
                    sym->a = ad.a;
                } else {
                    r = 0;
                    if ((type.t & VT_BTYPE) == VT_FUNC) {
                        /* external function definition */
                        /* specific case for func_call attribute */
                        type.ref->a = ad.a;
                    } else if (!(type.t & VT_ARRAY)) {
                        /* not lvalue if array */
                        r |= lvalue_type(type.t);
                    }
                    has_init = (tok == '=');
                    if (has_init && (type.t & VT_VLA))
                        tcc_error("variable length array cannot be initialized");
                    if (((type.t & VT_EXTERN) && (!has_init || l != VT_CONST)) ||
            ((type.t & VT_BTYPE) == VT_FUNC) ||
                        ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
                         !has_init && l == VT_CONST && type.ref->c < 0)) {
                        /* external variable or function */
                        /* NOTE: as GCC, uninitialized global static
                           arrays of null size are considered as
                           extern */
                        sym = external_sym(v, &type, r);
                        sym->asm_label = ad.asm_label;
                        if (ad.alias_target) {
                            Section tsec;
                            ElfW(Sym) *esym;
                            Sym *alias_target;

                            alias_target = sym_find(ad.alias_target);
                            if (!alias_target || !alias_target->c)
                                tcc_error("unsupported forward __alias__ attribute");
                            esym = &((ElfW(Sym) *)symtab_section->data)[alias_target->c];
                            tsec.sh_num = esym->st_shndx;
                            put_extern_sym2(sym, &tsec, esym->st_value, esym->st_size, 0);
                        }
                    } else {
                        if (type.t & VT_STATIC)
                            r |= VT_CONST;
                        else
                            r |= l;
                        if (has_init)
                            next();
                        decl_initializer_alloc(&type, &ad, r, has_init, v, l);
                    }
                }
                if (tok != ',') {
                    if (is_for_loop_init)
                        return 1;
                    skip(';');
                    break;
                }
                next();
            }
            ad.a.aligned = 0;
        }
    }
    return 0;
}

ST_FUNC void decl(int l)
{
    decl0(l, 0, NULL);
}

/* ------------------------------------------------------------------------- */

https://gitlab.com/janneke/tinycc/-/blob/ff2210b308321f27ee07476d07f24b5095602b17/tccelf.c

File: ../git/live-bootstrap/sysa/tcc-0.9.26/build/tcc-0.9.26-1136-g5bba73cc/tccelf.c used in: Step 378, Step 395, Step 407, Step 419, Step 431, Step 443, Step 455
/*
 *  ELF file handling for TCC
 *
 *  Copyright (c) 2001-2004 Fabrice Bellard
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef _TCC_H
#include "tcc.h"
#endif

/* Define this to get some debug output during relocation processing.  */
#undef DEBUG_RELOC

/********************************************************/
/* global variables */

ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
ST_DATA Section *common_section;
ST_DATA Section *cur_text_section; /* current section where function code is generated */
#ifdef CONFIG_TCC_ASM
ST_DATA Section *last_text_section; /* to handle .previous asm directive */
#endif
#ifdef CONFIG_TCC_BCHECK
/* bound check related sections */
ST_DATA Section *bounds_section; /* contains global data bound description */
ST_DATA Section *lbounds_section; /* contains local data bound description */
#endif
/* symbol sections */
ST_DATA Section *symtab_section, *strtab_section;
/* debug sections */
ST_DATA Section *stab_section, *stabstr_section;

/* XXX: avoid static variable */
static int new_undef_sym = 0; /* Is there a new undefined sym since last new_undef_sym() */

/* ------------------------------------------------------------------------- */

ST_FUNC void tccelf_new(TCCState *s)
{
    /* no section zero */
    dynarray_add(&s->sections, &s->nb_sections, NULL);

    /* create standard sections */
    text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
    data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
    bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
    common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);
    common_section->sh_num = SHN_COMMON;

    /* symbols are always generated for linking stage */
    symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
                                ".strtab",
                                ".hashtab", SHF_PRIVATE);
    strtab_section = symtab_section->link;
    s->symtab = symtab_section;

    /* private symbol table for dynamic symbols */
    s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE,
                                      ".dynstrtab",
                                      ".dynhashtab", SHF_PRIVATE);
    get_sym_attr(s, 0, 1);
}

#ifdef CONFIG_TCC_BCHECK
ST_FUNC void tccelf_bounds_new(TCCState *s)
{
    /* create bounds sections */
    bounds_section = new_section(s, ".bounds",
                                 SHT_PROGBITS, SHF_ALLOC);
    lbounds_section = new_section(s, ".lbounds",
                                  SHT_PROGBITS, SHF_ALLOC);
}
#endif

ST_FUNC void tccelf_stab_new(TCCState *s)
{
    stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
    stab_section->sh_entsize = sizeof(Stab_Sym);
    stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
    put_elf_str(stabstr_section, "");
    stab_section->link = stabstr_section;
    /* put first entry */
    put_stabs("", 0, 0, 0, 0);
}

static void free_section(Section *s)
{
    tcc_free(s->data);
}

ST_FUNC void tccelf_delete(TCCState *s1)
{
    int i;

    /* free all sections */
    for(i = 1; i < s1->nb_sections; i++)
        free_section(s1->sections[i]);
    dynarray_reset(&s1->sections, &s1->nb_sections);

    for(i = 0; i < s1->nb_priv_sections; i++)
        free_section(s1->priv_sections[i]);
    dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections);

    /* free any loaded DLLs */
#ifdef TCC_IS_NATIVE
    for ( i = 0; i < s1->nb_loaded_dlls; i++) {
        DLLReference *ref = s1->loaded_dlls[i];
        if ( ref->handle )
# ifdef _WIN32
            FreeLibrary((HMODULE)ref->handle);
# else
            dlclose(ref->handle);
# endif
    }
#endif
    /* free loaded dlls array */
    dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
    tcc_free(s1->sym_attrs);
}

ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
{
    Section *sec;

    sec = tcc_mallocz(sizeof(Section) + strlen(name));
    strcpy(sec->name, name);
    sec->sh_type = sh_type;
    sec->sh_flags = sh_flags;
    switch(sh_type) {
    case SHT_HASH:
    case SHT_REL:
    case SHT_RELA:
    case SHT_DYNSYM:
    case SHT_SYMTAB:
    case SHT_DYNAMIC:
        sec->sh_addralign = 4;
        break;
    case SHT_STRTAB:
        sec->sh_addralign = 1;
        break;
    default:
        sec->sh_addralign =  PTR_SIZE; /* gcc/pcc default alignment */
        break;
    }

    if (sh_flags & SHF_PRIVATE) {
        dynarray_add(&s1->priv_sections, &s1->nb_priv_sections, sec);
    } else {
        sec->sh_num = s1->nb_sections;
        dynarray_add(&s1->sections, &s1->nb_sections, sec);
    }

    return sec;
}

ST_FUNC Section *new_symtab(TCCState *s1,
                           const char *symtab_name, int sh_type, int sh_flags,
                           const char *strtab_name,
                           const char *hash_name, int hash_sh_flags)
{
    Section *symtab, *strtab, *hash;
    int *ptr, nb_buckets;

    symtab = new_section(s1, symtab_name, sh_type, sh_flags);
    symtab->sh_entsize = sizeof(ElfW(Sym));
    strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
    put_elf_str(strtab, "");
    symtab->link = strtab;
    put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);

    nb_buckets = 1;

    hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
    hash->sh_entsize = sizeof(int);
    symtab->hash = hash;
    hash->link = symtab;

    ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
    ptr[0] = nb_buckets;
    ptr[1] = 1;
    memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
    return symtab;
}

/* realloc section and set its content to zero */
ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
{
    unsigned long size;
    unsigned char *data;

    size = sec->data_allocated;
    if (size == 0)
        size = 1;
    while (size < new_size)
        size = size * 2;
    data = tcc_realloc(sec->data, size);
    memset(data + sec->data_allocated, 0, size - sec->data_allocated);
    sec->data = data;
    sec->data_allocated = size;
}

/* reserve at least 'size' bytes aligned per 'align' in section
   'sec' from current offset, and return the aligned offset */
ST_FUNC size_t section_add(Section *sec, addr_t size, int align)
{
    size_t offset, offset1;

    offset = (sec->data_offset + align - 1) & -align;
    offset1 = offset + size;
    if (sec->sh_type != SHT_NOBITS && offset1 > sec->data_allocated)
        section_realloc(sec, offset1);
    sec->data_offset = offset1;
    if (align > sec->sh_addralign)
        sec->sh_addralign = align;
    return offset;
}

/* reserve at least 'size' bytes in section 'sec' from
   sec->data_offset. */
ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
{
    size_t offset = section_add(sec, size, 1);
    return sec->data + offset;
}

/* reserve at least 'size' bytes from section start */
ST_FUNC void section_reserve(Section *sec, unsigned long size)
{
    if (size > sec->data_allocated)
        section_realloc(sec, size);
    if (size > sec->data_offset)
        sec->data_offset = size;
}

/* return a reference to a section, and create it if it does not
   exists */
ST_FUNC Section *find_section(TCCState *s1, const char *name)
{
    Section *sec;
    int i;
    for(i = 1; i < s1->nb_sections; i++) {
        sec = s1->sections[i];
        if (!strcmp(name, sec->name))
            return sec;
    }
    /* sections are created as PROGBITS */
    return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
}

/* ------------------------------------------------------------------------- */

ST_FUNC int put_elf_str(Section *s, const char *sym)
{
    int offset, len;
    char *ptr;

    len = strlen(sym) + 1;
    offset = s->data_offset;
    ptr = section_ptr_add(s, len);
    memcpy(ptr, sym, len);
    return offset;
}

/* elf symbol hashing function */
static unsigned long elf_hash(const unsigned char *name)
{
    unsigned long h = 0, g;

    while (*name) {
        h = (h << 4) + *name++;
        g = h & 0xf0000000;
        if (g)
            h ^= g >> 24;
        h &= ~g;
    }
    return h;
}

/* rebuild hash table of section s */
/* NOTE: we do factorize the hash table code to go faster */
static void rebuild_hash(Section *s, unsigned int nb_buckets)
{
    ElfW(Sym) *sym;
    int *ptr, *hash, nb_syms, sym_index, h;
    unsigned char *strtab;

    strtab = s->link->data;
    nb_syms = s->data_offset / sizeof(ElfW(Sym));

    s->hash->data_offset = 0;
    ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
    ptr[0] = nb_buckets;
    ptr[1] = nb_syms;
    ptr += 2;
    hash = ptr;
    memset(hash, 0, (nb_buckets + 1) * sizeof(int));
    ptr += nb_buckets + 1;

    sym = (ElfW(Sym) *)s->data + 1;
    for(sym_index = 1; sym_index < nb_syms; sym_index++) {
        if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
#if !BOOTSTRAP
            h = elf_hash(strtab + sym->st_name) % nb_buckets;
#else
            h = elf_hash(strtab + sym->st_name);
            h = h % nb_buckets;
#endif
            *ptr = hash[h];
            hash[h] = sym_index;
        } else {
            *ptr = 0;
        }
        ptr++;
        sym++;
    }
}

/* return the symbol number */
ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
    int info, int other, int shndx, const char *name)
{
    int name_offset, sym_index;
    int nbuckets, h;
    ElfW(Sym) *sym;
    Section *hs;

    sym = section_ptr_add(s, sizeof(ElfW(Sym)));
    if (name)
        name_offset = put_elf_str(s->link, name);
    else
        name_offset = 0;
    /* XXX: endianness */
    sym->st_name = name_offset;
    sym->st_value = value;
    sym->st_size = size;
    sym->st_info = info;
    sym->st_other = other;
    sym->st_shndx = shndx;
    sym_index = sym - (ElfW(Sym) *)s->data;
    hs = s->hash;
    if (hs) {
        int *ptr, *base;
        ptr = section_ptr_add(hs, sizeof(int));
        base = (int *)hs->data;
        /* only add global or weak symbols */
        if (ELFW(ST_BIND)(info) != STB_LOCAL) {
            /* add another hashing entry */
            nbuckets = base[0];
#if !BOOTSTRAP
            h = elf_hash((unsigned char *) name) % nbuckets;
#else
            h = elf_hash((unsigned char *) name);
            h = h % nbuckets;
#endif
            *ptr = base[2 + h];
            base[2 + h] = sym_index;
            base[1]++;
            /* we resize the hash table */
            hs->nb_hashed_syms++;
            if (hs->nb_hashed_syms > 2 * nbuckets) {
                rebuild_hash(s, 2 * nbuckets);
            }
        } else {
            *ptr = 0;
            base[1]++;
        }
    }
    return sym_index;
}

/* find global ELF symbol 'name' and return its index. Return 0 if not
   found. */
ST_FUNC int find_elf_sym(Section *s, const char *name)
{
    ElfW(Sym) *sym;
    Section *hs;
    int nbuckets, sym_index, h;
    const char *name1;

    hs = s->hash;
    if (!hs)
        return 0;
    nbuckets = ((int *)hs->data)[0];
#if !BOOTSTRAP
    h = elf_hash((unsigned char *) name) % nbuckets;
#else
    h = elf_hash((unsigned char *) name);
    h = h % nbuckets;
#endif
    sym_index = ((int *)hs->data)[2 + h];
    while (sym_index != 0) {
        sym = &((ElfW(Sym) *)s->data)[sym_index];
        name1 = (char *) s->link->data + sym->st_name;
        if (!strcmp(name, name1))
            return sym_index;
        sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
    }
    return 0;
}

/* return elf symbol value, signal error if 'err' is nonzero */
ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err)
{
    int sym_index;
    ElfW(Sym) *sym;

    sym_index = find_elf_sym(s->symtab, name);
    sym = &((ElfW(Sym) *)s->symtab->data)[sym_index];
    if (!sym_index || sym->st_shndx == SHN_UNDEF) {
        if (err)
            tcc_error("%s not defined", name);
        return 0;
    }
    return sym->st_value;
}

#if __MESC_MES__ || !__MESC__
#if !defined (__intptr_t_defined) && !defined (__MES_INTPTR_T)
typedef unsigned long uintptr_t;
#endif
#else // guile
#undef uintptr_t
#endif

/* return elf symbol value */
LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
{
    return (void*)(uintptr_t)get_elf_sym_addr(s, name, 0);
}

#if defined TCC_IS_NATIVE || defined TCC_TARGET_PE
/* return elf symbol value or error */
ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name)
{
    return (void*)(uintptr_t)get_elf_sym_addr(s, name, 1);
}
#endif

/* add an elf symbol : check if it is already defined and patch
   it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
                       int info, int other, int shndx, const char *name)
{
    ElfW(Sym) *esym;
    int sym_bind, sym_index, sym_type, esym_bind;
    unsigned char sym_vis, esym_vis, new_vis;

    sym_bind = ELFW(ST_BIND)(info);
    sym_type = ELFW(ST_TYPE)(info);
    sym_vis = ELFW(ST_VISIBILITY)(other);

    sym_index = find_elf_sym(s, name);
    esym = &((ElfW(Sym) *)s->data)[sym_index];
    if (sym_index && esym->st_value == value && esym->st_size == size
    && esym->st_info == info && esym->st_other == other
    && esym->st_shndx == shndx)
        return sym_index;

    if (sym_bind != STB_LOCAL) {
        /* we search global or weak symbols */
        if (!sym_index)
            goto do_def;
        if (esym->st_shndx != SHN_UNDEF) {
            esym_bind = ELFW(ST_BIND)(esym->st_info);
            /* propagate the most constraining visibility */
            /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
            esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
            if (esym_vis == STV_DEFAULT) {
                new_vis = sym_vis;
            } else if (sym_vis == STV_DEFAULT) {
                new_vis = esym_vis;
            } else {
                new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
            }
            esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
                             | new_vis;
            other = esym->st_other; /* in case we have to patch esym */
            if (shndx == SHN_UNDEF) {
                /* ignore adding of undefined symbol if the
                   corresponding symbol is already defined */
            } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
                /* global overrides weak, so patch */
                goto do_patch;
            } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
                /* weak is ignored if already global */
            } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
                /* keep first-found weak definition, ignore subsequents */
            } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
                /* ignore hidden symbols after */
            } else if ((esym->st_shndx == SHN_COMMON
                            || esym->st_shndx == bss_section->sh_num)
                        && (shndx < SHN_LORESERVE
                            && shndx != bss_section->sh_num)) {
                /* data symbol gets precedence over common/bss */
                goto do_patch;
            } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
                /* data symbol keeps precedence over common/bss */
            } else if (s == tcc_state->dynsymtab_section) {
                /* we accept that two DLL define the same symbol */
            } else {
#if 0
                printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
                       sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis);
#endif
                tcc_error_noabort("'%s' defined twice", name);
            }
        } else {
        do_patch:
            esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
            esym->st_shndx = shndx;
            new_undef_sym = 1;
            esym->st_value = value;
            esym->st_size = size;
            esym->st_other = other;
        }
    } else {
    do_def:
        sym_index = put_elf_sym(s, value, size,
                                ELFW(ST_INFO)(sym_bind, sym_type), other,
                                shndx, name);
    }
    return sym_index;
}

/* put relocation */
ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
                            int type, int symbol, addr_t addend)
{
    char buf[256];
    Section *sr;
    ElfW_Rel *rel;

    sr = s->reloc;
    if (!sr) {
        /* if no relocation section, create it */
        snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
        /* if the symtab is allocated, then we consider the relocation
           are also */
        sr = new_section(tcc_state, buf, SHT_RELX, symtab->sh_flags);
        sr->sh_entsize = sizeof(ElfW_Rel);
        sr->link = symtab;
        sr->sh_info = s->sh_num;
        s->reloc = sr;
    }
    rel = section_ptr_add(sr, sizeof(ElfW_Rel));
    rel->r_offset = offset;
    rel->r_info = ELFW(R_INFO)(symbol, type);
#if SHT_RELX == SHT_RELA
    rel->r_addend = addend;
#else
    if (addend)
        tcc_error("non-zero addend on REL architecture");
#endif
}

ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
                           int type, int symbol)
{
    put_elf_reloca(symtab, s, offset, type, symbol, 0);
}

/* Remove relocations for section S->reloc starting at oldrelocoffset
   that are to the same place, retaining the last of them.  As side effect
   the relocations are sorted.  Possibly reduces the number of relocs.  */
ST_FUNC void squeeze_multi_relocs(Section *s, size_t oldrelocoffset)
{
    Section *sr = s->reloc;
    ElfW_Rel *r, *dest;
    ssize_t a;
    ElfW(Addr) addr;

    if (oldrelocoffset + sizeof(*r) >= sr->data_offset)
      return;
    /* The relocs we're dealing with are the result of initializer parsing.
       So they will be mostly in order and there aren't many of them.
       Secondly we need a stable sort (which qsort isn't).  We use
       a simple insertion sort.  */
    for (a = oldrelocoffset + sizeof(*r); a < sr->data_offset; a += sizeof(*r)) {
    ssize_t i = a - sizeof(*r);
    ///addr = ((ElfW_Rel*)(sr->data + a))->r_offset;
    ElfW_Rel* ea = (ElfW_Rel*)(sr->data + a);
    ElfW_Rel* ei = (ElfW_Rel*)(sr->data + i);
    addr = ea->r_offset;
    for (; i >= (ssize_t)oldrelocoffset &&
               ei->r_offset > addr; i -= sizeof(*r)) {
            ei = (ElfW_Rel*)(sr->data + i);
        ElfW_Rel tmp = *(ElfW_Rel*)(sr->data + a);
        *(ElfW_Rel*)(sr->data + a) = *(ElfW_Rel*)(sr->data + i);
        *(ElfW_Rel*)(sr->data + i) = tmp;
    }
    }

    r = (ElfW_Rel*)(sr->data + oldrelocoffset);
    dest = r;
    for (; r < (ElfW_Rel*)(sr->data + sr->data_offset); r++) {
    if (dest->r_offset != r->r_offset)
      dest++;
    *dest = *r;
    }
    sr->data_offset = (unsigned char*)dest - sr->data + sizeof(*r);
}

/* put stab debug information */

ST_FUNC void put_stabs(const char *str, int type, int other, int desc,
                      unsigned long value)
{
    Stab_Sym *sym;

    sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
    if (str) {
        sym->n_strx = put_elf_str(stabstr_section, str);
    } else {
        sym->n_strx = 0;
    }
    sym->n_type = type;
    sym->n_other = other;
    sym->n_desc = desc;
    sym->n_value = value;
}

ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc,
                        unsigned long value, Section *sec, int sym_index)
{
    put_stabs(str, type, other, desc, value);
    put_elf_reloc(symtab_section, stab_section,
                  stab_section->data_offset - sizeof(unsigned int),
                  R_DATA_32, sym_index);
}

ST_FUNC void put_stabn(int type, int other, int desc, int value)
{
    put_stabs(NULL, type, other, desc, value);
}

ST_FUNC void put_stabd(int type, int other, int desc)
{
    put_stabs(NULL, type, other, desc, 0);
}

ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc)
{
    int n;
    struct sym_attr *tab;

    if (index >= s1->nb_sym_attrs) {
        if (!alloc)
            return s1->sym_attrs;
        /* find immediately bigger power of 2 and reallocate array */
        n = 1;
        while (index >= n)
            n *= 2;
        tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
        s1->sym_attrs = tab;
        memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
               (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
        s1->nb_sym_attrs = n;
    }
    return &s1->sym_attrs[index];
}

/* Browse each elem of type <type> in section <sec> starting at elem <startoff>
   using variable <elem> */
#define for_each_elem(sec, startoff, elem, type) \
    for (elem = (type *) sec->data + startoff; \
         elem < (type *) (sec->data + sec->data_offset); elem++)

/* In an ELF file symbol table, the local symbols must appear below
   the global and weak ones. Since TCC cannot sort it while generating
   the code, we must do it after. All the relocation tables are also
   modified to take into account the symbol table sorting */
static void sort_syms(TCCState *s1, Section *s)
{
    int *old_to_new_syms;
    ElfW(Sym) *new_syms;
    int nb_syms, i;
    ElfW(Sym) *p, *q;
    ElfW_Rel *rel;
    Section *sr;
    int type, sym_index;

    nb_syms = s->data_offset / sizeof(ElfW(Sym));
    new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
    old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));

    /* first pass for local symbols */
    p = (ElfW(Sym) *)s->data;
    q = new_syms;
    for(i = 0; i < nb_syms; i++) {
        if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
            old_to_new_syms[i] = q - new_syms;
            *q++ = *p;
        }
        p++;
    }
    /* save the number of local symbols in section header */
    s->sh_info = q - new_syms;

    /* then second pass for non local symbols */
    p = (ElfW(Sym) *)s->data;
    for(i = 0; i < nb_syms; i++) {
        if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
            old_to_new_syms[i] = q - new_syms;
            *q++ = *p;
        }
        p++;
    }

    /* we copy the new symbols to the old */
    memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
    tcc_free(new_syms);

    /* now we modify all the relocations */
    for(i = 1; i < s1->nb_sections; i++) {
        sr = s1->sections[i];
        if (sr->sh_type == SHT_RELX && sr->link == s) {
            for_each_elem(sr, 0, rel, ElfW_Rel) {
                sym_index = ELFW(R_SYM)(rel->r_info);
                type = ELFW(R_TYPE)(rel->r_info);
                sym_index = old_to_new_syms[sym_index];
                rel->r_info = ELFW(R_INFO)(sym_index, type);
            }
        }
    }

    tcc_free(old_to_new_syms);
}

/* relocate common symbols in the .bss section */
ST_FUNC void relocate_common_syms(void)
{
    ElfW(Sym) *sym;

    for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
        if (sym->st_shndx == SHN_COMMON) {
            /* symbol alignment is in st_value for SHN_COMMONs */
        sym->st_value = section_add(bss_section, sym->st_size,
                    sym->st_value);
            sym->st_shndx = bss_section->sh_num;
        }
    }
}

/* relocate symbol table, resolve undefined symbols if do_resolve is
   true and output error if undefined symbol. */
ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
{
    ElfW(Sym) *sym;
    int sym_bind, sh_num;
    const char *name;

    for_each_elem(symtab, 1, sym, ElfW(Sym)) {
        sh_num = sym->st_shndx;
        if (sh_num == SHN_UNDEF) {
            name = (char *) strtab_section->data + sym->st_name;
            /* Use ld.so to resolve symbol for us (for tcc -run) */
            if (do_resolve) {
#if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
                void *addr = dlsym(RTLD_DEFAULT, name);
                if (addr) {
                    sym->st_value = (addr_t) addr;
#ifdef DEBUG_RELOC
            printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
#endif
                    goto found;
                }
#endif
            /* if dynamic symbol exist, it will be used in relocate_section */
            } else if (s1->dynsym && find_elf_sym(s1->dynsym, name))
                goto found;
            /* XXX: _fp_hw seems to be part of the ABI, so we ignore
               it */
            if (!strcmp(name, "_fp_hw"))
                goto found;
            /* only weak symbols are accepted to be undefined. Their
               value is zero */
            sym_bind = ELFW(ST_BIND)(sym->st_info);
            if (sym_bind == STB_WEAK)
                sym->st_value = 0;
            else
                tcc_error_noabort("undefined symbol '%s'", name);
        } else if (sh_num < SHN_LORESERVE) {
            /* add section base */
            sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
        }
    found: ;
    }
}

/* relocate a given section (CPU dependent) by applying the relocations
   in the associated relocation section */
ST_FUNC void relocate_section(TCCState *s1, Section *s)
{
    Section *sr = s->reloc;
    ElfW_Rel *rel;
    ElfW(Sym) *sym;
    int type, sym_index;
    unsigned char *ptr;
    addr_t tgt, addr;

    relocate_init(sr);

    for_each_elem(sr, 0, rel, ElfW_Rel) {
        ptr = s->data + rel->r_offset;
        sym_index = ELFW(R_SYM)(rel->r_info);
        sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
        type = ELFW(R_TYPE)(rel->r_info);
        tgt = sym->st_value;
#if SHT_RELX == SHT_RELA
        tgt += rel->r_addend;
#endif
        addr = s->sh_addr + rel->r_offset;
        relocate(s1, rel, type, ptr, addr, tgt);
    }
    /* if the relocation is allocated, we change its symbol table */
    if (sr->sh_flags & SHF_ALLOC)
        sr->link = s1->dynsym;
}

/* relocate relocation table in 'sr' */
static void relocate_rel(TCCState *s1, Section *sr)
{
    Section *s;
    ElfW_Rel *rel;

    s = s1->sections[sr->sh_info];
    for_each_elem(sr, 0, rel, ElfW_Rel)
        rel->r_offset += s->sh_addr;
}

/* count the number of dynamic relocations so that we can reserve
   their space */
static int prepare_dynamic_rel(TCCState *s1, Section *sr)
{
    ElfW_Rel *rel;
    int sym_index, type, count;

    count = 0;
    for_each_elem(sr, 0, rel, ElfW_Rel) {
        sym_index = ELFW(R_SYM)(rel->r_info);
        type = ELFW(R_TYPE)(rel->r_info);
        switch(type) {
#if defined(TCC_TARGET_I386)
        case R_386_32:
#elif defined(TCC_TARGET_X86_64)
        case R_X86_64_32:
        case R_X86_64_32S:
        case R_X86_64_64:
#endif
            count++;
            break;
#if defined(TCC_TARGET_I386)
        case R_386_PC32:
#elif defined(TCC_TARGET_X86_64)
        case R_X86_64_PC32:
#endif
            if (get_sym_attr(s1, sym_index, 0)->dyn_index)
                count++;
            break;
        default:
            break;
        }
    }
    if (count) {
        /* allocate the section */
        sr->sh_flags |= SHF_ALLOC;
        sr->sh_size = count * sizeof(ElfW_Rel);
    }
    return count;
}

static void build_got(TCCState *s1)
{
    /* if no got, then create it */
    s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
    s1->got->sh_entsize = 4;
    set_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
                0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
    /* keep space for _DYNAMIC pointer and two dummy got entries */
    section_ptr_add(s1->got, 3 * PTR_SIZE);
}

/* Create a GOT and (for function call) a PLT entry corresponding to a symbol
   in s1->symtab. When creating the dynamic symbol table entry for the GOT
   relocation, use 'size' and 'info' for the corresponding symbol metadata.
   Returns the offset of the GOT or (if any) PLT entry. */
static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
                                       unsigned long size,
                                       int info, int sym_index)
{
    int need_plt_entry;
    const char *name;
    ElfW(Sym) *sym;
    struct sym_attr *attr;
    unsigned got_offset;
    char plt_name[100];
    int len;

    need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
    attr = get_sym_attr(s1, sym_index, 1);

    /* In case a function is both called and its address taken 2 GOT entries
       are created, one for taking the address (GOT) and the other for the PLT
       entry (PLTGOT).  */
    if (need_plt_entry ? attr->plt_offset : attr->got_offset)
        return attr;

    /* create the GOT entry */
    got_offset = s1->got->data_offset;
    section_ptr_add(s1->got, PTR_SIZE);

    /* Create the GOT relocation that will insert the address of the object or
       function of interest in the GOT entry. This is a static relocation for
       memory output (dlsym will give us the address of symbols) and dynamic
       relocation otherwise (executable and DLLs). The relocation should be
       done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
       associated to a PLT entry) but is currently done at load time for an
       unknown reason. */

    sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
    name = (char *) symtab_section->link->data + sym->st_name;

    if (s1->dynsym) {
    if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
        /* Hack alarm.  We don't want to emit dynamic symbols
           and symbol based relocs for STB_LOCAL symbols, but rather
           want to resolve them directly.  At this point the symbol
           values aren't final yet, so we must defer this.  We will later
           have to create a RELATIVE reloc anyway, so we misuse the
           relocation slot to smuggle the symbol reference until
           fill_local_got_entries.  Not that the sym_index is
           relative to symtab_section, not s1->dynsym!  Nevertheless
           we use s1->dyn_sym so that if this is the first call
           that got->reloc is correctly created.  Also note that
           RELATIVE relocs are not normally created for the .got,
           so the types serves as a marker for later (and is retained
           also for the final output, which is okay because then the
           got is just normal data).  */
        put_elf_reloc(s1->dynsym, s1->got, got_offset, R_RELATIVE,
              sym_index);
    } else {
        if (0 == attr->dyn_index)
                attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value, size,
                          info, 0, sym->st_shndx, name);
        put_elf_reloc(s1->dynsym, s1->got, got_offset, dyn_reloc_type,
              attr->dyn_index);
    }
    } else {
        put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
                      sym_index);
    }

    if (need_plt_entry) {
        if (!s1->plt) {
            s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
                          SHF_ALLOC | SHF_EXECINSTR);
            s1->plt->sh_entsize = 4;
        }

        attr->plt_offset = create_plt_entry(s1, got_offset, attr);

        /* create a symbol 'sym@plt' for the PLT jump vector */
        len = strlen(name);
        if (len > sizeof plt_name - 5)
            len = sizeof plt_name - 5;
        memcpy(plt_name, name, len);
        strcpy(plt_name + len, "@plt");
        attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, sym->st_size,
            ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name);

    } else {
        attr->got_offset = got_offset;
    }

    return attr;
}

/* build GOT and PLT entries */
ST_FUNC void build_got_entries(TCCState *s1)
{
    Section *s;
    ElfW_Rel *rel;
    ElfW(Sym) *sym;
    int i, type, gotplt_entry, reloc_type, sym_index;
    struct sym_attr *attr;

    for(i = 1; i < s1->nb_sections; i++) {
        s = s1->sections[i];
        if (s->sh_type != SHT_RELX)
            continue;
        /* no need to handle got relocations */
        if (s->link != symtab_section)
            continue;
        for_each_elem(s, 0, rel, ElfW_Rel) {
            type = ELFW(R_TYPE)(rel->r_info);
            gotplt_entry = gotplt_entry_type(type);
            sym_index = ELFW(R_SYM)(rel->r_info);
            sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];

            if (gotplt_entry == NO_GOTPLT_ENTRY) {
                continue;
            }

            /* Automatically create PLT/GOT [entry] if it is an undefined
           reference (resolved at runtime), or the symbol is absolute,
           probably created by tcc_add_symbol, and thus on 64-bit
           targets might be too far from application code.  */
            if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
                if (sym->st_shndx == SHN_UNDEF) {
                    ElfW(Sym) *esym;
            int dynindex;
                    if (s1->output_type == TCC_OUTPUT_DLL && ! PCRELATIVE_DLLPLT)
                        continue;
            /* Relocations for UNDEF symbols would normally need
               to be transferred into the executable or shared object.
               If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
               But TCC doesn't do that (at least for exes), so we
               need to resolve all such relocs locally.  And that
               means PLT slots for functions in DLLs and COPY relocs for
               data symbols.  COPY relocs were generated in
               bind_exe_dynsyms (and the symbol adjusted to be defined),
               and for functions we were generated a dynamic symbol
               of function type.  */
            if (s1->dynsym) {
            /* dynsym isn't set for -run :-/  */
            dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
            esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
            if (dynindex
                && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
                || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
                    && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
                goto jmp_slot;
            }
                } else if (!(sym->st_shndx == SHN_ABS
#ifndef TCC_TARGET_ARM
            && PTR_SIZE == 8
#endif
            ))
                    continue;
            }

#ifdef TCC_TARGET_X86_64
            if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
                (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
         ELFW(ST_BIND)(sym->st_info) == STB_LOCAL)) {
                rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
                continue;
            }
#endif
            if (code_reloc(type)) {
            jmp_slot:
                reloc_type = R_JMP_SLOT;
            } else
                reloc_type = R_GLOB_DAT;

            if (!s1->got)
                build_got(s1);

            if (gotplt_entry == BUILD_GOT_ONLY)
                continue;

            attr = put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
                                 sym_index);

            if (reloc_type == R_JMP_SLOT)
                rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
        }
    }
}

/* put dynamic tag */
static void put_dt(Section *dynamic, int dt, addr_t val)
{
    ElfW(Dyn) *dyn;
    dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
    dyn->d_tag = dt;
    dyn->d_un.d_val = val;
}

#ifndef TCC_TARGET_PE
static void add_init_array_defines(TCCState *s1, const char *section_name)
{
    Section *s;
    long end_offset;
    char sym_start[1024];
    char sym_end[1024];

    snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
    snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);

    s = find_section(s1, section_name);
    if (!s) {
        end_offset = 0;
        s = data_section;
    } else {
        end_offset = s->data_offset;
    }

    set_elf_sym(symtab_section,
                0, 0,
                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
                s->sh_num, sym_start);
    set_elf_sym(symtab_section,
                end_offset, 0,
                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
                s->sh_num, sym_end);
}
#endif

static int tcc_add_support(TCCState *s1, const char *filename)
{
    char buf[1024];
    snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, filename);
    return tcc_add_file(s1, buf);
}

ST_FUNC void tcc_add_bcheck(TCCState *s1)
{
#ifdef CONFIG_TCC_BCHECK
    addr_t *ptr;
    int sym_index;

    if (0 == s1->do_bounds_check)
        return;
    /* XXX: add an object file to do that */
    ptr = section_ptr_add(bounds_section, sizeof(*ptr));
    *ptr = 0;
    set_elf_sym(symtab_section, 0, 0,
                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
                bounds_section->sh_num, "__bounds_start");
    /* pull bcheck.o from libtcc1.a */
    sym_index = set_elf_sym(symtab_section, 0, 0,
                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
                SHN_UNDEF, "__bound_init");
    if (s1->output_type != TCC_OUTPUT_MEMORY) {
        /* add 'call __bound_init()' in .init section */
        Section *init_section = find_section(s1, ".init");
        unsigned char *pinit = section_ptr_add(init_section, 5);
        pinit[0] = 0xe8;
        write32le(pinit + 1, -4);
        put_elf_reloc(symtab_section, init_section,
            init_section->data_offset - 4, R_386_PC32, sym_index);
            /* R_386_PC32 = R_X86_64_PC32 = 2 */
    }
#endif
}

/* add tcc runtime libraries */
ST_FUNC void tcc_add_runtime(TCCState *s1)
{
    tcc_add_bcheck(s1);
    tcc_add_pragma_libs(s1);
    /* add libc */
    if (!s1->nostdlib) {
        tcc_add_library_err(s1, "c");
#ifdef TCC_LIBGCC
        if (!s1->static_link) {
            if (TCC_LIBGCC[0] == '/')
                tcc_add_file(s1, TCC_LIBGCC);
            else
                tcc_add_dll(s1, TCC_LIBGCC, 0);
        }
#endif
        tcc_add_support(s1, TCC_LIBTCC1);
#if CONFIG_TCC_LIBTCC1_MES
        tcc_add_support(s1, TCC_LIBTCC1_MES);
#endif
        /* add crt end if not memory output */
        if (s1->output_type != TCC_OUTPUT_MEMORY)
            tcc_add_crt(s1, "crtn.o");
    }
}

/* add various standard linker symbols (must be done after the
   sections are filled (for example after allocating common
   symbols)) */
ST_FUNC void tcc_add_linker_symbols(TCCState *s1)
{
    char buf[1024];
    int i;
    Section *s;

    set_elf_sym(symtab_section,
                text_section->data_offset, 0,
                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
                text_section->sh_num, "_etext");
    set_elf_sym(symtab_section,
                data_section->data_offset, 0,
                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
                data_section->sh_num, "_edata");
    set_elf_sym(symtab_section,
                bss_section->data_offset, 0,
                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
                bss_section->sh_num, "_end");
#ifndef TCC_TARGET_PE
    /* horrible new standard ldscript defines */
    add_init_array_defines(s1, ".preinit_array");
    add_init_array_defines(s1, ".init_array");
    add_init_array_defines(s1, ".fini_array");
#endif

    /* add start and stop symbols for sections whose name can be
       expressed in C */
    for(i = 1; i < s1->nb_sections; i++) {
        s = s1->sections[i];
        if (s->sh_type == SHT_PROGBITS &&
            (s->sh_flags & SHF_ALLOC)) {
            const char *p;
            int ch;

            /* check if section name can be expressed in C */
            p = s->name;
            for(;;) {
                ch = *p;
                if (!ch)
                    break;
                if (!isid(ch) && !isnum(ch))
                    goto next_sec;
                p++;
            }
            snprintf(buf, sizeof(buf), "__start_%s", s->name);
            set_elf_sym(symtab_section,
                        0, 0,
                        ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
                        s->sh_num, buf);
            snprintf(buf, sizeof(buf), "__stop_%s", s->name);
            set_elf_sym(symtab_section,
                        s->data_offset, 0,
                        ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
                        s->sh_num, buf);
        }
    next_sec: ;
    }
}

static void tcc_output_binary(TCCState *s1, FILE *f,
                              const int *sec_order)
{
    Section *s;
    int i, offset, size;

    offset = 0;
    for(i=1;i<s1->nb_sections;i++) {
        s = s1->sections[sec_order[i]];
        if (s->sh_type != SHT_NOBITS &&
            (s->sh_flags & SHF_ALLOC)) {
            while (offset < s->sh_offset) {
                fputc(0, f);
                offset++;
            }
            size = s->sh_size;
            fwrite(s->data, 1, size, f);
            offset += size;
        }
    }
}

#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
#define HAVE_PHDR       1
#define EXTRA_RELITEMS  14
#else
#define HAVE_PHDR      1
#define EXTRA_RELITEMS 9
#endif

ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
{
    int sym_index = ELFW(R_SYM) (rel->r_info);
    ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
    struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
    unsigned offset = attr->got_offset;

    if (0 == offset)
        return;
    section_reserve(s1->got, offset + PTR_SIZE);
#ifdef TCC_TARGET_X86_64
    write64le(s1->got->data + offset, sym->st_value);
#else
    write32le(s1->got->data + offset, sym->st_value);
#endif
}

/* Perform relocation to GOT or PLT entries */
ST_FUNC void fill_got(TCCState *s1)
{
    Section *s;
    ElfW_Rel *rel;
    int i;

    for(i = 1; i < s1->nb_sections; i++) {
        s = s1->sections[i];
        if (s->sh_type != SHT_RELX)
            continue;
        /* no need to handle got relocations */
        if (s->link != symtab_section)
            continue;
        for_each_elem(s, 0, rel, ElfW_Rel) {
            switch (ELFW(R_TYPE) (rel->r_info)) {
                case R_X86_64_GOT32:
                case R_X86_64_GOTPCREL:
        case R_X86_64_GOTPCRELX:
        case R_X86_64_REX_GOTPCRELX:
                case R_X86_64_PLT32:
                    fill_got_entry(s1, rel);
                    break;
            }
        }
    }
}

/* See put_got_entry for a description.  This is the second stage
   where GOT references to local defined symbols are rewritten.  */
static void fill_local_got_entries(TCCState *s1)
{
    ElfW_Rel *rel;
    for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
    if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
        int sym_index = ELFW(R_SYM) (rel->r_info);
        ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
        struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
        unsigned offset = attr->got_offset;
        if (offset != rel->r_offset - s1->got->sh_addr)
          tcc_error_noabort("huh");
        rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
#if SHT_RELX == SHT_RELA
        rel->r_addend = sym->st_value;
#else
        /* All our REL architectures also happen to be 32bit LE.  */
        write32le(s1->got->data + offset, sym->st_value);
#endif
    }
    }
}

/* Bind symbols of executable: resolve undefined symbols from exported symbols
   in shared libraries and export non local defined symbols to shared libraries
   if -rdynamic switch was given on command line */
static void bind_exe_dynsyms(TCCState *s1)
{
    const char *name;
    int sym_index, index;
    ElfW(Sym) *sym, *esym;
    int type;

    /* Resolve undefined symbols from dynamic symbols. When there is a match:
       - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
       - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
    for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
        if (sym->st_shndx == SHN_UNDEF) {
            name = (char *) symtab_section->link->data + sym->st_name;
            sym_index = find_elf_sym(s1->dynsymtab_section, name);
            if (sym_index) {
                esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
                type = ELFW(ST_TYPE)(esym->st_info);
                if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
                    /* Indirect functions shall have STT_FUNC type in executable
                     * dynsym section. Indeed, a dlsym call following a lazy
                     * resolution would pick the symbol value from the
                     * executable dynsym entry which would contain the address
                     * of the function wanted by the caller of dlsym instead of
                     * the address of the function that would return that
                     * address */
                    int dynindex
              = put_elf_sym(s1->dynsym, 0, esym->st_size,
                    ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
                    name);
            int index = sym - (ElfW(Sym) *) symtab_section->data;
            get_sym_attr(s1, index, 1)->dyn_index = dynindex;
                } else if (type == STT_OBJECT) {
                    unsigned long offset;
                    ElfW(Sym) *dynsym;
                    offset = bss_section->data_offset;
                    /* XXX: which alignment ? */
                    offset = (offset + 16 - 1) & -16;
                    set_elf_sym (s1->symtab, offset, esym->st_size,
                                 esym->st_info, 0, bss_section->sh_num, name);
                    index = put_elf_sym(s1->dynsym, offset, esym->st_size,
                                        esym->st_info, 0, bss_section->sh_num,
                                        name);

                    /* Ensure R_COPY works for weak symbol aliases */
                    if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
                        for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
                            if ((dynsym->st_value == esym->st_value)
                                && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
                                char *dynname = (char *) s1->dynsymtab_section->link->data
                                                + dynsym->st_name;
                                put_elf_sym(s1->dynsym, offset, dynsym->st_size,
                                            dynsym->st_info, 0,
                                            bss_section->sh_num, dynname);
                                break;
                            }
                        }
                    }

                    put_elf_reloc(s1->dynsym, bss_section,
                                  offset, R_COPY, index);
                    offset += esym->st_size;
                    bss_section->data_offset = offset;
                }
            } else {
                /* STB_WEAK undefined symbols are accepted */
                /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
                if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
                    !strcmp(name, "_fp_hw")) {
                } else {
                    tcc_error_noabort("undefined symbol '%s'", name);
                }
            }
        } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
            /* if -rdynamic option, then export all non local symbols */
            name = (char *) symtab_section->link->data + sym->st_name;
            set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
                        0, sym->st_shndx, name);
        }
    }
}

/* Bind symbols of libraries: export all non local symbols of executable that
   are referenced by shared libraries. The reason is that the dynamic loader
   search symbol first in executable and then in libraries. Therefore a
   reference to a symbol already defined by a library can still be resolved by
   a symbol in the executable. */
static void bind_libs_dynsyms(TCCState *s1)
{
    const char *name;
    int sym_index;
    ElfW(Sym) *sym, *esym;

    for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
        name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
        sym_index = find_elf_sym(symtab_section, name);
        /* XXX: avoid adding a symbol if already present because of
                -rdynamic ? */
        sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
        if (sym_index && sym->st_shndx != SHN_UNDEF)
            set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
                        0, sym->st_shndx, name);
        else if (esym->st_shndx == SHN_UNDEF) {
            /* weak symbols can stay undefined */
            if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
                tcc_warning("undefined dynamic symbol '%s'", name);
        }
    }
}

/* Export all non local symbols. This is used by shared libraries so that the
   non local symbols they define can resolve a reference in another shared
   library or in the executable. Correspondingly, it allows undefined local
   symbols to be resolved by other shared libraries or by the executable. */
static void export_global_syms(TCCState *s1)
{
    int dynindex, index;
    const char *name;
    ElfW(Sym) *sym;

    for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
        if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
        name = (char *) symtab_section->link->data + sym->st_name;
        dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
                   sym->st_info, 0, sym->st_shndx, name);
        index = sym - (ElfW(Sym) *) symtab_section->data;
            get_sym_attr(s1, index, 1)->dyn_index = dynindex;
        }
    }
}

/* Allocate strings for section names and decide if an unallocated section
   should be output.
   NOTE: the strsec section comes last, so its size is also correct ! */
static void alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
{
    int i;
    Section *s;

    /* Allocate strings for section names */
    for(i = 1; i < s1->nb_sections; i++) {
        s = s1->sections[i];
        /* when generating a DLL, we include relocations but we may
           patch them */
        if (file_type == TCC_OUTPUT_DLL &&
            s->sh_type == SHT_RELX &&
            !(s->sh_flags & SHF_ALLOC)) {
            /* gr: avoid bogus relocs for empty (debug) sections */
            if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)
                prepare_dynamic_rel(s1, s);
            else if (s1->do_debug)
                s->sh_size = s->data_offset;
        } else if (s1->do_debug ||
            file_type == TCC_OUTPUT_OBJ ||
            (s->sh_flags & SHF_ALLOC) ||
        i == (s1->nb_sections - 1)) {
            /* we output all sections if debug or object file */
            s->sh_size = s->data_offset;
        }
    if (s->sh_size || (s->sh_flags & SHF_ALLOC))
            s->sh_name = put_elf_str(strsec, s->name);
    }
    strsec->sh_size = strsec->data_offset;
}

/* Info to be copied in dynamic section */
struct dyn_inf {
    Section *dynamic;
    Section *dynstr;
    unsigned long dyn_rel_off;
    addr_t rel_addr;
    addr_t rel_size;
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
    addr_t bss_addr;
    addr_t bss_size;
#endif
};

/* Assign sections to segments and decide how are sections laid out when loaded
   in memory. This function also fills corresponding program headers. */
static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
                           Section *interp, Section* strsec,
                           struct dyn_inf *dyninf, int *sec_order)
{
    int i, j, k, file_type, sh_order_index, file_offset;
    unsigned long s_align;
    long long tmp;
    addr_t addr;
    ElfW(Phdr) *ph;
    Section *s;

    file_type = s1->output_type;
    sh_order_index = 1;
    file_offset = 0;
    if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
        file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
    s_align = ELF_PAGE_SIZE;
    if (s1->section_align)
        s_align = s1->section_align;

    if (phnum > 0) {
        if (s1->has_text_addr) {
            int a_offset, p_offset;
            addr = s1->text_addr;
            /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
               ELF_PAGE_SIZE */
            a_offset = (int) (addr & (s_align - 1));
            p_offset = file_offset & (s_align - 1);
            if (a_offset < p_offset)
                a_offset += s_align;
            file_offset += (a_offset - p_offset);
        } else {
            if (file_type == TCC_OUTPUT_DLL)
                addr = 0;
            else
                addr = ELF_START_ADDR;
            /* compute address after headers */
            addr += (file_offset & (s_align - 1));
        }

        ph = &phdr[0];
        /* Leave one program headers for the program interpreter and one for
           the program header table itself if needed. These are done later as
           they require section layout to be done first. */
        if (interp)
            ph += 1 + HAVE_PHDR;

        /* dynamic relocation table information, for .dynamic section */
        dyninf->rel_addr = dyninf->rel_size = 0;
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
        dyninf->bss_addr = dyninf->bss_size = 0;
#endif

        for(j = 0; j < 2; j++) {
            ph->p_type = PT_LOAD;
            if (j == 0)
                ph->p_flags = PF_R | PF_X;
            else
                ph->p_flags = PF_R | PF_W;
            ph->p_align = s_align;

            /* Decide the layout of sections loaded in memory. This must
               be done before program headers are filled since they contain
               info about the layout. We do the following ordering: interp,
               symbol tables, relocations, progbits, nobits */
            /* XXX: do faster and simpler sorting */
            for(k = 0; k < 5; k++) {
                for(i = 1; i < s1->nb_sections; i++) {
                    s = s1->sections[i];
                    /* compute if section should be included */
                    if (j == 0) {
                        if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
                            SHF_ALLOC)
                            continue;
                    } else {
                        if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
                            (SHF_ALLOC | SHF_WRITE))
                            continue;
                    }
                    if (s == interp) {
                        if (k != 0)
                            continue;
                    } else if (s->sh_type == SHT_DYNSYM ||
                               s->sh_type == SHT_STRTAB ||
                               s->sh_type == SHT_HASH) {
                        if (k != 1)
                            continue;
                    } else if (s->sh_type == SHT_RELX) {
                        if (k != 2)
                            continue;
                    } else if (s->sh_type == SHT_NOBITS) {
                        if (k != 4)
                            continue;
                    } else {
                        if (k != 3)
                            continue;
                    }
                    sec_order[sh_order_index++] = i;

                    /* section matches: we align it and add its size */
                    tmp = addr;
                    addr = (addr + s->sh_addralign - 1) &
                        ~(s->sh_addralign - 1);
                    file_offset += (int) ( addr - tmp );
                    s->sh_offset = file_offset;
                    s->sh_addr = addr;

                    /* update program header infos */
                    if (ph->p_offset == 0) {
                        ph->p_offset = file_offset;
                        ph->p_vaddr = addr;
                        ph->p_paddr = ph->p_vaddr;
                    }
                    /* update dynamic relocation infos */
                    if (s->sh_type == SHT_RELX) {
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
                        if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
                            dyninf->rel_addr = addr;
                            dyninf->rel_size += s->sh_size; /* XXX only first rel. */
                        }
                        if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
                            dyninf->bss_addr = addr;
                            dyninf->bss_size = s->sh_size; /* XXX only first rel. */
                        }
#else
                        if (dyninf->rel_size == 0)
                            dyninf->rel_addr = addr;
                        dyninf->rel_size += s->sh_size;
#endif
                    }
                    addr += s->sh_size;
                    if (s->sh_type != SHT_NOBITS)
                        file_offset += s->sh_size;
                }
            }
        if (j == 0) {
        /* Make the first PT_LOAD segment include the program
           headers itself (and the ELF header as well), it'll
           come out with same memory use but will make various
           tools like binutils strip work better.  */
        ph->p_offset &= ~(ph->p_align - 1);
        ph->p_vaddr &= ~(ph->p_align - 1);
        ph->p_paddr &= ~(ph->p_align - 1);
        }
            ph->p_filesz = file_offset - ph->p_offset;
            ph->p_memsz = addr - ph->p_vaddr;
            ph++;
            if (j == 0) {
                if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
                    /* if in the middle of a page, we duplicate the page in
                       memory so that one copy is RX and the other is RW */
                    if ((addr & (s_align - 1)) != 0)
                        addr += s_align;
                } else {
                    addr = (addr + s_align - 1) & ~(s_align - 1);
                    file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
                }
            }
        }
    }

    /* all other sections come after */
    for(i = 1; i < s1->nb_sections; i++) {
        s = s1->sections[i];
        if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
            continue;
        sec_order[sh_order_index++] = i;

        file_offset = (file_offset + s->sh_addralign - 1) &
            ~(s->sh_addralign - 1);
        s->sh_offset = file_offset;
        if (s->sh_type != SHT_NOBITS)
            file_offset += s->sh_size;
    }

    return file_offset;
}

static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
                                 Section *dynamic)
{
    ElfW(Phdr) *ph;

    /* if interpreter, then add corresponding program header */
    if (interp) {
        ph = &phdr[0];

        if (HAVE_PHDR)
        {
            int len = phnum * sizeof(ElfW(Phdr));

            ph->p_type = PT_PHDR;
            ph->p_offset = sizeof(ElfW(Ehdr));
            ph->p_vaddr = interp->sh_addr - len;
            ph->p_paddr = ph->p_vaddr;
            ph->p_filesz = ph->p_memsz = len;
            ph->p_flags = PF_R | PF_X;
            ph->p_align = 4; /* interp->sh_addralign; */
            ph++;
        }

        ph->p_type = PT_INTERP;
        ph->p_offset = interp->sh_offset;
        ph->p_vaddr = interp->sh_addr;
        ph->p_paddr = ph->p_vaddr;
        ph->p_filesz = interp->sh_size;
        ph->p_memsz = interp->sh_size;
        ph->p_flags = PF_R;
        ph->p_align = interp->sh_addralign;
    }

    /* if dynamic section, then add corresponding program header */
    if (dynamic) {
        ph = &phdr[phnum - 1];

        ph->p_type = PT_DYNAMIC;
        ph->p_offset = dynamic->sh_offset;
        ph->p_vaddr = dynamic->sh_addr;
        ph->p_paddr = ph->p_vaddr;
        ph->p_filesz = dynamic->sh_size;
        ph->p_memsz = dynamic->sh_size;
        ph->p_flags = PF_R | PF_W;
        ph->p_align = dynamic->sh_addralign;
    }
}

/* Fill the dynamic section with tags describing the address and size of
   sections */
static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
{
    Section *dynamic;

    dynamic = dyninf->dynamic;

    /* put dynamic section entries */
    dynamic->data_offset = dyninf->dyn_rel_off;
    put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
    put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
    put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
    put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
    put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
#if PTR_SIZE == 8
    put_dt(dynamic, DT_RELA, dyninf->rel_addr);
    put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
    put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
#else
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
    put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
    put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
    put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
    put_dt(dynamic, DT_PLTREL, DT_REL);
    put_dt(dynamic, DT_REL, dyninf->bss_addr);
    put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
#else
    put_dt(dynamic, DT_REL, dyninf->rel_addr);
    put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
    put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
#endif
#endif
    if (s1->do_debug)
        put_dt(dynamic, DT_DEBUG, 0);
    put_dt(dynamic, DT_NULL, 0);
}

/* Relocate remaining sections and symbols (that is those not related to
   dynamic linking) */
static int final_sections_reloc(TCCState *s1)
{
    int i;
    Section *s;

    relocate_syms(s1, s1->symtab, 0);

    if (s1->nb_errors != 0)
        return -1;

    /* relocate sections */
    /* XXX: ignore sections with allocated relocations ? */
    for(i = 1; i < s1->nb_sections; i++) {
        s = s1->sections[i];
#if defined(TCC_TARGET_I386) || defined(TCC_MUSL)
        if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr
        /* On X86 gdb 7.3 works in any case but gdb 6.6 will crash if SHF_ALLOC
        checking is removed */
#else
        if (s->reloc && s != s1->got)
        /* On X86_64 gdb 7.3 will crash if SHF_ALLOC checking is present */
#endif
            relocate_section(s1, s);
    }

    /* relocate relocation entries if the relocation tables are
       allocated in the executable */
    for(i = 1; i < s1->nb_sections; i++) {
        s = s1->sections[i];
        if ((s->sh_flags & SHF_ALLOC) &&
            s->sh_type == SHT_RELX) {
            relocate_rel(s1, s);
        }
    }
    return 0;
}

/* Create an ELF file on disk.
   This function handle ELF specific layout requirements */
static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
                           int file_offset, int *sec_order)
{
    int i, shnum, offset, size, file_type;
    Section *s;
    ElfW(Ehdr) ehdr;
    ElfW(Shdr) shdr, *sh;

    file_type = s1->output_type;
    shnum = s1->nb_sections;

    memset(&ehdr, 0, sizeof(ehdr));

    if (phnum > 0) {
        ehdr.e_phentsize = sizeof(ElfW(Phdr));
        ehdr.e_phnum = phnum;
        ehdr.e_phoff = sizeof(ElfW(Ehdr));
    }

    /* align to 4 */
    file_offset = (file_offset + 3) & -4;

    /* fill header */
    ehdr.e_ident[0] = ELFMAG0;
    ehdr.e_ident[1] = ELFMAG1;
    ehdr.e_ident[2] = ELFMAG2;
    ehdr.e_ident[3] = ELFMAG3;
    ehdr.e_ident[4] = ELFCLASSW;
    ehdr.e_ident[5] = ELFDATA2LSB;
    ehdr.e_ident[6] = EV_CURRENT;
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
    ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
#endif
#ifdef TCC_TARGET_ARM
#if defined (TCC_ARM_EABI) || BOOTSTRAP
    ehdr.e_ident[EI_OSABI] = 0;
    ehdr.e_flags = EF_ARM_EABI_VER4;
    if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
        ehdr.e_flags |= EF_ARM_HASENTRY;
    if (s1->float_abi == ARM_HARD_FLOAT)
        ehdr.e_flags |= EF_ARM_VFP_FLOAT;
    else
        ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
#else
    ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
#endif
#endif
    switch(file_type) {
    default:
    case TCC_OUTPUT_EXE:
        ehdr.e_type = ET_EXEC;
        ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
        break;
    case TCC_OUTPUT_DLL:
        ehdr.e_type = ET_DYN;
        ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
        break;
    case TCC_OUTPUT_OBJ:
        ehdr.e_type = ET_REL;
        break;
    }
    ehdr.e_machine = EM_TCC_TARGET;
    ehdr.e_version = EV_CURRENT;
    ehdr.e_shoff = file_offset;
    ehdr.e_ehsize = sizeof(ElfW(Ehdr));
    ehdr.e_shentsize = sizeof(ElfW(Shdr));
    ehdr.e_shnum = shnum;
    ehdr.e_shstrndx = shnum - 1;

    fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
    fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
    offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));

    sort_syms(s1, symtab_section);
    for(i = 1; i < s1->nb_sections; i++) {
        s = s1->sections[sec_order[i]];
        if (s->sh_type != SHT_NOBITS) {
            while (offset < s->sh_offset) {
                fputc(0, f);
                offset++;
            }
            size = s->sh_size;
            if (size)
                fwrite(s->data, 1, size, f);
            offset += size;
        }
    }

    /* output section headers */
    while (offset < ehdr.e_shoff) {
        fputc(0, f);
        offset++;
    }

    for(i = 0; i < s1->nb_sections; i++) {
        sh = &shdr;
        memset(sh, 0, sizeof(ElfW(Shdr)));
        s = s1->sections[i];
        if (s) {
            sh->sh_name = s->sh_name;
            sh->sh_type = s->sh_type;
            sh->sh_flags = s->sh_flags;
            sh->sh_entsize = s->sh_entsize;
            sh->sh_info = s->sh_info;
            if (s->link)
                sh->sh_link = s->link->sh_num;
            sh->sh_addralign = s->sh_addralign;
            sh->sh_addr = s->sh_addr;
            sh->sh_offset = s->sh_offset;
            sh->sh_size = s->sh_size;
        }
        fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
    }
}

/* Write an elf, coff or "binary" file */
static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
                              ElfW(Phdr) *phdr, int file_offset, int *sec_order)
{
    int fd, mode, file_type;
    FILE *f;

    file_type = s1->output_type;
    if (file_type == TCC_OUTPUT_OBJ)
        mode = 0666;
    else
        mode = 0777;
    unlink(filename);
    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
    if (fd < 0) {
        tcc_error_noabort("could not write '%s'", filename);
        return -1;
    }
    f = fdopen(fd, "wb");
    if (s1->verbose)
        printf("<- %s\n", filename);

#ifdef TCC_TARGET_COFF
    if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
        tcc_output_coff(s1, f);
    else
#endif
    if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
        tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
    else
        tcc_output_binary(s1, f, sec_order);
    fclose(f);

    return 0;
}

/* Sort section headers by assigned sh_addr, remove sections
   that we aren't going to output.  */
static void tidy_section_headers(TCCState *s1, int *sec_order)
{
    int i, nnew, l, *backmap;
    Section **snew, *s;
    ElfW(Sym) *sym;

    snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
    backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
    for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
    s = s1->sections[sec_order[i]];
    if (!i || s->sh_name) {
        backmap[sec_order[i]] = nnew;
        snew[nnew] = s;
        ++nnew;
    } else {
        backmap[sec_order[i]] = 0;
        snew[--l] = s;
    }
    }
    for (i = 0; i < nnew; i++) {
    s = snew[i];
    if (s) {
        s->sh_num = i;
            if (s->sh_type == SHT_RELX)
        s->sh_info = backmap[s->sh_info];
    }
    }

    for_each_elem(symtab_section, 1, sym, ElfW(Sym))
    if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
        sym->st_shndx = backmap[sym->st_shndx];
    for_each_elem(s1->dynsym, 1, sym, ElfW(Sym))
    if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
        sym->st_shndx = backmap[sym->st_shndx];

    for (i = 0; i < s1->nb_sections; i++)
    sec_order[i] = i;
    tcc_free(s1->sections);
    s1->sections = snew;
    s1->nb_sections = nnew;
    tcc_free(backmap);
}

/* Output an elf, coff or binary file */
/* XXX: suppress unneeded sections */
static int elf_output_file(TCCState *s1, const char *filename)
{
    int i, ret, phnum, shnum, file_type, file_offset, *sec_order;
    struct dyn_inf dyninf = {0};
    ElfW(Phdr) *phdr;
    ElfW(Sym) *sym;
    Section *strsec, *interp, *dynamic, *dynstr;

    file_type = s1->output_type;
    s1->nb_errors = 0;

    /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
    if (file_type != TCC_OUTPUT_OBJ) {
        tcc_add_runtime(s1);
    }

    phdr = NULL;
    sec_order = NULL;
    interp = dynamic = dynstr = NULL; /* avoid warning */

    if (file_type != TCC_OUTPUT_OBJ) {
        relocate_common_syms();

        tcc_add_linker_symbols(s1);

        if (!s1->static_link) {
            if (file_type == TCC_OUTPUT_EXE) {
                char *ptr;
                /* allow override the dynamic loader */
                const char *elfint = getenv("LD_SO");
                if (elfint == NULL)
                    elfint = DEFAULT_ELFINTERP(s1);
                /* add interpreter section only if executable */
                interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
                interp->sh_addralign = 1;
                ptr = section_ptr_add(interp, 1 + strlen(elfint));
                strcpy(ptr, elfint);
            }

            /* add dynamic symbol table */
            s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
                                    ".dynstr",
                                    ".hash", SHF_ALLOC);
            dynstr = s1->dynsym->link;

            /* add dynamic section */
            dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
                                  SHF_ALLOC | SHF_WRITE);
            dynamic->link = dynstr;
            dynamic->sh_entsize = sizeof(ElfW(Dyn));

            build_got(s1);

            if (file_type == TCC_OUTPUT_EXE) {
                bind_exe_dynsyms(s1);

                if (s1->nb_errors) {
                    ret = -1;
                    goto the_end;
                }

                bind_libs_dynsyms(s1);
            } else /* shared library case: simply export all global symbols */
                export_global_syms(s1);

            build_got_entries(s1);

            /* add a list of needed dlls */
            for(i = 0; i < s1->nb_loaded_dlls; i++) {
                DLLReference *dllref = s1->loaded_dlls[i];
                if (dllref->level == 0)
                    put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
            }

            if (s1->rpath)
                put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
                    put_elf_str(dynstr, s1->rpath));

            /* XXX: currently, since we do not handle PIC code, we
               must relocate the readonly segments */
            if (file_type == TCC_OUTPUT_DLL) {
                if (s1->soname)
                    put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
                put_dt(dynamic, DT_TEXTREL, 0);
            }

            if (s1->symbolic)
                put_dt(dynamic, DT_SYMBOLIC, 0);

            /* add necessary space for other entries */
            dyninf.dyn_rel_off = dynamic->data_offset;
            dynamic->data_offset += sizeof(ElfW(Dyn)) * EXTRA_RELITEMS;
        } else {
            /* still need to build got entries in case of static link */
            build_got_entries(s1);
        }
    }

    /* we add a section for symbols */
    strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
    put_elf_str(strsec, "");

    /* compute number of sections */
    shnum = s1->nb_sections;

    /* this array is used to reorder sections in the output file */
    sec_order = tcc_malloc(sizeof(int) * shnum);
    sec_order[0] = 0;

    /* compute number of program headers */
    switch(file_type) {
    default:
    case TCC_OUTPUT_OBJ:
        phnum = 0;
        break;
    case TCC_OUTPUT_EXE:
        if (!s1->static_link)
            phnum = 4 + HAVE_PHDR;
        else
            phnum = 2;
        break;
    case TCC_OUTPUT_DLL:
        phnum = 3;
        break;
    }

    /* Allocate strings for section names */
    alloc_sec_names(s1, file_type, strsec);

    /* allocate program segment headers */
    phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));

    /* compute section to program header mapping */
    file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
                                  sec_order);

    /* Fill remaining program header and finalize relocation related to dynamic
       linking. */
    if (phnum > 0) {
        fill_unloadable_phdr(phdr, phnum, interp, dynamic);
        if (dynamic) {
            dyninf.dynamic = dynamic;
            dyninf.dynstr = dynstr;

            fill_dynamic(s1, &dyninf);

            /* put in GOT the dynamic section address and relocate PLT */
            write32le(s1->got->data, dynamic->sh_addr);
            if (file_type == TCC_OUTPUT_EXE
                || (RELOCATE_DLLPLT && file_type == TCC_OUTPUT_DLL))
                relocate_plt(s1);

            /* relocate symbols in .dynsym now that final addresses are known */
            for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
                if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) {
                    /* do symbol relocation */
                    sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
                }
            }
        }
    }

    /* if building executable or DLL, then relocate each section
       except the GOT which is already relocated */
    if (file_type != TCC_OUTPUT_OBJ) {
        ret = final_sections_reloc(s1);
        if (ret)
            goto the_end;
#if !BOOTSTRAP
    tidy_section_headers(s1, sec_order);
#endif
    }

    /* Perform relocation to GOT or PLT entries */
    if (file_type == TCC_OUTPUT_EXE && s1->static_link)
        fill_got(s1);
    else if (s1->got)
        fill_local_got_entries(s1);

    /* Create the ELF file with name 'filename' */
    ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
    s1->nb_sections = shnum;
 the_end:
    tcc_free(sec_order);
    tcc_free(phdr);
    return ret;
}

LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
{
    int ret;
#ifdef TCC_TARGET_PE
    if (s->output_type != TCC_OUTPUT_OBJ) {
        ret = pe_output_file(s, filename);
    } else
#endif
        ret = elf_output_file(s, filename);
    return ret;
}

static void *load_data(int fd, unsigned long file_offset, unsigned long size)
{
    void *data;

    data = tcc_malloc(size);
    lseek(fd, file_offset, SEEK_SET);
    read(fd, data, size);
    return data;
}

typedef struct SectionMergeInfo {
    Section *s;            /* corresponding existing section */
    unsigned long offset;  /* offset of the new section in the existing section */
    uint8_t new_section;       /* true if section 's' was added */
    uint8_t link_once;         /* true if link once section */
} SectionMergeInfo;

ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
{
    int size = read(fd, h, sizeof *h);
    if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
        if (h->e_type == ET_REL)
            return AFF_BINTYPE_REL;
        if (h->e_type == ET_DYN)
            return AFF_BINTYPE_DYN;
    } else if (size >= 8) {
        if (0 == memcmp(h, ARMAG, 8))
            return AFF_BINTYPE_AR;
#ifdef TCC_TARGET_COFF
        if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
            return AFF_BINTYPE_C67;
#endif
    }
    return 0;
}

/* load an object file and merge it with current files */
/* XXX: handle correctly stab (debug) info */
ST_FUNC int tcc_load_object_file(TCCState *s1,
                                int fd, unsigned long file_offset)
{
    ElfW(Ehdr) ehdr;
    ElfW(Shdr) *shdr, *sh;
    int size, i, j, offset, offseti, nb_syms, sym_index, ret, seencompressed;
    unsigned char *strsec, *strtab;
    int *old_to_new_syms;
    char *sh_name, *name;
    SectionMergeInfo *sm_table, *sm;
    ElfW(Sym) *sym, *symtab;
    ElfW_Rel *rel;
    Section *s;

    int stab_index;
    int stabstr_index;

    stab_index = stabstr_index = 0;

    lseek(fd, file_offset, SEEK_SET);
    if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
        goto fail1;
    /* test CPU specific stuff */
    if (ehdr.e_ident[5] != ELFDATA2LSB ||
        ehdr.e_machine != EM_TCC_TARGET) {
    fail1:
        tcc_error_noabort("invalid object file");
        return -1;
    }
    /* read sections */
    shdr = load_data(fd, file_offset + ehdr.e_shoff,
                     sizeof(ElfW(Shdr)) * ehdr.e_shnum);
    sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);

    /* load section names */
    sh = &shdr[ehdr.e_shstrndx];
    strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);

    /* load symtab and strtab */
    old_to_new_syms = NULL;
    symtab = NULL;
    strtab = NULL;
    nb_syms = 0;
    seencompressed = 0;
    for(i = 1; i < ehdr.e_shnum; i++) {
        sh = &shdr[i];
        if (sh->sh_type == SHT_SYMTAB) {
            if (symtab) {
                tcc_error_noabort("object must contain only one symtab");
            fail:
                ret = -1;
                goto the_end;
            }
            nb_syms = sh->sh_size / sizeof(ElfW(Sym));
            symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
            sm_table[i].s = symtab_section;

            /* now load strtab */
            sh = &shdr[sh->sh_link];
            strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
        }
    if (sh->sh_flags & SHF_COMPRESSED)
        seencompressed = 1;
    }

    /* now examine each section and try to merge its content with the
       ones in memory */
    for(i = 1; i < ehdr.e_shnum; i++) {
        /* no need to examine section name strtab */
        if (i == ehdr.e_shstrndx)
            continue;
        sh = &shdr[i];
        sh_name = (char *) strsec + sh->sh_name;
        /* ignore sections types we do not handle */
        if (sh->sh_type != SHT_PROGBITS &&
            sh->sh_type != SHT_RELX &&
#ifdef TCC_ARM_EABI
            sh->sh_type != SHT_ARM_EXIDX &&
#endif
            sh->sh_type != SHT_NOBITS &&
            sh->sh_type != SHT_PREINIT_ARRAY &&
            sh->sh_type != SHT_INIT_ARRAY &&
            sh->sh_type != SHT_FINI_ARRAY &&
            strcmp(sh_name, ".stabstr")
            )
            continue;
    if (seencompressed
        && (!strncmp(sh_name, ".debug_", sizeof(".debug_")-1)
        || (sh->sh_type == SHT_RELX
            && !strncmp((char*)strsec + shdr[sh->sh_info].sh_name,
                    ".debug_", sizeof(".debug_")-1))))
      continue;
        if (sh->sh_addralign < 1)
            sh->sh_addralign = 1;
        /* find corresponding section, if any */
        for(j = 1; j < s1->nb_sections;j++) {
            s = s1->sections[j];
            if (!strcmp(s->name, sh_name)) {
                if (!strncmp(sh_name, ".gnu.linkonce",
                             sizeof(".gnu.linkonce") - 1)) {
                    /* if a 'linkonce' section is already present, we
                       do not add it again. It is a little tricky as
                       symbols can still be defined in
                       it. */
                    sm_table[i].link_once = 1;
                    goto next;
                } else {
                    goto found;
                }
            }
        }
        /* not found: create new section */
        s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
        /* take as much info as possible from the section. sh_link and
           sh_info will be updated later */
        s->sh_addralign = sh->sh_addralign;
        s->sh_entsize = sh->sh_entsize;
        sm_table[i].new_section = 1;
    found:
        if (sh->sh_type != s->sh_type) {
            tcc_error_noabort("invalid section type");
            goto fail;
        }

        /* align start of section */
        offset = s->data_offset;

        if (0 == strcmp(sh_name, ".stab")) {
            stab_index = i;
            goto no_align;
        }
        if (0 == strcmp(sh_name, ".stabstr")) {
            stabstr_index = i;
            goto no_align;
        }

        size = sh->sh_addralign - 1;
        offset = (offset + size) & ~size;
        if (sh->sh_addralign > s->sh_addralign)
            s->sh_addralign = sh->sh_addralign;
        s->data_offset = offset;
    no_align:
        sm_table[i].offset = offset;
        sm_table[i].s = s;
        /* concatenate sections */
        size = sh->sh_size;
        if (sh->sh_type != SHT_NOBITS) {
            unsigned char *ptr;
            lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
            ptr = section_ptr_add(s, size);
            read(fd, ptr, size);
        } else {
            s->data_offset += size;
        }
    next: ;
    }

    /* gr relocate stab strings */
    if (stab_index && stabstr_index) {
        Stab_Sym *a, *b;
        unsigned o;
        s = sm_table[stab_index].s;
        a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
        b = (Stab_Sym *)(s->data + s->data_offset);
        o = sm_table[stabstr_index].offset;
        while (a < b)
            a->n_strx += o, a++;
    }

    /* second short pass to update sh_link and sh_info fields of new
       sections */
    for(i = 1; i < ehdr.e_shnum; i++) {
        s = sm_table[i].s;
        if (!s || !sm_table[i].new_section)
            continue;
        sh = &shdr[i];
        if (sh->sh_link > 0)
            s->link = sm_table[sh->sh_link].s;
        if (sh->sh_type == SHT_RELX) {
            s->sh_info = sm_table[sh->sh_info].s->sh_num;
            /* update backward link */
            s1->sections[s->sh_info]->reloc = s;
        }
    }
    sm = sm_table;

    /* resolve symbols */
    old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));

    sym = symtab + 1;
    for(i = 1; i < nb_syms; i++, sym++) {
        if (sym->st_shndx != SHN_UNDEF &&
            sym->st_shndx < SHN_LORESERVE) {
            sm = &sm_table[sym->st_shndx];
            if (sm->link_once) {
                /* if a symbol is in a link once section, we use the
                   already defined symbol. It is very important to get
                   correct relocations */
                if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
                    name = (char *) strtab + sym->st_name;
                    sym_index = find_elf_sym(symtab_section, name);
                    if (sym_index)
                        old_to_new_syms[i] = sym_index;
                }
                continue;
            }
            /* if no corresponding section added, no need to add symbol */
            if (!sm->s)
                continue;
            /* convert section number */
            sym->st_shndx = sm->s->sh_num;
            /* offset value */
            sym->st_value += sm->offset;
        }
        /* add symbol */
        name = (char *) strtab + sym->st_name;
        sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
                                sym->st_info, sym->st_other,
                                sym->st_shndx, name);
        old_to_new_syms[i] = sym_index;
    }

    /* third pass to patch relocation entries */
    for(i = 1; i < ehdr.e_shnum; i++) {
        s = sm_table[i].s;
        if (!s)
            continue;
        sh = &shdr[i];
        offset = sm_table[i].offset;
        switch(s->sh_type) {
        case SHT_RELX:
            /* take relocation offset information */
            offseti = sm_table[sh->sh_info].offset;
            for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
                int type;
                unsigned sym_index;
                /* convert symbol index */
                type = ELFW(R_TYPE)(rel->r_info);
                sym_index = ELFW(R_SYM)(rel->r_info);
                /* NOTE: only one symtab assumed */
                if (sym_index >= nb_syms)
                    goto invalid_reloc;
                sym_index = old_to_new_syms[sym_index];
                /* ignore link_once in rel section. */
                if (!sym_index && !sm->link_once
#ifdef TCC_TARGET_ARM
                    && type != R_ARM_V4BX
#endif
                   ) {
                invalid_reloc:
                    tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
                        i, strsec + sh->sh_name, rel->r_offset);
                    goto fail;
                }
                rel->r_info = ELFW(R_INFO)(sym_index, type);
                /* offset the relocation offset */
                rel->r_offset += offseti;
#ifdef TCC_TARGET_ARM
                /* Jumps and branches from a Thumb code to a PLT entry need
                   special handling since PLT entries are ARM code.
                   Unconditional bl instructions referencing PLT entries are
                   handled by converting these instructions into blx
                   instructions. Other case of instructions referencing a PLT
                   entry require to add a Thumb stub before the PLT entry to
                   switch to ARM mode. We set bit plt_thumb_stub of the
                   attribute of a symbol to indicate such a case. */
                if (type == R_ARM_THM_JUMP24)
                    get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
#endif
            }
            break;
        default:
            break;
        }
    }

    ret = 0;
 the_end:
    tcc_free(symtab);
    tcc_free(strtab);
    tcc_free(old_to_new_syms);
    tcc_free(sm_table);
    tcc_free(strsec);
    tcc_free(shdr);
    return ret;
}

typedef struct ArchiveHeader {
    char ar_name[16];           /* name of this member */
    char ar_date[12];           /* file mtime */
    char ar_uid[6];             /* owner uid; printed as decimal */
    char ar_gid[6];             /* owner gid; printed as decimal */
    char ar_mode[8];            /* file mode, printed as octal   */
    char ar_size[10];           /* file size, printed as decimal */
    char ar_fmag[2];            /* should contain ARFMAG */
} ArchiveHeader;

static int get_be32(const uint8_t *b)
{
    return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
}

static long get_be64(const uint8_t *b)
{
  long long ret = get_be32(b);
  ret = (ret << 32) | (unsigned)get_be32(b+4);
  return (long)ret;
}

/* load only the objects which resolve undefined symbols */
static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
{
    long i, bound, nsyms, sym_index, off, ret;
    uint8_t *data;
    const char *ar_names, *p;
    const uint8_t *ar_index;
    ElfW(Sym) *sym;

    data = tcc_malloc(size);
    if (read(fd, data, size) != size)
        goto fail;
    nsyms = entrysize == 4 ? get_be32(data) : get_be64(data);
    ar_index = data + entrysize;
    ar_names = (char *) ar_index + nsyms * entrysize;

    do {
        bound = 0;
        for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
            sym_index = find_elf_sym(symtab_section, p);
            if(sym_index) {
                sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
                if(sym->st_shndx == SHN_UNDEF) {
                    off = (entrysize == 4
               ? get_be32(ar_index + i * 4)
               : get_be64(ar_index + i * 8))
              + sizeof(ArchiveHeader);
                    ++bound;
                    if(tcc_load_object_file(s1, fd, off) < 0) {
                    fail:
                        ret = -1;
                        goto the_end;
                    }
                }
            }
        }
    } while(bound);
    ret = 0;
 the_end:
    tcc_free(data);
    return ret;
}

/* load a '.a' file */
ST_FUNC int tcc_load_archive(TCCState *s1, int fd)
{
    ArchiveHeader hdr;
    char ar_size[11];
    char ar_name[17];
    char magic[8];
    int size, len, i;
    unsigned long file_offset;

    /* skip magic which was already checked */
    read(fd, magic, sizeof(magic));

    for(;;) {
        len = read(fd, &hdr, sizeof(hdr));
        if (len == 0)
            break;
        if (len != sizeof(hdr)) {
            tcc_error_noabort("invalid archive");
            return -1;
        }
        memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
        ar_size[sizeof(hdr.ar_size)] = '\0';
        size = strtol(ar_size, NULL, 0);
        memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
        for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
            if (ar_name[i] != ' ')
                break;
        }
        ar_name[i + 1] = '\0';
        file_offset = lseek(fd, 0, SEEK_CUR);
        /* align to even */
        size = (size + 1) & ~1;
        if (!strcmp(ar_name, "/")) {
            /* coff symbol table : we handle it */
            if(s1->alacarte_link)
                return tcc_load_alacarte(s1, fd, size, 4);
    } else if (!strcmp(ar_name, "/SYM64/")) {
            if(s1->alacarte_link)
                return tcc_load_alacarte(s1, fd, size, 8);
        } else {
            ElfW(Ehdr) ehdr;
            if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
                if (tcc_load_object_file(s1, fd, file_offset) < 0)
                    return -1;
            }
        }
        lseek(fd, file_offset + size, SEEK_SET);
    }
    return 0;
}

#ifndef TCC_TARGET_PE
/* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
   is referenced by the user (so it should be added as DT_NEEDED in
   the generated ELF file) */
ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
{
    ElfW(Ehdr) ehdr;
    ElfW(Shdr) *shdr, *sh, *sh1;
    int i, j, nb_syms, nb_dts, sym_bind, ret;
    ElfW(Sym) *sym, *dynsym;
    ElfW(Dyn) *dt, *dynamic;
    unsigned char *dynstr;
    const char *name, *soname;
    DLLReference *dllref;

    read(fd, &ehdr, sizeof(ehdr));

    /* test CPU specific stuff */
    if (ehdr.e_ident[5] != ELFDATA2LSB ||
        ehdr.e_machine != EM_TCC_TARGET) {
        tcc_error_noabort("bad architecture");
        return -1;
    }

    /* read sections */
    shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);

    /* load dynamic section and dynamic symbols */
    nb_syms = 0;
    nb_dts = 0;
    dynamic = NULL;
    dynsym = NULL; /* avoid warning */
    dynstr = NULL; /* avoid warning */
    for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
        switch(sh->sh_type) {
        case SHT_DYNAMIC:
            nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
            dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
            break;
        case SHT_DYNSYM:
            nb_syms = sh->sh_size / sizeof(ElfW(Sym));
            dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
            sh1 = &shdr[sh->sh_link];
            dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
            break;
        default:
            break;
        }
    }

    /* compute the real library name */
    soname = tcc_basename(filename);

    for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
        if (dt->d_tag == DT_SONAME) {
            soname = (char *) dynstr + dt->d_un.d_val;
        }
    }

    /* if the dll is already loaded, do not load it */
    for(i = 0; i < s1->nb_loaded_dlls; i++) {
        dllref = s1->loaded_dlls[i];
        if (!strcmp(soname, dllref->name)) {
            /* but update level if needed */
            if (level < dllref->level)
                dllref->level = level;
            ret = 0;
            goto the_end;
        }
    }

    /* add the dll and its level */
    dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
    dllref->level = level;
    strcpy(dllref->name, soname);
    dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);

    /* add dynamic symbols in dynsym_section */
    for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
        sym_bind = ELFW(ST_BIND)(sym->st_info);
        if (sym_bind == STB_LOCAL)
            continue;
        name = (char *) dynstr + sym->st_name;
        set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
                    sym->st_info, sym->st_other, sym->st_shndx, name);
    }

    /* load all referenced DLLs */
    for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
        switch(dt->d_tag) {
        case DT_NEEDED:
            name = (char *) dynstr + dt->d_un.d_val;
            for(j = 0; j < s1->nb_loaded_dlls; j++) {
                dllref = s1->loaded_dlls[j];
                if (!strcmp(name, dllref->name))
                    goto already_loaded;
            }
            if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
                tcc_error_noabort("referenced dll '%s' not found", name);
                ret = -1;
                goto the_end;
            }
        already_loaded:
            break;
        }
    }
    ret = 0;
 the_end:
    tcc_free(dynstr);
    tcc_free(dynsym);
    tcc_free(dynamic);
    tcc_free(shdr);
    return ret;
}

#define LD_TOK_NAME 256
#define LD_TOK_EOF  (-1)

/* return next ld script token */
static int ld_next(TCCState *s1, char *name, int name_size)
{
    int c;
    char *q;

 redo:
    switch(ch) {
    case ' ':
    case '\t':
    case '\f':
    case '\v':
    case '\r':
    case '\n':
        inp();
        goto redo;
    case '/':
        minp();
        if (ch == '*') {
            file->buf_ptr = parse_comment(file->buf_ptr);
            ch = file->buf_ptr[0];
            goto redo;
        } else {
            q = name;
            *q++ = '/';
            goto parse_name;
        }
        break;
    case '\\':
        ch = handle_eob();
        if (ch != '\\')
            goto redo;
        /* fall through */
    /* case 'a' ... 'z': */
    case 'a':
       case 'b':
       case 'c':
       case 'd':
       case 'e':
       case 'f':
       case 'g':
       case 'h':
       case 'i':
       case 'j':
       case 'k':
       case 'l':
       case 'm':
       case 'n':
       case 'o':
       case 'p':
       case 'q':
       case 'r':
       case 's':
       case 't':
       case 'u':
       case 'v':
       case 'w':
       case 'x':
       case 'y':
       case 'z':
    /* case 'A' ... 'z': */
    case 'A':
       case 'B':
       case 'C':
       case 'D':
       case 'E':
       case 'F':
       case 'G':
       case 'H':
       case 'I':
       case 'J':
       case 'K':
       case 'L':
       case 'M':
       case 'N':
       case 'O':
       case 'P':
       case 'Q':
       case 'R':
       case 'S':
       case 'T':
       case 'U':
       case 'V':
       case 'W':
       case 'X':
       case 'Y':
       case 'Z':
    case '_':
    case '.':
    case '$':
    case '~':
        q = name;
    parse_name:
        for(;;) {
            if (!((ch >= 'a' && ch <= 'z') ||
                  (ch >= 'A' && ch <= 'Z') ||
                  (ch >= '0' && ch <= '9') ||
                  strchr("/.-_+=$:\\,~", ch)))
                break;
            if ((q - name) < name_size - 1) {
                *q++ = ch;
            }
            minp();
        }
        *q = '\0';
        c = LD_TOK_NAME;
        break;
    case CH_EOF:
        c = LD_TOK_EOF;
        break;
    default:
        c = ch;
        inp();
        break;
    }
    return c;
}

static int ld_add_file(TCCState *s1, const char filename[])
{
    if (filename[0] == '/') {
        if (CONFIG_SYSROOT[0] == '\0'
            && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
            return 0;
        filename = tcc_basename(filename);
    }
    return tcc_add_dll(s1, filename, 0);
}

static inline int new_undef_syms(void)
{
    int ret = 0;
    ret = new_undef_sym;
    new_undef_sym = 0;
    return ret;
}

static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
{
    char filename[1024], libname[1024];
    int t, group, nblibs = 0, ret = 0;
    char **libs = NULL;

    group = !strcmp(cmd, "GROUP");
    if (!as_needed)
        new_undef_syms();
    t = ld_next(s1, filename, sizeof(filename));
    if (t != '(')
        expect("(");
    t = ld_next(s1, filename, sizeof(filename));
    for(;;) {
        libname[0] = '\0';
        if (t == LD_TOK_EOF) {
            tcc_error_noabort("unexpected end of file");
            ret = -1;
            goto lib_parse_error;
        } else if (t == ')') {
            break;
        } else if (t == '-') {
            t = ld_next(s1, filename, sizeof(filename));
            if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
                tcc_error_noabort("library name expected");
                ret = -1;
                goto lib_parse_error;
            }
            pstrcpy(libname, sizeof libname, &filename[1]);
            if (s1->static_link) {
                snprintf(filename, sizeof filename, "lib%s.a", libname);
            } else {
                snprintf(filename, sizeof filename, "lib%s.so", libname);
            }
        } else if (t != LD_TOK_NAME) {
            tcc_error_noabort("filename expected");
            ret = -1;
            goto lib_parse_error;
        }
        if (!strcmp(filename, "AS_NEEDED")) {
            ret = ld_add_file_list(s1, cmd, 1);
            if (ret)
                goto lib_parse_error;
        } else {
            /* TODO: Implement AS_NEEDED support. Ignore it for now */
            if (!as_needed) {
                ret = ld_add_file(s1, filename);
                if (ret)
                    goto lib_parse_error;
                if (group) {
                    /* Add the filename *and* the libname to avoid future conversions */
                    dynarray_add(&libs, &nblibs, tcc_strdup(filename));
                    if (libname[0] != '\0')
                        dynarray_add(&libs, &nblibs, tcc_strdup(libname));
                }
            }
        }
        t = ld_next(s1, filename, sizeof(filename));
        if (t == ',') {
            t = ld_next(s1, filename, sizeof(filename));
        }
    }
    if (group && !as_needed) {
        while (new_undef_syms()) {
            int i;

            for (i = 0; i < nblibs; i ++)
                ld_add_file(s1, libs[i]);
        }
    }
lib_parse_error:
    dynarray_reset(&libs, &nblibs);
    return ret;
}

/* interpret a subset of GNU ldscripts to handle the dummy libc.so
   files */
ST_FUNC int tcc_load_ldscript(TCCState *s1)
{
    char cmd[64];
    char filename[1024];
    int t, ret;

    ch = handle_eob();
    for(;;) {
        t = ld_next(s1, cmd, sizeof(cmd));
        if (t == LD_TOK_EOF)
            return 0;
        else if (t != LD_TOK_NAME)
            return -1;
        if (!strcmp(cmd, "INPUT") ||
            !strcmp(cmd, "GROUP")) {
            ret = ld_add_file_list(s1, cmd, 0);
            if (ret)
                return ret;
        } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
                   !strcmp(cmd, "TARGET")) {
            /* ignore some commands */
            t = ld_next(s1, cmd, sizeof(cmd));
            if (t != '(')
                expect("(");
            for(;;) {
                t = ld_next(s1, filename, sizeof(filename));
                if (t == LD_TOK_EOF) {
                    tcc_error_noabort("unexpected end of file");
                    return -1;
                } else if (t == ')') {
                    break;
                }
            }
        } else {
            return -1;
        }
    }
    return 0;
}
#endif /* !TCC_TARGET_PE */

https://gitlab.com/janneke/tinycc/-/blob/ff2210b308321f27ee07476d07f24b5095602b17/tccrun.c

File: ../git/live-bootstrap/sysa/tcc-0.9.26/build/tcc-0.9.26-1136-g5bba73cc/tccrun.c used in: Step 378, Step 395, Step 407, Step 419, Step 431, Step 443, Step 455
/*
 *  TCC - Tiny C Compiler - Support for -run switch
 *
 *  Copyright (c) 2001-2004 Fabrice Bellard
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef _TCC_H
#include "tcc.h"
#endif

/* only native compiler supports -run */
#ifdef TCC_IS_NATIVE

#ifndef _WIN32
# include <sys/mman.h>
#endif

#ifdef CONFIG_TCC_BACKTRACE
# ifndef _WIN32
#  include <signal.h>
#  ifndef __OpenBSD__
#   include <sys/ucontext.h>
#  endif
# else
#  define ucontext_t CONTEXT
# endif
ST_DATA int rt_num_callers = 6;
ST_DATA const char **rt_bound_error_msg;
ST_DATA void *rt_prog_main;
static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level);
static void rt_error(ucontext_t *uc, const char *fmt, ...);
static void set_exception_handler(void);
#endif

static void set_pages_executable(void *ptr, unsigned long length);
static int tcc_relocate_ex(TCCState *s1, void *ptr);

#ifdef _WIN64
static void *win64_add_function_table(TCCState *s1);
static void win64_del_function_table(void *);
#endif

// #define HAVE_SELINUX

/* ------------------------------------------------------------- */
/* Do all relocations (needed before using tcc_get_symbol())
   Returns -1 on error. */

LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr)
{
    int size;

    if (TCC_RELOCATE_AUTO != ptr)
        return tcc_relocate_ex(s1, ptr);

    size = tcc_relocate_ex(s1, NULL);
    if (size < 0)
        return -1;

#ifdef HAVE_SELINUX
    /* Use mmap instead of malloc for Selinux. */
    ptr = mmap (NULL, size, PROT_READ|PROT_WRITE,
        MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    if (ptr == MAP_FAILED)
        tcc_error("tccrun: could not map memory");
    dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, (void*)(addr_t)size);
#else
    ptr = tcc_malloc(size);
#endif
    tcc_relocate_ex(s1, ptr); /* no more errors expected */
    dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, ptr);
    return 0;
}

ST_FUNC void tcc_run_free(TCCState *s1)
{
    int i;

    for (i = 0; i < s1->nb_runtime_mem; ++i) {
#ifdef HAVE_SELINUX
        unsigned size = (unsigned)(addr_t)s1->runtime_mem[i++];
        munmap(s1->runtime_mem[i], size);
#else
#ifdef _WIN64
        win64_del_function_table(*(void**)s1->runtime_mem[i]);
#endif
        tcc_free(s1->runtime_mem[i]);
#endif
    }
    tcc_free(s1->runtime_mem);
}

/* launch the compiled program with the given arguments */
LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
{
    int (*prog_main)(int, char **);

    s1->runtime_main = "main";
    if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0)
        return -1;
    prog_main = tcc_get_symbol_err(s1, s1->runtime_main);

#ifdef CONFIG_TCC_BACKTRACE
    if (s1->do_debug) {
        set_exception_handler();
        rt_prog_main = prog_main;
    }
#endif

    errno = 0; /* clean errno value */

#ifdef CONFIG_TCC_BCHECK
    if (s1->do_bounds_check) {
        void (*bound_init)(void);
        void (*bound_exit)(void);
        void (*bound_new_region)(void *p, addr_t size);
        int  (*bound_delete_region)(void *p);
        int i, ret;

        /* set error function */
        rt_bound_error_msg = tcc_get_symbol_err(s1, "__bound_error_msg");
        /* XXX: use .init section so that it also work in binary ? */
        bound_init = tcc_get_symbol_err(s1, "__bound_init");
        bound_exit = tcc_get_symbol_err(s1, "__bound_exit");
        bound_new_region = tcc_get_symbol_err(s1, "__bound_new_region");
        bound_delete_region = tcc_get_symbol_err(s1, "__bound_delete_region");

        bound_init();
        /* mark argv area as valid */
        bound_new_region(argv, argc*sizeof(argv[0]));
        for (i=0; i<argc; ++i)
            bound_new_region(argv[i], strlen(argv[i]) + 1);

        ret = (*prog_main)(argc, argv);

        /* unmark argv area */
        for (i=0; i<argc; ++i)
            bound_delete_region(argv[i]);
        bound_delete_region(argv);
        bound_exit();
        return ret;
    }
#endif
    return (*prog_main)(argc, argv);
}

#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
 #define RUN_SECTION_ALIGNMENT 63
#else
 #define RUN_SECTION_ALIGNMENT 15
#endif

/* relocate code. Return -1 on error, required size if ptr is NULL,
   otherwise copy code into buffer passed by the caller */
static int tcc_relocate_ex(TCCState *s1, void *ptr)
{
    Section *s;
    unsigned offset, length, fill, i, k;
    addr_t mem;

    if (NULL == ptr) {
        s1->nb_errors = 0;
#ifdef TCC_TARGET_PE
        pe_output_file(s1, NULL);
#else
        tcc_add_runtime(s1);
        relocate_common_syms();
        tcc_add_linker_symbols(s1);
        build_got_entries(s1);
#endif
        if (s1->nb_errors)
            return -1;
    }

    offset = 0, mem = (addr_t)ptr;
    fill = -mem & RUN_SECTION_ALIGNMENT;
#ifdef _WIN64
    offset += sizeof (void*);
#endif
    for (k = 0; k < 2; ++k) {
        for(i = 1; i < s1->nb_sections; i++) {
            s = s1->sections[i];
            if (0 == (s->sh_flags & SHF_ALLOC))
                continue;
            if (k != !(s->sh_flags & SHF_EXECINSTR))
                continue;
            offset += fill;
            s->sh_addr = mem ? mem + offset : 0;
#if 0
            if (mem)
                printf("%-16s +%02lx %p %04x\n",
                    s->name, fill, (void*)s->sh_addr, (unsigned)s->data_offset);
#endif
            offset += s->data_offset;
            fill = -(mem + offset) & 15;
        }
#if RUN_SECTION_ALIGNMENT > 15
        /* To avoid that x86 processors would reload cached instructions each time
           when data is written in the near, we need to make sure that code and data
           do not share the same 64 byte unit */
        fill = -(mem + offset) & RUN_SECTION_ALIGNMENT;
#endif
    }

    /* relocate symbols */
    relocate_syms(s1, s1->symtab, 1);
    if (s1->nb_errors)
        return -1;

    if (0 == mem)
        return offset + RUN_SECTION_ALIGNMENT;

    /* relocate each section */
    for(i = 1; i < s1->nb_sections; i++) {
        s = s1->sections[i];
        if (s->reloc)
            relocate_section(s1, s);
    }
    relocate_plt(s1);

#ifdef _WIN64
    *(void**)ptr = win64_add_function_table(s1);
#endif

    for(i = 1; i < s1->nb_sections; i++) {
        s = s1->sections[i];
        if (0 == (s->sh_flags & SHF_ALLOC))
            continue;
        length = s->data_offset;
        ptr = (void*)s->sh_addr;
        if (NULL == s->data || s->sh_type == SHT_NOBITS)
            memset(ptr, 0, length);
        else
            memcpy(ptr, s->data, length);
        /* mark executable sections as executable in memory */
        if (s->sh_flags & SHF_EXECINSTR)
            set_pages_executable(ptr, length);
    }
    return 0;
}

/* ------------------------------------------------------------- */
/* allow to run code in memory */

static void set_pages_executable(void *ptr, unsigned long length)
{
#ifdef _WIN32
    unsigned long old_protect;
    VirtualProtect(ptr, length, PAGE_EXECUTE_READWRITE, &old_protect);
#else
    void __clear_cache(void *beginning, void *end);
    addr_t start, end;
#ifndef PAGESIZE
# define PAGESIZE 4096
#endif
    start = (addr_t)ptr & ~(PAGESIZE - 1);
    end = (addr_t)ptr + length;
    end = (end + PAGESIZE - 1) & ~(PAGESIZE - 1);
    if (mprotect((void *)start, end - start, PROT_READ | PROT_WRITE | PROT_EXEC))
        tcc_error("mprotect failed: did you mean to configure --with-selinux?");
# if defined TCC_TARGET_ARM || defined TCC_TARGET_ARM64
#if !BOOTSTRAP
    __clear_cache(ptr, (char *)ptr + length);
#endif
# endif
#endif
}

#ifdef _WIN64
static void *win64_add_function_table(TCCState *s1)
{
    void *p = NULL;
    if (s1->uw_pdata) {
        p = (void*)s1->uw_pdata->sh_addr;
        RtlAddFunctionTable(
            (RUNTIME_FUNCTION*)p,
            s1->uw_pdata->data_offset / sizeof (RUNTIME_FUNCTION),
            text_section->sh_addr
            );
        s1->uw_pdata = NULL;
    }
    return p;;
}

static void win64_del_function_table(void *p)
{
    if (p) {
        RtlDeleteFunctionTable((RUNTIME_FUNCTION*)p);
    }
}
#endif

/* ------------------------------------------------------------- */
#ifdef CONFIG_TCC_BACKTRACE

ST_FUNC void tcc_set_num_callers(int n)
{
    rt_num_callers = n;
}

/* print the position in the source file of PC value 'pc' by reading
   the stabs debug information */
static addr_t rt_printline(addr_t wanted_pc, const char *msg)
{
    char func_name[128], last_func_name[128];
    addr_t func_addr, last_pc, pc;
    const char *incl_files[INCLUDE_STACK_SIZE];
    int incl_index, len, last_line_num, i;
    const char *str, *p;

    Stab_Sym *stab_sym = NULL, *stab_sym_end, *sym;
    int stab_len = 0;
    char *stab_str = NULL;

    if (stab_section) {
        stab_len = stab_section->data_offset;
        stab_sym = (Stab_Sym *)stab_section->data;
        stab_str = (char *) stabstr_section->data;
    }

    func_name[0] = '\0';
    func_addr = 0;
    incl_index = 0;
    last_func_name[0] = '\0';
    last_pc = (addr_t)-1;
    last_line_num = 1;

    if (!stab_sym)
        goto no_stabs;

    stab_sym_end = (Stab_Sym*)((char*)stab_sym + stab_len);
    for (sym = stab_sym + 1; sym < stab_sym_end; ++sym) {
        switch(sym->n_type) {
            /* function start or end */
        case N_FUN:
            if (sym->n_strx == 0) {
                /* we test if between last line and end of function */
                pc = sym->n_value + func_addr;
                if (wanted_pc >= last_pc && wanted_pc < pc)
                    goto found;
                func_name[0] = '\0';
                func_addr = 0;
            } else {
                str = stab_str + sym->n_strx;
                p = strchr(str, ':');
                if (!p) {
                    pstrcpy(func_name, sizeof(func_name), str);
                } else {
                    len = p - str;
                    if (len > sizeof(func_name) - 1)
                        len = sizeof(func_name) - 1;
                    memcpy(func_name, str, len);
                    func_name[len] = '\0';
                }
                func_addr = sym->n_value;
            }
            break;
            /* line number info */
        case N_SLINE:
            pc = sym->n_value + func_addr;
            if (wanted_pc >= last_pc && wanted_pc < pc)
                goto found;
            last_pc = pc;
            last_line_num = sym->n_desc;
            /* XXX: slow! */
            strcpy(last_func_name, func_name);
            break;
            /* include files */
        case N_BINCL:
            str = stab_str + sym->n_strx;
        add_incl:
            if (incl_index < INCLUDE_STACK_SIZE) {
                incl_files[incl_index++] = str;
            }
            break;
        case N_EINCL:
            if (incl_index > 1)
                incl_index--;
            break;
        case N_SO:
            if (sym->n_strx == 0) {
                incl_index = 0; /* end of translation unit */
            } else {
                str = stab_str + sym->n_strx;
                /* do not add path */
                len = strlen(str);
                if (len > 0 && str[len - 1] != '/')
                    goto add_incl;
            }
            break;
        }
    }

no_stabs:
    /* second pass: we try symtab symbols (no line number info) */
    incl_index = 0;
    if (symtab_section)
    {
        ElfW(Sym) *sym, *sym_end;
        int type;

        sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
        for(sym = (ElfW(Sym) *)symtab_section->data + 1;
            sym < sym_end;
            sym++) {
            type = ELFW(ST_TYPE)(sym->st_info);
            if (type == STT_FUNC || type == STT_GNU_IFUNC) {
                if (wanted_pc >= sym->st_value &&
                    wanted_pc < sym->st_value + sym->st_size) {
                    pstrcpy(last_func_name, sizeof(last_func_name),
                            (char *) strtab_section->data + sym->st_name);
                    func_addr = sym->st_value;
                    goto found;
                }
            }
        }
    }
    /* did not find any info: */
    fprintf(stderr, "%s %p ???\n", msg, (void*)wanted_pc);
    fflush(stderr);
    return 0;
 found:
    i = incl_index;
    if (i > 0)
        fprintf(stderr, "%s:%d: ", incl_files[--i], last_line_num);
    fprintf(stderr, "%s %p", msg, (void*)wanted_pc);
    if (last_func_name[0] != '\0')
        fprintf(stderr, " %s()", last_func_name);
    if (--i >= 0) {
        fprintf(stderr, " (included from ");
        for (;;) {
            fprintf(stderr, "%s", incl_files[i]);
            if (--i < 0)
                break;
            fprintf(stderr, ", ");
        }
        fprintf(stderr, ")");
    }
    fprintf(stderr, "\n");
    fflush(stderr);
    return func_addr;
}

/* emit a run time error at position 'pc' */
static void rt_error(ucontext_t *uc, const char *fmt, ...)
{
    va_list ap;
    addr_t pc;
    int i;

    fprintf(stderr, "Runtime error: ");
    va_start(ap, fmt);
    vfprintf(stderr, fmt, ap);
    va_end(ap);
    fprintf(stderr, "\n");

    for(i=0;i<rt_num_callers;i++) {
        if (rt_get_caller_pc(&pc, uc, i) < 0)
            break;
        pc = rt_printline(pc, i ? "by" : "at");
        if (pc == (addr_t)rt_prog_main && pc)
            break;
    }
}

/* ------------------------------------------------------------- */
#ifndef _WIN32

/* signal handler for fatal errors */
static void sig_error(int signum, siginfo_t *siginf, void *puc)
{
    ucontext_t *uc = puc;

    switch(signum) {
    case SIGFPE:
        switch(siginf->si_code) {
        case FPE_INTDIV:
        case FPE_FLTDIV:
            rt_error(uc, "division by zero");
            break;
        default:
            rt_error(uc, "floating point exception");
            break;
        }
        break;
    case SIGBUS:
    case SIGSEGV:
        if (rt_bound_error_msg && *rt_bound_error_msg)
            rt_error(uc, *rt_bound_error_msg);
        else
            rt_error(uc, "dereferencing invalid pointer");
        break;
    case SIGILL:
        rt_error(uc, "illegal instruction");
        break;
    case SIGABRT:
        rt_error(uc, "abort() called");
        break;
    default:
        rt_error(uc, "caught signal %d", signum);
        break;
    }
    exit(255);
}

#ifndef SA_SIGINFO
# define SA_SIGINFO 0x00000004u
#endif

/* Generate a stack backtrace when a CPU exception occurs. */
static void set_exception_handler(void)
{
    struct sigaction sigact;
    /* install TCC signal handlers to print debug info on fatal
       runtime errors */
    sigact.sa_flags = SA_SIGINFO | SA_RESETHAND;
    sigact.sa_sigaction = sig_error;
    sigemptyset(&sigact.sa_mask);
    sigaction(SIGFPE, &sigact, NULL);
    sigaction(SIGILL, &sigact, NULL);
    sigaction(SIGSEGV, &sigact, NULL);
    sigaction(SIGBUS, &sigact, NULL);
    sigaction(SIGABRT, &sigact, NULL);
}

/* ------------------------------------------------------------- */
#ifdef __i386__

/* fix for glibc 2.1 */
#ifndef REG_EIP
#define REG_EIP EIP
#define REG_EBP EBP
#endif

/* return the PC at frame level 'level'. Return negative if not found */
static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level)
{
    addr_t fp;
    int i;

    if (level == 0) {
#if defined(__APPLE__)
        *paddr = uc->uc_mcontext->__ss.__eip;
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
        *paddr = uc->uc_mcontext.mc_eip;
#elif defined(__dietlibc__)
        *paddr = uc->uc_mcontext.eip;
#elif defined(__NetBSD__)
        *paddr = uc->uc_mcontext.__gregs[_REG_EIP];
#elif defined(__OpenBSD__)
        *paddr = uc->sc_eip;
#else
        *paddr = uc->uc_mcontext.gregs[REG_EIP];
#endif
        return 0;
    } else {
#if defined(__APPLE__)
        fp = uc->uc_mcontext->__ss.__ebp;
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
        fp = uc->uc_mcontext.mc_ebp;
#elif defined(__dietlibc__)
        fp = uc->uc_mcontext.ebp;
#elif defined(__NetBSD__)
        fp = uc->uc_mcontext.__gregs[_REG_EBP];
#elif defined(__OpenBSD__)
        *paddr = uc->sc_ebp;
#else
        fp = uc->uc_mcontext.gregs[REG_EBP];
#endif
        for(i=1;i<level;i++) {
            /* XXX: check address validity with program info */
            if (fp <= 0x1000 || fp >= 0xc0000000)
                return -1;
            fp = ((addr_t *)fp)[0];
        }
        *paddr = ((addr_t *)fp)[1];
        return 0;
    }
}

/* ------------------------------------------------------------- */
#elif defined(__x86_64__)

/* return the PC at frame level 'level'. Return negative if not found */
static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level)
{
    addr_t fp;
    int i;

    if (level == 0) {
        /* XXX: only support linux */
#if defined(__APPLE__)
        *paddr = uc->uc_mcontext->__ss.__rip;
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
        *paddr = uc->uc_mcontext.mc_rip;
#elif defined(__NetBSD__)
        *paddr = uc->uc_mcontext.__gregs[_REG_RIP];
#else
        *paddr = uc->uc_mcontext.gregs[REG_RIP];
#endif
        return 0;
    } else {
#if defined(__APPLE__)
        fp = uc->uc_mcontext->__ss.__rbp;
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
        fp = uc->uc_mcontext.mc_rbp;
#elif defined(__NetBSD__)
        fp = uc->uc_mcontext.__gregs[_REG_RBP];
#else
        fp = uc->uc_mcontext.gregs[REG_RBP];
#endif
        for(i=1;i<level;i++) {
            /* XXX: check address validity with program info */
            if (fp <= 0x1000)
                return -1;
            fp = ((addr_t *)fp)[0];
        }
        *paddr = ((addr_t *)fp)[1];
        return 0;
    }
}

/* ------------------------------------------------------------- */
#elif defined(__arm__)

/* return the PC at frame level 'level'. Return negative if not found */
static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level)
{
    addr_t fp, sp;
    int i;

    if (level == 0) {
        /* XXX: only supports linux */
#if defined(__linux__)
        *paddr = uc->uc_mcontext.arm_pc;
#else
        return -1;
#endif
        return 0;
    } else {
#if defined(__linux__)
        fp = uc->uc_mcontext.arm_fp;
        sp = uc->uc_mcontext.arm_sp;
        if (sp < 0x1000)
            sp = 0x1000;
#else
        return -1;
#endif
        /* XXX: specific to tinycc stack frames */
        if (fp < sp + 12 || fp & 3)
            return -1;
        for(i = 1; i < level; i++) {
            sp = ((addr_t *)fp)[-2];
            if (sp < fp || sp - fp > 16 || sp & 3)
                return -1;
            fp = ((addr_t *)fp)[-3];
            if (fp <= sp || fp - sp < 12 || fp & 3)
                return -1;
        }
        /* XXX: check address validity with program info */
        *paddr = ((addr_t *)fp)[-1];
        return 0;
    }
}

/* ------------------------------------------------------------- */
#elif defined(__aarch64__)

static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level)
{
    if (level < 0)
        return -1;
    else if (level == 0) {
        *paddr = uc->uc_mcontext.pc;
        return 0;
    }
    else {
        addr_t *fp = (addr_t *)uc->uc_mcontext.regs[29];
        int i;
        for (i = 1; i < level; i++)
            fp = (addr_t *)fp[0];
        *paddr = fp[1];
        return 0;
    }
}

/* ------------------------------------------------------------- */
#else

#warning add arch specific rt_get_caller_pc()
static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level)
{
    return -1;
}

#endif /* !__i386__ */

/* ------------------------------------------------------------- */
#else /* WIN32 */

static long __stdcall cpu_exception_handler(EXCEPTION_POINTERS *ex_info)
{
    EXCEPTION_RECORD *er = ex_info->ExceptionRecord;
    CONTEXT *uc = ex_info->ContextRecord;
    switch (er->ExceptionCode) {
    case EXCEPTION_ACCESS_VIOLATION:
        if (rt_bound_error_msg && *rt_bound_error_msg)
            rt_error(uc, *rt_bound_error_msg);
        else
        rt_error(uc, "access violation");
        break;
    case EXCEPTION_STACK_OVERFLOW:
        rt_error(uc, "stack overflow");
        break;
    case EXCEPTION_INT_DIVIDE_BY_ZERO:
        rt_error(uc, "division by zero");
        break;
    default:
        rt_error(uc, "exception caught");
        break;
    }
    return EXCEPTION_EXECUTE_HANDLER;
}

/* Generate a stack backtrace when a CPU exception occurs. */
static void set_exception_handler(void)
{
    SetUnhandledExceptionFilter(cpu_exception_handler);
}

/* return the PC at frame level 'level'. Return non zero if not found */
static int rt_get_caller_pc(addr_t *paddr, CONTEXT *uc, int level)
{
    addr_t fp, pc;
    int i;
#ifdef _WIN64
    pc = uc->Rip;
    fp = uc->Rbp;
#else
    pc = uc->Eip;
    fp = uc->Ebp;
#endif
    if (level > 0) {
        for(i=1;i<level;i++) {
        /* XXX: check address validity with program info */
        if (fp <= 0x1000 || fp >= 0xc0000000)
        return -1;
        fp = ((addr_t*)fp)[0];
    }
        pc = ((addr_t*)fp)[1];
    }
    *paddr = pc;
    return 0;
}

#endif /* _WIN32 */
#endif /* CONFIG_TCC_BACKTRACE */
/* ------------------------------------------------------------- */
#ifdef CONFIG_TCC_STATIC

/* dummy function for profiling */
ST_FUNC void *dlopen(const char *filename, int flag)
{
    return NULL;
}

ST_FUNC void dlclose(void *p)
{
}

ST_FUNC const char *dlerror(void)
{
    return "error";
}

typedef struct TCCSyms {
    char *str;
    void *ptr;
} TCCSyms;


/* add the symbol you want here if no dynamic linking is done */
static TCCSyms tcc_syms[] = {
#if !defined(CONFIG_TCCBOOT)
#define TCCSYM(a) { #a, &a, },
    TCCSYM(printf)
    TCCSYM(fprintf)
    TCCSYM(fopen)
    TCCSYM(fclose)
#undef TCCSYM
#endif
    { NULL, NULL },
};

ST_FUNC void *dlsym(void *handle, const char *symbol)
{
    TCCSyms *p;
    p = tcc_syms;
    while (p->str != NULL) {
        if (!strcmp(p->str, symbol))
            return p->ptr;
        p++;
    }
    return NULL;
}

#endif /* CONFIG_TCC_STATIC */
#endif /* TCC_IS_NATIVE */
/* ------------------------------------------------------------- */

https://gitlab.com/janneke/tinycc/-/blob/ff2210b308321f27ee07476d07f24b5095602b17/i386-gen.c

File: ../git/live-bootstrap/sysa/tcc-0.9.26/build/tcc-0.9.26-1136-g5bba73cc/i386-gen.c used in: Step 378, Step 395, Step 407, Step 419, Step 431, Step 443, Step 455
/*
 *  X86 code generator for TCC
 * 
 *  Copyright (c) 2001-2004 Fabrice Bellard
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifdef TARGET_DEFS_ONLY

/* number of available registers */
#define NB_REGS         5
#define NB_ASM_REGS     8
#define CONFIG_TCC_ASM

/* a register can belong to several classes. The classes must be
   sorted from more general to more precise (see gv2() code which does
   assumptions on it). */
#define RC_INT     0x0001 /* generic integer register */
#define RC_FLOAT   0x0002 /* generic float register */
#define RC_EAX     0x0004
#define RC_ST0     0x0008 
#define RC_ECX     0x0010
#define RC_EDX     0x0020
#define RC_EBX     0x0040

#define RC_IRET    RC_EAX /* function return: integer register */
#define RC_LRET    RC_EDX /* function return: second integer register */
#define RC_FRET    RC_ST0 /* function return: float register */

/* pretty names for the registers */
enum {
    TREG_EAX = 0,
    TREG_ECX,
    TREG_EDX,
    TREG_EBX,
    TREG_ST0,
    TREG_ESP = 4
};

/* return registers for function */
#define REG_IRET TREG_EAX /* single word int return register */
#define REG_LRET TREG_EDX /* second word return register (for long long) */
#define REG_FRET TREG_ST0 /* float return register */

/* defined if function parameters must be evaluated in reverse order */
#define INVERT_FUNC_PARAMS

/* defined if structures are passed as pointers. Otherwise structures
   are directly pushed on stack. */
/* #define FUNC_STRUCT_PARAM_AS_PTR */

/* pointer size, in bytes */
#define PTR_SIZE 4

/* long double size and alignment, in bytes */
#define LDOUBLE_SIZE  12
#define LDOUBLE_ALIGN 4
/* maximum alignment (for aligned attribute support) */
#define MAX_ALIGN     8

/******************************************************/
#else /* ! TARGET_DEFS_ONLY */
/******************************************************/
#ifndef _TCC_H
#include "tcc.h"
#endif

/* define to 1/0 to [not] have EBX as 4th register */
#define USE_EBX 0

ST_DATA const int reg_classes[NB_REGS] = {
    /* eax */ RC_INT | RC_EAX,
    /* ecx */ RC_INT | RC_ECX,
    /* edx */ RC_INT | RC_EDX,
    /* ebx */ (RC_INT | RC_EBX) * USE_EBX,
    /* st0 */ RC_FLOAT | RC_ST0,
};

static unsigned long func_sub_sp_offset;
static int func_ret_sub;
#ifdef CONFIG_TCC_BCHECK
static addr_t func_bound_offset;
static unsigned long func_bound_ind;
#endif

/* XXX: make it faster ? */
ST_FUNC void g(int c)
{
    int ind1;
    if (nocode_wanted)
        return;
    ind1 = ind + 1;
    if (ind1 > cur_text_section->data_allocated)
        section_realloc(cur_text_section, ind1);
    cur_text_section->data[ind] = c;
    ind = ind1;
}

ST_FUNC void o(unsigned int c)
{
    while (c) {
        g(c);
        c = c >> 8;
    }
}

ST_FUNC void gen_le16(int v)
{
    g(v);
    g(v >> 8);
}

ST_FUNC void gen_le32(int c)
{
    g(c);
    g(c >> 8);
    g(c >> 16);
    g(c >> 24);
}

/* output a symbol and patch all calls to it */
ST_FUNC void gsym_addr(int t, int a)
{
    while (t) {
        unsigned char *ptr = cur_text_section->data + t;
        uint32_t n = read32le(ptr); /* next value */
        write32le(ptr, a - t - 4);
        t = n;
    }
}

ST_FUNC void gsym(int t)
{
    gsym_addr(t, ind);
}

/* instruction + 4 bytes data. Return the address of the data */
static int oad(int c, int s)
{
    int t;
    if (nocode_wanted)
        return s;
    o(c);
    t = ind;
    gen_le32(s);
    return t;
}

/* generate jmp to a label */
#define gjmp2(instr,lbl) oad(instr,lbl)

/* output constant with relocation if 'r & VT_SYM' is true */
ST_FUNC void gen_addr32(int r, Sym *sym, long c)
{
    if (r & VT_SYM)
        greloc(cur_text_section, sym, ind, R_386_32);
    gen_le32(c);
}

ST_FUNC void gen_addrpc32(int r, Sym *sym, long c)
{
    if (r & VT_SYM)
        greloc(cur_text_section, sym, ind, R_386_PC32);
    gen_le32(c - 4);
}

/* generate a modrm reference. 'op_reg' contains the addtional 3
   opcode bits */
static void gen_modrm(int op_reg, int r, Sym *sym, int c)
{
    op_reg = op_reg << 3;
    if ((r & VT_VALMASK) == VT_CONST) {
        /* constant memory reference */
        o(0x05 | op_reg);
        gen_addr32(r, sym, c);
    } else if ((r & VT_VALMASK) == VT_LOCAL) {
        /* currently, we use only ebp as base */
        if (c == (char)c) {
            /* short reference */
            o(0x45 | op_reg);
            g(c);
        } else {
            oad(0x85 | op_reg, c);
        }
    } else {
        g(0x00 | op_reg | (r & VT_VALMASK));
    }
}

/* load 'r' from value 'sv' */
ST_FUNC void load(int r, SValue *sv)
{
    int v, t, ft, fc, fr;
    SValue v1;

#ifdef TCC_TARGET_PE
    SValue v2;
    sv = pe_getimport(sv, &v2);
#endif

    fr = sv->r;
    ft = sv->type.t;
    fc = sv->c.i;

    ft &= ~(VT_VOLATILE | VT_CONSTANT);

    v = fr & VT_VALMASK;
    if (fr & VT_LVAL) {
        if (v == VT_LLOCAL) {
            v1.type.t = VT_INT;
            v1.r = VT_LOCAL | VT_LVAL;
            v1.c.i = fc;
            fr = r;
            if (!(reg_classes[fr] & RC_INT))
                fr = get_reg(RC_INT);
            load(fr, &v1);
        }
        if ((ft & VT_BTYPE) == VT_FLOAT) {
            o(0xd9); /* flds */
            r = 0;
        } else if ((ft & VT_BTYPE) == VT_DOUBLE) {
            o(0xdd); /* fldl */
            r = 0;
        } else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
            o(0xdb); /* fldt */
            r = 5;
        } else if ((ft & VT_TYPE) == VT_BYTE || (ft & VT_TYPE) == VT_BOOL) {
            o(0xbe0f);   /* movsbl */
        } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {
            o(0xb60f);   /* movzbl */
        } else if ((ft & VT_TYPE) == VT_SHORT) {
            o(0xbf0f);   /* movswl */
        } else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED)) {
            o(0xb70f);   /* movzwl */
        } else {
            o(0x8b);     /* movl */
        }
        gen_modrm(r, fr, sv->sym, fc);
    } else {
        if (v == VT_CONST) {
            o(0xb8 + r); /* mov $xx, r */
            gen_addr32(fr, sv->sym, fc);
        } else if (v == VT_LOCAL) {
            if (fc) {
                o(0x8d); /* lea xxx(%ebp), r */
                gen_modrm(r, VT_LOCAL, sv->sym, fc);
            } else {
                o(0x89);
                o(0xe8 + r); /* mov %ebp, r */
            }
        } else if (v == VT_CMP) {
            oad(0xb8 + r, 0); /* mov $0, r */
            o(0x0f); /* setxx %br */
            o(fc);
            o(0xc0 + r);
        } else if (v == VT_JMP || v == VT_JMPI) {
            t = v & 1;
            oad(0xb8 + r, t); /* mov $1, r */
            o(0x05eb); /* jmp after */
            gsym(fc);
            oad(0xb8 + r, t ^ 1); /* mov $0, r */
        } else if (v != r) {
            o(0x89);
            o(0xc0 + r + v * 8); /* mov v, r */
        }
    }
}

/* store register 'r' in lvalue 'v' */
ST_FUNC void store(int r, SValue *v)
{
    int fr, bt, ft, fc;

#ifdef TCC_TARGET_PE
    SValue v2;
    v = pe_getimport(v, &v2);
#endif

    ft = v->type.t;
    fc = v->c.i;
    fr = v->r & VT_VALMASK;
    ft &= ~(VT_VOLATILE | VT_CONSTANT);
    bt = ft & VT_BTYPE;
    /* XXX: incorrect if float reg to reg */
    if (bt == VT_FLOAT) {
        o(0xd9); /* fsts */
        r = 2;
    } else if (bt == VT_DOUBLE) {
        o(0xdd); /* fstpl */
        r = 2;
    } else if (bt == VT_LDOUBLE) {
        o(0xc0d9); /* fld %st(0) */
        o(0xdb); /* fstpt */
        r = 7;
    } else {
        if (bt == VT_SHORT)
            o(0x66);
        if (bt == VT_BYTE || bt == VT_BOOL)
            o(0x88);
        else
            o(0x89);
    }
    if (fr == VT_CONST ||
        fr == VT_LOCAL ||
        (v->r & VT_LVAL)) {
        gen_modrm(r, v->r, v->sym, fc);
    } else if (fr != r) {
        o(0xc0 + fr + r * 8); /* mov r, fr */
    }
}

static void gadd_sp(int val)
{
    if (val == (char)val) {
        o(0xc483);
        g(val);
    } else {
        oad(0xc481, val); /* add $xxx, %esp */
    }
}

#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_PE
static void gen_static_call(int v)
{
    Sym *sym;

    sym = external_global_sym(v, &func_old_type, 0);
    oad(0xe8, -4);
    greloc(cur_text_section, sym, ind-4, R_386_PC32);
}
#endif

/* 'is_jmp' is '1' if it is a jump */
static void gcall_or_jmp(int is_jmp)
{
    int r;
    if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
        int rt;
        /* constant case */
        if (vtop->r & VT_SYM) {
            /* relocation case */
            greloc(cur_text_section, vtop->sym, 
                   ind + 1, R_386_PC32);
        } else {
            /* put an empty PC32 relocation */
            put_elf_reloc(symtab_section, cur_text_section, 
                          ind + 1, R_386_PC32, 0);
        }
        oad(0xe8 + is_jmp, vtop->c.i - 4); /* call/jmp im */
        /* extend the return value to the whole register if necessary
           visual studio and gcc do not always set the whole eax register
           when assigning the return value of a function  */
        rt = vtop->type.ref->type.t;
        switch (rt & VT_BTYPE) {
            case VT_BYTE:
                if (rt & VT_UNSIGNED) {
                    o(0xc0b60f); /* movzx %al, %eax */
                }
                else {
                    o(0xc0be0f); /* movsx %al, %eax */
                }
                break;
            case VT_SHORT:
                if (rt & VT_UNSIGNED) {
                    o(0xc0b70f); /* movzx %ax, %eax */
                }
                else {
                    o(0xc0bf0f); /* movsx %ax, %eax */
                }
                break;
            default:
                break;
        }
    } else {
        /* otherwise, indirect call */
        r = gv(RC_INT);
        o(0xff); /* call/jmp *r */
        o(0xd0 + r + (is_jmp << 4));
    }
}

static uint8_t fastcall_regs[3] = { TREG_EAX, TREG_EDX, TREG_ECX };
static uint8_t fastcallw_regs[2] = { TREG_ECX, TREG_EDX };

/* Return the number of registers needed to return the struct, or 0 if
   returning via struct pointer. */
ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize)
{
#ifdef TCC_TARGET_PE
    int size, align;
    *ret_align = 1; // Never have to re-align return values for x86
    *regsize = 4;
    size = type_size(vt, &align);
    if (size > 8 || (size & (size - 1)))
        return 0;
    if (size == 8)
        ret->t = VT_LLONG;
    else if (size == 4)
        ret->t = VT_INT;
    else if (size == 2)
        ret->t = VT_SHORT;
    else
        ret->t = VT_BYTE;
    ret->ref = NULL;
    return 1;
#else
    *ret_align = 1; // Never have to re-align return values for x86
    return 0;
#endif
}

/* Generate function call. The function address is pushed first, then
   all the parameters in call order. This functions pops all the
   parameters and the function address. */
ST_FUNC void gfunc_call(int nb_args)
{
    int size, align, r, args_size, i, func_call;
    Sym *func_sym;
    
    args_size = 0;
    for(i = 0;i < nb_args; i++) {
        if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
            size = type_size(&vtop->type, &align);
            /* align to stack align size */
            size = (size + 3) & ~3;
            /* allocate the necessary size on stack */
            oad(0xec81, size); /* sub $xxx, %esp */
            /* generate structure store */
            r = get_reg(RC_INT);
            o(0x89); /* mov %esp, r */
            o(0xe0 + r);
            vset(&vtop->type, r | VT_LVAL, 0);
            vswap();
            vstore();
            args_size += size;
        } else if (is_float(vtop->type.t)) {
            gv(RC_FLOAT); /* only one float register */
            if ((vtop->type.t & VT_BTYPE) == VT_FLOAT)
                size = 4;
            else if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
                size = 8;
            else
                size = 12;
            oad(0xec81, size); /* sub $xxx, %esp */
            if (size == 12)
                o(0x7cdb);
            else
                o(0x5cd9 + size - 4); /* fstp[s|l] 0(%esp) */
            g(0x24);
            g(0x00);
            args_size += size;
        } else {
            /* simple type (currently always same size) */
            /* XXX: implicit cast ? */
            r = gv(RC_INT);
            if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
                size = 8;
                o(0x50 + vtop->r2); /* push r */
            } else {
                size = 4;
            }
            o(0x50 + r); /* push r */
            args_size += size;
        }
        vtop--;
    }
    save_regs(0); /* save used temporary registers */
    func_sym = vtop->type.ref;
    func_call = func_sym->a.func_call;
    /* fast call case */
    if ((func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) ||
        func_call == FUNC_FASTCALLW) {
        int fastcall_nb_regs;
        uint8_t *fastcall_regs_ptr;
        if (func_call == FUNC_FASTCALLW) {
            fastcall_regs_ptr = fastcallw_regs;
            fastcall_nb_regs = 2;
        } else {
            fastcall_regs_ptr = fastcall_regs;
            fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;
        }
        for(i = 0;i < fastcall_nb_regs; i++) {
            if (args_size <= 0)
                break;
            o(0x58 + fastcall_regs_ptr[i]); /* pop r */
            /* XXX: incorrect for struct/floats */
            args_size -= 4;
        }
    }
#ifndef TCC_TARGET_PE
    else if ((vtop->type.ref->type.t & VT_BTYPE) == VT_STRUCT)
        args_size -= 4;
#endif
    gcall_or_jmp(0);

    if (args_size && func_call != FUNC_STDCALL)
        gadd_sp(args_size);
    vtop--;
}

#ifdef TCC_TARGET_PE
#define FUNC_PROLOG_SIZE (10 + USE_EBX)
#else
#define FUNC_PROLOG_SIZE (9 + USE_EBX)
#endif

/* generate function prolog of type 't' */
ST_FUNC void gfunc_prolog(CType *func_type)
{
    int addr, align, size, func_call, fastcall_nb_regs;
    int param_index, param_addr;
    uint8_t *fastcall_regs_ptr;
    Sym *sym;
    CType *type;

    sym = func_type->ref;
    func_call = sym->a.func_call;
    addr = 8;
    loc = 0;
    func_vc = 0;

    if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) {
        fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;
        fastcall_regs_ptr = fastcall_regs;
    } else if (func_call == FUNC_FASTCALLW) {
        fastcall_nb_regs = 2;
        fastcall_regs_ptr = fastcallw_regs;
    } else {
        fastcall_nb_regs = 0;
        fastcall_regs_ptr = NULL;
    }
    param_index = 0;

    ind += FUNC_PROLOG_SIZE;
    func_sub_sp_offset = ind;
    /* if the function returns a structure, then add an
       implicit pointer parameter */
    func_vt = sym->type;
    func_var = (sym->c == FUNC_ELLIPSIS);
#ifdef TCC_TARGET_PE
    size = type_size(&func_vt,&align);
    if (((func_vt.t & VT_BTYPE) == VT_STRUCT)
        && (size > 8 || (size & (size - 1)))) {
#else
    if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
#endif
        /* XXX: fastcall case ? */
        func_vc = addr;
        addr += 4;
        param_index++;
    }
    /* define parameters */
    while ((sym = sym->next) != NULL) {
        type = &sym->type;
        size = type_size(type, &align);
        size = (size + 3) & ~3;
#ifdef FUNC_STRUCT_PARAM_AS_PTR
        /* structs are passed as pointer */
        if ((type->t & VT_BTYPE) == VT_STRUCT) {
            size = 4;
        }
#endif
        if (param_index < fastcall_nb_regs) {
            /* save FASTCALL register */
            loc -= 4;
            o(0x89);     /* movl */
            gen_modrm(fastcall_regs_ptr[param_index], VT_LOCAL, NULL, loc);
            param_addr = loc;
        } else {
            param_addr = addr;
            addr += size;
        }
        sym_push(sym->v & ~SYM_FIELD, type,
                 VT_LOCAL | lvalue_type(type->t), param_addr);
        param_index++;
    }
    func_ret_sub = 0;
    /* pascal type call ? */
    if (func_call == FUNC_STDCALL)
        func_ret_sub = addr - 8;
#ifndef TCC_TARGET_PE
    else if (func_vc)
        func_ret_sub = 4;
#endif

#ifdef CONFIG_TCC_BCHECK
    /* leave some room for bound checking code */
    if (tcc_state->do_bounds_check) {
        func_bound_offset = lbounds_section->data_offset;
        func_bound_ind = ind;
        oad(0xb8, 0); /* lbound section pointer */
        oad(0xb8, 0); /* call to function */
    }
#endif
}

/* generate function epilog */
ST_FUNC void gfunc_epilog(void)
{
    addr_t v, saved_ind;

#ifdef CONFIG_TCC_BCHECK
    if (tcc_state->do_bounds_check
     && func_bound_offset != lbounds_section->data_offset) {
        addr_t saved_ind;
        addr_t *bounds_ptr;
        Sym *sym_data;

        /* add end of table info */
        bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t));
        *bounds_ptr = 0;

        /* generate bound local allocation */
        saved_ind = ind;
        ind = func_bound_ind;
        sym_data = get_sym_ref(&char_pointer_type, lbounds_section, 
                               func_bound_offset, lbounds_section->data_offset);
        greloc(cur_text_section, sym_data,
               ind + 1, R_386_32);
        oad(0xb8, 0); /* mov %eax, xxx */
        gen_static_call(TOK___bound_local_new);
        ind = saved_ind;

        /* generate bound check local freeing */
        o(0x5250); /* save returned value, if any */
        greloc(cur_text_section, sym_data, ind + 1, R_386_32);
        oad(0xb8, 0); /* mov %eax, xxx */
        gen_static_call(TOK___bound_local_delete);
        o(0x585a); /* restore returned value, if any */
    }
#endif

    /* align local size to word & save local variables */
    v = (-loc + 3) & -4;

#if USE_EBX
    o(0x8b);
    gen_modrm(TREG_EBX, VT_LOCAL, NULL, -(v+4));
#endif

    o(0xc9); /* leave */
    if (func_ret_sub == 0) {
        o(0xc3); /* ret */
    } else {
        o(0xc2); /* ret n */
        g(func_ret_sub);
        g(func_ret_sub >> 8);
    }
    saved_ind = ind;
    ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
#ifdef TCC_TARGET_PE
    if (v >= 4096) {
        oad(0xb8, v); /* mov stacksize, %eax */
        gen_static_call(TOK___chkstk); /* call __chkstk, (does the stackframe too) */
    } else
#endif
    {
        o(0xe58955);  /* push %ebp, mov %esp, %ebp */
        o(0xec81);  /* sub esp, stacksize */
        gen_le32(v);
#ifdef TCC_TARGET_PE
        o(0x90);  /* adjust to FUNC_PROLOG_SIZE */
#endif
    }
    o(0x53 * USE_EBX); /* push ebx */
    ind = saved_ind;
}

/* generate a jump to a label */
ST_FUNC int gjmp(int t)
{
    return gjmp2(0xe9, t);
}

/* generate a jump to a fixed address */
ST_FUNC void gjmp_addr(int a)
{
    int r;
    r = a - ind - 2;
    if (r == (char)r) {
        g(0xeb);
        g(r);
    } else {
        oad(0xe9, a - ind - 5);
    }
}

ST_FUNC void gtst_addr(int inv, int a)
{
    int v = vtop->r & VT_VALMASK;
    if (v == VT_CMP) {
    inv ^= (vtop--)->c.i;
    a -= ind + 2;
    if (a == (char)a) {
        g(inv - 32);
        g(a);
    } else {
        g(0x0f);
        oad(inv - 16, a - 4);
    }
    } else if ((v & ~1) == VT_JMP) {
    if ((v & 1) != inv) {
        gjmp_addr(a);
        gsym(vtop->c.i);
    } else {
        gsym(vtop->c.i);
        o(0x05eb);
        gjmp_addr(a);
    }
    vtop--;
    }
}

/* generate a test. set 'inv' to invert test. Stack entry is popped */
ST_FUNC int gtst(int inv, int t)
{
    int v = vtop->r & VT_VALMASK;
    if (nocode_wanted) {
        ;
    } else if (v == VT_CMP) {
        /* fast case : can jump directly since flags are set */
        g(0x0f);
        t = gjmp2((vtop->c.i - 16) ^ inv, t);
    } else if (v == VT_JMP || v == VT_JMPI) {
        /* && or || optimization */
        if ((v & 1) == inv) {
            /* insert vtop->c jump list in t */
            uint32_t n1, n = vtop->c.i;
            if (n) {
                while ((n1 = read32le(cur_text_section->data + n)))
                    n = n1;
                write32le(cur_text_section->data + n, t);
                t = vtop->c.i;
            }
        } else {
            t = gjmp(t);
            gsym(vtop->c.i);
        }
    }
    vtop--;
    return t;
}

/* generate an integer binary operation */
ST_FUNC void gen_opi(int op)
{
    int r, fr, opc, c;

    switch(op) {
    case '+':
    case TOK_ADDC1: /* add with carry generation */
        opc = 0;
    gen_op8:
        if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
            /* constant case */
            vswap();
            r = gv(RC_INT);
            vswap();
            c = vtop->c.i;
            if (c == (char)c) {
                /* generate inc and dec for smaller code */
                if (c==1 && opc==0 && op != TOK_ADDC1) {
                    o (0x40 | r); // inc
                } else if (c==1 && opc==5 && op != TOK_SUBC1) {
                    o (0x48 | r); // dec
                } else {
                    o(0x83);
                    o(0xc0 | (opc << 3) | r);
                    g(c);
                }
            } else {
                o(0x81);
                oad(0xc0 | (opc << 3) | r, c);
            }
        } else {
            gv2(RC_INT, RC_INT);
            r = vtop[-1].r;
            fr = vtop[0].r;
            o((opc << 3) | 0x01);
            o(0xc0 + r + fr * 8); 
        }
        vtop--;
        if (op >= TOK_ULT && op <= TOK_GT) {
            vtop->r = VT_CMP;
            vtop->c.i = op;
        }
        break;
    case '-':
    case TOK_SUBC1: /* sub with carry generation */
        opc = 5;
        goto gen_op8;
    case TOK_ADDC2: /* add with carry use */
        opc = 2;
        goto gen_op8;
    case TOK_SUBC2: /* sub with carry use */
        opc = 3;
        goto gen_op8;
    case '&':
        opc = 4;
        goto gen_op8;
    case '^':
        opc = 6;
        goto gen_op8;
    case '|':
        opc = 1;
        goto gen_op8;
    case '*':
        gv2(RC_INT, RC_INT);
        r = vtop[-1].r;
        fr = vtop[0].r;
        vtop--;
        o(0xaf0f); /* imul fr, r */
        o(0xc0 + fr + r * 8);
        break;
    case TOK_SHL:
        opc = 4;
        goto gen_shift;
    case TOK_SHR:
        opc = 5;
        goto gen_shift;
    case TOK_SAR:
        opc = 7;
    gen_shift:
        opc = 0xc0 | (opc << 3);
        if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
            /* constant case */
            vswap();
            r = gv(RC_INT);
            vswap();
            c = vtop->c.i & 0x1f;
            o(0xc1); /* shl/shr/sar $xxx, r */
            o(opc | r);
            g(c);
        } else {
            /* we generate the shift in ecx */
            gv2(RC_INT, RC_ECX);
            r = vtop[-1].r;
            o(0xd3); /* shl/shr/sar %cl, r */
            o(opc | r);
        }
        vtop--;
        break;
    case '/':
    case TOK_UDIV:
    case TOK_PDIV:
    case '%':
    case TOK_UMOD:
    case TOK_UMULL:
        /* first operand must be in eax */
        /* XXX: need better constraint for second operand */
        gv2(RC_EAX, RC_ECX);
        r = vtop[-1].r;
        fr = vtop[0].r;
        vtop--;
        save_reg(TREG_EDX);
        /* save EAX too if used otherwise */
        save_reg_upstack(TREG_EAX, 1);
        if (op == TOK_UMULL) {
            o(0xf7); /* mul fr */
            o(0xe0 + fr);
            vtop->r2 = TREG_EDX;
            r = TREG_EAX;
        } else {
            if (op == TOK_UDIV || op == TOK_UMOD) {
                o(0xf7d231); /* xor %edx, %edx, div fr, %eax */
                o(0xf0 + fr);
            } else {
                o(0xf799); /* cltd, idiv fr, %eax */
                o(0xf8 + fr);
            }
            if (op == '%' || op == TOK_UMOD)
                r = TREG_EDX;
            else
                r = TREG_EAX;
        }
        vtop->r = r;
        break;
    default:
        opc = 7;
        goto gen_op8;
    }
}

/* generate a floating point operation 'v = t1 op t2' instruction. The
   two operands are guaranteed to have the same floating point type */
/* XXX: need to use ST1 too */
ST_FUNC void gen_opf(int op)
{
    int a, ft, fc, swapped, r;

    /* convert constants to memory references */
    if ((vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
        vswap();
        gv(RC_FLOAT);
        vswap();
    }
    if ((vtop[0].r & (VT_VALMASK | VT_LVAL)) == VT_CONST)
        gv(RC_FLOAT);

    /* must put at least one value in the floating point register */
    if ((vtop[-1].r & VT_LVAL) &&
        (vtop[0].r & VT_LVAL)) {
        vswap();
        gv(RC_FLOAT);
        vswap();
    }
    swapped = 0;
    /* swap the stack if needed so that t1 is the register and t2 is
       the memory reference */
    if (vtop[-1].r & VT_LVAL) {
        vswap();
        swapped = 1;
    }
    if (op >= TOK_ULT && op <= TOK_GT) {
        /* load on stack second operand */
        load(TREG_ST0, vtop);
        save_reg(TREG_EAX); /* eax is used by FP comparison code */
        if (op == TOK_GE || op == TOK_GT)
            swapped = !swapped;
        else if (op == TOK_EQ || op == TOK_NE)
            swapped = 0;
        if (swapped)
            o(0xc9d9); /* fxch %st(1) */
        if (op == TOK_EQ || op == TOK_NE)
            o(0xe9da); /* fucompp */
        else
            o(0xd9de); /* fcompp */
        o(0xe0df); /* fnstsw %ax */
        if (op == TOK_EQ) {
            o(0x45e480); /* and $0x45, %ah */
            o(0x40fC80); /* cmp $0x40, %ah */
        } else if (op == TOK_NE) {
            o(0x45e480); /* and $0x45, %ah */
            o(0x40f480); /* xor $0x40, %ah */
            op = TOK_NE;
        } else if (op == TOK_GE || op == TOK_LE) {
            o(0x05c4f6); /* test $0x05, %ah */
            op = TOK_EQ;
        } else {
            o(0x45c4f6); /* test $0x45, %ah */
            op = TOK_EQ;
        }
        vtop--;
        vtop->r = VT_CMP;
        vtop->c.i = op;
    } else {
        /* no memory reference possible for long double operations */
        if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
            load(TREG_ST0, vtop);
            swapped = !swapped;
        }
        
        switch(op) {
        default:
        case '+':
            a = 0;
            break;
        case '-':
            a = 4;
            if (swapped)
                a++;
            break;
        case '*':
            a = 1;
            break;
        case '/':
            a = 6;
            if (swapped)
                a++;
            break;
        }
        ft = vtop->type.t;
        fc = vtop->c.i;
        if ((ft & VT_BTYPE) == VT_LDOUBLE) {
            o(0xde); /* fxxxp %st, %st(1) */
            o(0xc1 + (a << 3));
        } else {
            /* if saved lvalue, then we must reload it */
            r = vtop->r;
            if ((r & VT_VALMASK) == VT_LLOCAL) {
                SValue v1;
                r = get_reg(RC_INT);
                v1.type.t = VT_INT;
                v1.r = VT_LOCAL | VT_LVAL;
                v1.c.i = fc;
                load(r, &v1);
                fc = 0;
            }

            if ((ft & VT_BTYPE) == VT_DOUBLE)
                o(0xdc);
            else
                o(0xd8);
            gen_modrm(a, r, vtop->sym, fc);
        }
        vtop--;
    }
}

/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
   and 'long long' cases. */
ST_FUNC void gen_cvt_itof(int t)
{
    save_reg(TREG_ST0);
    gv(RC_INT);
    if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
        /* signed long long to float/double/long double (unsigned case
           is handled generically) */
        o(0x50 + vtop->r2); /* push r2 */
        o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
        o(0x242cdf); /* fildll (%esp) */
        o(0x08c483); /* add $8, %esp */
    } else if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == 
               (VT_INT | VT_UNSIGNED)) {
        /* unsigned int to float/double/long double */
        o(0x6a); /* push $0 */
        g(0x00);
        o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
        o(0x242cdf); /* fildll (%esp) */
        o(0x08c483); /* add $8, %esp */
    } else {
        /* int to float/double/long double */
        o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
        o(0x2404db); /* fildl (%esp) */
        o(0x04c483); /* add $4, %esp */
    }
    vtop->r = TREG_ST0;
}

/* convert fp to int 't' type */
ST_FUNC void gen_cvt_ftoi(int t)
{
#if HAVE_FLOAT
    int bt = vtop->type.t & VT_BTYPE;
    if (bt == VT_FLOAT)
        vpush_global_sym(&func_old_type, TOK___fixsfdi);
    else if (bt == VT_LDOUBLE)
        vpush_global_sym(&func_old_type, TOK___fixxfdi);
    else
        vpush_global_sym(&func_old_type, TOK___fixdfdi);
    vswap();
    gfunc_call(1);
    vpushi(0);
    vtop->r = REG_IRET;
    vtop->r2 = REG_LRET;
#endif // HAVE_FLOAT
}

/* convert from one floating point type to another */
ST_FUNC void gen_cvt_ftof(int t)
{
    /* all we have to do on i386 is to put the float in a register */
    gv(RC_FLOAT);
}

/* computed goto support */
ST_FUNC void ggoto(void)
{
    gcall_or_jmp(1);
    vtop--;
}

/* bound check support functions */
#ifdef CONFIG_TCC_BCHECK

/* generate a bounded pointer addition */
ST_FUNC void gen_bounded_ptr_add(void)
{
    /* prepare fast i386 function call (args in eax and edx) */
    gv2(RC_EAX, RC_EDX);
    /* save all temporary registers */
    vtop -= 2;
    save_regs(0);
    /* do a fast function call */
    gen_static_call(TOK___bound_ptr_add);
    /* returned pointer is in eax */
    vtop++;
    vtop->r = TREG_EAX | VT_BOUNDED;
    /* address of bounding function call point */
    vtop->c.i = (cur_text_section->reloc->data_offset - sizeof(Elf32_Rel));
}

/* patch pointer addition in vtop so that pointer dereferencing is
   also tested */
ST_FUNC void gen_bounded_ptr_deref(void)
{
    addr_t func;
    int  size, align;
    Elf32_Rel *rel;
    Sym *sym;

    size = 0;
    /* XXX: put that code in generic part of tcc */
    if (!is_float(vtop->type.t)) {
        if (vtop->r & VT_LVAL_BYTE)
            size = 1;
        else if (vtop->r & VT_LVAL_SHORT)
            size = 2;
    }
    if (!size)
        size = type_size(&vtop->type, &align);
    switch(size) {
    case  1: func = TOK___bound_ptr_indir1; break;
    case  2: func = TOK___bound_ptr_indir2; break;
    case  4: func = TOK___bound_ptr_indir4; break;
    case  8: func = TOK___bound_ptr_indir8; break;
    case 12: func = TOK___bound_ptr_indir12; break;
    case 16: func = TOK___bound_ptr_indir16; break;
    default:
        tcc_error("unhandled size when dereferencing bounded pointer");
        func = 0;
        break;
    }

    /* patch relocation */
    /* XXX: find a better solution ? */
    rel = (Elf32_Rel *)(cur_text_section->reloc->data + vtop->c.i);
    sym = external_global_sym(func, &func_old_type, 0);
    if (!sym->c)
        put_extern_sym(sym, NULL, 0, 0);
    rel->r_info = ELF32_R_INFO(sym->c, ELF32_R_TYPE(rel->r_info));
}
#endif

/* Save the stack pointer onto the stack */
ST_FUNC void gen_vla_sp_save(int addr) {
    /* mov %esp,addr(%ebp)*/
    o(0x89);
    gen_modrm(TREG_ESP, VT_LOCAL, NULL, addr);
}

/* Restore the SP from a location on the stack */
ST_FUNC void gen_vla_sp_restore(int addr) {
    o(0x8b);
    gen_modrm(TREG_ESP, VT_LOCAL, NULL, addr);
}

/* Subtract from the stack pointer, and push the resulting value onto the stack */
ST_FUNC void gen_vla_alloc(CType *type, int align) {
#ifdef TCC_TARGET_PE
    /* alloca does more than just adjust %rsp on Windows */
    vpush_global_sym(&func_old_type, TOK_alloca);
    vswap(); /* Move alloca ref past allocation size */
    gfunc_call(1);
#else
    int r;
    r = gv(RC_INT); /* allocation size */
    /* sub r,%rsp */
    o(0x2b);
    o(0xe0 | r);
    /* We align to 16 bytes rather than align */
    /* and ~15, %esp */
    o(0xf0e483);
    vpop();
#endif
}

/* end of X86 code generator */
/*************************************************************/
#endif
/*************************************************************/

https://gitlab.com/janneke/tinycc/-/blob/ff2210b308321f27ee07476d07f24b5095602b17/i386-link.c

File: ../git/live-bootstrap/sysa/tcc-0.9.26/build/tcc-0.9.26-1136-g5bba73cc/i386-link.c used in: Step 378, Step 395, Step 407, Step 419, Step 431, Step 443, Step 455
#ifdef TARGET_DEFS_ONLY

#define EM_TCC_TARGET EM_386

/* relocation type for 32 bit data relocation */
#define R_DATA_32   R_386_32
#define R_DATA_PTR  R_386_32
#define R_JMP_SLOT  R_386_JMP_SLOT
#define R_GLOB_DAT  R_386_GLOB_DAT
#define R_COPY      R_386_COPY
#define R_RELATIVE  R_386_RELATIVE

#define R_NUM       R_386_NUM

#define ELF_START_ADDR 0x08048000
#define ELF_PAGE_SIZE  0x1000

#define PCRELATIVE_DLLPLT 0
#define RELOCATE_DLLPLT 0

#else /* !TARGET_DEFS_ONLY */

#ifndef _TCC_H
#include "tcc.h"
#endif

/* Returns 1 for a code relocation, 0 for a data relocation. For unknown
   relocations, returns -1. */
int code_reloc (int reloc_type)
{
    switch (reloc_type) {
    case R_386_RELATIVE:
    case R_386_16:
        case R_386_32:
    case R_386_GOTPC:
    case R_386_GOTOFF:
    case R_386_GOT32:
    case R_386_GOT32X:
    case R_386_GLOB_DAT:
    case R_386_COPY:
            return 0;

    case R_386_PC16:
    case R_386_PC32:
    case R_386_PLT32:
    case R_386_JMP_SLOT:
            return 1;
    }

    tcc_error ("Unknown relocation type: %d", reloc_type);
    return -1;
}

/* Returns an enumerator to describe whether and when the relocation needs a
   GOT and/or PLT entry to be created. See tcc.h for a description of the
   different values. */
int gotplt_entry_type (int reloc_type)
{
    switch (reloc_type) {
    case R_386_RELATIVE:
    case R_386_16:
    case R_386_GLOB_DAT:
    case R_386_JMP_SLOT:
    case R_386_COPY:
            return NO_GOTPLT_ENTRY;

        case R_386_32:
        /* This relocations shouldn't normally need GOT or PLT
           slots if it weren't for simplicity in the code generator.
           See our caller for comments.  */
            return AUTO_GOTPLT_ENTRY;

    case R_386_PC16:
    case R_386_PC32:
            return AUTO_GOTPLT_ENTRY;

    case R_386_GOTPC:
    case R_386_GOTOFF:
            return BUILD_GOT_ONLY;

    case R_386_GOT32:
    case R_386_GOT32X:
    case R_386_PLT32:
            return ALWAYS_GOTPLT_ENTRY;
    }

    tcc_error ("Unknown relocation type: %d", reloc_type);
    return -1;
}

ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)
{
    Section *plt = s1->plt;
    uint8_t *p;
    int modrm;
    unsigned plt_offset, relofs;

    /* on i386 if we build a DLL, we add a %ebx offset */
    if (s1->output_type == TCC_OUTPUT_DLL)
        modrm = 0xa3;
    else
        modrm = 0x25;

    /* empty PLT: create PLT0 entry that pushes the library identifier
       (GOT + PTR_SIZE) and jumps to ld.so resolution routine
       (GOT + 2 * PTR_SIZE) */
    if (plt->data_offset == 0) {
        p = section_ptr_add(plt, 16);
        p[0] = 0xff; /* pushl got + PTR_SIZE */
        p[1] = modrm + 0x10;
        write32le(p + 2, PTR_SIZE);
        p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
        p[7] = modrm;
        write32le(p + 8, PTR_SIZE * 2);
    }
    plt_offset = plt->data_offset;

    /* The PLT slot refers to the relocation entry it needs via offset.
       The reloc entry is created below, so its offset is the current
       data_offset */
    relofs = s1->got->reloc ? s1->got->reloc->data_offset : 0;

    /* Jump to GOT entry where ld.so initially put the address of ip + 4 */
    p = section_ptr_add(plt, 16);
    p[0] = 0xff; /* jmp *(got + x) */
    p[1] = modrm;
    write32le(p + 2, got_offset);
    p[6] = 0x68; /* push $xxx */
    write32le(p + 7, relofs);
    p[11] = 0xe9; /* jmp plt_start */
    write32le(p + 12, -(plt->data_offset));
    return plt_offset;
}

/* relocate the PLT: compute addresses and offsets in the PLT now that final
   address for PLT and GOT are known (see fill_program_header) */
ST_FUNC void relocate_plt(TCCState *s1)
{
    uint8_t *p, *p_end;

    if (!s1->plt)
      return;

    p = s1->plt->data;
    p_end = p + s1->plt->data_offset;

    if (p < p_end) {
        add32le(p + 2, s1->got->sh_addr);
        add32le(p + 8, s1->got->sh_addr);
        p += 16;
        while (p < p_end) {
            add32le(p + 2, s1->got->sh_addr);
            p += 16;
        }
    }
}

static ElfW_Rel *qrel; /* ptr to next reloc entry reused */

void relocate_init(Section *sr)
{
    qrel = (ElfW_Rel *) sr->data;
}

void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
{
    int sym_index, esym_index;

    sym_index = ELFW(R_SYM)(rel->r_info);

    switch (type) {
        case R_386_32:
            if (s1->output_type == TCC_OUTPUT_DLL) {
                esym_index = s1->sym_attrs[sym_index].dyn_index;
                qrel->r_offset = rel->r_offset;
                if (esym_index) {
                    qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32);
                    qrel++;
                    return;
                } else {
                    qrel->r_info = ELFW(R_INFO)(0, R_386_RELATIVE);
                    qrel++;
                }
            }
            add32le(ptr, val);
            return;
        case R_386_PC32:
            if (s1->output_type == TCC_OUTPUT_DLL) {
                /* DLL relocation */
                esym_index = s1->sym_attrs[sym_index].dyn_index;
                if (esym_index) {
                    qrel->r_offset = rel->r_offset;
                    qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32);
                    qrel++;
                    return;
                }
            }
            add32le(ptr, val - addr);
            return;
        case R_386_PLT32:
            add32le(ptr, val - addr);
            return;
        case R_386_GLOB_DAT:
        case R_386_JMP_SLOT:
            write32le(ptr, val);
            return;
        case R_386_GOTPC:
            add32le(ptr, s1->got->sh_addr - addr);
            return;
        case R_386_GOTOFF:
            add32le(ptr, val - s1->got->sh_addr);
            return;
        case R_386_GOT32:
        case R_386_GOT32X:
            /* we load the got offset */
            add32le(ptr, s1->sym_attrs[sym_index].got_offset);
            return;
        case R_386_16:
            if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) {
            output_file:
                tcc_error("can only produce 16-bit binary files");
            }
            write16le(ptr, read16le(ptr) + val);
            return;
        case R_386_PC16:
            if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY)
                goto output_file;
            write16le(ptr, read16le(ptr) + val - addr);
            return;
        case R_386_RELATIVE:
            /* do nothing */
            return;
        case R_386_COPY:
            /* This relocation must copy initialized data from the library
            to the program .bss segment. Currently made like for ARM
            (to remove noise of default case). Is this true?
            */
            return;
        default:
            fprintf(stderr,"FIXME: handle reloc type %d at %x [%p] to %x\n",
                type, (unsigned)addr, ptr, (unsigned)val);
            return;
    }
}

#endif /* !TARGET_DEFS_ONLY */

https://gitlab.com/janneke/tinycc/-/blob/ff2210b308321f27ee07476d07f24b5095602b17/i386-asm.c

File: ../git/live-bootstrap/sysa/tcc-0.9.26/build/tcc-0.9.26-1136-g5bba73cc/i386-asm.c used in: Step 378, Step 395, Step 407, Step 419, Step 431, Step 443, Step 455
/*
 *  i386 specific functions for TCC assembler
 *
 *  Copyright (c) 2001, 2002 Fabrice Bellard
 *  Copyright (c) 2009 Frédéric Feret (x86_64 support)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef _TCC_H
#include "tcc.h"
#endif

#define MAX_OPERANDS 3

#define TOK_ASM_first TOK_ASM_clc
#define TOK_ASM_last TOK_ASM_emms
#define TOK_ASM_alllast TOK_ASM_subps

#define OPC_B          0x01  /* only used with OPC_WL */
#define OPC_WL         0x02  /* accepts w, l or no suffix */
#define OPC_BWL        (OPC_B | OPC_WL) /* accepts b, w, l or no suffix */
#define OPC_REG        0x04 /* register is added to opcode */
#define OPC_MODRM      0x08 /* modrm encoding */

#define OPCT_MASK      0x70
#define OPC_FWAIT      0x10 /* add fwait opcode */
#define OPC_SHIFT      0x20 /* shift opcodes */
#define OPC_ARITH      0x30 /* arithmetic opcodes */
#define OPC_FARITH     0x40 /* FPU arithmetic opcodes */
#define OPC_TEST       0x50 /* test opcodes */
#define OPCT_IS(v,i) (((v) & OPCT_MASK) == (i))

#define OPC_0F        0x100 /* Is secondary map (0x0f prefix) */
#define OPC_48        0x200 /* Always has REX prefix */
#ifdef TCC_TARGET_X86_64
# define OPC_WLQ     0x1000  /* accepts w, l, q or no suffix */
# define OPC_BWLQ    (OPC_B | OPC_WLQ) /* accepts b, w, l, q or no suffix */
# define OPC_WLX     OPC_WLQ
# define OPC_BWLX    OPC_BWLQ
#else
# define OPC_WLX     OPC_WL
# define OPC_BWLX    OPC_BWL
#endif

#define OPC_GROUP_SHIFT 13

/* in order to compress the operand type, we use specific operands and
   we or only with EA  */
enum {
    OPT_REG8=0, /* warning: value is hardcoded from TOK_ASM_xxx */
    OPT_REG16,  /* warning: value is hardcoded from TOK_ASM_xxx */
    OPT_REG32,  /* warning: value is hardcoded from TOK_ASM_xxx */
#ifdef TCC_TARGET_X86_64
    OPT_REG64,  /* warning: value is hardcoded from TOK_ASM_xxx */
#endif
    OPT_MMX,    /* warning: value is hardcoded from TOK_ASM_xxx */
    OPT_SSE,    /* warning: value is hardcoded from TOK_ASM_xxx */
    OPT_CR,     /* warning: value is hardcoded from TOK_ASM_xxx */
    OPT_TR,     /* warning: value is hardcoded from TOK_ASM_xxx */
    OPT_DB,     /* warning: value is hardcoded from TOK_ASM_xxx */
    OPT_SEG,
    OPT_ST,
#ifdef TCC_TARGET_X86_64
    OPT_REG8_LOW, /* %spl,%bpl,%sil,%dil, encoded like ah,ch,dh,bh, but
             with REX prefix, not used in insn templates */
#endif
    OPT_IM8,
    OPT_IM8S,
    OPT_IM16,
    OPT_IM32,
#ifdef TCC_TARGET_X86_64
    OPT_IM64,
#endif
    OPT_EAX,    /* %al, %ax, %eax or %rax register */
    OPT_ST0,    /* %st(0) register */
    OPT_CL,     /* %cl register */
    OPT_DX,     /* %dx register */
    OPT_ADDR,   /* OP_EA with only offset */
    OPT_INDIR,  /* *(expr) */
    /* composite types */
    OPT_COMPOSITE_FIRST,
    OPT_IM,     /* IM8 | IM16 | IM32 */
    OPT_REG,    /* REG8 | REG16 | REG32 | REG64 */
    OPT_REGW,   /* REG16 | REG32 | REG64 */
    OPT_IMW,    /* IM16 | IM32 */
    OPT_MMXSSE, /* MMX | SSE */
    OPT_DISP,   /* Like OPT_ADDR, but emitted as displacement (for jumps) */
    OPT_DISP8,  /* Like OPT_ADDR, but only 8bit (short jumps) */
    /* can be ored with any OPT_xxx */
    OPT_EA = 0x80
};

#define OP_REG8   (1 << OPT_REG8)
#define OP_REG16  (1 << OPT_REG16)
#define OP_REG32  (1 << OPT_REG32)
#define OP_MMX    (1 << OPT_MMX)
#define OP_SSE    (1 << OPT_SSE)
#define OP_CR     (1 << OPT_CR)
#define OP_TR     (1 << OPT_TR)
#define OP_DB     (1 << OPT_DB)
#define OP_SEG    (1 << OPT_SEG)
#define OP_ST     (1 << OPT_ST)
#define OP_IM8    (1 << OPT_IM8)
#define OP_IM8S   (1 << OPT_IM8S)
#define OP_IM16   (1 << OPT_IM16)
#define OP_IM32   (1 << OPT_IM32)
#define OP_EAX    (1 << OPT_EAX)
#define OP_ST0    (1 << OPT_ST0)
#define OP_CL     (1 << OPT_CL)
#define OP_DX     (1 << OPT_DX)
#define OP_ADDR   (1 << OPT_ADDR)
#define OP_INDIR  (1 << OPT_INDIR)
#ifdef TCC_TARGET_X86_64
# define OP_REG64 (1 << OPT_REG64)
# define OP_REG8_LOW (1 << OPT_REG8_LOW)
# define OP_IM64  (1 << OPT_IM64)
# define OP_EA32  (OP_EA << 1)
#else
# define OP_REG64 0
# define OP_REG8_LOW 0
# define OP_IM64  0
# define OP_EA32  0
#endif

#define OP_EA     0x40000000
#define OP_REG    (OP_REG8 | OP_REG16 | OP_REG32 | OP_REG64)

#ifdef TCC_TARGET_X86_64
# define TREG_XAX   TREG_RAX
# define TREG_XCX   TREG_RCX
# define TREG_XDX   TREG_RDX
#else
# define TREG_XAX   TREG_EAX
# define TREG_XCX   TREG_ECX
# define TREG_XDX   TREG_EDX
#endif

typedef struct ASMInstr {
    uint16_t sym;
    uint16_t opcode;
    uint16_t instr_type;
    uint8_t nb_ops;
    uint8_t op_type[MAX_OPERANDS]; /* see OP_xxx */
} ASMInstr;

typedef struct Operand {
    uint32_t type;
    int8_t  reg; /* register, -1 if none */
    int8_t  reg2; /* second register, -1 if none */
    uint8_t shift;
    ExprValue e;
} Operand;

static const uint8_t reg_to_size[9] = {
/*
    [OP_REG8] = 0,
    [OP_REG16] = 1,
    [OP_REG32] = 2,
#ifdef TCC_TARGET_X86_64
    [OP_REG64] = 3,
#endif
*/
    0, 0, 1, 0, 2, 0, 0, 0, 3
};

#define NB_TEST_OPCODES 30

static const uint8_t test_bits[NB_TEST_OPCODES] = {
 0x00, /* o */
 0x01, /* no */
 0x02, /* b */
 0x02, /* c */
 0x02, /* nae */
 0x03, /* nb */
 0x03, /* nc */
 0x03, /* ae */
 0x04, /* e */
 0x04, /* z */
 0x05, /* ne */
 0x05, /* nz */
 0x06, /* be */
 0x06, /* na */
 0x07, /* nbe */
 0x07, /* a */
 0x08, /* s */
 0x09, /* ns */
 0x0a, /* p */
 0x0a, /* pe */
 0x0b, /* np */
 0x0b, /* po */
 0x0c, /* l */
 0x0c, /* nge */
 0x0d, /* nl */
 0x0d, /* ge */
 0x0e, /* le */
 0x0e, /* ng */
 0x0f, /* nle */
 0x0f, /* g */
};

static const uint8_t segment_prefixes[] = {
 0x26, /* es */
 0x2e, /* cs */
 0x36, /* ss */
 0x3e, /* ds */
 0x64, /* fs */
 0x65  /* gs */
};

static const ASMInstr asm_instrs[] = {
#define ALT(x) x
/* This removes a 0x0f in the second byte */
#if HAVE_LONG_LONG
#define O(o) ((uint64_t) ((((o) & 0xff00) == 0x0f00) ? ((((o) >> 8) & ~0xff) | ((o) & 0xff)) : (o)))
#else
#define O(o) ((uint32_t) ((((o) & 0xff00) == 0x0f00) ? ((((o) >> 8) & ~0xff) | ((o) & 0xff)) : (o)))
#endif
/* This constructs instr_type from opcode, type and group.  */
#define T(o,i,g) ((i) | ((g) << OPC_GROUP_SHIFT) | ((((o) & 0xff00) == 0x0f00) ? OPC_0F : 0))
#define DEF_ASM_OP0(name, opcode)
#define DEF_ASM_OP0L(name, opcode, group, instr_type) { TOK_ASM_ ## name, O(opcode), T(opcode, instr_type, group), 0, { 0 } },
#define DEF_ASM_OP1(name, opcode, group, instr_type, op0) { TOK_ASM_ ## name, O(opcode), T(opcode, instr_type, group), 1, { op0 }},
#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) { TOK_ASM_ ## name, O(opcode), T(opcode, instr_type, group), 2, { op0, op1 }},
#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) { TOK_ASM_ ## name, O(opcode), T(opcode, instr_type, group), 3, { op0, op1, op2 }},
#ifdef TCC_TARGET_X86_64
# include "x86_64-asm.h"
#else
# include "i386-asm.h"
#endif
    /* last operation */
    { 0, },
};

static const uint16_t op0_codes[] = {
#define ALT(x)
#define DEF_ASM_OP0(x, opcode) opcode,
#define DEF_ASM_OP0L(name, opcode, group, instr_type)
#define DEF_ASM_OP1(name, opcode, group, instr_type, op0)
#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1)
#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2)
#ifdef TCC_TARGET_X86_64
# include "x86_64-asm.h"
#else
# include "i386-asm.h"
#endif
};

static inline int get_reg_shift(TCCState *s1)
{
    int shift, v;
    v = asm_int_expr(s1);
    switch(v) {
    case 1:
        shift = 0;
        break;
    case 2:
        shift = 1;
        break;
    case 4:
        shift = 2;
        break;
    case 8:
        shift = 3;
        break;
    default:
        expect("1, 2, 4 or 8 constant");
        shift = 0;
        break;
    }
    return shift;
}

#ifdef TCC_TARGET_X86_64
static int asm_parse_numeric_reg(int t, unsigned int *type)
{
    int reg = -1;
    if (t >= TOK_IDENT && t < tok_ident) {
    const char *s = table_ident[t - TOK_IDENT]->str;
    char c;
    *type = OP_REG64;
    if (*s == 'c') {
        s++;
        *type = OP_CR;
    }
    if (*s++ != 'r')
      return -1;
    /* Don't allow leading '0'.  */
    if ((c = *s++) >= '1' && c <= '9')
      reg = c - '0';
    else
      return -1;
    if ((c = *s) >= '0' && c <= '5')
      s++, reg = reg * 10 + c - '0';
    if (reg > 15)
      return -1;
    if ((c = *s) == 0)
      ;
    else if (*type != OP_REG64)
      return -1;
    else if (c == 'b' && !s[1])
      *type = OP_REG8;
    else if (c == 'w' && !s[1])
      *type = OP_REG16;
    else if (c == 'd' && !s[1])
      *type = OP_REG32;
    else
      return -1;
    }
    return reg;
}
#endif

static int asm_parse_reg(unsigned int *type)
{
    int reg = 0;
    *type = 0;
    if (tok != '%')
        goto error_32;
    next();
    if (tok >= TOK_ASM_eax && tok <= TOK_ASM_edi) {
        reg = tok - TOK_ASM_eax;
    *type = OP_REG32;
#ifdef TCC_TARGET_X86_64
    } else if (tok >= TOK_ASM_rax && tok <= TOK_ASM_rdi) {
        reg = tok - TOK_ASM_rax;
    *type = OP_REG64;
    } else if (tok == TOK_ASM_rip) {
        reg = -2; /* Probably should use different escape code. */
    *type = OP_REG64;
    } else if ((reg = asm_parse_numeric_reg(tok, type)) >= 0
           && (*type == OP_REG32 || *type == OP_REG64)) {
    ;
#endif
    } else {
    error_32:
        expect("register");
    }
    next();
    return reg;
}

static void parse_operand(TCCState *s1, Operand *op)
{
    ExprValue e;
    int reg, indir;
    const char *p;

    indir = 0;
    if (tok == '*') {
        next();
        indir = OP_INDIR;
    }

    if (tok == '%') {
        next();
        if (tok >= TOK_ASM_al && tok <= TOK_ASM_db7) {
            reg = tok - TOK_ASM_al;
            op->type = 1 << (reg >> 3); /* WARNING: do not change constant order */
            op->reg = reg & 7;
            if ((op->type & OP_REG) && op->reg == TREG_XAX)
                op->type |= OP_EAX;
            else if (op->type == OP_REG8 && op->reg == TREG_XCX)
                op->type |= OP_CL;
            else if (op->type == OP_REG16 && op->reg == TREG_XDX)
                op->type |= OP_DX;
        } else if (tok >= TOK_ASM_dr0 && tok <= TOK_ASM_dr7) {
            op->type = OP_DB;
            op->reg = tok - TOK_ASM_dr0;
        } else if (tok >= TOK_ASM_es && tok <= TOK_ASM_gs) {
            op->type = OP_SEG;
            op->reg = tok - TOK_ASM_es;
        } else if (tok == TOK_ASM_st) {
            op->type = OP_ST;
            op->reg = 0;
            next();
            if (tok == '(') {
                next();
                if (tok != TOK_PPNUM)
                    goto reg_error;
                p = tokc.str.data;
                reg = p[0] - '0';
                if ((unsigned)reg >= 8 || p[1] != '\0')
                    goto reg_error;
                op->reg = reg;
                next();
                skip(')');
            }
            if (op->reg == 0)
                op->type |= OP_ST0;
            goto no_skip;
#ifdef TCC_TARGET_X86_64
    } else if (tok >= TOK_ASM_spl && tok <= TOK_ASM_dil) {
        op->type = OP_REG8 | OP_REG8_LOW;
        op->reg = 4 + tok - TOK_ASM_spl;
        } else if ((op->reg = asm_parse_numeric_reg(tok, &op->type)) >= 0) {
        ;
#endif
        } else {
        reg_error:
            tcc_error("unknown register %%%s", get_tok_str(tok, &tokc));
        }
        next();
    no_skip: ;
    } else if (tok == '$') {
        /* constant value */
        next();
        asm_expr(s1, &e);
        op->type = OP_IM32;
        op->e = e;
        if (!op->e.sym) {
            if (op->e.v == (uint8_t)op->e.v)
                op->type |= OP_IM8;
            if (op->e.v == (int8_t)op->e.v)
                op->type |= OP_IM8S;
            if (op->e.v == (uint16_t)op->e.v)
                op->type |= OP_IM16;
#ifdef TCC_TARGET_X86_64
            if (op->e.v != (int32_t)op->e.v && op->e.v != (uint32_t)op->e.v)
                op->type = OP_IM64;
#endif
        }
    } else {
        /* address(reg,reg2,shift) with all variants */
        op->type = OP_EA;
        op->reg = -1;
        op->reg2 = -1;
        op->shift = 0;
        if (tok != '(') {
            asm_expr(s1, &e);
            op->e = e;
        } else {
            next();
            if (tok == '%') {
                unget_tok('(');
                op->e.v = 0;
                op->e.sym = NULL;
            } else {
                /* bracketed offset expression */
                asm_expr(s1, &e);
                if (tok != ')')
                    expect(")");
                next();
                op->e.v = e.v;
                op->e.sym = e.sym;
            }
        op->e.pcrel = 0;
        }
        if (tok == '(') {
        unsigned int type = 0;
            next();
            if (tok != ',') {
                op->reg = asm_parse_reg(&type);
            }
            if (tok == ',') {
                next();
                if (tok != ',') {
                    op->reg2 = asm_parse_reg(&type);
                }
                if (tok == ',') {
                    next();
                    op->shift = get_reg_shift(s1);
                }
            }
        if (type & OP_REG32)
            op->type |= OP_EA32;
            skip(')');
        }
        if (op->reg == -1 && op->reg2 == -1)
            op->type |= OP_ADDR;
    }
    op->type |= indir;
}

/* XXX: unify with C code output ? */
ST_FUNC void gen_expr32(ExprValue *pe)
{
    if (pe->pcrel)
        /* If PC-relative, always set VT_SYM, even without symbol,
       so as to force a relocation to be emitted.  */
    gen_addrpc32(VT_SYM, pe->sym, pe->v);
    else
    gen_addr32(pe->sym ? VT_SYM : 0, pe->sym, pe->v);
}

#ifdef TCC_TARGET_X86_64
ST_FUNC void gen_expr64(ExprValue *pe)
{
    gen_addr64(pe->sym ? VT_SYM : 0, pe->sym, pe->v);
}
#endif

/* XXX: unify with C code output ? */
static void gen_disp32(ExprValue *pe)
{
    Sym *sym = pe->sym;
    if (sym && sym->r == cur_text_section->sh_num) {
        /* same section: we can output an absolute value. Note
           that the TCC compiler behaves differently here because
           it always outputs a relocation to ease (future) code
           elimination in the linker */
        gen_le32(pe->v + sym->jnext - ind - 4);
    } else {
        if (sym && sym->type.t == VT_VOID) {
            sym->type.t = VT_FUNC;
            sym->type.ref = NULL;
        }
        gen_addrpc32(VT_SYM, sym, pe->v);
    }
}

/* generate the modrm operand */
static inline int asm_modrm(int reg, Operand *op)
{
    int mod, reg1, reg2, sib_reg1;

    if (op->type & (OP_REG | OP_MMX | OP_SSE)) {
        g(0xc0 + (reg << 3) + op->reg);
    } else if (op->reg == -1 && op->reg2 == -1) {
        /* displacement only */
#ifdef TCC_TARGET_X86_64
    g(0x04 + (reg << 3));
    g(0x25);
#else
    g(0x05 + (reg << 3));
#endif
    gen_expr32(&op->e);
#ifdef TCC_TARGET_X86_64
    } else if (op->reg == -2) {
        ExprValue *pe = &op->e;
        g(0x05 + (reg << 3));
        gen_addrpc32(pe->sym ? VT_SYM : 0, pe->sym, pe->v);
        return ind;
#endif
    } else {
        sib_reg1 = op->reg;
        /* fist compute displacement encoding */
        if (sib_reg1 == -1) {
            sib_reg1 = 5;
            mod = 0x00;
        } else if (op->e.v == 0 && !op->e.sym && op->reg != 5) {
            mod = 0x00;
        } else if (op->e.v == (int8_t)op->e.v && !op->e.sym) {
            mod = 0x40;
        } else {
            mod = 0x80;
        }
        /* compute if sib byte needed */
        reg1 = op->reg;
        if (op->reg2 != -1)
            reg1 = 4;
        g(mod + (reg << 3) + reg1);
        if (reg1 == 4) {
            /* add sib byte */
            reg2 = op->reg2;
            if (reg2 == -1)
                reg2 = 4; /* indicate no index */
            g((op->shift << 6) + (reg2 << 3) + sib_reg1);
        }
        /* add offset */
        if (mod == 0x40) {
            g(op->e.v);
        } else if (mod == 0x80 || op->reg == -1) {
        gen_expr32(&op->e);
        }
    }
    return 0;
}

#ifdef TCC_TARGET_X86_64
#define REX_W 0x48
#define REX_R 0x44
#define REX_X 0x42
#define REX_B 0x41

static void asm_rex(int width64, Operand *ops, int nb_ops, int *op_type,
            int regi, int rmi)
{
  unsigned char rex = width64 ? 0x48 : 0;
  int saw_high_8bit = 0;
  int i;
  if (rmi == -1) {
      /* No mod/rm byte, but we might have a register op nevertheless
         (we will add it to the opcode later).  */
      for(i = 0; i < nb_ops; i++) {
      if (op_type[i] & (OP_REG | OP_ST)) {
          if (ops[i].reg >= 8) {
          rex |= REX_B;
          ops[i].reg -= 8;
          } else if (ops[i].type & OP_REG8_LOW)
          rex |= 0x40;
          else if (ops[i].type & OP_REG8 && ops[i].reg >= 4)
          /* An 8 bit reg >= 4 without REG8 is ah/ch/dh/bh */
          saw_high_8bit = ops[i].reg;
          break;
      }
      }
  } else {
      if (regi != -1) {
      if (ops[regi].reg >= 8) {
          rex |= REX_R;
          ops[regi].reg -= 8;
      } else if (ops[regi].type & OP_REG8_LOW)
          rex |= 0x40;
      else if (ops[regi].type & OP_REG8 && ops[regi].reg >= 4)
          /* An 8 bit reg >= 4 without REG8 is ah/ch/dh/bh */
          saw_high_8bit = ops[regi].reg;
      }
      if (ops[rmi].type & (OP_REG | OP_MMX | OP_SSE | OP_CR | OP_EA)) {
      if (ops[rmi].reg >= 8) {
          rex |= REX_B;
          ops[rmi].reg -= 8;
      } else if (ops[rmi].type & OP_REG8_LOW)
          rex |= 0x40;
      else if (ops[rmi].type & OP_REG8 && ops[rmi].reg >= 4)
          /* An 8 bit reg >= 4 without REG8 is ah/ch/dh/bh */
          saw_high_8bit = ops[rmi].reg;
      }
      if (ops[rmi].type & OP_EA && ops[rmi].reg2 >= 8) {
      rex |= REX_X;
      ops[rmi].reg2 -= 8;
      }
  }
  if (rex) {
      if (saw_high_8bit)
      tcc_error("can't encode register %%%ch when REX prefix is required",
            "acdb"[saw_high_8bit-4]);
      g(rex);
  }
}
#endif

static void maybe_print_stats (void)
{
  static int already = 1;
  if (!already)
    /* print stats about opcodes */
    {
        const struct ASMInstr *pa;
        int freq[4];
        int op_vals[500];
        int nb_op_vals, i, j;

    already = 1;
        nb_op_vals = 0;
        memset(freq, 0, sizeof(freq));
        for(pa = asm_instrs; pa->sym != 0; pa++) {
            freq[pa->nb_ops]++;
            //for(i=0;i<pa->nb_ops;i++) {
                for(j=0;j<nb_op_vals;j++) {
                    //if (pa->op_type[i] == op_vals[j])
                    if (pa->instr_type == op_vals[j])
                        goto found;
                }
                //op_vals[nb_op_vals++] = pa->op_type[i];
                op_vals[nb_op_vals++] = pa->instr_type;
            found: ;
            //}
        }
        for(i=0;i<nb_op_vals;i++) {
            int v = op_vals[i];
            //if ((v & (v - 1)) != 0)
                printf("%3d: %08x\n", i, v);
        }
        printf("size=%d nb=%d f0=%d f1=%d f2=%d f3=%d\n",
               (int)sizeof(asm_instrs),
           (int)sizeof(asm_instrs) / (int)sizeof(ASMInstr),
               freq[0], freq[1], freq[2], freq[3]);
    }
}

ST_FUNC void asm_opcode(TCCState *s1, int opcode)
{
    const ASMInstr *pa;
    int i, modrm_index, modreg_index, reg, v, op1, seg_prefix, pc;
    int nb_ops, s;
    Operand ops[MAX_OPERANDS], *pop;
    int op_type[3]; /* decoded op type */
    int alltypes;   /* OR of all operand types */
    int autosize;
    int p66;
#ifdef TCC_TARGET_X86_64
    int rex64;
#endif

    maybe_print_stats();
    /* force synthetic ';' after prefix instruction, so we can handle */
    /* one-line things like "rep stosb" instead of only "rep\nstosb" */
    if (opcode >= TOK_ASM_wait && opcode <= TOK_ASM_repnz)
        unget_tok(';');

    /* get operands */
    pop = ops;
    nb_ops = 0;
    seg_prefix = 0;
    alltypes = 0;
    for(;;) {
        if (tok == ';' || tok == TOK_LINEFEED)
            break;
        if (nb_ops >= MAX_OPERANDS) {
            tcc_error("incorrect number of operands");
        }
        parse_operand(s1, pop);
        if (tok == ':') {
           if (pop->type != OP_SEG || seg_prefix)
               tcc_error("incorrect prefix");
           seg_prefix = segment_prefixes[pop->reg];
           next();
           parse_operand(s1, pop);
           if (!(pop->type & OP_EA)) {
               tcc_error("segment prefix must be followed by memory reference");
           }
        }
        pop++;
        nb_ops++;
        if (tok != ',')
            break;
        next();
    }

    s = 0; /* avoid warning */

    /* optimize matching by using a lookup table (no hashing is needed
       !) */
    for(pa = asm_instrs; pa->sym != 0; pa++) {
    int it = pa->instr_type & OPCT_MASK;
        s = 0;
        if (it == OPC_FARITH) {
            v = opcode - pa->sym;
            if (!((unsigned)v < 8 * 6 && (v % 6) == 0))
                continue;
        } else if (it == OPC_ARITH) {
            if (!(opcode >= pa->sym && opcode < pa->sym + 8*NBWLX))
                continue;
            s = (opcode - pa->sym) % NBWLX;
        if ((pa->instr_type & OPC_BWLX) == OPC_WLX)
          {
        /* We need to reject the xxxb opcodes that we accepted above.
           Note that pa->sym for WLX opcodes is the 'w' token,
           to get the 'b' token subtract one.  */
        if (((opcode - pa->sym + 1) % NBWLX) == 0)
            continue;
            s++;
          }
        } else if (it == OPC_SHIFT) {
            if (!(opcode >= pa->sym && opcode < pa->sym + 7*NBWLX))
                continue;
            s = (opcode - pa->sym) % NBWLX;
        } else if (it == OPC_TEST) {
            if (!(opcode >= pa->sym && opcode < pa->sym + NB_TEST_OPCODES))
                continue;
        /* cmovxx is a test opcode but accepts multiple sizes.
           TCC doesn't accept the suffixed mnemonic, instead we 
           simply force size autodetection always.  */
        if (pa->instr_type & OPC_WLX)
            s = NBWLX - 1;
        } else if (pa->instr_type & OPC_B) {
#ifdef TCC_TARGET_X86_64
        /* Some instructions don't have the full size but only
           bwl form.  insb e.g. */
        if ((pa->instr_type & OPC_WLQ) != OPC_WLQ
        && !(opcode >= pa->sym && opcode < pa->sym + NBWLX-1))
            continue;
#endif
            if (!(opcode >= pa->sym && opcode < pa->sym + NBWLX))
                continue;
            s = opcode - pa->sym;
        } else if (pa->instr_type & OPC_WLX) {
            if (!(opcode >= pa->sym && opcode < pa->sym + NBWLX-1))
                continue;
            s = opcode - pa->sym + 1;
        } else {
            if (pa->sym != opcode)
                continue;
        }
        if (pa->nb_ops != nb_ops)
            continue;
#ifdef TCC_TARGET_X86_64
    /* Special case for moves.  Selecting the IM64->REG64 form
       should only be done if we really have an >32bit imm64, and that
       is hardcoded.  Ignore it here.  */
    if (pa->opcode == 0xb0 && ops[0].type != OP_IM64
        && (ops[1].type & OP_REG) == OP_REG64
        && !(pa->instr_type & OPC_0F))
        continue;
#endif
        /* now decode and check each operand */
    alltypes = 0;
        for(i = 0; i < nb_ops; i++) {
            int op1, op2;
            op1 = pa->op_type[i];
            op2 = op1 & 0x1f;
            switch(op2) {
            case OPT_IM:
                v = OP_IM8 | OP_IM16 | OP_IM32;
                break;
            case OPT_REG:
                v = OP_REG8 | OP_REG16 | OP_REG32 | OP_REG64;
                break;
            case OPT_REGW:
                v = OP_REG16 | OP_REG32 | OP_REG64;
                break;
            case OPT_IMW:
                v = OP_IM16 | OP_IM32;
                break;
        case OPT_MMXSSE:
        v = OP_MMX | OP_SSE;
        break;
        case OPT_DISP:
        case OPT_DISP8:
        v = OP_ADDR;
        break;
            default:
                v = 1 << op2;
                break;
            }
            if (op1 & OPT_EA)
                v |= OP_EA;
        op_type[i] = v;
            if ((ops[i].type & v) == 0)
                goto next;
        alltypes |= ops[i].type;
        }
        /* all is matching ! */
        break;
    next: ;
    }
    if (pa->sym == 0) {
        if (opcode >= TOK_ASM_first && opcode <= TOK_ASM_last) {
            int b;
            b = op0_codes[opcode - TOK_ASM_first];
            if (b & 0xff00) 
                g(b >> 8);
            g(b);
            return;
        } else if (opcode <= TOK_ASM_alllast) {
            tcc_error("bad operand with opcode '%s'",
                  get_tok_str(opcode, NULL));
        } else {
            tcc_error("unknown opcode '%s'",
                  get_tok_str(opcode, NULL));
        }
    }
    /* if the size is unknown, then evaluate it (OPC_B or OPC_WL case) */
    autosize = NBWLX-1;
#ifdef TCC_TARGET_X86_64
    /* XXX the autosize should rather be zero, to not have to adjust this
       all the time.  */
    if ((pa->instr_type & OPC_BWLQ) == OPC_B)
        autosize = NBWLX-2;
#endif
    if (s == autosize) {
    /* Check for register operands providing hints about the size.
       Start from the end, i.e. destination operands.  This matters
       only for opcodes accepting different sized registers, lar and lsl
       are such opcodes.  */
        for(i = nb_ops - 1; s == autosize && i >= 0; i--) {
            if ((ops[i].type & OP_REG) && !(op_type[i] & (OP_CL | OP_DX)))
                s = reg_to_size[ops[i].type & OP_REG];
        }
        if (s == autosize) {
            if ((opcode == TOK_ASM_push || opcode == TOK_ASM_pop) &&
                (ops[0].type & (OP_SEG | OP_IM8S | OP_IM32)))
                s = 2;
        else if ((opcode == TOK_ASM_push || opcode == TOK_ASM_pop) &&
             (ops[0].type & OP_EA))
            s = NBWLX - 2;
            else
                tcc_error("cannot infer opcode suffix");
        }
    }

#ifdef TCC_TARGET_X86_64
    /* Generate addr32 prefix if needed */
    for(i = 0; i < nb_ops; i++) {
        if (ops[i].type & OP_EA32) {
        g(0x67);
        break;
        }
    }
#endif
    /* generate data16 prefix if needed */
    p66 = 0;
    if (s == 1)
        p66 = 1;
    else {
    /* accepting mmx+sse in all operands --> needs 0x66 to
       switch to sse mode.  Accepting only sse in an operand --> is
       already SSE insn and needs 0x66/f2/f3 handling.  */
        for (i = 0; i < nb_ops; i++)
            if ((op_type[i] & (OP_MMX | OP_SSE)) == (OP_MMX | OP_SSE)
            && ops[i].type & OP_SSE)
            p66 = 1;
    }
    if (p66)
        g(0x66);
#ifdef TCC_TARGET_X86_64
    rex64 = 0;
    if (pa->instr_type & OPC_48)
        rex64 = 1;
    else if (s == 3 || (alltypes & OP_REG64)) {
        /* generate REX prefix */
    int default64 = 0;
    for(i = 0; i < nb_ops; i++) {
        if (op_type[i] == OP_REG64 && pa->opcode != 0xb8) {
        /* If only 64bit regs are accepted in one operand
           this is a default64 instruction without need for
           REX prefixes, except for movabs(0xb8).  */
        default64 = 1;
        break;
        }
    }
    /* XXX find better encoding for the default64 instructions.  */
        if (((opcode != TOK_ASM_push && opcode != TOK_ASM_pop
          && opcode != TOK_ASM_pushw && opcode != TOK_ASM_pushl
          && opcode != TOK_ASM_pushq && opcode != TOK_ASM_popw
          && opcode != TOK_ASM_popl && opcode != TOK_ASM_popq
          && opcode != TOK_ASM_call && opcode != TOK_ASM_jmp))
        && !default64)
            rex64 = 1;
    }
#endif

    /* now generates the operation */
    if (OPCT_IS(pa->instr_type, OPC_FWAIT))
        g(0x9b);
    if (seg_prefix)
        g(seg_prefix);

    v = pa->opcode;
    if (pa->instr_type & OPC_0F)
        v = ((v & ~0xff) << 8) | 0x0f00 | (v & 0xff);
    if ((v == 0x69 || v == 0x6b) && nb_ops == 2) {
        /* kludge for imul $im, %reg */
        nb_ops = 3;
        ops[2] = ops[1];
        op_type[2] = op_type[1];
    } else if (v == 0xcd && ops[0].e.v == 3 && !ops[0].e.sym) {
        v--; /* int $3 case */
        nb_ops = 0;
    } else if ((v == 0x06 || v == 0x07)) {
        if (ops[0].reg >= 4) {
            /* push/pop %fs or %gs */
            v = 0x0fa0 + (v - 0x06) + ((ops[0].reg - 4) << 3);
        } else {
            v += ops[0].reg << 3;
        }
        nb_ops = 0;
    } else if (v <= 0x05) {
        /* arith case */
        v += ((opcode - TOK_ASM_addb) / NBWLX) << 3;
    } else if ((pa->instr_type & (OPCT_MASK | OPC_MODRM)) == OPC_FARITH) {
        /* fpu arith case */
        v += ((opcode - pa->sym) / 6) << 3;
    }

    /* search which operand will be used for modrm */
    modrm_index = -1;
    modreg_index = -1;
    if (pa->instr_type & OPC_MODRM) {
    if (!nb_ops) {
        /* A modrm opcode without operands is a special case (e.g. mfence).
           It has a group and acts as if there's an register operand 0
           (ax).  */
        i = 0;
        ops[i].type = OP_REG;
        ops[i].reg = 0;
        goto modrm_found;
    }
        /* first look for an ea operand */
        for(i = 0;i < nb_ops; i++) {
            if (op_type[i] & OP_EA)
                goto modrm_found;
        }
        /* then if not found, a register or indirection (shift instructions) */
        for(i = 0;i < nb_ops; i++) {
            if (op_type[i] & (OP_REG | OP_MMX | OP_SSE | OP_INDIR))
                goto modrm_found;
        }
#ifdef ASM_DEBUG
        tcc_error("bad op table");
#endif
    modrm_found:
        modrm_index = i;
        /* if a register is used in another operand then it is
           used instead of group */
        for(i = 0;i < nb_ops; i++) {
            int t = op_type[i];
            if (i != modrm_index &&
                (t & (OP_REG | OP_MMX | OP_SSE | OP_CR | OP_TR | OP_DB | OP_SEG))) {
                modreg_index = i;
                break;
            }
        }
    }
#ifdef TCC_TARGET_X86_64
    asm_rex (rex64, ops, nb_ops, op_type, modreg_index, modrm_index);
#endif

    if (pa->instr_type & OPC_REG) {
        /* mov $im, %reg case */
        if (v == 0xb0 && s >= 1)
            v += 7;
        for(i = 0; i < nb_ops; i++) {
            if (op_type[i] & (OP_REG | OP_ST)) {
                v += ops[i].reg;
                break;
            }
        }
    }
    if (pa->instr_type & OPC_B)
        v += s >= 1;
    if (nb_ops == 1 && pa->op_type[0] == OPT_DISP8) {
        Sym *sym;
        int jmp_disp;

        /* see if we can really generate the jump with a byte offset */
        sym = ops[0].e.sym;
        if (!sym)
            goto no_short_jump;
        if (sym->r != cur_text_section->sh_num)
            goto no_short_jump;
        jmp_disp = ops[0].e.v + sym->jnext - ind - 2 - (v >= 0xff);
        if (jmp_disp == (int8_t)jmp_disp) {
            /* OK to generate jump */
        ops[0].e.sym = 0;
            ops[0].e.v = jmp_disp;
        op_type[0] = OP_IM8S;
        } else {
        no_short_jump:
        /* long jump will be allowed. need to modify the
           opcode slightly */
        if (v == 0xeb) /* jmp */
            v = 0xe9;
        else if (v == 0x70) /* jcc */
            v += 0x0f10;
        else
            tcc_error("invalid displacement");
        }
    }
    if (OPCT_IS(pa->instr_type, OPC_TEST))
        v += test_bits[opcode - pa->sym];
    op1 = v >> 16;
    if (op1)
        g(op1);
    op1 = (v >> 8) & 0xff;
    if (op1)
        g(op1);
    g(v);

    if (OPCT_IS(pa->instr_type, OPC_SHIFT)) {
        reg = (opcode - pa->sym) / NBWLX;
        if (reg == 6)
            reg = 7;
    } else if (OPCT_IS(pa->instr_type, OPC_ARITH)) {
        reg = (opcode - pa->sym) / NBWLX;
    } else if (OPCT_IS(pa->instr_type, OPC_FARITH)) {
        reg = (opcode - pa->sym) / 6;
    } else {
        reg = (pa->instr_type >> OPC_GROUP_SHIFT) & 7;
    }

    pc = 0;
    if (pa->instr_type & OPC_MODRM) {
        /* if a register is used in another operand then it is
           used instead of group */
    if (modreg_index >= 0)
        reg = ops[modreg_index].reg;
        pc = asm_modrm(reg, &ops[modrm_index]);
    }

    /* emit constants */
#ifndef TCC_TARGET_X86_64
    if (!(pa->instr_type & OPC_0F)
    && (pa->opcode == 0x9a || pa->opcode == 0xea)) {
        /* ljmp or lcall kludge */
    gen_expr32(&ops[1].e);
        if (ops[0].e.sym)
            tcc_error("cannot relocate");
        gen_le16(ops[0].e.v);
        return;
    }
#endif
    for(i = 0;i < nb_ops; i++) {
        v = op_type[i];
        if (v & (OP_IM8 | OP_IM16 | OP_IM32 | OP_IM64 | OP_IM8S | OP_ADDR)) {
            /* if multiple sizes are given it means we must look
               at the op size */
            if ((v | OP_IM8 | OP_IM64) == (OP_IM8 | OP_IM16 | OP_IM32 | OP_IM64)) {
                if (s == 0)
                    v = OP_IM8;
                else if (s == 1)
                    v = OP_IM16;
                else if (s == 2 || (v & OP_IM64) == 0)
                    v = OP_IM32;
                else
                    v = OP_IM64;
            }

            if ((v & (OP_IM8 | OP_IM8S | OP_IM16)) && ops[i].e.sym)
                tcc_error("cannot relocate");

            if (v & (OP_IM8 | OP_IM8S)) {
                g(ops[i].e.v);
            } else if (v & OP_IM16) {
                gen_le16(ops[i].e.v);
#ifdef TCC_TARGET_X86_64
            } else if (v & OP_IM64) {
                gen_expr64(&ops[i].e);
#endif
        } else if (pa->op_type[i] == OPT_DISP || pa->op_type[i] == OPT_DISP8) {
                gen_disp32(&ops[i].e);
            } else {
                gen_expr32(&ops[i].e);
            }
        }
    }

    /* after immediate operands, adjust pc-relative address */
    if (pc)
        add32le(cur_text_section->data + pc - 4, pc - ind);
}

/* return the constraint priority (we allocate first the lowest
   numbered constraints) */
static inline int constraint_priority(const char *str)
{
    int priority, c, pr;

    /* we take the lowest priority */
    priority = 0;
    for(;;) {
        c = *str;
        if (c == '\0')
            break;
        str++;
        switch(c) {
        case 'A':
            pr = 0;
            break;
        case 'a':
        case 'b':
        case 'c':
        case 'd':
        case 'S':
        case 'D':
            pr = 1;
            break;
        case 'q':
            pr = 2;
            break;
        case 'r':
    case 'R':
    case 'p':
            pr = 3;
            break;
        case 'N':
        case 'M':
        case 'I':
    case 'e':
        case 'i':
        case 'm':
        case 'g':
            pr = 4;
            break;
        default:
            tcc_error("unknown constraint '%c'", c);
            pr = 0;
        }
        if (pr > priority)
            priority = pr;
    }
    return priority;
}

static const char *skip_constraint_modifiers(const char *p)
{
    while (*p == '=' || *p == '&' || *p == '+' || *p == '%')
        p++;
    return p;
}

/* If T (a token) is of the form "%reg" returns the register
   number and type, otherwise return -1.  */
ST_FUNC int asm_parse_regvar (int t)
{
    const char *s;
    Operand op;
    if (t < TOK_IDENT)
        return -1;
    s = table_ident[t - TOK_IDENT]->str;
    if (s[0] != '%')
        return -1;
    t = tok_alloc(s+1, strlen(s)-1)->tok;
    unget_tok(t);
    unget_tok('%');
    parse_operand(tcc_state, &op);
    /* Accept only integer regs for now.  */
    if (op.type & OP_REG)
        return op.reg;
    else
        return -1;
}

#define REG_OUT_MASK 0x01
#define REG_IN_MASK  0x02

#define is_reg_allocated(reg) (regs_allocated[reg] & reg_mask)

ST_FUNC void asm_compute_constraints(ASMOperand *operands,
                                    int nb_operands, int nb_outputs,
                                    const uint8_t *clobber_regs,
                                    int *pout_reg)
{
    ASMOperand *op;
    int sorted_op[MAX_ASM_OPERANDS];
    int i, j, k, p1, p2, tmp, reg, c, reg_mask;
    const char *str;
    uint8_t regs_allocated[NB_ASM_REGS];

    /* init fields */
    for(i=0;i<nb_operands;i++) {
        op = &operands[i];
        op->input_index = -1;
        op->ref_index = -1;
        op->reg = -1;
        op->is_memory = 0;
        op->is_rw = 0;
    }
    /* compute constraint priority and evaluate references to output
       constraints if input constraints */
    for(i=0;i<nb_operands;i++) {
        op = &operands[i];
        str = op->constraint;
        str = skip_constraint_modifiers(str);
        if (isnum(*str) || *str == '[') {
            /* this is a reference to another constraint */
            k = find_constraint(operands, nb_operands, str, NULL);
            if ((unsigned)k >= i || i < nb_outputs)
                tcc_error("invalid reference in constraint %d ('%s')",
                      i, str);
            op->ref_index = k;
            if (operands[k].input_index >= 0)
                tcc_error("cannot reference twice the same operand");
            operands[k].input_index = i;
            op->priority = 5;
    } else if ((op->vt->r & VT_VALMASK) == VT_LOCAL
           && op->vt->sym
           && (reg = op->vt->sym->r & VT_VALMASK) < VT_CONST) {
        op->priority = 1;
        op->reg = reg;
        } else {
            op->priority = constraint_priority(str);
        }
    }

    /* sort operands according to their priority */
    for(i=0;i<nb_operands;i++)
        sorted_op[i] = i;
    for(i=0;i<nb_operands - 1;i++) {
        for(j=i+1;j<nb_operands;j++) {
            p1 = operands[sorted_op[i]].priority;
            p2 = operands[sorted_op[j]].priority;
            if (p2 < p1) {
                tmp = sorted_op[i];
                sorted_op[i] = sorted_op[j];
                sorted_op[j] = tmp;
            }
        }
    }

    for(i = 0;i < NB_ASM_REGS; i++) {
        if (clobber_regs[i])
            regs_allocated[i] = REG_IN_MASK | REG_OUT_MASK;
        else
            regs_allocated[i] = 0;
    }
    /* esp cannot be used */
    regs_allocated[4] = REG_IN_MASK | REG_OUT_MASK;
    /* ebp cannot be used yet */
    regs_allocated[5] = REG_IN_MASK | REG_OUT_MASK;

    /* allocate registers and generate corresponding asm moves */
    for(i=0;i<nb_operands;i++) {
        j = sorted_op[i];
        op = &operands[j];
        str = op->constraint;
        /* no need to allocate references */
        if (op->ref_index >= 0)
            continue;
        /* select if register is used for output, input or both */
        if (op->input_index >= 0) {
            reg_mask = REG_IN_MASK | REG_OUT_MASK;
        } else if (j < nb_outputs) {
            reg_mask = REG_OUT_MASK;
        } else {
            reg_mask = REG_IN_MASK;
        }
    if (op->reg >= 0) {
        if (is_reg_allocated(op->reg))
            tcc_error("asm regvar requests register that's taken already");
        reg = op->reg;
        goto reg_found;
    }
    try_next:
        c = *str++;
        switch(c) {
        case '=':
            goto try_next;
        case '+':
            op->is_rw = 1;
            /* FALL THRU */
        case '&':
            if (j >= nb_outputs)
                tcc_error("'%c' modifier can only be applied to outputs", c);
            reg_mask = REG_IN_MASK | REG_OUT_MASK;
            goto try_next;
        case 'A':
            /* allocate both eax and edx */
            if (is_reg_allocated(TREG_XAX) ||
                is_reg_allocated(TREG_XDX))
                goto try_next;
            op->is_llong = 1;
            op->reg = TREG_XAX;
            regs_allocated[TREG_XAX] |= reg_mask;
            regs_allocated[TREG_XDX] |= reg_mask;
            break;
        case 'a':
            reg = TREG_XAX;
            goto alloc_reg;
        case 'b':
            reg = 3;
            goto alloc_reg;
        case 'c':
            reg = TREG_XCX;
            goto alloc_reg;
        case 'd':
            reg = TREG_XDX;
            goto alloc_reg;
        case 'S':
            reg = 6;
            goto alloc_reg;
        case 'D':
            reg = 7;
        alloc_reg:
            if (is_reg_allocated(reg))
                goto try_next;
            goto reg_found;
        case 'q':
            /* eax, ebx, ecx or edx */
            for(reg = 0; reg < 4; reg++) {
                if (!is_reg_allocated(reg))
                    goto reg_found;
            }
            goto try_next;
        case 'r':
    case 'R':
    case 'p': /* A general address, for x86(64) any register is acceptable*/
            /* any general register */
            for(reg = 0; reg < 8; reg++) {
                if (!is_reg_allocated(reg))
                    goto reg_found;
            }
            goto try_next;
        reg_found:
            /* now we can reload in the register */
            op->is_llong = 0;
            op->reg = reg;
            regs_allocated[reg] |= reg_mask;
            break;
    case 'e':
        case 'i':
            if (!((op->vt->r & (VT_VALMASK | VT_LVAL)) == VT_CONST))
                goto try_next;
            break;
        case 'I':
        case 'N':
        case 'M':
            if (!((op->vt->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST))
                goto try_next;
            break;
        case 'm':
        case 'g':
            /* nothing special to do because the operand is already in
               memory, except if the pointer itself is stored in a
               memory variable (VT_LLOCAL case) */
            /* XXX: fix constant case */
            /* if it is a reference to a memory zone, it must lie
               in a register, so we reserve the register in the
               input registers and a load will be generated
               later */
            if (j < nb_outputs || c == 'm') {
                if ((op->vt->r & VT_VALMASK) == VT_LLOCAL) {
                    /* any general register */
                    for(reg = 0; reg < 8; reg++) {
                        if (!(regs_allocated[reg] & REG_IN_MASK))
                            goto reg_found1;
                    }
                    goto try_next;
                reg_found1:
                    /* now we can reload in the register */
                    regs_allocated[reg] |= REG_IN_MASK;
                    op->reg = reg;
                    op->is_memory = 1;
                }
            }
            break;
        default:
            tcc_error("asm constraint %d ('%s') could not be satisfied",
                  j, op->constraint);
            break;
        }
        /* if a reference is present for that operand, we assign it too */
        if (op->input_index >= 0) {
            operands[op->input_index].reg = op->reg;
            operands[op->input_index].is_llong = op->is_llong;
        }
    }

    /* compute out_reg. It is used to store outputs registers to memory
       locations references by pointers (VT_LLOCAL case) */
    *pout_reg = -1;
    for(i=0;i<nb_operands;i++) {
        op = &operands[i];
        if (op->reg >= 0 &&
            (op->vt->r & VT_VALMASK) == VT_LLOCAL  &&
            !op->is_memory) {
            for(reg = 0; reg < 8; reg++) {
                if (!(regs_allocated[reg] & REG_OUT_MASK))
                    goto reg_found2;
            }
            tcc_error("could not find free output register for reloading");
        reg_found2:
            *pout_reg = reg;
            break;
        }
    }

    /* print sorted constraints */
#ifdef ASM_DEBUG
    for(i=0;i<nb_operands;i++) {
        j = sorted_op[i];
        op = &operands[j];
        printf("%%%d [%s]: \"%s\" r=0x%04x reg=%d\n",
               j,
               op->id ? get_tok_str(op->id, NULL) : "",
               op->constraint,
               op->vt->r,
               op->reg);
    }
    if (*pout_reg >= 0)
        printf("out_reg=%d\n", *pout_reg);
#endif
}

ST_FUNC void subst_asm_operand(CString *add_str,
                              SValue *sv, int modifier)
{
    int r, reg, size, val;
    char buf[64];

    r = sv->r;
    if ((r & VT_VALMASK) == VT_CONST) {
        if (!(r & VT_LVAL) && modifier != 'c' && modifier != 'n' &&
        modifier != 'P')
            cstr_ccat(add_str, '$');
        if (r & VT_SYM) {
        const char *name = get_tok_str(sv->sym->v, NULL);
        if (sv->sym->v >= SYM_FIRST_ANOM) {
        /* In case of anonymous symbols ("L.42", used
           for static data labels) we can't find them
           in the C symbol table when later looking up
           this name.  So enter them now into the asm label
           list when we still know the symbol.  */
        get_asm_sym(tok_alloc(name, strlen(name))->tok, sv->sym);
        }
            cstr_cat(add_str, name, -1);
            if ((uint32_t)sv->c.i == 0)
                goto no_offset;
        cstr_ccat(add_str, '+');
        }
        val = sv->c.i;
        if (modifier == 'n')
            val = -val;
        snprintf(buf, sizeof(buf), "%d", (int)sv->c.i);
        cstr_cat(add_str, buf, -1);
    no_offset:;
#ifdef TCC_TARGET_X86_64
        if (r & VT_LVAL)
            cstr_cat(add_str, "(%rip)", -1);
#endif
    } else if ((r & VT_VALMASK) == VT_LOCAL) {
#ifdef TCC_TARGET_X86_64
        snprintf(buf, sizeof(buf), "%d(%%rbp)", (int)sv->c.i);
#else
        snprintf(buf, sizeof(buf), "%d(%%ebp)", (int)sv->c.i);
#endif
        cstr_cat(add_str, buf, -1);
    } else if (r & VT_LVAL) {
        reg = r & VT_VALMASK;
        if (reg >= VT_CONST)
            tcc_error("internal compiler error");
        snprintf(buf, sizeof(buf), "(%%%s)",
#ifdef TCC_TARGET_X86_64
                 get_tok_str(TOK_ASM_rax + reg, NULL)
#else
                 get_tok_str(TOK_ASM_eax + reg, NULL)
#endif
         );
        cstr_cat(add_str, buf, -1);
    } else {
        /* register case */
        reg = r & VT_VALMASK;
        if (reg >= VT_CONST)
            tcc_error("internal compiler error");

        /* choose register operand size */
        if ((sv->type.t & VT_BTYPE) == VT_BYTE ||
        (sv->type.t & VT_BTYPE) == VT_BOOL)
            size = 1;
        else if ((sv->type.t & VT_BTYPE) == VT_SHORT)
            size = 2;
#ifdef TCC_TARGET_X86_64
        else if ((sv->type.t & VT_BTYPE) == VT_LLONG ||
         (sv->type.t & VT_BTYPE) == VT_PTR)
            size = 8;
#endif
        else
            size = 4;
        if (size == 1 && reg >= 4)
            size = 4;

        if (modifier == 'b') {
            if (reg >= 4)
                tcc_error("cannot use byte register");
            size = 1;
        } else if (modifier == 'h') {
            if (reg >= 4)
                tcc_error("cannot use byte register");
            size = -1;
        } else if (modifier == 'w') {
            size = 2;
        } else if (modifier == 'k') {
            size = 4;
#ifdef TCC_TARGET_X86_64
        } else if (modifier == 'q') {
            size = 8;
#endif
        }

        switch(size) {
        case -1:
            reg = TOK_ASM_ah + reg;
            break;
        case 1:
            reg = TOK_ASM_al + reg;
            break;
        case 2:
            reg = TOK_ASM_ax + reg;
            break;
        default:
            reg = TOK_ASM_eax + reg;
            break;
#ifdef TCC_TARGET_X86_64
        case 8:
            reg = TOK_ASM_rax + reg;
            break;
#endif
        }
        snprintf(buf, sizeof(buf), "%%%s", get_tok_str(reg, NULL));
        cstr_cat(add_str, buf, -1);
    }
}

/* generate prolog and epilog code for asm statement */
ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands,
                         int nb_outputs, int is_output,
                         uint8_t *clobber_regs,
                         int out_reg)
{
    uint8_t regs_allocated[NB_ASM_REGS];
    ASMOperand *op;
    int i, reg;

    /* Strictly speaking %Xbp and %Xsp should be included in the
       call-preserved registers, but currently it doesn't matter.  */
#ifdef TCC_TARGET_X86_64
#ifdef TCC_TARGET_PE
    static uint8_t reg_saved[] = { 3, 6, 7, 12, 13, 14, 15 };
#else
    static uint8_t reg_saved[] = { 3, 12, 13, 14, 15 };
#endif
#else
    static uint8_t reg_saved[] = { 3, 6, 7 };
#endif

    /* mark all used registers */
    memcpy(regs_allocated, clobber_regs, sizeof(regs_allocated));
    for(i = 0; i < nb_operands;i++) {
        op = &operands[i];
        if (op->reg >= 0)
            regs_allocated[op->reg] = 1;
    }
    if (!is_output) {
        /* generate reg save code */
        for(i = 0; i < sizeof(reg_saved)/sizeof(reg_saved[0]); i++) {
            reg = reg_saved[i];
            if (regs_allocated[reg]) {
        if (reg >= 8)
          g(0x41), reg-=8;
                g(0x50 + reg);
            }
        }

        /* generate load code */
        for(i = 0; i < nb_operands; i++) {
            op = &operands[i];
            if (op->reg >= 0) {
                if ((op->vt->r & VT_VALMASK) == VT_LLOCAL &&
                    op->is_memory) {
                    /* memory reference case (for both input and
                       output cases) */
                    SValue sv;
                    sv = *op->vt;
                    sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL | VT_LVAL;
                    sv.type.t = VT_PTR;
                    load(op->reg, &sv);
                } else if (i >= nb_outputs || op->is_rw) {
                    /* load value in register */
                    load(op->reg, op->vt);
                    if (op->is_llong) {
                        SValue sv;
                        sv = *op->vt;
                        sv.c.i += 4;
                        load(TREG_XDX, &sv);
                    }
                }
            }
        }
    } else {
        /* generate save code */
        for(i = 0 ; i < nb_outputs; i++) {
            op = &operands[i];
            if (op->reg >= 0) {
                if ((op->vt->r & VT_VALMASK) == VT_LLOCAL) {
                    if (!op->is_memory) {
                        SValue sv;
                        sv = *op->vt;
                        sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL;
            sv.type.t = VT_PTR;
                        load(out_reg, &sv);

            sv = *op->vt;
                        sv.r = (sv.r & ~VT_VALMASK) | out_reg;
                        store(op->reg, &sv);
                    }
                } else {
                    store(op->reg, op->vt);
                    if (op->is_llong) {
                        SValue sv;
                        sv = *op->vt;
                        sv.c.i += 4;
                        store(TREG_XDX, &sv);
                    }
                }
            }
        }
        /* generate reg restore code */
        for(i = sizeof(reg_saved)/sizeof(reg_saved[0]) - 1; i >= 0; i--) {
            reg = reg_saved[i];
            if (regs_allocated[reg]) {
        if (reg >= 8)
          g(0x41), reg-=8;
                g(0x58 + reg);
            }
        }
    }
}

ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str)
{
    int reg;
    TokenSym *ts;
#ifdef TCC_TARGET_X86_64
    unsigned int type;
#endif

    if (!strcmp(str, "memory") ||
        !strcmp(str, "cc") ||
    !strcmp(str, "flags"))
        return;
    ts = tok_alloc(str, strlen(str));
    reg = ts->tok;
    if (reg >= TOK_ASM_eax && reg <= TOK_ASM_edi) {
        reg -= TOK_ASM_eax;
    } else if (reg >= TOK_ASM_ax && reg <= TOK_ASM_di) {
        reg -= TOK_ASM_ax;
#ifdef TCC_TARGET_X86_64
    } else if (reg >= TOK_ASM_rax && reg <= TOK_ASM_rdi) {
        reg -= TOK_ASM_rax;
    } else if ((reg = asm_parse_numeric_reg(reg, &type)) >= 0) {
    ;
#endif
    } else {
        tcc_error("invalid clobber register '%s'", str);
    }
    clobber_regs[reg] = 1;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isalnum.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <ctype.h>

int
isalnum (int c)
{
  return isdigit (c) || isalpha (c);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isalpha.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <ctype.h>

int
isalpha (int c)
{
  return islower (c) || isupper (c);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isascii.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <ctype.h>

int
isascii (int c)
{
  return c >= 0 && c <= 127;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/iscntrl.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <ctype.h>

int
iscntrl (int c)
{
  return c >= 0 && c < 32;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isgraph.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <ctype.h>

int
isgraph (int c)
{
  return c > 32 && c < 127;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/isprint.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <ctype.h>

int
isprint (int c)
{
  return c >= 32 && c < 127;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/ctype/ispunct.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <ctype.h>

int
ispunct (int c)
{
  return isprint (c) && !isspace (c) && !isalnum (c);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/dirent/closedir.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright (C) 1991, 1993, 1995, 1996, 1998 Free Software Foundation, Inc.
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

// Taken from GNU C Library 2.2.5

#include <errno.h>
#include <stddef.h>
#include <stdlib.h>
#include <dirent.h>
#include <unistd.h>

#include <errno.h>
#include <stddef.h>
#include <stdlib.h>
#include <dirent.h>
#include <unistd.h>
#include <dirstream.h>

/* Close the directory stream DIRP.
   Return 0 if successful, -1 if not.  */
int
closedir (DIR * dirp)
{
  int filedes;

  if (dirp == NULL)
    {
      errno = EINVAL;
      return -1;
    }

  filedes = dirp->fd;
  free (dirp);

  return close (filedes);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/dirent/__getdirentries.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright (C) 1993 Free Software Foundation, Inc.
 * Copyright © 2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

// Taken from GNU C Library 1.06.4

#include <mes/lib.h>
#include <dirent.h>
#include <stdio.h>
#include <unistd.h>

int
__getdirentries (int filedes, char *buffer, size_t nbytes, off_t * basep)
{
  if (basep)
    *basep = lseek (filedes, (off_t) 0, SEEK_CUR);

  return read (filedes, buffer, nbytes);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/dirent/opendir.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright (C) 1991-1996,98,2000,2001 Free Software Foundation, Inc.
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

// Taken from GNU C Library 2.2.5

#include <mes/lib.h>
#include <errno.h>
#include <limits.h>
#include <stddef.h>
#include <stdlib.h>
#include <dirent.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>

#include <dirstream.h>

/* Open a directory stream on NAME.  */
DIR *
opendir (char const *name)
{
  DIR *dirp;
  struct stat statbuf;
  int fd;
  size_t allocation;
  int save_errno;

  if (name[0] == '\0')
    {
      /* POSIX.1-1990 says an empty name gets ENOENT;
         but `open' might like it fine.  */
      errno = ENOENT;
      return 0;
    }

  fd = open (name, O_RDONLY | O_DIRECTORY);
  if (fd < 0)
    return 0;

  if (fstat (fd, &statbuf) < 0)
    goto lose;

  if (fcntl (fd, F_SETFD, FD_CLOEXEC) < 0)
    goto lose;

  allocation = statbuf.st_blksize;

  dirp = (DIR *) calloc (1, sizeof (DIR) + allocation);
  if (!dirp)
  lose:
    {
      save_errno = errno;
      close (fd);
      errno = save_errno;
      return 0;
    }
  dirp->data = (char *) (dirp + 1);
  dirp->allocation = allocation;
  dirp->fd = fd;

  return dirp;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/dirent/readdir.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright (C) 1991,92,93,94,95,96,97,99,2000 Free Software Foundation, Inc.
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

// Taken from GNU C Library 2.2.5

#include <errno.h>
#include <limits.h>
#include <stddef.h>
#include <string.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/types.h>
#include <assert.h>

#include <dirstream.h>

int getdents (int filedes, char *buffer, size_t nbytes);

/* Read a directory entry from DIRP.  */
struct dirent *
readdir (DIR * dirp)
{
  struct dirent *dp;
  int saved_errno = errno;

  do
    {
      size_t reclen;

      if (dirp->offset >= dirp->size)
        {
          /* We've emptied out our buffer.  Refill it.  */

          size_t maxread;
          ssize_t bytes;

          maxread = dirp->allocation;

#if 0
          off_t base;
          bytes = __getdirentries (dirp->fd, dirp->data, maxread, &base);
#else
          bytes = getdents (dirp->fd, dirp->data, maxread);
#endif
          if (bytes <= 0)
            {
              /* Don't modifiy errno when reaching EOF.  */
              if (bytes == 0)
                errno = saved_errno;
              dp = 0;
              break;
            }
          dirp->size = (size_t) bytes;

          /* Reset the offset into the buffer.  */
          dirp->offset = 0;
        }

      dp = (struct dirent *) &dirp->data[dirp->offset];

      reclen = dp->d_reclen;
      dirp->offset += reclen;
      dirp->filepos = dp->d_off;

      /* Skip deleted files.  */
    }
  while (dp->d_ino == 0);

  return dp;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/chdir.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>

int
chdir (char const *file_name)
{
  return _sys_call1 (SYS_chdir, (long) file_name);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/fcntl.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <stdarg.h>

int
fcntl (int filedes, int command, ...)
{
  va_list ap;
  va_start (ap, command);
  int data = va_arg (ap, int);
  int r = _sys_call3 (SYS_fcntl, (int) filedes, (int) command, (int) data);
  va_end (ap);
  return r;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/fstat.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <sys/stat.h>

int
fstat (int filedes, struct stat *statbuf)
{
  return _sys_call2 (SYS_fstat, (int) filedes, (long) statbuf);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/getdents.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <sys/types.h>

int
getdents (int filedes, char *buffer, size_t nbytes)
{
  return _sys_call3 (SYS_getdents, (int) filedes, (long) buffer, (long) nbytes);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/getegid.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <unistd.h>

gid_t
getegid ()
{
  return _sys_call (SYS_getegid);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/geteuid.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <unistd.h>

uid_t
geteuid ()
{
  return _sys_call (SYS_geteuid);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/getgid.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <unistd.h>

gid_t
getgid ()
{
  return _sys_call (SYS_getgid);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/getppid.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <unistd.h>

pid_t
getppid ()
{
  return _sys_call (SYS_getppid);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/getrusage.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <sys/resource.h>

int
getrusage (int processes, struct rusage *rusage)
{
  return _sys_call2 (SYS_getrusage, (int) processes, (long) rusage);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/getuid.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <unistd.h>

uid_t
getuid ()
{
  return _sys_call (SYS_getuid);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/ioctl.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018,2019,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <stdarg.h>
#include <sys/ioctl.h>

int
ioctl (int filedes, unsigned long command, ...)
{
  va_list ap;
  va_start (ap, command);
  int data = va_arg (ap, int);
  int r = _sys_call3 (SYS_ioctl, (int) filedes, (long) command, (int) data);
  va_end (ap);
  return r;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/link.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>

int
link (char const *old_name, char const *new_name)
{
  return _sys_call2 (SYS_link, (long) old_name, (long) new_name);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/lstat.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <sys/stat.h>

int
lstat (char const *file_name, struct stat *statbuf)
{
  return _sys_call2 (SYS_lstat, (long) file_name, (long) statbuf);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/mkdir.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <sys/stat.h>

int
mkdir (char const *file_name, mode_t mode)
{
  return _sys_call2 (SYS_mkdir, (long) file_name, (long) mode);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/mknod.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <sys/stat.h>

int
mknod (char const *file_name, mode_t mode, dev_t dev)
{
  return _sys_call3 (SYS_mknod, (long) file_name, (long) mode, (long) dev);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/nanosleep.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <time.h>
#include <sys/time.h>

int
nanosleep (struct timespec const *requested_time, struct timespec const *remaining)
{
  return _sys_call2 (SYS_nanosleep, (long) requested_time, (long) remaining);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/pipe.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <unistd.h>

int
pipe (int filedes[2])
{
  return _sys_call1 (SYS_pipe, (long) filedes);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/readlink.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <sys/stat.h>

ssize_t
readlink (char const *file_name, char *buffer, size_t size)
{
  return _sys_call3 (SYS_readlink, (long) file_name, (long) buffer, (long) size);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/rename.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <unistd.h>

int
rename (char const *old_name, char const *new_name)
{
  return _sys_call2 (SYS_rename, (long) old_name, (long) new_name);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/setgid.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <unistd.h>

int
setgid (gid_t newgid)
{
  return _sys_call1 (SYS_setgid, (long) newgid);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/settimer.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <sys/time.h>
#include <unistd.h>

int
setitimer (int which, struct itimerval const *new, struct itimerval *old)
{
  return _sys_call3 (SYS_setitimer, (long) which, (long) new, (long) old);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/setuid.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <unistd.h>

int
setuid (uid_t newuid)
{
  return _sys_call1 (SYS_setuid, (long) newuid);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/signal.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019,2022,2023 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <unistd.h>
#include <signal.h>

#if __i386__
#else
void
_restorer_for_siginfo (void)
{
  _sys_call (SYS_rt_sigreturn);
}
#endif

sighandler_t
signal (int signum, sighandler_t action)
{
#if __i386__
  return (sighandler_t) _sys_call2 (SYS_signal, signum, (long) action);
#else
  static struct sigaction setup_action = { 0 };
  static struct sigaction old = { 0 };
  unsigned short bitindex;
  unsigned short itembitcount;

  setup_action.sa_handler = action;
  /* The sa_restorer is not used.  Reason:
     * The kernel uses its own restorer anyway by pretending we gave one on
     our side (no, really).
     glibc still has a custom restorer because they want to be able to
     backtrace.  gdb has a second part that detects a specific instruction
     sequence and then fixes up the backtrace.  Since we don't use that
     specific instruction sequence and also the non-siginfo restorer
     is complicated (pops foreign item off the stack--so needs inline
     assembly) and we don't support great debuggability in other places,
     I've decided to take the easy way out for now. */
  /*setup_action.sa_restorer = _restorer_for_siginfo;*/
  bitindex = signum - 1;
  itembitcount = 8 * sizeof (setup_action.sa_mask.items[0]);
  setup_action.sa_mask.items[bitindex / itembitcount] = 1UL << (bitindex % itembitcount);
  old.sa_handler = SIG_DFL;
  setup_action.sa_flags = SA_RESTART;
#if __x86_64__
  /* Tell kernel that we use a restorer, on penalty of segfault.  */
  setup_action.sa_flags |= SA_RESTORER;
#endif
  int r = _sys_call4 (SYS_rt_sigaction, signum, (long) &setup_action, (long) &old, sizeof (sigset_t));
  if (r)
    return 0;
  return old.sa_handler;
#endif
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/sigprogmask.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <signal.h>
#include <unistd.h>

int
sigprocmask (int how, sigset_t const *set, sigset_t * oldset)
{
#if __i386__
  return _sys_call3 (SYS_sigprocmask, (long) how, (long) set, (long) oldset);
#else
  return _sys_call3 (SYS_rt_sigprocmask, (long) how, (long) set, (long) oldset);
#endif
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/symlink.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/syscall.h>
#include <arch/syscall.h>
#include <unistd.h>

int
symlink (char const *old_name, char const *new_name)
{
  return _sys_call2 (SYS_symlink, (long) old_name, (long) new_name);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-gcc/_exit.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2019,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "mes/lib-mini.h"

#define SYS_exit   "0x01"

// *INDENT-OFF*
void
_exit (int code)
{
  asm (
       "mov    $"SYS_exit",%%eax\n\t"
       "mov    %0,%%ebx\n\t"
       "int    $0x80\n\t"
       : // no outputs "=" (r)
       : "rm" (code)
       : "eax", "ebx"
       );
  // not reached
  // _exit (0); // tcc has a problem with this
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-gcc/syscall.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <errno.h>
#include <linux/x86/syscall.h>

// *INDENT-OFF*
long
__sys_call (long sys_call)
{
  long r;
  asm (
       "mov    %1,%%eax\n\t"
       "int    $0x80\n\t"
       "mov    %%eax,%0\n\t"
       : "=r" (r)
       : "rm" (sys_call)
       : "eax"
       );
  return r;
}

long
__sys_call1 (long sys_call, long one)
{
  long r;
  asm (
       "mov    %1,%%eax\n\t"
       "mov    %2,%%ebx\n\t"
       "int    $0x80\n\t"
       "mov    %%eax,%0\n\t"
       : "=r" (r)
       : "rm" (sys_call), "rm" (one)
       : "eax", "ebx"
       );
  return r;
}

long
__sys_call2 (long sys_call, long one, long two)
{
  long r;
  asm (
       "mov    %1,%%eax\n\t"
       "mov    %2,%%ebx\n\t"
       "mov    %3,%%ecx\n\t"
       "int    $0x80\n\t"
       "mov    %%eax,%0\n\t"
       : "=r" (r)
       : "rm" (sys_call), "rm" (one), "rm" (two)
       : "eax", "ebx", "ecx"
       );
  return r;
}

long
__sys_call3 (long sys_call, long one, long two, long three)
{
  long r;
  asm (
       "mov    %2,%%ebx\n\t"
       "mov    %3,%%ecx\n\t"
       "mov    %4,%%edx\n\t"
       "mov    %1,%%eax\n\t"
       "int    $0x80\n\t"
       "mov    %%eax,%0\n\t"
       : "=r" (r)
       : "rm" (sys_call), "rm" (one), "rm" (two), "rm" (three)
       : "eax", "ebx", "ecx", "edx"
       );
  return r;
}

long
__sys_call4 (long sys_call, long one, long two, long three, long four)
{
  long r;
  asm (
       "mov    %2,%%ebx\n\t"
       "mov    %3,%%ecx\n\t"
       "mov    %4,%%edx\n\t"
       "mov    %5,%%esi\n\t"
       "mov    %1,%%eax\n\t"
       "int    $0x80\n\t"
       "mov    %%eax,%0\n\t"
       : "=r" (r)
       : "rm" (sys_call), "rm" (one), "rm" (two), "rm" (three), "rm" (four)
       : "eax", "ebx", "ecx", "edx", "esi"
       );
  return r;
}
// *INDENT-ON*

long
_sys_call (long sys_call)
{
  long r = __sys_call (sys_call);
  if (r < 0)
    {
      errno = -r;
      r = -1;
    }
  else
    errno = 0;
  return r;
}

long
_sys_call1 (long sys_call, long one)
{
  long r = __sys_call1 (sys_call, one);
  if (r < 0)
    {
      errno = -r;
      r = -1;
    }
  else
    errno = 0;
  return r;
}

long
_sys_call2 (long sys_call, long one, long two)
{
  long r = __sys_call2 (sys_call, one, two);
  if (r < 0)
    {
      errno = -r;
      r = -1;
    }
  else
    errno = 0;
  return r;
}

long
_sys_call3 (long sys_call, long one, long two, long three)
{
  long r = __sys_call3 (sys_call, one, two, three);
  if (r < 0)
    {
      errno = -r;
      r = -1;
    }
  else
    errno = 0;
  return r;
}

long
_sys_call4 (long sys_call, long one, long two, long three, long four)
{
  long r = __sys_call4 (sys_call, one, two, three, four);
  if (r < 0)
    {
      errno = -r;
      r = -1;
    }
  else
    errno = 0;
  return r;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-gcc/_write.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2016,2017,2019,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "mes/lib-mini.h"

#define SYS_write  "0x04"

// *INDENT-OFF*
ssize_t
_write (int filedes, void const *buffer, size_t size)
{
  long r;
  asm (
       "mov    $"SYS_write",%%eax\n\t"
       "mov    %1,%%ebx\n\t"
       "mov    %2,%%ecx\n\t"
       "mov    %3,%%edx\n\t"
       "int    $0x80\n\t"
       "mov    %%eax,%0\n\t"
       : "=r" (r)
       : "rm" (filedes), "rm" (buffer), "rm" (size)
       : "eax", "ebx", "ecx", "edx"
       );
  return r;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/math/ceil.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <math.h>

double
ceil (double number)
{
  long i = number + 0.9999;
  number = i;
  return number;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/math/fabs.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <math.h>

double
fabs (double number)
{
  if (number < 0)
    return -number;
  return number;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/math/floor.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <math.h>

double
floor (double number)
{
  long i = number;
  number = i;
  return number;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/mes/fdgets.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <stdio.h>

char *
fdgets (char *s, int count, int fd)
{
  int c = 0;
  char *p = s;
  while (--count > 0 && c != '\n')
    {
      c = fdgetc (fd);
      if (c == EOF)
        break;
      *p++ = c;
    }
  if (p == s && (c == EOF || count == -1))
    return 0;
  *p = 0;
  return s;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/alarm.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <unistd.h>
#include <sys/time.h>

unsigned int
alarm (unsigned int seconds)
{
#if !__MESC__
  struct itimerval old;
  struct itimerval new;
  new.it_interval.tv_usec = 0;
  new.it_interval.tv_sec = 0;
  new.it_value.tv_usec = 0;
  new.it_value.tv_sec = (long int) seconds;
  if (setitimer (ITIMER_REAL, &new, &old) < 0)
    return 0;
  return old.it_value.tv_sec;
#endif
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/execl.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <stdarg.h>
#include <unistd.h>

int
vexec (char const *file_name, va_list ap)
{
  char *arg = va_arg (ap, char *);
  char *argv[1000];             // POSIX minimum 4096
  int i = 0;

  argv[i++] = (char *) file_name;
  while (arg)
    {
      argv[i++] = arg;
      arg = va_arg (ap, char *);
      if (__mes_debug () > 2)
        {
          eputs ("arg[");
          eputs (itoa (i));
          eputs ("]: ");
          eputs (argv[i - 1]);
          eputs ("\n");
        }
    }
  argv[i] = 0;
  int r = execv (file_name, argv);
  va_end (ap);
  return r;
}

int
execl (char const *file_name, char const *arg, ...)
{
  va_list ap;
  int r;
  va_start (ap, arg);
  if (__mes_debug () > 2)
    {
      eputs ("execl ");
      eputs (file_name);
      eputs ("\n");
    }
  r = vexec (file_name, ap);
  va_end (ap);
  return r;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/execlp.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <errno.h>
#include <stdarg.h>
#include <string.h>

int
execlp (char const *file_name, char const *arg, ...)
{
  va_list ap;
  int r;
  va_start (ap, arg);
  if (!strchr (file_name, '/'))
    file_name = search_path (file_name);
  if (__mes_debug () > 2)
    {
      eputs ("execlp ");
      eputs (file_name ? file_name : "0");
      eputs ("\n");
    }
  if (!file_name)
    {
      errno = ENOENT;
      return -1;
    }
  r = vexec (file_name, ap);
  va_end (ap);
  return r;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/mktemp.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <string.h>
#include <unistd.h>

char *
mktemp (char *template)
{
  char *p = strchr (template, '\0');
  int q = (long) template;
  *--p = ((unsigned char) (q >> 4)) % 26 + 'a';
  *--p = ((unsigned char) (q >> 8)) % 26 + 'a';
  *--p = ((unsigned char) (q >> 12)) % 26 + 'a';
  *--p = ((unsigned char) (q >> 16)) % 26 + 'a';
  *--p = ((unsigned char) (q >> 20)) % 26 + 'a';
  *--p = ((unsigned char) (q >> 24)) % 26 + 'a';
  return template;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/sbrk.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <unistd.h>
#include <stdlib.h>

#if __SBRK_CHAR_PTRDIFF
char *
sbrk (ptrdiff_t)
#else
void *
sbrk (intptr_t delta)
#endif
{
  if (delta >= 0)
    return malloc (delta);
  return __brk;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/sleep.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <sys/time.h>
#include <time.h>
#include <unistd.h>

unsigned int
sleep (unsigned int seconds)
{
  struct timespec requested_time;
  struct timespec remaining;
  requested_time.tv_sec = seconds;
  requested_time.tv_nsec = 0;
  return nanosleep (&requested_time, &remaining);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/unsetenv.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <string.h>
#include <unistd.h>

void
unsetenv (char const *name)
{
  int length = strlen (name);
  char **p = environ;
  while (*p)
    {
      if (!strncmp (name, *p, length) && *(*p + length) == '=')
        {
          char **q = p;
          q[0] = q[1];
          while (*q++)
            q[0] = q[1];
        }
      p++;
    }
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/clearerr.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <errno.h>
#include <stdio.h>

void
clearerr (FILE * stream)
{
  errno = 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/feof.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>

int
feof (FILE * stream)
{
  int c = fgetc (stream);
  if (c != EOF)
    ungetc (c, stream);
  return c == EOF;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fgets.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <stdio.h>

char *
fgets (char *s, int count, FILE * stream)
{
  return fdgets (s, count, (int) (long) stream);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fileno.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>

int
fileno (FILE * stream)
{
  return (int) (long) stream;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/freopen.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>

FILE *
freopen (char const *file_name, char const *opentype, FILE * stream)
{
  fclose (stream);
  return fopen (file_name, opentype);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/fscanf.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <stdarg.h>
#include <stdio.h>

int
fscanf (FILE * stream, char const *template, ...)
{
  va_list ap;
  va_start (ap, template);
  int r = vfscanf (stream, template, ap);
  va_end (ap);
  return r;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/perror.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>

void
perror (char const *message)
{
  fprintf (stderr, "%s: %s\n", strerror (errno), message);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdio/vfscanf.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018,2019,2023 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>

int
vfscanf (FILE * stream, char const *template, va_list ap)
{
  char p = fgetc (stream);
  char const *t = template;
  int count = 0;
  while (*t && p != EOF)
    if (*t != '%')
      {
        t++;
        p = fgetc (stream);
      }
    else
      {
        t++;
        char c = *t;
        if (c == 'l')
          c = *++t;
        switch (c)
          {
          case '%':
            {
              p = fgetc (stream);
              break;
            }
          case 'c':
            {
              char *c = va_arg (ap, char *);
              *c = p;
              p = fgetc (stream);
              count++;
              break;
            }
          case 'd':
          case 'i':
          case 'u':
            {
              int *d = va_arg (ap, int *);
              char buf[20];
              char *q = buf;
              if (p == '+' || p == '-')
                {
                  *q++ = p;
                  p = fgetc (stream);
                }
              while (isdigit (p))
                {
                  *q++ = p;
                  p = fgetc (stream);
                }
              ungetc (p, stream);
              *q = 0;
              q = buf;
              *d = abtol ((char const**)&q, 10);
              count++;
              break;
            }
          case 'e':
          case 'f':
          case 'g':
          case 'E':
          case 'G':
            {
              float *f = va_arg (ap, float *);
              char buf[20];
              char *q = buf;
              if (p == '+' || p == '-')
                {
                  *q++ = p;
                  p = fgetc (stream);
                }
              while (isdigit (p))
                {
                  *q++ = p;
                  p = fgetc (stream);
                }
              ungetc (p, stream);
              *q = 0;
              q = buf;
              *f = strtod (q, &q);
              count++;
              break;
            }
          default:
            {
              eputs ("vsscanf: not supported: %:");
              eputc (c);
              eputs ("\n");
              t++;
              p = fgetc (stream);
            }
          }
        t++;
      }
  va_end (ap);
  return count;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/abort.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <signal.h>

void
abort (void)
{
  if (raise (SIGABRT) < 0) /* could not raise SIGABRT */
    {
      /* Fail in any way possible */
      unsigned char* x = (unsigned char*) 0;
      *x = 2;
    }
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/abs.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdlib.h>

int
abs (int x)
{
  if (x < 0)
    return -x;
  return x;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/alloca.c?h=v0.24.2

Files:
/* alloca.c -- allocate automatically reclaimed memory
   (Mostly) portable public-domain implementation -- D A Gwyn

   Taken from GNU binutils 2.10.1.
   Minor changes
   Copyright © 2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>

   This implementation of the PWB library alloca function,
   which is used to allocate space off the run-time stack so
   that it is automatically reclaimed upon procedure exit,
   was inspired by discussions with J. Q. Johnson of Cornell.

   There are some preprocessor constants that can
   be defined when compiling for your specific system, for
   improved efficiency; however, the defaults should be okay.

   The general concept of this implementation is to keep
   track of all alloca-allocated blocks, and reclaim any
   that are found to be deeper in the stack than the current
   invocation.  This heuristic does not reclaim storage as
   soon as it becomes invalid, but it will do so eventually.

   As a special case, alloca(0) reclaims storage without
   allocating any.  It is a good idea to use alloca(0) in
   your main control loop, etc. to force garbage collection.  */

#include <stdlib.h>
#include <unistd.h>

#define ALIGN_SIZE 4
#define ADDRESS_FUNCTION(arg) &(arg)
#define STACK_DIR -1

union alloca_header
{
  char align[ALIGN_SIZE];       /* To force sizeof(union alloca_header).  */
  struct
  {
    union alloca_header *next;  /* For chaining headers.  */
    char *deep;                 /* For stack depth measure.  */
  } h;
};

static union alloca_header *last_alloca_header = NULL;  /* -> last alloca header.  */

/* Return a void * to at least SIZE bytes of storage,
   which will be automatically reclaimed upon exit from
   the procedure that called alloca.  Originally, this space
   was supposed to be taken from the current stack frame of the
   caller, but that method cannot be made to work for some
   implementations of C, for example under Gould's UTX/32.  */

void *
alloca (size_t size)
{
  char probe;                   /* Probes stack depth: */
  char *depth = ADDRESS_FUNCTION (probe);

  /* Reclaim garbage, defined as all alloca'd storage that
     was allocated from deeper in the stack than currently.  */

  {
    union alloca_header *hp;    /* Traverses linked list.  */

    for (hp = last_alloca_header; hp != NULL;)
      if ((STACK_DIR > 0 && hp->h.deep > depth) || (STACK_DIR < 0 && hp->h.deep < depth))
        {
          union alloca_header *np = hp->h.next;

          free ((void *) hp);   /* Collect garbage.  */

          hp = np;              /* -> next header.  */
        }
      else
        break;                  /* Rest are not deeper.  */

    last_alloca_header = hp;    /* -> last valid storage.  */

  }

  if (size == 0)
    return NULL;                /* No allocation required.  */

  /* Allocate combined header + user data storage.  */

  {
    void *new = malloc (sizeof (union alloca_header) + size);
    /* Address of header.  */

    if (new == 0)
      abort ();

    ((union alloca_header *) new)->h.next = last_alloca_header;
    ((union alloca_header *) new)->h.deep = depth;

    last_alloca_header = (union alloca_header *) new;

    /* User storage begins just after header.  */

    return (void *) ((char *) new + sizeof (union alloca_header));
  }
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/atexit.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <stdlib.h>

int
atexit (void (*function) (void))
{
  __call_at_exit = function;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/atof.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>

double
atof (char const *string)
{
  char const *p = string;
  return abtod (&p, 0);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/atol.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdlib.h>

int
atol (char const *s)
{
  return atoi (s);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/__exit.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdlib.h>

int
__exit (int status)
{
  exit (status);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stdlib/mbstowcs.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2023 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

size_t
mbstowcs (wchar_t * wstring, char const *string, size_t size)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("mbstowcs stub\n");
  stub = 1;
  strcpy ((char*)wstring, string);
  return strlen (string);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/bcmp.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <string.h>

int
bcmp (void const *s1, void const *s2, size_t size)
{
  return memcmp (s1, s2, size);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/bcopy.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <string.h>

void
bcopy (void const *src, void *dest, size_t n)
{
  memmove (dest, src, n);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/bzero.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdlib.h>
#include <string.h>

#if BZERO_INT
int
#else
void
#endif
bzero (void *block, size_t size)
{
#if BZERO_INT
  return (int) (long)
#endif
    memset (block, 0, size);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/index.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <string.h>

#if INDEX_INT
int
#else
char *
#endif
index (char const *s, int c)
{
  return strchr (s, c);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/rindex.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <string.h>

#if INDEX_INT
int
#else
char *
#endif
rindex (char const *s, int c)
{
  return strrchr (s, c);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strcspn.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <string.h>

size_t
strcspn (char const *string, char const *stopset)
{
  char *p = (char *) string;
  while (*p)
    if (strchr (stopset, *p))
      break;
    else
      p++;
  return p - string;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strdup.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdlib.h>
#include <string.h>

char *
strdup (char const *s)
{
  size_t length = strlen (s) + 1;
  char *p = (char *) malloc (length);
  if (p)
    return memcpy (p, s, length);
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strerror.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <string.h>

char *sys_errlist[] = {
  "error 00",
  "error 01",
  "error 02",
  "error 03",
  "error 04",
  "error 05",
  "error 06",
  "error 07",
  "error 08",
  "error 09",
  "error 10",
  "error 11",
  "error 12",
  "error 13",
  "error 14",
  "error 15",
  "error 16",
  "error 17",
  "error 18",
  "error 19",
  "error 20",
  "error 21",
  "error 22",
  "error 23",
  "error 24",
  "error 25",
  "error 26",
  "error 27",
  "error 28",
  "error 29",
  "error 30",
  "error 31",
  "error 32",
  "error 33",
  "error 34",
  "error 35",
  "error 36",
  "error 37",
  "error 38",
  "error 39",
};

int sys_nerr = 39;

char *
strerror (int errnum)
{
  if (__mes_debug ())
    {
      eputs ("strerror errnum=");
      eputs (itoa (errnum));
      eputs ("\n");
    }
  if (errnum > 0 && errnum <= sys_nerr)
    return sys_errlist[errnum];
  return "sterror: unknown error";
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strncat.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <string.h>

char *
strncat (char *to, char const *from, size_t size)
{
  if (size == 0)
    return to;
  char *p = strchr (to, '\0');
  while (*from && size-- > 0)
    *p++ = *from++;
  *p = 0;
  return to;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strpbrk.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <string.h>

char *
strpbrk (char const *string, char const *stopset)
{
  char *p = (char *) string;
  while (*p)
    if (strchr (stopset, *p))
      break;
    else
      p++;
  return p;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/string/strspn.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <string.h>

size_t
strspn (char const *string, char const *skipset)
{
  char *p = (char *) string;
  while (*p)
    if (!strchr (skipset, *p))
      break;
    else
      p++;
  return p - string;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/atan2.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <math.h>

double
atan2 (double x, double y)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("atan2 stub\n");
  stub = 1;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/bsearch.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <stdlib.h>

void *
#if __MESC__
bsearch (void const *key, void const *array, size_t count, size_t size, void (*compare) ())
#else
bsearch (void const *key, void const *array, size_t count, size_t size, comparison_fn_t compare)
#endif
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("bsearch stub\n");
  stub = 1;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/chown.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <errno.h>
#include <unistd.h>

int
chown (char const *file_name, uid_t owner, gid_t group)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("chown stub\n");
  stub = 1;
  errno = 0;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/__cleanup.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>

int
__cleanup ()
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("__cleanup stub\n");
  stub = 1;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/cos.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <math.h>

double
cos (double x)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("cos stub\n");
  stub = 1;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/ctime.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <errno.h>
#include <time.h>

char *
ctime (time_t const *time)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("ctime stub\n");
  stub = 1;
  errno = 0;
  return "now";
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/exp.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <math.h>

double
exp (double x)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("exp stub\n");
  stub = 1;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/fpurge.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <errno.h>
#include <stdio.h>

int
fpurge (FILE * stream)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("fpurge stub\n");
  stub = 1;
  errno = 0;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/freadahead.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <errno.h>
#include <stdio.h>

size_t
freadahead (FILE * fp)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("freadahead stub\n");
  stub = 1;
  errno = 0;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/frexp.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>

double
frexp (int x)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("frexp stub\n");
  stub = 1;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/getgrgid.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <errno.h>
#include <grp.h>

struct group *
getgrgid (gid_t gid)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("getgrid stub\n");
  static char *groups[2] = { "root", 0 };
#if SYSTEM_LIBC
  static struct group root = { "root", 0, 0 };
  root.gr_mem = groups;
#else
  static struct group root = { "root", 0, groups };
#endif
  stub = 1;
  errno = 0;
  return &root;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/getgrnam.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <errno.h>
#include <grp.h>

struct group *
getgrnam (char const *name)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("getgrid stub\n");
  static char *groups[2] = { "root", 0 };
#if SYSTEM_LIBC
  static struct group root = { "root", 0, 0 };
  root.gr_mem = groups;
#else
  static struct group root = { "root", 0, groups };
#endif
  stub = 1;
  errno = 0;
  return &root;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/getlogin.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <errno.h>
#include <unistd.h>

char *
getlogin (void)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("getlogin stub\n");
  stub = 1;
  errno = 0;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/getpgid.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <errno.h>
#include <unistd.h>

int
getpgid (pid_t pid)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("getpgid stub\n");
  stub = 1;
  errno = 0;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/getpgrp.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <errno.h>
#include <unistd.h>

pid_t
getpgrp (void)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("getpgrp stub\n");
  stub = 1;
  errno = 0;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/getpwnam.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <errno.h>
#include <pwd.h>

struct passwd *
getpwnam (const char *name)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("getpwnam stub\n");
  stub = 1;
  errno = 0;
  static struct passwd root = { "root", "*", 0, 0, "", "/root", "/bin/sh" };
  return &root;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/getpwuid.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <errno.h>
#include <pwd.h>

struct passwd *
getpwuid (uid_t uid)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("getpwuid stub\n");
  stub = 1;
  errno = 0;
  static struct passwd root = { "root", "*", 0, 0, "", "/root", "/bin/sh" };
  return &root;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/gmtime.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <errno.h>
#include <time.h>
#include <sys/time.h>

struct tm *
gmtime (time_t const *time)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("gmtime stub\n");
  stub = 1;
  errno = 0;
  return localtime (time);
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/log.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <math.h>

double
log (double x)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("log stub\n");
  stub = 1;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/mktime.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <errno.h>
#include <time.h>

time_t
mktime (struct tm *broken_time)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("mktime stub\n");
  stub = 1;
  errno = 0;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/modf.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <math.h>

double
modf (double value, double *integer_part)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("modf stub\n");
  stub = 1;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/pclose.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <errno.h>

int
pclose (int x)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("pclose stub\n");
  stub = 1;
  errno = 0;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/popen.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <errno.h>

int
popen (int x)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("popen stub\n");
  stub = 1;
  errno = 0;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/pow.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <math.h>

double
pow (double base, double power)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("pow stub\n");
  stub = 1;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/rand.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <errno.h>

int
rand (void)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("rand stub\n");
  stub = 1;
  errno = 0;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/rewind.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <errno.h>

int
rewind (int x)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("rewind stub\n");
  stub = 1;
  errno = 0;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/setbuf.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <errno.h>

int
setbuf (int x)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("setbuf stub\n");
  stub = 1;
  errno = 0;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/setgrent.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <errno.h>

void
setgrent (void)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("setgrent stub\n");
  stub = 1;
  errno = 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/setlocale.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <locale.h>

char *
setlocale (int category, char const *locale)
{
  return "C";
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/setvbuf.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <stdio.h>

int
setvbuf (FILE * stream, char *buf, int mode, size_t size)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("setvbuf stub\n");
  stub = 1;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/sigaddset.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <signal.h>

int
sigaddset (sigset_t * set, int signum)
{
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/sigblock.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <signal.h>

int
sigblock (int mask)
{
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/sigdelset.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <signal.h>

int
sigdelset (sigset_t * set, int signum)
{
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/sigsetmask.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <errno.h>

int
sigsetmask (int x)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("sigsetmask stub\n");
  stub = 1;
  errno = 0;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/sin.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <math.h>

double
sin (double x)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("sin stub\n");
  stub = 1;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/sys_siglist.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <errno.h>

int
sys_siglist (int x)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("sys_siglist stub\n");
  stub = 1;
  errno = 0;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/system.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <errno.h>

int
system (int x)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("system stub\n");
  stub = 1;
  errno = 0;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/sqrt.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <math.h>

double
sqrt (double x)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("sqrt stub\n");
  stub = 1;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/strftime.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <time.h>

size_t
strftime (char *s, size_t size, char const *template, struct tm const *brokentime)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("strftime stub\n");
  stub = 1;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/times.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <sys/times.h>
#include <sys/time.h>

clock_t
times (struct tms *buffer)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("times stub\n");
  stub = 1;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/ttyname.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <errno.h>
#include <unistd.h>

char *
ttyname (int filedes)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("ttyname stub\n");
  stub = 1;
  errno = 0;
  if (isatty (filedes))
    return "/dev/tty0";
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/umask.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <errno.h>

int
umask (int x)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("umask stub\n");
  stub = 1;
  errno = 0;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/stub/utime.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>
#include <errno.h>

int
utime (int x)
{
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("utime stub\n");
  errno = 0;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/x86-mes-gcc/setjmp.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <setjmp.h>
#include <stdlib.h>

void
longjmp (jmp_buf env, int val)
{
  val = val == 0 ? 1 : val;
  // *INDENT-OFF*
  asm (
       "mov    0x8(%ebp),%ebp\n\t"     // env*

       "mov    0x4(%ebp),%ebx\n\t"     // env->__pc
       "mov    0x8(%ebp),%esp\n\t"     // env->__sp
       "mov    0x0(%ebp),%ebp\n\t"     // env->__bp
       "jmp    *%ebx\n\t"              // jmp *PC
       );
  // *INDENT-ON*
  // not reached
  exit (42);
}

int
setjmp (jmp_buf env)
{
  long *p = (long *) &env;
  env[0].__bp = p[-2];
  env[0].__pc = p[-1];
  env[0].__sp = (long) &env;
  return 0;
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-gcc/crt1.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 * Copyright © 2021 Paul Dersey <pdersey@gmail.com>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib-mini.h>
//int main (int argc, char *argv[], char *envp[]);

// *INDENT-OFF*
void
_start ()
{
  asm (
       "mov    $0,%%eax\n\t"
       "mov    %%eax,%0\n"
       : "=r" (__stdin)
       : //no inputs ""
       );

  asm (
       "mov    $1,%%eax\n\t"
       "mov    %%eax,%0\n"
       : "=r" (__stdout)
       : //no inputs ""
       );

  asm (
       "mov    $2,%%eax\n\t"
       "mov    %%eax,%0\n"
       : "=r" (__stderr)
       : //no inputs ""
       );
  asm (
       "mov     %%ebp,%%eax\n\t"
       "add     $4,%%eax\n\t"
       "mov     (%%eax),%%eax\n\t"
       "add     $3,%%eax\n\t"
       "shl     $2,%%eax\n\t"
       "add     %%ebp,%%eax\n\t"
       "mov     %%eax,%0\n\t"
       "push    %%eax\n\t"
       : "=r" (environ)
       : //no inputs ""
       );
  asm (
       "mov     %ebp,%eax\n\t"
       "add     $8,%eax\n\t"
       "push    %eax\n\t"

       "mov     %ebp,%eax\n\t"
       "add     $4,%eax\n\t"
       "mov     (%eax),%eax\n\t"
       "push    %eax\n\t"

       "call    main\n\t"

       "mov     %eax,%ebx\n\t"
       "mov     $1,%eax\n\t"
       "int     $0x80\n\t"
       "hlt     \n\t"
       );
}

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-gcc/crtn.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/linux/x86-mes-gcc/crti.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/libtcc1.c?h=v0.24.2

Files:
/* -*-comment-start: "//";comment-end:""-*-
 * GNU Mes --- Maxwell Equations of Software
 * Copyright © 2017,2018,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 * Copyright © 2021 Danny Milosavljevic <dannym@scratchpost.org>
 *
 * This file is part of GNU Mes.
 *
 * GNU Mes is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * GNU Mes is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <mes/lib.h>

#if HAVE_LONG_LONG
long long
__divdi3 (long long a, long long b)
#else
long
__divdi3 (long a, long b)
#endif
{
#if !__TINYC__
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("__divdi3 stub\n");
  stub = 1;
#endif
  // FIXME: Actually use long long
  long ai = a;
  long bi = b;
#if __arm__ && __TINYC__
  return __mesabi_idiv (ai, bi);
#else
  return ai / bi;
#endif
}

#if HAVE_LONG_LONG
long long
__moddi3 (long long a, long long b)
#else
long
__moddi3 (long a, long b)
#endif
{
#if !__TINYC__
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("__moddi3 stub\n");
  stub = 1;
#endif
  // FIXME: Actually use long long
  long ai = a;
  long bi = b;
#if __arm__ && __TINYC__
  return __mesabi_imod (ai, bi);
#else
  return ai % bi;
#endif
}

#if HAVE_LONG_LONG
unsigned long long
__udivdi3 (unsigned long long a, unsigned long long b)
#else
unsigned long
__udivdi3 (unsigned long a, long ah, unsigned long b)
#endif
{
#if !__TINYC__
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("__udivdi3 stub\n");
  stub = 1;
#endif
  // FIXME: Actually use long long
  unsigned long ai = a;
  unsigned long bi = b;
  if (!b)
    return 0;
#if __arm__ && __TINYC__
  return __mesabi_udiv (ai, bi);
#else
  return ai / bi;
#endif
}

#if HAVE_LONG_LONG
unsigned long long
__umoddi3 (unsigned long long a, unsigned long long b)
#else
unsigned long
__umoddi3 (unsigned long a, long ah, unsigned long b)
#endif
{
#if !__TINYC__
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("__umoddi3 stub\n");
  stub = 1;
#endif
  // FIXME: Actually use long long
  unsigned long ai = a;
  unsigned long bi = b;
#if __arm__ && __TINYC__
  return __mesabi_umod (ai, bi);
#else
  return ai % bi;
#endif
}

#if HAVE_LONG_LONG
unsigned long long
__lshrdi3 (unsigned long long a, long b)
#else
unsigned long
__lshrdi3 (unsigned long a, long ah, long b)
#endif
{
#if !__TINYC__
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("__lshrdi3 stub\n");
  stub = 1;
  return a >> b;
#else //  __TINYC__
  for (int i = 0; i < b; i++)
#if __arm__
    a = __mesabi_udiv (a, 2); // I sure hope that doesn't endless recurse because of the optimizations in __mesabi_udiv that shift
#else // !__arm__
    a /= 2;
#endif // !__arm__
  return a;
#endif // __TINYC__
}

#if HAVE_LONG_LONG
long long
__ashldi3 (long long a, long b)
#else
long
__ashldi3 (long a, long ah, long b)
#endif
{
#if !__TINYC__
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("__ashldi3 stub\n");
  stub = 1;
  return a << b;
#else //  __TINYC__
  for (int i = 0; i < b; i++)
    a += a;
  return a;
#endif // __TINYC__
}

#if HAVE_LONG_LONG
long long
__ashrdi3 (long long a, long b)
#else
long
__ashrdi3 (long a, long ah, long b)
#endif
{
#if !__TINYC__
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("__ashrdi3 stub\n");
  stub = 1;
 return a >> b;
#else //  __TINYC__
  for (int i = 0; i < b; i++)
#if __arm__
    a = __mesabi_idiv (a, 2); // I sure hope that doesn't endless recurse because of the optimizations in __mesabi_udiv that shift
#else // !__arm__
    a /= 2;
#endif // !__arm__
  return a;
#endif // __TINYC__
}

#if HAVE_FLOAT_STUB || HAVE_FLOAT
double
__attribute__((weak))
#if HAVE_LONG_LONG && HAVE_FLOAT
__floatundidf (unsigned long long a)
#else
__floatundidf (unsigned long a)
#endif
{
#if !__TINYC__
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("__floatundidf stub\n");
  stub = 1;
#endif
  return 0;
}

#if HAVE_LONG_LONG && HAVE_FLOAT
long double
__attribute__((weak))
__floatundixf (unsigned long long a)
#else
double
__attribute__((weak))
__floatundixf (unsigned long a)
#endif
{
#if !__TINYC__
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("__floatundixf stub\n");
  stub = 1;
#endif
  return 0;
}

#if HAVE_LONG_LONG
unsigned long long
#else
unsigned long
#endif
__attribute__((weak))
__fixunsxfdi (double a1)
{
#if !__TINYC__
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("__fixunsxfdi stub\n");
  stub = 1;
#endif
  return 0;
}

#if __TINYC__ == 9226
long
#elif __TINYC__
int
#else // !__TINYCC__
long long
#endif // !__TINYCC__
__attribute__((weak))
__fixdfdi (double a1)
{
#if !__TINYC__
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("__fixdfdi stub\n");
  stub = 1;
#endif
  return 0;
}

#if HAVE_LONG_LONG
unsigned long long
#else
unsigned long
#endif
__attribute__((weak))
__fixxfdi (double a1)
{
#if !__TINYC__
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("__fixxfdi stub\n");
  stub = 1;
#endif
  return 0;
}

#if HAVE_LONG_LONG
long long
#else
long
#endif
__attribute__((weak))
__fixsfdi (double a1)
{
#if !__TINYC__
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("__fixsfdi stub\n");
  stub = 1;
#endif
  return 0;
}

double
__attribute__((weak))
__fixunsdfdi (double num, double den)
{
#if !__TINYC__
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("__fixunsdfdi stub\n");
  stub = 1;
#endif
  return 0;
}
#endif // HAVE_FLOAT_STUB || HAVE_FLOAT

int
__attribute__((weak))
__fixunsdfsi (int a, int b)
{
#if !__TINYC__
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("__fixunsdfsi stub\n");
  stub = 1;
#endif
  return 0;
}

#if __arm__
int
__attribute__((weak))
__floatdisf (int a, int b)
{
#if !__TINYC__
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("__floatdisf stub\n");
  stub = 1;
#endif
  return 0;
}

int
__attribute__((weak))
__floatdidf (int a, int b)
{
#if !__TINYC__
  static int stub = 0;
  if (__mes_debug () && !stub)
    eputs ("__floatdidf stub\n");
  stub = 1;
#endif
  return 0;
}

int
__divsi3 (int num, int den)
{
  return __mesabi_idiv (num, den);
}

int
__modsi3 (int num, int den)
{
  return __mesabi_imod (num, den);
}

int
__udivsi3 (int num, int den)
{
  return __mesabi_udiv (num, den);
}

int
__umodsi3 (int num, int den)
{
  return __mesabi_umod (num, den);
}
#endif //__arm__

https://git.savannah.gnu.org/cgit/mes.git/tree/lib/posix/getopt.c?h=v0.24.2

File: ../git/live-bootstrap/sysa/tcc-0.9.26/build/mes-0.24.2/lib/posix/getopt.c used in: Step 393, Step 471
/* Getopt for GNU.
   Copyright (C) 1987, 88, 89, 90, 91, 1992 Free Software Foundation, Inc.
   Copyright (C) 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; If not, see <http://www.gnu.org/licenses/>. */



#include <stdio.h>
#include <string.h>
#include <getopt.h>

#if __MESC__
#define static
#endif

/* For communication from `getopt' to the caller.
   When `getopt' finds an option that takes an argument,
   the argument value is returned here. */

char *optarg = 0;

/* Index in ARGV of the next element to be scanned.
   This is used for communication to and from the caller
   and for communication between successive calls to `getopt'.

   On entry to `getopt', zero means this is the first call; initialize.

   When `getopt' returns EOF, this is the index of the first of the
   non-option elements that the caller should itself scan.

   Otherwise, `optind' communicates from one call to the next
   how much of ARGV has been scanned so far.  */

int optind = 0;

/* The next char to be scanned in the option-element
   in which the last option character we returned was found.
   This allows us to pick up the scan where we left off.

   If this is zero, or a null string, it means resume the scan
   by advancing to the next ARGV-element.  */

static char *nextchar;

/* Callers store zero here to inhibit the error message
   for unrecognized options.  */

int opterr = 1;



/* Handle permutation of arguments.  */

/* Describe the part of ARGV that contains non-options that have
   been skipped.  `first_nonopt' is the index in ARGV of the first of them;
   `last_nonopt' is the index after the last of them.  */

static int first_nonopt;
static int last_nonopt;



/* Scan elements of ARGV (whose length is ARGC) for option characters
   given in OPTSTRING.

   If an element of ARGV starts with '-', and is not exactly "-" or "--",
   then it is an option element.  The characters of this element
   (aside from the initial '-') are option characters.  If `getopt'
   is called repeatedly, it returns successively each of the option characters
   from each of the option elements.

   If `getopt' finds another option character, it returns that character,
   updating `optind' and `nextchar' so that the next call to `getopt' can
   resume the scan with the following option character or ARGV-element.

   If there are no more option characters, `getopt' returns `EOF'.
   Then `optind' is the index in ARGV of the first ARGV-element
   that is not an option.  (The ARGV-elements have been permuted
   so that those that are not options now come last.)

   OPTSTRING is a string containing the legitimate option characters.
   If an option character is seen that is not listed in OPTSTRING,
   return '?' after printing an error message.  If you set `opterr' to
   zero, the error message is suppressed but we still return '?'.

   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
   so the following text in the same ARGV-element, or the text of the following
   ARGV-element, is returned in `optarg'.  Two colons mean an option that
   wants an optional arg; if there is text in the current ARGV-element,
   it is returned in `optarg', otherwise `optarg' is set to zero.

   If OPTSTRING starts with `-' or `+', it requests different methods of
   handling the non-option ARGV-elements.

   Long-named options begin with `--' instead of `-'.
   Their names may be abbreviated as long as the abbreviation is unique
   or is an exact match for some defined option.  If they have an
   argument, it follows the option name in the same ARGV-element, separated
   from the option name by a `=', or else the in next ARGV-element.
   When `getopt' finds a long-named option, it returns 0 if that option's
   `flag' field is nonzero, the value of the option's `val' field
   if the `flag' field is zero.

   The elements of ARGV aren't really const, because we permute them.
   But we pretend they're const in the prototype to be compatible
   with other systems.

   LONGOPTS is a vector of `struct option' terminated by an
   element containing a name which is zero.

   LONGIND returns the index in LONGOPT of the long-named option found.
   It is only valid when a long-named option has been found by the most
   recent call.

   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
   long-named options.  */

int
_getopt_internal (int argc, char *const
                  *argv, char const *optstring, struct option const *longopts, int *longind, int long_only)
{
  int option_index;

  optarg = 0;

  /* Initialize the internal data when the first call is made.
     Start processing options with ARGV-element 1 (since ARGV-element 0
     is the program name); the sequence of previously skipped
     non-option ARGV-elements is empty.  */

  if (optind == 0)
    {
      first_nonopt = last_nonopt = optind = 1;

      nextchar = NULL;
    }

  if (nextchar == NULL || *nextchar == '\0')
    {
      /* If we have done all the ARGV-elements, stop the scan
         and back over any non-options that we skipped and permuted.  */

      if (optind == argc)
        {
          /* Set the next-arg-index to point at the non-options
             that we previously skipped, so the caller will digest them.  */
          if (first_nonopt != last_nonopt)
            optind = first_nonopt;
          return EOF;
        }

      /* If we have come to a non-option and did not permute it,
         either stop the scan or describe it to the caller and pass it by.  */

      if ((argv[optind][0] != '-' || argv[optind][1] == '\0'))
        return EOF;

      /* We have found another option-ARGV-element.
         Start decoding its characters.  */

      nextchar = (argv[optind] + 1 + (longopts != NULL && argv[optind][1] == '-'));
    }

  if (longopts != NULL && ((argv[optind][0] == '-' && (argv[optind][1] == '-' || long_only))))
    {
      const struct option *p;
      char *s = nextchar;
      int exact = 0;
      int ambig = 0;
      const struct option *pfound = NULL;
      int indfound;

      while (*s && *s != '=')
        s++;

      /* Test all options for either exact match or abbreviated matches.  */
      for (p = longopts, option_index = 0; p->name; p++, option_index++)
        if (!strncmp (p->name, nextchar, s - nextchar))
          {
            if (s - nextchar == strlen (p->name))
              {
                /* Exact match found.  */
                pfound = p;
                indfound = option_index;
                exact = 1;
                break;
              }
            else if (pfound == NULL)
              {
                /* First nonexact match found.  */
                pfound = p;
                indfound = option_index;
              }
            else
              /* Second nonexact match found.  */
              ambig = 1;
          }

      if (ambig && !exact)
        {
          if (opterr)
            fprintf (stderr, "%s: option `%s' is ambiguous\n", argv[0], argv[optind]);
          nextchar += strlen (nextchar);
          optind++;
          return '?';
        }

      if (pfound != NULL)
        {
          option_index = indfound;
          optind++;
          if (*s)
            {
              /* Don't test has_arg with >, because some C compilers don't
                 allow it to be used on enums. */
              if (pfound->has_arg)
                optarg = s + 1;
              else
                {
                  if (opterr)
                    {
                      if (argv[optind - 1][1] == '-')
                        /* --option */
                        fprintf (stderr,
                                 "%s: option `--%s' doesn't allow an argument\n", argv[0], pfound->name);
                      else
                        /* +option or -option */
                        fprintf (stderr,
                                 "%s: option `%c%s' doesn't allow an argument\n",
                                 argv[0], argv[optind - 1][0], pfound->name);
                    }
                  nextchar += strlen (nextchar);
                  return '?';
                }
            }
          else if (pfound->has_arg == 1)
            {
              if (optind < argc)
                optarg = argv[optind++];
              else
                {
                  if (opterr)
                    fprintf (stderr, "%s: option `%s' requires an argument\n", argv[0], argv[optind - 1]);
                  nextchar += strlen (nextchar);
                  return '?';
                }
            }
          nextchar += strlen (nextchar);
          if (longind != NULL)
            *longind = option_index;
          if (pfound->flag)
            {
              *(pfound->flag) = pfound->val;
              return 0;
            }
          return pfound->val;
        }
      /* Can't find it as a long option.  If this is not getopt_long_only,
         or the option starts with '--' or is not a valid short
         option, then it's an error.
         Otherwise interpret it as a short option. */
      if (!long_only || argv[optind][1] == '-' || strchr (optstring, *nextchar) == NULL)
        {
          if (opterr)
            {
              if (argv[optind][1] == '-')
                /* --option */
                fprintf (stderr, "%s: unrecognized option `--%s'\n", argv[0], nextchar);
              else
                /* +option or -option */
                fprintf (stderr, "%s: unrecognized option `%c%s'\n", argv[0], argv[optind][0], nextchar);
            }
          nextchar += strlen (nextchar);
          optind++;
          return '?';
        }
    }

  /* Look at and handle the next option-character.  */

  {
    char c = *nextchar++;
    char *temp = strchr (optstring, c);

    /* Increment `optind' when we start to process its last character.  */
    if (*nextchar == '\0')
      optind++;

    if (temp == NULL || c == ':')
      {
        if (opterr)
          {
            if (c < 040 || c >= 0177)
              fprintf (stderr, "%s: unrecognized option, character code 0%o\n", argv[0], c);
            else
              fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c);
          }
        return '?';
      }
    if (temp[1] == ':')
      {
        if (temp[2] == ':')
          {
            /* This is an option that accepts an argument optionally.  */
            if (*nextchar != '\0')
              {
                optarg = nextchar;
                optind++;
              }
            else
              optarg = 0;
            nextchar = NULL;
          }
        else
          {
            /* This is an option that requires an argument.  */
            if (*nextchar != 0)
              {
                optarg = nextchar;
                /* If we end this ARGV-element by taking the rest as an arg,
                   we must advance to the next element now.  */
                optind++;
              }
            else if (optind == argc)
              {
                if (opterr)
                  fprintf (stderr, "%s: option `-%c' requires an argument\n", argv[0], c);
                c = '?';
              }
            else
              /* We already incremented `optind' once;
                 increment it again when taking next ARGV-elt as argument.  */
              optarg = argv[optind++];
            nextchar = NULL;
          }
      }
    return c;
  }
}

int
getopt (int argc, char *const *argv, char const *options)
{
  return _getopt_internal (argc, argv, options, (const struct option *) 0, (int *) 0, 0);
}

int
getopt_long (int argc, char *const *argv, char const *options,
             struct option const *long_options, int *opt_index)
{
  return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
}

int
getopt_long_only (int argc, char *const *argv, char const *options,
                  struct option const *long_options, int *opt_index)
{
  return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
}

https://gitlab.com/janneke/tinycc/-/blob/ff2210b308321f27ee07476d07f24b5095602b17/lib/libtcc1.c

File: ../git/live-bootstrap/sysa/tcc-0.9.26/build/tcc-0.9.26-1136-g5bba73cc/lib/libtcc1.c used in: Step 402, Step 414, Step 426, Step 438, Step 450, Step 462
/* TCC runtime library. 
   Parts of this code are (c) 2002 Fabrice Bellard 

   Copyright (C) 1987, 1988, 1992, 1994, 1995 Free Software Foundation, Inc.

This file is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.

In addition to the permissions in the GNU General Public License, the
Free Software Foundation gives you unlimited permission to link the
compiled version of this file into combinations with other programs,
and to distribute those combinations without any restriction coming
from the use of this file.  (The General Public License restrictions
do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)

This file is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; see the file COPYING.  If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.  
*/

#define W_TYPE_SIZE   32
#define BITS_PER_UNIT 8

typedef int Wtype;
typedef unsigned int UWtype;
typedef unsigned int USItype;
typedef long long DWtype;
typedef unsigned long long UDWtype;

struct DWstruct {
    Wtype low, high;
};

typedef union
{
  struct DWstruct s;
  DWtype ll;
} DWunion;

typedef long double XFtype;
#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)

/* the following deal with IEEE single-precision numbers */
#define EXCESS      126
#define SIGNBIT     0x80000000
#define HIDDEN      (1 << 23)
#define SIGN(fp)    ((fp) & SIGNBIT)
#define EXP(fp)     (((fp) >> 23) & 0xFF)
#define MANT(fp)    (((fp) & 0x7FFFFF) | HIDDEN)
#define PACK(s,e,m) ((s) | ((e) << 23) | (m))

/* the following deal with IEEE double-precision numbers */
#define EXCESSD     1022
#define HIDDEND     (1 << 20)
#define EXPD(fp)    (((fp.l.upper) >> 20) & 0x7FF)
#define SIGND(fp)   ((fp.l.upper) & SIGNBIT)
#define MANTD(fp)   (((((fp.l.upper) & 0xFFFFF) | HIDDEND) << 10) | \
                (fp.l.lower >> 22))
#define HIDDEND_LL  ((long long)1 << 52)
#define MANTD_LL(fp)    ((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL)
#define PACKD_LL(s,e,m) (((long long)((s)+((e)<<20))<<32)|(m))

/* the following deal with x86 long double-precision numbers */
#define EXCESSLD    16382
#define EXPLD(fp)   (fp.l.upper & 0x7fff)
#define SIGNLD(fp)  ((fp.l.upper) & 0x8000)

/* only for x86 */
union ldouble_long {
    long double ld;
    struct {
        unsigned long long lower;
        unsigned short upper;
    } l;
};

union double_long {
    double d;
#if 1
    struct {
        unsigned int lower;
        int upper;
    } l;
#else
    struct {
        int upper;
        unsigned int lower;
    } l;
#endif
    long long ll;
};

union float_long {
    float f;
    unsigned int l;
};

/* XXX: we don't support several builtin supports for now */
#if !defined(TCC_TARGET_X86_64) && !defined(TCC_TARGET_ARM)

/* XXX: use gcc/tcc intrinsic ? */
#if defined(TCC_TARGET_I386)
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
  __asm__ ("subl %5,%1\n\tsbbl %3,%0"                   \
       : "=r" ((USItype) (sh)),                 \
         "=&r" ((USItype) (sl))                 \
       : "0" ((USItype) (ah)),                  \
         "g" ((USItype) (bh)),                  \
         "1" ((USItype) (al)),                  \
         "g" ((USItype) (bl)))
#define umul_ppmm(w1, w0, u, v) \
  __asm__ ("mull %3"                            \
       : "=a" ((USItype) (w0)),                 \
         "=d" ((USItype) (w1))                  \
       : "%0" ((USItype) (u)),                  \
         "rm" ((USItype) (v)))
#define udiv_qrnnd(q, r, n1, n0, dv) \
  __asm__ ("divl %4"                            \
       : "=a" ((USItype) (q)),                  \
         "=d" ((USItype) (r))                   \
       : "0" ((USItype) (n0)),                  \
         "1" ((USItype) (n1)),                  \
         "rm" ((USItype) (dv)))
#define count_leading_zeros(count, x) \
  do {                                  \
    USItype __cbtmp;                            \
    __asm__ ("bsrl %1,%0"                       \
         : "=r" (__cbtmp) : "rm" ((USItype) (x)));          \
    (count) = __cbtmp ^ 31;                     \
  } while (0)
#else
#error unsupported CPU type
#endif

/* most of this code is taken from libgcc2.c from gcc */

static UDWtype __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
{
  DWunion ww;
  DWunion nn, dd;
  DWunion rr;
  UWtype d0, d1, n0, n1, n2;
  UWtype q0, q1;
  UWtype b, bm;

  nn.ll = n;
  dd.ll = d;

  d0 = dd.s.low;
  d1 = dd.s.high;
  n0 = nn.s.low;
  n1 = nn.s.high;

#if !defined(UDIV_NEEDS_NORMALIZATION)
  if (d1 == 0)
    {
      if (d0 > n1)
    {
      /* 0q = nn / 0D */

      udiv_qrnnd (q0, n0, n1, n0, d0);
      q1 = 0;

      /* Remainder in n0.  */
    }
      else
    {
      /* qq = NN / 0d */

      if (d0 == 0)
        d0 = 1 / d0;    /* Divide intentionally by zero.  */

      udiv_qrnnd (q1, n1, 0, n1, d0);
      udiv_qrnnd (q0, n0, n1, n0, d0);

      /* Remainder in n0.  */
    }

      if (rp != 0)
    {
      rr.s.low = n0;
      rr.s.high = 0;
      *rp = rr.ll;
    }
    }

#else /* UDIV_NEEDS_NORMALIZATION */

  if (d1 == 0)
    {
      if (d0 > n1)
    {
      /* 0q = nn / 0D */

      count_leading_zeros (bm, d0);

      if (bm != 0)
        {
          /* Normalize, i.e. make the most significant bit of the
         denominator set.  */

          d0 = d0 << bm;
          n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
          n0 = n0 << bm;
        }

      udiv_qrnnd (q0, n0, n1, n0, d0);
      q1 = 0;

      /* Remainder in n0 >> bm.  */
    }
      else
    {
      /* qq = NN / 0d */

      if (d0 == 0)
        d0 = 1 / d0;    /* Divide intentionally by zero.  */

      count_leading_zeros (bm, d0);

      if (bm == 0)
        {
          /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
         conclude (the most significant bit of n1 is set) /\ (the
         leading quotient digit q1 = 1).

         This special case is necessary, not an optimization.
         (Shifts counts of W_TYPE_SIZE are undefined.)  */

          n1 -= d0;
          q1 = 1;
        }
      else
        {
          /* Normalize.  */

          b = W_TYPE_SIZE - bm;

          d0 = d0 << bm;
          n2 = n1 >> b;
          n1 = (n1 << bm) | (n0 >> b);
          n0 = n0 << bm;

          udiv_qrnnd (q1, n1, n2, n1, d0);
        }

      /* n1 != d0...  */

      udiv_qrnnd (q0, n0, n1, n0, d0);

      /* Remainder in n0 >> bm.  */
    }

      if (rp != 0)
    {
      rr.s.low = n0 >> bm;
      rr.s.high = 0;
      *rp = rr.ll;
    }
    }
#endif /* UDIV_NEEDS_NORMALIZATION */

  else
    {
      if (d1 > n1)
    {
      /* 00 = nn / DD */

      q0 = 0;
      q1 = 0;

      /* Remainder in n1n0.  */
      if (rp != 0)
        {
          rr.s.low = n0;
          rr.s.high = n1;
          *rp = rr.ll;
        }
    }
      else
    {
      /* 0q = NN / dd */

      count_leading_zeros (bm, d1);
      if (bm == 0)
        {
          /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
         conclude (the most significant bit of n1 is set) /\ (the
         quotient digit q0 = 0 or 1).

         This special case is necessary, not an optimization.  */

          /* The condition on the next line takes advantage of that
         n1 >= d1 (true due to program flow).  */
          if (n1 > d1 || n0 >= d0)
        {
          q0 = 1;
          sub_ddmmss (n1, n0, n1, n0, d1, d0);
        }
          else
        q0 = 0;

          q1 = 0;

          if (rp != 0)
        {
          rr.s.low = n0;
          rr.s.high = n1;
          *rp = rr.ll;
        }
        }
      else
        {
          UWtype m1, m0;
          /* Normalize.  */

          b = W_TYPE_SIZE - bm;

          d1 = (d1 << bm) | (d0 >> b);
          d0 = d0 << bm;
          n2 = n1 >> b;
          n1 = (n1 << bm) | (n0 >> b);
          n0 = n0 << bm;

          udiv_qrnnd (q0, n1, n2, n1, d1);
          umul_ppmm (m1, m0, q0, d0);

          if (m1 > n1 || (m1 == n1 && m0 > n0))
        {
          q0--;
          sub_ddmmss (m1, m0, m1, m0, d1, d0);
        }

          q1 = 0;

          /* Remainder in (n1n0 - m1m0) >> bm.  */
          if (rp != 0)
        {
          sub_ddmmss (n1, n0, n1, n0, m1, m0);
          rr.s.low = (n1 << b) | (n0 >> bm);
          rr.s.high = n1 >> bm;
          *rp = rr.ll;
        }
        }
    }
    }

  ww.s.low = q0;
  ww.s.high = q1;
  return ww.ll;
}

#define __negdi2(a) (-(a))

long long __divdi3(long long u, long long v)
{
    int c = 0;
    DWunion uu, vv;
    DWtype w;
    
    uu.ll = u;
    vv.ll = v;
    
    if (uu.s.high < 0) {
        c = ~c;
        uu.ll = __negdi2 (uu.ll);
    }
    if (vv.s.high < 0) {
        c = ~c;
        vv.ll = __negdi2 (vv.ll);
    }
    w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
    if (c)
        w = __negdi2 (w);
    return w;
}

long long __moddi3(long long u, long long v)
{
    int c = 0;
    DWunion uu, vv;
    DWtype w;
    
    uu.ll = u;
    vv.ll = v;
    
    if (uu.s.high < 0) {
        c = ~c;
        uu.ll = __negdi2 (uu.ll);
    }
    if (vv.s.high < 0)
        vv.ll = __negdi2 (vv.ll);
    
    __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) &w);
    if (c)
        w = __negdi2 (w);
    return w;
}

unsigned long long __udivdi3(unsigned long long u, unsigned long long v)
{
    return __udivmoddi4 (u, v, (UDWtype *) 0);
}

unsigned long long __umoddi3(unsigned long long u, unsigned long long v)
{
    UDWtype w;
    
    __udivmoddi4 (u, v, &w);
    return w;
}

/* XXX: fix tcc's code generator to do this instead */
long long __ashrdi3(long long a, int b)
{
#ifdef __TINYC__
    DWunion u;
    u.ll = a;
    if (b >= 32) {
        u.s.low = u.s.high >> (b - 32);
        u.s.high = u.s.high >> 31;
    } else if (b != 0) {
        u.s.low = ((unsigned)u.s.low >> b) | (u.s.high << (32 - b));
        u.s.high = u.s.high >> b;
    }
    return u.ll;
#else
    return a >> b;
#endif
}

/* XXX: fix tcc's code generator to do this instead */
unsigned long long __lshrdi3(unsigned long long a, int b)
{
#ifdef __TINYC__
    DWunion u;
    u.ll = a;
    if (b >= 32) {
        u.s.low = (unsigned)u.s.high >> (b - 32);
        u.s.high = 0;
    } else if (b != 0) {
        u.s.low = ((unsigned)u.s.low >> b) | (u.s.high << (32 - b));
        u.s.high = (unsigned)u.s.high >> b;
    }
    return u.ll;
#else
    return a >> b;
#endif
}

/* XXX: fix tcc's code generator to do this instead */
long long __ashldi3(long long a, int b)
{
#ifdef __TINYC__
    DWunion u;
    u.ll = a;
    if (b >= 32) {
        u.s.high = (unsigned)u.s.low << (b - 32);
        u.s.low = 0;
    } else if (b != 0) {
        u.s.high = ((unsigned)u.s.high << b) | ((unsigned)u.s.low >> (32 - b));
        u.s.low = (unsigned)u.s.low << b;
    }
    return u.ll;
#else
    return a << b;
#endif
}

#endif /* !__x86_64__ */

/* XXX: fix tcc's code generator to do this instead */
float __floatundisf(unsigned long long a)
{
    DWunion uu; 
    XFtype r;

    uu.ll = a;
    if (uu.s.high >= 0) {
        return (float)uu.ll;
    } else {
        r = (XFtype)uu.ll;
        r += 18446744073709551616.0;
        return (float)r;
    }
}

double __floatundidf(unsigned long long a)
{
    DWunion uu; 
    XFtype r;

    uu.ll = a;
    if (uu.s.high >= 0) {
        return (double)uu.ll;
    } else {
        r = (XFtype)uu.ll;
        r += 18446744073709551616.0;
        return (double)r;
    }
}

long double __floatundixf(unsigned long long a)
{
    DWunion uu; 
    XFtype r;

    uu.ll = a;
    if (uu.s.high >= 0) {
        return (long double)uu.ll;
    } else {
        r = (XFtype)uu.ll;
        r += 18446744073709551616.0;
        return (long double)r;
    }
}

unsigned long long __fixunssfdi (float a1)
{
    register union float_long fl1;
    register int exp;
    register unsigned long l;

    fl1.f = a1;

    if (fl1.l == 0)
    return (0);

    exp = EXP (fl1.l) - EXCESS - 24;

    l = MANT(fl1.l);
    if (exp >= 41)
    return (unsigned long long)-1;
    else if (exp >= 0)
        return (unsigned long long)l << exp;
    else if (exp >= -23)
        return l >> -exp;
    else
        return 0;
}

long long __fixsfdi (float a1)
{
    long long ret; int s;
    ret = __fixunssfdi((s = a1 >= 0) ? a1 : -a1);
    return s ? ret : -ret;
}

unsigned long long __fixunsdfdi (double a1)
{
    register union double_long dl1;
    register int exp;
    register unsigned long long l;

    dl1.d = a1;

    if (dl1.ll == 0)
    return (0);

    exp = EXPD (dl1) - EXCESSD - 53;

    l = MANTD_LL(dl1);

    if (exp >= 12)
    return (unsigned long long)-1;
    else if (exp >= 0)
        return l << exp;
    else if (exp >= -52)
        return l >> -exp;
    else
        return 0;
}

long long __fixdfdi (double a1)
{
    long long ret; int s;
    ret = __fixunsdfdi((s = a1 >= 0) ? a1 : -a1);
    return s ? ret : -ret;
}

#ifndef TCC_TARGET_ARM
unsigned long long __fixunsxfdi (long double a1)
{
    register union ldouble_long dl1;
    register int exp;
    register unsigned long long l;

    dl1.ld = a1;

    if (dl1.l.lower == 0 && dl1.l.upper == 0)
    return (0);

    exp = EXPLD (dl1) - EXCESSLD - 64;

    l = dl1.l.lower;

    if (exp > 0)
    return (unsigned long long)-1;
    else if (exp >= -63) 
        return l >> -exp;
    else
        return 0;
}

long long __fixxfdi (long double a1)
{
    long long ret; int s;
    ret = __fixunsxfdi((s = a1 >= 0) ? a1 : -a1);
    return s ? ret : -ret;
}
#endif /* !ARM */

https://github.com/fosslinux/live-bootstrap/blob/master/sysa/tcc-0.9.26/tcc-0.9.26.checksums

File: ../git/live-bootstrap/sysa/tcc-0.9.26/tcc-0.9.26.checksums used in: Step 474
7897c2ba182e92765856a9e3ddd2bdfcd69988b3ddc45b3ef932dc3ec041041a  /usr/bin/mes-tcc
64bdb36f0048744957454b6ad186d37db4a7fcc392f67bf052b9bc7ec033b963  /usr/bin/boot0-tcc
18af79e0e3c4bfeaced2b0867561bc9fd370cbfcc78860de5a70926374ba7c53  /usr/bin/boot1-tcc
d6fa0c2006f6c8fefb4f3750fade14aa884670637098857d06aef3c7a9bd02d8  /usr/bin/boot2-tcc
93b2c1c567f5938435fbe6c0115276f6073bd46a0a92791b164ca2752180caf5  /usr/bin/boot3-tcc
a40305e6d2acb3dc64dbc80f64952431f4728eeff03f6e7c91c737cbf6e1bdda  /usr/bin/boot4-tcc
c56d99e284dfecae047e792b049c0cee022452f13262d6b3c869ec1c9935b276  /usr/bin/tcc
96f93f2d281ee6996767b25fbff4441e8335e7eeaeab060c1d4b698366b277c9  /usr/lib/mes/libc.a
12c07ae103e7e3b390150a79e5c600d88de14e9bb73a066f6342582729ef5a3f  /usr/lib/mes/libgetopt.a
d1168ee9b528e39f0b40e8d51fb7fa3619c4a5ee928137f7faf6d0879b0916b0  /usr/lib/mes/crt1.o
09d4f9821a2566f7e56381a19259c41bd97f3c5ed83f490705acbfd1139a7736  /usr/lib/mes/crti.o
461ca1494737fab86fe1c1d3addeaf9d0ece413e353abcdea8674db3f700cda3  /usr/lib/mes/crtn.o
ac11f09698f092ed76ae40ebcd56cf3f2b903ea1333ef7537a00673dd6f73da7  /usr/lib/mes/tcc/libtcc1.a

https://github.com/fosslinux/live-bootstrap/blob/master/sysa/tcc-0.9.27/sources

File: ../git/live-bootstrap/sysa/tcc-0.9.27/sources used in: Step 476
https://download.savannah.gnu.org/releases/tinycc/tcc-0.9.27.tar.bz2 de23af78fca90ce32dff2dd45b3432b2334740bb9bb7b05bf60fdbfc396ceb9c

https://github.com/fosslinux/live-bootstrap/blob/master/sysa/tcc-0.9.27/simple-patches/remove-fileopen.before

File: /sysa/tcc-0.9.27/simple-patches/remove-fileopen.before used in: Step 482
    if (ret == 1)
        return ar_usage(ret);

    if ((fh = fopen(argv[i_lib], "wb")) == NULL)
    {
        fprintf(stderr, "tcc: ar: can't open file %s \n", argv[i_lib]);
        goto the_end;
    }

https://github.com/fosslinux/live-bootstrap/blob/master/sysa/tcc-0.9.27/simple-patches/remove-fileopen.after

File: /sysa/tcc-0.9.27/simple-patches/remove-fileopen.after used in: Step 482
    if (ret == 1)
        return ar_usage(ret);

https://github.com/fosslinux/live-bootstrap/blob/master/sysa/tcc-0.9.27/simple-patches/addback-fileopen.before

File: /sysa/tcc-0.9.27/simple-patches/addback-fileopen.before used in: Step 483
    // write header

https://github.com/fosslinux/live-bootstrap/blob/master/sysa/tcc-0.9.27/simple-patches/addback-fileopen.after

File: /sysa/tcc-0.9.27/simple-patches/addback-fileopen.after used in: Step 483
    if ((fh = fopen(argv[i_lib], "wb")) == NULL)
    {
        fprintf(stderr, "tcc: ar: can't open file %s \n", argv[i_lib]);
        goto the_end;
    }

    // write header

https://gitlab.com/janneke/tinycc/-/tree/release_0_9_27/tccelf.c

Files:
/*
 *  ELF file handling for TCC
 *
 *  Copyright (c) 2001-2004 Fabrice Bellard
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "tcc.h"

/* Define this to get some debug output during relocation processing.  */
#undef DEBUG_RELOC

/********************************************************/
/* global variables */

ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
ST_DATA Section *common_section;
ST_DATA Section *cur_text_section; /* current section where function code is generated */
#ifdef CONFIG_TCC_ASM
ST_DATA Section *last_text_section; /* to handle .previous asm directive */
#endif
#ifdef CONFIG_TCC_BCHECK
/* bound check related sections */
ST_DATA Section *bounds_section; /* contains global data bound description */
ST_DATA Section *lbounds_section; /* contains local data bound description */
#endif
/* symbol sections */
ST_DATA Section *symtab_section;
/* debug sections */
ST_DATA Section *stab_section, *stabstr_section;

/* XXX: avoid static variable */
static int new_undef_sym = 0; /* Is there a new undefined sym since last new_undef_sym() */

/* special flag to indicate that the section should not be linked to the other ones */
#define SHF_PRIVATE 0x80000000
/* section is dynsymtab_section */
#define SHF_DYNSYM 0x40000000

/* ------------------------------------------------------------------------- */

ST_FUNC void tccelf_new(TCCState *s)
{
    /* no section zero */
    dynarray_add(&s->sections, &s->nb_sections, NULL);

    /* create standard sections */
    text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
    data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
    bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
    common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);
    common_section->sh_num = SHN_COMMON;

    /* symbols are always generated for linking stage */
    symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
                                ".strtab",
                                ".hashtab", SHF_PRIVATE);
    s->symtab = symtab_section;

    /* private symbol table for dynamic symbols */
    s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE|SHF_DYNSYM,
                                      ".dynstrtab",
                                      ".dynhashtab", SHF_PRIVATE);
    get_sym_attr(s, 0, 1);
}

#ifdef CONFIG_TCC_BCHECK
ST_FUNC void tccelf_bounds_new(TCCState *s)
{
    /* create bounds sections */
    bounds_section = new_section(s, ".bounds",
                                 SHT_PROGBITS, SHF_ALLOC);
    lbounds_section = new_section(s, ".lbounds",
                                  SHT_PROGBITS, SHF_ALLOC);
}
#endif

ST_FUNC void tccelf_stab_new(TCCState *s)
{
    stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
    stab_section->sh_entsize = sizeof(Stab_Sym);
    stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
    put_elf_str(stabstr_section, "");
    stab_section->link = stabstr_section;
    /* put first entry */
    put_stabs("", 0, 0, 0, 0);
}

static void free_section(Section *s)
{
    tcc_free(s->data);
}

ST_FUNC void tccelf_delete(TCCState *s1)
{
    int i;

    /* free all sections */
    for(i = 1; i < s1->nb_sections; i++)
        free_section(s1->sections[i]);
    dynarray_reset(&s1->sections, &s1->nb_sections);

    for(i = 0; i < s1->nb_priv_sections; i++)
        free_section(s1->priv_sections[i]);
    dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections);

    /* free any loaded DLLs */
#ifdef TCC_IS_NATIVE
    for ( i = 0; i < s1->nb_loaded_dlls; i++) {
        DLLReference *ref = s1->loaded_dlls[i];
        if ( ref->handle )
# ifdef _WIN32
            FreeLibrary((HMODULE)ref->handle);
# else
            dlclose(ref->handle);
# endif
    }
#endif
    /* free loaded dlls array */
    dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
    tcc_free(s1->sym_attrs);

    symtab_section = NULL; /* for tccrun.c:rt_printline() */
}

/* save section data state */
ST_FUNC void tccelf_begin_file(TCCState *s1)
{
    Section *s; int i;
    for (i = 1; i < s1->nb_sections; i++) {
        s = s1->sections[i];
        s->sh_offset = s->data_offset;
    }
    /* disable symbol hashing during compilation */
    s = s1->symtab, s->reloc = s->hash, s->hash = NULL;
#if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
    s1->uw_sym = 0;
#endif
}

/* At the end of compilation, convert any UNDEF syms to global, and merge
   with previously existing symbols */
ST_FUNC void tccelf_end_file(TCCState *s1)
{
    Section *s = s1->symtab;
    int first_