[
  {
    "path": ".gitignore",
    "content": "# Compiled Object files\n*.slo\n*.lo\n*.o\n\n# Compiled Dynamic libraries\n*.so\n*.dylib\n\n# Compiled Static libraries\n*.lai\n*.la\n*.a\n\n# Elf binaries\n*.elf\n\n# Vagrant\n/src/.vagrant/\n\n# Other\n/src/userland/helloworld/hello\n\n# SDK binaries\n/src/sdk/bootdisk/bin/hello\n/src/sdk/c.img\n\nnode_modules\n.grunt\n_book\n"
  },
  {
    "path": "Chapter-1/README.md",
    "content": "## Chapter 1: Introduction to the x86 architecture and about our OS\n\n### What is the x86 architecture?\n\n> The term x86 denotes a family of backward compatible instruction set architectures based on the Intel 8086 CPU.\n\nThe x86 architecture is the most common instruction set architecture since its introduction in 1981 for the IBM PC. A large amount of software, including operating systems (OS's) such as DOS, Windows, Linux, BSD, Solaris and Mac OS X, function with x86-based hardware.\n\nIn this course we are not going to design an operating system for the x86-64 architecture but for x86-32, thanks to backward compatibility, our OS will be compatible with our newer PCs (but take caution if you want to test it on your real machine).\n\n### Our Operating System\n\nThe goal is to build a very simple UNIX-based operating system in C++, but the goal is not to just build a \"proof-of-concept\". The OS should be able to boot, start a userland shell and be extensible.\n\nThe OS will be built for the x86 architecture, running on 32 bits, and compatible with IBM PCs.\n\n**Specifications:**\n\n* Code in C++\n* x86, 32 bit architecture\n* Boot with Grub\n* Kind of modular system for drivers\n* Kind of UNIX style\n* Multitasking\n* ELF executable in userland\n* Modules (accessible in userland using /dev/...) :\n    * IDE disks\n    * DOS partitions\n    * Clock\n    * EXT2 (read only)\n    * Boch VBE\n* Userland :\n    * API Posix\n    * LibC\n    * \"Can\" run a shell or some executables (e.g., lua)\n"
  },
  {
    "path": "Chapter-2/README.md",
    "content": "## Chapter 2: Setup the development environment\n\nThe first step is to setup a good and viable development environment. Using Vagrant and Virtualbox, you'll be able to compile and test your OS from all the OSs (Linux, Windows or Mac).\n\n### Install Vagrant\n\n> Vagrant is free and open-source software for creating and configuring virtual development environments. It can be considered a wrapper around VirtualBox.\n\nVagrant will help us create a clean virtual development environment on whatever system you are using.\nThe first step is to download and install Vagrant for your system at http://www.vagrantup.com/.\n\n### Install Virtualbox\n\n> Oracle VM VirtualBox is a virtualization software package for x86 and AMD64/Intel64-based computers.\n\nVagrant needs Virtualbox to work, Download and install for your system at https://www.virtualbox.org/wiki/Downloads.\n\n### Start and test your development environment\n\nOnce Vagrant and Virtualbox are installed, you need to download the ubuntu lucid32 image for Vagrant:\n\n```\nvagrant box add lucid32 http://files.vagrantup.com/lucid32.box\n```\n\nOnce the lucid32 image is ready, we need to define our development environment using a *Vagrantfile*, [create a file named *Vagrantfile*](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/blob/master/src/Vagrantfile). This file defines what prerequisites our environment needs: nasm, make, build-essential, grub and qemu.\n\nStart your box using:\n\n```\nvagrant up\n```\n\nYou can now access your box by using ssh to connect to the virtual box using:\n\n```\nvagrant ssh\n```\n\nThe directory containing the *Vagrantfile* will be mounted by default in the */vagrant* directory of the guest VM (in this case, Ubuntu Lucid32):\n\n```\ncd /vagrant\n```\n\n#### Build and test our operating system\n\nThe file [**Makefile**](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/blob/master/src/Makefile) defines some basics rules for building the kernel, the user libc and some userland programs.\n\nBuild:\n\n```\nmake all\n```\n\nTest our operating system with qemu:\n\n```\nmake run\n```\n\nThe documentation for qemu is available at [QEMU Emulator Documentation](http://wiki.qemu.org/download/qemu-doc.html).\n\nYou can exit the emulator using: Ctrl-a.\n"
  },
  {
    "path": "Chapter-3/README.md",
    "content": "## Chapter 3: First boot with GRUB\n\n#### How the boot works?\n\nWhen an x86-based computer is turned on, it begins a complex path to get to the stage where control is transferred to our kernel's \"main\" routine (`kmain()`). For this course, we are only going to consider the BIOS boot method and not it's successor (UEFI).\n\nThe BIOS boot sequence is: RAM detection -> Hardware detection/Initialization -> Boot sequence.\n\nThe most important step for us is the \"Boot sequence\", where the BIOS is done with its initialization and tries to transfer control to the next stage of the bootloader process.\n\nDuring the \"Boot sequence\", the BIOS will try to determine a \"boot device\" (e.g. floppy disk, hard-disk, CD, USB flash memory device or network). Our Operating System will initially boot from the hard-disk (but it will be possible to boot it from a CD or a USB flash memory device in future). A device is considered bootable if the bootsector contains the valid signature bytes `0x55` and `0xAA` at offsets 511 and 512 respectively (called the magic bytes of the Master Boot Record, also known as the MBR). This signature is represented (in binary) as 0b1010101001010101. The alternating bit pattern was thought to be a protection against certain failures (drive or controller). If this pattern is garbled or 0x00, the device is not considered bootable.\n\nBIOS physically searches for a boot device by loading the first 512 bytes from the bootsector of each device into physical memory, starting at the address `0x7C00` (1 KiB below the 32 KiB mark). When the valid signature bytes are detected, BIOS transfers control to the `0x7C00` memory address (via a jump instruction) in order to execute the bootsector code.\n\nThroughout this process the CPU has been running in 16-bit Real Mode, which is the default state for x86 CPUs in order to maintain backwards compatibility. To execute the 32-bit instructions within our kernel, a bootloader is required to switch the CPU into Protected Mode.\n\n#### What is GRUB?\n\n> GNU GRUB (short for GNU GRand Unified Bootloader) is a boot loader package from the GNU Project. GRUB is the reference implementation of the Free Software Foundation's Multiboot Specification, which provides a user the choice to boot one of multiple operating systems installed on a computer or select a specific kernel configuration available on a particular operating system's partitions.\n\nTo make it simple, GRUB is the first thing booted by the machine (a boot-loader) and will simplify the loading of our kernel stored on the hard-disk.\n\n#### Why are we using GRUB?\n\n* GRUB is very simple to use\n* Make it very simple to load 32bits kernels without needs of 16bits code\n* Multiboot with Linux, Windows and others\n* Make it easy to load external modules in memory\n\n#### How to use GRUB?\n\nGRUB uses the Multiboot specification, the executable binary should be 32bits and must contain a special header (multiboot header) in its 8192 first bytes. Our kernel will be a ELF executable file (\"Executable and Linkable Format\", a common standard file format for executables in most UNIX system).\n\nThe first boot sequence of our kernel is written in Assembly: [start.asm](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/blob/master/src/kernel/arch/x86/start.asm) and we use a linker file to define our executable structure: [linker.ld](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/blob/master/src/kernel/arch/x86/linker.ld).\n\nThis boot process also initializes some of our C++ runtime, it will be described in the next chapter.\n\nMultiboot header structure:\n\n```cpp\nstruct multiboot_info {\n\tu32 flags;\n\tu32 low_mem;\n\tu32 high_mem;\n\tu32 boot_device;\n\tu32 cmdline;\n\tu32 mods_count;\n\tu32 mods_addr;\n\tstruct {\n\t\tu32 num;\n\t\tu32 size;\n\t\tu32 addr;\n\t\tu32 shndx;\n\t} elf_sec;\n\tunsigned long mmap_length;\n\tunsigned long mmap_addr;\n\tunsigned long drives_length;\n\tunsigned long drives_addr;\n\tunsigned long config_table;\n\tunsigned long boot_loader_name;\n\tunsigned long apm_table;\n\tunsigned long vbe_control_info;\n\tunsigned long vbe_mode_info;\n\tunsigned long vbe_mode;\n\tunsigned long vbe_interface_seg;\n\tunsigned long vbe_interface_off;\n\tunsigned long vbe_interface_len;\n};\n```\n\nYou can use the command ```mbchk kernel.elf``` to validate your kernel.elf file against the multiboot standard. You can also use the command ```nm -n kernel.elf``` to validate the offset of the different objects in the ELF binary.\n\n#### Create a disk image for our kernel and grub\n\nThe script [diskimage.sh](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/blob/master/src/sdk/diskimage.sh) will generate a hard disk image that can be used by QEMU.\n\nThe first step is to create a hard-disk image (c.img) using qemu-img:\n\n```\nqemu-img create c.img 2M\n```\n\nWe need now to partition the disk using fdisk:\n\n```bash\nfdisk ./c.img\n\n# Switch to Expert commands\n> x\n\n# Change number of cylinders (1-1048576)\n> c\n> 4\n\n# Change number of heads (1-256, default 16):\n> h\n> 16\n\n# Change number of sectors/track (1-63, default 63)\n> s\n> 63\n\n# Return to main menu\n> r\n\n# Add a new partition\n> n\n\n# Choose primary partition\n> p\n\n# Choose partition number\n> 1\n\n# Choose first sector (1-4, default 1)\n> 1\n\n# Choose last sector, +cylinders or +size{K,M,G} (1-4, default 4)\n> 4\n\n# Toggle bootable flag\n> a\n\n# Choose first partition for bootable flag\n> 1\n\n# Write table to disk and exit\n> w\n```\n\nWe need now to attach the created partition to the loop-device using losetup. This allows a file to be access like a block device. The offset of the partition is passed as an argument and calculated using: **offset= start_sector * bytes_by_sector**.\n\nUsing ```fdisk -l -u c.img```, you get: 63 * 512 = 32256.\n\n```bash\nlosetup -o 32256 /dev/loop1 ./c.img\n```\n\nWe create a EXT2 filesystem on this new device using:\n\n```bash\nmke2fs /dev/loop1\n```\n\nWe copy our files on a mounted disk:\n\n```bash\nmount  /dev/loop1 /mnt/\ncp -R bootdisk/* /mnt/\numount /mnt/\n```\n\nInstall GRUB on the disk:\n\n```bash\ngrub --device-map=/dev/null << EOF\ndevice (hd0) ./c.img\ngeometry (hd0) 4 16 63\nroot (hd0,0)\nsetup (hd0)\nquit\nEOF\n```\n\nAnd finally we detach the loop device:\n\n```bash\nlosetup -d /dev/loop1\n```\n\n#### See Also\n\n* [GNU GRUB on Wikipedia](http://en.wikipedia.org/wiki/GNU_GRUB)\n* [Multiboot specification](https://www.gnu.org/software/grub/manual/multiboot/multiboot.html)\n"
  },
  {
    "path": "Chapter-4/README.md",
    "content": "## Chapter 4: Backbone of the OS and C++ runtime\n\n#### C++ kernel run-time\n\nA kernel can be written in C++ just as it can be in C, with the exception of a few pitfalls that come with using C++ (runtime support, constructors, etc). \n\nThe compiler will assume that all the necessary C++ runtime support is available by default, but as we are not linking libsupc++ into your C++ kernel, we need to add some basic functions that can be found in the [cxx.cc](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/blob/master/src/kernel/runtime/cxx.cc) file.\n\n**Caution:** The operators `new` and `delete` cannot be used before virtual memory and pagination have been initialized.\n\n#### Basic C/C++ functions\n\nThe kernel code can't use functions from the standard libraries so we need to add some basic functions for managing memory and strings:\n\n```cpp\nvoid \titoa(char *buf, unsigned long int n, int base);\n\nvoid *\tmemset(char *dst,char src, int n);\nvoid *\tmemcpy(char *dst, char *src, int n);\n\nint \tstrlen(char *s);\nint \tstrcmp(const char *dst, char *src);\nint \tstrcpy(char *dst,const char *src);\nvoid \tstrcat(void *dest,const void *src);\nchar *\tstrncpy(char *destString, const char *sourceString,int maxLength);\nint \tstrncmp( const char* s1, const char* s2, int c );\n```\n\nThese functions are defined in [string.cc](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/blob/master/src/kernel/runtime/string.cc), [memory.cc](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/blob/master/src/kernel/runtime/memory.cc), [itoa.cc](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/blob/master/src/kernel/runtime/itoa.cc)\n\n#### C types\n\nIn the next step, we're going to define different types we're going to use in our code. Most of our variable types are going to be unsigned. This means that all the bits are used to store the integer. Signed variables use their first bit to indicate their sign. \n\n```cpp\ntypedef unsigned char \tu8;\ntypedef unsigned short \tu16;\ntypedef unsigned int \tu32;\ntypedef unsigned long long \tu64;\n\ntypedef signed char \ts8;\ntypedef signed short \ts16;\ntypedef signed int \t\ts32;\ntypedef signed long long\ts64;\n```\n\n#### Compile our kernel\n\nCompiling a kernel is not the same thing as compiling a linux executable, we can't use a standard library and should have no dependencies to the system.\n\nOur [Makefile](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/blob/master/src/kernel/Makefile) will define the process to compile and link our kernel.\n\nFor x86 architecture, the followings arguments will be used for gcc/g++/ld:\n\n```\n# Linker\nLD=ld\nLDFLAG= -melf_i386 -static  -L ./  -T ./arch/$(ARCH)/linker.ld\n\n# C++ compiler\nSC=g++\nFLAG= $(INCDIR) -g -O2 -w -trigraphs -fno-builtin  -fno-exceptions -fno-stack-protector -O0 -m32  -fno-rtti -nostdlib -nodefaultlibs \n\n# Assembly compiler\nASM=nasm\nASMFLAG=-f elf -o\n```\n"
  },
  {
    "path": "Chapter-5/README.md",
    "content": "## Chapter 5: Base classes for managing x86 architecture\n\nNow that we know how to compile our C++ kernel and boot the binary using GRUB, we can start to do some cool things in C/C++.\n\n#### Printing to the screen console\n\nWe are going to use VGA default mode (03h) to display some text to the user. The screen can be directly accessed using the video memory at 0xB8000. The screen resolution is 80x25 and each character on the screen is defined by 2 bytes: one for the character code, and one for the style flag. This means that the total size of the video memory is 4000B (80B*25B*2B).\n\nIn the IO class ([io.cc](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/blob/master/src/kernel/arch/x86/io.cc)),:\n* **x,y**: define the cursor position on the screen\n* **real_screen**: define the  video memory pointer\n* **putc(char c)**: print a unique character on the screen and manage cursor position\n* **printf(char* s, ...)**: print a string\n\nWe add a method **putc** to the [IO Class](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/blob/master/src/kernel/arch/x86/io.cc) to put a character on the screen and update the (x,y) position.\n\n```cpp\n/* put a byte on screen */\nvoid Io::putc(char c){\n\tkattr = 0x07;\n\tunsigned char *video;\n\tvideo = (unsigned char *) (real_screen+ 2 * x + 160 * y);\n\t// newline\n\tif (c == '\\n') {\n\t\tx = 0;\n\t\ty++;\n\t// back space\n\t} else if (c == '\\b') {\n\t\tif (x) {\n\t\t\t*(video + 1) = 0x0;\n\t\t\tx--;\n\t\t}\n\t// horizontal tab\n\t} else if (c == '\\t') {\n\t\tx = x + 8 - (x % 8);\n\t// carriage return\n\t} else if (c == '\\r') {\n\t\tx = 0;\n\t} else {\n\t\t*video = c;\n\t\t*(video + 1) = kattr;\n\n\t\tx++;\n\t\tif (x > 79) {\n\t\t\tx = 0;\n\t\t\ty++;\n\t\t}\n\t}\n\tif (y > 24)\n\t\tscrollup(y - 24);\n}\n```\n\nWe also add a useful and very known method: [printf](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/blob/master/src/kernel/arch/x86/io.cc#L155)\n\n```cpp\n/* put a string in screen */\nvoid Io::print(const char *s, ...){\n\tva_list ap;\n\n\tchar buf[16];\n\tint i, j, size, buflen, neg;\n\n\tunsigned char c;\n\tint ival;\n\tunsigned int uival;\n\n\tva_start(ap, s);\n\n\twhile ((c = *s++)) {\n\t\tsize = 0;\n\t\tneg = 0;\n\n\t\tif (c == 0)\n\t\t\tbreak;\n\t\telse if (c == '%') {\n\t\t\tc = *s++;\n\t\t\tif (c >= '0' && c <= '9') {\n\t\t\t\tsize = c - '0';\n\t\t\t\tc = *s++;\n\t\t\t}\n\n\t\t\tif (c == 'd') {\n\t\t\t\tival = va_arg(ap, int);\n\t\t\t\tif (ival < 0) {\n\t\t\t\t\tuival = 0 - ival;\n\t\t\t\t\tneg++;\n\t\t\t\t} else\n\t\t\t\t\tuival = ival;\n\t\t\t\titoa(buf, uival, 10);\n\n\t\t\t\tbuflen = strlen(buf);\n\t\t\t\tif (buflen < size)\n\t\t\t\t\tfor (i = size, j = buflen; i >= 0;\n\t\t\t\t\t     i--, j--)\n\t\t\t\t\t\tbuf[i] =\n\t\t\t\t\t\t    (j >=\n\t\t\t\t\t\t     0) ? buf[j] : '0';\n\n\t\t\t\tif (neg)\n\t\t\t\t\tprint(\"-%s\", buf);\n\t\t\t\telse\n\t\t\t\t\tprint(buf);\n\t\t\t}\n\t\t\t else if (c == 'u') {\n\t\t\t\tuival = va_arg(ap, int);\n\t\t\t\titoa(buf, uival, 10);\n\n\t\t\t\tbuflen = strlen(buf);\n\t\t\t\tif (buflen < size)\n\t\t\t\t\tfor (i = size, j = buflen; i >= 0;\n\t\t\t\t\t     i--, j--)\n\t\t\t\t\t\tbuf[i] =\n\t\t\t\t\t\t    (j >=\n\t\t\t\t\t\t     0) ? buf[j] : '0';\n\n\t\t\t\tprint(buf);\n\t\t\t} else if (c == 'x' || c == 'X') {\n\t\t\t\tuival = va_arg(ap, int);\n\t\t\t\titoa(buf, uival, 16);\n\n\t\t\t\tbuflen = strlen(buf);\n\t\t\t\tif (buflen < size)\n\t\t\t\t\tfor (i = size, j = buflen; i >= 0;\n\t\t\t\t\t     i--, j--)\n\t\t\t\t\t\tbuf[i] =\n\t\t\t\t\t\t    (j >=\n\t\t\t\t\t\t     0) ? buf[j] : '0';\n\n\t\t\t\tprint(\"0x%s\", buf);\n\t\t\t} else if (c == 'p') {\n\t\t\t\tuival = va_arg(ap, int);\n\t\t\t\titoa(buf, uival, 16);\n\t\t\t\tsize = 8;\n\n\t\t\t\tbuflen = strlen(buf);\n\t\t\t\tif (buflen < size)\n\t\t\t\t\tfor (i = size, j = buflen; i >= 0;\n\t\t\t\t\t     i--, j--)\n\t\t\t\t\t\tbuf[i] =\n\t\t\t\t\t\t    (j >=\n\t\t\t\t\t\t     0) ? buf[j] : '0';\n\n\t\t\t\tprint(\"0x%s\", buf);\n\t\t\t} else if (c == 's') {\n\t\t\t\tprint((char *) va_arg(ap, int));\n\t\t\t}\n\t\t} else\n\t\t\tputc(c);\n\t}\n\n\treturn;\n}\n```\n\n#### Assembly interface\n\nA large number of instructions are available in Assembly but there is not equivalent in C (like cli, sti, in and out), so we need an interface to these instructions.\n\nIn C, we can include Assembly using the directive \"asm()\", gcc use gas to compile the assembly.\n\n**Caution:** gas uses the AT&T syntax.\n\n```cpp\n/* output byte */\nvoid Io::outb(u32 ad, u8 v){\n\tasmv(\"outb %%al, %%dx\" :: \"d\" (ad), \"a\" (v));;\n}\n/* output word */\nvoid Io::outw(u32 ad, u16 v){\n\tasmv(\"outw %%ax, %%dx\" :: \"d\" (ad), \"a\" (v));\n}\n/* output word */\nvoid Io::outl(u32 ad, u32 v){\n\tasmv(\"outl %%eax, %%dx\" : : \"d\" (ad), \"a\" (v));\n}\n/* input byte */\nu8 Io::inb(u32 ad){\n\tu8 _v;       \\\n\tasmv(\"inb %%dx, %%al\" : \"=a\" (_v) : \"d\" (ad)); \\\n\treturn _v;\n}\n/* input word */\nu16\tIo::inw(u32 ad){\n\tu16 _v;\t\t\t\\\n\tasmv(\"inw %%dx, %%ax\" : \"=a\" (_v) : \"d\" (ad));\t\\\n\treturn _v;\n}\n/* input word */\nu32\tIo::inl(u32 ad){\n\tu32 _v;\t\t\t\\\n\tasmv(\"inl %%dx, %%eax\" : \"=a\" (_v) : \"d\" (ad));\t\\\n\treturn _v;\n}\n```\n"
  },
  {
    "path": "Chapter-6/README.md",
    "content": "## Chapter 6: GDT\n\nThanks to GRUB, your kernel is no longer in real-mode, but already in [protected mode](http://en.wikipedia.org/wiki/Protected_mode), this mode allows us to use all the possibilities of the microprocessor such as virtual memory management, paging and safe multi-tasking.\n\n#### What is the GDT?\n\nThe [GDT](http://en.wikipedia.org/wiki/Global_Descriptor_Table) (\"Global Descriptor Table\") is a data structure used to define the different memory areas: the base address, the size and access privileges like execute and write. These memory areas are called \"segments\".\n\nWe are going to use the GDT to define different memory segments:\n\n* *\"code\"*: kernel code, used to stored the executable binary code\n* *\"data\"*: kernel data\n* *\"stack\"*: kernel stack, used to stored the call stack during kernel execution\n* *\"ucode\"*: user code, used to stored the executable binary code for user program\n* *\"udata\"*: user program data\n* *\"ustack\"*: user stack, used to stored the call stack during execution in userland\n\n#### How to load our GDT?\n\nGRUB initializes a GDT but this GDT is does not correspond to our kernel.\nThe GDT is loaded using the LGDT assembly instruction. It expects the location of a GDT description structure:\n\n![GDTR](./gdtr.png)\n\nAnd the C structure:\n\n```cpp\nstruct gdtr {\n\tu16 limite;\n\tu32 base;\n} __attribute__ ((packed));\n```\n\n**Caution:** the directive ```__attribute__ ((packed))``` signal to gcc that the structure should use as little memory as possible. Without this directive, gcc include some bytes to optimize the memory alignment and the access during execution.\n\nNow we need to define our GDT table and then load it using LGDT. The GDT table can be stored wherever we want in memory, its address should just be signaled to the process using the GDTR registry.\n\nThe GDT table is composed of segments with the following structure:\n\n![GDTR](./gdtentry.png)\n\nAnd the C structure:\n\n```cpp\nstruct gdtdesc {\n\tu16 lim0_15;\n\tu16 base0_15;\n\tu8 base16_23;\n\tu8 acces;\n\tu8 lim16_19:4;\n\tu8 other:4;\n\tu8 base24_31;\n} __attribute__ ((packed));\n```\n\n#### How to define our GDT table?\n\nWe need now to define our GDT in memory and finally load it using the GDTR registry.\n\nWe are going to store our GDT at the address:\n\n```cpp\n#define GDTBASE\t0x00000800\n```\n\nThe function **init_gdt_desc** in [x86.cc](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/blob/master/src/kernel/arch/x86/x86.cc) initialize a gdt segment descriptor.\n\n```cpp\nvoid init_gdt_desc(u32 base, u32 limite, u8 acces, u8 other, struct gdtdesc *desc)\n{\n\tdesc->lim0_15 = (limite & 0xffff);\n\tdesc->base0_15 = (base & 0xffff);\n\tdesc->base16_23 = (base & 0xff0000) >> 16;\n\tdesc->acces = acces;\n\tdesc->lim16_19 = (limite & 0xf0000) >> 16;\n\tdesc->other = (other & 0xf);\n\tdesc->base24_31 = (base & 0xff000000) >> 24;\n\treturn;\n}\n```\n\nAnd the function **init_gdt** initialize the GDT, some parts of the below function will be explained later and are used for multitasking.\n\n```cpp\nvoid init_gdt(void)\n{\n\tdefault_tss.debug_flag = 0x00;\n\tdefault_tss.io_map = 0x00;\n\tdefault_tss.esp0 = 0x1FFF0;\n\tdefault_tss.ss0 = 0x18;\n\n\t/* initialize gdt segments */\n\tinit_gdt_desc(0x0, 0x0, 0x0, 0x0, &kgdt[0]);\n\tinit_gdt_desc(0x0, 0xFFFFF, 0x9B, 0x0D, &kgdt[1]);\t/* code */\n\tinit_gdt_desc(0x0, 0xFFFFF, 0x93, 0x0D, &kgdt[2]);\t/* data */\n\tinit_gdt_desc(0x0, 0x0, 0x97, 0x0D, &kgdt[3]);\t\t/* stack */\n\n\tinit_gdt_desc(0x0, 0xFFFFF, 0xFF, 0x0D, &kgdt[4]);\t/* ucode */\n\tinit_gdt_desc(0x0, 0xFFFFF, 0xF3, 0x0D, &kgdt[5]);\t/* udata */\n\tinit_gdt_desc(0x0, 0x0, 0xF7, 0x0D, &kgdt[6]);\t\t/* ustack */\n\n\tinit_gdt_desc((u32) & default_tss, 0x67, 0xE9, 0x00, &kgdt[7]);\t/* descripteur de tss */\n\n\t/* initialize the gdtr structure */\n\tkgdtr.limite = GDTSIZE * 8;\n\tkgdtr.base = GDTBASE;\n\n\t/* copy the gdtr to its memory area */\n\tmemcpy((char *) kgdtr.base, (char *) kgdt, kgdtr.limite);\n\n\t/* load the gdtr registry */\n\tasm(\"lgdtl (kgdtr)\");\n\n\t/* initiliaz the segments */\n\tasm(\"   movw $0x10, %ax\t\\n \\\n            movw %ax, %ds\t\\n \\\n            movw %ax, %es\t\\n \\\n            movw %ax, %fs\t\\n \\\n            movw %ax, %gs\t\\n \\\n            ljmp $0x08, $next\t\\n \\\n            next:\t\t\\n\");\n}\n```\n"
  },
  {
    "path": "Chapter-7/README.md",
    "content": "## Chapter 7: IDT and interrupts\n\nAn interrupt is a signal to the processor emitted by hardware or software indicating an event that needs immediate attention.\n\nThere are 3 types of interrupts:\n\n- **Hardware interrupts:** are sent to the processor from an external device (keyboard, mouse, hard disk, ...). Hardware interrupts were introduced as a way to reduce wasting the processor's valuable time in polling loops, waiting for external events.\n- **Software interrupts:** are initiated voluntarily by the software. It's used to manage system calls.\n- **Exceptions:**  are used for errors or events occurring during program execution that are exceptional enough that they cannot be handled within the program itself (division by zero, page fault, ...)\n\n#### The keyboard example:\n\nWhen the user pressed a key on the keyboard, the keyboard controller will signal an interrupt to the Interrupt Controller. If the interrupt is not masked, the controller will signal the interrupt to the processor, the processor will execute a routine to manage the interrupt (key pressed or key released), this routine could, for example, get the pressed key from the keyboard controller and print the key to the screen. Once the character processing routine is completed, the interrupted job can be resumed.\n\n#### What is the PIC?\n\nThe [PIC](http://en.wikipedia.org/wiki/Programmable_Interrupt_Controller) (Programmable interrupt controller)is a device that is used to combine several sources of interrupt onto one or more CPU lines, while allowing priority levels to be assigned to its interrupt outputs. When the device has multiple interrupt outputs to assert, it asserts them in the order of their relative priority.\n\nThe best known PIC is the 8259A, each 8259A can handle 8 devices but most computers have two controllers: one master and one slave, this allows the computer to manage interrupts from 14 devices.\n\nIn this chapter, we will need to program this controller to initialize and mask interrupts.\n\n#### What is the IDT?\n\n> The Interrupt Descriptor Table (IDT) is a data structure used by the x86 architecture to implement an interrupt vector table. The IDT is used by the processor to determine the correct response to interrupts and exceptions.\n\nOur kernel is going to use the IDT to define the different functions to be executed when an interrupt occurred.\n\nLike the GDT, the IDT is loaded using the LIDTL assembly instruction. It expects the location of a IDT description structure:\n\n```cpp\nstruct idtr {\n\tu16 limite;\n\tu32 base;\n} __attribute__ ((packed));\n```\n\nThe IDT table is composed of IDT segments with the following structure:\n\n```cpp\nstruct idtdesc {\n\tu16 offset0_15;\n\tu16 select;\n\tu16 type;\n\tu16 offset16_31;\n} __attribute__ ((packed));\n```\n\n**Caution:** the directive ```__attribute__ ((packed))``` signal to gcc that the structure should use as little memory as possible. Without this directive, gcc includes some bytes to optimize the memory alignment and the access during execution.\n\nNow we need to define our IDT table and then load it using LIDTL. The IDT table can be stored wherever we want in memory, its address should just be signaled to the process using the IDTR registry.\n\nHere is a table of common interrupts (Maskable hardware interrupt are called IRQ):\n\n\n| IRQ   |         Description        |\n|:-----:| -------------------------- |\n| 0 | Programmable Interrupt Timer Interrupt |\n| 1 | Keyboard Interrupt |\n| 2 | Cascade (used internally by the two PICs. never raised) |\n| 3 | COM2 (if enabled) |\n| 4 | COM1 (if enabled) |\n| 5 | LPT2 (if enabled) |\n| 6 | Floppy Disk |\n| 7 | LPT1 |\n| 8 | CMOS real-time clock (if enabled) |\n| 9 | Free for peripherals / legacy SCSI / NIC |\n| 10 | Free for peripherals / SCSI / NIC |\n| 11 | Free for peripherals / SCSI / NIC |\n| 12 | PS2 Mouse |\n| 13 | FPU / Coprocessor / Inter-processor |\n| 14 | Primary ATA Hard Disk |\n| 15 | Secondary ATA Hard Disk |\n\n#### How to initialize the interrupts?\n\nThis is a simple method to define an IDT segment\n\n```cpp\nvoid init_idt_desc(u16 select, u32 offset, u16 type, struct idtdesc *desc)\n{\n\tdesc->offset0_15 = (offset & 0xffff);\n\tdesc->select = select;\n\tdesc->type = type;\n\tdesc->offset16_31 = (offset & 0xffff0000) >> 16;\n\treturn;\n}\n```\n\nAnd we can now initialize the interupts:\n\n```cpp\n#define IDTBASE\t0x00000000\n#define IDTSIZE 0xFF\nidtr kidtr;\n```\n\n\n```cpp\nvoid init_idt(void)\n{\n\t/* Init irq */\n\tint i;\n\tfor (i = 0; i < IDTSIZE; i++)\n\t\tinit_idt_desc(0x08, (u32)_asm_schedule, INTGATE, &kidt[i]); //\n\n\t/* Vectors  0 -> 31 are for exceptions */\n\tinit_idt_desc(0x08, (u32) _asm_exc_GP, INTGATE, &kidt[13]);\t\t/* #GP */\n\tinit_idt_desc(0x08, (u32) _asm_exc_PF, INTGATE, &kidt[14]);     /* #PF */\n\n\tinit_idt_desc(0x08, (u32) _asm_schedule, INTGATE, &kidt[32]);\n\tinit_idt_desc(0x08, (u32) _asm_int_1, INTGATE, &kidt[33]);\n\n\tinit_idt_desc(0x08, (u32) _asm_syscalls, TRAPGATE, &kidt[48]);\n\tinit_idt_desc(0x08, (u32) _asm_syscalls, TRAPGATE, &kidt[128]); //48\n\n\tkidtr.limite = IDTSIZE * 8;\n\tkidtr.base = IDTBASE;\n\n\n\t/* Copy the IDT to the memory */\n\tmemcpy((char *) kidtr.base, (char *) kidt, kidtr.limite);\n\n\t/* Load the IDTR registry */\n\tasm(\"lidtl (kidtr)\");\n}\n```\n\nAfter intialization of our IDT, we need to activate interrupts by configuring the PIC. The following function will configure the two PICs by writting in their internal registries using the output ports of the processor ```io.outb```. We configure the PICs using the ports:\n\n* Master PIC: 0x20 and 0x21\n* Slave PIC: 0xA0 and 0xA1\n\nFor a PIC, there are 2 types of registries:\n\n* ICW (Initialization Command Word): reinit the controller\n* OCW (Operation Control Word): configure the controller once initialized (used to mask/unmask the interrupts)\n\n```cpp\nvoid init_pic(void)\n{\n\t/* Initialization of ICW1 */\n\tio.outb(0x20, 0x11);\n\tio.outb(0xA0, 0x11);\n\n\t/* Initialization of ICW2 */\n\tio.outb(0x21, 0x20);\t/* start vector = 32 */\n\tio.outb(0xA1, 0x70);\t/* start vector = 96 */\n\n\t/* Initialization of ICW3 */\n\tio.outb(0x21, 0x04);\n\tio.outb(0xA1, 0x02);\n\n\t/* Initialization of ICW4 */\n\tio.outb(0x21, 0x01);\n\tio.outb(0xA1, 0x01);\n\n\t/* mask interrupts */\n\tio.outb(0x21, 0x0);\n\tio.outb(0xA1, 0x0);\n}\n```\n\n#### PIC ICW configurations details\n\nThe registries have to be configured in order.\n\n**ICW1 (port 0x20 / port 0xA0)**\n```\n|0|0|0|1|x|0|x|x|\n         |   | +--- with ICW4 (1) or without (0)\n         |   +----- one controller (1), or cascade (0)\n         +--------- triggering by level (level) (1) or by edge (edge) (0)\n```\n\n**ICW2 (port 0x21 / port 0xA1)**\n```\n|x|x|x|x|x|0|0|0|\n | | | | |\n +----------------- base address for interrupts vectors\n```\n\n**ICW2 (port 0x21 / port 0xA1)**\n\nFor the master:\n```\n|x|x|x|x|x|x|x|x|\n | | | | | | | |\n +------------------ slave controller connected to the port yes (1), or no (0)\n```\n\nFor the slave:\n```\n|0|0|0|0|0|x|x|x|  pour l'esclave\n           | | |\n           +-------- Slave ID which is equal to the master port\n```\n\n**ICW4 (port 0x21 / port 0xA1)**\n\nIt is used to define in which mode the controller should work.\n\n```\n|0|0|0|x|x|x|x|1|\n       | | | +------ mode \"automatic end of interrupt\" AEOI (1)\n       | | +-------- mode buffered slave (0) or master (1)\n       | +---------- mode buffered (1)\n       +------------ mode \"fully nested\" (1)\n```\n\n#### Why do idt segments offset our ASM functions?\n\nYou should have noticed that when I'm initializing our IDT segments, I'm using offsets to segment the code in Assembly. The different functions are defined in [x86int.asm](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/blob/master/src/kernel/arch/x86/x86int.asm) and are of the following scheme:\n\n```asm\n%macro\tSAVE_REGS 0\n\tpushad\n\tpush ds\n\tpush es\n\tpush fs\n\tpush gs\n\tpush ebx\n\tmov bx,0x10\n\tmov ds,bx\n\tpop ebx\n%endmacro\n\n%macro\tRESTORE_REGS 0\n\tpop gs\n\tpop fs\n\tpop es\n\tpop ds\n\tpopad\n%endmacro\n\n%macro\tINTERRUPT 1\nglobal _asm_int_%1\n_asm_int_%1:\n\tSAVE_REGS\n\tpush %1\n\tcall isr_default_int\n\tpop eax\t;;a enlever sinon\n\tmov al,0x20\n\tout 0x20,al\n\tRESTORE_REGS\n\tiret\n%endmacro\n```\n\nThese macros will be used to define the interrupt segment that will prevent corruption of the different registries, it will be very useful for multitasking.\n"
  },
  {
    "path": "Chapter-8/README.md",
    "content": "## Chapter 8: Theory: physical and virtual memory\n\nIn the chapter related to the GDT, we saw that using segmentation a physical memory address is calculated using a segment selector and an offset.\n\nIn this chapter, we are going to implement paging, paging will translate a linear address from segmentation into a physical address.\n\n#### Why do we need paging?\n\nPaging will allow our kernel to:\n\n* use the hard-drive as a memory and not be limited by the machine ram memory limit\n* to have a unique memory space for each process\n* to allow and unallow memory space in a dynamic way\n\nIn a paged system, each process may execute in its own 4gb area of memory, without any chance of effecting any other process's memory, or the kernel's. It simplifies multitasking.\n\n![Processes memories](./processes.png)\n\n#### How does it work?\n\nThe translation of a linear address to a physical address is done in multiple steps:\n\n1. The processor use the registry `CR3` to know the physical address of the pages directory.\n2. The first 10 bits of the linear address represent an offset (between 0 and 1023), pointing to an entry in the pages directory. This entry contains the physical address of a pages table.\n3. the next 10 bits of the linear address represent an offset, pointing to an entry in the pages table. This entry is pointing to a 4ko page.\n4. The last 12 bits of the linear address represent an offset (between 0 and 4095), which indicates the position in the 4ko page.\n\n![Address translation](./paging_memory.png)\n\n#### Format for pages table and directory\n\nThe two types of entries (table and directory) look like the same. Only the field in gray will be used in our OS.\n\n![Page directory entry](./page_directory_entry.png)\n\n![Page table entry](./page_table_entry.png)\n\n* `P`: indicate if the page or table is in physical memory\n* `R/W`: indicate if the page or table is accessible in writting (equals 1)\n* `U/S`: equals 1 to allow access to non-preferred tasks\n* `A`: indicate if the page or table was accessed\n* `D`: (only for pages table) indicate if the page was written\n* `PS` (only for pages directory) indicate the size of pages:\n    * 0 = 4kb\n    * 1 = 4mb\n\n**Note:** Physical addresses in the pages diretcory or pages table are written using 20 bits because these addresses are aligned on 4kb, so the last 12bits should be equal to 0.\n\n* A pages directory or pages table used 1024*4 = 4096 bytes = 4k\n* A pages table can address 1024 * 4k = 4 Mb\n* A pages directory can address 1024 * (1024 * 4k) = 4 Gb\n\n#### How to enable pagination?\n\nTo enable pagination, we just need to set bit 31 of the `CR0`registry to 1:\n\n```asm\nasm(\"  mov %%cr0, %%eax; \\\n       or %1, %%eax;     \\\n       mov %%eax, %%cr0\" \\\n       :: \"i\"(0x80000000));\n```\n\nBut before, we need to initialize our pages directory with at least one pages table.\n\n#### Identity Mapping\n\nWith the identity mapping model, the page will apply only to the kernel as the first 4 MB of virtual memory coincide with the first 4 MB of physical memory:\n\n![Identity Mapping](identitymapping.png)\n\nThis model is simple: the first virtual memory page coincide to the first page in physical memory, the second page coincide to the second page on physical memory and so on ...\n\n\n\n\n\n\n"
  },
  {
    "path": "LICENSE",
    "content": "Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"{}\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright 2014 Samy Pessé\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "README.md",
    "content": "How to Make a Computer Operating System\n=======================================\n\nOnline book about how to write a computer operating system in C/C++ from scratch.\n\n**Caution**: This repository is a remake of my old course. It was written several years ago [as one of my first projects when I was in High School](https://github.com/SamyPesse/devos), I'm still refactoring some parts. The original course was in French and I'm not an English native. I'm going to continue and improve this course in my free-time.\n\n**Book**: An online version is available at [http://samypesse.gitbooks.io/how-to-create-an-operating-system/](http://samypesse.gitbooks.io/how-to-create-an-operating-system/) (PDF, Mobi and ePub). It was generated using [GitBook](https://www.gitbook.com/).\n\n**Source Code**: All the system source code will be stored in the [src](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/tree/master/src) directory. Each step will contain links to the different related files.\n\n**Contributions**: This course is open to contributions, feel free to signal errors with issues or directly correct the errors with pull-requests.\n\n**Questions**: Feel free to ask any questions by adding issues or commenting sections.\n\nYou can follow me on Twitter [@SamyPesse](https://twitter.com/SamyPesse) or [GitHub](https://github.com/SamyPesse).\n\n### What kind of OS are we building?\n\nThe goal is to build a very simple UNIX-based operating system in C++, not just a \"proof-of-concept\". The OS should be able to boot, start a userland shell, and be extensible.\n\n![Screen](./preview.png)\n"
  },
  {
    "path": "SUMMARY.md",
    "content": "# Summary\n\n* [Introduction](README.md)\n* [Introduction about the x86 architecture and about our OS](Chapter-1/README.md)\n* [Setup the development environment](Chapter-2/README.md)\n* [First boot with GRUB](Chapter-3/README.md)\n* [Backbone of the OS and C++ runtime](Chapter-4/README.md)\n* [Base classes for managing x86 architecture](Chapter-5/README.md)\n* [GDT](Chapter-6/README.md)\n* [IDT and interrupts](Chapter-7/README.md)\n* [Theory: physical and virtual memory](Chapter-8/README.md)\n* [Memory management: physical and virtual](chapter9/README.md)\n* Process management and multitasking\n* External program execution: ELF files\n* Userland and syscalls\n* Modular drivers\n* Some basics modules: console, keyboard\n* IDE Hard disks\n* DOS Partitions\n* EXT2 read-only filesystems\n* Standard C library (libC)\n* UNIX basic tools: sh, cat\n* Lua interpreter\n\n"
  },
  {
    "path": "chapter9/README.md",
    "content": "# Memory management: physical and virtual\n\nThe kernel knows the size of the physical memory available thanks to [GRUB](../Chapter-3/README.md).\n\nIn our implementation, the first 8 megabytes of physical memory will be reserved for use by the kernel and will contain:\n\n- The kernel\n- GDT, IDT et TSS\n- Kernel Stack\n- Some space reserved to hardware (video memory, ...)\n- Page directory and pages table for the kernel\n\nThe rest of the physical memory is freely available to the kernel and applications.\n\n![Physical Memory](physicalmemory.png)\n\n\n### Virtual Memory Mapping\n\nThe address space between the beginning of memory and `0x40000000` address is the kernel space, while the space between the address `0x40000000` and the end of the memory corresponds to user space:\n\n![Virtual Memory](virtualmemory.png)\n\nThe kernel space in virtual memory, which is using 1Gb of virtual memory, is common to all tasks (kernel and user).\n\nThis is implemented by pointing the first 256 entries of the task page directory to the kernel page directory (In [vmm.cc](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/blob/master/src/kernel/arch/x86/vmm.cc#L204)):\n\n```cpp\n/* \n * Kernel Space. v_addr < USER_OFFSET are addressed by the kernel pages table\n */\nfor (i=0; i<256; i++) \n    pdir[i] = pd0[i];\n```"
  },
  {
    "path": "src/Makefile",
    "content": "SDKDIR=./sdk\n\nhelp:\n\t@echo \"Makefile for Building Dev Operating System.\"\n\t@echo \"Usage: make [ all | clean | help | build | run] \" \n\t@echo \"\"\n\t@echo\n\nall: \n\t@echo \"Building Kernel\"\n\tmake -C ./kernel\n\t@echo \"Building SDK\"\n\tmake -C ./sdk\n\t@echo \"Building Userland\"\n\tmake -C ./userland\n\t\n\nbuild:\n\tzip -r devos-$(VERSION).zip ./\n\n\nrun:\n\t@echo \"Running Dev Operating System.\"\n\tcd ./sdk && sudo bash ./diskimage.sh\n\tcd ./sdk && ./qemu.sh\n\nclean:\n\tmake -C ./kernel clean\n\tmake -C ./userland clean\n"
  },
  {
    "path": "src/Vagrantfile",
    "content": "# -*- mode: ruby -*-\n# vi: set ft=ruby :\n\n# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!\nVAGRANTFILE_API_VERSION = \"2\"\n\nVagrant.configure(VAGRANTFILE_API_VERSION) do |config|\n  # All Vagrant configuration is done here. The most common configuration\n  # options are documented and commented below. For a complete reference,\n  # please see the online documentation at vagrantup.com.\n\n  # Every Vagrant virtual environment requires a box to build off of.\n  config.vm.box = \"lucid32\"\n\n  # The url from where the 'config.vm.box' box will be fetched if it\n  # doesn't already exist on the user's system.\n  config.vm.box_url = \"http://files.vagrantup.com/lucid32.box\"\n\n  # Create a forwarded port mapping which allows access to a specific port\n  # within the machine from a port on the host machine. In the example below,\n  # accessing \"localhost:8080\" will access port 80 on the guest machine.\n  # config.vm.network :forwarded_port, guest: 80, host: 8080\n\n  # Create a private network, which allows host-only access to the machine\n  # using a specific IP.\n  # config.vm.network :private_network, ip: \"192.168.33.10\"\n\n  # Create a public network, which generally matched to bridged network.\n  # Bridged networks make the machine appear as another physical device on\n  # your network.\n  # config.vm.network :public_network\n\n  # If true, then any SSH connections made will enable agent forwarding.\n  # Default value: false\n  # config.ssh.forward_agent = true\n\n  # Share an additional folder to the guest VM. The first argument is\n  # the path on the host to the actual folder. The second argument is\n  # the path on the guest to mount the folder. And the optional third\n  # argument is a set of non-required options.\n  # config.vm.synced_folder \"../data\", \"/vagrant_data\"\n\n  # Provider-specific configuration so you can fine-tune various\n  # backing providers for Vagrant. These expose provider-specific options.\n  # Example for VirtualBox:\n  #\n  # config.vm.provider :virtualbox do |vb|\n  #   # Don't boot with headless mode\n  #   vb.gui = true\n  #\n  #   # Use VBoxManage to customize the VM. For example to change memory:\n  #   vb.customize [\"modifyvm\", :id, \"--memory\", \"1024\"]\n  # end\n  #\n  # View the documentation for the provider you're using for more\n  # information on available options.\n\n  # Enable provisioning with Puppet stand alone.  Puppet manifests\n  # are contained in a directory path relative to this Vagrantfile.\n  # You will need to create the manifests directory and a manifest in\n  # the file base.pp in the manifests_path directory.\n  #\n  # An example Puppet manifest to provision the message of the day:\n  #\n  # # group { \"puppet\":\n  # #   ensure => \"present\",\n  # # }\n  # #\n  # # File { owner => 0, group => 0, mode => 0644 }\n  # #\n  # # file { '/etc/motd':\n  # #   content => \"Welcome to your Vagrant-built virtual machine!\n  # #               Managed by Puppet.\\n\"\n  # # }\n  #\n  # config.vm.provision :puppet do |puppet|\n  #   puppet.manifests_path = \"manifests\"\n  #   puppet.manifest_file  = \"init.pp\"\n  # end\n\n  # Enable provisioning with chef solo, specifying a cookbooks path, roles\n  # path, and data_bags path (all relative to this Vagrantfile), and adding\n  # some recipes and/or roles.\n  #\n  # config.vm.provision :chef_solo do |chef|\n  #   chef.cookbooks_path = \"../my-recipes/cookbooks\"\n  #   chef.roles_path = \"../my-recipes/roles\"\n  #   chef.data_bags_path = \"../my-recipes/data_bags\"\n  #   chef.add_recipe \"mysql\"\n  #   chef.add_role \"web\"\n  #\n  #   # You may also specify custom JSON attributes:\n  #   chef.json = { :mysql_password => \"foo\" }\n  # end\n\n  $script = %Q{\n    sudo apt-get update\n    sudo apt-get install nasm make build-essential grub qemu zip -y\n  }\n\n  \n  config.vm.provision :shell, :inline => $script\n  \n\n  # Enable provisioning with chef server, specifying the chef server URL,\n  # and the path to the validation key (relative to this Vagrantfile).\n  #\n  # The Opscode Platform uses HTTPS. Substitute your organization for\n  # ORGNAME in the URL and validation key.\n  #\n  # If you have your own Chef Server, use the appropriate URL, which may be\n  # HTTP instead of HTTPS depending on your configuration. Also change the\n  # validation key to validation.pem.\n  #\n  # config.vm.provision :chef_client do |chef|\n  #   chef.chef_server_url = \"https://api.opscode.com/organizations/ORGNAME\"\n  #   chef.validation_key_path = \"ORGNAME-validator.pem\"\n  # end\n  #\n  # If you're using the Opscode platform, your validator client is\n  # ORGNAME-validator, replacing ORGNAME with your organization name.\n  #\n  # If you have your own Chef Server, the default validation client name is\n  # chef-validator, unless you changed the configuration.\n  #\n  #   chef.validation_client_name = \"ORGNAME-validator\"\nend\n"
  },
  {
    "path": "src/kernel/Makefile",
    "content": "ARCH=x86\nKERNEL=kernel.elf\nSDKDIR=../sdk\nINCDIR= -I ./ -I ./modules -I ./core -I ./arch/$(ARCH)\n\n\ninclude ./arch/$(ARCH)/config.make\n\ninclude ./runtime/Makefile\ninclude ./core/Makefile\ninclude ./modules/Makefile\ninclude ./arch/$(ARCH)/Makefile\n\nFLAG :=$(FLAG) -D__$(ARCH)__\nPLATFORMS= `find ./arch/ -type d | sed \"s/.*\\///\" | sort`\n\n\nall: $(KERNEL)\n\n$(KERNEL): $(OBJS)\n\t$(LD) $(LDFLAG) -o $@ $^ \n\tcp $(KERNEL) $(SDKDIR)/bootdisk/\n\t\nhelp:\n\t@echo \"Makefile for Kernel.\"\n\t@echo \"Please see COPYING for licensing information.\"\n\t@echo \"Output should be: \"$(KERNEL)\n\t@echo \"Usage: make [ all | clean] \" \n\t@echo \"Currently supported platforms:\"\n\t@echo $(PLATFORMS)\n\t@echo\n\ntosdk:\n\tcp $(KERNEL) $(SDKDIR)/disk/\n\ninstall:\n\tsudo cp $(KERNEL) /boot/\n\t\ndebug:\n\t$(NM) -n $(KERNEL)\n\n\t\nhinfo:\n\t$(OBJDUMP) -f $(KERNEL)\n\t\ndasm:\n\t$(OBJDUMP) -d $(KERNEL) > dasm.txt\n\t\n\t\t\t\t\nrun:\n\tcd $(SDKDIR) &&\tsh ./diskimage.sh\n\tcd $(SDKDIR) &&\tsh ./qemu.sh\n\t\ngeniso:\n\tcd $(SDKDIR) &&\tsh ./cdrom.sh\n\n%.o: %.cc\n\t$(SC) $(FLAG) -c $< -o  $@\n\t\n%.o: %.S\n\t$(SC) $(FLAG) -c $< -o  $@\n\t\n%.o: %.asm\n\t$(ASM) $(ASMFLAG)  -c $< -o  $@\n\n\nclean:\n\trm -f $(OBJS)  $(KERNEL) dasm.txt\n\t\n\t\n\n"
  },
  {
    "path": "src/kernel/arch/x86/Makefile",
    "content": "OBJS:= arch/$(ARCH)/start.o  $(OBJS) arch/$(ARCH)/alloc.o arch/$(ARCH)/architecture.o \\\n\tarch/$(ARCH)/io.o arch/$(ARCH)/vmm.o arch/$(ARCH)/x86.o arch/$(ARCH)/switch.o arch/$(ARCH)/x86int.o\n"
  },
  {
    "path": "src/kernel/arch/x86/alloc.cc",
    "content": "#include <os.h>\n\nextern \"C\" {\n\t\t\n\t/* change memory segment size */\n\tvoid *ksbrk(int n)\n\t{\n\t\tstruct kmalloc_header *chunk;\n\t\tchar *p_addr;\n\t\tint i;\n\n\t\tif ((kern_heap + (n * PAGESIZE)) > (char *) KERN_HEAP_LIM) {\n\t\t\tio.print\n\t\t\t    (\"PANIC: ksbrk(): no virtual memory left for kernel heap !\\n\");\n\t\t\treturn (char *) -1;\n\t\t}\n\n\t\tchunk = (struct kmalloc_header *) kern_heap;\n\n\t\t/* Allocation d'une page libre */\n\t\tfor (i = 0; i < n; i++) {\n\t\t\tp_addr = get_page_frame();\n\t\t\tif ((int)(p_addr) < 0) {\n\t\t\t\tio.print\n\t\t\t\t    (\"PANIC: ksbrk(): no free page frame available !\\n\");\n\t\t\t\treturn (char *) -1;\n\t\t\t}\n\n\t\t\t/* Ajout dans le repertoire de pages */\n\t\t\tpd0_add_page(kern_heap, p_addr, 0);\n\n\t\t\tkern_heap += PAGESIZE;\n\t\t}\n\n\t\t/* Marquage pour kmalloc */\n\t\tchunk->size = PAGESIZE * n;\n\t\tchunk->used = 0;\n\n\t\treturn chunk;\n\t}\n\n\t/* allocate memory block */\n\tvoid *kmalloc(unsigned long size)\n\t{\n\t\tif (size==0)\n\t\t\treturn 0;\n\t\t\t\n\t\tunsigned long realsize;\t/* taille totale de l'enregistrement */\n\t\tstruct kmalloc_header *chunk, *other;\n\n\t\tif ((realsize =\n\t\t     sizeof(struct kmalloc_header) + size) < KMALLOC_MINSIZE)\n\t\t\trealsize = KMALLOC_MINSIZE;\n\n\t\t/* \n\t\t * On recherche un bloc libre de 'size' octets en parcourant le HEAP\n\t\t * kernel a partir du debut\n\t\t */\n\t\tchunk = (struct kmalloc_header *) KERN_HEAP;\n\t\twhile (chunk->used || chunk->size < realsize) {\n\t\t\tif (chunk->size == 0) {\n\t\t\t\tio.print\n\t\t\t\t    (\"\\nPANIC: kmalloc(): corrupted chunk on %x with null size (heap %x) !\\nSystem halted\\n\",\n\t\t\t\t     chunk, kern_heap);\n\t\t\t\t\t //error\n\t\t\t\t\t asm(\"hlt\");\n\t\t\t\t\t return 0;\n\t\t\t}\n\n\t\t\tchunk =\n\t\t\t    (struct kmalloc_header *) ((char *) chunk +\n\t\t\t\t\t\t       chunk->size);\n\n\t\t\tif (chunk == (struct kmalloc_header *) kern_heap) {\n\t\t\t\tif ((int)(ksbrk((realsize / PAGESIZE) + 1)) < 0) {\n\t\t\t\t\tio.print\n\t\t\t\t\t    (\"\\nPANIC: kmalloc(): no memory left for kernel !\\nSystem halted\\n\");\n\t\t\t\t\t asm(\"hlt\");\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\t\t\t} else if (chunk > (struct kmalloc_header *) kern_heap) {\n\t\t\t\tio.print\n\t\t\t\t    (\"\\nPANIC: kmalloc(): chunk on %x while heap limit is on %x !\\nSystem halted\\n\",\n\t\t\t\t     chunk, kern_heap);\n\t\t\t\t asm(\"hlt\");\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\n\t\t/* \n\t\t * Found free block with size >= 'size'\n\t\t * We limit size block\n\t\t */\n\t\tif (chunk->size - realsize < KMALLOC_MINSIZE)\n\t\t\tchunk->used = 1;\n\t\telse {\n\t\t\tother =\n\t\t\t    (struct kmalloc_header *) ((char *) chunk + realsize);\n\t\t\tother->size = chunk->size - realsize;\n\t\t\tother->used = 0;\n\n\t\t\tchunk->size = realsize;\n\t\t\tchunk->used = 1;\n\t\t}\n\n\t\tkmalloc_used += realsize;\n\n\t\t/* Return a pointer to the memory area */\n\t\treturn (char *) chunk + sizeof(struct kmalloc_header);\n\t}\n\n\t/* free memory block */\n\tvoid kfree(void *v_addr)\n\t{\n\t\tif (v_addr==(void*)0)\n\t\t\treturn;\n\t\t\t\n\t\tstruct kmalloc_header *chunk, *other;\n\n\t\t/* On libere le bloc alloue */\n\t\tchunk =\n\t\t    (struct kmalloc_header *) ((u32)v_addr -\n\t\t\t\t\t       sizeof(struct kmalloc_header));\n\t\tchunk->used = 0;\n\n\t\tkmalloc_used -= chunk->size;\n\n\t\t/* \n\t\t * Merge free block with next free block\n\t\t */\n\t\twhile ((other =\n\t\t\t(struct kmalloc_header *) ((char *) chunk + chunk->size))\n\t\t       && other < (struct kmalloc_header *) kern_heap\n\t\t       && other->used == 0)\n\t\t\tchunk->size += other->size;\n\t}\n}\n"
  },
  {
    "path": "src/kernel/arch/x86/architecture.cc",
    "content": "#include <os.h>\n#include <x86.h>\n\n/* Stack pointer */\nextern u32 *\t\tstack_ptr;\n\n/* Current cpu name */\nstatic char cpu_name[512] = \"x86-noname\";\n\n\n/* Detect the type of processor */\nchar* Architecture::detect(){\n\tcpu_vendor_name(cpu_name);\n\treturn cpu_name;\n}\n\n/* Start and initialize the architecture */\nvoid Architecture::init(){\n\t io.print(\"Architecture x86, cpu=%s \\n\", detect());\n\t\n\t io.print(\"Loading GDT \\n\");\n\t\t init_gdt();\n\t\t asm(\"\tmovw $0x18, %%ax \\n \\\n\t\t\tmovw %%ax, %%ss \\n \\\n\t\t\tmovl %0, %%esp\"::\"i\" (KERN_STACK));\n\t\t\n\t io.print(\"Loading IDT \\n\");\n\t\t init_idt();\n\t\t\n\t\t\n\t io.print(\"Configure PIC \\n\");\n\t\t init_pic();\n\t \n\t io.print(\"Loading Task Register \\n\");\n\t\t asm(\"\tmovw $0x38, %ax; ltr %ax\");\t \n}\n\n/* Initialise the list of processus */\nvoid Architecture::initProc(){\n\tfirstProc= new Process(\"kernel\");\n\tfirstProc->setState(ZOMBIE);\n\tfirstProc->addFile(fsm.path(\"/dev/tty\"),0);\n\tfirstProc->addFile(fsm.path(\"/dev/tty\"),0);\n\tfirstProc->addFile(fsm.path(\"/dev/tty\"),0);\n\t\n\t\n\tplist=firstProc;\n\tpcurrent=firstProc; \n\tpcurrent->setPNext(NULL);\n\tprocess_st* current=pcurrent->getPInfo();\n\tcurrent->regs.cr3 = (u32) pd0;\n}\n\n/* Reboot the computer */\nvoid Architecture::reboot(){\n    u8 good = 0x02;\n    while ((good & 0x02) != 0)\n        good = io.inb(0x64);\n    io.outb(0x64, 0xFE);\n}\n\n/* Shutdown the computer */\nvoid Architecture::shutdown(){\n\t// todo\n}\n\n/* Install a interruption handler */\nvoid Architecture::install_irq(int_handler h){\n\t// todo\n}\n\n/* Add a process to the scheduler */\nvoid Architecture::addProcess(Process* p){\n\tp->setPNext(plist);\n\tplist=p;\n}\n\n/* Fork a process */\nint Architecture::fork(process_st* info,process_st* father){\n\tmemcpy((char*)info,(char*)father,sizeof(process_st));\n\tinfo->pd = pd_copy(father->pd);\n}\n\n/* Initialise a new process */\nint Architecture::createProc(process_st* info, char* file, int argc, char** argv){\n\tpage *kstack;\n\tprocess_st *previous;\n\tprocess_st *current;\n\n\tchar **param, **uparam;\n\tu32 stackp;\n\tu32 e_entry; \n\n\t\n\tint pid;\n\tint i;\n\n\tpid = 1;\n\n\tinfo->pid = pid;\n\t\n\tif (argc) {\n\t\tparam = (char**) kmalloc(sizeof(char*) * (argc+1));\n\t\tfor (i=0 ; i<argc ; i++) {\n\t\t\tparam[i] = (char*) kmalloc(strlen(argv[i]) + 1);\n\t\t\tstrcpy(param[i], argv[i]);\n\t\t}\n\t\tparam[i] = 0;\n\t}\n\t\n\tinfo->pd = pd_create();\n\n\n\tINIT_LIST_HEAD(&(info->pglist));\n\n\n\tprevious = arch.pcurrent->getPInfo();\n\tcurrent=info;\n\t\n\tasm(\"mov %0, %%eax; mov %%eax, %%cr3\"::\"m\"((info->pd)->base->p_addr));\n\t\n\te_entry = (u32) load_elf(file,info);\n\n\tif (e_entry == 0) {\t\n\t\tfor (i=0 ; i<argc ; i++) \n\t\t\tkfree(param[i]);\n\t\tkfree(param);\n\t\tarch.pcurrent = (Process*) previous->vinfo;\n\t\tcurrent=arch.pcurrent->getPInfo();\n\t\tasm(\"mov %0, %%eax ;mov %%eax, %%cr3\"::\"m\" (current->regs.cr3));\n\t\tpd_destroy(info->pd);\n\t\treturn -1;\n\t}\n\n\n\tstackp = USER_STACK - 16;\n\n\n\tif (argc) {\n\t\tuparam = (char**) kmalloc(sizeof(char*) * argc);\n\n\t\tfor (i=0 ; i<argc ; i++) {\n\t\t\tstackp -= (strlen(param[i]) + 1);\n\t\t\tstrcpy((char*) stackp, param[i]);\n\t\t\tuparam[i] = (char*) stackp;\n\t\t}\n\n\t\tstackp &= 0xFFFFFFF0;\t\n\n\t\t// Creation des arguments de main() : argc, argv[]... \n\t\tstackp -= sizeof(char*);\n\t\t*((char**) stackp) = 0;\n\n\t\tfor (i=argc-1 ; i>=0 ; i--) {\t\t\n\t\t\tstackp -= sizeof(char*);\n\t\t\t*((char**) stackp) = uparam[i]; \n\t\t}\n\n\t\tstackp -= sizeof(char*);\t\n\t\t*((char**) stackp) = (char*) (stackp + 4); \n\n\t\tstackp -= sizeof(char*);\t\n\t\t*((int*) stackp) = argc; \n\n\t\tstackp -= sizeof(char*);\n\n\t\tfor (i=0 ; i<argc ; i++) \n\t\t\tkfree(param[i]);\n\n\t\tkfree(param);\n\t\tkfree(uparam);\n\t}\n\n\t\n\tkstack = get_page_from_heap();\n\n\n\t// Initialise le reste des registres et des attributs \n\tinfo->regs.ss = 0x33;\n\tinfo->regs.esp = stackp;\n\tinfo->regs.eflags = 0x0;\n\tinfo->regs.cs = 0x23;\n\tinfo->regs.eip = e_entry;\n\tinfo->regs.ds = 0x2B;\n\tinfo->regs.es = 0x2B;\n\tinfo->regs.fs = 0x2B;\n\tinfo->regs.gs = 0x2B;\n\tinfo->regs.cr3 = (u32) info->pd->base->p_addr;\n\n\tinfo->kstack.ss0 = 0x18;\n\tinfo->kstack.esp0 = (u32) kstack->v_addr + PAGESIZE - 16;\n\n\tinfo->regs.eax = 0;\n\tinfo->regs.ecx = 0;\n\tinfo->regs.edx = 0;\n\tinfo->regs.ebx = 0;\n\n\tinfo->regs.ebp = 0;\n\tinfo->regs.esi = 0;\n\tinfo->regs.edi = 0;\n\n\tinfo->b_heap = (char*) ((u32) info->e_bss & 0xFFFFF000) + PAGESIZE;\n\tinfo->e_heap = info->b_heap;\n\n\tinfo->signal = 0;\n\tfor(i=0 ; i<32 ; i++)\n\t\tinfo->sigfn[i] = (char*) SIG_DFL;\n\n\tarch.pcurrent = (Process*) previous->vinfo;\n\tcurrent=arch.pcurrent->getPInfo();\n\tasm(\"mov %0, %%eax ;mov %%eax, %%cr3\":: \"m\"(current->regs.cr3));\n\t\n\treturn 1;\n}\n\n\n// Destroy a process\nvoid Architecture::destroy_process(Process* pp){\n\tdisable_interrupt();\n\t\n\tu16 kss;\n\tu32 kesp;\n\tu32 accr3;\n\tlist_head *p, *n;\n\tpage *pg;\n\tprocess_st *proccurrent=(arch.pcurrent)->getPInfo();\n\tprocess_st *pidproc=pp->getPInfo();\n\t\n\t\n\t// Switch page to the process to destroy\n\tasm(\"mov %0, %%eax ;mov %%eax, %%cr3\"::\"m\" (pidproc->regs.cr3));\n\n\t\n\t// Free process memory:\n\t//  - pages used by the executable code\n\t//  - user stack\n\t//  - kernel stack\n\t//  - pages directory\n\n\t// Free process memory\n\tlist_for_each_safe(p, n, &pidproc->pglist) {\n\t\tpg = list_entry(p, struct page, list);\n\t\trelease_page_frame(pg->p_addr);\n\t\tlist_del(p);\n\t\tkfree(pg);\n\t}\n\t\n\trelease_page_from_heap((char *) ((u32)pidproc->kstack.esp0 & 0xFFFFF000));\n\n\t// Free pages directory\n\tasm(\"mov %0, %%eax; mov %%eax, %%cr3\"::\"m\"(pd0));\n\n\tpd_destroy(pidproc->pd);\n\n\tasm(\"mov %0, %%eax ;mov %%eax, %%cr3\"::\"m\" (proccurrent->regs.cr3));\n\t\n\t// Remove from the list\n\tif (plist==pp){\n\t\tplist=pp->getPNext();\n\t}\n\telse{\n\t\tProcess* l=plist;\n\t\tProcess*ol=plist;\n\t\twhile (l!=NULL){\n\t\t\t\n\t\t\tif (l==pp){\n\t\t\t\tol->setPNext(pp->getPNext());\n\t\t\t}\n\t\t\t\n\t\t\tol=l;\n\t\t\tl=l->getPNext();\n\t\t}\n\t}\n\t\n\tenable_interrupt();\n}\n\n\nvoid Architecture::change_process_father(Process* pe, Process* pere){\n\tProcess* p=plist;\n\tProcess* pn=NULL;\n\twhile (p!=NULL){\n\t\tpn=p->getPNext();\n\t\tif (p->getPParent()==pe){\n\t\t\tp->setPParent(pere);\n\t\t}\n\t\t\n\t\tp=pn;\n\t}\n}\n\n\nvoid Architecture::destroy_all_zombie(){\n\tProcess* p=plist;\n\tProcess* pn=NULL;\n\twhile (p!=NULL){\n\t\tpn=p->getPNext();\n\t\tif (p->getState()==ZOMBIE && p->getPid()!=1){\n\t\t\tdestroy_process(p);\n\t\t\tdelete p;\n\t\t}\n\t\t\n\t\tp=pn;\n\t}\n}\n\n/* Set the syscall arguments */\nvoid Architecture::setParam(u32 ret, u32 ret1, u32 ret2, u32 ret3,u32 ret4){\n\tret_reg[0]=ret;\n\tret_reg[1]=ret1;\n\tret_reg[2]=ret2;\n\tret_reg[3]=ret3;\n\tret_reg[4]=ret4;\n}\n\n/* Enable the interruption */\nvoid Architecture::enable_interrupt(){\n\tasm (\"sti\");\n}\n\n/* Disable the interruption */\nvoid Architecture::disable_interrupt(){\n\tasm (\"cli\");\n}\n\n/* Get a syscall argument */\nu32\tArchitecture::getArg(u32 n){\n\tif (n<5)\n\t\treturn ret_reg[n];\n\telse\n\t\treturn 0;\n}\n\n/* Set the return value of syscall */\nvoid Architecture::setRet(u32 ret){\n\tstack_ptr[14] = ret;\n}\n"
  },
  {
    "path": "src/kernel/arch/x86/architecture.h",
    "content": "#ifndef ARCH_H\n#define ARCH_H\n\n#include <runtime/types.h>\n\n#include <process.h>\n\n\n/** Processor architecture class **/\nclass Architecture\n{\n\tpublic:\n\t\t/** architecture class functions **/\n\t\tvoid\tinit();\t\t\t/* start the processor interface */\n\t\tvoid\treboot();\t\t/* reboot the computer */\n\t\tvoid\tshutdown();\t\t/* shutdown the computer */\n\t\tchar*\tdetect();\t\t/* detect the type of processor */\n\t\tvoid\tinstall_irq(int_handler h);\t/* install a interruption handler */\n\t\tvoid\taddProcess(Process* p);\t\t/* add a process to the scheduler */\n\t\tvoid\tenable_interrupt();\t\t/* enable the interruption */\n\t\tvoid\tdisable_interrupt();\t/* disable the interruption */\n\t\tint \tcreateProc(process_st* info,char* file,int argc,char** argv);\t/* initialise a process */\n\t\tvoid\tsetParam(u32 ret,u32 ret1,u32 ret2, u32 ret3,u32 ret4);\t\t/* set the syscall arguments */\n\t\tu32\t\tgetArg(u32 n);\t\t/* get a syscall argument */\n\t\tvoid\tsetRet(u32 ret);\t/* set the return value of syscall */\n\t\tvoid \tinitProc();\t\t\t/* initialise the list of processes */\n\t\tvoid\tdestroy_process(Process* pp);\t/* destroy a processes */\n\t\tvoid\tdestroy_all_zombie();\n\t\tvoid\tchange_process_father(Process* p,Process* pere);\n\t\tint\t\tfork(process_st* info,process_st* father);\t/* fork a process */\n\t\t\n\t\t\n\t\t/** architecture public class attributes */\n\t\tProcess*\tpcurrent;\t\t/* the current processes */\n\t\tProcess*\tplist;\t\t\t/* the chain list of processes */\n\t\t\n\t\t\n\tprivate:\n\t\t/** architecture private attributes **/\n\t\tu32\t\t\tret_reg[5];\n\t\tProcess* \tfirstProc;\n\t\t\n};\n\n/** standart starting architecture interface **/\nextern Architecture arch;\n\n#endif\n"
  },
  {
    "path": "src/kernel/arch/x86/archprocess.h",
    "content": "#ifndef APROC_H\n#define APROC_H\n\n#include <runtime/types.h>\n\nextern \"C\" {\n\n#define KERNELMODE\t0\n#define USERMODE\t1\n\n\t/** info processor structure for a process */\n\tstruct process_st {\n\t\tint pid;\n\n\t\tstruct {\n\t\t\tu32 eax, ecx, edx, ebx;\n\t\t\tu32 esp, ebp, esi, edi;\n\t\t\tu32 eip, eflags;\n\t\t\tu32 cs:16, ss:16, ds:16, es:16, fs:16, gs:16;\n\t\t\tu32 cr3;\n\t\t} regs __attribute__ ((packed));\n\n\t\tstruct {\n\t\t\tu32 esp0;\n\t\t\tu16 ss0;\n\t\t} kstack __attribute__ ((packed));\n\n\t\t// Caution: with task switch\n\t\tstruct page_directory *pd;\t\n\n\t\tlist_head pglist;\n\n\t\tchar *b_exec;\n\t\tchar *e_exec;\n\t\tchar *b_bss;\n\t\tchar *e_bss;\n\t\tchar *b_heap;\n\t\tchar *e_heap;\n\n\t\tu32 signal;\n\t\tvoid* sigfn[32];\n\n\t\tvoid*\tvinfo;\n\t\t\n\t} __attribute__ ((packed));\n}\n\n#endif\n"
  },
  {
    "path": "src/kernel/arch/x86/config.make",
    "content": "LDFLAG= -melf_i386 -static  -L ./  -T ./arch/$(ARCH)/linker.ld\nSC=g++\nFLAG= $(INCDIR) -g -O2 -w -trigraphs -fno-builtin  -fno-exceptions -fno-stack-protector -O0 -m32  -fno-rtti -nostdlib -nodefaultlibs \nASM=nasm  \nASMFLAG=-f elf -o\nLD=ld\nNM=nm\nOBJDUMP=objdump\n"
  },
  {
    "path": "src/kernel/arch/x86/io.cc",
    "content": "#include <os.h>\n\nIo* Io::last_io=&io;\t\t/* definis la derniere io avant switch */\nIo* Io::current_io=&io;\t\t/* interface actuel (clavier redirig vers celle ci) */\n\n/* Video memory */\nchar* Io::vidmem = (char*)RAMSCREEN;\n\n/* Constructor */\nIo::Io(){\n\treal_screen = (char*)RAMSCREEN;\n}\n\n/* Destructor */\nIo::Io(u32 flag){\n\treal_screen=(char*)screen;\n}\n\n/* output byte */\nvoid Io::outb(u32 ad,u8 v){\n\tasmv(\"outb %%al, %%dx\" :: \"d\" (ad), \"a\" (v));;\n}\n/* output word */\nvoid Io::outw(u32 ad,u16 v){\n\tasmv(\"outw %%ax, %%dx\" :: \"d\" (ad), \"a\" (v));\n}\n/* output word */\nvoid Io::outl(u32 ad,u32 v){\n\tasmv(\"outl %%eax, %%dx\" : : \"d\" (ad), \"a\" (v));\n}\n/* input byte */\nu8 Io::inb(u32 ad){\n\tu8 _v;       \\\n\tasmv(\"inb %%dx, %%al\" : \"=a\" (_v) : \"d\" (ad)); \\\n\treturn _v;\n}\n/* input word */\nu16\tIo::inw(u32 ad){\n\tu16 _v;\t\t\t\\\n\tasmv(\"inw %%dx, %%ax\" : \"=a\" (_v) : \"d\" (ad));\t\\\n\treturn _v;\n}\n/* input word */\nu32\tIo::inl(u32 ad){\n\tu32 _v;\t\t\t\\\n\tasmv(\"inl %%dx, %%eax\" : \"=a\" (_v) : \"d\" (ad));\t\\\n\treturn _v;\n}\n\n/* renvoie la position x du curseur */\nu32\tIo::getX(){\n\treturn (u32)x;\n}\n\n/* renvoie la position y du curseur */\nu32\tIo::getY(){\n\treturn (u32)y;\n}\n\n/* x86 scroll up screen */\nvoid Io::scrollup(unsigned int n)\n{\n\t\tunsigned char *video, *tmp;\n\n\t\tfor (video = (unsigned char *) real_screen;\n\t\t     video < (unsigned char *) SCREENLIM; video += 2) {\n\t\t\ttmp = (unsigned char *) (video + n * 160);\n\n\t\t\tif (tmp < (unsigned char *) SCREENLIM) {\n\t\t\t\t*video = *tmp;\n\t\t\t\t*(video + 1) = *(tmp + 1);\n\t\t\t} else {\n\t\t\t\t*video = 0;\n\t\t\t\t*(video + 1) = 0x07;\n\t\t\t}\n\t\t}\n\n\t\ty -= n;\n\t\tif (y < 0)\n\t\t\ty = 0;\n}\n\n/* sauvegarde la memoire video */\nvoid Io::save_screen(){\n\tmemcpy(screen,(char*)RAMSCREEN,SIZESCREEN);\n\treal_screen=(char*)screen;\n}\n\n/* charge la memoire video */\nvoid Io::load_screen(){\n\tmemcpy((char*)RAMSCREEN,screen,SIZESCREEN);\n\treal_screen=(char*)RAMSCREEN;\n}\n\n/* switch tty io */\nvoid Io::switchtty(){\n\tcurrent_io->save_screen();\n\tload_screen();\n\tlast_io=current_io;\n\tcurrent_io=this;\n}\n\n/* put a byte on screen */\nvoid Io::putc(char c){\n\tkattr = 0x07;\n\tunsigned char *video;\n\tvideo = (unsigned char *) (real_screen+ 2 * x + 160 * y);\n\tif (c == 10) {\t\t\t\n\t\tx = 0;\n\t\ty++;\n\t} else if (c == 8) {\t\n\t\tif (x) {\n\t\t\t\t*(video + 1) = 0x0;\n\t\t\tx--;\n\t\t}\n\t} else if (c == 9) {\t\n\t\tx = x + 8 - (x % 8);\n\t} else if (c == 13) {\t\n\t\tx = 0;\n\t} else {\t\t\n\t\t\t*video = c;\n\t\t\t*(video + 1) = kattr;\n\n\t\tx++;\n\t\tif (x > 79) {\n\t\t\tx = 0;\n\t\t\ty++;\n\t\t}\n\t}\n\t\t\tif (y > 24)\n\t\t\t\tscrollup(y - 24);\n}\n\n/* change colors */\nvoid Io::setColor(char fcol,char bcol){\n\tfcolor=fcol;\n\tbcolor=bcol;\n}\n\n/* change cursor position */\nvoid Io::setXY(char xc,char yc){\n\tx=xc;\n\ty=yc;\n}\n\n/* clear screen */\nvoid Io::clear(){\n\tx=0;\n\ty=0;\n\tmemset((char*)RAMSCREEN,0,SIZESCREEN);\n}\n\n/* put a string in screen */\nvoid Io::print(const char *s, ...){\n\tva_list ap;\n\n\tchar buf[16];\n\tint i, j, size, buflen, neg;\n\n\tunsigned char c;\n\tint ival;\n\tunsigned int uival;\n\n\tva_start(ap, s);\n\n\twhile ((c = *s++)) {\n\t\tsize = 0;\n\t\tneg = 0;\n\n\t\tif (c == 0)\n\t\t\tbreak;\n\t\telse if (c == '%') {\n\t\t\tc = *s++;\n\t\t\tif (c >= '0' && c <= '9') {\n\t\t\t\tsize = c - '0';\n\t\t\t\tc = *s++;\n\t\t\t}\n\n\t\t\tif (c == 'd') {\n\t\t\t\tival = va_arg(ap, int);\n\t\t\t\tif (ival < 0) {\n\t\t\t\t\tuival = 0 - ival;\n\t\t\t\t\tneg++;\n\t\t\t\t} else\n\t\t\t\t\tuival = ival;\n\t\t\t\titoa(buf, uival, 10);\n\n\t\t\t\tbuflen = strlen(buf);\n\t\t\t\tif (buflen < size)\n\t\t\t\t\tfor (i = size, j = buflen; i >= 0;\n\t\t\t\t\t     i--, j--)\n\t\t\t\t\t\tbuf[i] =\n\t\t\t\t\t\t    (j >=\n\t\t\t\t\t\t     0) ? buf[j] : '0';\n\n\t\t\t\tif (neg)\n\t\t\t\t\tprint(\"-%s\", buf);\n\t\t\t\telse\n\t\t\t\t\tprint(buf);\n\t\t\t}\n\t\t\t else if (c == 'u') {\n\t\t\t\tuival = va_arg(ap, int);\n\t\t\t\titoa(buf, uival, 10);\n\n\t\t\t\tbuflen = strlen(buf);\n\t\t\t\tif (buflen < size)\n\t\t\t\t\tfor (i = size, j = buflen; i >= 0;\n\t\t\t\t\t     i--, j--)\n\t\t\t\t\t\tbuf[i] =\n\t\t\t\t\t\t    (j >=\n\t\t\t\t\t\t     0) ? buf[j] : '0';\n\n\t\t\t\tprint(buf);\n\t\t\t} else if (c == 'x' || c == 'X') {\n\t\t\t\tuival = va_arg(ap, int);\n\t\t\t\titoa(buf, uival, 16);\n\n\t\t\t\tbuflen = strlen(buf);\n\t\t\t\tif (buflen < size)\n\t\t\t\t\tfor (i = size, j = buflen; i >= 0;\n\t\t\t\t\t     i--, j--)\n\t\t\t\t\t\tbuf[i] =\n\t\t\t\t\t\t    (j >=\n\t\t\t\t\t\t     0) ? buf[j] : '0';\n\n\t\t\t\tprint(\"0x%s\", buf);\n\t\t\t} else if (c == 'p') {\n\t\t\t\tuival = va_arg(ap, int);\n\t\t\t\titoa(buf, uival, 16);\n\t\t\t\tsize = 8;\n\n\t\t\t\tbuflen = strlen(buf);\n\t\t\t\tif (buflen < size)\n\t\t\t\t\tfor (i = size, j = buflen; i >= 0;\n\t\t\t\t\t     i--, j--)\n\t\t\t\t\t\tbuf[i] =\n\t\t\t\t\t\t    (j >=\n\t\t\t\t\t\t     0) ? buf[j] : '0';\n\n\t\t\t\tprint(\"0x%s\", buf);\n\t\t\t} else if (c == 's') {\n\t\t\t\tprint((char *) va_arg(ap, int));\n\t\t\t} \n\t\t} else\n\t\t\tputc(c);\n\t}\n\n\treturn;\n}\n\n/* put a byte on the console */\nvoid Io::putctty(char c){\n\tif (keystate==BUFFERED){\n\t\tif (c == 8) {\t\t/* backspace */\n\t\t\tif (keypos>0) {\n\t\t\t\tinbuf[keypos--] = 0;\n\t\t\t}\n\t\t}\n\t\telse if (c == 10) {\t/* newline */\n\t\t\tinbuf[keypos++] = c;\n\t\t\tinbuf[keypos] = 0; \n\t\t\tinlock = 0;\n\t\t\tkeypos = 0;\n\t\t}\n\t\telse {\n\t\t\tinbuf[keypos++] = c; \n\t\t}\n\t}\n\telse if (keystate==GETCHAR){\n\t\tinbuf[0]=c;\n\t\tinbuf[1]=0;\n\t\tinlock = 0;\n\t\tkeypos = 0;\n\t}\n}\n\n/* read a string in the console */\nu32 Io::read(char* buf,u32 count){\n\tif (count>1){\n\t\tkeystate=BUFFERED;\n\t}\n\telse{\t//getchar\n\t\tkeystate=GETCHAR;\n\t}\n\tasm(\"sti\");\n\tinlock=1;\n\twhile (inlock == 1);\n\tasm(\"cli\");\n\tstrncpy(buf,inbuf,count);\n\treturn strlen(buf);\n}"
  },
  {
    "path": "src/kernel/arch/x86/io.h",
    "content": "\n#ifndef IO_H\n#define IO_H\n\n#include <runtime/types.h>\n\n\n\n#define RAMSCREEN 0xB8000\t/* debut de la memoire video */\n#define SIZESCREEN 0xFA0\t/* 4000, nombres d'octets d'une page texte */\n#define SCREENLIM 0xB8FA0\n\n/** Input/output class **/\nclass Io\n{\n\tpublic:\n\t\n\t\tIo();\n\t\tIo(u32 flag);\n\t\t\n\t\t/** standart io color **/\n\t\tenum Colour\n\t\t  {\n\t\t\tBlack       =0,\n\t\t\tBlue        =1,\n\t\t\tGreen       =2,\n\t\t\tCyan        =3,\n\t\t\tRed         =4,\n\t\t\tMagenta     =5,\n\t\t\tOrange      =6,\n\t\t\tLightGrey   =7,\n\t\t\tDarkGrey    =8,\n\t\t\tLightBlue   =9,\n\t\t\tLightGreen  =10,\n\t\t\tLightCyan   =11,\n\t\t\tLightRed    =12,\n\t\t\tLightMagenta=13,\n\t\t\tYellow      =14,\n\t\t\tWhite       =15\n\t\t  };\n\n\t\t/** io class functions **/\n\t\tvoid\toutb(u32 ad,u8 v);\t\t/* output byte */\n\t\tvoid\toutw(u32 ad,u16 v);\t\t/* output word */\n\t\tvoid\toutl(u32 ad,u32 v);\t\t/* output word */\n\t\t\n\t\tu8\t\tinb(u32 ad);\t\t\t/* input byte */\n\t\tu16\t\tinw(u32 ad);\t\t\t/* input word */\n\t\tu32\t\tinl(u32 ad);\t\t\t/* input word */\n\t\t\n\t\tvoid\tputctty(char c);\t\t/* put a byte on the console */\n\t\t\n\t\tu32 \tread(char* buf,u32 count);\t/* read a string in the console */\n\t\tvoid\tputc(char c);\t\t\t\t/* put a byte on screen */\n\t\tvoid\tsetColor(char fcol,char bcol);\t/* change colors */\n\t\tvoid\tsetXY(char xc,char yc);\t\t\t/* change cursor position */\n\t\tvoid\tclear();\t\t\t\t/* clear screen */\n\t\tvoid\tprint(const char *s, ...);\t/* put a string in screen */\n\t\t\n\t\tu32\t\tgetX();\n\t\tu32\t\tgetY();\n\t\t\n\t\t\n\t\tvoid\tswitchtty();\t\t/* change the io interface */\t\n\t\t\n\t\t/** x86 functions **/\n\t\tvoid\tscrollup(unsigned int n);\n\t\tvoid\tsave_screen();\n\t\tvoid\tload_screen();\n\t\t\n\t\tenum ConsoleType {\n\t\t\tBUFFERED,\n\t\t\tGETCHAR\n\t\t};\n\t\t\n\t\tstatic Io*\tcurrent_io;\n\t\tstatic Io*\tlast_io;\n\t\t\n\tprivate:\n\n\t\n\t\n\t\t/** x86 private attributes **/\n\t\tchar*\treal_screen;\n\t\tchar\tscreen[SIZESCREEN];\n\t\t\n\t\tchar\tinbuf[512];\t\t/* console buffer */\n\t\tint\t\tkeypos;\t\t\t/* console read position */\n\t\tint\t\tinlock;\t\t\t/* console state */\n\t\tint\t\tkeystate;\t\t/* console type keyboard */\n\t\t\n\t\t\n\t\tchar \tfcolor;\t\t\t/* console foreground color */\n\t\tchar\tbcolor;\t\t\t/* console background color */\n\t\tchar\tx;\t\t\t\t/* console x position */\n\t\tchar\ty;\t\t\t\t/* console y position */\n\t\tchar kattr;\t\t\t\t/* console attribut */\n\t\tstatic char*\tvidmem;\t/* screen video memory */\n\t\t\n};\n\n/** standart starting io interface **/\nextern Io io;\n\n#endif\n"
  },
  {
    "path": "src/kernel/arch/x86/linker.ld",
    "content": "OUTPUT_FORMAT(elf32-i386)\r\nOUTPUT_ARCH(i386)\r\nENTRY (_start)\r\n\r\nSECTIONS{\r\n    . = 0x00100000;\r\n\r\n    .text :{\r\n        *(.text)\r\n    }\r\n\r\n\t.data ALIGN (0x1000) : {\r\n\t   start_ctors = .;\r\n\t   *(.ctor*)\r\n\t   end_ctors = .;\r\n\t   start_dtors = .;\r\n\t   *(.dtor*)\r\n\t   end_dtors = .;\r\n\t   *(.data)\r\n\t}\r\n\r\n\r\n    .rodata ALIGN (0x1000) : {\r\n        *(.rodata)\r\n    }\r\n\r\n    .data ALIGN (0x1000) : {\r\n        *(.data)\r\n    }\r\n\r\n    .bss : {\r\n        sbss = .;\r\n        *(COMMON)\r\n        *(.bss)\r\n        ebss = .;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/kernel/arch/x86/start.asm",
    "content": "global _start, _kmain\r\nextern kmain, start_ctors, end_ctors, start_dtors, end_dtors\r\n\r\n    \r\n%define MULTIBOOT_HEADER_MAGIC  0x1BADB002\r\n%define MULTIBOOT_HEADER_FLAGS\t0x00000003\r\n%define CHECKSUM -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)\r\n\r\n;-- Entry point\r\n_start:\r\n\tjmp start\r\n\r\n;-- Multiboot header --\r\nalign 4\r\n\r\nmultiboot_header:\r\ndd MULTIBOOT_HEADER_MAGIC\r\ndd MULTIBOOT_HEADER_FLAGS\r\ndd CHECKSUM     \r\n;--/Multiboot header --\r\n\r\nstart:\r\n\tpush ebx\r\n\t \r\nstatic_ctors_loop:\r\n   mov ebx, start_ctors\r\n   jmp .test\r\n.body:\r\n   call [ebx]\r\n   add ebx,4\r\n.test:\r\n   cmp ebx, end_ctors\r\n   jb .body\r\n \r\n   call kmain                      ; call kernel proper\r\n \r\nstatic_dtors_loop:\r\n   mov ebx, start_dtors\r\n   jmp .test\r\n.body:\r\n   call [ebx]\r\n   add ebx,4\r\n.test:\r\n   cmp ebx, end_dtors\r\n   jb .body\r\n\t\r\n\tcli ; stop interrupts\r\n\thlt ; halt the CPU\r\n"
  },
  {
    "path": "src/kernel/arch/x86/switch.asm",
    "content": "\nglobal do_switch\n\ndo_switch:\n\t; recuper l'adresse de *current \n\tmov esi, [esp]\n\tpop eax\t\t\t; depile @current\n\n\t; prepare les registres\n\tpush dword [esi+4]\t; eax\n\tpush dword [esi+8]\t; ecx\n\tpush dword [esi+12]\t; edx\n\tpush dword [esi+16]\t; ebx\n\tpush dword [esi+24]\t; ebp\n\tpush dword [esi+28]\t; esi\n\tpush dword [esi+32]\t; edi\n\tpush dword [esi+48]\t; ds\n\tpush dword [esi+50]\t; es\n\tpush dword [esi+52]\t; fs\n\tpush dword [esi+54]\t; gs\n\n\t; enleve le mask du PIC\n\tmov al, 0x20\n\tout 0x20, al\n\n\t; charge table des pages\n\tmov eax, [esi+56]\n\tmov cr3, eax\n\n\t; charge les registres\n\tpop gs\n\tpop fs\n\tpop es\n\tpop ds\n\tpop edi\n\tpop esi\n\tpop ebp\n\tpop ebx\n\tpop edx\n\tpop ecx\n\tpop eax\n\n\t; retourne \n\tiret\n\n"
  },
  {
    "path": "src/kernel/arch/x86/vmm.cc",
    "content": "#include <os.h>\n\nextern \"C\" {\n\tchar *kern_heap;\n\tlist_head kern_free_vm;\n\tu32 *pd0 = (u32 *) KERN_PDIR;\t\t\t/* kernel page directory */\n\tchar *pg0 = (char *) 0;\t\t\t\t\t/* kernel page 0 (4MB) */\n\tchar *pg1 = (char *) KERN_PG_1;\t\t\t/* kernel page 1 (4MB) 0x400000*/\n\tchar *pg1_end = (char *) KERN_PG_1_LIM;\t/* limite de la page 1 0x800000*/\n\tu8 mem_bitmap[RAM_MAXPAGE / 8];\t\t\t/* bitmap allocation de pages (1 Go) */\n\n\tu32 kmalloc_used = 0;\n\t\n\t\n\t/*\n\t * Parcours le bitmap a la recherche d'une page libre et la marque\n\t * comme utilisee avant de retourner son adresse physique.\n\t */\n\tchar* get_page_frame(void)\n\t{\n\t\tint byte, bit;\n\t\tint page = -1;\n\n\t\tfor (byte = 0; byte < RAM_MAXPAGE / 8; byte++)\n\t\t\tif (mem_bitmap[byte] != 0xFF)\n\t\t\t\tfor (bit = 0; bit < 8; bit++)\n\t\t\t\t\tif (!(mem_bitmap[byte] & (1 << bit))) {\n\t\t\t\t\t\tpage = 8 * byte + bit;\n\t\t\t\t\t\tset_page_frame_used(page);\n\t\t\t\t\t\treturn (char *) (page * PAGESIZE);\n\t\t\t\t\t}\n\t\treturn (char *) -1;\n\t}\n\n\n\t/* \n\t * Recherche une page virtuelle libre dans l'espace d'adresses virtuelles du\n\t * noyau. La fonction demande ensuite une page physique libre a associer.\n\t * NOTE: ces pages sont dans l'espace d'adressage du noyau. Celui-ci est mis a\n\t * jour.\n\t */\n\tpage* get_page_from_heap(void)\n\t{\n\t\tpage *pg;\n\t\tvm_area *area;\n\t\tchar *v_addr, *p_addr;\n\n\t\t/* Prend une page physique libre */\n\t\tp_addr = get_page_frame();\n\t\tif ((int)(p_addr) < 0) {\n\t\t\tio.print (\"PANIC: get_page_from_heap(): no page frame available. System halted !\\n\");\n\t\t}\n\n\t\t/* Verifie si il y a une page virtuelle libre */\n\t\tif (list_empty(&kern_free_vm)) {\n\t\t\tio.print (\"PANIC: get_page_from_heap(): not memory left in page heap. System halted !\\n\");\n\t\t}\n\n\t\t/* Prend la premiere page virtuelle libre de disponible */\n\t\tarea = list_first_entry(&kern_free_vm, vm_area, list);\n\t\tv_addr = area->vm_start;\n\n\t\t/* Met a jour la liste de pages libres dans l'espace virtuel du noyau */\n\t\tarea->vm_start += PAGESIZE;\n\t\tif (area->vm_start == area->vm_end) {\n\t\t\tlist_del(&area->list);\n\t\t\tkfree(area);\n\t\t}\n\n\t\t/* Met a jour l'espace d'adressage du noyau */\n\t\tpd0_add_page(v_addr, p_addr, 0);\n\n\t\t/* Renvoie la page */\n\t\tpg = (page*) kmalloc(sizeof(page));\n\t\tpg->v_addr = v_addr;\n\t\tpg->p_addr = p_addr;\n\t\tpg->list.next = 0;\n\t\tpg->list.prev = 0;\n\n\t\treturn pg;\n\t}\n\n\tint release_page_from_heap(char *v_addr)\n\t{\n\t\tstruct vm_area *next_area, *prev_area, *new_area;\n\t\tchar *p_addr;\n\n\t\t/* Retrouve la page frame associee a v_addr et la libere */\n\t\tp_addr = get_p_addr(v_addr);\n\t\tif (p_addr) {\n\t\t\trelease_page_frame(p_addr);\n\t\t}\n\t\telse {\n\t\t\tio.print(\"WARNING: release_page_from_heap(): no page frame associated with v_addr %x\\n\", v_addr);\n\t\t\treturn 1;\n\t\t}\n\n\t\t/* Met a jour le repertoire de pages */\n\t\tpd_remove_page(v_addr);\n\n\t\t/* Met a jour la liste d'adresses virtuelles libres */\n\t\tlist_for_each_entry(next_area, &kern_free_vm, list) {\n\t\t\tif (next_area->vm_start > v_addr)\n\t\t\t\tbreak;\n\t\t}\n\n\t\tprev_area = list_entry(next_area->list.prev, struct vm_area, list);\n\t\t\n\t\tif (prev_area->vm_end == v_addr) {\n\t\t\tprev_area->vm_end += PAGESIZE;\n\t\t\tif (prev_area->vm_end == next_area->vm_start) {\n\t\t\t\tprev_area->vm_end = next_area->vm_end;\n\t\t\t\tlist_del(&next_area->list);\n\t\t\t\tkfree(next_area);\n\t\t\t}\n\t\t}\n\t\telse if (next_area->vm_start == v_addr + PAGESIZE) {\n\t\t\tnext_area->vm_start = v_addr;\n\t\t}\n\t\telse if (next_area->vm_start > v_addr + PAGESIZE) {\n\t\t\tnew_area = (struct vm_area*) kmalloc(sizeof(struct vm_area));\n\t\t\tnew_area->vm_start = v_addr;\n\t\t\tnew_area->vm_end = v_addr + PAGESIZE;\n\t\t\tlist_add(&new_area->list, &prev_area->list);\n\t\t}\n\t\telse {\n\t\t\tio.print (\"\\nPANIC: release_page_from_heap(): corrupted linked list. System halted !\\n\");\n\t\t\tasm(\"hlt\");\n\t\t}\n\n\t\treturn 0;\n\t}\n\n\n\n\n\t/* \n\t * Initialise le bitmap memoire et cree le repertoire de pages du kernel.\n\t * Utilise un identity mapping tel que vaddr = paddr sur 4Mo \n\t */\n\tvoid Memory_init(u32 high_mem)\n\t{\n\t\tint pg, pg_limit;\n\t\tunsigned long i;\n\t\tstruct vm_area *p;\n\t\tstruct vm_area *pm;\n\n\t\t/* Numero de la derniere page */\n\t\tpg_limit = (high_mem * 1024) / PAGESIZE;\n\n\t\t/* Initialisation du bitmap de pages physiques */\n\t\tfor (pg = 0; pg < pg_limit / 8; pg++)\n\t\t\tmem_bitmap[pg] = 0;\n\n\t\tfor (pg = pg_limit / 8; pg < RAM_MAXPAGE / 8; pg++)\n\t\t\tmem_bitmap[pg] = 0xFF;\n\n\t\t/* Pages reservees pour le noyau */\n\t\tfor (pg = PAGE(0x0); pg < (int)(PAGE((u32) pg1_end)); pg++) {\n\t\t\tset_page_frame_used(pg);\n\t\t}\n\n\t\t/* Initialisation du repertoire de pages */\n\t\tpd0[0] = ((u32) pg0 | (PG_PRESENT | PG_WRITE | PG_4MB));\n\t\tpd0[1] = ((u32) pg1 | (PG_PRESENT | PG_WRITE | PG_4MB));\n\t\tfor (i = 2; i < 1023; i++)\n\t\t\tpd0[i] =\n\t\t\t    ((u32) pg1 + PAGESIZE * i) | (PG_PRESENT | PG_WRITE);\n\n\t\t// Page table mirroring magic trick ! \n\t\tpd0[1023] = ((u32) pd0 | (PG_PRESENT | PG_WRITE));\n\n\n\t\t/* Passe en mode pagination */\n\t\tasm(\"\tmov %0, %%eax \\n \\\n\t\t\tmov %%eax, %%cr3 \\n \\\n\t\t\tmov %%cr4, %%eax \\n \\\n\t\t\tor %2, %%eax \\n \\\n\t\t\tmov %%eax, %%cr4 \\n \\\n\t\t\tmov %%cr0, %%eax \\n \\\n\t\t\tor %1, %%eax \\n \\\n\t\t\tmov %%eax, %%cr0\"::\"m\"(pd0), \"i\"(PAGING_FLAG), \"i\"(PSE_FLAG));\n\n\t\t\n\t\t/* Initialisation du heap du noyau utilise par kmalloc */\n\t\tkern_heap = (char *) KERN_HEAP;\n\t\tksbrk(1);\n\n\t\t/* Initialisation de la liste d'adresses virtuelles libres */\n\t\tp = (struct vm_area*) kmalloc(sizeof(struct vm_area));\n\t\tp->vm_start = (char*) KERN_PG_HEAP;\n\t\tp->vm_end = (char*) KERN_PG_HEAP_LIM;\n\t\tINIT_LIST_HEAD(&kern_free_vm);\n\t\tlist_add(&p->list, &kern_free_vm);\n\n\t\tarch.initProc();\n\n\t\treturn;\n\t}\n\n\t/*\n\t * Cree et initialise un rep. de pages pour une tache\n\t */\n\tstruct page_directory *pd_create(void)\n\t{\n\t\tstruct page_directory *pd;\n\t\tu32 *pdir;\n\t\tint i;\n\n\t\t/* Prend et initialise une page pour le Page Directory */\n\t\tpd = (struct page_directory *) kmalloc(sizeof(struct page_directory));\n\t\tpd->base = get_page_from_heap();\n\n\t\t/* \n\t\t * Espace kernel. Les v_addr < USER_OFFSET sont adressees par la table\n\t\t * de pages du noyau (pd0[]).\n\t\t */\n\t\tpdir = (u32 *) pd->base->v_addr;\n\t\tfor (i = 0; i < 256; i++)\n\t\t\tpdir[i] = pd0[i];\n\n\t\t/* Espace utilisateur */\n\t\tfor (i = 256; i < 1023; i++)\n\t\t\tpdir[i] = 0;\n\n\t\t/* Page table mirroring magic trick !... */\n\t\tpdir[1023] = ((u32) pd->base->p_addr | (PG_PRESENT | PG_WRITE));\n\n\n\t\t/* Mise a jour de la liste des tables de pages de l'espace utilisateur */\n\t\tINIT_LIST_HEAD(&pd->pt);\n\n\t\treturn pd;\n\t}\n\n\tvoid page_copy_in_pd(process_st* current,u32 virtadr){\n\t\t\tstruct page *pg;\n\t\t\tpg = (struct page *) kmalloc(sizeof(struct page));\n\t\t\tpg->p_addr = get_page_frame();\n\t\t\t/* todo copier le contenus de l'autre page */\n\t\t\tpg->v_addr = (char *) (virtadr & 0xFFFFF000);\n\t\t\tlist_add(&pg->list, &current->pglist);\n\t\t\tpd_add_page(pg->v_addr, pg->p_addr, PG_USER, current->pd);\n\t}\n\n\n\t/*\n\t * Cree et initialise un rep. de pages pour une tache en copie d'une autre  (ne marche pas encore )\n\t */\n\tstruct page_directory *pd_copy(struct page_directory * pdfather)\n\t{\n\t\tstruct page_directory *pd;\n\t\tu32 *pdir;\n\t\tint i;\n\n\t\t/* Prend et initialise une page pour le Page Directory */\n\t\tpd = (struct page_directory *) kmalloc(sizeof(struct page_directory));\n\t\tpd->base = get_page_from_heap();\n\n\t\t/* \n\t\t * Espace kernel. Les v_addr < USER_OFFSET sont adressees par la table\n\t\t * de pages du noyau (pd0[]).\n\t\t */\n\t\tpdir = (u32 *) pd->base->v_addr;\n\t\tfor (i = 0; i < 256; i++)\n\t\t\tpdir[i] = pd0[i];\n\n\t\t/* Espace utilisateur */\n\t\tfor (i = 256; i < 1023; i++)\n\t\t\tpdir[i] = 0;\n\n\t\t/* Page table mirroring magic trick !... */\n\t\tpdir[1023] = ((u32) pd->base->p_addr | (PG_PRESENT | PG_WRITE));\n\n\n\t\t/* Mise a jour de la liste des tables de pages de l'espace utilisateur */\n\t\tINIT_LIST_HEAD(&pd->pt);\n\n\t\treturn pd;\n\t}\n\n\tint pd_destroy(struct page_directory *pd)\n\t{\n\t\tstruct page *pg;\n\t\tstruct list_head *p, *n;\n\n\t\t/* Libere les pages correspondant aux tables */\n\t\tlist_for_each_safe(p, n, &pd->pt) {\n\t\t\tpg = list_entry(p, struct page, list);\n\t\t\trelease_page_from_heap(pg->v_addr);\n\t\t\tlist_del(p);\n\t\t\tkfree(pg);\n\t\t}\n\n\t\t/* Libere la page correspondant au repertoire */\n\t\trelease_page_from_heap(pd->base->v_addr);\n\t\tkfree(pd);\n\n\t\treturn 0;\n\t}\n\n\t/* \n\t * Met a jour l'espace d'adressage du noyau.\n\t * NOTE : cet espace est commun a tous les repertoires de pages.\n\t */\n\tint pd0_add_page(char *v_addr, char *p_addr, int flags)\n\t{\n\t\tu32 *pde;\n\t\tu32 *pte;\n\n\t\tif (v_addr > (char *) USER_OFFSET) {\n\t\t\tio.print(\"ERROR: pd0_add_page(): %p is not in kernel space !\\n\", v_addr);\n\t\t\treturn 0;\n\t\t}\n\n\t\t/* On verifie que la table de page est bien presente */\n\t\tpde = (u32 *) (0xFFFFF000 | (((u32) v_addr & 0xFFC00000) >> 20));\n\t\tif ((*pde & PG_PRESENT) == 0) {\n\t\t\t//error\n\t\t}\n\n\t\t/* Modification de l'entree dans la table de page */\n\t\tpte = (u32 *) (0xFFC00000 | (((u32) v_addr & 0xFFFFF000) >> 10));\n\t\t*pte = ((u32) p_addr) | (PG_PRESENT | PG_WRITE | flags);\n\t\tset_page_frame_used(p_addr);\n\t\treturn 0;\n\t}\n\n\t/* \n\t * Met a jour le repertoire de pages courant\n\t * input:\n\t * \tv_addr : adresse lineaire de la page \n\t * \tp_addr : adresse physique de la page allouee \n\t * \tpd     : structure qui doit etre mise a jour avec les pages allouees\n\t */\n\tint pd_add_page(char *v_addr, char *p_addr, int flags, struct page_directory *pd)\n\t{\n\t\tu32 *pde;\t\t/* adresse virtuelle de l'entree du repertoire de pages */\n\t\tu32 *pte;\t\t/* adresse virtuelle de l'entree de la table de pages */\n\t\tu32 *pt;\t\t/* adresse virtuelle de la table de pages */\n\t\tstruct page *pg;\n\t\tint i;\n\n\t\t//// io.print(\"DEBUG: pd_add_page(%p, %p, %d)\\n\", v_addr, p_addr, flags); /* DEBUG */\n\n\t\t/*\n\t\t * La derniere entree du PageDir pointe sur lui-meme.\n\t\t * Les adresses commencant par 0xFFC00000 utilisent cette entree et il\n\t\t * s'ensuite que :\n\t\t * - les 10 bits en 0x003FF000 sont un index dans le PageDir et designent une\n\t\t *   PageTable. Les 12 derniers bits permettent de modifier une entree du PageTable\n\t\t * - l'adresse 0xFFFFF000 designe le PageDir lui-meme\n\t\t */\n\t\tpde = (u32 *) (0xFFFFF000 | (((u32) v_addr & 0xFFC00000) >> 20));\n\n\t\t/* \n\t\t * On cree la table de pages correspondante si elle n'est pas presente\n\t\t */\n\t\tif ((*pde & PG_PRESENT) == 0) {\n\n\t\t\t/* \n\t\t\t * Allocation d'une page pour y mettre la table. \n\t\t\t */\n\t\t\tpg = get_page_from_heap();\n\n\t\t\t/* On initialise la nouvelle table de pages */\n\t\t\tpt = (u32 *) pg->v_addr;\n\t\t\tfor (i = 1; i < 1024; i++)\n\t\t\t\tpt[i] = 0;\n\n\t\t\t/* On ajoute l'entree correspondante dans le repertoire */\n\t\t\t*pde = (u32) pg->p_addr | (PG_PRESENT | PG_WRITE | flags);\n\n\t\t\t/* On rajoute la nouvelle page dans la structure  passee en parametre */\n\t\t\tif (pd) \n\t\t\t\tlist_add(&pg->list, &pd->pt);\n\t\t}\n\n\t\tpte = (u32 *) (0xFFC00000 | (((u32) v_addr & 0xFFFFF000) >> 10));\n\t\t*pte = ((u32) p_addr) | (PG_PRESENT | PG_WRITE | flags);\n\n\t\treturn 0;\n\t}\n\n\tint pd_remove_page(char *v_addr)\n\t{\n\t\tu32 *pte;\n\n\t\tif (get_p_addr(v_addr)) {\n\t\t\tpte = (u32 *) (0xFFC00000 | (((u32) v_addr & 0xFFFFF000) >> 10));\n\t\t\t*pte = (*pte & (~PG_PRESENT));\n\t\t\t\n\t\t\tasm(\"invlpg %0\"::\"m\"(v_addr));\n\t\t}\n\n\t\treturn 0;\n\t}\n\n\t/*\n\t * Retourne l'adresse physique de la page associee a l'adresse virtuelle passee\n\t * en argument\n\t */\n\tchar *get_p_addr(char *v_addr)\n\t{\n\t\tu32 *pde;\t\t/* adresse virtuelle de l'entree du repertoire de pages */\n\t\tu32 *pte;\t\t/* adresse virtuelle de l'entree de la table de pages */\n\n\t\tpde = (u32 *) (0xFFFFF000 | (((u32) v_addr & 0xFFC00000) >> 20));\n\t\tif ((*pde & PG_PRESENT)) {\n\t\t\tpte = (u32 *) (0xFFC00000 | (((u32) v_addr & 0xFFFFF000) >> 10));\n\t\t\tif ((*pte & PG_PRESENT))\n\t\t\t\treturn (char *) ((*pte & 0xFFFFF000) + (VADDR_PG_OFFSET((u32) v_addr)));\n\t\t}\n\n\t\treturn 0;\n\t}\n}\n\nvoid Vmm::kmap(u32 phy,u32 virt){\n\tpd0_add_page((char*)phy,(char*)virt,PG_USER);\n}\n\nvoid Vmm::init(u32 high){\n\tMemory_init(high);\n}\n"
  },
  {
    "path": "src/kernel/arch/x86/vmm.h",
    "content": "#ifndef VMM_H\n#define VMM_H\n\n#include <runtime/types.h>\n#include <runtime/list.h>\n#include <runtime/alloc.h>\n#include <x86.h>\n\n\nextern \"C\" {\n\nstruct page {\n\t\tchar *v_addr;\n\t\tchar *p_addr;\n\t\tlist_head list;\n};\n\nstruct page_directory {\n\t\tpage *base;\n\t\tlist_head pt;\n};\n\nstruct vm_area {\n\t\tchar *vm_start;\t\n\t\tchar *vm_end;\t/* exclude */\n\t\tlist_head list;\n};\n\ntypedef page_directory proc_memory;\n\n\t/* Pointe sur le sommet du heap noyau */\n\textern char *kern_heap;\n\n\t/* Pointe sur le debut de la liste des pages libres du noyau */\n\textern list_head kern_free_vm;\n\n\n\textern u32 *pd0;\n\textern u8 mem_bitmap[];\n\n\textern u32 kmalloc_used;\n\n\n\n\t/* Marque une page comme utilisee / libre dans le bitmap */\n\t#define set_page_frame_used(page)\tmem_bitmap[((u32) page)/8] |= (1 << (((u32) page)%8))\n\t#define release_page_frame(p_addr)\tmem_bitmap[((u32) p_addr/PAGESIZE)/8] &= ~(1 << (((u32) p_addr/PAGESIZE)%8))\n\n\t/* Selectionne une page libre dans le bitmap */\n\tchar *get_page_frame(void);\n\n\t/* Selectionne / libere une page libre dans le bitmap et l'associe a une page\n\t * virtuelle libre du heap */\n\tstruct page *get_page_from_heap(void);\n\tint release_page_from_heap(char *);\n\n\t/* Initialise les structures de donnees de gestion de la memoire */\n\tvoid Memory_init(u32 high_mem);\n\n\t/* Cree un repertoire de page pour un processus */\n\tstruct page_directory *pd_create(void);\n\tint pd_destroy(struct page_directory *);\n\tstruct page_directory *pd_copy(struct page_directory * pdfather);\n\t\n\t\n\t/* Ajoute une entree dans l'espace du noyau */\n\tint pd0_add_page(char *, char *, int);\n\n\t/* Ajoute / enleve une entree dans le repertoire de pages courant */\n\tint pd_add_page(char *, char *, int, struct page_directory *);\n\tint pd_remove_page(char *);\n\n\t/* Retourne l'adresse physique associee a une adresse virtuelle */\n\tchar *get_p_addr(char *);\n\n\t\n\t#define KMALLOC_MINSIZE\t\t16\n\n\tstruct kmalloc_header {\n\t\tunsigned long size:31;\t/* taille totale de l'enregistrement */\n\t\tunsigned long used:1;\n\t} __attribute__ ((packed));\n\n}\n\nclass Vmm\n{\n\tpublic:\n\t\tvoid\t\t\tinit(u32 high);\n\t\tproc_memory*\tcreatePM();\t\t\t\t\t/* Create page directory for a process */\n\t\tvoid\t\t\tswitchPM(proc_memory* ad);\t/* Switch page directory for a process */\n\t\tvoid\t\t\tmap(proc_memory* ad,u32 phy,u32 adr);\t/* map a physical page memory in virtual space */\n\t\t\n\t\tvoid\t\t\tkmap(u32 phy,u32 virt);\n\t\t\n};\n\nextern Vmm vmm;\n\n#endif\n"
  },
  {
    "path": "src/kernel/arch/x86/x86.cc",
    "content": "#include <os.h>\n#include <x86.h>\n#include <keyboard.h>\n\n\nextern \"C\" {\n\nregs_t cpu_cpuid(int code)\n{\n\tregs_t r;\n\tasm volatile(\"cpuid\":\"=a\"(r.eax),\"=b\"(r.ebx),\n                 \"=c\"(r.ecx),\"=d\"(r.edx):\"0\"(code));\n\treturn r;\n}\n\n\nu32 cpu_vendor_name(char *name)\n{\n\t\tregs_t r = cpu_cpuid(0x00);\n\t\t\n\t\tchar line1[5];\n\t\tline1[0] = ((char *) &r.ebx)[0];\n\t\tline1[1] = ((char *) &r.ebx)[1];\n\t\tline1[2] = ((char *) &r.ebx)[2];\n\t\tline1[3] = ((char *) &r.ebx)[3];\n\t\tline1[4] = '\\0';\n\n\t\tchar line2[5];\n\t\tline2[0] = ((char *) &r.ecx)[0];\n\t\tline2[1] = ((char *) &r.ecx)[1];\n\t\tline2[2] = ((char *) &r.ecx)[2];\n\t\tline2[3] = ((char *) &r.ecx)[3];\n\t\tline2[4] = '\\0';\n\t\t\n\t\tchar line3[5];\n\t\tline3[0] = ((char *) &r.edx)[0];\n\t\tline3[1] = ((char *) &r.edx)[1];\n\t\tline3[2] = ((char *) &r.edx)[2];\n\t\tline3[3] = ((char *) &r.edx)[3];\n\t\tline3[4] = '\\0';\n\t\t\t\t\t\t\t\n\t\tstrcpy(name, line1);\n\t\tstrcat(name, line3);\n\t\tstrcat(name, line2);\n\t\treturn 15;\n}\n\n\nvoid schedule();\n\nidtdesc \tkidt[IDTSIZE]; \t\t/* IDT table */\nint_desc \tintt[IDTSIZE]; \t\t/* Interruptions functions tables */\ngdtdesc \tkgdt[GDTSIZE];\t\t/* GDT */\ntss \t\tdefault_tss;\ngdtr \t\tkgdtr;\t\t\t\t/* GDTR */\nidtr \t\tkidtr; \t\t\t\t/* IDTR registry */\nu32 *\t\tstack_ptr=0;\n\n/*\n * 'init_desc' initialize a segment descriptor in gdt or ldt.\n * 'desc' is a pointer to the address\n */\nvoid init_gdt_desc(u32 base, u32 limite, u8 acces, u8 other,struct gdtdesc *desc)\n{\n\tdesc->lim0_15 = (limite & 0xffff);\n\tdesc->base0_15 = (base & 0xffff);\n\tdesc->base16_23 = (base & 0xff0000) >> 16;\n\tdesc->acces = acces;\n\tdesc->lim16_19 = (limite & 0xf0000) >> 16;\n\tdesc->other = (other & 0xf);\n\tdesc->base24_31 = (base & 0xff000000) >> 24;\n\treturn;\n}\n\n\n/*\n * This function initialize the GDT after the kernel is loaded.\n */\nvoid init_gdt(void)\n{\n\n\tdefault_tss.debug_flag = 0x00;\n\tdefault_tss.io_map = 0x00;\n\tdefault_tss.esp0 = 0x1FFF0;\n\tdefault_tss.ss0 = 0x18;\n\n\t/* initialize gdt segments */\n\tinit_gdt_desc(0x0, 0x0, 0x0, 0x0, &kgdt[0]);\n\tinit_gdt_desc(0x0, 0xFFFFF, 0x9B, 0x0D, &kgdt[1]);\t/* code */\n\tinit_gdt_desc(0x0, 0xFFFFF, 0x93, 0x0D, &kgdt[2]);\t/* data */\n\tinit_gdt_desc(0x0, 0x0, 0x97, 0x0D, &kgdt[3]);\t\t/* stack */\n\n\tinit_gdt_desc(0x0, 0xFFFFF, 0xFF, 0x0D, &kgdt[4]);\t/* ucode */\n\tinit_gdt_desc(0x0, 0xFFFFF, 0xF3, 0x0D, &kgdt[5]);\t/* udata */\n\tinit_gdt_desc(0x0, 0x0, 0xF7, 0x0D, &kgdt[6]);\t\t/* ustack */\n\n\tinit_gdt_desc((u32) & default_tss, 0x67, 0xE9, 0x00, &kgdt[7]);\t/* descripteur de tss */\n\n\t/* initialize the gdtr structure */\n\tkgdtr.limite = GDTSIZE * 8;\n\tkgdtr.base = GDTBASE;\n\n\t/* copy the gdtr to its memory area */\n\tmemcpy((char *) kgdtr.base, (char *) kgdt, kgdtr.limite);\n\n\t/* load the gdtr registry */\n\tasm(\"lgdtl (kgdtr)\");\n\n\t/* initiliaz the segments */\n\tasm(\"   movw $0x10, %ax\t\\n \\\n            movw %ax, %ds\t\\n \\\n            movw %ax, %es\t\\n \\\n            movw %ax, %fs\t\\n \\\n            movw %ax, %gs\t\\n \\\n            ljmp $0x08, $next\t\\n \\\n            next:\t\t\\n\");\n\t\t\t\n}\n\n\nvoid init_idt_desc(u16 select, u32 offset, u16 type, struct idtdesc *desc)\n{\n\tdesc->offset0_15 = (offset & 0xffff);\n\tdesc->select = select;\n\tdesc->type = type;\n\tdesc->offset16_31 = (offset & 0xffff0000) >> 16;\n\treturn;\n}\n\nextern void _asm_int_0();\nextern void _asm_int_1();\nextern void _asm_syscalls();\nextern void _asm_exc_GP(void);\nextern void _asm_exc_PF(void);\nextern void _asm_schedule();\n\nvoid do_syscalls(int num){\n\t u32 ret,ret1,ret2,ret3,ret4;\n\t asm(\"mov %%ebx, %0\": \"=m\"(ret):);\n\t asm(\"mov %%ecx, %0\": \"=m\"(ret1):);\n\t asm(\"mov %%edx, %0\": \"=m\"(ret2):);\n\t asm(\"mov %%edi, %0\": \"=m\"(ret3):);\n\t asm(\"mov %%esi, %0\": \"=m\"(ret4):);\n\t //io.print(\"syscall %d \\n\",num);\n\t /*io.print(\" ebx : %x  \",ret);\n\t io.print(\" ecx : %x \\n\",ret1);\n\t io.print(\" edx : %x  \",ret2);\n\t io.print(\" edi : %x \\n\",ret3);*/\n\t   \n\t arch.setParam(ret,ret1,ret2,ret3,ret4);\n\t asm(\"cli\");\n\t asm(\"mov %%ebp, %0\": \"=m\"(stack_ptr):);\n\n\t \n\t syscall.call(num);\n\t asm(\"sti\");\n}\n\n\n\nvoid isr_kbd_int(void)\n{\n\tu8 i;\n\tstatic int lshift_enable;\n\tstatic int rshift_enable;\n\tstatic int alt_enable;\n\tstatic int ctrl_enable;\n\tdo {\n\t\ti = io.inb(0x64);\n\t} while ((i & 0x01) == 0);\n\t\n\n\ti = io.inb(0x60);\n\ti--;\n\n\tif (i < 0x80) {\t\t/* touche enfoncee */\n\t\tswitch (i) {\n\t\tcase 0x29:\n\t\t\tlshift_enable = 1;\n\t\t\tbreak;\n\t\tcase 0x35:\n\t\t\trshift_enable = 1;\n\t\t\tbreak;\n\t\tcase 0x1C:\n\t\t\tctrl_enable = 1;\n\t\t\tbreak;\n\t\tcase 0x37:\n\t\t\talt_enable = 1;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\n\t\t\t\tif(alt_enable==1)\n\t\t\t\t{\n\t\t\t\t\tio.putctty(kbdmap[i * 4 + 2]);\n\t\t\t\t\tif (&io != io.current_io)\n\t\t\t\t\tio.current_io->putctty(kbdmap[i * 4 + 2]);\n\t\t \n\t\t\t\t}\n\t\t\t\telse if(lshift_enable == 1 || rshift_enable == 1)\n\t\t\t\t{\n\t\t \n\t\t\t\t\t io.putctty(kbdmap[i * 4 + 1]);\n\t\t\t\t\t if (&io != io.current_io)\n\t\t\t\t\t\tio.current_io->putctty(kbdmap[i * 4 + 1]);\n\t\t \n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t\t  io.putctty(kbdmap[i * 4]);\n\t\t\t\t\t if (&io != io.current_io)\n\t\t\t\t\t io.current_io->putctty(kbdmap[i * 4]);\n\t\t \n\t\t\t\t}\n               break;\n\n\t\t\t//io.print(\"sancode: %x \\n\",i * 4 + (lshift_enable || rshift_enable));\n\t\t\t/*io.putctty(kbdmap[i * 4 + (lshift_enable || rshift_enable)]);\t//replac depuis la 10.4.6\n\t\t\tif (&io != io.current_io)\n\t\t\t\tio.current_io->putctty(kbdmap[i * 4 + (lshift_enable || rshift_enable)]);*/\n\t\t\tbreak;\n\t\t}\n\t} else {\t\t/* touche relachee */\n\t\ti -= 0x80;\n\t\tswitch (i) {\n\t\tcase 0x29:\n\t\t\tlshift_enable = 0;\n\t\t\tbreak;\n\t\tcase 0x35:\n\t\t\trshift_enable = 0;\n\t\t\tbreak;\n\t\tcase 0x1C:\n\t\t\tctrl_enable = 0;\n\t\t\tbreak;\n\t\tcase 0x37:\n\t\t\talt_enable = 0;\n\t\t\tbreak;\n\t\t}\n\t}\n\t\n\t\tio.outb(0x20,0x20);\n\t\tio.outb(0xA0,0x20); \n}\n\n\nvoid isr_default_int(int id)\n{\n\tstatic int tic = 0;\n\tstatic int sec = 0;\n\tswitch (id){\n\t\tcase 1:\n\t\t\tisr_kbd_int();\n\t\t\tbreak;\n\t\t\t\n\t\t\t\n\t\tdefault:\n\t\t\treturn;\n\t\t\n\t}\n\t\n\tio.outb(0x20,0x20);\n\tio.outb(0xA0,0x20);\n}\n\n\nvoid isr_schedule_int()\n{\n\tstatic int tic = 0;\n\tstatic int sec = 0;\n\t\ttic++;\n\t\tif (tic % 100 == 0) {\n\t\tsec++;\n\t\ttic = 0;\n\t}\n\tschedule();\n\tio.outb(0x20,0x20);\n\tio.outb(0xA0,0x20);\n}\n\nvoid isr_GP_exc(void)\n{\n\tio.print(\"\\n General protection fault !\\n\");\n\tif (arch.pcurrent!=NULL){\n\t\tio.print(\"The processus %s have to be killed !\\n\\n\",(arch.pcurrent)->getName());\n\t\t(arch.pcurrent)->exit();\n\t\tschedule();\n\t}\n\telse{\n\t\tio.print(\"The kernel have to be killed !\\n\\n\");\n\t\tasm(\"hlt\");\n\t}\n}\n\nvoid isr_PF_exc(void)\n{\n\tu32 faulting_addr, code;\n\tu32 eip;\n\tstruct page *pg;\n\tu32 stack;\n \tasm(\" \tmovl 60(%%ebp), %%eax\t\\n \\\n    \t\tmov %%eax, %0\t\t\\n \\\n\t\tmov %%cr2, %%eax\t\\n \\\n\t\tmov %%eax, %1\t\t\\n \\\n \t\tmovl 56(%%ebp), %%eax\t\\n \\\n    \t\tmov %%eax, %2\"\n\t\t: \"=m\"(eip), \"=m\"(faulting_addr), \"=m\"(code));\n\t asm(\"mov %%ebp, %0\": \"=m\"(stack):);\n\t\n\t//io.print(\"#PF : %x \\n\",faulting_addr);\n\t\n\t//for (;;);\n\t\tif (arch.pcurrent==NULL)\n\t\t\treturn;\n\t\t\t\n\t\tprocess_st* current=arch.pcurrent->getPInfo();\n\n\tif (faulting_addr >= USER_OFFSET && faulting_addr <= USER_STACK) {\n\t\tpg = (struct page *) kmalloc(sizeof(struct page));\n\t\tpg->p_addr = get_page_frame();\n\t\tpg->v_addr = (char *) (faulting_addr & 0xFFFFF000);\n\t\tlist_add(&pg->list, &current->pglist);\n\t\tpd_add_page(pg->v_addr, pg->p_addr, PG_USER, current->pd);\n\t}\n\telse {\n\t\tio.print(\"\\n\");\n\t\tio.print(\"No autorized memory acces on : %p (eip:%p,code:%p)\\n\", faulting_addr,eip,  code);\n\t\tio.print(\"heap=%x, heap_limit=%x, stack=%x\\n\",kern_heap,KERN_HEAP_LIM,stack);\n\t\t\n\t\tif (arch.pcurrent!=NULL){\n\t\t\tio.print(\"The processus %s have to be killed !\\n\\n\",(arch.pcurrent)->getName());\n\t\t\t(arch.pcurrent)->exit();\n\t\t\tschedule();\n\t\t}\n\t\telse{\n\t\t\tio.print(\"The kernel have to be killed !\\n\\n\");\n\t\t\tasm(\"hlt\");\n\t\t}\n\t}\n\t\t\n}\n\n\n\n/*\n * Init IDT after kernel is loaded\n */\nvoid init_idt(void)\n{\n\t/* Init irq */\n\tint i;\n\tfor (i = 0; i < IDTSIZE; i++) \n\t\tinit_idt_desc(0x08, (u32)_asm_schedule, INTGATE, &kidt[i]); // \n\t\n\t/* Vectors  0 -> 31 are for exceptions */\n\tinit_idt_desc(0x08, (u32) _asm_exc_GP, INTGATE, &kidt[13]);\t\t/* #GP */\n\tinit_idt_desc(0x08, (u32) _asm_exc_PF, INTGATE, &kidt[14]);     /* #PF */\n\t\n\tinit_idt_desc(0x08, (u32) _asm_schedule, INTGATE, &kidt[32]);\n\tinit_idt_desc(0x08, (u32) _asm_int_1, INTGATE, &kidt[33]);\n\t\n\tinit_idt_desc(0x08, (u32) _asm_syscalls, TRAPGATE, &kidt[48]);\n\tinit_idt_desc(0x08, (u32) _asm_syscalls, TRAPGATE, &kidt[128]); //48\n\t\n\tkidtr.limite = IDTSIZE * 8;\n\tkidtr.base = IDTBASE;\n\t\n\t\n\t/* Copy the IDT to the memory */\n\tmemcpy((char *) kidtr.base, (char *) kidt, kidtr.limite);\n\n\t/* Load the IDTR registry */\n\tasm(\"lidtl (kidtr)\");\n}\n\n\nvoid init_pic(void)\n{\n\t/* Initialization of ICW1 */\n\tio.outb(0x20, 0x11);\n\tio.outb(0xA0, 0x11);\n\n\t/* Initialization of ICW2 */\n\tio.outb(0x21, 0x20);\t/* start vector = 32 */\n\tio.outb(0xA1, 0x70);\t/* start vector = 96 */\n\n\t/* Initialization of ICW3 */\n\tio.outb(0x21, 0x04);\n\tio.outb(0xA1, 0x02);\n\n\t/* Initialization of ICW4 */\n\tio.outb(0x21, 0x01);\n\tio.outb(0xA1, 0x01);\n\n\t/* mask interrupts */\n\tio.outb(0x21, 0x0);\n\tio.outb(0xA1, 0x0);\n}\n\n#define DEBUG_REG(a) io.print(\"  %s : %x\",#a,p->regs.a)\n\nvoid schedule(){\n\tProcess* pcurrent=arch.pcurrent;\n\tProcess*plist=arch.plist;\n\tif (pcurrent==0)\n\t\treturn;\n\n\tif (pcurrent->getPNext() == 0 && plist==pcurrent)\t//si le proc est seul\n\t\treturn;\n\n\tprocess_st* current=pcurrent->getPInfo();\n\tprocess_st *p;\n\tint i, newpid;\n\n\t/* Stocke dans stack_ptr le pointeur vers les registres sauvegardes */\n\tasm(\"mov (%%ebp), %%eax; mov %%eax, %0\": \"=m\"(stack_ptr):);\n\t//asm(\"mov (%%eip), %%eax; mov %%eax, %0\": \"=m\"(current->regs.eip):);\n\t\n\t//io.print(\"stack_ptr : %x \\n\",stack_ptr);\n\t\t/* Sauver les registres du processus courant */\n\t\tcurrent->regs.eflags = stack_ptr[16];\n\t\tcurrent->regs.cs = stack_ptr[15];\n\t\tcurrent->regs.eip = stack_ptr[14];\n\t\tcurrent->regs.eax = stack_ptr[13];\n\t\tcurrent->regs.ecx = stack_ptr[12];\n\t\tcurrent->regs.edx = stack_ptr[11];\n\t\tcurrent->regs.ebx = stack_ptr[10];\n\t\tcurrent->regs.ebp = stack_ptr[8];\n\t\tcurrent->regs.esi = stack_ptr[7];\n\t\tcurrent->regs.edi = stack_ptr[6];\n\t\tcurrent->regs.ds = stack_ptr[5];\n\t\tcurrent->regs.es = stack_ptr[4];\n\t\tcurrent->regs.fs = stack_ptr[3];\n\t\tcurrent->regs.gs = stack_ptr[2];\n\n\t\n\t\t/* \n\t\t * Sauvegarde le contenu des registres de pile (ss, esp)\n\t\t * au moment de l'interruption. Necessaire car le processeur\n\t\t * empile ou non ces valeurs selon le contexte de l'interruption.\n\t\t */\n\t\tif (current->regs.cs != 0x08) {\t/* mode utilisateur */\n\t\t\tcurrent->regs.esp = stack_ptr[17];\n\t\t\tcurrent->regs.ss = stack_ptr[18];\n\t\t} else {\t/* pendant un appel systeme */\n\t\t\tcurrent->regs.esp = stack_ptr[9] + 12;\t/* vaut : &stack_ptr[17] */\n\t\t\tcurrent->regs.ss = default_tss.ss0;\n\t\t}\n\n\t\t/* Sauver le TSS de l'ancien processus */\n\t\tcurrent->kstack.ss0 = default_tss.ss0;\n\t\tcurrent->kstack.esp0 = default_tss.esp0;\n\t\n\t//io.print(\"schedule %s \",pcurrent->getName());\n\tpcurrent=pcurrent->schedule();\n\tp = pcurrent->getPInfo();\n\n\t//io.print(\"to %s \\n\",pcurrent->getName());\n\t/*DEBUG_REG(eax);\n\tDEBUG_REG(ebx);\n\tDEBUG_REG(ecx);\n\tDEBUG_REG(edx);*/\n\t/*DEBUG_REG(esp); io.print(\"\\t\");\n\tDEBUG_REG(ebp);\tio.print(\"\\n\");*/\n\t//DEBUG_REG(esi);\n\t//DEBUG_REG(edi);\n\t//DEBUG_REG(eip);\tio.print(\"\\t\");\n\t/*DEBUG_REG(eflags);\n\tDEBUG_REG(cs);\n\tDEBUG_REG(ss);\n\tDEBUG_REG(ds);\n\tDEBUG_REG(es);\n\tDEBUG_REG(fs);\n\tDEBUG_REG(gs);\n\tDEBUG_REG(cr3);\n\tio.print(\"\\n\");*/\n\t\n\t/* Commutation */\n\tif (p->regs.cs != 0x08)\n\t\tswitch_to_task(p, USERMODE);\n\telse\n\t\tswitch_to_task(p, KERNELMODE);\n}\n\n/* \n * switch_to_task(): Prepare la commutation de tache effectuee par do_switch().\n * Le premier parametre indique le pid du processus a charger.\n * Le mode indique si ce processus etait en mode utilisateur ou en mode kernel\n * quand il a ete precedement interrompu par le scheduler.\n * L'empilement des registres sur la pile change selon le cas.\n */\nvoid switch_to_task(process_st* current, int mode)\n{\n\n\tu32 kesp, eflags;\n\tu16 kss, ss, cs;\n\tint sig;\n\t\n\t/* Traite les signaux */\n\n\t\tif ((sig = dequeue_signal(current->signal))) \n\t\t\thandle_signal(sig);\n\t\n\t/* Charge le TSS du nouveau processus */\n\tdefault_tss.ss0 = current->kstack.ss0;\n\tdefault_tss.esp0 = current->kstack.esp0;\n\n\t/* \n\t * Empile les registres ss, esp, eflags, cs et eip necessaires a la\n\t * commutation. Ensuite, la fonction do_switch() restaure les\n\t * registres, la table de page du nouveau processus courant et commute\n\t * avec l'instruction iret.\n\t */\n\tss = current->regs.ss;\n\tcs = current->regs.cs;\n\teflags = (current->regs.eflags | 0x200) & 0xFFFFBFFF;\n\t\n\n\t\n\t/* Prepare le changement de pile noyau */\n\tif (mode == USERMODE) {\n\t\tkss = current->kstack.ss0;\n\t\tkesp = current->kstack.esp0;\n\t} else {\t\t\t/* KERNELMODE */\n\t\tkss = current->regs.ss;\n\t\tkesp = current->regs.esp;\n\t}\n\t\n\t\n\t//io.print(\"switch to %x \\n\",current->regs.eip);\n\n\t\n\tasm(\"\tmov %0, %%ss; \\\n\t\tmov %1, %%esp; \\\n\t\tcmp %[KMODE], %[mode]; \\\n\t\tje nextt; \\\n\t\tpush %2; \\\n\t\tpush %3; \\\n\t\tnextt: \\\n\t\tpush %4; \\\n\t\tpush %5; \\\n\t\tpush %6; \\\n\t\tpush %7; \\\n\t\tljmp $0x08, $do_switch\" \n\t\t:: \\\n\t\t\"m\"(kss), \\\n\t\t\"m\"(kesp), \\\n\t\t\"m\"(ss), \\\n\t\t\"m\"(current->regs.esp), \\\n\t\t\"m\"(eflags), \\\n\t\t\"m\"(cs), \\\n\t\t\"m\"(current->regs.eip), \\\n\t\t\"m\"(current), \\\n\t\t[KMODE] \"i\"(KERNELMODE), \\\n\t\t[mode] \"g\"(mode)\n\t    );\n\t\n}\n\n\nint dequeue_signal(int mask) \n{\n\tint sig;\n\n\tif (mask) {\n\t\tsig = 1;\n\t\twhile (!(mask & 1)) {\n\t\t\tmask = mask >> 1;\n\t\t\tsig++;\n\t\t}\n\t}\n\telse\n\t\tsig = 0;\n\n\treturn sig;\n}\n\nint handle_signal(int sig)\n{\n\tProcess* pcurrent=arch.pcurrent;\n\tif (pcurrent==0)\n\t\treturn 0;\n\n\tprocess_st* current=pcurrent->getPInfo();\n\t\n\tu32 *esp;\n\n\t//io.print(\"signal> handle signal : signal %d for process %d\\n\", sig, pcurrent->getPid());\n\n\tif (current->sigfn[sig] == (void*) SIG_IGN) {\n\t\tclear_signal(&(current->signal), sig);\n\t}\n\telse if (current->sigfn[sig] == (void*) SIG_DFL) {\n\t\tswitch(sig) {\n\t\t\tcase SIGHUP : case SIGINT : case SIGQUIT : \n\t\t\t\tasm(\"mov %0, %%eax; mov %%eax, %%cr3\"::\"m\"(current->regs.cr3));\n\t\t\t\tpcurrent->exit();\n\t\t\t\tbreak;\n\t\t\tcase SIGCHLD : \n\t\t\t\tbreak;\n\t\t\tdefault :\n\t\t\t\tclear_signal(&(current->signal), sig);\n\t\t}\n\t}\n\telse {\n\n\t\tesp = (u32*) current->regs.esp - 20;\n\n\t\tasm(\"mov %0, %%eax; mov %%eax, %%cr3\"::\"m\"(current->regs.cr3));\n\t\t\n\t\t// Code assembleur qui appelle sys_sigreturn() \n\t\tesp[19] = 0x0030CD00;\n\t\tesp[18] = 0x00000EB8;\n\n\t\t// Sauvegarde des registres \n\t\tesp[17] = current->kstack.esp0;\n\t\tesp[16] = current->regs.ss;\n\t\tesp[15] = current->regs.esp;\n\t\tesp[14] = current->regs.eflags;\n\t\tesp[13] = current->regs.cs;\n\t\tesp[12] = current->regs.eip;\n\t\tesp[11] = current->regs.eax;\n\t\tesp[10] = current->regs.ecx;\n\t\tesp[9] = current->regs.edx;\n\t\tesp[8] = current->regs.ebx;\n\t\tesp[7] = current->regs.ebp;\n\t\tesp[6] = current->regs.esi;\n\t\tesp[5] = current->regs.edi;\n\t\tesp[4] = current->regs.ds;\n\t\tesp[3] = current->regs.es;\n\t\tesp[2] = current->regs.fs;\n\t\tesp[1] = current->regs.gs;\n\n\t\t// Adresse de retour pour %eip \n\t\tesp[0] = (u32) &esp[18];\n\n\n\t\tcurrent->regs.esp = (u32) esp;\n\t\tcurrent->regs.eip = (u32) current->sigfn[sig];\n\n\t\t// Efface le signal et retablit le handler par defaut *\n\t\tcurrent->sigfn[sig] = (void*) SIG_DFL;\n\t\tif (sig != SIGCHLD)\n\t\t\tclear_signal(&(current->signal), sig);\n\t}\n\n\treturn 0;\n}\n\n\n}"
  },
  {
    "path": "src/kernel/arch/x86/x86.h",
    "content": "#ifndef __X86__\n#define __X86__\n\n#include <runtime/types.h>\n\n#define IDTSIZE\t\t0xFF\t/* nombre max. de descripteurs dans la table */\n#define GDTSIZE\t\t0xFF\t/* nombre max. de descripteurs dans la table */\n\n#define IDTBASE\t\t0x00000000\t/* addr. physique ou doit resider la IDT */\n#define GDTBASE\t\t0x00000800\t/* addr. physique ou doit resider la gdt */\n\n#define INTGATE  0x8E00\t\t/* utilise pour gerer les interruptions */\n#define TRAPGATE 0xEF00\t\t/* utilise pour faire des appels systemes */\n\n#define\tKERN_PDIR\t\t\t0x00001000\n#define\tKERN_STACK\t\t\t0x0009FFF0\n#define\tKERN_BASE\t\t\t0x00100000\n#define KERN_PG_HEAP\t\t0x00800000\n#define KERN_PG_HEAP_LIM\t0x10000000\n#define KERN_HEAP\t\t\t0x10000000\n#define KERN_HEAP_LIM\t\t0x40000000\n\n#define\tUSER_OFFSET \t\t0x40000000\n#define\tUSER_STACK \t\t\t0xE0000000\n\t\n#define KERN_PG_1\t\t\t0x400000\n#define KERN_PG_1_LIM \t\t0x800000\n\n#define\tVADDR_PD_OFFSET(addr)\t((addr) & 0xFFC00000) >> 22\n#define\tVADDR_PT_OFFSET(addr)\t((addr) & 0x003FF000) >> 12\n#define\tVADDR_PG_OFFSET(addr)\t(addr) & 0x00000FFF\n#define PAGE(addr)\t\t(addr) >> 12\n\n#define\tPAGING_FLAG \t\t0x80000000\t/* CR0 - bit 31 */\n#define PSE_FLAG\t\t\t0x00000010\t/* CR4 - bit 4  */\n\n#define PG_PRESENT\t\t\t0x00000001\t/* page directory / table */\n#define PG_WRITE\t\t\t0x00000002\n#define PG_USER\t\t\t\t0x00000004\n#define PG_4MB\t\t\t\t0x00000080\n\n#define\tPAGESIZE \t\t\t4096\n#define\tRAM_MAXSIZE\t\t\t0x100000000\n#define\tRAM_MAXPAGE\t\t\t0x100000\n\n/* Descripteur de segment */\nstruct gdtdesc {\n\tu16 lim0_15;\n\tu16 base0_15;\n\tu8 base16_23;\n\tu8 acces;\n\tu8 lim16_19:4;\n\tu8 other:4;\n\tu8 base24_31;\n} __attribute__ ((packed));\n\n/* Registre GDTR */\nstruct gdtr {\n\tu16 limite;\n\tu32 base;\n} __attribute__ ((packed));\n\nstruct tss {\n\tu16 previous_task, __previous_task_unused;\n\tu32 esp0;\n\tu16 ss0, __ss0_unused;\n\tu32 esp1;\n\tu16 ss1, __ss1_unused;\n\tu32 esp2;\n\tu16 ss2, __ss2_unused;\n\tu32 cr3;\n\tu32 eip, eflags, eax, ecx, edx, ebx, esp, ebp, esi, edi;\n\tu16 es, __es_unused;\n\tu16 cs, __cs_unused;\n\tu16 ss, __ss_unused;\n\tu16 ds, __ds_unused;\n\tu16 fs, __fs_unused;\n\tu16 gs, __gs_unused;\n\tu16 ldt_selector, __ldt_sel_unused;\n\tu16 debug_flag, io_map;\n} __attribute__ ((packed));\n\n/* Descripteur de segment */\nstruct idtdesc {\n\tu16 offset0_15;\n\tu16 select;\n\tu16 type;\n\tu16 offset16_31;\n} __attribute__ ((packed));\n\n/* Registre IDTR */\nstruct idtr {\n\tu16 limite;\n\tu32 base;\n} __attribute__ ((packed));\n\ntypedef struct\n{\n\tu32 edi, esi, ebp, esp, ebx, edx, ecx, eax;\n\tu32 ds, es, fs, gs;\n\tu32 which_int, err_code;\n\tu32 eip, cs, eflags, user_esp, user_ss;\n} __attribute__((packed)) regs_t;\n\ntypedef void (*int_desc)(void);\n\nextern \"C\" {\n\tvoid init_gdt_desc(u32, u32, u8, u8, struct gdtdesc *);\n\tvoid init_gdt(void);\n\tvoid init_idt_desc(u16, u32, u16, struct idtdesc *);\n\tvoid init_idt(void);\n\tvoid init_pic(void);\n\tint install_irq(unsigned int num,unsigned int irq);\n\tvoid switch_to_task(process_st* current, int mode);\n\textern tss \t\tdefault_tss;\n\tu32 cpu_vendor_name(char *name);\n\tint dequeue_signal(int);\n\tint handle_signal(int);\n}\n\n#endif\n"
  },
  {
    "path": "src/kernel/arch/x86/x86int.asm",
    "content": "extern isr_default_int, do_syscalls, isr_schedule_int\n\n\n%macro\tSAVE_REGS 0\n\tpushad \n\tpush ds\n\tpush es\n\tpush fs\n\tpush gs \n\tpush ebx\n\tmov bx,0x10\n\tmov ds,bx\n\tpop ebx\n%endmacro\n\n%macro\tRESTORE_REGS 0\n\tpop gs\n\tpop fs\n\tpop es\n\tpop ds\n\tpopad\n%endmacro\n\n%macro\tINTERRUPT 1\nglobal _asm_int_%1\n_asm_int_%1:\n\tSAVE_REGS\n\tpush %1\n\tcall isr_default_int\n\tpop eax\t;;a enlever sinon\n\tmov al,0x20\n\tout 0x20,al\n\tRESTORE_REGS\n\tiret\n%endmacro\n\nextern isr_GP_exc, isr_PF_exc \nglobal _asm_syscalls, _asm_exc_GP, _asm_exc_PF\n_asm_syscalls:\n\tSAVE_REGS\n\tpush eax                 ; transmission du numero d'appel\n\tcall do_syscalls\n\tpop eax\n\tcli\n\tsti\n\tRESTORE_REGS\n\tiret\n\n\n_asm_exc_GP:\n\tSAVE_REGS\n\tcall isr_GP_exc\n\tRESTORE_REGS\n\tadd esp,4\n\tiret\n\n_asm_exc_PF:\n\tSAVE_REGS\n\tcall isr_PF_exc\n\tRESTORE_REGS\n\tadd esp,4\n\tiret\n\nglobal _asm_schedule\n_asm_schedule:\n\tSAVE_REGS\n\tcall isr_schedule_int\n\tmov al,0x20\n\tout 0x20,al\n\tRESTORE_REGS\n\tiret\n\nINTERRUPT 1\nINTERRUPT 2\n"
  },
  {
    "path": "src/kernel/config.h",
    "content": "#ifndef CONFIG_H\n#define CONFIG_H\n\n#define KERNEL_NAME\t\t\"devos\"\t\t/* kernel name */\n#define KERNEL_VERSION\t\"1\"\t\t/* kernel version */\n#define KERNEL_DATE\t\t__DATE__\n#define KERNEL_TIME\t\t__TIME__\n#define KERNEL_LICENCE\t\"Apache License\"\t/* license */\n#define KERNEL_COMPUTERNAME\t\"test-pc\"\t/* default name for the machine */\n\n/* identifiant du processeur */\n#ifdef __x86__\n#define KERNEL_PROCESSOR_IDENTIFIER \"x86\"\n#else\n#define KERNEL_PROCESSOR_IDENTIFIER \"(null)\"\n#endif\n\n/* max open file */\n#define CONFIG_MAX_FILE\t32\n\n#endif\n"
  },
  {
    "path": "src/kernel/core/Makefile",
    "content": "OBJS:=  $(OBJS) core/class.o core/elf_loader.o core/file.o \\\n\tcore/filesystem.o core/kernel.o core/api_posix.o\\\n\tcore/process.o core/syscalls.o core/device.o core/system.o \\\n\tcore/env.o core/user.o core/modulelink.o core/socket.o\n\t\n"
  },
  {
    "path": "src/kernel/core/api/dev/clock.h",
    "content": "#ifndef __API_CLOCK__\r\n#define __API_CLOCK__\r\n\r\ntypedef unsigned int clock_d;\r\n\r\nstruct clock_info{\r\n\tclock_d\t\th;\r\n\tclock_d\t\tm;\r\n\tclock_d\t\ts;\r\n\t\r\n\tclock_d\t\tday;\r\n\tclock_d\t\tmonth;\r\n\tclock_d\t\tyear;\r\n};\r\n\r\n#define API_CLOCK_GET_INFO\t\t0x6122\r\n\r\n#endif\r\n"
  },
  {
    "path": "src/kernel/core/api/dev/fb.h",
    "content": "#ifndef __API_FB__\r\n#define __API_FB__\r\n\r\nstruct fb_info{\r\n\tunsigned int\t\tw;\t//largeur\r\n\tunsigned int\t\th;\t//hauteur\r\n\tchar\t\t\t\tbpp;\t//bit per pixel\r\n\tchar\t\t\t\tstate;\t//etat de la carte\r\n\tunsigned int*\t\tvmem;\t//video memory\r\n};\r\n\r\nenum{\r\n\tFB_NOT_ACTIVE=0,\r\n\tFB_ACTIVE=1,\r\n};\r\n\r\n#define API_FB_IS_AVAILABLE\t\t\t0x801\r\n#define API_FB_GET_INFO\t\t\t\t0x802\t//info actuel\r\n#define API_FB_GET_BINFO\t\t\t0x803\t//meilleur info\r\n#define API_FB_SET_INFO\t\t\t\t0x804\r\n\r\n\r\n#endif\r\n"
  },
  {
    "path": "src/kernel/core/api/dev/ioctl.h",
    "content": "#ifndef __API_IOCTL__\r\n#define __API_IOCTL__\r\n\r\n\r\n#define DEV_GET_TYPE\t\t0x01\t/* Renvoie le type de peripherique */\r\n#define\tDEV_GET_STATE\t\t0x02\t/* renvoie l'etat du peripherique */\r\n#define\tDEV_GET_FORMAT\t\t0x03\t/* renvoie le format du peripherique */\r\n\r\n//Type de peripherique :\r\n#define DEV_TYPE_TTY 0x01\r\n#define DEV_TYPE_DISK 0x02\r\n#define DEV_TYPE_FB 0x03\r\n#define DEV_TYPE_HID 0x04 //Added by NoMaitener (aka William). HID stand for Human Interface Device\r\n\r\n//Format du peripherique\r\n#define DEV_FORMAT_CHAR 0x01\r\n#define DEV_FORMAT_BLOCK 0x02\r\n#define DEV_FORMAT_FB 0x03\r\n\r\n//Etat du peripherique\r\n#define DEV_STATE_OK 0x01\r\n#define DEV_STATE_NOTREADY 0x02 //Added by NoMaitener (aka William). Discuss here of \"NOTREADY\"\r\n\r\n\r\n#endif\r\n"
  },
  {
    "path": "src/kernel/core/api/dev/ipc.h",
    "content": "#ifndef __API_IPC__\n#define __API_IPC__\n\n#define STDIPC_FILENO\t3\n#define SIGIPC\t\tSIGUSR1\n\n\n//iotcl\n#define API_TTY_SWITCH_SCREEN\t0xff52\n\n\n\n#endif\n"
  },
  {
    "path": "src/kernel/core/api/dev/keyboard.h",
    "content": "#ifndef __API_KEYBOARD__\r\n#define __API_KEYBOARD__\r\n\r\n\r\n//keyboard\r\nenum {\r\n    KEY_TAB = 7,\r\n    KEY_BACKSPACE = 8,\r\n    KEY_ENTER = 10,\r\n    KEY_ESCAPE = 27,\r\n    KEY_F1 = 255,\r\n    KEY_F2 = 254,\r\n    KEY_F3 = 253,\r\n    KEY_F4 = 252,\r\n    KEY_F5 = 251,\r\n    KEY_F6 = 250,\r\n    KEY_F7 = 249,\r\n    KEY_F8 = 248,\r\n    KEY_F9 = 247,\r\n    KEY_F10 = 246,\r\n    KEY_F11 = 245,\r\n    KEY_F12 = 244\r\n};\r\n\r\n#define TABLE_KEYBOARD_SIZE\t\t\t388\r\n\r\n#define API_KEYBOARD_SET_TABLE\t\t0x4122\r\n\r\n#endif\r\n"
  },
  {
    "path": "src/kernel/core/api/dev/proc.h",
    "content": "#ifndef __API_PROC__\r\n#define __API_PROC__\r\n\r\nstruct proc_info{\r\n\tchar\t\t\t\tname[32];\r\n\tunsigned int\t\tpid;\r\n\tunsigned int\t\ttid;\r\n\tunsigned char\t\tstate;\r\n\tunsigned int\t\tvmem;\r\n\tunsigned int\t\tpmem;\r\n};\r\n\r\nenum{\r\n\tPROC_STATE_RUN=0,\r\n\tPROC_STATE_ZOMBIE=1,\r\n\tPROC_STATE_THREAD=2,\r\n};\r\n\r\n#define API_PROC_GET_PID\t\t0x5200\r\n#define API_PROC_GET_INFO\t\t0x5201\r\n\r\n#endif\r\n"
  },
  {
    "path": "src/kernel/core/api/dev/tty.h",
    "content": "#ifndef __API_TTY__\r\n#define __API_TTY__\r\n\r\n#include <api/dev/keyboard.h>\r\n\r\n#define TTY_NAME_LEN\t16\r\n\r\n//tty info\r\nstruct tty_info_static{\r\n\tchar\t\t\tname[TTY_NAME_LEN];\r\n\tchar\t\t\tstate;\r\n\tchar\t\t\ttype;\r\n\tunsigned int\tflags;\r\n};\r\n\r\nstruct tty_info_moving{\r\n\tunsigned int\tx;\r\n\tunsigned int\ty;\r\n\tunsigned int\tattrf;\r\n\tunsigned int\tattrb;\r\n};\r\n\r\n\r\n//tty type\r\nenum {\r\n    TTY_TYPE_IOSTD=0,\r\n\tTTY_TYPE_SERIAL=1,\r\n\tTTY_TYPE_SCREEN=2,\r\n\tTTY_TYPE_VIRTUAL=3,\r\n\tTTY_TYPE_GUI=4\r\n};\r\n\r\n//tty state\r\nenum {\r\n    TTY_STATE_RUN=0,\r\n\tTTY_STATE_SWITCH=1,\r\n\tTTY_STATE_ERROR=2,\r\n\tTTY_STATE_PAUSE=3\r\n};\r\n\r\n\r\nenum TTY_Colour\r\n{\r\n\tBlack       =0,\r\n\tBlue        =1,\r\n\tGreen       =2,\r\n\tCyan        =3,\r\n\tRed         =4,\r\n\tMagenta     =5,\r\n\tOrange      =6,\r\n\tLightGrey   =7,\r\n\tDarkGrey    =8,\r\n\tLightBlue   =9,\r\n\tLightGreen  =10,\r\n\tLightCyan   =11,\r\n\tLightRed    =12,\r\n\tLightMagenta=13,\r\n\tYellow      =14,\r\n\tWhite       =15\r\n};\r\n\t\t  \r\n//iotcl\r\n#define API_TTY_SWITCH_SCREEN\t0xff52\r\n#define API_TTY_CLEAR_SCREEN\t0xff53\r\n#define API_TTY_GET_SINFO\t\t0xff54\r\n#define API_TTY_GET_MINFO\t\t0xff55\r\n#define API_TTY_SET_MINFO\t\t0xff56\r\n\r\n#endif\r\n"
  },
  {
    "path": "src/kernel/core/api/kernel/syscall.h",
    "content": "\n#ifndef _OS_SYSCALL_H_\n#define _OS_SYSCALL_H_\n\n\nint syscall0( int number );\nint syscall1( int number, unsigned int p1 );\nint syscall2( int number, unsigned int p1, unsigned int p2 );\nint syscall3( int number, unsigned int p1, unsigned int p2, unsigned int p3 );\nint syscall4( int number, unsigned int p1, unsigned int p2, unsigned int p3, unsigned int p4 );\nint syscall5( int number, unsigned int p1, unsigned int p2, unsigned int p3, unsigned int p4, unsigned int p5 );\n\n#endif\n"
  },
  {
    "path": "src/kernel/core/api/kernel/syscall_table.h",
    "content": "\n#ifndef _OS_SYSCALL_TABLE_H_\n#define _OS_SYSCALL_TABLE_H_\n\n\n#define NOT_DEFINED 0\n\nenum {\n\tSYS_rewinddir\t\t\t=NOT_DEFINED,\n\tSYS_sbrk\t\t\t\t=45,\t//\t(count)\n\tSYS_fork\t\t\t\t=NOT_DEFINED,\n\tSYS_write\t\t\t\t=4,\t\t//\t(fd,buffer,count)\n\tSYS_read\t\t\t\t=3,\t\t//\t(fd,buffer,count)\n\tSYS_open\t\t\t\t=5,\t\t//\t(filename,flag)\n\tSYS_close\t\t\t\t=6,\t\t//\t(fd)\n\tSYS_execve\t\t\t\t=11,\t\t//\t(filename,argv,envp )\n\tSYS_dup\t\t\t\t\t=NOT_DEFINED,\n\tSYS_dup2\t\t\t\t=38,\n\tSYS_pwrite\t\t\t\t=NOT_DEFINED,\n\tSYS_pread\t\t\t\t=NOT_DEFINED,\n\tSYS_exit\t\t\t\t=1,\t//\t(status)\n\tSYS_getdents\t\t\t=89,\n\tSYS_fchdir\t\t\t\t=NOT_DEFINED,\n\tSYS_isatty\t\t\t\t=NOT_DEFINED,\n\tSYS_lseek\t\t\t\t=19,\n\tSYS_unlink\t\t\t\t=17,\n\tSYS_link\t\t\t\t=18,\n\tSYS_readlink\t\t\t=19,\n\tSYS_sleep_thread\t\t=NOT_DEFINED,\n\tSYS_access\t\t\t\t=NOT_DEFINED,\n\tSYS_chdir\t\t\t\t=12,\n\tSYS_getpid\t\t\t\t=20,\n\tSYS_getuid\t\t\t\t=70,\n\tSYS_gettid\t\t\t\t=NOT_DEFINED,\n\tSYS_rmdir\t\t\t\t=NOT_DEFINED,\n\tSYS_symlink\t\t\t\t=9,\t\t//\t(oldname,newname)\n\tSYS_fcntl\t\t\t\t=NOT_DEFINED,\n\tSYS_get_system_time\t\t=NOT_DEFINED,\n\tSYS_stat\t\t\t\t=106,\n\tSYS_fstat\t\t\t\t=NOT_DEFINED,\n\tSYS_stime\t\t\t\t=NOT_DEFINED,\n\tSYS_mkdir\t\t\t\t=15,\n\tSYS_ioctl\t\t\t\t=54,\t//\t(fd,adress,buffer)\n\tSYS_select\t\t\t\t=NOT_DEFINED,\n\tSYS_mount\t\t\t\t=13,\n\tSYS_unmount\t\t\t\t=14,\n\tSYS_lstat\t\t\t\t=NOT_DEFINED,\n\tSYS_utime\t\t\t\t=NOT_DEFINED,\n\tSYS_wait4\t\t\t\t=7,\n\tSYS_socket\t\t\t\t=NOT_DEFINED,\n\tSYS_connect\t\t\t\t=NOT_DEFINED,\n\tSYS_sigaction\t\t\t=67,\n\tSYS_kill\t\t\t\t=37,\n\tSYS_sigprocmask\t\t\t=NOT_DEFINED,\n\tSYS_dbprintf\t\t\t=NOT_DEFINED,\n\tSYS_create_semaphore\t=NOT_DEFINED,\n\tSYS_delete_semaphore\t=NOT_DEFINED,\n\tSYS_lock_semaphore\t\t=NOT_DEFINED,\n\tSYS_unlock_semaphore\t=NOT_DEFINED,\n\tSYS_create_thread\t\t=101,\n\tSYS_wake_up_thread\t\t=NOT_DEFINED,\n\tSYS_kill_thread\t\t\t=NOT_DEFINED,\n\tSYS_mmap\t\t\t\t=55,\n\t\n\tSYS_loadmod\t\t\t\t=71,\n\tSYS_login\t\t\t\t=72,\n\tSYS_newuser\t\t\t\t=73,\n};\n\n\n\n\n#endif \n"
  },
  {
    "path": "src/kernel/core/api.h",
    "content": "#ifndef API_H\n#define API_H\n\n//posix\nvoid call_open();\nvoid call_close();\nvoid call_read();\nvoid call_write();\nvoid call_sbrk();\nvoid call_ioctl();\nvoid call_exit();\nvoid call_execv();\nvoid call_symlink();\nvoid call_getdents();\nvoid call_wait();\nvoid call_dup2();\nvoid call_fork();\nvoid call_chdir();\nvoid call_mmap();\n\n#endif\n"
  },
  {
    "path": "src/kernel/core/api_posix.cc",
    "content": "#include <os.h>\n\n\n/*\n *\tu32 open(char* name,u32 flag);\n */\nvoid call_open(){\n\tchar*name=(char*)arch.getArg(0);\n\tu32 flag=arch.getArg(1);\n\t\n\tProcess* p=arch.pcurrent;\n\tif (p==NULL){\n\t\tarch.setRet((u32)-1);\n\t\treturn;\n\t}\n\t\n\tFile* fp=fsm.path(name);\n\tfp->open(flag);\n\tu32 fd=p->addFile(fp,flag);\n\t\n\tarch.setRet(fd);\n}\n\n/*\n *\tvoid close(u32 fd);\n */\nvoid call_close(){\n\tu32 fd=arch.getArg(0);\n\tProcess* p=arch.pcurrent;\n\tif (p==NULL){\n\t\tarch.setRet((u32)-1);\n\t\treturn;\n\t}\n\t\t\n\tFile* fp=p->getFile(fd);\n\tif (fp==NULL){\n\t\treturn;\n\t}\n\t\n\tfp->close();\n\tp->deleteFile(fd);\n}\n\n/*\n *\tu32 read(u32 fd,char* buf,u32 size);\n */\nvoid call_read(){\n\tu32 fd=arch.getArg(0);\n\tu8*buf=(u8*)arch.getArg(1);\n\tu32 size=arch.getArg(2);\n\t\n\tProcess* p=arch.pcurrent;\n\tif (p==NULL){\n\t\tarch.setRet((u32)-1);\n\t\treturn;\n\t}\n\t\t\n\tFile* fp=p->getFile(fd);\n\tif (fp==NULL){\n\t\tarch.setRet((u32)-1);\n\t\treturn;\n\t}\n\topenfile* info = p->getFileInfo(fd);\n\tu32 ret=fp->read(info->ptr,buf,size);\n\tinfo->ptr=info->ptr + ret;\n\tarch.setRet(ret);\n}\n\n/*\n *\tu32 write(u32 fd,char* buf,u32 size);\n */\nvoid call_write(){\n\tu32 fd=arch.getArg(0);\n\tu8*buf=(u8*)arch.getArg(1);\n\tu32 size=arch.getArg(2);\n\t\n\tProcess* p=arch.pcurrent;\n\tif (p==NULL){\n\t\tarch.setRet((u32)-1);\n\t\treturn;\n\t}\n\t\t\n\tFile* fp=p->getFile(fd);\n\tif (fp==NULL){\n\t\tarch.setRet(-1);\n\t\treturn;\n\t}\n\topenfile* info = p->getFileInfo(fd);\n\tu32 ret=fp->write(info->ptr,buf,size);\n\tinfo->ptr=info->ptr + ret;\n\tarch.setRet(ret);\n}\n\n/*\n *\tu32 ioctl(u32 fd,u32 pos,char* buf);\n */\nvoid call_ioctl(){\n\tu32 fd=arch.getArg(0);\n\tu8*buf=(u8*)arch.getArg(2);\n\tu32 pos=arch.getArg(1);\n\t\n\tProcess* p=arch.pcurrent;\n\tif (p==NULL){\n\t\tarch.setRet((u32)-1);\n\t\treturn;\n\t}\n\t\t\n\tFile* fp=p->getFile(fd);\n\tif (fp==NULL){\n\t\tarch.setRet(-1);\n\t\treturn;\n\t}\n\t\n\tu32 ret=fp->ioctl(pos,buf);\n\tarch.setRet(ret);\n}\n\n/*\n *\tchar* sbrk(int size);\n */\nvoid call_sbrk(){\n\tint size;\n\tsize=arch.getArg(0);\n\tchar *ret;\n\tProcess* p=arch.pcurrent;\n\tprocess_st* current=p->getPInfo();\n\tret = current->e_heap;\n\n\tcurrent->e_heap += size;\n\t\n\tarch.setRet((u32)ret);\n\treturn;\n}\n\n\n/*\n *\tvoid exit(int code);\n */\nvoid call_exit(){\n\tint code;\n\tcode=arch.getArg(0);\n\t\n\tProcess* p=arch.pcurrent;\n\tp->exit();\n\treturn;\n}\n\n/*\n *\tint execv(const char* filename, char* const argv[], char* const envp[] );\n */\nvoid call_execv(){\n\tchar* filename,**argv,**envp;\n\tfilename=(char*)arch.getArg(0);\n\targv=(char**)arch.getArg(1);\n\tenvp=(char**)arch.getArg(2);\n\tint argc;\n\tchar **ap;\n\t\n\tap = argv;\n\targc = 0;\n\twhile (*ap++) \n\t\targc++;\n\t\t\n\tint ret=execv(filename,argc,argv);\n\tarch.setRet((u32)ret);\n\treturn;\n}\n\n\n/*\n *\tint symlink(const char* oldpath, const char* newpath);\n */\nvoid call_symlink(){\n\tchar* oldpath,*path;\n\toldpath=(char*)arch.getArg(0);\n\tpath=(char*)arch.getArg(1);\n\n\tint ret=fsm.link(oldpath,path);\n\tarch.setRet((u32)ret);\n\treturn;\n}\n\nstruct dirent {\n    u64\t d_ino;\n    char d_name[256];\n};\n\n/*\n *\tint getdents(int fd,dirrent* entry,int size);\n */\nvoid call_getdents(){\n\tdirent nentry;\n\tu32 fd=arch.getArg(0);\n\tdirent* entry=(dirent*)arch.getArg(1);\n\tint size=arch.getArg(2);\n\t\n\tProcess* p=arch.pcurrent;\n\tif (p==NULL){\n\t\tarch.setRet((u32)0);\n\t\treturn;\n\t}\n\t\n\tFile* fp=p->getFile(fd);\n\tif (fp==NULL){\n\t\tarch.setRet(0);\n\t\treturn;\n\t}\n\topenfile* info = p->getFileInfo(fd);\n\tint i=0;\n\tFile* child=fp->getChild();\n\twhile (child!=NULL){\n\t\tif (i==(info->ptr)){\n\t\t\t//io.print(\"readdir=%s  - size=%d  entry=%x\\n\",child->getName(),size,entry);\n\t\t\tnentry.d_ino=child->getInode();\n\t\t\tstrncpy(nentry.d_name,child->getName(),256);\n\t\t\tmemcpy((char*)entry,(char*)&nentry,size);\n\t\t\tinfo->ptr++;\n\t\t\tarch.setRet(1);\n\t\t\treturn;\n\t\t}\n\t\ti++;\n\t\tchild=child->getNext();\n\t}\n\tarch.setRet((u32)0);\n\treturn;\n}\n\n/*\n *\tint wait(int* status);\n */\nvoid call_wait(){\n\tu32*status=(u32*)arch.getArg(1);\n\t*status=0;\n\tProcess* p=arch.pcurrent;\n\tu32 ret=p->wait();\n\t//arch.setRet(ret);\n}\n\n/*\n *\tint dup2( int old_fd, int new_fd );\n */\nvoid call_dup2(){\n\tu32 oldfd=arch.getArg(0);\n\tu32 newfd=arch.getArg(1);\n\t//io.print(\"dup2 %d to %d\\n\",oldfd,newfd);\n\tu32 ret=newfd;\n\tProcess* p=arch.pcurrent;\n\tp->setFile((u32)newfd,p->getFile(oldfd),0, 0);\n\tarch.setRet((u32)ret);\n}\n\n/*\n *\tint fork();\n */\nvoid call_fork(){\n\tProcess* p=arch.pcurrent;\n\tint ret=p->fork();\n\tarch.setRet((u32)ret);\n}\n \n/*\n *\tint chdir(char* n);\n */\nvoid call_chdir(){\n\tchar* n;\n\tn=(char*)arch.getArg(0);\n\t\n\tProcess* p=arch.pcurrent;\n\tFile*f=fsm.path(n);\n\tif (f==NULL){\n\t\tarch.setRet((u32)-1);\n\t\treturn;\n\t}\n\t\n\tp->setCurrentDir(f);\n\tarch.setRet((u32)1);\n\treturn;\n}\n\n/*\n *\tvoid * mmap (void *addr,size_t len,int prot,int flags,int fd,off_t offset)\n */\nvoid call_mmap(){\n\tu32 fd=arch.getArg(3);\n\tu32 size=arch.getArg(0);\n\tu32 prot=0;\n\tu32 flags=0;\n\tu32 offset=0;\n\t\n\tProcess* p=arch.pcurrent;\n\tif (p==NULL){\n\t\tarch.setRet((u32)-1);\n\t\treturn;\n\t}\n\t\t\n\tFile* fp=p->getFile(fd);\n\tif (fp==NULL){\n\t\tarch.setRet((u32)-1);\n\t\treturn;\n\t}\n\topenfile* info = p->getFileInfo(fd);\n\tu32 ret=fp->mmap(size,flags,offset,prot);\n\tarch.setRet(ret);\n}\n"
  },
  {
    "path": "src/kernel/core/boot.h",
    "content": "#ifndef __MY_BOOT__\r\n#define __MY_BOOT__\r\n\r\n#include <runtime/types.h>\r\n\r\nstruct multiboot_info {\r\n\tu32 flags;\r\n\tu32 low_mem;\r\n\tu32 high_mem;\r\n\tu32 boot_device;\r\n\tu32 cmdline;\r\n\tu32 mods_count;\r\n\tu32 mods_addr;\r\n\tstruct {\r\n\t\tu32 num;\r\n\t\tu32 size;\r\n\t\tu32 addr;\r\n\t\tu32 shndx;\r\n\t} elf_sec;\r\n\tunsigned long mmap_length;\r\n\tunsigned long mmap_addr;\r\n\tunsigned long drives_length;\r\n\tunsigned long drives_addr;\r\n\tunsigned long config_table;\r\n\tunsigned long boot_loader_name;\r\n\tunsigned long apm_table;\r\n\tunsigned long vbe_control_info;\r\n\tunsigned long vbe_mode_info;\r\n\tunsigned long vbe_mode;\r\n\tunsigned long vbe_interface_seg;\r\n\tunsigned long vbe_interface_off;\r\n\tunsigned long vbe_interface_len;\r\n};\r\n\r\n\r\n\r\n/* VBE controller information.  */\r\nstruct vbe_controller\r\n{\r\n  unsigned char signature[4];\r\n  unsigned short version;\r\n  unsigned long oem_string;\r\n  unsigned long capabilities;\r\n  unsigned long video_mode;\r\n  unsigned short total_memory;\r\n  unsigned short oem_software_rev;\r\n  unsigned long oem_vendor_name;\r\n  unsigned long oem_product_name;\r\n  unsigned long oem_product_rev;\r\n  unsigned char reserved[222];\r\n  unsigned char oem_data[256];\r\n} __attribute__ ((packed));\r\n\r\n/* VBE mode information.  */\r\nstruct vbe_mode\r\n{\r\n  unsigned short mode_attributes;\r\n  unsigned char win_a_attributes;\r\n  unsigned char win_b_attributes;\r\n  unsigned short win_granularity;\r\n  unsigned short win_size;\r\n  unsigned short win_a_segment;\r\n  unsigned short win_b_segment;\r\n  unsigned long win_func;\r\n  unsigned short bytes_per_scanline;\r\n\r\n  /* >=1.2 */\r\n  unsigned short x_resolution;\r\n  unsigned short y_resolution;\r\n  unsigned char x_char_size;\r\n  unsigned char y_char_size;\r\n  unsigned char number_of_planes;\r\n  unsigned char bits_per_pixel;\r\n  unsigned char number_of_banks;\r\n  unsigned char memory_model;\r\n  unsigned char bank_size;\r\n  unsigned char number_of_image_pages;\r\n  unsigned char reserved0;\r\n\r\n  /* direct color */\r\n  unsigned char red_mask_size;\r\n  unsigned char red_field_position;\r\n  unsigned char green_mask_size;\r\n  unsigned char green_field_position;\r\n  unsigned char blue_mask_size;\r\n  unsigned char blue_field_position;\r\n  unsigned char reserved_mask_size;\r\n  unsigned char reserved_field_position;\r\n  unsigned char direct_color_mode_info;\r\n\r\n  /* >=2.0 */\r\n  unsigned long phys_base;\r\n  unsigned long reserved1;\r\n  unsigned short reversed2;\r\n\r\n  /* >=3.0 */\r\n  unsigned short linear_bytes_per_scanline;\r\n  unsigned char banked_number_of_image_pages;\r\n  unsigned char linear_number_of_image_pages;\r\n  unsigned char linear_red_mask_size;\r\n  unsigned char linear_red_field_position;\r\n  unsigned char linear_green_mask_size;\r\n  unsigned char linear_green_field_position;\r\n  unsigned char linear_blue_mask_size;\r\n  unsigned char linear_blue_field_position;\r\n  unsigned char linear_reserved_mask_size;\r\n  unsigned char linear_reserved_field_position;\r\n  unsigned long max_pixel_clock;\r\n\r\n  unsigned char reserved3[189];\r\n} __attribute__ ((packed));\r\n\r\n#endif"
  },
  {
    "path": "src/kernel/core/class.cc",
    "content": "#include <os.h>\n\n/*\nStatic objects\n*/\n\nIo \t\t\t\tio;\t\t\t/* Input/Output interface */\nArchitecture \tarch;\t\t/*\tCpu and architecture interface */\nVmm \t\t\tvmm;\t\t/*\tVirtual memory manager interface */\nFilesystem\t\tfsm;\t\t/*\tFilesystem interface */\nModule\t\t\tmodm;\t\t/* Module manager */\nSyscalls\t\tsyscall;\t/* Syscalls manager */\nSystem\t\t\tsys;\t\t/* System manager */\n"
  },
  {
    "path": "src/kernel/core/device.cc",
    "content": "#include <os.h>\n\n\n\nDevice::~Device(){\n\t\n}\n\nDevice::Device(char* n) : File(n,TYPE_DEVICE)\n{\n\tfsm.addFile(\"/dev\",this);\n}\n\nu32\tDevice::open(u32 flag){\n\treturn NOT_DEFINED;\n}\n\nu32\tDevice::close(){\n\treturn NOT_DEFINED;\n}\n\nu32\tDevice::read(u8* buffer,u32 size){\n\treturn NOT_DEFINED;\n}\n\nu32\tDevice::write(u8* buffer,u32 size){\n\treturn NOT_DEFINED;\n}\n\nu32\tDevice::ioctl(u32 id,u8* buffer){\n\treturn NOT_DEFINED;\n}\n\nu32\tDevice::remove(){\n\tdelete this;\n}\n\nvoid Device::scan(){\n\n}\n\n"
  },
  {
    "path": "src/kernel/core/device.h",
    "content": "#ifndef DEVICE_H\n#define DEVICE_H\n\n#include <core/file.h>\n#include <runtime/list.h>\n\n\nclass Device : public File\n{\n\tpublic:\n\t\tDevice(char* n);\n\t\t~Device();\n\t\t\n\t\tvirtual u32\t\topen(u32 flag);\n\t\tvirtual u32\t\tclose();\n\t\tvirtual u32\t\tread(u8* buffer,u32 size);\n\t\tvirtual u32\t\twrite(u8* buffer,u32 size);\n\t\tvirtual u32\t\tioctl(u32 id,u8* buffer);\n\t\tvirtual u32\t\tremove();\n\t\tvirtual void\tscan();\n\t\t\n\t\t\n\tprotected:\n\n};\n\n#endif"
  },
  {
    "path": "src/kernel/core/elf_loader.cc",
    "content": "#include <os.h>\n\n/*\nChargeur de module externe au format elf32 :\npour le moment compil en static sans librairies partags */\n\n\nchar* __default_proc_name=\"_proc_\";\t/* nom par default avec en plus un nombre */\nchar \tnb_default='0';\n\n \n/* \n * Teste si le fichier dont l'adresse est passee en argument\n * est au format ELF\n */\nint is_elf(char *file)\n{\n\tElf32_Ehdr *hdr;\n\n\thdr = (Elf32_Ehdr *) file;\n\tif (hdr->e_ident[0] == 0x7f && hdr->e_ident[1] == 'E'\n\t    && hdr->e_ident[2] == 'L' && hdr->e_ident[3] == 'F')\n\t\treturn RETURN_OK;\n\telse\n\t\treturn ERROR_PARAM;\n}\n\n/*\n *\tCharge le fichier elf dans la memoire virtuelle et renvoie l'adresse de depart\n */\nu32 load_elf(char *file,process_st *proc)\n{\n\tchar *p;\n\tu32 v_begin, v_end;\n\tElf32_Ehdr *hdr;\n\tElf32_Phdr *p_entry;\n\tElf32_Scdr *s_entry;\n\tint i, pe;\n\n\thdr = (Elf32_Ehdr *) file;\n\tp_entry = (Elf32_Phdr *) (file + hdr->e_phoff);\n\n\ts_entry= (Elf32_Scdr*) (file + hdr->e_shoff);\n\t\n\tif (is_elf(file)==ERROR_PARAM) {\n\t\tio.print(\"INFO: load_elf(): file not in ELF format !\\n\");\n\t\treturn 0;\n\t}\n\t\n\tfor (pe = 0; pe < hdr->e_phnum; pe++, p_entry++) {\t/* Read each entry */\n\n\t\tif (p_entry->p_type == PT_LOAD) {\n\t\t\tv_begin = p_entry->p_vaddr;\n\t\t\tv_end = p_entry->p_vaddr + p_entry->p_memsz;\n\t\t\tif (v_begin < USER_OFFSET) {\n\t\t\t\tio.print (\"INFO: load_elf(): can't load executable below %p\\n\", USER_OFFSET);\n\t\t\t\treturn 0;\n\t\t\t}\n\n\t\t\tif (v_end > USER_STACK) {\n\t\t\t\tio.print (\"INFO: load_elf(): can't load executable above %p\\n\", USER_STACK);\n\t\t\t\treturn 0;\n\t\t\t}\n\n\t\t\t// Description de la zone exec + rodata \n\t\t\tif (p_entry->p_flags == PF_X + PF_R) {\t\n\t\t\t\tproc->b_exec = (char*) v_begin;\n\t\t\t\tproc->e_exec = (char*) v_end;\n\t\t\t}\n\n\t\t\t// Description de la zone bss \n\t\t\tif (p_entry->p_flags == PF_W + PF_R) {\t\n\t\t\t\tproc->b_bss = (char*) v_begin;\n\t\t\t\tproc->e_bss = (char*) v_end;\n\t\t\t}\n\t\t\t//io.print(\"elf : %x to %x \\n\",(file + p_entry->p_offset),v_begin);\n\t\t\tmemcpy((char *) v_begin, (char *) (file + p_entry->p_offset), p_entry->p_filesz);\n\t\t\tif (p_entry->p_memsz > p_entry->p_filesz)\n\t\t\t\tfor (i = p_entry->p_filesz, p = (char *) p_entry->p_vaddr; i < (int)(p_entry->p_memsz); i++)\n\t\t\t\t\tp[i] = 0;\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t}\n\t}\n\t/* Return program entry point */\n\t\n\treturn hdr->e_entry;\n}\n\n/*\n *\tCharge un fichier en creant un nouveau processus\n */\nint execv(char* file,int argc,char** argv){\n\tchar* map_elf=NULL;\n\tFile* fp=fsm.path(file);\n\tif (fp==NULL)\n\t\treturn ERROR_PARAM;\n\t\n\tmap_elf=(char*)kmalloc(fp->getSize());\n\tfp->open(NO_FLAG);\n\tfp->read(0,(u8*)map_elf,fp->getSize());\n\tfp->close();\n\t\n\tchar* name;\n\t__default_proc_name[strlen(__default_proc_name)-1]=nb_default;\n\tnb_default++;\n\tif (argc<=0)\n\t\tname=__default_proc_name;\n\telse\n\t\tname=argv[0];\n\t//io.print(\"exec %s > %s\\n\",file,name);\n\n\tProcess* proc=new Process(name);\n\tproc->create(map_elf,argc,argv);\n\tkfree(map_elf);\n\treturn (int)proc->getPid();\n}\n\n/*\n *\tCharge un module\n */\nvoid execv_module(u32 entry,int argc,char** argv){\n\tchar* name;\n\t__default_proc_name[strlen(__default_proc_name)-1]=nb_default;\n\tnb_default++;\n\tif (argc<=0)\n\t\tname=__default_proc_name;\n\telse\n\t\tname=argv[0];\n\t\n\tProcess* proc=new Process(name);\n\tproc->create((char*)entry,argc,argv);\n}\n\n\n"
  },
  {
    "path": "src/kernel/core/elf_loader.h",
    "content": "#ifndef ELF_H\n#define ELF_H\n\n#include <runtime/types.h>\n#include <process.h>\n\n/*\n * ELF HEADER\n */\ntypedef struct {\n\tunsigned char e_ident[16];\t/* ELF identification */\n\tu16 e_type;\t\t/* 2 (exec file) */\n\tu16 e_machine;\t\t/* 3 (intel architecture) */\n\tu32 e_version;\t\t/* 1 */\n\tu32 e_entry;\t\t/* starting point */\n\tu32 e_phoff;\t\t/* program header table offset */\n\tu32 e_shoff;\t\t/* section header table offset */\n\tu32 e_flags;\t\t/* various flags */\n\tu16 e_ehsize;\t\t/* ELF header (this) size */\n\n\tu16 e_phentsize;\t/* program header table entry size */\n\tu16 e_phnum;\t\t/* number of entries */\n\n\tu16 e_shentsize;\t/* section header table entry size */\n\tu16 e_shnum;\t\t/* number of entries */\n\n\tu16 e_shstrndx;\t\t/* index of the section name string table */\n} Elf32_Ehdr;\n\n/* \n * ELF identification\n */\n#define\tEI_MAG0\t\t0\n#define\tEI_MAG1\t\t1\n#define\tEI_MAG2\t\t2\n#define\tEI_MAG3\t\t3\n#define\tEI_CLASS\t4\n#define\tEI_DATA\t\t5\n#define\tEI_VERSION\t6\n#define EI_PAD\t\t7\n\n/* EI_MAG */\n#define\tELFMAG0\t\t0x7f\n#define\tELFMAG1\t\t'E'\n#define\tELFMAG2\t\t'L'\n#define\tELFMAG3\t\t'F'\n\n/* EI_CLASS */\n#define\tELFCLASSNONE\t0\t/* invalid class */\n#define\tELFCLASS32\t1\t/* 32-bit objects */\n#define\tELFCLASS64\t2\t/* 64-bit objects */\n\n/* EI_DATA */\n#define\tELFDATANONE\t0\t/* invalide data encoding */\n#define\tELFDATA2LSB\t1\t/* least significant byte first (0x01020304 is 0x04 0x03 0x02 0x01) */\n#define\tELFDATA2MSB\t2\t/* most significant byte first (0x01020304 is 0x01 0x02 0x03 0x04) */\n\n/* EI_VERSION */\n#define\tEV_CURRENT\t1\n#define\tELFVERSION\tEV_CURRENT\n\n/* \n * PROGRAM HEADER \n */\ntypedef struct {\n\tu32 p_type;\t\t/* type of segment */\n\tu32 p_offset;\n\tu32 p_vaddr;\n\tu32 p_paddr;\n\tu32 p_filesz;\n\tu32 p_memsz;\n\tu32 p_flags;\n\tu32 p_align;\n} Elf32_Phdr;\n\n/* p_type */\n#define\tPT_NULL             0\n#define\tPT_LOAD             1\n#define\tPT_DYNAMIC          2\n#define\tPT_INTERP           3\n#define\tPT_NOTE             4\n#define\tPT_SHLIB            5\n#define\tPT_PHDR             6\n#define\tPT_LOPROC  0x70000000\n#define\tPT_HIPROC  0x7fffffff\n\n/* p_flags */\n#define PF_X\t0x1\n#define PF_W\t0x2\n#define PF_R\t0x4\n\n\n\n\n\n\n\n\n\nenum eElfSectionTypes {\n\tSHT_NULL,\t//0\n\tSHT_PROGBITS,\t//1\n\tSHT_SYMTAB,\t//2\n\tSHT_STRTAB,\t//3\n\tSHT_RELA,\t//4\n\tSHT_HASH,\t//5\n\tSHT_DYNAMIC,\t//6\n\tSHT_NOTE,\t//7\n\tSHT_NOBITS,\t//8\n\tSHT_REL,\t//9\n\tSHT_SHLIB,\t//A\n\tSHT_DYNSYM,\t//B\n\tSHT_LAST,\t//C\n\tSHT_LOPROC = 0x70000000,\n\tSHT_HIPROC = 0x7fffffff,\n\tSHT_LOUSER = 0x80000000,\n\tSHT_HIUSER = 0xffffffff\n};\n\n\ntypedef struct {\n\tu32\t\tname;\n\tu32\ttype;\n\tu32\tflags;\n\tu32\taddress;\n\tu32\toffset;\n\tu32\tsize;\n\tu32\tlink;\n\tu32\tinfo;\n\tu32\taddralign;\n\tu32\tentsize;\n} Elf32_Scdr;\n\n\n\n\n\nenum {\n\tR_386_NONE=0,\t// none\n\tR_386_32,\t// S+A\n\tR_386_PC32,\t// S+A-P\n\tR_386_GOT32,\t// G+A-P\n\tR_386_PLT32,\t// L+A-P\n\tR_386_COPY,\t// none\n\tR_386_GLOB_DAT,\t// S\n\tR_386_JMP_SLOT,\t// S\n\tR_386_RELATIVE,\t// B+A\n\tR_386_GOTOFF,\t// S+A-GOT\n\tR_386_GOTPC,\t// GOT+A-P\n\tR_386_LAST\t// none\n};\n\ntypedef struct {\n\tu16\td_tag;\n\tu32\td_val;\t//Also d_ptr\n} Elf32_dyn;\n\n\nenum {\n\tDT_NULL,\t//!< Marks End of list\n\tDT_NEEDED,\t//!< Offset in strtab to needed library\n\tDT_PLTRELSZ,\t//!< Size in bytes of PLT\n\tDT_PLTGOT,\t//!< Address of PLT/GOT\n\tDT_HASH,\t//!< Address of symbol hash table\n\tDT_STRTAB,\t//!< String Table address\n\tDT_SYMTAB,\t//!< Symbol Table address\n\tDT_RELA,\t//!< Relocation table address\n\tDT_RELASZ,\t//!< Size of relocation table\n\tDT_RELAENT,\t//!< Size of entry in relocation table\n\tDT_STRSZ,\t//!< Size of string table\n\tDT_SYMENT,\t//!< Size of symbol table entry\n\tDT_INIT,\t//!< Address of initialisation function\n\tDT_FINI,\t//!< Address of termination function\n\tDT_SONAME,\t//!< String table offset of so name\n\tDT_RPATH,\t//!< String table offset of library path\n\tDT_SYMBOLIC,//!< Reverse order of symbol searching for library, search libs first then executable\n\tDT_REL,\t\t//!< Relocation Entries (Elf32_Rel instead of Elf32_Rela)\n\tDT_RELSZ,\t//!< Size of above table (bytes)\n\tDT_RELENT,\t//!< Size of entry in above table\n\tDT_PLTREL,\t//!< Relocation entry of PLT\n\tDT_DEBUG,\t//!< Debugging Entry - Unknown contents\n\tDT_TEXTREL,\t//!< Indicates that modifcations to a non-writeable segment may occur\n\tDT_JMPREL,\t//!< Address of PLT only relocation entries\n\tDT_LOPROC = 0x70000000,\t//!< Low Definable\n\tDT_HIPROC = 0x7FFFFFFF\t//!< High Definable\n};\n\n\nint is_elf(char *);\nu32 load_elf(char *,process_st *);\n\nint execv(char* file,int argc,char** argv);\nvoid execv_module(u32 entry,int argc,char** argv);\n\n#endif\n"
  },
  {
    "path": "src/kernel/core/env.cc",
    "content": "#include <os.h>\n\n/*\n *\tDefinis la structure d'une variable d'environnement\n *\tchaque variable est un fichier stoqu dans le dossier virtuel /sys/env\n */\n\n/*\n *\tDestructeur de la variable\n */\nVariable::~Variable(){\n\tif (value!=NULL)\n\t\tkfree(value);\n}\n\n/* \n *\tConstructeur :\n *\t\tn : nom\n *\t\tv : valeur\n */\nVariable::Variable(char* n,char* v) : File(n,TYPE_FILE)\n{\n\tfsm.addFile(\"/sys/env/\",this);\n\tif (v!=NULL){\n\t\tio.print(\"env: create %s (%s) \\n\",n,v);\n\t\tvalue=(char*)kmalloc(strlen(v)+1);\n\t\tmemcpy(value,v,strlen(v)+1);\n\t\tsetSize(strlen(v)+1);\n\t}\n\telse{\n\t\tvalue=NULL;\n\t}\n}\n\nu32\tVariable::open(u32 flag){\n\treturn RETURN_OK;\n}\n\nu32\tVariable::close(){\n\treturn RETURN_OK;\n}\n\n/* lecture de la valeur dans buffer */\nu32\tVariable::read(u32 pos,u8* buffer,u32 size){\n\tif (value==NULL)\n\t\treturn NOT_DEFINED;\n\telse{\n\t\tstrncpy((char*)buffer,value,size);\n\t\treturn size;\t\t\n\t}\n}\n\n/* ecriture de buffer dans la variable */\nu32\tVariable::write(u32 pos,u8* buffer,u32 size){\n\tif (value!=NULL)\n\t\tkfree(value);\n\tvalue=(char*)kmalloc(size+1);\n\tmemset((char*)value,0,size+1);\n\tmemcpy(value,(char*)buffer,size+1);\n\tvalue[size]=0;\t//to make sure it's a string\n\tsetSize(size+1);\n\treturn size;\n}\n\n/* controle de la variable (TODO) */\nu32\tVariable::ioctl(u32 id,u8* buffer){\n\treturn NOT_DEFINED;\n}\n\n/* destruction de la variable */\nu32\tVariable::remove(){\n\tdelete this;\n\treturn NOT_DEFINED;\n}\n\n/* seulement pour les dossiers */\nvoid Variable::scan(){\n\n}\n\n"
  },
  {
    "path": "src/kernel/core/env.h",
    "content": "#ifndef ENV_H\n#define ENV_H\n\n#include <core/file.h>\n#include <runtime/list.h>\n\n\nclass Variable : public File\n{\n\tpublic:\n\t\tVariable(char* n,char* v);\n\t\t~Variable();\n\t\t\n\t\tu32\t\topen(u32 flag);\n\t\tu32\t\tclose();\n\t\tu32\t\tread(u32 pos,u8* buffer,u32 size);\n\t\tu32\t\twrite(u32 pos,u8* buffer,u32 size);\n\t\tu32\t\tioctl(u32 id,u8* buffer);\n\t\tu32\t\tremove();\n\t\tvoid\tscan();\n\t\t\n\t\t\n\t\t\n\t\t\n\tprotected:\n\t\tchar*\tvalue;\n\n\n};\n\n#endif"
  },
  {
    "path": "src/kernel/core/file.cc",
    "content": "\n#include <os.h>\n\n/* dans myos quasiment tous herite de cette classe */\n\n\n/*\n *\tRemplace dans s tous les a par to\n */\nstatic void strreplace(char* s,char a,char to){\n\tif (s==NULL)\n\t\treturn;\n\twhile (*s){\n\t\tif (*s==a)\n\t\t\t*s=to;\n\t\ts++;\n\t}\n}\n\n\nu32\tFile::inode_system=0;\t/* numero d'inode de depart */\n\n/* constructeur */\nFile::File(char* n,u8 t){\n\tname=(char*)kmalloc(strlen(n)+1);\n\tmemset(name,0,strlen(n));\n\tmemcpy(name,n,strlen(n));\n\tname[strlen(n)]=0;\n\t\n\tcheckName();\n\tmaster=arch.pcurrent;\t// la creation, le maitre est le processus courant\n\tinode=inode_system;\n\tinode_system++;\n\tsize=0;\n\ttype=t;\n\tparent=NULL;\n\tchild=NULL;\n\tnext=NULL;\n\tprec=NULL;\n\tlink=NULL;\n\tmap_memory=NULL;\n}\n\n/* destructeur */\nFile::~File(){\n\tkfree(name);\n\t\n\t//on modifie la liste des frere\n\t\n\tif (prec==NULL){\n\t\tparent->setChild(next);\n\t\tnext->setPrec(NULL);\n\t}\n\telse if (next==NULL){\n\t\tprec->setNext(NULL);\n\t}\n\telse if (next==NULL && prec==NULL){\n\t\tparent->setChild(NULL);\n\t}\n\telse{\n\t\tio.print(\"prec (%s) next is now %s\\n\",prec->getName(),next->getName());\n\t\tio.print(\"next (%s) prec is now %s\\n\",next->getName(),prec->getName());\n\t\tprec->setNext(next);\n\t\tnext->setPrec(prec);\n\t}\n\t\n\t//on supprime les enfant (dossier)\n\tFile* n=child;\n\tFile* nn=NULL;\n\twhile (n!=NULL){\n\t\t//io.print(\"delete %s \\n\",n->getName());\n\t\tnn=n->getNext();\n\t\tdelete n;\n\t\tn=nn;\n\t}\n\t\n}\n\n#define CAR_REPLACE '_'\n\n\nvoid File::checkName(){\n\t//Adapte le nom\n\tstrreplace(name,'/',CAR_REPLACE);\n\tstrreplace(name,'\\ ',CAR_REPLACE);\n\tstrreplace(name,'?',CAR_REPLACE);\n\tstrreplace(name,':',CAR_REPLACE);\n\tstrreplace(name,'>',CAR_REPLACE);\n\tstrreplace(name,'<',CAR_REPLACE);\n\tstrreplace(name,'*',CAR_REPLACE);\n\tstrreplace(name,'\"',CAR_REPLACE);\n\tstrreplace(name,':',CAR_REPLACE);\n}\n\nu32 File::addChild(File* n){\n\tif (!n){\n\t\treturn PARAM_NULL;\n\t}\n\tn->setParent(this);\n\tn->setPrec(NULL);\n\tn->setNext(child);\n\tif (child != NULL)\n\t\tchild->setPrec(n);\n\tchild=n;\n\treturn RETURN_OK;\n}\n\nFile*\tFile::createChild(char* n,u8 t){\n\tFile* fp=new File(n,t);\n\taddChild(fp);\n\treturn fp;\n}\n\nFile*\tFile::getParent(){\n\treturn parent;\n}\n\nFile*\tFile::getChild(){\n\treturn child;\n}\n\nFile*\tFile::getNext(){\n\treturn next;\n}\n\nFile*\tFile::getPrec(){\n\treturn prec;\n}\n\nFile*\tFile::getLink(){\n\treturn link;\n}\n\nu32\tFile::getSize(){\n\treturn size;\n}\n\nu32\tFile::getInode(){\n\treturn inode;\n}\n\nvoid File::scan(){\n\n}\n\nvoid\tFile::setType(u8 t){\n\ttype=t;\n}\n\nvoid\tFile::setSize(u32 t){\n\tsize=t;\n}\n\nvoid\tFile::setParent(File* n){\n\tparent=n;\n}\n\nvoid\tFile::setLink(File* n){\n\tlink=n;\n}\n\nvoid\tFile::setChild(File* n){\n\tchild=n;\n}\n\nvoid\tFile::setNext(File* n){\n\tnext=n;\n}\n\nvoid\tFile::setPrec(File* n){\n\tprec=n;\n}\n\nvoid\tFile::setName(char* n){\n\tkfree(name);\n\tname=(char*)kmalloc(strlen(n));\n\tmemcpy(name,n,strlen(n));\n\tcheckName();\n}\n\nu8\tFile::getType(){\n\treturn type;\n}\n\nchar* File::getName(){\n\treturn name;\n}\n\nFile* File::find(char* n){\n\tFile* fp=child;\n\twhile (fp!=0){\n\t\tif (!strcmp(fp->getName(),n))\n\t\t\treturn fp;\n\t\t\n\t\tfp=fp->next;\n\t}\n\treturn NULL;\n}\n\n\n\nu32\tFile::open(u32 flag){\n\treturn NOT_DEFINED;\n}\n\nu32\tFile::close(){\n\treturn NOT_DEFINED;\n}\n\nu32\tFile::read(u32 pos,u8* buffer,u32 size){\n\treturn NOT_DEFINED;\n}\n\nu32\tFile::write(u32 pos,u8* buffer,u32 size){\n\treturn NOT_DEFINED;\n}\n\nu32\tFile::ioctl(u32 id,u8* buffer){\n\treturn NOT_DEFINED;\n}\n\nu32\tFile::remove(){\n\tdelete this;\n\treturn NOT_DEFINED;\n}\n\nstat_fs File::stat(){\n\tstat_fs st;\n\t\n\treturn st;\n}\n\nu32 File::mmap(u32 sizee,u32 flags,u32 offset,u32 prot){\n\tif (map_memory!=NULL){\n\t\tint i=0;\n\t\tunsigned int adress;\n\t\tstruct page *pg;\n\t\tprocess_st* current=(arch.pcurrent)->getPInfo();\n\t\tfor (i=0;i<sizee;i++){\n\t\t\t\tadress=(unsigned int)(map_memory+i*PAGESIZE);\n\t\t\t\t//io.print(\"mmap : %x %d\\n\",adress,sizee);\n\t\t\t\tpg = (struct page *) kmalloc(sizeof(struct page));\n\t\t\t\tpg->p_addr = (char*) (adress);\n\t\t\t\tpg->v_addr = (char *) (adress & 0xFFFFF000);\n\t\t\t\tlist_add(&pg->list, &current->pglist);\n\t\t\t\tpd_add_page(pg->v_addr, pg->p_addr, PG_USER, current->pd);\n\t\t}\n\t\treturn (u32)map_memory;\n\t}\n\telse{\n\t\treturn -1;\n\t}\n}\n\n"
  },
  {
    "path": "src/kernel/core/file.h",
    "content": "\n#ifndef FILE_H\n#define FILE_H\n\n#include <runtime/types.h>\n\nenum{\n\tTYPE_FILE,\n\tTYPE_DIRECTORY,\n\tTYPE_DEVICE,\n\tTYPE_PROCESS,\n\tTYPE_LINK\n};\n\n\nclass File\n{\n\tpublic:\n\t\tFile(char* n,u8 t);\n\t\t~File();\n\t\t\n\t\tvirtual u32\t\topen(u32 flag);\n\t\tvirtual u32\t\tclose();\n\t\tvirtual u32\t\tread(u32 pos,u8* buffer,u32 size);\n\t\tvirtual u32\t\twrite(u32 pos,u8* buffer,u32 size);\n\t\tvirtual u32\t\tioctl(u32 id,u8* buffer);\n\t\tvirtual u32\t\tremove();\n\t\tvirtual void\tscan();\n\t\t\n\t\t\n\t\tvoid\tcheckName();\n\t\t\n\t\tu32\t\taddChild(File* n);\n\t\tFile*\tcreateChild(char* n,u8 t);\n\t\tFile* \tfind(char* n);\n\t\tu32 \tmmap(u32 sizee,u32 flags,u32 offset,u32 prot);\n\t\t\n\t\tvoid\tsetSize(u32 t);\n\t\tvoid\tsetType(u8 t);\n\t\tvoid\tsetParent(File* n);\n\t\tvoid\tsetChild(File* n);\n\t\tvoid\tsetNext(File* n);\n\t\tvoid\tsetPrec(File* n);\n\t\tvoid\tsetLink(File* n);\n\t\tvoid\tsetName(char* n);\n\t\t\n\t\tchar*\tgetName();\n\t\tFile*\tgetParent();\n\t\tFile*\tgetChild();\n\t\tFile*\tgetNext();\n\t\tFile*\tgetPrec();\n\t\tFile*\tgetLink();\n\t\tu8\t\tgetType();\n\t\tu32\t\tgetSize();\n\t\tu32\t\tgetInode();\n\t\t\n\t\tstat_fs stat();\n\t\t\n\tprotected:\n\t\tstatic u32 inode_system;\n\t\n\t\tchar*\tmap_memory;\t/* to mmap */\n\t\t\n\t\tchar*\tname;\t\t/* Nom du fichier\t*/\n\t\tu32\t\tsize;\t\t/* Taille du fichier */\n\t\tu8\t\ttype;\t\t/* Type de fichier */\n\t\tu32\t\tinode;\t\t/* Inode du fichier */\n\t\tFile*\tdev;\t\t/* the master device, example : /dev/hda */\n\t\tFile*\tlink;\t\t/* the real file, if this file is a link */\n\t\t\n\t\t\n\t\tFile*\tmaster;\t/* processus maitre ou NULL */\n\t\t\n\t\tFile*\tparent;\n\t\tFile*\tchild;\n\t\tFile*\tnext;\n\t\tFile*\tprec;\n\t\t\n\t\tFile*\tdevice;\t\t/* This file is the device master of the current file */\n};\n\n#endif\n"
  },
  {
    "path": "src/kernel/core/filesystem.cc",
    "content": "\n#include <os.h>\n\n/*\nCette classe organise les fichiers entre eux\n*/\n\nFilesystem::Filesystem(){\n\n}\n\nvoid Filesystem::init(){\n\troot=new File(\"/\",TYPE_DIRECTORY);\n\t\n\tdev=root->createChild(\"dev\",TYPE_DIRECTORY);\t\t//dossier contenant les peripherique\n\troot->createChild(\"proc\",TYPE_DIRECTORY);\t\t\t//dossier contenant les processus tournant\n\troot->createChild(\"mnt\",TYPE_DIRECTORY);\t\t\t//dossier contenant les points de montages des disques\n\tFile* sysd=root->createChild(\"sys\",TYPE_DIRECTORY);\t//dossier contenant toutes les infos du systemes\n\t\tvar=sysd->createChild(\"env\",TYPE_DIRECTORY);\t\t//dossier contenant toutes les variables d'environnement\n\t\tsysd->createChild(\"usr\",TYPE_DIRECTORY);\t\t//dossier contenant tous les utilisateurs\n\t\tsysd->createChild(\"mods\",TYPE_DIRECTORY);\t\t//dossier contenant tous les modules disponiles\n\t\tsysd->createChild(\"sockets\",TYPE_DIRECTORY);\t//dossier contenant tous les sockets actuels\n}\n\nFilesystem::~Filesystem(){\n\tdelete root;\n}\n\nvoid Filesystem::mknod(char* module,char* name,u32 flag){\n\tmodm.createDevice(name,module,flag);\n}\n\nFile* Filesystem::getRoot(){\n\treturn root;\n}\n\nFile* Filesystem::path(char* p){\n\tif (!p)\n\t\treturn NULL;\n\t\t\n\tFile* fp=root;\n\tchar *name, *beg_p, *end_p;\n\t\n\tif (p[0]=='/')\n\t\tfp=root;\n\telse{\n\t\tif (arch.pcurrent!=NULL)\t\t/* prend de le dossier actuel du fichier */\n\t\t\tfp=(arch.pcurrent)->getCurrentDir();\n\t}\n\tbeg_p = p;\n\twhile (*beg_p == '/')\n\t\tbeg_p++;\n\tend_p = beg_p + 1;\n\t\n\twhile (*beg_p != 0) {\n\t\tif (fp->getType() != TYPE_DIRECTORY){\n\t\t\treturn NULL;\n\t\t}\n\t\twhile (*end_p != 0 && *end_p != '/')\n\t\t\tend_p++;\n\t\tname = (char *) kmalloc(end_p - beg_p + 1);\n\t\tmemcpy(name, beg_p, end_p - beg_p);\n\t\tname[end_p - beg_p] = 0;\n\n\t\tif (strcmp(\"..\", name) == 0) {\t\t// '..' \n\t\t\tfp = fp->getParent();\n\t\t} else if (strcmp(\".\", name) == 0) {\t// '.' \n\t\t\n\t\t} else {\n\t\t\tfp->scan();\n\t\t\tif (!(fp = fp->find(name))) {\n\t\t\t\tkfree(name);\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\t\n\t\t\tif (fp->getType()==TYPE_LINK && (fp->getLink()!=NULL)){\n\t\t\t\tfp=fp->getLink();\n\t\t\t}\n\t\t}\n\n\t\tbeg_p = end_p;\n\t\twhile (*beg_p == '/')\n\t\t\tbeg_p++;\n\t\tend_p = beg_p + 1;\n\n\t\tkfree(name);\n\t}\n\t\n\treturn fp;\n}\n\nFile* Filesystem::pivot_root(File* targetdir){\n\tif (targetdir == NULL)\n\t\treturn root;\n\telse\n\t{\n\t  File* newRoot = new File(\"/\",TYPE_DIRECTORY);\n\t  File* mainChild = targetdir->getChild();\n\t  newRoot->addChild(mainChild);\n\t  s8 i, ii = 0;\n\t  File* tempChild = mainChild->getPrec(); //Est que File doit tre initialis ? ou pas ?\n\t      do\n\t      {\n\t\t  if(tempChild == NULL)\n\t\t  {\n\t\t    i = 0;\n\t\t  }\n\t\t  else\n\t\t  {\n\t\t    newRoot->addChild(tempChild);\n\t\t    tempChild = tempChild->getPrec();\n\t\t  }\n\t      }while(i == 1);\n\t       tempChild = mainChild->getNext();\n\t      i = 1;\n\t      do\n\t      {\n\t\t  if(tempChild == NULL)\n\t\t    i = 0;\n\t\t  else\n\t\t  {\n\t\t    newRoot->addChild(tempChild);\n\t\t    tempChild = tempChild->getNext();\n\t\t  }\n\t      }while(i == 1);\n\treturn newRoot;\n\t}\n \n}\n\nFile* Filesystem::path_parent(char* p,char *fname){\n\tif (!p)\n\t\treturn NULL;\n\tFile* ofp;\n\tFile* fp=root;\n\tchar *name, *beg_p, *end_p;\n\t\n\tif (p[0]=='/')\n\t\tfp=root;\n\t\t\n\tbeg_p = p;\n\twhile (*beg_p == '/')\n\t\tbeg_p++;\n\tend_p = beg_p + 1;\n\t\n\twhile (*beg_p != 0) {\n\t\tif (fp->getType() != TYPE_DIRECTORY)\n\t\t\treturn NULL;\n\n\t\twhile (*end_p != 0 && *end_p != '/')\n\t\t\tend_p++;\n\t\tname = (char *) kmalloc(end_p - beg_p + 1);\n\t\tmemcpy(name, beg_p, end_p - beg_p);\n\t\tname[end_p - beg_p] = 0;\n\n\n\t\tif (strcmp(\"..\", name) == 0) {\t\t// '..' \n\t\t\tfp = fp->getParent();\n\t\t} else if (strcmp(\".\", name) == 0) {\t// '.' \n\t\t\n\t\t} else {\n\t\t\tofp=fp;\n\t\t\t\n\t\t\tif (fp->getType()==TYPE_LINK && (fp->getLink()!=NULL)){\n\t\t\t\tfp=fp->getLink();\n\t\t\t}\n\t\t\t\n\t\t\tif (!(fp = fp->find(name))) {\n\t\t\t\tstrcpy(fname,name);\n\t\t\t\tkfree(name);\n\t\t\t\treturn ofp;\n\t\t\t}\n\t\t\n\t\t}\n\n\t\tbeg_p = end_p;\n\t\twhile (*beg_p == '/')\n\t\t\tbeg_p++;\n\t\tend_p = beg_p + 1;\n\n\t\tkfree(name);\n\t}\n\t\n\treturn fp;\n}\n\nu32 Filesystem::link(char* fname,char *newf){\n\n\tFile*tolink=path(fname);\n\tif (tolink==NULL)\n\t\treturn -1;\n\n\tchar* nname=(char*)kmalloc(255);\n\tFile* par=path_parent(newf,nname);\n\tFile* fp=new File(nname,TYPE_LINK);\n\tfp->setLink(tolink);\n\tpar->addChild(fp);\n\treturn RETURN_OK;\n}\n\n\nu32 Filesystem::addFile(char* dir,File* fp){\n\tFile* fdir=path(dir);\n\tif (fdir==NULL)\n\t\treturn ERROR_PARAM;\n\telse{\n\t\treturn fdir->addChild(fp);\n\t}\n}\n\n\n\n"
  },
  {
    "path": "src/kernel/core/filesystem.h",
    "content": "\n#ifndef FILESYSTEM_H\n#define FILESYSTEM_H\n\n#include <runtime/types.h>\n#include <core/file.h>\n\n\nclass Filesystem\n{\n\tpublic:\n\t\tFilesystem();\n\t\t~Filesystem();\n\t\t\n\t\tvoid \tinit();\n\t\tvoid\tmknod(char* module,char* name,u32 flag);\n\t\t\n\t\tFile* \tpath(char* p);\n\t\tFile* \tpath_parent(char* p,char *fname);\n\t\t\n\t\tu32\t\tlink(char* fname,char *newf);\n\t\t\n\t\t\n\t\tu32 \taddFile(char* dir,File* fp);\n\t\t\n\t\tFile* \tpivot_root(File* targetdir);\n\t\t\n\t\tFile*\tgetRoot();\n\t\t\n\tprivate:\n\t\tFile*\troot;\n\t\tFile*\tdev;\n\t\tFile*\tvar;\n};\n\nextern Filesystem\t\tfsm;\n#endif\n"
  },
  {
    "path": "src/kernel/core/kernel.cc",
    "content": "\n#include <os.h>\n#include <boot.h>\n\n\nstatic char* init_argv[2]={\"init\",\"-i\"};\n\n/* charge les modules de depart */\nstatic void load_modules(multiboot_info* mbi){\n\t\n\tif (mbi->mods_count>0){\n\t\tu32 initrd_location = *((u32*)mbi->mods_addr);\n\t\tu32 initrd_end = *(u32*)(mbi->mods_addr+4);\n\t\tu32\tinitrd_size=initrd_end-initrd_location;\n\t\tio.print(\" >load module:  location=%x, size=%d \\n\",initrd_location,initrd_end-initrd_location);\n\t\tint i=0;\n\t\tunsigned int adress;\n\t\n\t\tfor (i=0;i<(initrd_size/4072)+1;i++){\t\n\t\t\t\tadress=(initrd_location+i*4096);\n\t\t\t\tvmm.kmap(adress,adress);\n\t\t}\n\t\texecv_module(initrd_location,1,init_argv);\n\t}\n}\n\n\n/* le main du noyau */\nextern \"C\" void kmain(multiboot_info* mbi){\n\tio.clear();\n\tio.print(\"%s - %s -- %s %s \\n\",\tKERNEL_NAME,\n\t\t\t\t\t\t\t\t\tKERNEL_VERSION,\n\t\t\t\t\t\t\t\t\tKERNEL_DATE,\n\t\t\t\t\t\t\t\t\tKERNEL_TIME);\n\t\n\tio.print(\"%s \\n\",KERNEL_LICENCE);\n\tarch.init();\n\t\n\tio.print(\"Loading Virtual Memory Management \\n\");\n\tvmm.init(mbi->high_mem);\n\t\n\tio.print(\"Loading FileSystem Management \\n\");\n\tfsm.init();\n\t\n\tio.print(\"Loading syscalls interface \\n\");\n\tsyscall.init();\n\t\n\tio.print(\"Loading system \\n\");\n\tsys.init();\n\t\n\tio.print(\"Loading modules \\n\");\n\tmodm.init();\n\tmodm.initLink();\n\n\n\tmodm.install(\"hda0\",\"module.dospartition\",0,\"/dev/hda\");\n\tmodm.install(\"hda1\",\"module.dospartition\",1,\"/dev/hda\");\n\tmodm.install(\"hda2\",\"module.dospartition\",2,\"/dev/hda\");\n\tmodm.install(\"hda3\",\"module.dospartition\",3,\"/dev/hda\");\n\tmodm.mount(\"/dev/hda0\",\"boot\",\"module.ext2\",NO_FLAG);\n\n\tarch.initProc();\n\t\n\tio.print(\"Loading binary modules \\n\");\n\tload_modules(mbi);\n\t\n\tfsm.link(\"/mnt/boot/bin/\",\"/bin/\");\n\n\t\n\tio.print(\"\\n\");\n\tio.print(\"  ==== System is ready (%s - %s) ==== \\n\",KERNEL_DATE,KERNEL_TIME);\n\tarch.enable_interrupt();\n\tfor (;;);\n\tarch.shutdown();\n}\n\n"
  },
  {
    "path": "src/kernel/core/kernel.h",
    "content": "\n#ifndef KERNEL_H\n#define KERNEL_H\n\n#include <runtime/alloc.h>\n#include <runtime/libc.h>\n#include <runtime/string.h>\n\n\n#include <core/file.h>\n#include <core/filesystem.h>\n#include <core/elf_loader.h>\n#include <core/syscalls.h>\n#include <core/env.h>\n#include <core/user.h>\n#include <core/modulelink.h>\n#include <core/device.h>\n#include <core/socket.h>\n#include <core/system.h>\n\n\n#include <module.h>\n\n\n#include <io.h>\n#include <architecture.h>\n#include <vmm.h>\n#include <process.h>\n\n#endif\n"
  },
  {
    "path": "src/kernel/core/keyboard.h",
    "content": "\n\n#ifndef __KBD__\n#define __KBD__\n\n#include <api/dev/tty.h>\n\nchar kbdmap_default[] = {\n\tKEY_ESCAPE, KEY_ESCAPE, KEY_ESCAPE, KEY_ESCAPE,\t/*      esc     (0x01)  */\n\t'1', '!', '1', '1',\n\t'2', '@', '2', '2',\n\t'3', '#', '3', '3',\n\t'4', '$', '4', '4',\n\t'5', '%', '5', '5',\n\t'6', ':', '6', '6',\n\t'7', '&', '7', '7',\n\t'8', '*', '8', '8',\n\t'9', '(', '9', '9',\n\t'0', ')', '0', '0',\n\t'-', '_', '-', '-',\n\t'=', '+', '=', '=',\n\t0x08, 0x08, 0x7F, 0x08,\t/*      backspace       */\n\t0x09, 0x09, 0x09, 0x09,\t/*      tab     */\n\t'a', 'A', 'a', 'a',\n\t'z', 'Z', 'z', 'z',\n\t'e', 'E', 'e', 'e',\n\t'r', 'R', 'r', 'r',\n\t't', 'T', 't', 't',\n\t'y', 'Y', 'y', 'y',\n\t'u', 'U', 'u', 'u',\n\t'i', 'I', 'i', 'i',\n\t'o', 'O', 'o', 'o',\n\t'p', 'P', 'p', 'p',\n\t'^', '\"', '^', '^',\n\t'$', '£', ' ', '$',\n\t0x0A, 0x0A, 0x0A, 0x0A,\t/*      enter   */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      ctrl    */\n\t'q', 'Q', 'q', 'q',\n\t's', 'S', 's', 's',\n\t'd', 'D', 'd', 'd',\n\t'f', 'F', 'f', 'f',\n\t'g', 'G', 'g', 'g',\n\t'h', 'H', 'h', 'h',\n\t'j', 'J', 'j', 'j',\n\t'k', 'K', 'k', 'k',\n\t'l', 'L', 'l', 'l',\n\t'm', 'M', 'm', 'm',\n\t0x27, 0x22, 0x27, 0x27,\t/*      '\"      */\n\t'*', '~', '`', '`',\t/*      `~      */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      Lshift  (0x2a)  */\n\t'<', '>', '\\\\', '\\\\',\n\t'w', 'W', 'w', 'w',\n\t'x', 'X', 'x', 'x',\n\t'c', 'C', 'c', 'c',\n\t'v', 'V', 'v', 'v',\n\t'b', 'B', 'b', 'b',\n\t'n', 'N', 'n', 'n',\n\t',', '?', ',', ',',\n\t0x2C, 0x3C, 0x2C, 0x2C,\t/*      ,<      */\n\t0x2E, 0x3E, 0x2E, 0x2E,\t/*      .>      */\n\t0x2F, 0x3F, 0x2F, 0x2F,\t/*      /?      */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      Rshift  (0x36)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x37)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x38)  */\n\t' ', ' ', ' ', ' ',\t/*      space   */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x3a)  */\n\tKEY_F1, 0xFF, 0xFF, 0xFF,\t/*      (0x3b)  */\n\tKEY_F2, 0xFF, 0xFF, 0xFF,\t/*      (0x3c)  */\n\tKEY_F3, 0xFF, 0xFF, 0xFF,\t/*      (0x3d)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x3e)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x3f)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x40)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x41)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x42)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x43)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x44)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x45)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x46)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x47)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x48)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x49)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x4a)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x4b)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x4c)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x4d)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x4e)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x4f)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x50)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x51)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x52)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x53)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x54)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x55)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x56)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x57)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x58)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x59)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x5a)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x5b)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x5c)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x5d)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x5e)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x5f)  */\n\t0xFF, 0xFF, 0xFF, 0xFF,\t/*      (0x60)  */\n\t0xFF, 0xFF, 0xFF, 0xFF\t/*      (0x61)  */\n};\n\nchar* kbdmap=kbdmap_default;\n\n#endif\n"
  },
  {
    "path": "src/kernel/core/modulelink.cc",
    "content": "\n#include <os.h>\n\n\n\nModLink::~ModLink(){\n\t\n}\n\nModLink::ModLink(char* n) : File(n,TYPE_FILE)\n{\n\tfsm.addFile(\"/sys/mods/\",this);\n}\n\nu32\tModLink::open(u32 flag){\n\treturn RETURN_OK;\n}\n\nu32\tModLink::close(){\n\treturn RETURN_OK;\n}\n\nu32\tModLink::read(u8* buffer,u32 size){\n\treturn NOT_DEFINED;\n}\n\nu32\tModLink::write(u8* buffer,u32 size){\n\treturn NOT_DEFINED;\n}\n\nu32\tModLink::ioctl(u32 id,u8* buffer){\n\treturn NOT_DEFINED;\n}\n\nu32\tModLink::remove(){\n\tdelete this;\n}\n\nvoid ModLink::scan(){\n\n}\n\n"
  },
  {
    "path": "src/kernel/core/modulelink.h",
    "content": "\n#ifndef MODLINK_H\n#define MODLINK_H\n\n#include <core/file.h>\n#include <runtime/list.h>\n\n\nclass ModLink : public File\n{\n\tpublic:\n\t\tModLink(char* n);\n\t\t~ModLink();\n\t\t\n\t\tu32\t\topen(u32 flag);\n\t\tu32\t\tclose();\n\t\tu32\t\tread(u8* buffer,u32 size);\n\t\tu32\t\twrite(u8* buffer,u32 size);\n\t\tu32\t\tioctl(u32 id,u8* buffer);\n\t\tu32\t\tremove();\n\t\tvoid\tscan();\n\t\t\n\t\t\n\t\t\n\t\t\n\tprotected:\n\n};\n\n#endif\n"
  },
  {
    "path": "src/kernel/core/os.h",
    "content": "#ifndef OS_H\n#define OS_H\n\n#include <config.h>\n#include <kernel.h>\n\n\ntypedef File* (*device_driver)\t(char* name,u32 flag,File* dev);\n\nstruct module_class{\n\tint\t\t\t\t\tmodule_type;\n\tchar*\t\t\tmodule_name;\n\tchar*\t\t\tclass_name;\n\tdevice_driver\tdrive;\n};\n\n\n\n\n/*\n *\tModule Macro\n */\n#define MODULE_DEVICE\t\t0\n#define MODULE_FILESYSTEM\t1\n#define module(name,type,classe,mknod)\tmodule_class classe##_module={type,\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tname, \\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t#classe, \\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t(device_driver)mknod};\t\n\n#define import_module(classe) \textern module_class  classe##_module\n\n#define run_module_builder\tmodule_class* module_builder[]=\n#define build_module(classe) \t&classe##_module\n#define end_module() \t\tNULL\n\n#define std_buildin_module\tvoid Module::init()\n#define\trun_module(n,m,f) createDevice(#m,#n,f);\n\n/*\n *\tAsm Macro\n */\n#define asm \t\t__asm__\n#define asmv \t\t__asm__ __volatile__\n\n\n\n#endif\n"
  },
  {
    "path": "src/kernel/core/process.cc",
    "content": "\n#include <os.h>\n#include <api/dev/proc.h>\n\n/* Definis un process (/dev/proc) */\n\nchar* Process::default_tty=\"/dev/tty\";\n\nu32 Process::proc_pid=0;\n\nProcess::~Process(){\n\tdelete ipc;\n\tarch.change_process_father(this,pparent);\t//on change le pere des enfants\t\n}\n\nProcess::Process(char* n) : File(n,TYPE_PROCESS)\n{\n\tfsm.addFile(\"/proc/\",this);\n\tpparent=arch.pcurrent;\n\tpid=proc_pid;\n\tproc_pid++;\n\tif (pparent!=NULL)\n\t\tcdir=pparent->getCurrentDir();\n\telse\n\t\tcdir=fsm.getRoot();\n\t\t\n\tarch.addProcess(this);\n\tinfo.vinfo=(void*)this;\n\tint i;\n\tfor (i=0;i<CONFIG_MAX_FILE;i++){\t//open files\n\t\topenfp[i].fp=NULL;\n\t}\n\tipc= new Buffer();\t//ipc buffer\n}\n\nu32\tProcess::open(u32 flag){\n\treturn RETURN_OK;\n}\n\nu32\tProcess::close(){\n\treturn RETURN_OK;\n}\n\nProcess* Process::getPParent(){\n\treturn pparent;\n}\n\nvoid Process::setPParent(Process*p){\n\tpparent=p;\n}\n\nu32\tProcess::read(u32 pos,u8* buffer,u32 sizee){\n\tu32 ret=RETURN_OK;\n\tarch.enable_interrupt();\n\twhile (ipc->isEmpty());\n\tret=ipc->get(buffer,sizee);\n\t\n\tarch.disable_interrupt();\n\treturn ret;\n}\n\nu32\tProcess::write(u32 pos,u8* buffer,u32 sizee){\n\tipc->add(buffer,sizee);\n\treturn size;\n}\n\nu32\tProcess::ioctl(u32 id,u8* buffer){\n\tu32 ret;\n\tswitch (id){\n\t\tcase API_PROC_GET_PID:\n\t\t\tret= pid;\n\t\t\tbreak;\n\t\t\t\n\t\tcase API_PROC_GET_INFO:\n\t\t\treset_pinfo();\n\t\t\tmemcpy((char*)buffer,(char*)&ppinfo,sizeof(proc_info));\n\t\t\tbreak;\n\t\t\t\n\t\t\t\n\t\tdefault:\n\t\t\tret=NOT_DEFINED;\n\t\t\tbreak;\n\t}\n\t\n\treturn ret;\n}\n\nint\tProcess::fork(){\n\t/*Process* p=new Process(\"fork_child\");\n\treturn arch.fork(p->getPInfo(),&info);*/\n\tif (pparent!=NULL)\n\t\tpparent->sendSignal(SIGCHLD);\t\n\treturn 0;\n}\n\nu32\tProcess::wait(){\n\tarch.enable_interrupt();\n\twhile (is_signal(info.signal, SIGCHLD)==0);\n\tclear_signal(&(info.signal), SIGCHLD);\n\tarch.destroy_all_zombie();\n\tarch.disable_interrupt();\n\treturn 1;\n}\n\nu32\tProcess::remove(){\n\tdelete this;\n\treturn RETURN_OK;\n}\n\nvoid Process::scan(){\n\n}\n\nvoid Process::exit(){\n\tsetState(ZOMBIE);\n\tif (pparent!=NULL)\n\t\tpparent->sendSignal(SIGCHLD);\n}\n\nvoid Process::setPNext(Process* p){\n\tpnext=p;\n}\n\nprocess_st* Process::getPInfo(){\n\treturn &info;\n}\n\nProcess* Process::getPNext(){\n\treturn pnext;\n}\n\nu32 Process::create(char* file, int argc, char **argv){\n\tint ret=arch.createProc(&info,file,argc,argv);\n\tif (ret==1)\n\t\tsetState(CHILD);\n\telse\n\t\tsetState(ZOMBIE);\n\t\t\n\t//stdin stdout et stderr du parent\n\tif (pparent!=NULL){\n\t\tmemcpy((char*)&openfp[0],(char*)pparent->getFileInfo(0),sizeof(openfile));\n\t\tmemcpy((char*)&openfp[1],(char*)pparent->getFileInfo(1),sizeof(openfile));\n\t\tmemcpy((char*)&openfp[2],(char*)pparent->getFileInfo(2),sizeof(openfile));\n\t\taddFile(this,0);\n\t}\n\telse{\n\t\taddFile(fsm.path(default_tty),0);\n\t\taddFile(fsm.path(default_tty),0);\n\t\taddFile(fsm.path(default_tty),0);\n\t\t\n\t}\n\t\n\treturn RETURN_OK;\n}\n\nvoid Process::setFile(u32 fd,File* fp,u32 ptr, u32 mode){\n\tif (fd<0 || fd>CONFIG_MAX_FILE)\n\t\treturn;\n\topenfp[fd].fp=fp;\n\topenfp[fd].ptr=ptr;\n\topenfp[fd].mode=mode;\n}\n\nu32 Process::addFile(File* f,u32 m){\n\tint i;\n\tfor (i=0;i<CONFIG_MAX_FILE;i++){\n\t\tif (openfp[i].fp==NULL && f!=NULL){\n\t\t\t//io.print(\"%s:  add %s in %d\\n\",name,f->getName(),i);\n\t\t\topenfp[i].fp=f;\n\t\t\topenfp[i].mode=m;\n\t\t\topenfp[i].ptr=0;\n\t\t\treturn i;\n\t\t}\n\t}\n}\n\nFile* Process::getFile(u32 fd){\n\tif (fd<0 || fd>CONFIG_MAX_FILE)\n\t\treturn NULL;\n\treturn openfp[fd].fp;\n}\n\nopenfile* Process::getFileInfo(u32 fd){\n\tif (fd<0 || fd>CONFIG_MAX_FILE)\n\t\treturn NULL;\n\treturn &openfp[fd];\n}\n\nvoid Process::deleteFile(u32 fd){\n\tif (fd<0 || fd>CONFIG_MAX_FILE)\n\t\treturn;\n\topenfp[fd].fp=NULL;\n\topenfp[fd].mode=0;\n\topenfp[fd].ptr=0;\n}\n\nProcess* Process::schedule(){\n\tProcess* n=this;\n\tint out=1;\n\tn=n->getPNext();\n\twhile (out){\n\t\t\n\t\tif (n==NULL){\n\t\t\tn=arch.plist;\n\t\t}\n\t\t//io.print(\"testing %s\\n\",n->getName());\n\t\t\n\t\t\n\t\tif (n->getState() !=ZOMBIE){\n\t\t\tout=0;\n\t\t}\n\t\telse{\n\t\t\tn=n->getPNext();\n\t\t}\n\t\t\n\t}\n\t\n\tarch.pcurrent=n;\n\t\n\treturn n;\n}\n\n\nFile* Process::getCurrentDir(){\n\treturn cdir;\n}\n\nvoid Process::setCurrentDir(File* f){\n\tcdir=f;\n}\n\n\n\nvoid Process::setState(u8 st){\n\tstate=st;\n}\n\nu8\tProcess::getState(){\n\treturn state;\n}\n\n\nvoid Process::setPid(u32 st){\n\tpid=st;\n}\n\nu32\tProcess::getPid(){\n\treturn pid;\n}\n\nvoid Process::sendSignal(int sig){\n\tset_signal(&(info.signal),sig);\n}\n\nvoid Process::reset_pinfo(){\n\tstrncpy(ppinfo.name,name,32);\n\tppinfo.pid=pid;\n\tppinfo.tid=0;\n\tppinfo.state=state;\n\tppinfo.vmem=10*1024*1024;\n\tppinfo.pmem=10*1024*1024;\n}\n\n"
  },
  {
    "path": "src/kernel/core/process.h",
    "content": "\n#ifndef PROC_H\n#define PROC_H\n\n#include <core/file.h>\n#include <runtime/list.h>\n#include <archprocess.h>\t/* definition de process_st */\n\n#include <core/signal.h>\n\n#include <runtime/buffer.h>\n\n#include <api/dev/proc.h>\n\n#define ZOMBIE\tPROC_STATE_ZOMBIE\n#define CHILD\tPROC_STATE_RUN\n\nstruct openfile\n{\n\tu32\t\t\t\tmode;\t/* Mode d'ouverture */\n\tu32\t\t\t\tptr;\t/* Pointeur de lecture/ecriture */\n\tFile*\t\t\tfp;\t\t/* Fichier ouvert */\n};\n\nclass Process : public File\n{\n\tpublic:\n\t\tProcess(char* n);\n\t\t~Process();\n\t\t\n\t\tu32\t\topen(u32 flag);\n\t\tu32\t\tclose();\n\t\tu32\t\tread(u32 pos,u8* buffer,u32 size);\n\t\tu32\t\twrite(u32 pos,u8* buffer,u32 size);\n\t\tu32\t\tioctl(u32 id,u8* buffer);\n\t\tu32\t\tremove();\n\t\tvoid\tscan();\n\t\t\n\t\t\n\t\tu32\t\tcreate(char* file, int argc, char **argv);\n\t\tvoid\tsendSignal(int sig);\n\t\tu32\t\twait();\n\t\t\n\t\tu32 \taddFile(File* fp,u32 m);\n\t\tFile*\tgetFile(u32 fd);\n\t\tvoid\tdeleteFile(u32 fd);\n\t\topenfile*\tgetFileInfo(u32 fd);\n\t\t\n\t\tvoid\texit();\n\t\tint\t\tfork();\n\t\t\n\t\t\n\t\tvoid\tsetState(u8 st);\n\t\tu8\t\tgetState();\n\t\tvoid\tsetFile(u32 fd,File* fp,u32 ptr, u32 mode);\n\t\tvoid\tsetPid(u32 st);\n\t\tu32\t\tgetPid();\n\t\t\n\t\tvoid\t\t\tsetPNext(Process* p);\n\t\t\n\t\tProcess* \t\tschedule();\n\t\tProcess*\t\tgetPNext();\n\t\tProcess*\t\tgetPParent();\n\t\tprocess_st* \tgetPInfo();\n\t\tvoid\t\t\tsetPParent(Process*p);\n\t\t\n\t\tvoid\t\t\treset_pinfo();\n\t\t\n\t\tprocess_st\t\tinfo;\n\t\t\n\t\tFile*\tgetCurrentDir();\n\t\tvoid\tsetCurrentDir(File* f);\n\t\t\n\tprotected:\n\t\tstatic u32\tproc_pid;\n\t\t\n\t\tu32 \t\tpid;\n\t\tu8\t\t\tstate;\n\t\tProcess*\tpparent;\n\t\tProcess*\tpnext;\n\t\topenfile\topenfp[CONFIG_MAX_FILE];\n\t\tproc_info\tppinfo;\n\t\tFile*\t\tcdir;\n\t\t\n\t\tBuffer*\t\tipc;\n\t\t\n\t\tstatic char*\tdefault_tty;\n\n};\n\n\n#endif\n"
  },
  {
    "path": "src/kernel/core/signal.h",
    "content": "\n#ifndef SIGNAL_H\n#define SIGNAL_H\n\n\n#include <runtime/types.h>\n#include <process.h>\n\n\t#define SIGHUP    1       /* Hangup (POSIX).  */\n\t#define SIGINT    2       /* Interrupt (ANSI).  */\n\t#define SIGQUIT   3       /* Quit (POSIX).  */\n\t#define SIGILL    4       /* Illegal instruction (ANSI).  */\n\t#define SIGTRAP   5       /* Trace trap (POSIX).  */\n\t#define SIGABRT   6       /* Abort (ANSI).  */\n\t#define SIGIOT    6       /* IOT trap (4.2 BSD).  */\n\t#define SIGBUS    7       /* BUS error (4.2 BSD).  */\n\t#define SIGFPE    8       /* Floating-point exception (ANSI).  */\n\t#define SIGKILL   9       /* Kill, unblockable (POSIX).  */\n\t#define SIGUSR1   10      /* User-defined signal 1 (POSIX).  */\n\t#define SIGSEGV   11      /* Segmentation violation (ANSI).  */\n\t#define SIGUSR2   12      /* User-defined signal 2 (POSIX).  */\n\t#define SIGPIPE   13      /* Broken pipe (POSIX).  */\n\t#define SIGALRM   14      /* Alarm clock (POSIX).  */\n\t#define SIGTERM   15      /* Termination (ANSI).  */\n\t#define SIGSTKFLT 16      /* Stack fault.  */\n\t#define SIGCLD    SIGCHLD /* Same as SIGCHLD (System V).  */\n\t#define SIGCHLD   17      /* Child status has changed (POSIX).  */\n\t#define SIGCONT   18      /* Continue (POSIX).  */\n\t#define SIGSTOP   19      /* Stop, unblockable (POSIX).  */\n\t#define SIGTSTP   20      /* Keyboard stop (POSIX).  */\n\t#define SIGTTIN   21      /* Background read from tty (POSIX).  */\n\t#define SIGTTOU   22      /* Background write to tty (POSIX).  */\n\t#define SIGURG    23      /* Urgent condition on socket (4.2 BSD).  */\n\t#define SIGXCPU   24      /* CPU limit exceeded (4.2 BSD).  */\n\t#define SIGXFSZ   25      /* File size limit exceeded (4.2 BSD).  */\n\t#define SIGVTALRM 26      /* Virtual alarm clock (4.2 BSD).  */\n\t#define SIGPROF   27      /* Profiling alarm clock (4.2 BSD).  */\n\t#define SIGWINCH  28      /* Window size change (4.3 BSD, Sun).  */\n\t#define SIGPOLL   SIGIO   /* Pollable event occurred (System V).  */\n\t#define SIGIO     29      /* I/O now possible (4.2 BSD).  */\n\t#define SIGPWR    30      /* Power failure restart (System V).  */\n\t#define SIGSYS    31      /* Bad system call.  */\n\n\t#define SIGEVENT\tSIGPOLL\n\t#define SIGIPC\t\tSIGUSR1\n\t\n\t\n\t\n\t#define SIG_DFL\t\t0\t/* default signal handling */\n\t#define SIG_IGN\t\t1\t/* ignore signal */\n\n\t#define set_signal(mask, sig)\t*(mask) |= ((u32) 1 << (sig - 1))\n\t#define clear_signal(mask, sig)\t*(mask) &= ~((u32) 1 << (sig - 1))\n\t#define is_signal(mask, sig)\t(mask & ((u32) 1 << (sig - 1)))\n\n\n\n\n#endif\n"
  },
  {
    "path": "src/kernel/core/socket.cc",
    "content": "\n#include <os.h>\n\n\n\nSocket::~Socket(){\n\t\n}\n\nSocket::Socket(char* n) : File(n,TYPE_FILE)\n{\n\tfsm.addFile(\"/sys/sockets/\",this);\n}\n\nu32\tSocket::open(u32 flag){\n\treturn RETURN_OK;\n}\n\nu32\tSocket::close(){\n\treturn RETURN_OK;\n}\n\nu32\tSocket::read(u8* buffer,u32 size){\n\treturn NOT_DEFINED;\n}\n\nu32\tSocket::write(u8* buffer,u32 size){\n\treturn NOT_DEFINED;\n}\n\nu32\tSocket::ioctl(u32 id,u8* buffer){\n\treturn NOT_DEFINED;\n}\n\nu32\tSocket::remove(){\n\tdelete this;\n}\n\nvoid Socket::scan(){\n\n}\n\n"
  },
  {
    "path": "src/kernel/core/socket.h",
    "content": "\n#ifndef SOCKET_H\n#define SOCKET_H\n\n#include <core/file.h>\n#include <runtime/list.h>\n\n\nclass Socket : public File\n{\n\tpublic:\n\t\tSocket(char* n);\n\t\t~Socket();\n\t\t\n\t\tu32\t\topen(u32 flag);\n\t\tu32\t\tclose();\n\t\tu32\t\tread(u8* buffer,u32 size);\n\t\tu32\t\twrite(u8* buffer,u32 size);\n\t\tu32\t\tioctl(u32 id,u8* buffer);\n\t\tu32\t\tremove();\n\t\tvoid\tscan();\n\t\t\n\t\t\n\t\t\n\t\t\n\tprotected:\n\n};\n\n#endif\n"
  },
  {
    "path": "src/kernel/core/syscalls.cc",
    "content": "\n#include <os.h>\n#include <api.h>\n\n#include <api/kernel/syscall_table.h>\n\n#define sysc(a,h) add(a,(syscall_handler)h)\n\nvoid Syscalls::init(){\n\tint i;\n\tfor (i=0;i<NB_SYSCALLS;i++)\n\t\tcalls[i]=NULL;\n\tsysc(SYS_open,\t\t&call_open);\n\tsysc(SYS_close,\t\t&call_close);\n\tsysc(SYS_read,\t\t&call_read);\n\tsysc(SYS_write,\t\t&call_write);\n\tsysc(SYS_sbrk,\t\t&call_sbrk);\n\tsysc(SYS_ioctl,\t\t&call_ioctl);\n\tsysc(SYS_exit,\t\t&call_exit);\n\tsysc(SYS_execve,\t&call_execv);\n\tsysc(SYS_symlink,\t&call_symlink);\n\tsysc(SYS_getdents,\t&call_getdents);\n\tsysc(SYS_wait4,\t\t&call_wait);\n\tsysc(SYS_dup2,\t\t&call_dup2);\n\tsysc(SYS_fork,\t\t&call_fork);\n\tsysc(SYS_chdir,\t\t&call_chdir);\n\tsysc(SYS_mmap,\t\t&call_mmap);\n}\n\n\nvoid Syscalls::add(u32 num,syscall_handler h){\n\tcalls[num]=h;\n}\n\nvoid Syscalls::call(u32 num){\n\tif (calls[num]!=NULL)\n\t\tcalls[num]();\n}\n"
  },
  {
    "path": "src/kernel/core/syscalls.h",
    "content": "\n#ifndef SYSCALL_H\n#define SYSCALL_H\n\n#include <core/file.h>\n#include <runtime/list.h>\n\n\n#define NB_SYSCALLS\t100\n\n\ntypedef void (*syscall_handler)(void);\n\nclass Syscalls \n{\n\tpublic:\n\t\tvoid\tinit();\n\t\tvoid\tadd(u32 num,syscall_handler h);\n\t\tvoid\tcall(u32 num);\n\t\t\n\tprotected:\n\t\tsyscall_handler\t\tcalls[NB_SYSCALLS];\n\n};\n\nextern Syscalls\tsyscall;\n\n#endif\n"
  },
  {
    "path": "src/kernel/core/system.cc",
    "content": "\n#include <os.h>\n\n/**\n *\t10/04/06 (Samy Pess) : creation du fichier\n *\t\t\t\t\t\t\tajout gestion login et variable d'environnement\n *\t10/04/07 (Samy Pess) : la classe System gere maintenant une liste chain des utilisateur (User)\n **/\n \n\n\n/*\nCette classe organise le systeme en lui meme : utilisateur, variable, ...\n*/\n\nSystem::System(){\n\t\n}\n\nSystem::~System(){\n\n}\n\n\nvoid System::init(){\n\tvar=fsm.path(\"/sys/env/\");\n\n\t/** System user **/\n\troot=new User(\"root\");\n\troot->setUType(USER_ROOT);\n\t\n\tactual=new User(\"liveuser\");\n\n\t\n\t/** Environnement variable **/\n\tuservar=new Variable(\"USER\",\"liveuser\");\n\tnew Variable(\"OS_NAME\",KERNEL_NAME);\n\tnew Variable(\"OS_VERSION\",KERNEL_VERSION);\n\tnew Variable(\"OS_DATE\",KERNEL_DATE);\n\tnew Variable(\"OS_TIME\",KERNEL_TIME);\n\tnew Variable(\"OS_LICENCE\",KERNEL_LICENCE);\n\tnew Variable(\"COMPUTERNAME\",KERNEL_COMPUTERNAME);\n\tnew Variable(\"PROCESSOR_IDENTIFIER\",KERNEL_PROCESSOR_IDENTIFIER);\n\tnew Variable(\"PROCESSOR_NAME\",arch.detect());\n\tnew Variable(\"PATH\",\"/bin/\");\n\tnew Variable(\"SHELL\",\"/bin/sh\");\n}\n\n//fonction de login\nint\tSystem::login(User* us,char* pass){\n\tif (us==NULL)\n\t\treturn ERROR_PARAM;\n\tif (us->getPassword() != NULL){\t//si il ya un password\n\t\t\n\t\tif (pass==NULL)\t//si on a pass un code\n\t\t\treturn PARAM_NULL;\n\t\t\t//\n\t\tif (strncmp(pass,us->getPassword(),strlen(us->getPassword())))\t//test password\n\t\t\treturn RETURN_FAILURE;\n\t\t//io.print(\"login %s with %s (%s)\\n\",us->getName(),pass,us->getPassword());\n\t}\n\t\t\n\tuservar->write(0,(u8*)us->getName(),strlen(us->getName()));\n\tactual=us;\n\treturn RETURN_OK;\n}\n\n/* ne pas oubliez de faire un free de la variable */\nchar* System::getvar(char* name){\n\tchar* varin;\n\tFile* temp=var->find(name);\n\tif (temp==NULL){\n\t\treturn NULL;\n\t}\n\tvarin=(char*)kmalloc(temp->getSize());\n\tmemset(varin,0,temp->getSize());\n\ttemp->read(0,(u8*)varin,temp->getSize());\n\treturn varin;\n}\n\nUser* System::getUser(char* nae){\n\tUser* us=listuser;\n\twhile (us!=NULL){\n\t\t//io.print(\"test '%s' with '%s'\\n\",nae,us->getName());\n\t\tif (!strncmp(nae,us->getName(),strlen(us->getName())))\n\t\t\treturn us;\n\t\tus=us->getUNext();\n\t}\n\treturn NULL;\n}\n\nvoid System::addUserToList(User* us){\n\tif (us==NULL)\n\t\treturn;\n\tus->setUNext(listuser);\n\tlistuser=us;\n}\n\nu32 System::isRoot(){\n\tif (actual!=NULL){\n\t\tif (actual->getUType() == USER_ROOT)\n\t\t\treturn 1;\n\t\telse\n\t\t\treturn 0;\n\t}\n\telse\n\t\treturn 0;\n}\n"
  },
  {
    "path": "src/kernel/core/system.h",
    "content": "\n#ifndef SYSTEM_H\n#define SYSTEM_H\n\n#include <runtime/types.h>\n#include <core/env.h>\n#include <core/user.h>\n\n\nclass System\n{\n\tpublic:\n\t\tSystem();\n\t\t~System();\n\t\t\n\t\tvoid\tinit();\n\t\tchar*\tgetvar(char* name);\n\t\t\n\t\t\n\t\tvoid\taddUserToList(User* us);\n\t\t\n\t\tUser*\tgetUser(char* nae);\n\t\t\n\t\tint\t\tlogin(User* us,char* pass);\n\t\tu32 \tisRoot();\t\t\t//renvoie 1 si root\n\t\t\n\t\t\n\tprivate:\n\t\tUser*\t\tlistuser;\n\t\n\t\tFile*\t\tvar;\n\t\t\n\t\tUser*\t\tactual;\n\t\tUser*\t\troot;\n\t\t\n\t\tVariable*\tuservar;\n};\n\nextern System\t\tsys;\n#endif\n"
  },
  {
    "path": "src/kernel/core/user.cc",
    "content": "\n#include <os.h>\n\n\n\nUser::~User(){\n\t\n}\n\nUser::User(char* n) : File(n,TYPE_FILE)\n{\n\tfsm.addFile(\"/sys/usr/\",this);\n\tunext=0;\n\tsys.addUserToList(this);\n\tutype=USER_NORM;\n\tmemset(password,0,512);\n}\n\nu32\tUser::open(u32 flag){\n\treturn RETURN_OK;\n}\n\nu32\tUser::close(){\n\treturn RETURN_OK;\n}\n\nu32\tUser::read(u8* buffer,u32 size){\n\treturn NOT_DEFINED;\n}\n\nu32\tUser::write(u8* buffer,u32 size){\n\treturn NOT_DEFINED;\n}\n\nu32\tUser::ioctl(u32 id,u8* buffer){\n\treturn NOT_DEFINED;\n}\n\nu32\tUser::remove(){\n\tdelete this;\n}\n\nvoid User::scan(){\n\n}\n\nvoid User::setPassword(char *n){\n\tif (n!=NULL)\n\t\treturn;\n\tmemset(password,0,512);\n\tstrcpy(password,n);\n}\n\nchar* User::getPassword(){\n\tif (password[0]=0)\n\t\treturn NULL;\n\telse\n\t\treturn password;\n}\n\nUser* User::getUNext(){\n\treturn unext;\n}\n\nvoid User::setUNext(User* us){\n\tunext=us;\n}\n\nvoid User::setUType(u32 t){\n\tutype=t;\n}\n\nu32\tUser::getUType(){\n\treturn utype;\n}\n\n"
  },
  {
    "path": "src/kernel/core/user.h",
    "content": "\n#ifndef USER_H\n#define USER_H\n\n#include <core/file.h>\n#include <runtime/list.h>\n\n\nenum {\n\tUSER_ROOT,\t//root\n\tUSER_NORM\t//utilisateur normal\n};\n\nclass User : public File\n{\n\tpublic:\n\t\tUser(char* n);\n\t\t~User();\n\t\t\n\t\tu32\t\topen(u32 flag);\n\t\tu32\t\tclose();\n\t\tu32\t\tread(u8* buffer,u32 size);\n\t\tu32\t\twrite(u8* buffer,u32 size);\n\t\tu32\t\tioctl(u32 id,u8* buffer);\n\t\tu32\t\tremove();\n\t\tvoid\tscan();\n\t\t\n\t\t\n\t\tvoid\tsetPassword(char *n);\n\t\tchar*\tgetPassword();\n\t\t\n\t\tUser*\tgetUNext();\n\t\tvoid\tsetUNext(User* us);\n\t\t\n\t\tvoid\tsetUType(u32 t);\n\t\tu32\t\tgetUType();\n\t\t\n\tprotected:\n\t\tu32\t\tutype;\n\t\n\t\tUser*\tunext;\n\t\tchar\tpassword[512];\n\t\t\n};\n\n#endif\n"
  },
  {
    "path": "src/kernel/modules/Makefile",
    "content": "OBJS:=  $(OBJS) modules/module.o \\\n\t\tmodules/null.o modules/stdtty.o modules/x86serial.o\\\n\t\tmodules/ide.o modules/bochsvbe.o \\\n\t\tmodules/ext2.o modules/dospartition.o \\\n\t\tmodules/clock_x86.o modules/keys.o\n\n"
  },
  {
    "path": "src/kernel/modules/bochsvbe.cc",
    "content": "\n#include <os.h>\n#include <bochsvbe.h>\n\n/* Driver video pour bios VBE/Bios */\n\n\nstatic void BgaWriteRegister(unsigned short IndexValue, unsigned short DataValue)\n{\n    io.outw(VBE_DISPI_IOPORT_INDEX, IndexValue);\n    io.outw(VBE_DISPI_IOPORT_DATA, DataValue);\n}\n \nstatic unsigned short BgaReadRegister(unsigned short IndexValue)\n{\n    io.outw(VBE_DISPI_IOPORT_INDEX, IndexValue);\n    return io.inw(VBE_DISPI_IOPORT_DATA);\n}\n \nstatic int BgaIsAvailable(void)\n{\n    return (BgaReadRegister(VBE_DISPI_INDEX_ID) == VBE_DISPI_ID4);\n}\n \nstatic void BgaSetVideoMode(unsigned int Width, unsigned int Height, unsigned int BitDepth, int UseLinearFrameBuffer, int ClearVideoMemory)\n{\n    BgaWriteRegister(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_DISABLED);\n    BgaWriteRegister(VBE_DISPI_INDEX_XRES, Width);\n    BgaWriteRegister(VBE_DISPI_INDEX_YRES, Height);\n    BgaWriteRegister(VBE_DISPI_INDEX_BPP, BitDepth);\n    BgaWriteRegister(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED |\n        (UseLinearFrameBuffer ? VBE_DISPI_LFB_ENABLED : 0) |\n        (ClearVideoMemory ? 0 : VBE_DISPI_NOCLEARMEM));\n}\n \nstatic void BgaSetBank(unsigned short BankNumber)\n{\n    BgaWriteRegister(VBE_DISPI_INDEX_BANK, BankNumber);\n}\n\nFile* bochs_mknod(char* name,u32 flag,File* dev){\n\tBochs* cons=new Bochs(name);\n\treturn cons;\n}\n\nmodule(\"module.bvbe\",MODULE_DEVICE,Bochs,bochs_mknod)\n\nBochs::~Bochs(){\n\t\n}\n\nBochs::Bochs(char* n) : Device(n)\n{\n\tfbinfo_best.w=1024;\n\tfbinfo_best.h=768;\n\tfbinfo_best.bpp=32;\n\tfbinfo_best.state=FB_ACTIVE;\n\tfbinfo_best.vmem=(unsigned int*)VBE_DISPI_LFB_PHYSICAL_ADDRESS;\n\t\n\tfbinfo.w=0;\n\tfbinfo.h=0;\n\tfbinfo.bpp=0;\n\tfbinfo.state=FB_NOT_ACTIVE;\n\tfbinfo.vmem=(unsigned int*)VBE_DISPI_LFB_PHYSICAL_ADDRESS;\n\tmap_memory=(char*)VBE_DISPI_LFB_PHYSICAL_ADDRESS;\n}\n\nu32\tBochs::open(u32 flag){\n\treturn RETURN_OK;\n}\n\nu32\tBochs::read(u32 pos,u8* buffer,u32 size){\n\treturn NOT_DEFINED;\n}\n\nu32\tBochs::write(u32 pos,u8* buffer,u32 size){\n\treturn NOT_DEFINED;\n}\n\nu32\tBochs::close(){\n\treturn RETURN_OK;\n}\n\nvoid Bochs::scan(){\n\n}\n\n\nu32\tBochs::ioctl(u32 id,u8* buffer){\n\tu32 ret=0;\n\tswitch (id){\n\t\tcase DEV_GET_TYPE:\n\t\t\tret=DEV_TYPE_FB;\n\t\t\tbreak;\n\t\t\t\n\t\tcase DEV_GET_STATE:\n\t\t\tret=DEV_STATE_OK;\n\t\t\tbreak;\n\t\t\t\n\t\tcase DEV_GET_FORMAT:\n\t\t\tret=DEV_FORMAT_FB;\n\t\t\tbreak;\n\t\t\t\n\t\t\t\n\t\tcase API_FB_IS_AVAILABLE:\n\t\t\tret=(u32)BgaIsAvailable();\n\t\t\tbreak;\n\t\t\t\n\t\tcase API_FB_GET_INFO:\n\t\t\tmemcpy((char*)buffer,(char*)&fbinfo,sizeof(fb_info));\n\t\t\tbreak;\n\t\t\t\n\t\tcase API_FB_SET_INFO:\n\t\t\tmemcpy((char*)&fbinfo,(char*)buffer,sizeof(fb_info));\n\t\t\tBgaSetVideoMode(fbinfo.w, fbinfo.h, (unsigned int)fbinfo.bpp/8, 1, 1);\n\t\t\tbreak;\n\t\t\t\n\t\tcase API_FB_GET_BINFO:\n\t\t\tmemcpy((char*)buffer,(char*)&fbinfo_best,sizeof(fb_info));\n\t\t\tbreak;\n\t\t\t\n\t\tdefault:\n\t\t\tret=NOT_DEFINED;\n\t\t\tbreak;\n\t}\n\treturn ret;\n}\n\nu32\tBochs::remove(){\n\tdelete this;\n\treturn RETURN_OK;\n}\n"
  },
  {
    "path": "src/kernel/modules/bochsvbe.h",
    "content": "\r\n#ifndef __BOCHS_VBE__\r\n#define __BOCHS_VBE__\r\n\r\n#include <runtime/types.h>\r\n#include <core/device.h>\r\n#include <io.h>\r\n\r\n#include <api/dev/ioctl.h>\r\n#include <api/dev/fb.h>\r\n\r\n\r\n#define VBE_DISPI_ENABLED (0x01)\r\n#define VBE_DISPI_DISABLED (0x00)\r\n#define VBE_DISPI_INDEX_ENABLE (4)\r\n#define VBE_DISPI_ID4 (0xB0C4)\r\n#define VBE_DISPI_LFB_ENABLED (0x40)\r\n#define VBE_DISPI_NOCLEARMEM (0x80)\r\n#define VBE_DISPI_IOPORT_INDEX (0x01CE)\r\n#define VBE_DISPI_INDEX_ID (0)\r\n#define VBE_DISPI_INDEX_XRES (1)\r\n#define VBE_DISPI_INDEX_YRES (2)\r\n#define VBE_DISPI_INDEX_BPP (3)\r\n#define VBE_DISPI_INDEX_ENABLE (4)\r\n#define VBE_DISPI_INDEX_BANK (5)\r\n#define VBE_DISPI_INDEX_VIRT_WIDTH (6)\r\n#define VBE_DISPI_INDEX_VIRT_HEIGHT (7)\r\n#define VBE_DISPI_INDEX_X_OFFSET (8)\r\n#define VBE_DISPI_INDEX_Y_OFFSET (9) \r\n#define VBE_DISPI_IOPORT_DATA (0x01CF)\r\n \r\n#define VBE_DISPI_LFB_PHYSICAL_ADDRESS  0xE0000000\r\n\r\n\r\nclass Bochs : public Device\r\n{\r\n\tpublic:\r\n\t\tBochs(char* n);\r\n\t\t~Bochs();\r\n\t\t\r\n\t\t\r\n\t\tu32\t\topen(u32 flag);\r\n\t\tu32\t\tclose();\r\n\t\tu32\t\tread(u32 pos,u8* buffer,u32 size);\r\n\t\tu32\t\twrite(u32 pos,u8* buffer,u32 size);\r\n\t\tu32\t\tioctl(u32 id,u8* buffer);\r\n\t\tu32\t\tremove();\r\n\t\tvoid\tscan();\r\n\t\t\r\n\t\t\r\n\tprivate:\r\n\t\tfb_info\tfbinfo_best;\r\n\t\tfb_info\tfbinfo;\r\n};\r\n\r\n#endif\r\n"
  },
  {
    "path": "src/kernel/modules/clock_x86.cc",
    "content": "\n#include <os.h>\n#include <clock_x86.h>\n\n#include <api/dev/ioctl.h>\n\n\nstatic void GetWeekday(unsigned int *Weekday)\n{\n\tunsigned int DataWeekday;\n\n\tio.outb(0x70, 0x95);\n\n\tio.outb(0x70, 6);\n\tDataWeekday = io.inb(0x71);\n\tif(DataWeekday<6) *Weekday = DataWeekday + 2;\n\telse *Weekday = DataWeekday - 5;\n}\n\nstatic void GetDate(unsigned int *Year, unsigned int *Month, unsigned int *Day)\n{\n\tunsigned int DataYear, DataMonth, DataDay;\n\n\tio.outb(0x70, 0x95);\n\n\tio.outb(0x70, 9);\n\tDataYear = io.inb(0x71);\n\t*Year = DataYear - ((unsigned int) DataYear/16) * 6;\n\n\tio.outb(0x70, 8);\n\tDataMonth = io.inb(0x71);\n\t*Month = DataMonth - ((unsigned int) DataMonth/16) * 6;\n\n\tio.outb(0x70, 7);\n\tDataDay = io.inb(0x71);\n\t*Day = DataDay - ((unsigned int) DataDay/16) * 6;\n}\n\nstatic void GetTime(unsigned int *Hour, unsigned int *Minute, unsigned int *Second)\n{\n\tunsigned int DataHour, DataMinute, DataSecond;\n\n\tio.outb(0x70, 0x95);\n\n\tio.outb(0x70, 4);\n\tDataHour = io.inb(0x71);\n\t*Hour = DataHour - ((unsigned int) DataHour/16) * 6;\n\n\tio.outb(0x70, 2);\n\tDataMinute = io.inb(0x71);\n\t*Minute = DataMinute - ((unsigned int) DataMinute/16) * 6;\t\n\t\n\tio.outb(0x70, 0);\n\tDataSecond = io.inb(0x71);\n\t*Second = DataSecond - ((unsigned int) DataSecond/16) * 6;\n}\n\n\n\n\nFile* clockx86_mknod(char* name,u32 flag,File* dev){\n\tClock_x86* cons=new Clock_x86(name);\n\treturn cons;\n}\n\nmodule(\"module.clock_x86\",MODULE_DEVICE,Clock_x86,clockx86_mknod)\n\nClock_x86::~Clock_x86(){\n\t\n}\n\nClock_x86::Clock_x86(char* n) : Device(n)\n{\n\n}\n\nvoid Clock_x86::scan(){\n\n}\n\nu32\tClock_x86::close(){\n\treturn RETURN_OK;\n}\n\nu32\tClock_x86::open(u32 flag){\n\treturn RETURN_OK;\n}\n\nu32\tClock_x86::read(u32 pos,u8* buffer,u32 size){\n\treturn NOT_DEFINED;\n}\n\nu32\tClock_x86::write(u32 pos,u8* buffer,u32 size){\n\treturn NOT_DEFINED;\n}\n\nvoid Clock_x86::reset_info(){\n\tGetDate(&(cinfo.year),&(cinfo.month), &(cinfo.day));\n\tGetTime(&(cinfo.h),&(cinfo.m), &(cinfo.s));\n}\n\nu32\tClock_x86::ioctl(u32 id,u8* buffer){\n\tu32 ret=0;\n\tswitch (id){\n\t\tcase DEV_GET_TYPE:\n\t\t\tret=DEV_TYPE_TTY;\n\t\t\tbreak;\n\t\t\t\n\t\tcase DEV_GET_STATE:\n\t\t\tret=DEV_STATE_OK;\n\t\t\tbreak;\n\t\t\t\n\t\tcase DEV_GET_FORMAT:\n\t\t\tret=DEV_FORMAT_CHAR;\n\t\t\tbreak;\n\t\t\t\n\t\tcase API_CLOCK_GET_INFO:\n\t\t\treset_info();\n\t\t\tmemcpy((char*)buffer,(char*)&cinfo,sizeof(clock_info));\n\t\t\tbreak;\n\t\n\t\tdefault:\n\t\t\tret=NOT_DEFINED;\n\t}\n\treturn ret;\n}\n\nu32\tClock_x86::remove(){\n\tdelete this;\n\treturn RETURN_OK;\n}\n"
  },
  {
    "path": "src/kernel/modules/clock_x86.h",
    "content": "\r\n#ifndef __CLOCK__\r\n#define __CLOCK__\r\n\r\n#include <runtime/types.h>\r\n#include <core/device.h>\r\n#include <io.h>\r\n\r\n#include <api/dev/clock.h>\r\n\r\nclass Clock_x86 : public Device\r\n{\r\n\tpublic:\r\n\t\tClock_x86(char* n);\r\n\t\t~Clock_x86();\r\n\t\t\r\n\t\t\r\n\t\tu32\t\topen(u32 flag);\r\n\t\tu32\t\tclose();\r\n\t\tu32\t\tread(u32 pos,u8* buffer,u32 size);\r\n\t\tu32\t\twrite(u32 pos,u8* buffer,u32 size);\r\n\t\tu32\t\tioctl(u32 id,u8* buffer);\r\n\t\tu32\t\tremove();\r\n\t\tvoid\tscan();\r\n\t\t\r\n\t\tvoid \treset_info();\r\n\tprivate:\r\n\t\tclock_info\tcinfo;\r\n};\r\n\r\n#endif\r\n"
  },
  {
    "path": "src/kernel/modules/dospartition.cc",
    "content": "#include <os.h>\n#include <dospartition.h>\n\n/*\n *\tFlag indique le numero de partition\n */\nFile* dospartition_mount(char* name,u32 flag,File* dev){\n\tDosPartition* dos=new DosPartition(name,dev,flag);\n\treturn dos;\n}\n\nmodule(\"module.dospartition\",MODULE_FILESYSTEM,DosPartition,dospartition_mount)\n\nDosPartition::~DosPartition(){\n\t\n}\n\nDosPartition::DosPartition(char* n,File* dev,u32 num) : Device(n)\n{\n\tdevice=dev;\n\tnumpart=num;\n\tpartition_info=NULL;\n\tif (device!=NULL){\n\t\tpartition_info=(dos_partition*)kmalloc(sizeof(dos_partition));\n\t\tdevice->read((u32)(DOS_PART_1+(u32)(numpart*sizeof(dos_partition))),\n\t\t\t\t\t (u8*)partition_info,\n\t\t\t\t\t sizeof(dos_partition));\t\n\t}\n}\n\nvoid DosPartition::scan(){\n\t\n}\n\nu32\tDosPartition::close(){\n\tif (partition_info!=NULL && device!=NULL){\n\t\treturn device->close();\n\t}\n\treturn ERROR_PARAM;\n}\n\nu32\tDosPartition::open(u32 flag){\n\tif (partition_info!=NULL && device!=NULL){\n\t\treturn device->open(flag);\n\t}\n\treturn ERROR_PARAM;\n}\n\nu32\tDosPartition::read(u32 pos,u8* buffer,u32 sizee){\n\tif (partition_info!=NULL && device!=NULL){\n\t\treturn device->read(((partition_info->s_lba)*512)+pos,buffer,sizee);\n\t}\n\treturn ERROR_PARAM;\n}\n\nu32\tDosPartition::write(u32 pos,u8* buffer,u32 sizee){\n\tif (partition_info!=NULL && device!=NULL){\n\t\treturn device->write((partition_info->s_lba*512)+pos,buffer,sizee);\n\t}\n\treturn ERROR_PARAM;\n}\n\nu32\tDosPartition::ioctl(u32 id,u8* buffer){\n\tif (partition_info!=NULL && device!=NULL){\n\t\treturn device->ioctl(id,buffer);\n\t}\n\treturn ERROR_PARAM;\n}\n\nu32\tDosPartition::remove(){\n\tdelete this;\n\treturn RETURN_OK;\n}\n\n\n"
  },
  {
    "path": "src/kernel/modules/dospartition.h",
    "content": "\r\n#ifndef __DOS_PARTITION__\r\n#define __DOS_PARTITION__\r\n\r\n#include <runtime/types.h>\r\n#include <core/file.h>\r\n#include <io.h>\r\n\r\n#define DOS_PART_1\t0x01BE\r\n#define DOS_PART_2\t0x01CE\r\n#define DOS_PART_3\t0x01DE\r\n#define DOS_PART_4\t0x01EE\r\n\r\nstruct dos_partition {\r\n\tu8 bootable;\t\t\t/* 0 = no, 0x80 = bootable */\r\n\tu8 s_head;\t\t\t\t/* Starting head */\r\n\tu16 s_sector:6;\t\t\t/* Starting sector */\r\n\tu16 s_cyl:10;\t\t\t/* Starting cylinder */\r\n\tu8 id;\t\t\t\t\t/* System ID */\r\n\tu8 e_head;\t\t\t\t/* Ending Head */\r\n\tu16 e_sector:6;\t\t\t/* Ending Sector */\r\n\tu16 e_cyl:10;\t\t\t/* Ending Cylinder */\r\n\tu32 s_lba;\t\t\t\t/* Starting LBA value */\r\n\tu32 size;\t\t\t\t/* Total Sectors in partition */\r\n} __attribute__ ((packed));\r\n \r\n/*\r\n *\tDriver class\r\n */\r\nclass DosPartition : public Device\r\n{\r\n\tpublic:\r\n\t\tDosPartition(char* n,File* dev,u32 num);\r\n\t\t~DosPartition();\r\n\t\t\r\n\t\t\r\n\t\tu32\t\topen(u32 flag);\r\n\t\tu32\t\tclose();\r\n\t\tu32\t\tread(u32 pos,u8* buffer,u32 sizee);\r\n\t\tu32\t\twrite(u32 pos,u8* buffer,u32 sizee);\r\n\t\tu32\t\tioctl(u32 id,u8* buffer);\r\n\t\tu32\t\tremove();\r\n\t\tvoid\tscan();\r\n\t\t\r\n\r\n\tprivate:\r\n\t\tu32 \t\t\tnumpart;\r\n\t\tdos_partition*\tpartition_info;\r\n};\r\n\r\n#endif\r\n"
  },
  {
    "path": "src/kernel/modules/ext2.cc",
    "content": "\n \n#include <os.h>\n#include <ext2.h>\n\n\nFile* ext2_mount(char* name,u32 flag,File* dev){\n\tint ret=ext2_check_disk(dev);\n\tif (ret!=RETURN_OK){\n\t\tio.print(\"ext2: can't mount %s in %s \\n\",dev->getName(),name);\n\t\treturn NULL;\n\t}\n\telse{\t\n\t\tio.print(\"ext2:  mount %s in %s \\n\",dev->getName(),name);\n\t\tExt2* ret=new Ext2(name);\n\t\tret->ext2inode=EXT2_INUM_ROOT;\n\t\text2_get_disk_info(dev,ret);\n\t\tret->scan();\n\t\treturn ret;\n\t}\n}\n\nmodule(\"module.ext2\",MODULE_FILESYSTEM,Ext2,ext2_mount)\n\nExt2::~Ext2(){\n\t\n}\n\nExt2::Ext2(char* n) : File(n,TYPE_DIRECTORY)\n{\n\tmap=NULL;\n}\n\nvoid Ext2::scan(){\n\text2_scan(this);\n}\n\nu32\tExt2::close(){\n\treturn NOT_DEFINED;\n}\n\nu32\tExt2::open(u32 flag){\n\text2_inode *inodee=ext2_read_inode(disk,ext2inode);\n\tmap=ext2_read_file(disk,inodee);\n\tkfree(inodee);\n\treturn RETURN_OK;\n}\n\nu32\tExt2::read(u32 pos,u8* buffer,u32 sizee){\n\tu32 bufsize=sizee;\n\tif ((pos + bufsize) > (size))\n\t\tbufsize = (u32)(size) - pos;\n\tmemcpy((char*)buffer, (char *) (map + pos), bufsize);\n\treturn bufsize;\n}\n\nu32\tExt2::write(u32 pos,u8* buffer,u32 sizee){\n\treturn NOT_DEFINED;\n}\n\nu32\tExt2::ioctl(u32 id,u8* buffer){\n\treturn NOT_DEFINED;\n}\n\nu32\tExt2::remove(){\n\tdelete this;\n\treturn RETURN_OK;\n}\n\n\n\n/*\n *\tEXT2 specification\n */\nint ext2_read_sb(File* dev,ext2_super_block *sb)\n{\n\tif (dev!=NULL){\n\t\tdev->read((u32)1024,(u8 *) sb,sizeof(ext2_super_block));\n\t\treturn RETURN_OK;\n\t}\n\telse\n\t\treturn ERROR_PARAM;\n}\n\nint ext2_read_gd(File* fdev,ext2_group_desc *gd,ext2_disk* info)\n{\n\tif (fdev!=NULL){\n\t\tu32 offset;\n\t\toffset = ((info->blocksize == 1024) ? 2048 : info->blocksize);\n\t\tint gd_size = (info->groups * ((int)sizeof(struct ext2_group_desc)));\n\t\tfdev->read(offset,(u8*) gd,gd_size);\n\t\treturn RETURN_OK;\n\t}\n\telse\n\t\treturn ERROR_PARAM;\n}\n\nvoid ext2_get_disk_info(File*dev,Ext2 *fp)\n{\n\text2_disk* info=(ext2_disk*)kmalloc(sizeof(ext2_disk));\n\tinfo->sb=(ext2_super_block*)kmalloc(sizeof(ext2_super_block));\n\tinfo->dev=dev;\n\tint i, j;\n\text2_read_sb(dev,info->sb);\n\tinfo->blocksize = 1024 << ((info->sb)->s_log_block_size);\n\ti = (info->sb->s_blocks_count / info->sb->s_blocks_per_group) + ((info->sb->s_blocks_count % info->sb->s_blocks_per_group) ? 1 : 0);\n\tj = (info->sb->s_inodes_count / info->sb->s_inodes_per_group) + ((info->sb->s_inodes_count % info->sb->s_inodes_per_group) ? 1 : 0);\n\tinfo->groups = (i > j) ? i : j;\n\tint gd_size = info->groups * ((int)sizeof(ext2_group_desc));\n\tinfo->gd = (ext2_group_desc *) kmalloc(gd_size);\n\text2_read_gd(info->dev,info->gd,info);\n\tfp->disk=info;\n\treturn;\n}\nint ext2_check_disk(File *dev)\n{\n\text2_super_block *sb=(ext2_super_block *)kmalloc(sizeof(ext2_super_block));\n\tif (ext2_read_sb(dev,sb)!=RETURN_OK)\n\t\treturn ERROR_PARAM;\n\tif (sb->s_magic==0xEF53){\n\t\tkfree(sb);\n\t\treturn RETURN_OK;\n\t}\n\telse{\n\t\tkfree(sb);\n\t\treturn ERROR_PARAM;\n\t}\n}\next2_inode *ext2_read_inode(ext2_disk* hd, int i_num)\n{\n\tint gr_num, index;\n\tu32 offset;\n\text2_inode *inode;\n\text2_group_desc * info=hd->gd;\n\tinode = (ext2_inode *) kmalloc((hd->sb)->s_inode_size);//sizeof(ext2_inode));\n\tgr_num = (i_num - 1) / ((hd->sb)->s_inodes_per_group);\n\tindex = (i_num - 1) % ((hd->sb)->s_inodes_per_group);\n\toffset = (info[gr_num].bg_inode_table * (hd->blocksize)) + (index * ((hd->sb)->s_inode_size));\n\tif ((hd->dev)!=NULL){\n\t\t(hd->dev)->read(offset,(u8*) inode,(hd->sb)->s_inode_size);\n\t}\n\treturn inode;\n}\nint ext2_is_directory(Ext2 *fp)\n{\n\text2_inode *inod=ext2_read_inode(fp->disk,fp->ext2inode);\n\tint ret=(inod->i_mode & EXT2_S_IFDIR) ? 1 : 0;\n\tkfree(inod);\n\treturn ret;\n}\nchar *ext2_read_file(ext2_disk *hd,ext2_inode *inode)\n{\n\tFile *dev=hd->dev;\n\t\n\tchar *mmap_base, *mmap_head, *buf;\n\n\tint *p, *pp, *ppp;\n\tint i, j, k;\n\tint n, size;\n\n\tbuf = (char *) kmalloc(hd->blocksize);\n\tp = (int *) kmalloc(hd->blocksize);\n\tpp = (int *) kmalloc(hd->blocksize);\n\tppp = (int *) kmalloc(hd->blocksize);\n\n\t/* taille totale du fichier */\n\tsize = inode->i_size;\n\tmmap_head = mmap_base = (char*)kmalloc(size);\n\t/* direct block number */\n\tfor (i = 0; i < 12 && inode->i_block[i]; i++) {\n        dev->read((u32)(inode->i_block[i] * hd->blocksize),(u8*) buf, (hd->blocksize));\n\t\tn = ((size > (int)hd->blocksize) ? (int)hd->blocksize : size);\n\t\tmemcpy(mmap_head, buf, n);\n\t\tmmap_head += n;\n\t\tsize -= n;\n\t}\n\t/* indirect block number */\n\tif (inode->i_block[12]) {\n\t    dev->read((u32)(inode->i_block[12] * hd->blocksize), (u8*) p, (hd->blocksize));\n\n\n\t\tfor (i = 0; i < (int)hd->blocksize / 4 && p[i]; i++) {\n            dev->read((u32)(p[i] * hd->blocksize),(u8*)buf, (hd->blocksize));\n\t\t\tn = ((size > (int)hd->blocksize) ? (int)hd->blocksize : size);\n\t\t\tmemcpy(mmap_head, buf, n);\n\t\t\tmmap_head += n;\n\t\t\tsize -= n;\n\t\t}\n\t}\n\n\t/* bi-indirect block number */\n\tif (inode->i_block[13]) {\n\t    dev->read((u32)(inode->i_block[13] * hd->blocksize), (u8*) p, (hd->blocksize));\n\n\t\tfor (i = 0; i < (int)hd->blocksize / 4 && p[i]; i++) {\n            dev->read((u32)(p[i] * (int)hd->blocksize), (u8*) pp,(hd->blocksize));\n\t\t\tfor (j = 0; j < (int)hd->blocksize / 4 && pp[j]; j++) {\n                dev->read((u32)(pp[j] * hd->blocksize),(u8*)buf,(hd->blocksize));\n\t\t\t\tn = ((size > (int)hd-> blocksize) ? (int)hd->blocksize : size);\n\t\t\t\tmemcpy(mmap_head, buf, n);\n\t\t\t\tmmap_head += n;\n\t\t\t\tsize -= n;\n\t\t\t}\n\t\t}\n\t}\n\t/* tri-indirect block number */\n\tif (inode->i_block[14]) {\n        dev->read((u32)(inode->i_block[14] * hd->blocksize), (u8*) p,(hd->blocksize));\n\t\tfor (i = 0; i < (int)hd->blocksize / 4 && p[i]; i++) {\n            dev->read((u32)(p[i] * hd->blocksize), (u8*) pp,(hd->blocksize));\n\t\t\tfor (j = 0; j < (int)hd->blocksize / 4 && pp[j]; j++) {\n                dev->read((u32)(pp[j] * hd->blocksize), (u8*) ppp,(hd->blocksize));\n\t\t\t\tfor (k = 0; k < (int)hd->blocksize / 4 && ppp[k]; k++) {\n                    dev->read((u32)(ppp[k] * hd->blocksize),(u8*)buf,(hd->blocksize));\n\t\t\t\t\tn = ((size > (int)hd->blocksize) ? (int)hd->blocksize : size);\n\t\t\t\t\tmemcpy(mmap_head, buf, n);\n\t\t\t\t\tmmap_head += n;\n\t\t\t\t\tsize -= n;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tkfree(buf);\n\tkfree(p);\n\tkfree(pp);\n\tkfree(ppp);;\n\treturn mmap_base;\n}\nint ext2_scan(Ext2 *dir)\n{\n\text2_directory_entry *dentry;\n\tExt2 *leaf;\n\tu32 dsize;\n\tchar *filename;\n\tint f_toclose;\n\text2_inode *inode = ext2_read_inode(dir->disk, dir->ext2inode);\n\tif (dir->getType()!=TYPE_DIRECTORY) {\n\t\treturn ERROR_PARAM;\n\t}\n\t\n\tif (!dir->map) {\n\t\tdir->map = ext2_read_file(dir->disk, inode);\n\t\tf_toclose = 1;\n\t} else {\n\t\tf_toclose = 0;\n\t}\n\t\n\tdsize = inode->i_size;\n\tdentry = (ext2_directory_entry *) dir->map;\n\twhile (inode && dsize) {\n\t\t\t\tfilename = (char *) kmalloc(dentry->name_len + 1);\n\t\t\t\tmemcpy(filename,(char*)&(dentry->name), dentry->name_len);\n\t\t\t\tfilename[dentry->name_len] = 0;\n\t\t\t\tif (strcmp(\".\", filename) && strcmp(\"..\", filename)) {\n\t\t\t\t\tif (dir->find(filename)==NULL) {\n\t\t\t\t\t\tleaf= new Ext2(filename);\n\t\t\t\t\t\tleaf->ext2inode = dentry->inode;\n\t\t\t\t\t\tleaf->disk=dir->disk;\n\t\t\t\t\t\tif (ext2_is_directory(leaf))\n\t\t\t\t\t\t\tleaf->setType(TYPE_DIRECTORY);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tleaf->setType(TYPE_FILE);\n\t\t\t\t\t\tdir->addChild(leaf);\n\t\t\t\t\t\tleaf->map = 0;\n\t\t\t\t\t\text2_inode *inod=ext2_read_inode((ext2_disk*)leaf->disk,leaf->ext2inode);\n\t\t\t\t\t\tleaf->setSize(inod->i_size);\n\t\t\t\t\t\tkfree(inod);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tkfree(filename);\n\t\tdsize -= dentry->rec_len;\n\t\tdentry = (ext2_directory_entry *) ((char *) dentry + dentry->rec_len);\n\t}\n\tkfree(inode);\n\tif (f_toclose == 1) {\n\t\tkfree(dir->map);\n\t\tdir->map = 0;\n\t}\n\treturn 0;\n}\n"
  },
  {
    "path": "src/kernel/modules/ext2.h",
    "content": "\r\n#ifndef __EXT2__\r\n#define __EXT2__\r\n\r\n#include <runtime/types.h>\r\n#include <core/file.h>\r\n#include <io.h>\r\n\r\n/*\r\n *\tExt2 specification\r\n */\r\nstruct ext2_super_block {\r\n\tu32 s_inodes_count;\t/* Total number of inodes */\r\n\tu32 s_blocks_count;\t/* Total number of blocks */\r\n\tu32 s_r_blocks_count;\t/* Total number of blocks reserved for the super user */\r\n\tu32 s_free_blocks_count;\t/* Total number of free blocks */\r\n\tu32 s_free_inodes_count;\t/* Total number of free inodes */\r\n\tu32 s_first_data_block;\t/* Id of the block containing the superblock structure */\r\n\tu32 s_log_block_size;\t/* Used to compute block size = 1024 << s_log_block_size */\r\n\tu32 s_log_frag_size;\t/* Used to compute fragment size */\r\n\tu32 s_blocks_per_group;\t/* Total number of blocks per group */\r\n\tu32 s_frags_per_group;\t/* Total number of fragments per group */\r\n\tu32 s_inodes_per_group;\t/* Total number of inodes per group */\r\n\tu32 s_mtime;\t\t/* Last time the file system was mounted */\r\n\tu32 s_wtime;\t\t/* Last write access to the file system */\r\n\tu16 s_mnt_count;\t/* How many `mount' since the last was full verification */\r\n\tu16 s_max_mnt_count;\t/* Max count between mount */\r\n\tu16 s_magic;\t\t/* = 0xEF53 */\r\n\tu16 s_state;\t\t/* File system state */\r\n\tu16 s_errors;\t\t/* Behaviour when detecting errors */\r\n\tu16 s_minor_rev_level;\t/* Minor revision level */\r\n\tu32 s_lastcheck;\t/* Last check */\r\n\tu32 s_checkinterval;\t/* Max. time between checks */\r\n\tu32 s_creator_os;\t/* = 5 */\r\n\tu32 s_rev_level;\t/* = 1, Revision level */\r\n\tu16 s_def_resuid;\t/* Default uid for reserved blocks */\r\n\tu16 s_def_resgid;\t/* Default gid for reserved blocks */\r\n\tu32 s_first_ino;\t/* First inode useable for standard files */\r\n\tu16 s_inode_size;\t/* Inode size */\r\n\tu16 s_block_group_nr;\t/* Block group hosting this superblock structure */\r\n\tu32 s_feature_compat;\r\n\tu32 s_feature_incompat;\r\n\tu32 s_feature_ro_compat;\r\n\tu8 s_uuid[16];\t\t/* Volume id */\r\n\tchar s_volume_name[16];\t/* Volume name */\r\n\tchar s_last_mounted[64];\t/* Path where the file system was last mounted */\r\n\tu32 s_algo_bitmap;\t/* For compression */\r\n\tu8 s_padding[820];\r\n} __attribute__ ((packed));\r\n\r\n\r\nstruct ext2_group_desc {\r\n\tu32 bg_block_bitmap;\t/* Id of the first block of the \"block bitmap\" */\r\n\tu32 bg_inode_bitmap;\t/* Id of the first block of the \"inode bitmap\" */\r\n\tu32 bg_inode_table;\t/* Id of the first block of the \"inode table\" */\r\n\tu16 bg_free_blocks_count;\t/* Total number of free blocks */\r\n\tu16 bg_free_inodes_count;\t/* Total number of free inodes */\r\n\tu16 bg_used_dirs_count;\t/* Number of inodes allocated to directories */\r\n\tu16 bg_pad;\t\t/* Padding the structure on a 32bit boundary */\r\n\tu32 bg_reserved[3];\t/* Future implementation */\r\n} __attribute__ ((packed));\r\n\r\nstruct ext2_inode {\r\n\tu16 i_mode;\t\t/* File type + access rights */\r\n\tu16 i_uid;\r\n\tu32 i_size;\r\n\tu32 i_atime;\r\n\tu32 i_ctime;\r\n\tu32 i_mtime;\r\n\tu32 i_dtime;\r\n\tu16 i_gid;\r\n\tu16 i_links_count;\r\n\tu32 i_blocks;\t\t/* 512 bytes blocks ! */\r\n\tu32 i_flags;\r\n\tu32 i_osd1;\r\n\r\n\t/*\r\n\t * [0] -> [11] : block number (32 bits per block)\r\n\t * [12]        : indirect block number\r\n\t * [13]        : bi-indirect block number\r\n\t * [14]        : tri-indirect block number\r\n\t */\r\n\tu32 i_block[15];\r\n\r\n\tu32 i_generation;\r\n\tu32 i_file_acl;\r\n\tu32 i_dir_acl;\r\n\tu32 i_faddr;\r\n\tu8 i_osd2[12];\r\n} __attribute__ ((packed));\r\n\r\nstruct ext2_directory_entry {\r\n\tu32 inode;\t\t/* inode number or 0 (unused) */\r\n\tu16 rec_len;\t\t/* offset to the next dir. entry */\r\n\tu8 name_len;\t\t/* name length */\r\n\tu8 file_type;\r\n\tchar name;\r\n} __attribute__ ((packed));\r\n\r\n\r\nstruct ext2_disk {\r\n\text2_super_block*\tsb;\r\n\text2_group_desc*\tgd;\r\n\tu32 \t\t\t\tblocksize;\r\n\tu16 \t\t\t\tgroups;\t\t/* Total number of groups */\r\n\tFile*\t\t\t\tdev;\r\n};\r\n\r\n\r\n/* super_block: s_errors */\r\n#define\tEXT2_ERRORS_CONTINUE\t1\r\n#define\tEXT2_ERRORS_RO\t\t2\r\n#define\tEXT2_ERRORS_PANIC\t3\r\n#define\tEXT2_ERRORS_DEFAULT\t1\r\n\r\n/* inode: i_mode */\r\n#define\tEXT2_S_IFMT\t0xF000\t\t/* format mask  */\r\n#define\tEXT2_S_IFSOCK\t0xC000\t/* socket */\r\n#define\tEXT2_S_IFLNK\t0xA000\t/* symbolic link */\r\n#define\tEXT2_S_IFREG\t0x8000\t/* regular file */\r\n#define\tEXT2_S_IFBLK\t0x6000\t/* block device */\r\n#define\tEXT2_S_IFDIR\t0x4000\t/* directory */\r\n#define\tEXT2_S_IFCHR\t0x2000\t/* character device */\r\n#define\tEXT2_S_IFIFO\t0x1000\t/* fifo */\r\n\r\n#define\tEXT2_S_ISUID\t0x0800\t/* SUID */\r\n#define\tEXT2_S_ISGID\t0x0400\t/* SGID */\r\n#define\tEXT2_S_ISVTX\t0x0200\t/* sticky bit */\r\n#define\tEXT2_S_IRWXU\t0x01C0\t/* user access rights mask */\r\n#define\tEXT2_S_IRUSR\t0x0100\t/* read */\r\n#define\tEXT2_S_IWUSR\t0x0080\t/* write */\r\n#define\tEXT2_S_IXUSR\t0x0040\t/* execute */\r\n#define\tEXT2_S_IRWXG\t0x0038\t/* group access rights mask */\r\n#define\tEXT2_S_IRGRP\t0x0020\t/* read */\r\n#define\tEXT2_S_IWGRP\t0x0010\t/* write */\r\n#define\tEXT2_S_IXGRP\t0x0008\t/* execute */\r\n#define\tEXT2_S_IRWXO\t0x0007\t/* others access rights mask */\r\n#define\tEXT2_S_IROTH\t0x0004\t/* read */\r\n#define\tEXT2_S_IWOTH\t0x0002\t/* write */\r\n#define\tEXT2_S_IXOTH\t0x0001\t/* execute */\r\n\r\n#define EXT2_INUM_ROOT\t2\r\n \r\n/*\r\n *\tDriver class\r\n */\r\nclass Ext2 : public File\r\n{\r\n\tpublic:\r\n\t\tExt2(char* n);\r\n\t\t~Ext2();\r\n\t\t\r\n\t\t\r\n\t\tu32\t\topen(u32 flag);\r\n\t\tu32\t\tclose();\r\n\t\tu32\t\tread(u32 pos,u8* buffer,u32 sizee);\r\n\t\tu32\t\twrite(u32 pos,u8* buffer,u32 sizee);\r\n\t\tu32\t\tioctl(u32 id,u8* buffer);\r\n\t\tu32\t\tremove();\r\n\t\tvoid\tscan();\r\n\t\t\r\n\t\tchar*\t\tmap;\r\n\t\text2_disk*\tdisk;\r\n\t\tint \t\text2inode;\r\n\tprivate:\r\n\t\t\r\n};\r\n\r\nint \t\t\text2_check_disk(File *dev);\r\nvoid \t\t\text2_get_disk_info(File*dev,Ext2 *fp);\r\nint \t\t\text2_read_gd(File* fdev,ext2_group_desc *gd,ext2_disk* info);\r\nint \t\t\text2_read_sb(File* dev,ext2_super_block *sb);\r\next2_inode*\t\text2_read_inode(ext2_disk* hd, int i_num);\r\nint \t\t\text2_is_directory(Ext2 *fp);\r\nint \t\t\text2_scan(Ext2 *dir);\r\nchar *\t\t\text2_read_file(ext2_disk *hd,ext2_inode *inode);\r\n\r\n#endif\r\n"
  },
  {
    "path": "src/kernel/modules/ide.cc",
    "content": "\n#include <os.h>\n#include <ide.h>\n\n#include <api/dev/ioctl.h>\n\n\n/*\n *\tCette fonction attend que le disque soit pret avant une operation\n */\nint bl_wait(unsigned short base)\n{\n\twhile(io.inb(base+0x206) & 0x80);\n\treturn 0;\t\n}\n\n/*\n *\tCette fonction permet de ce deplacer sur le disque\n */\nint bl_common(int drive, int numblock, int count)\n{\n\tbl_wait(0x1F0);\n\t\n\tio.outb(0x1F1, 0x00);\t/* NULL byte to port 0x1F1 */\n\tio.outb(0x1F2, count);\t/* Sector count */\n\tio.outb(0x1F3, (unsigned char) numblock);\t/* Low 8 bits of the block address */\n\tio.outb(0x1F4, (unsigned char) (numblock >> 8));\t/* Next 8 bits of the block address */\n\tio.outb(0x1F5, (unsigned char) (numblock >> 16));\t/* Next 8 bits of the block address */\n\n\t/* Drive indicator, magic bits, and highest 4 bits of the block address */\n\tio.outb(0x1F6, 0xE0 | (drive << 4) | ((numblock >> 24) & 0x0F));\n\n\treturn 0;\n}\n\n/*\n *\tCette fonction permet de lire un buffer sur le disque\n */\nint bl_read(int drive, int numblock, int count, char *buf)\n{\n\tu16 tmpword;\n\tint idx;\n\n\tbl_common(drive, numblock, count);\n\tio.outb(0x1F7, 0x20);\n\n\tbl_wait(0x1F0);\n\twhile (!(io.inb(0x1F7) & 0x08));\n\n\tfor (idx = 0; idx < 256 * count; idx++) {\n\t\ttmpword = io.inw(0x1F0);\n\t\tbuf[idx * 2] = (unsigned char) tmpword;\n\t\tbuf[idx * 2 + 1] = (unsigned char) (tmpword >> 8);\n\t}\n\treturn count;\n}\n\n/*\n *\tCette fonction permet d'ecrire un buffer sur le disque\n */\nint bl_write(int drive, int numblock, int count, char *buf)\n{\n\tu16 tmpword;\n\tint idx;\n\n\tbl_common(drive, numblock, count);\n\tio.outb(0x1F7, 0x30);\n\tbl_wait(0x1F0);\n\t/* Wait for the drive to signal that it's ready: */\n\twhile (!(io.inb(0x1F7) & 0x08));\n\n\tfor (idx = 0; idx < 256 * count; idx++) {\n\t\ttmpword = (buf[idx * 2 + 1] << 8) | buf[idx * 2];\n\t\tio.outw(0x1F0, tmpword);\n\t}\n\n\treturn count;\n}\n\n\n\n\nFile* ide_mknod(char* name,u32 flag,File* dev){\n\tIde* disk=new Ide(name);\n\tdisk->setId(flag);\n\treturn disk;\n}\n\nmodule(\"module.ide\",MODULE_DEVICE,Ide,ide_mknod)\n\nIde::~Ide(){\n\t\n}\n\nIde::Ide(char* n) : Device(n)\n{\n\t\n}\n\nu32\tIde::close(){\n\treturn RETURN_OK;\n}\n\nvoid Ide::scan(){\n\t\n}\n\nu32\tIde::open(u32 flag){\n\treturn RETURN_OK;\n}\n\nu32\tIde::read(u32 pos,u8* buffer,u32 sizee){\n\tint count=(int)sizee;\n\t\n\tif (buffer==NULL)\n\t\treturn -1;\n\t\n\tint offset=(int)pos;\n\tint bl_begin, bl_end, blocks;\n\n\tbl_begin = (offset/512);\n\tbl_end = ((offset + count)/512);\n\tblocks = bl_end - bl_begin + 1;\n\t//io.print(\"%s> read at %d - %d  size=%d begin=%d blocks=%d\\n\",getName(),offset,offset/512,count,bl_begin,blocks);\n\tchar*bl_buffer = (char *) kmalloc(blocks * 512);\n\tbl_read(id, bl_begin, blocks,bl_buffer);\n\tmemcpy((char*)buffer, (char *) ((int)bl_buffer + ((int)offset % (int)(512))), count);\n\tkfree(bl_buffer);\n\treturn count;\n}\n\nu32\tIde::write(u32 pos,u8* buffer,u32 sizee){\n\treturn NOT_DEFINED;\n}\n\nu32\tIde::ioctl(u32 idd,u8* buffer){\n\tu32 ret=0;\n\tswitch (idd){\n\t\tcase DEV_GET_TYPE:\n\t\t\tret=DEV_TYPE_DISK;\n\t\t\tbreak;\n\t\t\t\n\t\tcase DEV_GET_STATE:\n\t\t\tret=DEV_STATE_OK;\n\t\t\tbreak;\n\t\t\t\n\t\tcase DEV_GET_FORMAT:\n\t\t\tret=DEV_FORMAT_BLOCK;\n\t\t\tbreak;\n\t\t\t\n\t\tdefault:\n\t\t\tret=NOT_DEFINED;\n\t\t\tbreak;\n\t}\t\n\treturn ret;\n}\n\n\n\nu32\tIde::remove(){\n\tdelete this;\n\treturn RETURN_OK;\n}\n\nvoid Ide::setId(u32 flag){\n\tid=flag;\n}\n"
  },
  {
    "path": "src/kernel/modules/ide.h",
    "content": "\r\n#ifndef __IDE__\r\n#define __IDE__\r\n\r\n#include <runtime/types.h>\r\n#include <core/device.h>\r\n#include <io.h>\r\n\r\nclass Ide : public Device\r\n{\r\n\tpublic:\r\n\t\tIde(char* n);\r\n\t\t~Ide();\r\n\t\t\r\n\t\t\r\n\t\tu32\t\topen(u32 flag);\r\n\t\tu32\t\tclose();\r\n\t\tu32\t\tread(u32 pos,u8* buffer,u32 size);\r\n\t\tu32\t\twrite(u32 pos,u8* buffer,u32 size);\r\n\t\tu32\t\tioctl(u32 id,u8* buffer);\r\n\t\tu32\t\tremove();\r\n\t\tvoid\tscan();\r\n\t\t\r\n\t\tvoid\tsetId(u32 flag);\r\n\t\t\r\n\tprivate:\r\n\t\tu32 id;\r\n\r\n};\r\n\r\n#endif\r\n"
  },
  {
    "path": "src/kernel/modules/keys.cc",
    "content": "\n#include <os.h>\n#include <keys.h>\n\n#include <api/dev/ioctl.h>\n\nextern char* kbdmap;\n\nFile* keys_mknod(char* name,u32 flag,File* dev){\n\tKeyboard* cons=new Keyboard(name);\n\treturn cons;\n}\n\nmodule(\"module.keyboard\",MODULE_DEVICE,Keyboard,keys_mknod)\n\nKeyboard::~Keyboard(){\n\t\n}\n\nKeyboard::Keyboard(char* n) : Device(n)\n{\n\n}\n\nvoid Keyboard::scan(){\n\n}\n\nu32\tKeyboard::close(){\n\treturn RETURN_OK;\n}\n\nu32\tKeyboard::open(u32 flag){\n\treturn RETURN_OK;\n}\n\nu32\tKeyboard::read(u32 pos,u8* buffer,u32 sizee){\n\treturn NOT_DEFINED;\n}\n\nu32\tKeyboard::write(u32 pos,u8* buffer,u32 sizee){\n\treturn NOT_DEFINED;\n}\n\nu32\tKeyboard::ioctl(u32 id,u8* buffer){\n\tu32 ret=0;\n\tswitch (id){\n\t\tcase DEV_GET_TYPE:\n\t\t\tret=DEV_TYPE_TTY;\n\t\t\tbreak;\n\t\t\t\n\t\tcase DEV_GET_STATE:\n\t\t\tret=DEV_STATE_OK;\n\t\t\tbreak;\n\t\t\t\n\t\tcase DEV_GET_FORMAT:\n\t\t\tret=DEV_FORMAT_CHAR;\n\t\t\tbreak;\n\t\t\t\n\t\tcase API_KEYBOARD_SET_TABLE:\n\t\t\tmemcpy(scantable,(char*)buffer,TABLE_KEYBOARD_SIZE);\n\t\t\tkbdmap=scantable;\n\t\t\tret=TABLE_KEYBOARD_SIZE;\n\t\t\tbreak;\n\t\n\t\tdefault:\n\t\t\tret=NOT_DEFINED;\n\t}\n\treturn ret;\n}\n\nu32\tKeyboard::remove(){\n\tdelete this;\n\treturn RETURN_OK;\n}\n"
  },
  {
    "path": "src/kernel/modules/keys.h",
    "content": "\r\n#ifndef __KEYS__\r\n#define __KEYS__\r\n\r\n#include <runtime/types.h>\r\n#include <core/device.h>\r\n#include <io.h>\r\n\r\n#include <api/dev/keyboard.h>\r\n\r\nclass Keyboard : public Device\r\n{\r\n\tpublic:\r\n\t\tKeyboard(char* n);\r\n\t\t~Keyboard();\r\n\t\t\r\n\t\t\r\n\t\tu32\t\topen(u32 flag);\r\n\t\tu32\t\tclose();\r\n\t\tu32\t\tread(u32 pos,u8* buffer,u32 size);\r\n\t\tu32\t\twrite(u32 pos,u8* buffer,u32 size);\r\n\t\tu32\t\tioctl(u32 id,u8* buffer);\r\n\t\tu32\t\tremove();\r\n\t\tvoid\tscan();\r\n\t\t\r\n\tprivate:\r\n\t\tchar\tscantable[TABLE_KEYBOARD_SIZE];\r\n};\r\n\r\n#endif\r\n"
  },
  {
    "path": "src/kernel/modules/module.cc",
    "content": "\n#include <os.h>\n#include <core/file.h>\n#include <runtime/alloc.h>\n#include <runtime/libc.h>\n#include <core/filesystem.h>\n#include <module.h>\n\n/* Inclusion de la liste des modules */\n#include \"modules.conf\"\n\t\nModule::Module(){\n\n}\n\nModule::~Module(){\n\n}\n\t\t\nvoid Module::initLink(){\n\tint i=0;\n\tModLink* mod;\n\twhile (module_builder[i] != 0){\n\t\tmod=new ModLink(module_builder[i]->module_name);\n\t\ti=i++;\n\t}\n}\n\nFile* Module::createDevice(char* name,char* module,u32 flag){\n\tint i=0;\n\tFile* fp;\n\twhile (module_builder[i] != 0){\n\t\tif (!strcmp(module_builder[i]->module_name,module)){\n\t\t\t\n\t\t\tif (module_builder[i]->module_type==MODULE_DEVICE){\n\t\t\t\tfp=module_builder[i]->drive(name,flag,NULL);\n\t\t\t\treturn fp;\n\t\t\t}\n\t\t}\n\t\t\n\t\ti=i++;\n\t}\n\treturn NULL;\n}\n\nFile* Module::mount(char* dev,char* dir,char* module,u32 flag){\n\tFile* fdev=fsm.path(dev);\n\tif (fdev==NULL)\n\t\treturn NULL;\n\tint i=0;\n\tFile* fp;\n\twhile (module_builder[i] != 0){\n\t\tif (!strcmp(module_builder[i]->module_name,module)){\n\t\t\tfp=module_builder[i]->drive(dir,flag,fdev);\n\t\t\tif (module_builder[i]->module_type==MODULE_FILESYSTEM && fp!=NULL){\n\t\t\t\tfsm.addFile(\"/mnt/\",fp);\n\t\t\t\tfp->setType(TYPE_DIRECTORY);\n\t\t\t\treturn fp;\n\t\t\t}\n\t\t\telse\n\t\t\t\treturn NULL;\n\t\t}\n\t\t\n\t\ti=i++;\n\t}\n\treturn NULL;\n}\n\nFile* Module::install(char* dir,char* module,u32 flag,char* dev){\n\tFile* fdev=fsm.path(dev);\n\tif (fdev==NULL)\n\t\treturn NULL;\n\tint i=0;\n\tFile* fp;\n\twhile (module_builder[i] != 0){\n\t\tif (!strcmp(module_builder[i]->module_name,module)){\n\t\t\tif (module_builder[i]->module_type==MODULE_FILESYSTEM){\n\t\t\t\treturn module_builder[i]->drive(dir,flag,fdev);\n\t\t\t}\n\t\t}\n\t\t\n\t\ti=i++;\n\t}\n\treturn NULL;\n}\n"
  },
  {
    "path": "src/kernel/modules/module.h",
    "content": "\r\n#ifndef __MODULE__\r\n#define __MODULE__\r\n\r\n#include <runtime/types.h>\r\n#include <core/file.h>\r\n#include <io.h>\r\n\r\n\r\n#define NO_FLAG\t0\r\n\r\nclass Module\r\n{\r\n\tpublic:\r\n\t\tModule();\r\n\t\t~Module();\r\n\t\t\r\n\t\tvoid \tinitLink();\r\n\t\tvoid \tinit();\r\n\t\t\r\n\t\tFile*\tcreateDevice(char* name,char* module,u32 flag);\r\n\t\tFile*\tmount(char* dev,char* dir,char* module,u32 flag);\r\n\t\tFile*\tinstall(char* dir,char* module,u32 flag,char* dev);\r\n};\r\n\r\nextern Module\tmodm;\r\n\r\n#endif\r\n"
  },
  {
    "path": "src/kernel/modules/modules.conf",
    "content": "\r\nimport_module(Console);\r\nimport_module(Null);\r\nimport_module(Ide);\r\nimport_module(Bochs);\r\nimport_module(Ext2);\r\nimport_module(DosPartition);\r\nimport_module(Keyboard);\r\n\r\n#ifdef __x86__\r\nimport_module(Clock_x86);\r\nimport_module(X86Serial);\r\n#endif\r\n\r\nrun_module_builder{\r\n\tbuild_module(Console),\r\n\tbuild_module(Null),\r\n\tbuild_module(Ide),\r\n\tbuild_module(Bochs),\r\n\tbuild_module(X86Serial),\r\n\tbuild_module(Ext2),\r\n\tbuild_module(DosPartition),\r\n\tbuild_module(Clock_x86),\r\n\tbuild_module(Keyboard),\r\n\tend_module()\r\n};\r\n\r\nstd_buildin_module{\r\n\trun_module(module.keyboard,key,NO_FLAG)\r\n\t\r\n\trun_module(module.stdio,tty,1)\r\n\trun_module(module.stdio,tty0,NO_FLAG)\r\n\trun_module(module.stdio,tty1,NO_FLAG)\r\n\trun_module(module.stdio,tty2,NO_FLAG)\r\n\trun_module(module.stdio,tty3,NO_FLAG)\r\n\t\r\n\t\r\n\t#ifdef __x86__\r\n\trun_module(module.clock_x86,clock,NO_FLAG)\t\t/* clock info */\r\n\trun_module(module.x86serial,ttyS,NO_FLAG)\t\t/* serial console */\r\n\trun_module(module.ide,hda,0)\t\t\t\t\t/* hard disk 0 */\r\n\trun_module(module.ide,hdb,1)\t\t\t\t\t/* hard disk 1 */\r\n\trun_module(module.bvbe,fb0,0)\t\t\t\t\t/* BOCHS emulation vbe bios */\r\n\t#endif\r\n\t\r\n\trun_module(module.null,null,0)\r\n\trun_module(module.zero,zero,0)\r\n\t\r\n\t\r\n}\r\n\r\n"
  },
  {
    "path": "src/kernel/modules/null.cc",
    "content": "\n#include <os.h>\n#include <null.h>\n\n#include <api/dev/ioctl.h>\n\nFile* null_mknod(char* name,u32 flag,File* dev){\n\tNull* cons=new Null(name);\n\treturn cons;\n}\n\nmodule(\"module.null\",MODULE_DEVICE,Null,null_mknod)\n\nNull::~Null(){\n\t\n}\n\nNull::Null(char* n) : Device(n)\n{\n\n}\n\nvoid Null::scan(){\n\n}\n\nu32\tNull::close(){\n\treturn RETURN_OK;\n}\n\nu32\tNull::open(u32 flag){\n\treturn RETURN_OK;\n}\n\nu32\tNull::read(u32 pos,u8* buffer,u32 size){\n\tmemset((char*)buffer,0,size);\n\treturn size;\n}\n\nu32\tNull::write(u32 pos,u8* buffer,u32 size){\n\treturn size;\n}\n\nu32\tNull::ioctl(u32 id,u8* buffer){\n\tu32 ret=0;\n\tswitch (id){\n\t\tcase DEV_GET_TYPE:\n\t\t\tret=DEV_TYPE_TTY;\n\t\t\tbreak;\n\t\t\t\n\t\tcase DEV_GET_STATE:\n\t\t\tret=DEV_STATE_OK;\n\t\t\tbreak;\n\t\t\t\n\t\tcase DEV_GET_FORMAT:\n\t\t\tret=DEV_FORMAT_CHAR;\n\t\t\tbreak;\n\t\n\t\tdefault:\n\t\t\tret=NOT_DEFINED;\n\t}\n\treturn ret;\n}\n\nu32\tNull::remove(){\n\tdelete this;\n\treturn RETURN_OK;\n}\n"
  },
  {
    "path": "src/kernel/modules/null.h",
    "content": "\r\n#ifndef __NULL__\r\n#define __NULL__\r\n\r\n#include <runtime/types.h>\r\n#include <core/device.h>\r\n#include <io.h>\r\n\r\nclass Null : public Device\r\n{\r\n\tpublic:\r\n\t\tNull(char* n);\r\n\t\t~Null();\r\n\t\t\r\n\t\t\r\n\t\tu32\t\topen(u32 flag);\r\n\t\tu32\t\tclose();\r\n\t\tu32\t\tread(u32 pos,u8* buffer,u32 size);\r\n\t\tu32\t\twrite(u32 pos,u8* buffer,u32 size);\r\n\t\tu32\t\tioctl(u32 id,u8* buffer);\r\n\t\tu32\t\tremove();\r\n\t\tvoid\tscan();\r\n};\r\n\r\n#endif\r\n"
  },
  {
    "path": "src/kernel/modules/stdtty.cc",
    "content": "\n#include <os.h>\n#include <stdtty.h>\n\n\n\n\nFile* console_mknod(char* name,u32 flag,File* dev){\n\tConsole* cons=new Console(name,flag);\n\treturn cons;\n}\n\nmodule(\"module.stdio\",MODULE_DEVICE,Console,console_mknod)\n\nConsole::~Console(){\n\tif (iotty!=&io)\n\t\tdelete iotty;\n}\n\nConsole::Console(char* n,u32 flag) : Device(n)\n{\n\tif (flag==0)\n\t\tiotty=new Io(flag);\n\telse\n\t\tiotty=&io;\n}\n\nvoid Console::reset_info(){\n\t//static info\n\tstrncpy(sinfo.name,name,TTY_NAME_LEN);\n\tsinfo.state=TTY_STATE_RUN;\n\tsinfo.type=TTY_TYPE_IOSTD;\n\tsinfo.flags=0;\n\t\n\t//moving info\n\tminfo.x=iotty->getX();\n\tminfo.y=iotty->getY();\n\tminfo.attrf=White;\n\tminfo.attrb=Black;\n}\n\nvoid Console::scan(){\n\n}\n\nu32\tConsole::open(u32 flag){\n\treturn RETURN_OK;\n}\n\nu32\tConsole::close(){\n\treturn RETURN_OK;\n}\n\nu32\tConsole::read(u32 pos,u8* buffer,u32 sizee){\n\treturn iotty->read((char*)buffer,sizee);\n}\n\nu32\tConsole::write(u32 pos,u8* buffer,u32 size){\t\n\tint i;\n\tfor (i=0;i<size;i++){\n\t\tiotty->putc(*buffer);\n\t\tbuffer++;\n\t}\n\treturn size;\n}\n\nu32\tConsole::ioctl(u32 id,u8* buffer){\n\tu32 ret=0;\n\treset_info();\n\tswitch (id){\n\t\tcase DEV_GET_TYPE:\n\t\t\tret=DEV_TYPE_TTY;\n\t\t\tbreak;\n\t\t\t\n\t\tcase DEV_GET_STATE:\n\t\t\tret=DEV_STATE_OK;\n\t\t\tbreak;\n\t\t\t\n\t\tcase DEV_GET_FORMAT:\n\t\t\tret=DEV_FORMAT_CHAR;\n\t\t\tbreak;\n\t\t\t\n\t\tcase API_TTY_SWITCH_SCREEN:\n\t\t\tiotty->switchtty();\n\t\t\tbreak;\n\t\t\t\n\t\tcase API_TTY_CLEAR_SCREEN:\n\t\t\tiotty->clear();\n\t\t\tbreak;\n\t\t\t\n\t\tcase API_TTY_GET_SINFO:\n\t\t\tmemcpy((char*)buffer,(char*)&sinfo,sizeof(tty_info_static));\n\t\t\tbreak;\n\t\t\t\n\t\tcase API_TTY_GET_MINFO:\n\t\t\tmemcpy((char*)buffer,(char*)&minfo,sizeof(tty_info_moving));\n\t\t\tbreak;\n\t\t\t\n\t\tcase API_TTY_SET_MINFO:\n\t\t\tbreak;\n\t\t\t\n\t\tdefault:\n\t\t\tret=NOT_DEFINED;\n\t\t\tbreak;\n\t}\n\treturn ret;\n}\n\nu32\tConsole::remove(){\n\tdelete this;\n\treturn RETURN_OK;\n}\n"
  },
  {
    "path": "src/kernel/modules/stdtty.h",
    "content": "\r\n#ifndef __CONSOLE__\r\n#define __CONSOLE__\r\n\r\n#include <runtime/types.h>\r\n#include <core/file.h>\r\n#include <io.h>\r\n\r\n#include <api/dev/ioctl.h>\r\n#include <api/dev/tty.h>\r\n\r\nclass Console : public Device\r\n{\r\n\tpublic:\r\n\t\tConsole(char* n,u32 flag);\r\n\t\t~Console();\r\n\t\t\r\n\t\t\r\n\t\tu32\t\topen(u32 flag);\r\n\t\tu32\t\tclose();\r\n\t\tu32\t\tread(u32 pos,u8* buffer,u32 size);\r\n\t\tu32\t\twrite(u32 pos,u8* buffer,u32 size);\r\n\t\tu32\t\tioctl(u32 id,u8* buffer);\r\n\t\tu32\t\tremove();\r\n\t\tvoid\tscan();\r\n\t\t\r\n\t\tvoid\treset_info();\r\n\t\t\r\n\tprivate:\r\n\t\ttty_info_static\tsinfo;\r\n\t\ttty_info_moving\tminfo;\r\n\t\r\n\t\tIo*\t\tiotty;\r\n};\r\n\r\n#endif\r\n"
  },
  {
    "path": "src/kernel/modules/x86serial.cc",
    "content": "\n#include <os.h>\n#include <x86serial.h>\n\n#include <api/dev/ioctl.h>\n#include <api/dev/tty.h>\n\n\nu8 X86Serial::init_serial=0;\n\nFile* x86serial_mknod(char* name,u32 flag,File* dev){\n\tX86Serial* cons=new X86Serial(name);\n\treturn cons;\n}\n\nmodule(\"module.x86serial\",MODULE_DEVICE,X86Serial,x86serial_mknod)\n\nX86Serial::~X86Serial(){\n\t\n}\n\nX86Serial::X86Serial(char* n) : Device(n)\n{\n\n}\n\n\nvoid X86Serial::putc(char c){\n\twhile(io.inb(COM1 + 5) & 0x20 == 0 );\n\t\tio.outb(COM1,c);\n}\n\nchar X86Serial::getc(){\n\twhile(io.inb(COM1 + 5) & 0x1 == 0 );\n\treturn (char)io.inb(COM1);\n}\n\nu32\tX86Serial::open(u32 flag){\n\tif (init_serial==0){\n\t\tio.outb( COM1 + 1,\t0x00 );\t\n\t\tio.outb( COM1 + 3,\t0x80 );\t\n\t\tio.outb( COM1,\t\t0x03 );\t\n\t\tio.outb( COM1 + 1,\t0x00 ); \n\t\tio.outb( COM1 + 3, 0x03 );\t\n\t\tio.outb( COM1 + 2, 0xC7 );\t\n\t\tio.outb( COM1 + 4, 0x0B );\t\n\t\tinit_serial=1;\n\t}\n\treturn RETURN_OK;\n}\n\nu32\tX86Serial::close(){\n\treturn RETURN_OK;\n}\n\nvoid X86Serial::scan(){\n\n}\n\nu32\tX86Serial::read(u32 pos,u8* buffer,u32 sizee){\n\tint i;\n\tfor (i=0;i<sizee;i++){\n\t\t*buffer=getc();\n\t\tbuffer++;\n\t}\n\treturn sizee;\n}\n\nu32\tX86Serial::write(u32 pos,u8* buffer,u32 sizee){\t\n\tint i;\n\tfor (i=0;i<sizee;i++){\n\t\tputc(*buffer);\n\t\tbuffer++;\n\t}\n\treturn sizee;\n}\n\nu32\tX86Serial::ioctl(u32 id,u8* buffer){\n\tu32 ret=0;\n\tswitch (id){\n\t\tcase DEV_GET_TYPE:\n\t\t\tret=DEV_TYPE_TTY;\n\t\t\tbreak;\n\t\t\t\n\t\tcase DEV_GET_STATE:\n\t\t\tret=DEV_STATE_OK;\n\t\t\tbreak;\n\t\t\t\n\t\tcase DEV_GET_FORMAT:\n\t\t\tret=DEV_FORMAT_CHAR;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tret=NOT_DEFINED;\n\t\t\tbreak;\n\t}\n\treturn ret;\n}\n\nu32\tX86Serial::remove(){\n\tdelete this;\n\treturn RETURN_OK;\n}\n"
  },
  {
    "path": "src/kernel/modules/x86serial.h",
    "content": "\r\n#ifndef __X86Serial__\r\n#define __X86Serial__\r\n\r\n#include <runtime/types.h>\r\n#include <core/device.h>\r\n#include <io.h>\r\n\r\n#define COM1\t   0x3F8\t\r\n#define IRQ_COM1   4\r\n#define COM2 \t   2F8 \t\r\n#define IRQ_COM2   3\r\n#define COM3 \t   3E8 \t\r\n#define IRQ_COM3   4\r\n#define COM4 \t   2E8 \t\r\n#define IRQ_COM4   3\r\n\r\n\r\nclass X86Serial : public Device\r\n{\r\n\tpublic:\r\n\t\tX86Serial(char* n);\r\n\t\t~X86Serial();\r\n\t\t\r\n\t\tvoid\tputc(char c);\r\n\t\tchar \tgetc();\r\n\t\t\r\n\t\tu32\t\topen(u32 flag);\r\n\t\tu32\t\tclose();\r\n\t\tu32\t\tread(u32 pos,u8* buffer,u32 size);\r\n\t\tu32\t\twrite(u32 pos,u8* buffer,u32 size);\r\n\t\tu32\t\tioctl(u32 id,u8* buffer);\r\n\t\tu32\t\tremove();\r\n\t\tvoid\tscan();\r\n\t\t\r\n\tprivate:\r\n\t\tstatic u8 init_serial;\r\n};\r\n\r\n#endif\r\n"
  },
  {
    "path": "src/kernel/runtime/Makefile",
    "content": "OBJS:=  $(OBJS) runtime/cxx.o runtime/itoa.o runtime/buffer.o \\\n\truntime/memory.o runtime/string.o\n\t\n"
  },
  {
    "path": "src/kernel/runtime/alloc.h",
    "content": "\n#ifndef ALLOC_H\n#define ALLOC_H\n\n\nextern \"C\" {\n\tvoid *ksbrk(int);\n\tvoid *kmalloc(unsigned long);\n\tvoid kfree(void *);\n}\n\n#endif\n"
  },
  {
    "path": "src/kernel/runtime/buffer.cc",
    "content": "\n#include <os.h>\n#include <runtime/buffer.h>\n\n\n\nBuffer::Buffer(char* n,u32 siz){\n\tmap=(char*)kmalloc(siz);\n\tsize=siz;\n\tmemcpy(map,n,siz);\n}\n\nBuffer::Buffer(){\n\tsize=0;\n\tmap=NULL;\n}\n\nBuffer::~Buffer(){\n\tif (map!=NULL)\n\t\tkfree(map);\n}\n\nvoid Buffer::add(u8* c,u32 s){\n\tchar* old=map;\n\tmap=(char*)kmalloc(size+s);\n\tmemcpy(map,old,size);\n\tkfree(old);\n\tmemcpy((char*)(map+size),(char*)c,s);\n\tsize=size+s;\n}\n\nu32 Buffer::get(u8* c,u32 s){\n\tif( s>size)\n\t\ts=size;\n\tmemcpy((char*)c,(char*)(map+(size-s)),s);\n\tchar*old=map;\n\tmap=(char*)kmalloc(size-s);\n\tmemcpy(map,old,(size-s));\n\tkfree(old);\n\tsize=size-s;\n\treturn s;\n}\n\nu32 Buffer::isEmpty(){\n\tif (size==0)\n\t\treturn 1;\n\telse\n\t\treturn 0;\n}\n\nvoid Buffer::clear(){\n\tsize=0;\n\tif (map!=NULL)\n\t\tkfree(map);\t\n}\n\nBuffer &Buffer::operator>>(char *c)\n{\n\tmemcpy(c,map,size);\n\treturn *this;\n}\n"
  },
  {
    "path": "src/kernel/runtime/buffer.h",
    "content": "\n#ifndef BUFFER_H\n#define BUFFER_H\n\n\nclass Buffer\n{\n\tpublic:\n\t\tBuffer(char* n,u32 siz);\n\t\tBuffer();\n\t\t~Buffer();\n\t\t\n\t\tvoid\tadd(u8* c,u32 s);\n\t\tu32\tget(u8* c,u32 s);\n\t\tvoid\tclear();\n\t\tu32\t\tisEmpty();\n\t\t\n\t\t\n\t\tBuffer &operator>>(char *c);\n\t\t\n\t\t\n\t\tu32 \tsize;\n\t\tchar*\tmap;\n\t\n};\n\n\n#endif\n"
  },
  {
    "path": "src/kernel/runtime/cxx.cc",
    "content": "#include <os.h>\n\nextern \"C\"\n{\n\t\n\tint __cxa_atexit(void (*Destructor) (void *), void *Parameter, void *HomeDSO);\n\tvoid __cxa_finalize(void *);\n\tvoid __cxa_pure_virtual();\n\tvoid __stack_chk_guard_setup();\n\tvoid __attribute__((noreturn)) __stack_chk_fail();\n\tvoid _Unwind_Resume();\n}\n\nvoid *__dso_handle;\t\nvoid *__stack_chk_guard(0);\n\n\nnamespace __cxxabiv1\n{\n\t__extension__ typedef int __guard __attribute__((mode(__DI__)));\n\n\textern \"C\"\n\t{\n\t\tint __cxa_guard_acquire(__guard *Guard)\t\t{ return ! *(char *) (Guard); }\n\t\tvoid __cxa_guard_release(__guard *Guard)\t{ *(char *) Guard = 1; }\n\t\tvoid __cxa_guard_abort(__guard *)\t\t\t{ }\n\t}\n}\n\n\nint __cxa_atexit(void (*) (void *), void *, void *)\n{\n\treturn 0;\n}\n\nvoid _Unwind_Resume(){\n\t\n}\n\nvoid __cxa_finalize(void *)\n{\n\t\n}\n\nvoid __cxa_pure_virtual()\n{\n\n}\n\nvoid __stack_chk_guard_setup()\n{\n\tunsigned char *Guard;\n\tGuard = (unsigned char *) &__stack_chk_guard;\n\tGuard[sizeof(__stack_chk_guard) - 1] = 255;\n\tGuard[sizeof(__stack_chk_guard) - 2] = '\\n';\n\tGuard[0] = 0;\n}\n\n\nstruct IntRegs;\n\nvoid __attribute__((noreturn)) __stack_chk_fail()\n{\n\tio.print(\"Buffer Overflow (SSP Signal)\\n\");\n\tfor(;;) ;\n}\n\nvoid operator delete(void *ptr) \n{\n\t\tkfree(ptr);\n}\n\n#ifndef __arm__\nvoid* operator new(size_t len) \n{\n\treturn (void*)kmalloc(len);\n}\n\nvoid operator delete[](void *ptr) \n{\n\t::operator delete(ptr);\n}\n\nvoid* operator new[](size_t len) \n{\n\treturn ::operator new(len);\n}\n\n#else\n\n\t\nvoid* operator new(size_t len) \n{\n\treturn (void*)kmalloc(len);\n}\n\nvoid operator delete[](void *ptr) \n{\n\t::operator delete(ptr);\n}\n\nvoid* operator new[](size_t len) \n{\n\treturn ::operator new(len);\n}\n#endif\n\n\nvoid *__gxx_personality_v0=(void*)0xDEADBEAF;\n"
  },
  {
    "path": "src/kernel/runtime/itoa.cc",
    "content": "\n#include <os.h>\n\n\n\n/*\n * Convertit un nombre en chaine de caractre\n */\nextern \"C\" {\n\tvoid itoa(char *buf, unsigned long int n, int base)\n\t{\n\t\tunsigned long int tmp;\n\t\tint i, j;\n\n\t\ttmp = n;\n\t\ti = 0;\n\n\t\tdo {\n\t\t\ttmp = n % base;\n\t\t\tbuf[i++] = (tmp < 10) ? (tmp + '0') : (tmp + 'a' - 10);\n\t\t} while (n /= base);\n\t\tbuf[i--] = 0;\n\n\t\tfor (j = 0; j < i; j++, i--) {\n\t\t\ttmp = buf[j];\n\t\t\tbuf[j] = buf[i];\n\t\t\tbuf[i] = tmp;\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "src/kernel/runtime/libc.h",
    "content": "\n#ifndef LIBC_H\n#define LIBC_H\n\n#include <stdarg.h>\n\nextern \"C\" {\n\tvoid \titoa(char *buf, unsigned long int n, int base);\n\t\n\tvoid *\tmemset(char *dst,char src, int n);\n\tvoid *\tmemcpy(char *dst, char *src, int n);\n\t\n\t\n\tint \tstrlen(char *s);\n\tint \tstrcmp(const char *dst, char *src);\n\tint \tstrcpy(char *dst,const char *src);\n\tvoid \tstrcat(void *dest,const void *src);\n\tchar *\tstrncpy(char *destString, const char *sourceString,int maxLength);\n\tint \tstrncmp( const char* s1, const char* s2, int c );\n}\n\n#endif\n"
  },
  {
    "path": "src/kernel/runtime/list.h",
    "content": "\n \n#ifndef __LIST__\n#define __LIST__\n\n\n\tstruct list_head {\n\t\tstruct list_head *next, *prev;\n\t};\n\n\t#define LIST_HEAD_INIT(name) { &(name), &(name) }\n\n\t#define LIST_HEAD(name) \\\n\t\tstruct list_head name = LIST_HEAD_INIT(name)\n\n\tstatic inline void INIT_LIST_HEAD(struct list_head *list)\n\t{\n\t\tlist->next = list;\n\t\tlist->prev = list;\n\t}\n\n\tstatic inline void list_add(struct list_head *neww, struct list_head *head)\n\t{\n\t\tneww->next = head->next;\n\t\tneww->prev = head;\n\t\t(head->next)->prev = neww;\n\t\thead->next = neww;\n\t}\n\n\tstatic inline void list_del(struct list_head *p)\n\t{\n\t\t(p->next)->prev = p->prev;\n\t\t(p->prev)->next = p->next;\n\t\tp->next = 0;\n\t\tp->prev = 0;\n\t}\n\n\tstatic inline int list_empty(const struct list_head *head)\n\t{\n\t\treturn head->next == head;\n\t}\n\n\t#define list_entry(ptr, type, member) \\\n\t\t(type*) ((char*) ptr - (char*) &((type*)0)->member)\n\n\t#define list_first_entry(head, type, member) \\\n\t\tlist_entry((head)->next, type, member)\n\n\t#define list_for_each(p, head) \\\n\t\tfor (p = (head)->next; p != (head); p = p->next) \n\n\t#define list_for_each_safe(p, n, head) \\\n\t\tfor (p = (head)->next, n = p->next; p != (head); p = n, n = n->next) \n\n\t#define list_for_each_entry(p, head, member)\t\t\t\t\\\n\t\tfor (p = list_entry((head)->next, typeof(*p), member);\t\t\\\n\t\t\t &p->member != (head);\t\t\t\t\t\\\n\t\t\t p = list_entry(p->member.next, typeof(*p), member))\t\\\n\n\n#endif\t/* __LIST__ */\n"
  },
  {
    "path": "src/kernel/runtime/memory.cc",
    "content": "#include <os.h>\n\n\nextern \"C\" {\n\n/* \n * La fonction memcpy permet de copier n octets de src vers dest.\n * Les adresses sont lineaires.\n */\nvoid *memcpy(char *dst, char *src, int n)\n{\n\tchar *p = dst;\n\twhile (n--)\n\t\t*dst++ = *src++;\n\treturn p;\n}\n\n/*\n * Met un ensemble memoire (dst>>n)  la valeur src\n */\nvoid *memset(char *dst,char src, int n)\n{\n\tchar *p = dst;\n\twhile (n--)\n\t\t*dst++ = src;\n\treturn p;\n}\n\n}\n\n"
  },
  {
    "path": "src/kernel/runtime/string.cc",
    "content": "\n#include <os.h>\n\n\n\nextern \"C\"\n{\n\tint strlen(char *s)\n\t{\n\t\tint i = 0;\n\t\twhile (*s++)\n\t\t\ti++;\n\t\treturn i;\n\t}\n\t\n\tchar *strncpy(char *destString, const char *sourceString,int maxLength)\n\t{\n\t  unsigned count;\n\n\t  if ((destString == (char *) NULL) || (sourceString == (char *) NULL))\n\t\t{\n\t\t  return (destString = NULL);\n\t\t}\n\n\t  if (maxLength > 255)\n\t\tmaxLength = 255;\n\n\t  for (count = 0; (int)count < (int)maxLength; count ++)\n\t\t{\n\t\t  destString[count] = sourceString[count];\n\t\t  \n\t\t  if (sourceString[count] == '\\0')\n\t\tbreak;\n\t\t}\n\n\t  if (count >= 255)\n\t\t{\n\t\t  return (destString = NULL);\n\t\t}\n\n\t  return (destString);\n\t}\n\t\n\tint strcmp(const char *dst, char *src)\n\t{\n\t\tint i = 0;\n\n\t\twhile ((dst[i] == src[i])) {\n\t\t\tif (src[i++] == 0)\n\t\t\t\treturn 0;\n\t\t}\n\n\t\treturn 1;\n\t}\n\t\n\n\tint strcpy(char *dst,const char *src)\n\t{\n\t\tint i = 0;\n\t\twhile ((dst[i] = src[i++]));\n\n\t\treturn i;\n\t}\n\t\n\n\tvoid strcat(void *dest,const void *src)\n\t{\n\t   memcpy((char*)((int)dest+(int)strlen((char*)dest)),(char*)src,strlen((char*)src));\n\t}\n\t\n\n\tint strncmp( const char* s1, const char* s2, int c ) {\n\t\tint result = 0;\n\n\t\twhile ( c ) {\n\t\t\tresult = *s1 - *s2++;\n\n\t\t\tif ( ( result != 0 ) || ( *s1++ == 0 ) ) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tc--;\n\t\t}\n\n\t\treturn result;\n\t}\n}\n\n"
  },
  {
    "path": "src/kernel/runtime/string.h",
    "content": "\n#ifndef STRING_H\n#define STRING_H\n\n\n#endif\n"
  },
  {
    "path": "src/kernel/runtime/types.h",
    "content": "\n#ifndef TYPES_H\n#define TYPES_H\n\n/*\n *\tGeneral C-Types\n */\ntypedef unsigned char \tu8;\ntypedef unsigned short \tu16;\ntypedef unsigned int \tu32;\ntypedef unsigned long long \tu64;\n\n\ntypedef signed char \ts8;\ntypedef signed short \ts16;\ntypedef signed int \t\ts32;\ntypedef signed long long\ts64;\n\n\ntypedef unsigned char u_char;\n\ntypedef unsigned int size_t;\ntypedef int pid_t;\ntypedef s64 ino_t;\ntypedef s64 off_t;\ntypedef int dev_t;\ntypedef int mode_t;\ntypedef int nlink_t;\ntypedef int uid_t;\ntypedef int gid_t;\ntypedef int blksize_t;\ntypedef s64 blkcnt_t;\n#define time_t s64\n\nstruct stat_fs {\n    dev_t st_dev;\n    ino_t st_ino;\n    mode_t st_mode;\n    nlink_t st_nlink;\n    uid_t st_uid;\n    gid_t st_gid;\n    dev_t st_rdev;\n    off_t st_size;\n    blksize_t st_blksize;\n    blkcnt_t st_blocks;\n    time_t st_atime;\n    time_t st_mtime;\n    time_t st_ctime;\n};\n\n\n/*\n* Return code\n*/\nenum{\n\tRETURN_OK=0,\n\tNOT_DEFINED=-1, //If not implemented\n\tERROR_MEMORY=-2,\n\tPARAM_NULL=-3,\n\tERROR_PARAM=-4,\n\tRETURN_FAILURE=-128 //Added by NoMaintener aka William. In case of error\n};\n \n \n/*\n *\tInterruption handler\n */\ntypedef void (*int_handler)(void);\n\n\n#define NULL 0\n#define true 1\n#define false 0\n\n#endif\n"
  },
  {
    "path": "src/sdk/Makefile",
    "content": "\nall: \n\t@echo \"Building LibC\"\n\tmake -C ./src/libc\n\t\nclean:\n\tmake -C ./src/libc clean\n"
  },
  {
    "path": "src/sdk/bootdisk/bin/.gitkeep",
    "content": ""
  },
  {
    "path": "src/sdk/bootdisk/boot/grub/grub.conf",
    "content": "default=0\ntimeout=30\n\nroot (hd0,0)\n\ntitle=Dev Operating System (with init)\n\tkernel /kernel.elf\n\tmodule /bin/hello\n\tboot\n\t\ntitle=Dev Operating System\n\tkernel /kernel.elf\n\tboot\n"
  },
  {
    "path": "src/sdk/bootdisk/boot/grub/menu.lst",
    "content": "default=0\ntimeout=30\n\nroot (cd)\n\ntitle=Dev Operating System (with init)\n\tkernel /kernel.elf\n\tmodule /bin/hello\n\tboot\n\t\ntitle=Dev Operating System\n\tkernel /kernel.elf\n\tboot\n"
  },
  {
    "path": "src/sdk/build.mak",
    "content": "CP       = cp\nRM       = rm\nMKDIR    = mkdir\nTRUE     = true\n\nCC       = gcc\nCXX      = g++\nAS       = nasm\nLD       = ld\nAR       = ar\nRANLIB   = ranlib\nSTRIP    = strip\n\nINCDIR   = $(SDKDIR)/include\nLIBDIR   = $(SDKDIR)/lib\n\nDEFS:= $(DEFS)\n\nCFLAGS   = -I $(INCDIR) -Wall -fno-builtin -g -O2 -w -trigraphs   -fno-exceptions -fno-stack-protector -O0 -m32  -fno-rtti $(DEFS)\nCXXFLAGS = $(CFLAGS) \nASFLAGS  = $(CFLAGS) \n\nifeq ($(CRT_FILE),)\nCRT_FILE = crt_c.o\nendif\n\nLDFLAGS  = -melf_i386 -L $(INCDIR)  -T ./linker.ld --entry=_start -nostdlib -L $(LIBDIR) -lc $(LIBS)\nMYOS_VERSION=500\n\n\nall: $(TARGET)\n\n$(TARGET): $(OBJS)\n\t$(LD) -o $@ $^ $(SDKDIR)/lib/$(CRT_FILE) $(LDFLAGS)\n\tcp $(TARGET) $(SDKDIR)/bootdisk/bin/$(TARGET)\n\ninstall:\n\tcp $(TARGET) $(SDKDIR)/bootdisk/bin/$(TARGET)\n\nrun:\n\tcd $(SDKDIR) &&\tsh ./diskimage.sh\n\tcd $(SDKDIR) &&\tsh ./qemu.sh\n\n%.o: %.c\n\t$(CC) $(CFLAGS)  -c $< \n\n%.o: %.cpp\n\t$(CXX) $(CXXFLAGS)  -c $< \n\t\n%.o: %.cc\n\t$(CXX) $(CXXFLAGS)  -c $< \n\t\n.PHONY: clean \n\t\nclean:\n\trm -rf *.o $(TARGET)\n\n"
  },
  {
    "path": "src/sdk/diskimage.sh",
    "content": "#!/bin/bash\nqemu-img create c.img 2M\nfdisk ./c.img  << EOF\nx\nc\n4\nh\n16\ns\n63\nr\nn\np\n1\n1\n4\na\n1\nw\nEOF\nfdisk -l -u ./c.img\nlosetup -o 32256 /dev/loop1 ./c.img\n\nmke2fs /dev/loop1\nmount  /dev/loop1 /mnt/\ncp -R bootdisk/* /mnt/\numount /mnt/\ngrub --device-map=/dev/null << EOF\ndevice (hd0) ./c.img\ngeometry (hd0) 4 16 63\nroot (hd0,0)\nsetup (hd0)\nquit\nEOF\n\nlosetup -d /dev/loop1\n"
  },
  {
    "path": "src/sdk/include/_ansi.h",
    "content": "\n\n#ifndef\t_ANSIDECL_H_\n#define\t_ANSIDECL_H_\n\n\n\n/*  ISO C++.  */\n\n#ifdef __cplusplus\n#if !(defined(_BEGIN_STD_C) && defined(_END_STD_C))\n#ifdef _HAVE_STD_CXX\n#define _BEGIN_STD_C namespace std { extern \"C\" {\n#define _END_STD_C  } }\n#else\n#define _BEGIN_STD_C extern \"C\" {\n#define _END_STD_C  }\n#endif\n#if defined(__GNUC__) && \\\n  ( (__GNUC__ >= 4) || \\\n    ( (__GNUC__ >= 3) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 3) ) )\n#define _NOTHROW __attribute__ ((nothrow))\n#else\n#define _NOTHROW throw()\n#endif\n#endif\n#else\n#define _BEGIN_STD_C\n#define _END_STD_C\n#define _NOTHROW\n#endif\n\n\n#endif /* _ANSIDECL_H_ */\n"
  },
  {
    "path": "src/sdk/include/alloca.h",
    "content": "\n \n\n#ifndef _ALLOCA_H_\n#define _ALLOCA_H_\n\n#undef alloca\n#define alloca(size) __builtin_alloca(size)\n\n#endif /* _ALLOCA_H_ */\n"
  },
  {
    "path": "src/sdk/include/arpa/inet.h",
    "content": "\n\n#ifndef _ARPA_INET_H_\n#define _ARPA_INET_H_\n\n#include <netinet/in.h> /* struct in_addr */\n\nint inet_aton( const char* cp, struct in_addr* inp );\n\nin_addr_t inet_addr( const char* cp );\n\nin_addr_t inet_network( const char* cp );\n\nchar* inet_ntoa( struct in_addr in );\n\nstruct in_addr inet_makeaddr( int net, int host );\n\nin_addr_t inet_lnaof( struct in_addr in );\n\nin_addr_t inet_netof( struct in_addr in );\n\n#endif /* _ARPA_INET_H_ */\n"
  },
  {
    "path": "src/sdk/include/assert.h",
    "content": "\n \n\n#undef assert\n\n#ifdef NDEBUG\n#define assert(expr) ((void)0)\n#else\n#define assert(expr) \\\n    if ( !(expr) ) { __assert_fail( #expr, __FILE__, __LINE__ ); }\n#endif /* NDEBUG */\n\n#ifndef _ASSERT_H_\n#define _ASSERT_H_\n\n#include <stdio.h>\n#include <stdlib.h>\n\nstatic inline void __assert_fail( const char* expr, const char* file, int line ) {\n    printf( \"Assertion (%s) failed at %s:%d\\n\", expr, file, line );\n    abort();\n}\n\n#endif /* _ASSERT_H_ */\n"
  },
  {
    "path": "src/sdk/include/ctype.h",
    "content": "\n\n#ifndef _CTYPE_H_\n#define _CTYPE_H_\n\nint isupper( int c );\nint islower( int c );\nint isalpha( int c );\nint isdigit( int c );\nint isxdigit( int c );\nint isalnum( int c );\nint isblank( int c );\nint isspace( int c );\nint isprint( int c );\nint iscntrl( int c );\nint isgraph( int c );\nint ispunct( int c );\nint isascii( int c );\n\nint tolower( int c );\nint toupper( int c );\n\ntypedef struct {\n\tlong quot;   \n\tlong rem;  \n}ldiv_t;\n\ntypedef struct {\n\tint quot;\n\tint rem;   \n}div_t;\n\ndiv_t div ( int numerator, int denominator );\nldiv_t ldiv ( long numerator, long denominator );\n\n\n\n\n#endif // _CTYPE_H_\n"
  },
  {
    "path": "src/sdk/include/dirent.h",
    "content": "\n \n\n#ifndef _DIRENT_H_\n#define _DIRENT_H_\n\n#include <unistd.h>\n\n\ntypedef struct DIR {\n    int fd;\n    struct dirent entry;\n} DIR;\n\nDIR* opendir( const char* name );\nint closedir( DIR* dir );\n\nstruct dirent* readdir( DIR* dir );\nint readdir_r( DIR* dir, struct dirent* entry, struct dirent** result );\n\nvoid rewinddir( DIR* dir );\n\n#endif /* _DIRENT_H_ */\n"
  },
  {
    "path": "src/sdk/include/endian.h",
    "content": "\n \n\n#ifndef _ENDIAN_H_\n#define _ENDIAN_H_\n\n#define __LITTLE_ENDIAN 1234\n#define __BIG_ENDIAN    4321\n\n#define __BYTE_ORDER    __LITTLE_ENDIAN\n\n#endif /* _ENDIAN_H_ */\n"
  },
  {
    "path": "src/sdk/include/errno.h",
    "content": "\n \n\n#ifndef _ERRNO_H_\n#define _ERRNO_H_\n\n#define ENOMEM       1\n#define EINVAL       2\n#define EIO          3\n#define ETIME        4\n#define ENOSYS       5\n#define ENOENT       6\n#define EEXIST       7\n#define EBUSY        8\n#define EISDIR       9\n#define ENOINO       10\n#define ENOEXEC      11\n#define EBADF        12\n#define EHW          13\n#define ERANGE       14\n#define ENXIO        15\n#define EDOM         16\n#define ENODEV       17\n#define EINTR        18\n#define ENOTTY       19\n#define EPERM        20\n#define EROFS        21\n#define ELOOP        22\n#define ENOTDIR      23\n#define ENOTEMPTY    24\n#define EAGAIN       25\n#define E2BIG        26\n#define ETIMEDOUT    27\n#define EOVERFLOW    28\n#define ENOSPC       29\n#define ECHILD       30\n#define ENAMETOOLONG 31\n#define ESPIPE       32\n#define EACCES       33\n\nextern int errno;\n\n#endif /* _ERRNO_H_ */\n"
  },
  {
    "path": "src/sdk/include/fcntl.h",
    "content": "\n \n\n#ifndef _FCNTL_H_\n#define _FCNTL_H_\n\n#include <sys/cdefs.h>\n#include <sys/types.h>\n\n#define O_RDONLY   0x01\n#define O_WRONLY   0x02\n#define O_RDWR     0x03\n#define O_CREAT    0x04\n#define O_TRUNC    0x08\n#define O_APPEND   0x10\n#define O_EXCL     0x20\n#define O_NONBLOCK 0x40\n\n#define F_DUPFD 0\n#define F_GETFD 1\n#define F_SETFD 2\n#define F_GETFL 3\n#define F_SETFL 4\n\n#define FD_CLOEXEC 1\n\nint open( const char* filename, int flags, ... ) __nonnull((1));\nint creat( const char* pathname, mode_t mode ) __nonnull((1));\nint fcntl( int fd, int cmd, ... );\n\n#endif /* _FCNTL_H_ */\n"
  },
  {
    "path": "src/sdk/include/float.h",
    "content": "\n\n/*\n * ISO C Standard:  5.2.4.2.2  Characteristics of floating types <float.h>\n */\n\n#ifndef _FLOAT_H___\n#define _FLOAT_H___\n\n/* Radix of exponent representation, b. */\n#undef FLT_RADIX\n#define FLT_RADIX\t__FLT_RADIX__\n\n/* Number of base-FLT_RADIX digits in the significand, p.  */\n#undef FLT_MANT_DIG\n#undef DBL_MANT_DIG\n#undef LDBL_MANT_DIG\n#define FLT_MANT_DIG\t__FLT_MANT_DIG__\n#define DBL_MANT_DIG\t__DBL_MANT_DIG__\n#define LDBL_MANT_DIG\t__LDBL_MANT_DIG__\n\n/* Number of decimal digits, q, such that any floating-point number with q\n   decimal digits can be rounded into a floating-point number with p radix b\n   digits and back again without change to the q decimal digits,\n\n\tp * log10(b)\t\t\tif b is a power of 10\n\tfloor((p - 1) * log10(b))\totherwise\n*/\n#undef FLT_DIG\n#undef DBL_DIG\n#undef LDBL_DIG\n#define FLT_DIG\t\t__FLT_DIG__\n#define DBL_DIG\t\t__DBL_DIG__\n#define LDBL_DIG\t__LDBL_DIG__\n\n/* Minimum int x such that FLT_RADIX**(x-1) is a normalized float, emin */\n#undef FLT_MIN_EXP\n#undef DBL_MIN_EXP\n#undef LDBL_MIN_EXP\n#define FLT_MIN_EXP\t__FLT_MIN_EXP__\n#define DBL_MIN_EXP\t__DBL_MIN_EXP__\n#define LDBL_MIN_EXP\t__LDBL_MIN_EXP__\n\n/* Minimum negative integer such that 10 raised to that power is in the\n   range of normalized floating-point numbers,\n\n\tceil(log10(b) * (emin - 1))\n*/\n#undef FLT_MIN_10_EXP\n#undef DBL_MIN_10_EXP\n#undef LDBL_MIN_10_EXP\n#define FLT_MIN_10_EXP\t__FLT_MIN_10_EXP__\n#define DBL_MIN_10_EXP\t__DBL_MIN_10_EXP__\n#define LDBL_MIN_10_EXP\t__LDBL_MIN_10_EXP__\n\n/* Maximum int x such that FLT_RADIX**(x-1) is a representable float, emax.  */\n#undef FLT_MAX_EXP\n#undef DBL_MAX_EXP\n#undef LDBL_MAX_EXP\n#define FLT_MAX_EXP\t__FLT_MAX_EXP__\n#define DBL_MAX_EXP\t__DBL_MAX_EXP__\n#define LDBL_MAX_EXP\t__LDBL_MAX_EXP__\n\n/* Maximum integer such that 10 raised to that power is in the range of\n   representable finite floating-point numbers,\n\n\tfloor(log10((1 - b**-p) * b**emax))\n*/\n#undef FLT_MAX_10_EXP\n#undef DBL_MAX_10_EXP\n#undef LDBL_MAX_10_EXP\n#define FLT_MAX_10_EXP\t__FLT_MAX_10_EXP__\n#define DBL_MAX_10_EXP\t__DBL_MAX_10_EXP__\n#define LDBL_MAX_10_EXP\t__LDBL_MAX_10_EXP__\n\n/* Maximum representable finite floating-point number,\n\n\t(1 - b**-p) * b**emax\n*/\n#undef FLT_MAX\n#undef DBL_MAX\n#undef LDBL_MAX\n#define FLT_MAX\t\t__FLT_MAX__\n#define DBL_MAX\t\t__DBL_MAX__\n#define LDBL_MAX\t__LDBL_MAX__\n\n/* The difference between 1 and the least value greater than 1 that is\n   representable in the given floating point type, b**1-p.  */\n#undef FLT_EPSILON\n#undef DBL_EPSILON\n#undef LDBL_EPSILON\n#define FLT_EPSILON\t__FLT_EPSILON__\n#define DBL_EPSILON\t__DBL_EPSILON__\n#define LDBL_EPSILON\t__LDBL_EPSILON__\n\n/* Minimum normalized positive floating-point number, b**(emin - 1).  */\n#undef FLT_MIN\n#undef DBL_MIN\n#undef LDBL_MIN\n#define FLT_MIN\t\t__FLT_MIN__\n#define DBL_MIN\t\t__DBL_MIN__\n#define LDBL_MIN\t__LDBL_MIN__\n\n/* Addition rounds to 0: zero, 1: nearest, 2: +inf, 3: -inf, -1: unknown.  */\n/* ??? This is supposed to change with calls to fesetround in <fenv.h>.  */\n#undef FLT_ROUNDS\n#define FLT_ROUNDS 1\n\n#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L\n/* The floating-point expression evaluation method.\n        -1  indeterminate\n         0  evaluate all operations and constants just to the range and\n            precision of the type\n         1  evaluate operations and constants of type float and double\n            to the range and precision of the double type, evaluate\n            long double operations and constants to the range and\n            precision of the long double type\n         2  evaluate all operations and constants to the range and\n            precision of the long double type\n\n   ??? This ought to change with the setting of the fp control word;\n   the value provided by the compiler assumes the widest setting.  */\n#undef FLT_EVAL_METHOD\n#define FLT_EVAL_METHOD\t__FLT_EVAL_METHOD__\n\n/* Number of decimal digits, n, such that any floating-point number in the\n   widest supported floating type with pmax radix b digits can be rounded\n   to a floating-point number with n decimal digits and back again without\n   change to the value,\n\n\tpmax * log10(b)\t\t\tif b is a power of 10\n\tceil(1 + pmax * log10(b))\totherwise\n*/\n#undef DECIMAL_DIG\n#define DECIMAL_DIG\t__DECIMAL_DIG__\n\n#endif /* C99 */\n\n#ifdef __STDC_WANT_DEC_FP__\n/* Draft Technical Report 24732, extension for decimal floating-point\n   arithmetic: Characteristic of decimal floating types <float.h>.  */\n\n/* Number of base-FLT_RADIX digits in the significand, p.  */\n#undef DEC32_MANT_DIG\n#undef DEC64_MANT_DIG\n#undef DEC128_MANT_DIG\n#define DEC32_MANT_DIG\t__DEC32_MANT_DIG__\n#define DEC64_MANT_DIG\t__DEC64_MANT_DIG__\n#define DEC128_MANT_DIG\t__DEC128_MANT_DIG__\n\n/* Minimum exponent. */\n#undef DEC32_MIN_EXP\n#undef DEC64_MIN_EXP\n#undef DEC128_MIN_EXP\n#define DEC32_MIN_EXP\t__DEC32_MIN_EXP__\n#define DEC64_MIN_EXP\t__DEC64_MIN_EXP__\n#define DEC128_MIN_EXP\t__DEC128_MIN_EXP__\n\n/* Maximum exponent. */\n#undef DEC32_MAX_EXP\n#undef DEC64_MAX_EXP\n#undef DEC128_MAX_EXP\n#define DEC32_MAX_EXP\t__DEC32_MAX_EXP__\n#define DEC64_MAX_EXP\t__DEC64_MAX_EXP__\n#define DEC128_MAX_EXP\t__DEC128_MAX_EXP__\n\n/* Maximum representable finite decimal floating-point number\n   (there are 6, 15, and 33 9s after the decimal points respectively). */\n#undef DEC32_MAX\n#undef DEC64_MAX\n#undef DEC128_MAX\n#define DEC32_MAX   __DEC32_MAX__\n#define DEC64_MAX   __DEC64_MAX__\n#define DEC128_MAX  __DEC128_MAX__\n\n/* The difference between 1 and the least value greater than 1 that is\n   representable in the given floating point type. */\n#undef DEC32_EPSILON\n#undef DEC64_EPSILON\n#undef DEC128_EPSILON\n#define DEC32_EPSILON\t__DEC32_EPSILON__\n#define DEC64_EPSILON\t__DEC64_EPSILON__\n#define DEC128_EPSILON\t__DEC128_EPSILON__\n\n/* Minimum normalized positive floating-point number. */\n#undef DEC32_MIN\n#undef DEC64_MIN\n#undef DEC128_MIN\n#define DEC32_MIN\t__DEC32_MIN__\n#define DEC64_MIN\t__DEC64_MIN__\n#define DEC128_MIN\t__DEC128_MIN__\n\n/* Minimum denormalized positive floating-point number. */\n#undef DEC32_DEN\n#undef DEC64_DEN\n#undef DEC128_DEN\n#define DEC32_DEN       __DEC32_DEN__\n#define DEC64_DEN       __DEC64_DEN__\n#define DEC128_DEN      __DEC128_DEN__\n\n/* The floating-point expression evaluation method.\n         -1  indeterminate\n         0  evaluate all operations and constants just to the range and\n            precision of the type\n         1  evaluate operations and constants of type _Decimal32 \n\t    and _Decimal64 to the range and precision of the _Decimal64 \n            type, evaluate _Decimal128 operations and constants to the \n\t    range and precision of the _Decimal128 type;\n\t 2  evaluate all operations and constants to the range and\n\t    precision of the _Decimal128 type.  */\n\n#undef DECFLT_EVAL_METHOD\n#define DECFLT_EVAL_METHOD\t__DECFLT_EVAL_METHOD__\n\n#endif /* __STDC_WANT_DEC_FP__ */\n\n#endif /* _FLOAT_H___ */\n"
  },
  {
    "path": "src/sdk/include/getopt.h",
    "content": "\n \n#ifndef _GETOPT_H_\n#define _GETOPT_H_\n\ntypedef struct option {\n    const char *name;\n    int has_arg;\n    int* flag;\n    int val;\n} option_t ;\n\n#define no_argument         0\n#define required_argument   1\n#define optional_argument   2\n\n\nextern char *optarg;\nextern int optind, opterr, optopt;\n\nint getopt( int argc, char* const * argv, const char* opstring );\n\nint getopt_long( int argc, char* const * argv, const char* shortopts,\n                 const struct option* longopts, int* longind );\n\nint getopt_long_only( int argc, char* const * argv,\n                      const char* shortopts, const struct option* longopts, int* longind );\n\n#endif // _GETOPT_H_\n"
  },
  {
    "path": "src/sdk/include/inttypes.h",
    "content": "\n \n\n#ifndef _INTTYPES_H_\n#define _INTTYPES_H_\n\n#include <stdint.h>\n\nintmax_t strtoimax( const char *nptr, char** endptr, int base );\nuintmax_t strtoumax( const char *nptr, char** endptr, int base );\n\n#endif /* _INTTYPES_H_ */\n"
  },
  {
    "path": "src/sdk/include/limits.h",
    "content": "\n \n\n#ifndef _LIMITS_H_\n#define _LIMITS_H_\n\n#ifndef __INT_MAX__\n#define __INT_MAX__ 2147483647\n#endif\n#ifndef __LONG_MAX__\n#if __WORDSIZE == 64\n#define __LONG_MAX__ 9223372036854775807L\n#else\n#define __LONG_MAX__ 2147483647L\n#endif\n#endif\n\n#define CHAR_BIT 8\n\n#define SCHAR_MIN     (-128)\n#define SCHAR_MAX     127\n\n#define UCHAR_MAX     255\n\n#ifdef __CHAR_UNSIGNED__\n#define CHAR_MIN     0\n#define CHAR_MAX     UCHAR_MAX\n#else\n#define CHAR_MIN     SCHAR_MIN\n#define CHAR_MAX     SCHAR_MAX\n#endif\n\n#define SHRT_MIN      (-32768)\n#define SHRT_MAX      32767\n\n#define USHRT_MAX     65535\n\n#define INT_MIN         (-1 - INT_MAX)\n#define INT_MAX         (__INT_MAX__)\n#define UINT_MAX        (INT_MAX * 2U + 1U)\n\n#define LONG_MIN        (-1L - LONG_MAX)\n#define LONG_MAX        ((__LONG_MAX__) + 0L)\n#define ULONG_MAX       (LONG_MAX * 2UL + 1UL)\n\n#define LLONG_MAX 9223372036854775807LL\n#define LLONG_MIN (-LLONG_MAX - 1LL)\n#define ULLONG_MAX 18446744073709551615ULL\n\n#define PATH_MAX 256\n#define MB_LEN_MAX 16\n\n#endif // _LIMITS_H_\n"
  },
  {
    "path": "src/sdk/include/linker.ld",
    "content": "OUTPUT_FORMAT(elf32-i386)\r\nOUTPUT_ARCH(i386)\r\nENTRY (_start)\r\n\r\nSECTIONS{\r\n    . = 0x40000000;\r\n\r\n    .text :{\r\n        *(.text)\r\n    }\r\n\r\n\t.data ALIGN (0x1000) : {\r\n\t   start_ctors = .;\r\n\t   *(.ctor*)\r\n\t   end_ctors = .;\r\n\t   start_dtors = .;\r\n\t   *(.dtor*)\r\n\t   end_dtors = .;\r\n\t   *(.data)\r\n\t}\r\n\r\n\r\n    .rodata ALIGN (0x1000) : {\r\n        *(.rodata)\r\n    }\r\n\r\n    .data ALIGN (0x1000) : {\r\n        *(.data)\r\n    }\r\n\r\n    .bss : {\r\n        sbss = .;\r\n        *(COMMON)\r\n        *(.bss)\r\n        ebss = .;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/sdk/include/locale.h",
    "content": "\n \n\n#ifndef _LOCALE_H_\n#define _LOCALE_H_\n\nenum {\n    LC_CTYPE = 0,\n    LC_NUMERIC = 1,\n    LC_TIME = 2,\n    LC_COLLATE = 3,\n    LC_MONETARY = 4,\n    LC_MESSAGES = 5,\n    LC_ALL = 6,\n    LC_PAPER = 7,\n    LC_NAME = 8,\n    LC_ADDRESS = 9,\n    LC_TELEPHONE = 10,\n    LC_MEASUREMENT = 11,\n    LC_IDENTIFICATION = 12\n};\n\nstruct lconv {\n    char* decimal_point;\n    char* thousands_sep;\n    char* grouping;\n    char* int_curr_symbol;\n    char* currency_symbol;\n    char* mon_decimal_point;\n    char* mon_thousands_sep;\n    char* mon_grouping;\n    char* positive_sign;\n    char* negative_sign;\n    char int_frac_digits;\n    char frac_digits;\n    char p_cs_precedes;\n    char p_sep_by_space;\n    char n_cs_precedes;\n    char n_sep_by_space;\n    char p_sign_posn;\n    char n_sign_posn;\n    char int_p_cs_precedes;\n    char int_p_sep_by_space;\n    char int_n_cs_precedes;\n    char int_n_sep_by_space;\n    char int_p_sign_posn;\n    char int_n_sign_posn;\n};\n\nstruct lconv* localeconv( void );\n\nchar* setlocale( int category, const char* locale );\n\n#endif /* _LOCALE_H_ */\n"
  },
  {
    "path": "src/sdk/include/math.h",
    "content": "\n \n\n#ifndef _MATH_H_\n#define _MATH_H_\n\n#define HUGE_VAL \\\n  (__extension__                                                              \\\n   ((union { unsigned __l __attribute__((__mode__(__DI__))); double __d; })   \\\n    { __l: 0x7ff0000000000000ULL }).__d)\n\nint finite( double x );\n\ndouble sin( double x );\ndouble cos( double x );\ndouble log( double x );\ndouble log10( double x );\ndouble exp( double x );\ndouble floor( double x );\ndouble ceil( double x );\ndouble frexp( double x, int* exp );\ndouble fabs( double x );\ndouble fmod( double x, double y );\ndouble atan2( double y, double x );\ndouble hypot( double x, double y );\ndouble pow( double x, double y );\ndouble ldexp( double x, int exp );\ndouble scalbn( double x, int exp );\ndouble modf( double x, double* iptr );\n\n#endif // _MATH_H_\n"
  },
  {
    "path": "src/sdk/include/netinet/in.h",
    "content": "\n\n#ifndef _NETINET_IN_H_\n#define _NETINET_IN_H_\n\n#include <sys/types.h>\n#include <sys/socket.h>\n\n#define ntohs(n) \\\n    ((((uint16_t)(n) & 0xFF) << 8) | ((uint16_t)(n) >> 8))\n#define ntohl(n) \\\n    (((uint32_t)(n) << 24) | (((uint32_t)(n) & 0xFF00) << 8) | (((uint32_t)(n) & 0x00FF0000) >> 8) | ((uint32_t)(n) >> 24))\n\n#define htons ntohs\n#define htonl ntohl\n\n/* Standard well-defined IP protocols. */\n\nenum {\n    IPPROTO_IP = 0,        /* Dummy protocol for TCP.  */\n#define IPPROTO_IP              IPPROTO_IP\n    IPPROTO_HOPOPTS = 0,   /* IPv6 Hop-by-Hop options.  */\n#define IPPROTO_HOPOPTS         IPPROTO_HOPOPTS\n    IPPROTO_ICMP = 1,      /* Internet Control Message Protocol.  */\n#define IPPROTO_ICMP            IPPROTO_ICMP\n    IPPROTO_IGMP = 2,      /* Internet Group Management Protocol. */\n#define IPPROTO_IGMP            IPPROTO_IGMP\n    IPPROTO_IPIP = 4,      /* IPIP tunnels (older KA9Q tunnels use 94).  */\n#define IPPROTO_IPIP            IPPROTO_IPIP\n    IPPROTO_TCP = 6,       /* Transmission Control Protocol.  */\n#define IPPROTO_TCP             IPPROTO_TCP\n    IPPROTO_EGP = 8,       /* Exterior Gateway Protocol.  */\n#define IPPROTO_EGP             IPPROTO_EGP\n    IPPROTO_PUP = 12,      /* PUP protocol.  */\n#define IPPROTO_PUP             IPPROTO_PUP\n    IPPROTO_UDP = 17,      /* User Datagram Protocol.  */\n#define IPPROTO_UDP             IPPROTO_UDP\n    IPPROTO_IDP = 22,      /* XNS IDP protocol.  */\n#define IPPROTO_IDP             IPPROTO_IDP\n    IPPROTO_TP = 29,       /* SO Transport Protocol Class 4.  */\n#define IPPROTO_TP              IPPROTO_TP\n    IPPROTO_DCCP = 33,     /* Datagram Congestion Control Protocol.  */\n#define IPPROTO_DCCP            IPPROTO_DCCP\n    IPPROTO_IPV6 = 41,     /* IPv6 header.  */\n#define IPPROTO_IPV6            IPPROTO_IPV6\n    IPPROTO_ROUTING = 43,  /* IPv6 routing header.  */\n#define IPPROTO_ROUTING         IPPROTO_ROUTING\n    IPPROTO_FRAGMENT = 44, /* IPv6 fragmentation header.  */\n#define IPPROTO_FRAGMENT        IPPROTO_FRAGMENT\n    IPPROTO_RSVP = 46,     /* Reservation Protocol.  */\n#define IPPROTO_RSVP            IPPROTO_RSVP\n    IPPROTO_GRE = 47,      /* General Routing Encapsulation.  */\n#define IPPROTO_GRE             IPPROTO_GRE\n    IPPROTO_ESP = 50,      /* encapsulating security payload.  */\n#define IPPROTO_ESP             IPPROTO_ESP\n    IPPROTO_AH = 51,       /* authentication header.  */\n#define IPPROTO_AH              IPPROTO_AH\n    IPPROTO_ICMPV6 = 58,   /* ICMPv6.  */\n#define IPPROTO_ICMPV6          IPPROTO_ICMPV6\n    IPPROTO_NONE = 59,     /* IPv6 no next header.  */\n#define IPPROTO_NONE            IPPROTO_NONE\n    IPPROTO_DSTOPTS = 60,  /* IPv6 destination options.  */\n#define IPPROTO_DSTOPTS         IPPROTO_DSTOPTS\n    IPPROTO_MTP = 92,      /* Multicast Transport Protocol.  */\n#define IPPROTO_MTP             IPPROTO_MTP\n    IPPROTO_ENCAP = 98,    /* Encapsulation Header.  */\n#define IPPROTO_ENCAP           IPPROTO_ENCAP\n    IPPROTO_PIM = 103,     /* Protocol Independent Multicast.  */\n#define IPPROTO_PIM             IPPROTO_PIM\n    IPPROTO_COMP = 108,    /* Compression Header Protocol.  */\n#define IPPROTO_COMP            IPPROTO_COMP\n    IPPROTO_SCTP = 132,    /* Stream Control Transmission Protocol.  */\n#define IPPROTO_SCTP            IPPROTO_SCTP\n    IPPROTO_UDPLITE = 136, /* UDP-Lite protocol.  */\n#define IPPROTO_UDPLITE         IPPROTO_UDPLITE\n    IPPROTO_RAW = 255,     /* Raw IP packets.  */\n#define IPPROTO_RAW             IPPROTO_RAW\n    IPPROTO_MAX\n};\n\ntypedef uint16_t in_port_t;\ntypedef uint32_t in_addr_t;\n\nstruct in_addr {\n    in_addr_t s_addr;\n};\n\nstruct sockaddr_in {\n    sa_family_t sin_family;\n    in_port_t sin_port;      /* Port number.  */\n    struct in_addr sin_addr; /* Internet address.  */\n\n    /* Pad to size of `struct sockaddr'. */\n    unsigned char sin_zero[\n        sizeof( struct sockaddr ) -\n        sizeof( sa_family_t ) -\n        sizeof( in_port_t ) -\n        sizeof( struct in_addr )\n    ];\n};\n\n#endif /* _NETINET_IN_H_ */\n"
  },
  {
    "path": "src/sdk/include/os.h",
    "content": "\n#ifndef _OS_H_\n#define _OS_H_\n\n#include <sys/types.h>\n\n#include \"../../kernel/core/api/kernel/syscall.h\"\n#include \"../../kernel/core/api/kernel/syscall_table.h\"\n\n#endif \n"
  },
  {
    "path": "src/sdk/include/pwd.h",
    "content": "\n \n\n#ifndef _PWD_H_\n#define _PWD_H_\n\n#include <sys/types.h>\n\nstruct passwd {\n    char* pw_name;\n    char* pw_passwd;\n    uid_t pw_uid;\n    gid_t pw_gid;\n    char* pw_gecos;\n    char* pw_dir;\n    char* pw_shell;\n};\n\nstruct passwd* getpwnam( const char* name );\nstruct passwd* getpwent( void );\nstruct passwd* getpwuid( uid_t uid );\n\nvoid setpwent( void );\nvoid endpwent( void );\n\n#endif /* _PWD_H_ */\n"
  },
  {
    "path": "src/sdk/include/setjmp.h",
    "content": "\n \n\n#ifndef _SETJMP_H_\n#define _SETJMP_H_\n\ntypedef unsigned long jmp_buf[ 6 ];\n\nint setjmp( jmp_buf env );\nvoid longjmp( jmp_buf env, int val );\n\n#endif // _SETJMP_H_\n"
  },
  {
    "path": "src/sdk/include/signal.h",
    "content": "\n \n\n#ifndef _SIGNAL_H_\n#define _SIGNAL_H_\n\n#include <time.h>\n#include <sys/types.h>\n\n#define SIGHUP    1       /* Hangup (POSIX).  */\n#define SIGINT    2       /* Interrupt (ANSI).  */\n#define SIGQUIT   3       /* Quit (POSIX).  */\n#define SIGILL    4       /* Illegal instruction (ANSI).  */\n#define SIGTRAP   5       /* Trace trap (POSIX).  */\n#define SIGABRT   6       /* Abort (ANSI).  */\n#define SIGIOT    6       /* IOT trap (4.2 BSD).  */\n#define SIGBUS    7       /* BUS error (4.2 BSD).  */\n#define SIGFPE    8       /* Floating-point exception (ANSI).  */\n#define SIGKILL   9       /* Kill, unblockable (POSIX).  */\n#define SIGUSR1   10      /* User-defined signal 1 (POSIX).  */\n#define SIGSEGV   11      /* Segmentation violation (ANSI).  */\n#define SIGUSR2   12      /* User-defined signal 2 (POSIX).  */\n#define SIGPIPE   13      /* Broken pipe (POSIX).  */\n#define SIGALRM   14      /* Alarm clock (POSIX).  */\n#define SIGTERM   15      /* Termination (ANSI).  */\n#define SIGSTKFLT 16      /* Stack fault.  */\n#define SIGCLD    SIGCHLD /* Same as SIGCHLD (System V).  */\n#define SIGCHLD   17      /* Child status has changed (POSIX).  */\n#define SIGCONT   18      /* Continue (POSIX).  */\n#define SIGSTOP   19      /* Stop, unblockable (POSIX).  */\n#define SIGTSTP   20      /* Keyboard stop (POSIX).  */\n#define SIGTTIN   21      /* Background read from tty (POSIX).  */\n#define SIGTTOU   22      /* Background write to tty (POSIX).  */\n#define SIGURG    23      /* Urgent condition on socket (4.2 BSD).  */\n#define SIGXCPU   24      /* CPU limit exceeded (4.2 BSD).  */\n#define SIGXFSZ   25      /* File size limit exceeded (4.2 BSD).  */\n#define SIGVTALRM 26      /* Virtual alarm clock (4.2 BSD).  */\n#define SIGPROF   27      /* Profiling alarm clock (4.2 BSD).  */\n#define SIGWINCH  28      /* Window size change (4.3 BSD, Sun).  */\n#define SIGPOLL   SIGIO   /* Pollable event occurred (System V).  */\n#define SIGIO     29      /* I/O now possible (4.2 BSD).  */\n#define SIGPWR    30      /* Power failure restart (System V).  */\n#define SIGSYS    31      /* Bad system call.  */\n\n#define _NSIG     65      /* Biggest signal number + 1 (including real-time signals). */\n\n#define SIG_ERR ((sighandler_t)-1) /* Error return.  */\n#define SIG_DFL ((sighandler_t)0) /* Default action.  */\n#define SIG_IGN ((sighandler_t)1) /* Ignore signal.  */\n\n#define SIG_BLOCK   0 /* Block signals.  */\n#define SIG_UNBLOCK 1 /* Unblock signals.  */\n#define SIG_SETMASK 2 /* Set the set of blocked signals.  */\n\n#define SA_NOCLDSTOP 1 /* Don't send SIGCHLD when children stop.  */\n#define SA_NOCLDWAIT 2 /* Don't create zombie on child death.  */\n#define SA_SIGINFO   4 /* Invoke signal-catching function with three arguments instead of one.  */\n#define SA_ONSTACK   0x08000000 /* Use signal stack by using `sa_restorer'. */\n#define SA_STACK     SA_ONSTACK\n#define SA_RESTART   0x10000000 /* Restart syscall on signal return.  */\n#define SA_NODEFER   0x40000000 /* Don't automatically block the signal when its handler is being executed.  */\n#define SA_NOMASK    SA_NODEFER\n#define SA_RESETHAND 0x80000000 /* Reset to SIG_DFL on entry to handler.  */\n#define SA_ONESHOT   SA_RESETHAND\n\ntypedef int sig_atomic_t;\ntypedef uint64_t sigset_t;\ntypedef int sigval_t;\ntypedef void ( *__sighandler_t )( int );\ntypedef __sighandler_t sighandler_t;\n\ntypedef struct siginfo {\n    int      si_signo;   /* Signal number */\n    int      si_errno;   /* An errno value */\n    int      si_code;    /* Signal code */\n    int      si_trapno;  /* Trap number that caused\n                                 hardware-generated signal\n                                 (unused on most architectures) */\n    pid_t    si_pid;     /* Sending process ID */\n    uid_t    si_uid;     /* Real user ID of sending process */\n    int      si_status;  /* Exit value or signal */\n    clock_t  si_utime;   /* User time consumed */\n    clock_t  si_stime;   /* System time consumed */\n    sigval_t si_value;   /* Signal value */\n    int      si_int;     /* POSIX.1b signal */\n    void    *si_ptr;     /* POSIX.1b signal */\n    int      si_overrun; /* Timer overrun count; POSIX.1b timers */\n    int      si_timerid; /* Timer ID; POSIX.1b timers */\n    void    *si_addr;    /* Memory location which caused fault */\n    int      si_band;    /* Band event */\n    int      si_fd;      /* File descriptor */\n} siginfo_t;\n\nstruct sigaction {\n    void ( *sa_handler )( int );\n    void ( *sa_sigaction )( int, siginfo_t*, void* );\n    sigset_t sa_mask;\n    int sa_flags;\n    void ( *sa_restorer )( void );\n};\n\nint sigemptyset( sigset_t* set );\nint sigfillset( sigset_t* set );\nint sigaddset( sigset_t* set, int signum );\nint sigdelset( sigset_t* set, int signum );\nint sigismember( const sigset_t* set, int signum );\n\nsighandler_t signal( int signum, sighandler_t handler );\nint sigaction( int signum, const struct sigaction* act, struct sigaction* oldact );\nint sigprocmask( int how, const sigset_t* set, sigset_t* oldset );\n\nint kill( pid_t pid, int signal );\nint killpg( int pgrp, int signal );\n\nint raise( int signal );\n\n#endif /* _SIGNAL_H_ */\n"
  },
  {
    "path": "src/sdk/include/stdarg.h",
    "content": "\n\n#ifndef _STDARG_H_\n#define _STDARG_H_\n\ntypedef __builtin_va_list va_list;\n\n#define va_start(a,b)  __builtin_va_start(a,b)\n#define va_end(a)      __builtin_va_end(a)\n#define va_arg(a,b)    __builtin_va_arg(a,b)\n#define __va_copy(d,s) __builtin_va_copy((d),(s))\n\n#endif // _STDARG_H_\n"
  },
  {
    "path": "src/sdk/include/stddef.h",
    "content": "\n#ifndef _STDDEF_H\n#define _STDDEF_H\n\n#ifndef\tNULL\n#define NULL\t\t0\n#endif\n\n\n#ifndef _HAVE_PTRDIFF_T\n#define _HAVE_PTRDIFF_T\ntypedef signed long int\tptrdiff_t;\n#endif\n\n#ifndef _HAVE_SIZE_T\n#define _HAVE_SIZE_T\n//typedef\tunsigned int\tsize_t;\ntypedef long unsigned int size_t;\n#endif\n\n\n#if ( (! defined _HAVE_WCHAR_T) && (! defined __cplusplus ) )\n#define _HAVE_WCHAR_T\ntypedef int\twchar_t;\n#endif\n\n#define offsetof(struct_type, member) \\\n          (size_t) &(((struct_type *)0)->member)\n          \n/*#define offsetof(type, memberdesig)\t\\\n\t\t\t((const unsigned int)((ptrdiff_t)&(type.memberdesig) - (ptrdiff_t)&type))\n*/\n\n#endif\n\n"
  },
  {
    "path": "src/sdk/include/stdint.h",
    "content": "\n \n\n#ifndef _STDINT_H_\n#define _STDINT_H_\n\ntypedef signed char int8_t;\ntypedef signed short int16_t;\ntypedef signed int int32_t;\ntypedef signed long long int64_t;\ntypedef unsigned char uint8_t;\ntypedef unsigned short uint16_t;\ntypedef unsigned int uint32_t;\ntypedef unsigned long long uint64_t;\n\ntypedef signed long intptr_t;\ntypedef unsigned long uintptr_t;\n\n#if __WORDSIZE == 64\ntypedef signed long int intmax_t;\ntypedef unsigned long int uintmax_t;\n#else\ntypedef signed long long int intmax_t;\ntypedef unsigned long long int uintmax_t;\n#endif /* __WORDSIZE == 64 */\n\n/* The ISO C99 standard specifies that in C++ implementations these\n   macros should only be defined if explicitly requested.  */\n\n#if !defined __cplusplus || defined __STDC_LIMIT_MACROS\n\n#if __WORDSIZE == 64\n#define __INT64_C(c)  c ## L\n#define __UINT64_C(c) c ## UL\n#else\n#define __INT64_C(c)  c ## LL\n#define __UINT64_C(c) c ## ULL\n#endif\n\n/* Limits of integral types.  */\n\n/* Minimum of signed integral types.  */\n# define INT8_MIN               (-128)\n# define INT16_MIN              (-32767-1)\n# define INT32_MIN              (-2147483647-1)\n# define INT64_MIN              (-__INT64_C(9223372036854775807)-1)\n\n/* Maximum of signed integral types.  */\n# define INT8_MAX               (127)\n# define INT16_MAX              (32767)\n# define INT32_MAX              (2147483647)\n# define INT64_MAX              (__INT64_C(9223372036854775807))\n\n/* Maximum of unsigned integral types.  */\n# define UINT8_MAX              (255)\n# define UINT16_MAX             (65535)\n# define UINT32_MAX             (4294967295U)\n# define UINT64_MAX             (__UINT64_C(18446744073709551615))\n\n#endif\n\n#endif /* _STDINT_H_ */\n"
  },
  {
    "path": "src/sdk/include/stdio.h",
    "content": "\n \n\n#ifndef _STDIO_H_\n#define _STDIO_H_\n\n#define __need_size_t\n#define __need_NULL\n#include <stddef.h>\n#include <stdarg.h>\n#include <sys/types.h>\n\n\n#define _IONBF 0\n#define _IOLBF 1\n#define _IOFBF 2\n\n#define __FILE_CAN_READ    0x01\n#define __FILE_CAN_WRITE   0x02\n#define __FILE_ERROR       0x04\n#define __FILE_EOF         0x08\n#define __FILE_BUFLINEWISE 0x10\n#define __FILE_DONTFREEBUF 0x20\n#define __FILE_NOBUF       0x40\n#define __FILE_BUFINPUT    0x80\n\n#define EOF -1\n\n#define _IO_BUFSIZE 2048\n\n#ifndef BUFSIZ\n#define BUFSIZ _IO_BUFSIZE\n#endif /* BUFSIZ */\n\n#define SEEK_SET 0\n#define SEEK_CUR 1\n#define SEEK_END 2\n\n#define P_tmpdir \"/temp\"\n\ntypedef struct FILE {\n    int fd;\n    int flags;\n    char* buffer;\n    unsigned int buffer_pos;\n    unsigned int buffer_size;\n    unsigned int buffer_data_size;\n    int has_ungotten;\n    unsigned char unget_buffer;\n} FILE;\n\nextern FILE* stdin;\nextern FILE* stdout;\nextern FILE* stderr;\n\nFILE* fopen( const char* path, const char* mode );\nFILE* fdopen( int fd, const char* mode );\nFILE* freopen( const char* path, const char* mode, FILE* stream );\n\nint fclose( FILE* stream );\nint feof( FILE* stream );\nint ferror( FILE* stream );\nint fileno( FILE* stream );\nint fflush( FILE* stream );\nint fseek( FILE* stream, long offset, int whence );\nint fseeko( FILE* stream, off_t offset, int whence );\nlong ftell( FILE* stream );\noff_t ftello( FILE* stream );\nsize_t fread( void* ptr, size_t size, size_t nmemb, FILE* stream );\nsize_t fwrite( const void* ptr, size_t size, size_t nmemb, FILE* stream );\nint fpurge( FILE* stream );\nvoid rewind( FILE* stream );\n\nint ungetc( int c, FILE* stream );\nvoid clearerr( FILE* stream );\n\nint printf( const char* format, ... ) __attribute__(( __format__( __printf__, 1, 2 ) ));\nint fprintf( FILE* stream, const char* format, ... ) __attribute__(( __format__( __printf__, 2, 3 ) ));\nint sprintf( char* str, const char* format, ... ) __attribute__(( __format__( __printf__, 2, 3 ) ));\nint snprintf( char* str, size_t size, const char* format, ... ) __attribute__(( __format__( __printf__, 3, 4 ) ));\n\nint vprintf( const char* format, va_list ap ) __attribute__(( __format__( __printf__, 1, 0 ) ));\nint vfprintf( FILE* stream, const char* format, va_list ap ) __attribute__(( __format__( __printf__, 2, 0 ) ));\nint vsprintf( char *str, const char *format, va_list ap ) __attribute__(( __format__( __printf__, 2, 0 ) ));\nint vsnprintf( char* str, size_t size, const char* format, va_list ap ) __attribute__(( __format__( __printf__, 3, 0 ) ));\n\nint asprintf(char **strp, const char *fmt, ...) __attribute__(( __format__( __printf__, 2, 3 ) ));\n\nint scanf( const char* format, ... );\nint fscanf( FILE* stream, const char* format, ... );\nint sscanf( const char* str, const char* format, ... );\n\nint vscanf( const char* format, va_list ap );\nint vsscanf( const char* str, const char* format, va_list ap );\nint vfscanf( FILE* stream, const char* format, va_list ap );\n\nint fgetc( FILE* stream );\nint getc( FILE* stream );\nchar* fgets( char* s, int size, FILE* stream );\n#define getchar(c) getc(stdin)\n\nint fputc( int c, FILE* stream );\nint putc( int c, FILE* stream );\nint fputs( const char* s, FILE* stream );\nint puts( const char* s );\nint putchar( int c );\n\n#define setbuf(stream,buf) setvbuf(stream,buf,(buf!=NULL)?_IOFBF:_IONBF,BUFSIZ)\n#define setbuffer(stream,buf,size) setvbuf(stream,buf,(buf!=NULL)?_IOFBF:_IONBF,size)\nint setvbuf( FILE* stream, char* buf, int flags, size_t size );\n\nint rename( const char* oldpath, const char* newpath );\nint remove( const char* path );\n\nvoid perror( const char* s );\n\n\n#endif /* _STDIO_H_ */\n"
  },
  {
    "path": "src/sdk/include/stdlib.h",
    "content": "\n \n\n#ifndef _STDLIB_H_\n#define _STDLIB_H_\n\n\n\n#define __need_size_t\n#define __need_NULL\n#include <stddef.h>\n\n\n#define EXIT_FAILURE 1\n#define EXIT_SUCCESS 0\n\n#define ATEXIT_MAX 32\n\n#define WEXITSTATUS(status) (((status) & 0xFF00) >> 8)\n#define WTERMSIG(status)    ((status) & 0x7F)\n\n#define WIFEXITED(status)   (WTERMSIG(status) == 0)\n\nint abs( int j );\nlong labs( long j );\nlong long llabs( long long j );\n\nvoid exit( int status );\nint atexit( void ( *function )( void ) );\n\nchar* getenv( const char* name );\n\nvoid* calloc( size_t nmemb, size_t size ) __attribute__(( malloc ));\nvoid* malloc( size_t size ) __attribute__(( malloc ));\nvoid free( void* ptr );\nvoid* realloc( void* ptr, size_t size );\n\nvoid abort( void ) __attribute__(( __noreturn__ ));\n\nint atoi( const char* s );\nlong atol( const char* s );\nlong long atoll( const char* s );\ndouble atof( const char* s );\n\nlong int strtol( const char* nptr, char** endptr, int base );\nunsigned long int strtoul( const char* nptr, char** endptr, int base );\ndouble strtod( const char* s, char** endptr );\nlong int strtol( const char* nptr, char** endptr, int base );\nlong long int strtoll( const char* nptr, char** endptr, int base );\nunsigned long long int strtoull( const char* nptr, char** endptr, int base );\n\nvoid qsort( void* base, size_t nmemb, size_t size, int ( *compar )( const void*, const void* ) );\nvoid* bsearch( const void* key, const void* base, size_t nmemb, size_t size, int ( *compare )( const void*, const void* ) );\n\nlong int random( void );\nvoid srandom( unsigned int seed );\nint rand( void );\nvoid srand( unsigned int seed );\n\nchar* mktemp( char* templat );\nint mkstemp( char* templat );\nint system(char *ccc);\n\n\n#endif /* _STDLIB_H_ */\n"
  },
  {
    "path": "src/sdk/include/string.h",
    "content": "\n\n#ifndef _STRING_H_\n#define _STRING_H_\n\n#define __need_size_t\n#define __need_NULL\n#include <stddef.h>\n\nvoid* memset( void* s, int c, size_t n );\nvoid* memcpy( void* d, const void* s, size_t n );\nint memcmp( const void* p1, const void* p2, size_t c );\nvoid* memmove( void* dest, const void* src, size_t n );\nvoid* memchr( const void* s, int c, size_t n );\n\nsize_t strlen( const char* s );\nsize_t strnlen( const char* s, size_t count );\nchar* strchr( const char* s, int c );\nchar* strrchr( const char* s, int c );\nchar* strstr( const char* s1, const char* s2 );\nint strcmp( const char* s1, const char* s2 );\nint strncmp( const char* s1, const char* s2, size_t c );\nint strcasecmp( const char* s1, const char* s2 );\nint strncasecmp( const char* s1, const char* s2, size_t c );\nchar* strcpy( char* d, const char* s );\nchar* strncpy( char* d, const char* s, size_t c );\nchar* strcat( char* d, const char* s );\nchar* strncat( char* d, const char* s, size_t c );\nchar* strpbrk( const char* s, const char* accept );\nsize_t strspn( const char* s, const char* accept );\nsize_t strcspn( const char* s, const char* reject );\nchar* strtok_r( char* s, const char* delim, char** ptrptr );\nchar* strtok( char* s, const char* delim );\n\nchar* strdup( const char* s );\nchar* strndup( const char* s, size_t n);\n\nchar* strerror( int errnum );\nchar* strsignal( int signum );\n\n#endif /* _STRING_H_ */\n"
  },
  {
    "path": "src/sdk/include/strings.h",
    "content": "\n \n\n#ifndef _STRINGS_H_\n#define _STRINGS_H_\n\n#endif /* _STRINGS_H_ */\n"
  },
  {
    "path": "src/sdk/include/sys/cdefs.h",
    "content": "\n\n#ifndef _SYS_CDEFS_H_\n#define _SYS_CDEFS_H_\n\n#define __nonnull(params) __attribute__((__nonnull__ params))\n\n#endif // _SYS_CDEFS_H_\n"
  },
  {
    "path": "src/sdk/include/sys/ioctl.h",
    "content": "\n\n#ifndef _SYS_IOCTL_H_\n#define _SYS_IOCTL_H_\n\n#include <sys/types.h>\n\n#include \"../../kernel/core/api/dev/ioctl.h\"\n\nint ioctl( int fd, int request, ... );\n\n#endif /* _SYS_IOCTL_H_ */\n"
  },
  {
    "path": "src/sdk/include/sys/mman.h",
    "content": "\n\n#ifndef _SYS_MMAN_H_\n#define _SYS_MMAN_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n#include <stddef.h>\n#include <sys/types.h>\n\n#define PROT_NONE 0\n#define PROT_READ 1\n#define PROT_WRITE 2\n#define PROT_EXEC 4\n\n#define MAP_FILE 0\n#define MAP_SHARED 1\n#define MAP_PRIVATE 2\n#define MAP_TYPE 0xF\n#define MAP_FIXED 0x10\n#define MAP_ANONYMOUS 0x20\n#define MAP_ANON MAP_ANONYMOUS\n/* Non-standard flag */\n#define MAP_NORESERVE 0x4000\t/* Don't reserve swap space for this mapping.\n\t\t\t\t   Page protection must be set explicitely\n\t\t\t\t   to access page. Only supported for anonymous\n\t\t\t\t   private mappings. */\n#define MAP_AUTOGROW 0x8000\t/* Grow underlying object to mapping size.\n\t\t\t\t   File must be opened for writing. */\n\n#define MAP_FAILED ((void *)-1)\n\n/*\n * Flags for msync.\n */\n#define MS_ASYNC 1\n#define MS_SYNC 2\n#define MS_INVALIDATE 4\n\n/*\n * Flags for posix_madvise.\n */\n#define POSIX_MADV_NORMAL 0\n#define POSIX_MADV_SEQUENTIAL 1\n#define POSIX_MADV_RANDOM 2\n#define POSIX_MADV_WILLNEED 3\n#define POSIX_MADV_DONTNEED 4\n\nextern void *mmap (void *__addr, size_t __len, int __prot, int __flags, int __fd, off_t __off);\nextern int munmap (void *__addr, size_t __len);\nextern int mprotect (void *__addr, size_t __len, int __prot);\nextern int msync (void *__addr, size_t __len, int __flags);\nextern int mlock (const void *__addr, size_t __len);\nextern int munlock (const void *__addr, size_t __len);\n\nextern int posix_madvise (void *__addr, size_t __len, int __advice);\n\nextern int shm_open (const char *__name, int __oflag, mode_t __mode);\nextern int shm_unlink (const char *__name);\n\n#ifdef __cplusplus\n};\n#endif /* __cplusplus */\n\n#endif /*  _SYS_MMAN_H_ */\n"
  },
  {
    "path": "src/sdk/include/sys/mount.h",
    "content": "\n\n#ifndef _SYS_MOUNT_H_\n#define _SYS_MOUNT_H_\n\n#define MOUNT_NONE      0\n#define MOUNT_RO        1\n#define MOUNT_NOATIME   2\n\nint mount(\n    const char* source,\n    const char* target,\n    const char* filesystemtype,\n    unsigned long mountflags,\n    const void* data\n);\n\nint umount(\n    const char* dir\n);\n\n#endif /* _SYS_MOUNT_H_ */\n"
  },
  {
    "path": "src/sdk/include/sys/param.h",
    "content": "\n\n#ifndef _SYS_PARAM_H_\n#define _SYS_PARAM_H_\n\n#include <limits.h>\n\n#undef MIN\n#define MIN(a,b) ((a)<(b)?(a):(b))\n\n#undef MAX\n#define MAX(a,b) ((a)>(b)?(a):(b))\n\n#define MAXPATHLEN PATH_MAX\n\n#endif // _SYS_PARAM_H_\n"
  },
  {
    "path": "src/sdk/include/sys/resource.h",
    "content": "\n\n#ifndef _SYS_RESOURCE_H_\n#define _SYS_RESOURCE_H_\n\n#include <sys/time.h>\n\nstruct rusage {\n    struct timeval ru_utime; /* user time used */\n    struct timeval ru_stime; /* system time used */\n    long   ru_maxrss;        /* maximum resident set size */\n    long   ru_ixrss;         /* integral shared memory size */\n    long   ru_idrss;         /* integral unshared data size */\n    long   ru_isrss;         /* integral unshared stack size */\n    long   ru_minflt;        /* page reclaims */\n    long   ru_majflt;        /* page faults */\n    long   ru_nswap;         /* swaps */\n    long   ru_inblock;       /* block input operations */\n    long   ru_oublock;       /* block output operations */\n    long   ru_msgsnd;        /* messages sent */\n    long   ru_msgrcv;        /* messages received */\n    long   ru_nsignals;      /* signals received */\n    long   ru_nvcsw;         /* voluntary context switches */\n    long   ru_nivcsw;        /* involuntary context switches */\n};\n\n#endif /* _SYS_RESOURCE_H_ */\n"
  },
  {
    "path": "src/sdk/include/sys/select.h",
    "content": "\n\n#ifndef _SYS_SELECT_H_\n#define _SYS_SELECT_H_\n\n#include <sys/time.h>\n#include <sys/types.h>\n\n#define FD_ZERO(set) \\\n    memset( (set)->fds, 0, 1024 / 32 );\n\n#define FD_CLR(fd,set) \\\n    (set)->fds[fd/32] &= ~(1<<(fd%32));\n\n#define FD_SET(fd,set) \\\n    (set)->fds[fd/32] |= (1<<(fd%32));\n\n#define FD_ISSET(fd,set) \\\n    ((set)->fds[fd/32] & (1<<(fd%32)))\n\ntypedef struct fd_set {\n    uint32_t fds[ 1024 / 32 ];\n} fd_set;\n\nint select( int fds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, struct timeval* timeout );\n\n#endif // _SYS_SELECT_H_\n"
  },
  {
    "path": "src/sdk/include/sys/socket.h",
    "content": "\n\n#ifndef _SYS_SOCKET_H_\n#define _SYS_SOCKET_H_\n\n/* Protocol families.  */\n\n#define PF_UNSPEC       0       /* Unspecified.  */\n#define PF_LOCAL        1       /* Local to host (pipes and file-domain).  */\n#define PF_UNIX         PF_LOCAL /* POSIX name for PF_LOCAL.  */\n#define PF_FILE         PF_LOCAL /* Another non-standard name for PF_LOCAL.  */\n#define PF_INET         2       /* IP protocol family.  */\n#define PF_AX25         3       /* Amateur Radio AX.25.  */\n#define PF_IPX          4       /* Novell Internet Protocol.  */\n#define PF_APPLETALK    5       /* Appletalk DDP.  */\n#define PF_NETROM       6       /* Amateur radio NetROM.  */\n#define PF_BRIDGE       7       /* Multiprotocol bridge.  */\n#define PF_ATMPVC       8       /* ATM PVCs.  */\n#define PF_X25          9       /* Reserved for X.25 project.  */\n#define PF_INET6        10      /* IP version 6.  */\n#define PF_ROSE         11      /* Amateur Radio X.25 PLP.  */\n#define PF_DECnet       12      /* Reserved for DECnet project.  */\n#define PF_NETBEUI      13      /* Reserved for 802.2LLC project.  */\n#define PF_SECURITY     14      /* Security callback pseudo AF.  */\n#define PF_KEY          15      /* PF_KEY key management API.  */\n#define PF_NETLINK      16\n#define PF_ROUTE        PF_NETLINK /* Alias to emulate 4.4BSD.  */\n#define PF_PACKET       17      /* Packet family.  */\n#define PF_ASH          18      /* Ash.  */\n#define PF_ECONET       19      /* Acorn Econet.  */\n#define PF_ATMSVC       20      /* ATM SVCs.  */\n#define PF_SNA          22      /* Linux SNA Project */\n#define PF_IRDA         23      /* IRDA sockets.  */\n#define PF_PPPOX        24      /* PPPoX sockets.  */\n#define PF_WANPIPE      25      /* Wanpipe API sockets.  */\n#define PF_BLUETOOTH    31      /* Bluetooth sockets.  */\n#define PF_IUCV         32      /* IUCV sockets.  */\n#define PF_RXRPC        33      /* RxRPC sockets.  */\n#define PF_ISDN         34      /* mISDN sockets.  */\n#define PF_MAX          35      /* For now..  */\n\n/* Address families. */\n\n#define AF_UNSPEC    PF_UNSPEC\n#define AF_LOCAL     PF_LOCAL\n#define AF_UNIX      PF_UNIX\n#define AF_FILE      PF_FILE\n#define AF_INET      PF_INET\n#define AF_AX25      PF_AX25\n#define AF_IPX       PF_IPX\n#define AF_APPLETALK PF_APPLETALK\n#define AF_NETROM    PF_NETROM\n#define AF_BRIDGE    PF_BRIDGE\n#define AF_ATMPVC    PF_ATMPVC\n#define AF_X25       PF_X25\n#define AF_INET6     PF_INET6\n#define AF_ROSE      PF_ROSE\n#define AF_DECnet    PF_DECnet\n#define AF_NETBEUI   PF_NETBEUI\n#define AF_SECURITY  PF_SECURITY\n#define AF_KEY       PF_KEY\n#define AF_NETLINK   PF_NETLINK\n#define AF_ROUTE     PF_ROUTE\n#define AF_PACKET    PF_PACKET\n#define AF_ASH       PF_ASH\n#define AF_ECONET    PF_ECONET\n#define AF_ATMSVC    PF_ATMSVC\n#define AF_SNA       PF_SNA\n#define AF_IRDA      PF_IRDA\n#define AF_PPPOX     PF_PPPOX\n#define AF_WANPIPE   PF_WANPIPE\n#define AF_BLUETOOTH PF_BLUETOOTH\n#define AF_IUCV      PF_IUCV\n#define AF_RXRPC     PF_RXRPC\n#define AF_ISDN      PF_ISDN\n#define AF_MAX       PF_MAX\n\n/* Types of sockets. */\n\nenum socket_type {\n  SOCK_STREAM = 1,              /* Sequenced, reliable, connection-based\n                                   byte streams.  */\n#define SOCK_STREAM SOCK_STREAM\n  SOCK_DGRAM = 2,               /* Connectionless, unreliable datagrams\n                                   of fixed maximum length.  */\n#define SOCK_DGRAM SOCK_DGRAM\n  SOCK_RAW = 3,                 /* Raw protocol interface.  */\n#define SOCK_RAW SOCK_RAW\n};\n\ntypedef unsigned short int sa_family_t;\ntypedef unsigned int socklen_t;\n\nstruct sockaddr {\n    sa_family_t sa_family;\n    char sa_data[ 14 ];\n};\n\nint socket( int domain, int type, int protocol );\nint connect( int fd, const struct sockaddr* address, socklen_t addrlen );\n\n/* Not implemented functions\nint socketpair( int d, int type, int protocol, int sv[2] );\n\nint bind( int sockfd, const struct sockaddr *addr,\n          socklen_t addrlen );\n\nint getsockname( int s, struct sockaddr *name, socklen_t *namelen );\n\nint getpeername( int s, struct sockaddr *name, socklen_t *namelen );\n\nssize_t send( int s, const void *buf, size_t len, int flags );\n\nssize_t sendto( int s, const void *buf, size_t len, int flags,\n                const struct sockaddr *to, socklen_t tolen );\n\nssize_t sendmsg( int s, const struct msghdr *msg, int flags );\n\nssize_t recv( int s, void *buf, size_t len, int flags );\n\nssize_t recvfrom( int s, void *buf, size_t len, int flags,\n                  struct sockaddr *from, socklen_t *fromlen );\n\nssize_t recvmsg( int s, struct msghdr *msg, int flags );\n\nint getsockopt( int s, int level, int optname,\n                void *optval, socklen_t *optlen );\n\nint setsockopt( int s, int level, int optname,\n                const void *optval, socklen_t optlen );\n\nint listen( int sockfd, int backlog );\n\nint accept( int sockfd, struct sockaddr *addr, socklen_t *addrlen );\n\nint shutdown( int s, int how );\n*/\n\n#endif /* _SYS_SOCKET_H_ */\n"
  },
  {
    "path": "src/sdk/include/sys/stat.h",
    "content": "\n\n#ifndef _SYS_STAT_H_\n#define _SYS_STAT_H_\n\n#include <time.h>\n#include <sys/types.h>\n\n#define S_IFMT  00170000\n#define S_IFSOCK 0140000\n#define S_IFLNK  0120000\n#define S_IFREG  0100000\n#define S_IFBLK  0060000\n#define S_IFDIR  0040000\n#define S_IFCHR  0020000\n#define S_IFIFO  0010000\n#define S_ISUID  0004000\n#define S_ISGID  0002000\n#define S_ISVTX  0001000\n\n#define S_ISSOCK(m)  (((m) & S_IFMT) == S_IFSOCK)\n#define S_ISLNK(m)  (((m) & S_IFMT) == S_IFLNK)\n#define S_ISREG(m)  (((m) & S_IFMT) == S_IFREG)\n#define S_ISBLK(m)  (((m) & S_IFMT) == S_IFBLK)\n#define S_ISDIR(m)  (((m) & S_IFMT) == S_IFDIR)\n#define S_ISCHR(m)  (((m) & S_IFMT) == S_IFCHR)\n#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)\n\n#define S_IRWXU 00700\n#define S_IRUSR 00400\n#define S_IWUSR 00200\n#define S_IXUSR 00100\n\n#define S_IRWXG 00070\n#define S_IRGRP 00040\n#define S_IWGRP 00020\n#define S_IXGRP 00010\n\n#define S_IRWXO 00007\n#define S_IROTH 00004\n#define S_IWOTH 00002\n#define S_IXOTH 00001\n\nstruct stat {\n    dev_t st_dev;\n    ino_t st_ino;\n    mode_t st_mode;\n    nlink_t st_nlink;\n    uid_t st_uid;\n    gid_t st_gid;\n    dev_t st_rdev;\n    off_t st_size;\n    blksize_t st_blksize;\n    blkcnt_t st_blocks;\n    time_t st_atime;\n    time_t st_mtime;\n    time_t st_ctime;\n};\n\nint stat( const char* path, struct stat* stat );\nint fstat( int fd, struct stat* stat );\nint lstat( const char* path, struct stat* stat );\n\nint mkdir( const char* pathname, mode_t mode );\n\nmode_t umask( mode_t mask );\n\nint chmod( const char* path, mode_t mode );\n\n#endif // _SYS_STAT_H_\n"
  },
  {
    "path": "src/sdk/include/sys/time.h",
    "content": "\n\n#ifndef _SYS_TIME_H_\n#define _SYS_TIME_H_\n\n#include <time.h>\n\nint gettimeofday( struct timeval* tv, struct timezone* tz );\n\n#endif // _SYS_TIME_H_\n"
  },
  {
    "path": "src/sdk/include/sys/types.h",
    "content": "\n\n#ifndef _SYS_TYPES_H_\n#define _SYS_TYPES_H_\n\n#include <stdint.h>\n\n#define __need_size_t\n#include <stddef.h>\n\n#ifndef NULL\n#ifdef __cplusplus\n#define NULL 0\n#else\n#define NULL ((void*)0)\n#endif /* __cplusplus */\n#endif /* NULL */\n\n#define INFINITE_TIMEOUT 18446744073709551615ULL\n\ntypedef unsigned char u_char;\n\ntypedef int ssize_t;\ntypedef int pid_t;\ntypedef int64_t ino_t;\ntypedef int64_t off_t;\ntypedef int dev_t;\ntypedef int mode_t;\ntypedef int nlink_t;\ntypedef int uid_t;\ntypedef int gid_t;\ntypedef int blksize_t;\ntypedef int64_t blkcnt_t;\n\n#endif /* _SYS_TYPES_H_ */\n"
  },
  {
    "path": "src/sdk/include/sys/wait.h",
    "content": "\n\n#ifndef _SYS_WAIT_H_\n#define _SYS_WAIT_H_\n\n#include <sys/types.h>\n#include <sys/resource.h>\n\n#define WNOHANG   1\n#define WUNTRACED 2\n\npid_t wait( int* status );\npid_t waitpid( pid_t pid, int* status, int options );\npid_t wait3( int* status, int options, struct rusage* rusage );\npid_t wait4( pid_t pid, int* status, int options, struct rusage* rusage );\n\n#endif /* _SYS_WAIT_H_ */\n"
  },
  {
    "path": "src/sdk/include/termios.h",
    "content": "\n \n\n#ifndef _TERMIOS_H_\n#define _TERMIOS_H_\n\n/*\n * Number of control characters.\n */\n\n#define NCCS 19\n\n/*\n * Control characters.\n */\n\n#define VINTR     0\n#define VQUIT     1\n#define VERASE    2\n#define VKILL     3\n#define VEOF      4\n#define VTIME     5\n#define VMIN      6\n#define VSWTC     7\n#define VSTART    8\n#define VSTOP     9\n#define VSUSP    10\n#define VEOL     11\n#define VREPRINT 12\n#define VDISCARD 13\n#define VWERASE  14\n#define VLNEXT   15\n#define VEOL2    16\n\n#define IGNBRK  0000001\n#define BRKINT  0000002\n#define IGNPAR  0000004\n#define PARMRK  0000010\n#define INPCK   0000020\n#define ISTRIP  0000040\n#define INLCR   0000100\n#define IGNCR   0000200\n#define ICRNL   0000400\n#define IUCLC   0001000\n#define IXON    0002000\n#define IXANY   0004000\n#define IXOFF   0010000\n#define IMAXBEL 0020000\n\n#define  B0       0000000\n#define  B50      0000001\n#define  B75      0000002\n#define  B110     0000003\n#define  B134     0000004\n#define  B150     0000005\n#define  B200     0000006\n#define  B300     0000007\n#define  B600     0000010\n#define  B1200    0000011\n#define  B1800    0000012\n#define  B2400    0000013\n#define  B4800    0000014\n#define  B9600    0000015\n#define  B19200   0000016\n#define  B38400   0000017\n#define CSIZE     0000060\n#define   CS5     0000000\n#define   CS6     0000020\n#define   CS7     0000040\n#define   CS8     0000060\n#define CSTOPB    0000100\n#define CREAD     0000200\n#define PARENB    0000400\n#define PARODD    0001000\n#define HUPCL     0002000\n#define CLOCAL    0004000\n#define  B57600   0010001\n#define  B115200  0010002\n#define  B230400  0010003\n#define  B460800  0010004\n#define  B500000  0010005\n#define  B576000  0010006\n#define  B921600  0010007\n#define  B1000000 0010010\n#define  B1152000 0010011\n#define  B1500000 0010012\n#define  B2000000 0010013\n#define  B2500000 0010014\n#define  B3000000 0010015\n#define  B3500000 0010016\n#define  B4000000 0010017\n\n#define ISIG    0000001\n#define ICANON  0000002\n#define XCASE   0000004\n#define ECHO    0000010\n#define ECHOE   0000020\n#define ECHOK   0000040\n#define ECHONL  0000100\n#define NOFLSH  0000200\n#define TOSTOP  0000400\n#define ECHOCTL 0001000\n#define ECHOPRT 0002000\n#define ECHOKE  0004000\n#define FLUSHO  0010000\n#define PENDIN  0040000\n#define IEXTEN  0100000\n\n#define OPOST   0000001\n#define OLCUC   0000002\n#define ONLCR   0000004\n#define OCRNL   0000010\n#define ONOCR   0000020\n#define ONLRET  0000040\n#define OFILL   0000100\n#define OFDEL   0000200\n\n/* tcflow() and TCXONC use these */\n\n#define TCOOFF          0\n#define TCOON           1\n#define TCIOFF          2\n#define TCION           3\n\n/* tcflush() and TCFLSH use these */\n\n#define TCIFLUSH        0\n#define TCOFLUSH        1\n#define TCIOFLUSH       2\n\n/* tcsetattr uses these */\n\n#define TCSANOW         0\n#define TCSADRAIN       1\n#define TCSAFLUSH       2\n\n/* 0x54 is just a magic number to make these relatively unique ('T') */\n\n#define TCGETS          0x5401\n#define TCSETS          0x5402 /* Clashes with SNDCTL_TMR_START sound ioctl */\n#define TCSETSW         0x5403\n#define TCSETSF         0x5404\n#define TCGETA          0x5405\n#define TCSETA          0x5406\n#define TCSETAW         0x5407\n#define TCSETAF         0x5408\n#define TCSBRK          0x5409\n#define TCXONC          0x540A\n#define TCFLSH          0x540B\n#define TIOCEXCL        0x540C\n#define TIOCNXCL        0x540D\n#define TIOCSCTTY       0x540E\n#define TIOCGPGRP       0x540F\n#define TIOCSPGRP       0x5410\n#define TIOCOUTQ        0x5411\n#define TIOCSTI         0x5412\n#define TIOCGWINSZ      0x5413\n#define TIOCSWINSZ      0x5414\n#define TIOCMGET        0x5415\n#define TIOCMBIS        0x5416\n#define TIOCMBIC        0x5417\n#define TIOCMSET        0x5418\n#define TIOCGSOFTCAR    0x5419\n#define TIOCSSOFTCAR    0x541A\n#define FIONREAD        0x541B\n#define TIOCINQ         FIONREAD\n#define TIOCLINUX       0x541C\n#define TIOCCONS        0x541D\n#define TIOCGSERIAL     0x541E\n#define TIOCSSERIAL     0x541F\n#define TIOCPKT         0x5420\n#define FIONBIO         0x5421\n#define TIOCNOTTY       0x5422\n#define TIOCSETD        0x5423\n#define TIOCGETD        0x5424\n\n#define cfgetispeed(tio)      ((tio)->c_ispeed)\n#define cfgetospeed(tio)      ((tio)->c_ospeed)\n#define cfsetispeed(tio, spd) ((tio)->c_ispeed = (spd))\n#define cfsetospeed(tio, spd) ((tio)->c_ospeed = (spd))\n\ntypedef unsigned char cc_t;\ntypedef unsigned int speed_t;\ntypedef unsigned int tcflag_t;\n\nstruct termios {\n    tcflag_t c_iflag;\n    tcflag_t c_oflag;\n    tcflag_t c_cflag;\n    tcflag_t c_lflag;\n    cc_t c_line;\n    cc_t c_cc[ NCCS ];\n    speed_t c_ispeed;\n    speed_t c_ospeed;\n};\n\nstruct winsize {\n    unsigned short ws_row;\n    unsigned short ws_col;\n};\n\nint tcflow( int fd, int action );\nint tcflush( int fd, int queue_selector );\nint tcgetattr( int fd, struct termios* tio );\nint tcsetattr( int fd, int optional_actions, const struct termios* tio );\n\n#endif // _TERMIOS_H_\n"
  },
  {
    "path": "src/sdk/include/time.h",
    "content": "\n\n#ifndef _TIME_H_\n#define _TIME_H_\n\n#include <sys/types.h>\n\n#define time_t uint64_t\n#define suseconds_t int\n\ntypedef unsigned int clock_t;\n\ntypedef struct timeval {\n    time_t      tv_sec;  /* Seconds */\n    suseconds_t tv_usec; /* Microseconds */\n} timeval_t;\n\ntypedef struct timezone {\n    int tz_minuteswest;\n    int tz_dsttime;\n} timezone_t;\n\nstruct timespec {\n    time_t tv_sec;  /* Seconds */\n    long   tv_nsec; /* Nanoseconds */\n};\n\ntypedef struct tm {\n    int tm_sec;    /* Seconds. [0-60] (1 leap second) */\n    int tm_min;    /* Minutes. [0-59] */\n    int tm_hour;   /* Hours.   [0-23] */\n    int tm_mday;   /* Day.     [1-31] */\n    int tm_mon;    /* Month.   [0-11] */\n    int tm_year;   /* Year [1970; ...] */\n    int tm_wday;   /* Day of week. [0-6], 0=Sunday */\n    int tm_yday;   /* Days in year. [0-365] */\n    int tm_isdst;  /* Daylight saving [-1/0/1] */\n} tm_t;\n\nvoid tzset( void );\n\ntime_t time(time_t* tloc);\nint stime(time_t* tptr);\n\nsize_t strftime(char *s, size_t max, const char *format,\n                const struct tm *tm);\n\n/* Converts a broken-down time to UNIX timestamp */\ntime_t mktime(tm_t* tloc);\n\nchar* asctime(const tm_t* tm);\nchar* asctime_r(const tm_t* tm, char* buf);\n\ntm_t* gmtime(const time_t* timep);\ntm_t* gmtime_r(const time_t* timep, tm_t* result);\n\ntm_t* localtime(const time_t* timep);\ntm_t* localtime_r(const time_t* timep, tm_t* result);\n\nchar* ctime( const time_t* timep );\nchar* ctime_r( const time_t* timep, char* buf );\n\nint nanosleep( const struct timespec* req, struct timespec* rem );\n\n#endif // _TIME_H_\n"
  },
  {
    "path": "src/sdk/include/unistd.h",
    "content": "\n \n\n#ifndef _UNISTD_H_\n#define _UNISTD_H_\n\n#include <string.h>\n#include <sys/types.h>\n\n#define STDIN_FILENO  0\n#define STDOUT_FILENO 1\n#define STDERR_FILENO 2\n\n#define F_OK 0x00\n#define R_OK 0x01\n#define W_OK 0x02\n#define X_OK 0x04\n\n#define NAME_MAX 255\n\n#define _D_EXACT_NAMLEN(d) (strlen((d)->d_name))\n#define _D_ALLOC_NAMLEN(d) (NAME_MAX+1)\n\nenum {\n    _PC_LINK_MAX,\n#define _PC_LINK_MAX                    _PC_LINK_MAX\n    _PC_MAX_CANON,\n#define _PC_MAX_CANON                   _PC_MAX_CANON\n    _PC_MAX_INPUT,\n#define _PC_MAX_INPUT                   _PC_MAX_INPUT\n    _PC_NAME_MAX,\n#define _PC_NAME_MAX                    _PC_NAME_MAX\n    _PC_PATH_MAX,\n#define _PC_PATH_MAX                    _PC_PATH_MAX\n    _PC_PIPE_BUF,\n#define _PC_PIPE_BUF                    _PC_PIPE_BUF\n    _PC_CHOWN_RESTRICTED,\n#define _PC_CHOWN_RESTRICTED            _PC_CHOWN_RESTRICTED\n    _PC_NO_TRUNC,\n#define _PC_NO_TRUNC                    _PC_NO_TRUNC\n    _PC_VDISABLE,\n#define _PC_VDISABLE                    _PC_VDISABLE\n    _PC_SYNC_IO,\n#define _PC_SYNC_IO                     _PC_SYNC_IO\n    _PC_ASYNC_IO,\n#define _PC_ASYNC_IO                    _PC_ASYNC_IO\n    _PC_PRIO_IO,\n#define _PC_PRIO_IO                     _PC_PRIO_IO\n    _PC_SOCK_MAXBUF,\n#define _PC_SOCK_MAXBUF                 _PC_SOCK_MAXBUF\n    _PC_FILESIZEBITS,\n#define _PC_FILESIZEBITS                _PC_FILESIZEBITS\n    _PC_REC_INCR_XFER_SIZE,\n#define _PC_REC_INCR_XFER_SIZE          _PC_REC_INCR_XFER_SIZE\n    _PC_REC_MAX_XFER_SIZE,\n#define _PC_REC_MAX_XFER_SIZE           _PC_REC_MAX_XFER_SIZE\n    _PC_REC_MIN_XFER_SIZE,\n#define _PC_REC_MIN_XFER_SIZE           _PC_REC_MIN_XFER_SIZE\n    _PC_REC_XFER_ALIGN,\n#define _PC_REC_XFER_ALIGN              _PC_REC_XFER_ALIGN\n    _PC_ALLOC_SIZE_MIN,\n#define _PC_ALLOC_SIZE_MIN              _PC_ALLOC_SIZE_MIN\n    _PC_SYMLINK_MAX,\n#define _PC_SYMLINK_MAX                 _PC_SYMLINK_MAX\n    _PC_2_SYMLINKS\n#define _PC_2_SYMLINKS                  _PC_2_SYMLINKS\n};\n\nstruct dirent {\n    ino_t d_ino;\n    char d_name[ NAME_MAX + 1 ];\n};\n\nvoid _exit( int status );\n\npid_t fork( void );\n\nint execv( const char* file, char* const argv[] );\nint execve( const char* filename, char* const argv[], char* const envp[] );\nint execvp( const char* filename, char* const argv[] );\nint execlp( const char* file, const char* arg, ... );\n\nvoid* sbrk( int increment );\n\nint open( const char* filename, int flags, ... );\nint close( int fd );\nint dup( int old_fd );\nint dup2( int old_fd, int new_fd );\n\nssize_t read( int fd, void* buf, size_t count );\nssize_t write( int fd, const void* buf, size_t count );\nssize_t pread( int fd, void* buf, size_t count, off_t offset );\nssize_t pwrite( int fd, const void* buf, size_t count, off_t offset );\noff_t lseek( int fd, off_t offset, int whence );\n\nint pipe( int pipefd[2] );\nint isatty( int fd );\nint chdir( const char* path );\nint fchdir( int fd );\nint getdents( int fd, struct dirent* entry, unsigned int count );\nint ftruncate( int fd, off_t length );\n\nint link( const char* oldpath, const char* newpath );\nint access( const char* pathname, int mode );\nint unlink( const char* pathname );\nssize_t readlink( const char* path, char* buf, size_t bufsiz );\nint rmdir( const char* pathname );\nint chown( const char* path, uid_t owner, gid_t group );\nchar* getcwd( char* buf, size_t size );\nint symlink( const char* oldpath, const char* newpath );\nchar* ttyname( int fd );\nint ttyname_r( int fd, char* buf, size_t buflen );\n\npid_t getpid( void );\npid_t getppid( void );\npid_t gettid( void );\nint getpagesize( void );\nint getdtablesize( void );\n\nint gethostname( char* name, size_t len );\n\nunsigned int sleep( unsigned int seconds );\nunsigned int alarm( unsigned int seconds );\n\nlong fpathconf( int fd, int name );\n\nuid_t getuid( void );\nuid_t geteuid( void );\nint setuid( uid_t uid );\nint setreuid( uid_t ruid, uid_t euid );\n\ngid_t getgid( void );\ngid_t getegid( void );\nint setgid( gid_t gid );\nint setregid( gid_t rgid, gid_t egid );\n\npid_t tcgetpgrp( int fd );\nint tcsetpgrp( int fd, pid_t pgrp );\n\npid_t getpgid( pid_t pid );\nint setpgid( pid_t pid, pid_t pgid );\n\npid_t getpgrp( void );\nint setpgrp( void );\n\n#endif /* _UNISTD_H_ */\n"
  },
  {
    "path": "src/sdk/include/utime.h",
    "content": "\n \n\n#ifndef _UTIME_H_\n#define _UTIME_H_\n\n#include <time.h>\n\nstruct utimbuf {\n    time_t actime; /* access time */\n    time_t modtime; /* modification time */\n};\n\nint utime( const char* filename, const struct utimbuf* times );\nint utimes( const char* filename, const timeval_t times[2] );\n\n#endif // _UTIME_H_\n"
  },
  {
    "path": "src/sdk/lib/.gitkeep",
    "content": ""
  },
  {
    "path": "src/sdk/qemu.sh",
    "content": "#!/bin/bash\nqemu -m 1024 -s -hda ./c.img  -curses -serial /dev/tty  -redir tcp:2323::23\n"
  },
  {
    "path": "src/sdk/src/libc/Makefile",
    "content": "ASMOBJS=arch/i386/setjmp.S \\\narch/i386/longjmp.S \\\narch/i386/math/e_exp.S \\\narch/i386/math/e_log.S \\\narch/i386/math/s_sin.S \\\narch/i386/math/s_cos.S \\\narch/i386/math/s_floor.S \\\narch/i386/math/s_ceil.S \\\narch/i386/math/s_frexp.S \\\narch/i386/math/s_fabs.S \\\narch/i386/math/e_fmod.S \\\narch/i386/math/e_atan2.S \\\narch/i386/math/e_hypot.S \\\narch/i386/math/e_pow.S \\\narch/i386/math/s_finite.S \\\narch/i386/math/s_scalbn.S \\\narch/i386/math/e_log10.S \n\nOBJS= arch/i386/getpagesize.c \\\nsrc/os/syscall.c \\\nsrc/opendir.c \\\nsrc/readdir.c \\\nsrc/closedir.c \\\nsrc/rewinddir.c \\\nsrc/udivmoddi4.c \\\nsrc/sscanf.c \\\nsrc/stdlib/malloc.c \\\nsrc/stdlib/abort.c \\\nsrc/stdlib/getenv.c \\\nsrc/stdlib/strtol.c \\\nsrc/stdlib/strtoll.c \\\nsrc/stdlib/strtoul.c \\\nsrc/stdlib/strtoull.c \\\nsrc/stdlib/atoi.c \\\nsrc/stdlib/atol.c \\\nsrc/stdlib/atoll.c \\\nsrc/stdlib/atof.c \\\nsrc/stdlib/qsort.c \\\nsrc/stdlib/bsearch.c \\\nsrc/stdlib/abs.c \\\nsrc/stdlib/labs.c \\\nsrc/stdlib/llabs.c \\\nsrc/stdlib/strtod.c \\\nsrc/stdlib/mkstemp.c \\\nsrc/stdlib/random.c \\\nsrc/stdlib/srandom.c \\\nsrc/stdlib/rand.c \\\nsrc/stdlib/srand.c \\\nsrc/stdlib/mktemp.c \\\nsrc/string/memset.c \\\nsrc/string/memcpy.c \\\nsrc/string/memcmp.c \\\nsrc/string/memmove.c \\\nsrc/string/memchr.c \\\nsrc/string/strchr.c \\\nsrc/string/strrchr.c \\\nsrc/string/strlen.c \\\nsrc/string/strnlen.c \\\nsrc/string/strcmp.c \\\nsrc/string/strncmp.c \\\nsrc/string/strcasecmp.c \\\nsrc/string/strncasecmp.c \\\nsrc/string/strdup.c \\\nsrc/string/strndup.c \\\nsrc/string/strcpy.c \\\nsrc/string/strncpy.c \\\nsrc/string/strstr.c \\\nsrc/string/strerror.c \\\nsrc/string/strsignal.c \\\nsrc/string/strcat.c \\\nsrc/string/strncat.c \\\nsrc/string/strpbrk.c \\\nsrc/string/strspn.c \\\nsrc/string/strcspn.c \\\nsrc/string/strtok_r.c \\\nsrc/string/strtok.c \\\nsrc/unistd/sbrk.c \\\nsrc/unistd/fork.c \\\nsrc/unistd/execve.c \\\nsrc/unistd/execv.c \\\nsrc/unistd/execlp.c \\\nsrc/unistd/dup.c \\\nsrc/unistd/dup2.c \\\nsrc/unistd/write.c \\\nsrc/unistd/read.c \\\nsrc/unistd/pwrite.c \\\nsrc/unistd/pread.c \\\nsrc/unistd/exit.c \\\nsrc/unistd/getdents.c \\\nsrc/unistd/close.c \\\nsrc/unistd/execvp.c \\\nsrc/unistd/fchdir.c \\\nsrc/unistd/isatty.c \\\nsrc/unistd/lseek.c \\\nsrc/unistd/unlink.c \\\nsrc/unistd/readlink.c \\\nsrc/unistd/getcwd.c \\\nsrc/unistd/sleep.c \\\nsrc/unistd/access.c \\\nsrc/unistd/chdir.c \\\nsrc/unistd/ftruncate.c \\\nsrc/unistd/getpid.c \\\nsrc/unistd/getppid.c \\\nsrc/unistd/gettid.c \\\nsrc/unistd/link.c \\\nsrc/unistd/rmdir.c \\\nsrc/unistd/chown.c \\\nsrc/unistd/symlink.c \\\nsrc/unistd/ttyname.c \\\nsrc/unistd/pipe.c \\\nsrc/unistd/mmap.c \\\nsrc/unistd/alarm.c \\\nsrc/unistd/fpathconf.c \\\nsrc/unistd/getuid.c \\\nsrc/unistd/geteuid.c \\\nsrc/unistd/setuid.c \\\nsrc/unistd/setreuid.c \\\nsrc/unistd/getgid.c \\\nsrc/unistd/getegid.c \\\nsrc/unistd/setgid.c \\\nsrc/unistd/setregid.c \\\nsrc/unistd/gethostname.c \\\nsrc/unistd/getdtablesize.c \\\nsrc/unistd/getpgid.c \\\nsrc/unistd/setpgid.c \\\nsrc/unistd/getpgrp.c \\\nsrc/unistd/setpgrp.c \\\nsrc/fcntl/open.c \\\nsrc/fcntl/creat.c \\\nsrc/fcntl/fcntl.c \\\nsrc/stdio/support_bufio.c \\\nsrc/stdio/support_pf.c \\\nsrc/stdio/support_supcon.c \\\nsrc/stdio/stdio_internal.c \\\nsrc/stdio/streams.c \\\nsrc/stdio/ferror.c \\\nsrc/stdio/fgetc.c \\\nsrc/stdio/getc.c \\\nsrc/stdio/fgets.c \\\nsrc/stdio/fputc.c \\\nsrc/stdio/fputs.c \\\nsrc/stdio/fileno.c \\\nsrc/stdio/feof.c \\\nsrc/stdio/fflush.c \\\nsrc/stdio/ungetc.c \\\nsrc/stdio/clearerr.c \\\nsrc/stdio/fopen.c \\\nsrc/stdio/fdopen.c \\\nsrc/stdio/freopen.c \\\nsrc/stdio/fclose.c \\\nsrc/stdio/putc.c \\\nsrc/stdio/setvbuf.c \\\nsrc/stdio/fseek.c \\\nsrc/stdio/ftell.c \\\nsrc/stdio/fread.c \\\nsrc/stdio/fwrite.c \\\nsrc/stdio/rewind.c \\\nsrc/stdio/perror.c \\\nsrc/stdio/puts.c \\\nsrc/stdio/putchar.c \\\nsrc/stdio/rename.c \\\nsrc/stdio/remove.c \\\nsrc/stdio/fpurge.c \\\nsrc/time/tzset.c \\\nsrc/time/time_int.c \\\nsrc/time/strftime.c \\\nsrc/time/mktime.c \\\nsrc/time/ctime.c \\\nsrc/time/ctime_r.c \\\nsrc/time/localtime.c \\\nsrc/time/localtime_r.c \\\nsrc/time/asctime.c \\\nsrc/time/asctime_r.c \\\nsrc/time/gmtime.c \\\nsrc/time/gmtime_r.c \\\nsrc/time/gettimeofday.c \\\nsrc/time/ctime.c \\\nsrc/time/time.c \\\nsrc/time/nanosleep.c \\\nsrc/getopt/getopt.c \\\nsrc/getopt/getopt_long.c \\\nsrc/getopt/getopt_long_only.c \\\nsrc/sys/stat.c \\\nsrc/sys/fstat.c \\\nsrc/sys/stime.c \\\nsrc/sys/mkdir.c \\\nsrc/sys/ioctl.c \\\nsrc/sys/select.c \\\nsrc/sys/mount.c \\\nsrc/sys/umount.c \\\nsrc/sys/lstat.c \\\nsrc/sys/umask.c \\\nsrc/sys/chmod.c \\\nsrc/sys/utime.c \\\nsrc/sys/utimes.c \\\nsrc/sys/wait.c \\\nsrc/sys/wait3.c \\\nsrc/sys/wait4.c \\\nsrc/sys/waitpid.c \\\nsrc/sys/socket.c \\\nsrc/sys/connect.c \\\nsrc/ctype/isalpha.c \\\nsrc/ctype/isupper.c \\\nsrc/ctype/isblank.c \\\nsrc/ctype/islower.c \\\nsrc/ctype/isdigit.c \\\nsrc/ctype/isxdigit.c \\\nsrc/ctype/isalnum.c \\\nsrc/ctype/isspace.c \\\nsrc/ctype/isprint.c \\\nsrc/ctype/iscntrl.c \\\nsrc/ctype/tolower.c \\\nsrc/ctype/toupper.c \\\nsrc/ctype/toascii.c \\\nsrc/ctype/isgraph.c \\\nsrc/ctype/ispunct.c \\\nsrc/ctype/isascii.c \\\nsrc/signal/signal.c \\\nsrc/signal/sigaction.c \\\nsrc/signal/kill.c \\\nsrc/signal/killpg.c \\\nsrc/signal/raise.c \\\nsrc/signal/sigemptyset.c \\\nsrc/signal/sigfillset.c \\\nsrc/signal/sigaddset.c \\\nsrc/signal/sigdelset.c \\\nsrc/signal/sigismember.c \\\nsrc/signal/sigprocmask.c \\\nsrc/locale/localeconv.c \\\nsrc/locale/setlocale.c \\\nsrc/termios/tcflush.c \\\nsrc/termios/tcgetattr.c \\\nsrc/termios/tcsetattr.c \\\nsrc/termios/tcflow.c \\\nsrc/termios/tcgetpgrp.c \\\nsrc/termios/tcsetpgrp.c \\\nsrc/math/s_ldexp.c \\\nsrc/math/s_modf.c \\\nsrc/os/debug.c \\\nsrc/os/semaphore.c \\\nsrc/os/sysinfo.c \\\nsrc/os/region.c \\\nsrc/os/module.c \\\nsrc/os/os.c \\\nsrc/os/thread.c \\\nsrc/os/ipc.c \\\nsrc/pwd/getpwuid.c \\\nsrc/pwd/getpwent.c \\\nsrc/pwd/getpwnam.c \\\nsrc/pwd/endpwent.c \\\nsrc/pwd/setpwent.c \\\nsrc/network/inet_aton.c \\\nsrc/network/inet_ntoa.c \n\n# src/trio/trio.c \\\n# src/trio/trionan.c \\\n# src/trio/triostr.c \\\n\nSTART=src/start.c\nSTARTO= $(START:.c=.o) \nOBJO = $(OBJS:.c=.o) \nOBJSO= $(ASMOBJS:.S=.o)\nOBJ=libc.a crt\nCC=gcc -w -m32 -Wa,--32  -g -nostdlib -nostdinc -trigraphs  -I $(SDKDIR)/include -c\nSDKDIR=../..\n\nall: $(OBJ) \n\nlibc.a: $(OBJO) $(OBJSO) \n\tar rcs $@ *.o\n\tcp libc.a $(SDKDIR)/lib/libc.a\n\t\ncrt: $(STARTO)\n\tcp start.o $(SDKDIR)/lib/crt_c.o\n\trm *.o\n\t\n%.o: %.c\n\t$(CC) $<\n\t\n%.o: %.S\n\t$(CC) $<\n\nclean:\n\trm -f $(OBJ) *.o *.a\n"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/getpagesize.c",
    "content": "/* getpagesize function\n *\n * Copyright (c) 2009 Zoltan Kovacs\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of version 2 of the GNU General Public License\n * as published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n */\n\n#include <unistd.h>\n\nint getpagesize( void ) {\n    return 4096;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/longjmp.S",
    "content": "/* longjmp function\n *\n * Copyright (c) 2009 Zoltan Kovacs\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of version 2 of the GNU General Public License\n * as published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n */\n\n.section .text\n\n.global longjmp\n\nlongjmp:\n    movl 4(%esp), %edx\n    movl 8(%esp), %eax\n\n    /* Restore registers */\n\n    movl 4(%edx), %ebp\n    movl 8(%edx), %esp\n    movl 12(%edx), %ebx\n    movl 16(%edx), %edi\n    movl 20(%edx), %esi\n\n    /* Restore return address */\n\n    movl 0(%edx), %ecx\n    movl %ecx, 0(%esp)\n\n    /* Check return code */\n\n    cmpl $0, %eax\n    je  1f\n    ret\n\n1:\n    movl $1, %eax\n    ret\n\n"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/math/e_atan2.S",
    "content": "/*\n * Written by J.T. Conklin <jtc@netbsd.org>.\n * Public domain.\n */\n\n.section .text\n\n.align 4\n\n.global atan2\n\n\natan2:\n\tfldl\t 4(%esp)\n\tfldl\t12(%esp)\n\tfpatan\n\tret\n\n"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/math/e_exp.S",
    "content": "/*\n * Written by J.T. Conklin <jtc@netbsd.org>.\n * Public domain.\n */\n\n/* e^x = 2^(x * log2(e)) */\n\n.section .text\n\n.align 4\n\n.global exp\n\n\nexp:\n\tfldl\t4(%esp)\n/* I added the following ugly construct because exp(+-Inf) resulted\n   in NaN.  The ugliness results from the bright minds at Intel.\n   For the i686 the code can be written better.\n   -- drepper@cygnus.com.  */\n\tfxam\t\t\t\t/* Is NaN or +-Inf?  */\n\tfstsw\t%ax\n\tmovb\t$0x45, %dh\n\tandb\t%ah, %dh\n\tcmpb\t$0x05, %dh\n\tje\t1f\t\t\t/* Is +-Inf, jump.  */\n\tfldl2e\n\tfmulp\t\t\t\t/* x * log2(e) */\n\tfld\t%st\n\tfrndint\t\t\t\t/* int(x * log2(e)) */\n\tfsubr\t%st,%st(1)\t\t/* fract(x * log2(e)) */\n\tfxch\n\tf2xm1\t\t\t\t/* 2^(fract(x * log2(e))) - 1 */\n\tfld1\n\tfaddp\t\t\t\t/* 2^(fract(x * log2(e))) */\n\tfscale\t\t\t\t/* e^x */\n\tfstp\t%st(1)\n\tret\n\n1:\ttestl\t$0x200, %eax\t\t/* Test sign.  */\n\tjz\t2f\t\t\t/* If positive, jump.  */\n\tfstp\t%st\n\tfldz\t\t\t\t/* Set result to 0.  */\n2:\tret\n\n"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/math/e_fmod.S",
    "content": "/*\n * Written by J.T. Conklin <jtc@netbsd.org>.\n * Public domain.\n */\n\n.section .text\n\n.align 4\n\n.global fmod\n\n\nfmod:\n\tfldl\t12(%esp)\n\tfldl\t4(%esp)\n1:\tfprem\n\tfstsw\t%ax\n\tsahf\n\tjp\t1b\n\tfstp\t%st(1)\n\tret\n\n"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/math/e_hypot.S",
    "content": "/* Compute the hypothenuse of X and Y.\n   Copyright (C) 1998 Free Software Foundation, Inc.\n   This file is part of the GNU C Library.\n   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.\n\n   The GNU C Library is free software; you can redistribute it and/or\n   modify it under the terms of the GNU Lesser General Public\n   License as published by the Free Software Foundation; either\n   version 2.1 of the License, or (at your option) any later version.\n\n   The GNU C Library is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public\n   License along with the GNU C Library; if not, write to the Free\n   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA\n   02111-1307 USA.  */\n\n.section .text\n\n.align 4\n\n.global hypot\n\n\nhypot:\n\tfldl\t4(%esp)\t\t// x\n\tfxam\n\tfnstsw\n\tfldl\t12(%esp)\t// y : x\n\tmovb\t%ah, %ch\n\tfxam\n\tfnstsw\n\tmovb\t%ah, %al\n\torb\t%ch, %ah\n\tsahf\n\tjc\t1f\n\tfmul\t%st(0)\t\t// y * y : x\n\tfxch\t\t\t// x : y * y\n\tfmul\t%st(0)\t\t// x * x : y * y\n\tfaddp\t\t\t// x * x + y * y\n\tfsqrt\n2:\tret\n\n\t// We have to test whether any of the parameters is Inf.\n\t// In this case the result is infinity.\n1:\tandb\t$0x45, %al\n\tcmpb\t$5, %al\n\tje\t3f\t\t// jump if y is Inf\n\tandb\t$0x45, %ch\n\tcmpb\t$5, %ch\n\tjne\t4f\t\t// jump if x is not Inf\n\tfxch\n3:\tfstp\t%st(1)\n\tfabs\n\tjmp\t2b\n\n4:\ttestb\t$1, %al\n\tjnz\t5f\t\t// y is NaN\n\tfxch\n5:\tfstp\t%st(1)\n\tjmp\t2b\n\n"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/math/e_log.S",
    "content": "/*\n * Written by J.T. Conklin <jtc@netbsd.org>.\n * Public domain.\n *\n * Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.\n */\n\n.section .rodata\n\n.align 4\n\n\none:\n    .double 1.0\n\n\n/* It is not important that this constant is precise.  It is only\n   a value which is known to be on the safe side for using the\n   fyl2xp1 instruction.  */\n\n\nlimit:\n    .double 0.29\n\n\n\n#ifdef PIC\n#define MO(op) op##@GOTOFF(%edx)\n#else\n#define MO(op) op\n#endif\n\n.section .text\n\n.global log\n\n\nlog:\n\tfldln2\t\t\t// log(2)\n\tfldl\t4(%esp)\t\t// x : log(2)\n\tfxam\n\tfnstsw\n#ifdef PIC\n\tLOAD_PIC_REG (dx)\n#endif\n\tfld\t%st\t\t// x : x : log(2)\n\tsahf\n\tjc\t3f\t\t// in case x is NaN or +-Inf\n4:\tfsubl\tMO(one)\t\t// x-1 : x : log(2)\n\tfld\t%st\t\t// x-1 : x-1 : x : log(2)\n\tfabs\t\t\t// |x-1| : x-1 : x : log(2)\n\tfcompl\tMO(limit)\t// x-1 : x : log(2)\n\tfnstsw\t\t\t// x-1 : x : log(2)\n\tandb\t$0x45, %ah\n\tjz\t2f\n\tfstp\t%st(1)\t\t// x-1 : log(2)\n\tfyl2xp1\t\t\t// log(x)\n\tret\n\n2:\tfstp\t%st(0)\t\t// x : log(2)\n\tfyl2x\t\t\t// log(x)\n\tret\n\n3:\tjp\t4b\t\t// in case x is +-Inf\n\tfstp\t%st(1)\n\tfstp\t%st(1)\n\tret\n\n"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/math/e_log10.S",
    "content": "/*\n * Written by J.T. Conklin <jtc@netbsd.org>.\n * Public domain.\n *\n * Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.\n */\n\n.section .rodata\n\n.align 4\n\none:\n.double 1.0\n\n\n/* It is not important that this constant is precise.  It is only\n   a value which is known to be on the safe side for using the\n   fyl2xp1 instruction.  */\n\n\nlimit:\n.double 0.29\n\n\n#ifdef PIC\n#define MO(op) op##@GOTOFF(%edx)\n#else\n#define MO(op) op\n#endif\n\n.section .text\n\n.align 4\n\n.global log10\n\n\nlog10:\n\tfldlg2\t\t\t// log10(2)\n\tfldl\t4(%esp)\t\t// x : log10(2)\n#ifdef PIC\n\tLOAD_PIC_REG (dx)\n#endif\n\tfxam\n\tfnstsw\n\tfld\t%st\t\t// x : x : log10(2)\n\tsahf\n\tjc\t3f\t\t// in case x is NaN or Inf\n4:\tfsubl\tMO(one)\t\t// x-1 : x : log10(2)\n\tfld\t%st\t\t// x-1 : x-1 : x : log10(2)\n\tfabs\t\t\t// |x-1| : x-1 : x : log10(2)\n\tfcompl\tMO(limit)\t// x-1 : x : log10(2)\n\tfnstsw\t\t\t// x-1 : x : log10(2)\n\tandb\t$0x45, %ah\n\tjz\t2f\n\tfstp\t%st(1)\t\t// x-1 : log10(2)\n\tfyl2xp1\t\t\t// log10(x)\n\tret\n\n2:\tfstp\t%st(0)\t\t// x : log10(2)\n\tfyl2x\t\t\t// log10(x)\n\tret\n\n3:\tjp\t4b\t\t// in case x is Inf\n\tfstp\t%st(1)\n\tfstp\t%st(1)\n\tret\n\n"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/math/e_pow.S",
    "content": "/* ix87 specific implementation of pow function.\n   Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004, 2005, 2007\n   Free Software Foundation, Inc.\n   This file is part of the GNU C Library.\n   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.\n\n   The GNU C Library is free software; you can redistribute it and/or\n   modify it under the terms of the GNU Lesser General Public\n   License as published by the Free Software Foundation; either\n   version 2.1 of the License, or (at your option) any later version.\n\n   The GNU C Library is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public\n   License along with the GNU C Library; if not, write to the Free\n   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA\n   02111-1307 USA.  */\n\n.section .rodata\n\n.align 4\n\n\ninf_zero:\ninfinity:\n.byte 0, 0, 0, 0, 0, 0, 0xf0, 0x7f\n\n\n\nzero:\n.double 0.0\n\n\n\nminf_mzero:\nminfinity:\n.byte 0, 0, 0, 0, 0, 0, 0xf0, 0xff\nmzero:\n.byte 0, 0, 0, 0, 0, 0, 0, 0x80\n\n\n\none:\n.double 1.0\n\n\n\nlimit:\n.double 0.29\n\n\n\np63:\t.byte 0, 0, 0, 0, 0, 0, 0xe0, 0x43\n\n\n#ifdef PIC\n#define MO(op) op##@GOTOFF(%ecx)\n#define MOX(op,x,f) op##@GOTOFF(%ecx,x,f)\n#else\n#define MO(op) op\n#define MOX(op,x,f) op(,x,f)\n#endif\n\n.section .text\n\n.align 4\n\n.global pow\n\n\npow:\n\tfldl\t12(%esp)\t// y\n\tfxam\n\n#ifdef\tPIC\n\tLOAD_PIC_REG (cx)\n#endif\n\n\tfnstsw\n\tmovb\t%ah, %dl\n\tandb\t$0x45, %ah\n\tcmpb\t$0x40, %ah\t// is y == 0 ?\n\tje\t11f\n\n\tcmpb\t$0x05, %ah\t// is y == inf ?\n\tje\t12f\n\n\tcmpb\t$0x01, %ah\t// is y == NaN ?\n\tje\t30f\n\n\tfldl\t4(%esp)\t\t// x : y\n\n\tsubl\t$8,%esp\n\n\tfxam\n\tfnstsw\n\tmovb\t%ah, %dh\n\tandb\t$0x45, %ah\n\tcmpb\t$0x40, %ah\n\tje\t20f\t\t// x is 0\n\n\tcmpb\t$0x05, %ah\n\tje\t15f\t\t// x is inf\n\n\tfxch\t\t\t// y : x\n\n\t/* fistpll raises invalid exception for |y| >= 1L<<63.  */\n\tfld\t%st\t\t// y : y : x\n\tfabs\t\t\t// |y| : y : x\n\tfcompl\tMO(p63)\t\t// y : x\n\tfnstsw\n\tsahf\n\tjnc\t2f\n\n\t/* First see whether `y' is a natural number.  In this case we\n\t   can use a more precise algorithm.  */\n\tfld\t%st\t\t// y : y : x\n\tfistpll\t(%esp)\t\t// y : x\n\tfildll\t(%esp)\t\t// int(y) : y : x\n\tfucomp\t%st(1)\t\t// y : x\n\tfnstsw\n\tsahf\n\tjne\t2f\n\n\t/* OK, we have an integer value for y.  */\n\tpopl\t%eax\n\tpopl\t%edx\n\torl\t$0, %edx\n\tfstp\t%st(0)\t\t// x\n\tjns\t4f\t\t// y >= 0, jump\n\tfdivrl\tMO(one)\t\t// 1/x\t\t(now referred to as x)\n\tnegl\t%eax\n\tadcl\t$0, %edx\n\tnegl\t%edx\n4:\tfldl\tMO(one)\t\t// 1 : x\n\tfxch\n\n6:\tshrdl\t$1, %edx, %eax\n\tjnc\t5f\n\tfxch\n\tfmul\t%st(1)\t\t// x : ST*x\n\tfxch\n5:\tfmul\t%st(0), %st\t// x*x : ST*x\n\tshrl\t$1, %edx\n\tmovl\t%eax, %ecx\n\torl\t%edx, %ecx\n\tjnz\t6b\n\tfstp\t%st(0)\t\t// ST*x\n\tret\n\n\t/* y is NAN */\n30:\tfldl\t4(%esp)\t\t// x : y\n\tfldl\tMO(one)\t\t// 1.0 : x : y\n\tfucomp\t%st(1)\t\t// x : y\n\tfnstsw\n\tsahf\n\tje\t31f\n\tfxch\t\t\t// y : x\n31:\tfstp\t%st(1)\n\tret\n\n.align 4\n2:\t/* y is a real number.  */\n\tfxch\t\t\t// x : y\n\tfldl\tMO(one)\t\t// 1.0 : x : y\n\tfldl\tMO(limit)\t// 0.29 : 1.0 : x : y\n\tfld\t%st(2)\t\t// x : 0.29 : 1.0 : x : y\n\tfsub\t%st(2)\t\t// x-1 : 0.29 : 1.0 : x : y\n\tfabs\t\t\t// |x-1| : 0.29 : 1.0 : x : y\n\tfucompp\t\t\t// 1.0 : x : y\n\tfnstsw\n\tfxch\t\t\t// x : 1.0 : y\n\tsahf\n\tja\t7f\n\tfsub\t%st(1)\t\t// x-1 : 1.0 : y\n\tfyl2xp1\t\t\t// log2(x) : y\n\tjmp\t8f\n\n7:\tfyl2x\t\t\t// log2(x) : y\n8:\tfmul\t%st(1)\t\t// y*log2(x) : y\n\tfst\t%st(1)\t\t// y*log2(x) : y*log2(x)\n\tfrndint\t\t\t// int(y*log2(x)) : y*log2(x)\n\tfsubr\t%st, %st(1)\t// int(y*log2(x)) : fract(y*log2(x))\n\tfxch\t\t\t// fract(y*log2(x)) : int(y*log2(x))\n\tf2xm1\t\t\t// 2^fract(y*log2(x))-1 : int(y*log2(x))\n\tfaddl\tMO(one)\t\t// 2^fract(y*log2(x)) : int(y*log2(x))\n\tfscale\t\t\t// 2^fract(y*log2(x))*2^int(y*log2(x)) : int(y*log2(x))\n\taddl\t$8, %esp\n\tfstp\t%st(1)\t\t// 2^fract(y*log2(x))*2^int(y*log2(x))\n\tret\n\n\n\t// pow(x,0) = 1\n.align 4\n11:\tfstp\t%st(0)\t\t// pop y\n\tfldl\tMO(one)\n\tret\n\n\t// y == inf\n.align 4\n12:\tfstp\t%st(0)\t\t// pop y\n\tfldl\tMO(one)\t\t// 1\n\tfldl\t4(%esp)\t\t// x : 1\n\tfabs\t\t\t// abs(x) : 1\n\tfucompp\t\t\t// < 1, == 1, or > 1\n\tfnstsw\n\tandb\t$0x45, %ah\n\tcmpb\t$0x45, %ah\n\tje\t13f\t\t// jump if x is NaN\n\n\tcmpb\t$0x40, %ah\n\tje\t14f\t\t// jump if |x| == 1\n\n\tshlb\t$1, %ah\n\txorb\t%ah, %dl\n\tandl\t$2, %edx\n\tfldl\tMOX(inf_zero, %edx, 4)\n\tret\n\n.align 4\n14:\tfldl\tMO(one)\n\tret\n\n.align 4\n13:\tfldl\t4(%esp)\t\t// load x == NaN\n\tret\n\n.align 4\n\t// x is inf\n15:\tfstp\t%st(0)\t\t// y\n\ttestb\t$2, %dh\n\tjz\t16f\t\t// jump if x == +inf\n\n\t// We must find out whether y is an odd integer.\n\tfld\t%st\t\t// y : y\n\tfistpll\t(%esp)\t\t// y\n\tfildll\t(%esp)\t\t// int(y) : y\n\tfucompp\t\t\t// <empty>\n\tfnstsw\n\tsahf\n\tjne\t17f\n\n\t// OK, the value is an integer, but is the number of bits small\n\t// enough so that all are coming from the mantissa?\n\tpopl\t%eax\n\tpopl\t%edx\n\tandb\t$1, %al\n\tjz\t18f\t\t// jump if not odd\n\tmovl\t%edx, %eax\n\torl\t%edx, %edx\n\tjns\t155f\n\tnegl\t%eax\n155:\tcmpl\t$0x00200000, %eax\n\tja\t18f\t\t// does not fit in mantissa bits\n\t// It's an odd integer.\n\tshrl\t$31, %edx\n\tfldl\tMOX(minf_mzero, %edx, 8)\n\tret\n\n.align 4\n16:\tfcompl\tMO(zero)\n\taddl\t$8, %esp\n\tfnstsw\n\tshrl\t$5, %eax\n\tandl\t$8, %eax\n\tfldl\tMOX(inf_zero, %eax, 1)\n\tret\n\n.align 4\n17:\tshll\t$30, %edx\t// sign bit for y in right position\n\taddl\t$8, %esp\n18:\tshrl\t$31, %edx\n\tfldl\tMOX(inf_zero, %edx, 8)\n\tret\n\n.align 4\n\t// x is 0\n20:\tfstp\t%st(0)\t\t// y\n\ttestb\t$2, %dl\n\tjz\t21f\t\t// y > 0\n\n\t// x is 0 and y is < 0.  We must find out whether y is an odd integer.\n\ttestb\t$2, %dh\n\tjz\t25f\n\n\tfld\t%st\t\t// y : y\n\tfistpll\t(%esp)\t\t// y\n\tfildll\t(%esp)\t\t// int(y) : y\n\tfucompp\t\t\t// <empty>\n\tfnstsw\n\tsahf\n\tjne\t26f\n\n\t// OK, the value is an integer, but is the number of bits small\n\t// enough so that all are coming from the mantissa?\n\tpopl\t%eax\n\tpopl\t%edx\n\tandb\t$1, %al\n\tjz\t27f\t\t// jump if not odd\n\tcmpl\t$0xffe00000, %edx\n\tjbe\t27f\t\t// does not fit in mantissa bits\n\t// It's an odd integer.\n\t// Raise divide-by-zero exception and get minus infinity value.\n\tfldl\tMO(one)\n\tfdivl\tMO(zero)\n\tfchs\n\tret\n\n25:\tfstp\t%st(0)\n26:\taddl\t$8, %esp\n27:\t// Raise divide-by-zero exception and get infinity value.\n\tfldl\tMO(one)\n\tfdivl\tMO(zero)\n\tret\n\n.align 4\n\t// x is 0 and y is > 0.  We must find out whether y is an odd integer.\n21:\ttestb\t$2, %dh\n\tjz\t22f\n\n\tfld\t%st\t\t// y : y\n\tfistpll\t(%esp)\t\t// y\n\tfildll\t(%esp)\t\t// int(y) : y\n\tfucompp\t\t\t// <empty>\n\tfnstsw\n\tsahf\n\tjne\t23f\n\n\t// OK, the value is an integer, but is the number of bits small\n\t// enough so that all are coming from the mantissa?\n\tpopl\t%eax\n\tpopl\t%edx\n\tandb\t$1, %al\n\tjz\t24f\t\t// jump if not odd\n\tcmpl\t$0xffe00000, %edx\n\tjae\t24f\t\t// does not fit in mantissa bits\n\t// It's an odd integer.\n\tfldl\tMO(mzero)\n\tret\n\n22:\tfstp\t%st(0)\n23:\taddl\t$8, %esp\t// Don't use 2 x pop\n24:\tfldl\tMO(zero)\n\tret\n\n"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/math/s_ceil.S",
    "content": "/*\n * Written by J.T. Conklin <jtc@netbsd.org>.\n * Public domain.\n */\n\n.section .text\n\n.align 4\n\n.global ceil\n\n\nceil:\n\tfldl\t4(%esp)\n\tsubl\t$8,%esp\n\n\tfstcw\t4(%esp)\t\t\t/* store fpu control word */\n\n\t/* We use here %edx although only the low 1 bits are defined.\n\t   But none of the operations should care and they are faster\n\t   than the 16 bit operations.  */\n\tmovl\t$0x0800,%edx\t\t/* round towards +oo */\n\torl\t4(%esp),%edx\n\tandl\t$0xfbff,%edx\n\tmovl\t%edx,(%esp)\n\tfldcw\t(%esp)\t\t\t/* load modified control word */\n\n\tfrndint\t\t\t\t/* round */\n\n\tfldcw\t4(%esp)\t\t\t/* restore original control word */\n\n\taddl\t$8,%esp\n\tret\n\n"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/math/s_cos.S",
    "content": "/*\n * Written by J.T. Conklin <jtc@netbsd.org>.\n * Public domain.\n */\n\n.section .text\n\n.align 4\n\n.global cos\n\n\ncos:\n\tfldl\t4(%esp)\n\tfcos\n\tfnstsw\t%ax\n\ttestl\t$0x400,%eax\n\tjnz\t1f\n\tret\n\n.align 4\n\n1:\tfldpi\n\tfadd\t%st(0)\n\tfxch\t%st(1)\n2:\tfprem1\n\tfnstsw\t%ax\n\ttestl\t$0x400,%eax\n\tjnz\t2b\n\tfstp\t%st(1)\n\tfcos\n\tret\n\n"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/math/s_fabs.S",
    "content": ".section .text\n\n.align 4\n\n.global fabs\n\n\nfabs:\n\tfldl\t4(%esp)\n\tfabs\n\tret\n\n"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/math/s_finite.S",
    "content": "/*\n * Written by Joe Keane <jgk@jgk.org>.\n */\n\n.section .text\n\n.align 4\n\n.global finite\n\n\nfinite:\n\tmovl\t8(%esp),%eax\n\tmovl    $0xFFEFFFFF,%ecx\n\tsubl    %eax,%ecx\n\txorl    %ecx,%eax\n\tshrl\t$31, %eax\n\tret\n\n"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/math/s_floor.S",
    "content": "/*\n * Written by J.T. Conklin <jtc@netbsd.org>.\n * Public domain.\n */\n\n.section .text\n\n.align 4\n\n.global floor\n\n\nfloor:\n\tfldl\t4(%esp)\n\tsubl\t$8,%esp\n\n\tfstcw\t4(%esp)\t\t\t/* store fpu control word */\n\n\t/* We use here %edx although only the low 1 bits are defined.\n\t   But none of the operations should care and they are faster\n\t   than the 16 bit operations.  */\n\tmovl\t$0x400,%edx\t\t/* round towards -oo */\n\torl\t4(%esp),%edx\n\tandl\t$0xf7ff,%edx\n\tmovl\t%edx,(%esp)\n\tfldcw\t(%esp)\t\t\t/* load modified control word */\n\n\tfrndint\t\t\t\t/* round */\n\n\tfldcw\t4(%esp)\t\t\t/* restore original control word */\n\n\taddl\t$8,%esp\n\tret\n\n"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/math/s_frexp.S",
    "content": "/* ix87 specific frexp implementation for double.\n   Copyright (C) 1997, 2000, 2005 Free Software Foundation, Inc.\n   This file is part of the GNU C Library.\n   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.\n\n   The GNU C Library is free software; you can redistribute it and/or\n   modify it under the terms of the GNU Lesser General Public\n   License as published by the Free Software Foundation; either\n   version 2.1 of the License, or (at your option) any later version.\n\n   The GNU C Library is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public\n   License along with the GNU C Library; if not, write to the Free\n   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA\n   02111-1307 USA.  */\n\n.section .rodata\n\n.align 4\n\ntwo54:\n.byte 0, 0, 0, 0, 0, 0, 0x50, 0x43\n\n\n#ifdef PIC\n#define MO(op) op##@GOTOFF(%edx)\n#else\n#define MO(op) op\n#endif\n\n#define PARMS\t4\n#define VAL0\tPARMS\n#define VAL1\tVAL0+4\n#define EXPP\tVAL1+4\n\n.section .text\n\n.align 4\n\n.global frexp\n\n\nfrexp:\n\tmovl\tVAL0(%esp), %ecx\n\tmovl\tVAL1(%esp), %eax\n\tmovl\t%eax, %edx\n\tandl\t$0x7fffffff, %eax\n\torl\t%eax, %ecx\n\tjz\t1f\n\txorl\t%ecx, %ecx\n\tcmpl\t$0x7ff00000, %eax\n\tjae\t1f\n\n\tcmpl\t$0x00100000, %eax\n\tjae\t2f\n\n\tfldl\tVAL0(%esp)\n#ifdef\tPIC\n\tLOAD_PIC_REG (dx)\n#endif\n\tfmull\tMO(two54)\n\tmovl\t$-54, %ecx\n\tfstpl\tVAL0(%esp)\n\tfwait\n\tmovl\tVAL1(%esp), %eax\n\tmovl\t%eax, %edx\n\tandl\t$0x7fffffff, %eax\n\n2:\tshrl\t$20, %eax\n\tandl\t$0x800fffff, %edx\n\tsubl\t$1022, %eax\n\torl\t$0x3fe00000, %edx\n\taddl\t%eax, %ecx\n\tmovl\t%edx, VAL1(%esp)\n\n\t/* Store %ecx in the variable pointed to by the second argument,\n\t   get the factor from the stack and return.  */\n1:\tmovl\tEXPP(%esp), %eax\n\tfldl\tVAL0(%esp)\n\tmovl\t%ecx, (%eax)\n\n\tret\n\n"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/math/s_scalbn.S",
    "content": "/*\n * Written by J.T. Conklin <jtc@netbsd.org>.\n * Public domain.\n */\n\n.section .text\n\n.align 4\n\n.global scalbn\n\n\nscalbn:\n\tfildl\t12(%esp)\n\tfldl\t4(%esp)\n\tfscale\n\tfstp\t%st(1)\n\tret\n\n"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/math/s_sin.S",
    "content": "/*\n * Written by J.T. Conklin <jtc@netbsd.org>.\n * Public domain.\n */\n\n.section .text\n\n.align 4\n\n.global sin\n\n\nsin:\n\tfldl\t4(%esp)\n\tfsin\n\tfnstsw\t%ax\n\ttestl\t$0x400,%eax\n\tjnz\t1f\n\tret\n\n.align 4\n\n1:\tfldpi\n\tfadd\t%st(0)\n\tfxch\t%st(1)\n2:\tfprem1\n\tfnstsw\t%ax\n\ttestl\t$0x400,%eax\n\tjnz\t2b\n\tfstp\t%st(1)\n\tfsin\n\tret\n\n"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/setjmp.S",
    "content": "/* setjmp function\n *\n * Copyright (c) 2009 Zoltan Kovacs\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of version 2 of the GNU General Public License\n * as published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n */\n\n.section .text\n\n.global setjmp\n\nsetjmp:\n    movl 4(%esp), %edx\n\n    /* Save return address */\n\n    movl 0(%esp), %ecx\n    movl %ecx, 0(%edx)\n\n    /* Save registers: ebp, esp, ebx, edi and esi */\n\n    movl %ebp, 4(%edx)\n    movl %esp, 8(%edx)\n    movl %ebx, 12(%edx)\n    movl %edi, 16(%edx)\n    movl %esi, 20(%edx)\n\n    /* Return 0 */\n\n    movl $0, %eax\n    ret\n\n"
  },
  {
    "path": "src/sdk/src/libc/src/closedir.c",
    "content": "\n \n\n#include <dirent.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <errno.h>\n\nint closedir( DIR* dir ) {\n    if ( dir == NULL ) {\n        errno = EBADF;\n        return -1;\n    }\n\n    close( dir->fd );\n    free( dir );\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/ctype/isalnum.c",
    "content": "\n \n\n#include <ctype.h>\n\nint isalnum( int c ) {\n    return ( ( isalpha( c ) ) || ( isdigit( c ) ) );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/ctype/isalpha.c",
    "content": "\n \n\n#include <ctype.h>\n\nint isalpha( int c ) {\n    return ( islower( c ) || isupper( c ) );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/ctype/isascii.c",
    "content": "\n \n\n#include <ctype.h>\n\nint isascii( int c ) {\n    return ( ( unsigned int )c < 128u );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/ctype/isblank.c",
    "content": "\n \n\n#include <ctype.h>\n\nint isblank( int c ) {\n    return ( c == ' ' || c == '\\t' );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/ctype/iscntrl.c",
    "content": "\n \n\n#include <ctype.h>\n\nint iscntrl( int c ) {\n    return ( ( ( unsigned int )c < 32u ) ||\n             ( c == 127 ) );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/ctype/isdigit.c",
    "content": "\n \n\n#include <ctype.h>\n\nint isdigit( int c ) {\n    return ( ( c >= '0' ) && ( c <= '9' ) );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/ctype/isgraph.c",
    "content": "\n \n\n#include <ctype.h>\n\nint isgraph( int c ) {\n    if ( c == ' ' ) {\n        return 0;\n    }\n\n    return isprint( c );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/ctype/islower.c",
    "content": "\n \n\n#include <ctype.h>\n\nint islower( int c ) {\n    return ( ( c >= 'a' ) && ( c <= 'z' ) );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/ctype/isprint.c",
    "content": "\n \n\n#include <ctype.h>\n\nint isprint( int c ) {\n    c &= 0x7F;\n    return ( ( c >= 0x20 ) && ( c < 0x7F ) );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/ctype/ispunct.c",
    "content": "\n \n\n#include <ctype.h>\n\nint ispunct( int c ) {\n    return ( isprint( c ) &&\n             !isalnum( c ) &&\n             !isspace( c ) );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/ctype/isspace.c",
    "content": "\n \n\n#include <ctype.h>\n\nint isspace( int c ) {\n    return ( c == '\\t' || c == '\\n' || c == '\\v' || c == '\\f' || c == '\\r' || c == ' ' );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/ctype/isupper.c",
    "content": "\n \n\n#include <ctype.h>\n\nint isupper( int c ) {\n    return ( ( c >= 'A' ) && ( c <= 'Z' ) );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/ctype/isxdigit.c",
    "content": "\n \n\n#include <ctype.h>\n\nint isxdigit( int c ) {\n    return ( ( ( c >= '0' ) && ( c <= '9' ) ) ||\n             ( ( c >= 'a' ) && ( c <= 'f' ) ) ||\n             ( ( c >= 'A' ) && ( c <= 'F' ) ) );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/ctype/toascii.c",
    "content": "\n \n\n#include <ctype.h>\n\nint toascii( int c ) {\n    return ( c & ~0x80 );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/ctype/tolower.c",
    "content": "\n \n\n#include <ctype.h>\n\nint tolower( int c ) {\n    if ( isupper( c ) ) {\n        return c | 0x20;\n    } else {\n        return c;\n    }\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/ctype/toupper.c",
    "content": "\n \n#include <ctype.h>\n\nint toupper( int c ) {\n    if ( islower( c ) ) {\n        return c & ~0x20;\n    } else {\n        return c;\n    }\n}\n\nldiv_t ldiv(long numerator, long denominator) {\n  ldiv_t x;\n  x.quot=numerator/denominator;\n  x.rem=numerator-x.quot*denominator;\n  return x;\n}\n\ndiv_t div(int numerator, int denominator) {\n  div_t x;\n  x.quot=numerator/denominator;\n  x.rem=numerator-x.quot*denominator;\n  return x;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/fcntl/creat.c",
    "content": "\n \n\n#include <fcntl.h>\n\nint creat( const char *pathname, mode_t mode ) {\n    return open( pathname, O_CREAT | O_WRONLY | O_TRUNC, mode );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/fcntl/fcntl.c",
    "content": "\n \n\n#include <errno.h>\n#include <fcntl.h>\n\n#include <os.h>\n\nint fcntl( int fd, int cmd, ... ) {\n    int error;\n\n    error = syscall3( SYS_fcntl, fd, cmd, *( ( ( int* )&cmd ) + 1 ) );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return error;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/fcntl/open.c",
    "content": "\n \n\n#include <fcntl.h>\n#include <errno.h>\n\n#include <os.h>\n\nint open( const char* filename, int flags, ... ) {\n    int error;\n\n    error = syscall2( SYS_open, ( int )filename, flags );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return error;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/getopt/getopt.c",
    "content": "\n \n#include <string.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <sys/types.h> /* NULL */\n\n#include <getopt.h>\n#include \"getopt_int.h\"\n\n# ifdef USE_NONOPTION_FLAGS\n#  define SWAP_FLAGS(ch1, ch2) \\\n  if (d->__nonoption_flags_len > 0)                       \\\n    {                                         \\\n      char __tmp = __getopt_nonoption_flags[ch1];                 \\\n      __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2];          \\\n      __getopt_nonoption_flags[ch2] = __tmp;                      \\\n    }\n# else\n#  define SWAP_FLAGS(ch1, ch2)\n# endif\n\n\nchar *optarg;\nint optind = 1;\nint opterr = 1;\nint optopt = '?';\n\nstatic struct _getopt_data getopt_data;\n\nstatic void\nexchange (char **argv, struct _getopt_data *d)\n{\n  int bottom = d->__first_nonopt;\n  int middle = d->__last_nonopt;\n  int top = d->optind;\n  char *tem;\n\n  /* Exchange the shorter segment with the far end of the longer segment.\n     That puts the shorter segment into the right place.\n     It leaves the longer segment in the right place overall,\n     but it consists of two parts that need to be swapped next.  */\n\n#if defined _LIBC && defined USE_NONOPTION_FLAGS\n  /* First make sure the handling of the `__getopt_nonoption_flags'\n     string can work normally.  Our top argument must be in the range\n     of the string.  */\n  if (d->__nonoption_flags_len > 0 && top >= d->__nonoption_flags_max_len)\n    {\n      /* We must extend the array.  The user plays games with us and\n\t presents new arguments.  */\n      char *new_str = malloc (top + 1);\n      if (new_str == NULL)\n\td->__nonoption_flags_len = d->__nonoption_flags_max_len = 0;\n      else\n\t{\n\t  memset (__mempcpy (new_str, __getopt_nonoption_flags,\n\t\t\t     d->__nonoption_flags_max_len),\n\t\t  '\\0', top + 1 - d->__nonoption_flags_max_len);\n\t  d->__nonoption_flags_max_len = top + 1;\n\t  __getopt_nonoption_flags = new_str;\n\t}\n    }\n#endif\n\n  while (top > middle && middle > bottom)\n    {\n      if (top - middle > middle - bottom)\n\t{\n\t  /* Bottom segment is the short one.  */\n\t  int len = middle - bottom;\n\t  register int i;\n\n\t  /* Swap it with the top part of the top segment.  */\n\t  for (i = 0; i < len; i++)\n\t    {\n\t      tem = argv[bottom + i];\n\t      argv[bottom + i] = argv[top - (middle - bottom) + i];\n\t      argv[top - (middle - bottom) + i] = tem;\n\t      SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);\n\t    }\n\t  /* Exclude the moved bottom segment from further swapping.  */\n\t  top -= len;\n\t}\n      else\n\t{\n\t  /* Top segment is the short one.  */\n\t  int len = top - middle;\n\t  register int i;\n\n\t  /* Swap it with the bottom part of the bottom segment.  */\n\t  for (i = 0; i < len; i++)\n\t    {\n\t      tem = argv[bottom + i];\n\t      argv[bottom + i] = argv[middle + i];\n\t      argv[middle + i] = tem;\n\t      SWAP_FLAGS (bottom + i, middle + i);\n\t    }\n\t  /* Exclude the moved top segment from further swapping.  */\n\t  bottom += len;\n\t}\n    }\n\n  /* Update records for the slots the non-options now occupy.  */\n\n  d->__first_nonopt += (d->optind - d->__last_nonopt);\n  d->__last_nonopt = d->optind;\n}\n\n/* Initialize the internal data when the first call is made.  */\n\nstatic const char *\n_getopt_initialize (int argc, char *const *argv, const char *optstring,\n\t\t    struct _getopt_data *d)\n{\n  /* Start processing options with ARGV-element 1 (since ARGV-element 0\n     is the program name); the sequence of previously skipped\n     non-option ARGV-elements is empty.  */\n\n  d->__first_nonopt = d->__last_nonopt = d->optind;\n\n  d->__nextchar = NULL;\n\n  d->__posixly_correct = !!getenv (\"POSIXLY_CORRECT\");\n\n  /* Determine how to handle the ordering of options and nonoptions.  */\n\n  if (optstring[0] == '-')\n    {\n      d->__ordering = RETURN_IN_ORDER;\n      ++optstring;\n    }\n  else if (optstring[0] == '+')\n    {\n      d->__ordering = REQUIRE_ORDER;\n      ++optstring;\n    }\n  else if (d->__posixly_correct)\n    d->__ordering = REQUIRE_ORDER;\n  else\n    d->__ordering = PERMUTE;\n\n#if defined _LIBC && defined USE_NONOPTION_FLAGS\n  if (!d->__posixly_correct\n      && argc == __libc_argc && argv == __libc_argv)\n    {\n      if (d->__nonoption_flags_max_len == 0)\n\t{\n\t  if (__getopt_nonoption_flags == NULL\n\t      || __getopt_nonoption_flags[0] == '\\0')\n\t    d->__nonoption_flags_max_len = -1;\n\t  else\n\t    {\n\t      const char *orig_str = __getopt_nonoption_flags;\n\t      int len = d->__nonoption_flags_max_len = strlen (orig_str);\n\t      if (d->__nonoption_flags_max_len < argc)\n\t\td->__nonoption_flags_max_len = argc;\n\t      __getopt_nonoption_flags =\n\t\t(char *) malloc (d->__nonoption_flags_max_len);\n\t      if (__getopt_nonoption_flags == NULL)\n\t\td->__nonoption_flags_max_len = -1;\n\t      else\n\t\tmemset (__mempcpy (__getopt_nonoption_flags, orig_str, len),\n\t\t\t'\\0', d->__nonoption_flags_max_len - len);\n\t    }\n\t}\n      d->__nonoption_flags_len = d->__nonoption_flags_max_len;\n    }\n  else\n    d->__nonoption_flags_len = 0;\n#endif\n\n  return optstring;\n}\n\f\n/* Scan elements of ARGV (whose length is ARGC) for option characters\n   given in OPTSTRING.\n\n   If an element of ARGV starts with '-', and is not exactly \"-\" or \"--\",\n   then it is an option element.  The characters of this element\n   (aside from the initial '-') are option characters.  If `getopt'\n   is called repeatedly, it returns successively each of the option characters\n   from each of the option elements.\n\n   If `getopt' finds another option character, it returns that character,\n   updating `optind' and `nextchar' so that the next call to `getopt' can\n   resume the scan with the following option character or ARGV-element.\n\n   If there are no more option characters, `getopt' returns -1.\n   Then `optind' is the index in ARGV of the first ARGV-element\n   that is not an option.  (The ARGV-elements have been permuted\n   so that those that are not options now come last.)\n\n   OPTSTRING is a string containing the legitimate option characters.\n   If an option character is seen that is not listed in OPTSTRING,\n   return '?' after printing an error message.  If you set `opterr' to\n   zero, the error message is suppressed but we still return '?'.\n\n   If a char in OPTSTRING is followed by a colon, that means it wants an arg,\n   so the following text in the same ARGV-element, or the text of the following\n   ARGV-element, is returned in `optarg'.  Two colons mean an option that\n   wants an optional arg; if there is text in the current ARGV-element,\n   it is returned in `optarg', otherwise `optarg' is set to zero.\n\n   If OPTSTRING starts with `-' or `+', it requests different methods of\n   handling the non-option ARGV-elements.\n   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.\n\n   Long-named options begin with `--' instead of `-'.\n   Their names may be abbreviated as long as the abbreviation is unique\n   or is an exact match for some defined option.  If they have an\n   argument, it follows the option name in the same ARGV-element, separated\n   from the option name by a `=', or else the in next ARGV-element.\n   When `getopt' finds a long-named option, it returns 0 if that option's\n   `flag' field is nonzero, the value of the option's `val' field\n   if the `flag' field is zero.\n\n   The elements of ARGV aren't really const, because we permute them.\n   But we pretend they're const in the prototype to be compatible\n   with other systems.\n\n   LONGOPTS is a vector of `struct option' terminated by an\n   element containing a name which is zero.\n\n   LONGIND returns the index in LONGOPT of the long-named option found.\n   It is only valid when a long-named option has been found by the most\n   recent call.\n\n   If LONG_ONLY is nonzero, '-' as well as '--' can introduce\n   long-named options.  */\n\nint\n_getopt_internal_r (int argc, char *const *argv, const char *optstring,\n\t\t    const struct option *longopts, int *longind,\n\t\t    int long_only, struct _getopt_data *d)\n{\n  int print_errors = d->opterr;\n  if (optstring[0] == ':')\n    print_errors = 0;\n\n  if (argc < 1)\n    return -1;\n\n  d->optarg = NULL;\n\n  if (d->optind == 0 || !d->__initialized)\n    {\n      if (d->optind == 0)\n\td->optind = 1;\t/* Don't scan ARGV[0], the program name.  */\n      optstring = _getopt_initialize (argc, argv, optstring, d);\n      d->__initialized = 1;\n    }\n\n  /* Test whether ARGV[optind] points to a non-option argument.\n     Either it does not have option syntax, or there is an environment flag\n     from the shell indicating it is not an option.  The later information\n     is only used when the used in the GNU libc.  */\n#if defined _LIBC && defined USE_NONOPTION_FLAGS\n# define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\\0' \\\n\t\t      || (d->optind < d->__nonoption_flags_len\t\t      \\\n\t\t\t  && __getopt_nonoption_flags[d->optind] == '1'))\n#else\n# define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\\0')\n#endif\n\n  if (d->__nextchar == NULL || *d->__nextchar == '\\0')\n    {\n      /* Advance to the next ARGV-element.  */\n\n      /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been\n\t moved back by the user (who may also have changed the arguments).  */\n      if (d->__last_nonopt > d->optind)\n\td->__last_nonopt = d->optind;\n      if (d->__first_nonopt > d->optind)\n\td->__first_nonopt = d->optind;\n\n      if (d->__ordering == PERMUTE)\n\t{\n\t  /* If we have just processed some options following some non-options,\n\t     exchange them so that the options come first.  */\n\n\t  if (d->__first_nonopt != d->__last_nonopt\n\t      && d->__last_nonopt != d->optind)\n\t    exchange ((char **) argv, d);\n\t  else if (d->__last_nonopt != d->optind)\n\t    d->__first_nonopt = d->optind;\n\n\t  /* Skip any additional non-options\n\t     and extend the range of non-options previously skipped.  */\n\n\t  while (d->optind < argc && NONOPTION_P)\n\t    d->optind++;\n\t  d->__last_nonopt = d->optind;\n\t}\n\n      /* The special ARGV-element `--' means premature end of options.\n\t Skip it like a null option,\n\t then exchange with previous non-options as if it were an option,\n\t then skip everything else like a non-option.  */\n\n      if (d->optind != argc && !strcmp (argv[d->optind], \"--\"))\n\t{\n\t  d->optind++;\n\n\t  if (d->__first_nonopt != d->__last_nonopt\n\t      && d->__last_nonopt != d->optind)\n\t    exchange ((char **) argv, d);\n\t  else if (d->__first_nonopt == d->__last_nonopt)\n\t    d->__first_nonopt = d->optind;\n\t  d->__last_nonopt = argc;\n\n\t  d->optind = argc;\n\t}\n\n      /* If we have done all the ARGV-elements, stop the scan\n\t and back over any non-options that we skipped and permuted.  */\n\n      if (d->optind == argc)\n\t{\n\t  /* Set the next-arg-index to point at the non-options\n\t     that we previously skipped, so the caller will digest them.  */\n\t  if (d->__first_nonopt != d->__last_nonopt)\n\t    d->optind = d->__first_nonopt;\n\t  return -1;\n\t}\n\n      /* If we have come to a non-option and did not permute it,\n\t either stop the scan or describe it to the caller and pass it by.  */\n\n      if (NONOPTION_P)\n\t{\n\t  if (d->__ordering == REQUIRE_ORDER)\n\t    return -1;\n\t  d->optarg = argv[d->optind++];\n\t  return 1;\n\t}\n\n      /* We have found another option-ARGV-element.\n\t Skip the initial punctuation.  */\n\n      d->__nextchar = (argv[d->optind] + 1\n\t\t  + (longopts != NULL && argv[d->optind][1] == '-'));\n    }\n\n  /* Decode the current option-ARGV-element.  */\n\n  /* Check whether the ARGV-element is a long option.\n\n     If long_only and the ARGV-element has the form \"-f\", where f is\n     a valid short option, don't consider it an abbreviated form of\n     a long option that starts with f.  Otherwise there would be no\n     way to give the -f short option.\n\n     On the other hand, if there's a long option \"fubar\" and\n     the ARGV-element is \"-fu\", do consider that an abbreviation of\n     the long option, just like \"--fu\", and not \"-f\" with arg \"u\".\n\n     This distinction seems to be the most useful approach.  */\n\n  if (longopts != NULL\n      && (argv[d->optind][1] == '-'\n\t  || (long_only && (argv[d->optind][2]\n\t\t\t    || !strchr (optstring, argv[d->optind][1])))))\n    {\n      char *nameend;\n      const struct option *p;\n      const struct option *pfound = NULL;\n      int exact = 0;\n      int ambig = 0;\n      int indfound = -1;\n      int option_index;\n\n      for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++)\n\t/* Do nothing.  */ ;\n\n      /* Test all long options for either exact match\n\t or abbreviated matches.  */\n      for (p = longopts, option_index = 0; p->name; p++, option_index++)\n\tif (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar))\n\t  {\n\t    if ((unsigned int) (nameend - d->__nextchar)\n\t\t== (unsigned int) strlen (p->name))\n\t      {\n\t\t/* Exact match found.  */\n\t\tpfound = p;\n\t\tindfound = option_index;\n\t\texact = 1;\n\t\tbreak;\n\t      }\n\t    else if (pfound == NULL)\n\t      {\n\t\t/* First nonexact match found.  */\n\t\tpfound = p;\n\t\tindfound = option_index;\n\t      }\n\t    else if (long_only\n\t\t     || pfound->has_arg != p->has_arg\n\t\t     || pfound->flag != p->flag\n\t\t     || pfound->val != p->val)\n\t      /* Second or later nonexact match found.  */\n\t      ambig = 1;\n\t  }\n\n      if (ambig && !exact)\n\t{\n\t  if (print_errors)\n\t    {\n#if defined _LIBC && defined USE_IN_LIBIO\n\t      char *buf;\n\n\t      if (__asprintf (&buf, \"%s: option '%s' is ambiguous\\n\",\n\t\t\t      argv[0], argv[d->optind]) >= 0)\n\t\t{\n\t\t  _IO_flockfile (stderr);\n\n\t\t  int old_flags2 = ((_IO_FILE *) stderr)->_flags2;\n\t\t  ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;\n\n\t\t  __fxprintf (NULL, \"%s\", buf);\n\n\t\t  ((_IO_FILE *) stderr)->_flags2 = old_flags2;\n\t\t  _IO_funlockfile (stderr);\n\n\t\t  free (buf);\n\t\t}\n#else\n\t      fprintf (stderr, \"%s: option '%s' is ambiguous\\n\",\n\t\t       argv[0], argv[d->optind]);\n#endif\n\t    }\n\t  d->__nextchar += strlen (d->__nextchar);\n\t  d->optind++;\n\t  d->optopt = 0;\n\t  return '?';\n\t}\n\n      if (pfound != NULL)\n\t{\n\t  option_index = indfound;\n\t  d->optind++;\n\t  if (*nameend)\n\t    {\n\t      /* Don't test has_arg with >, because some C compilers don't\n\t\t allow it to be used on enums.  */\n\t      if (pfound->has_arg)\n\t\td->optarg = nameend + 1;\n\t      else\n\t\t{\n\t\t  if (print_errors)\n\t\t    {\n#if defined _LIBC && defined USE_IN_LIBIO\n\t\t      char *buf;\n\t\t      int n;\n#endif\n\n\t\t      if (argv[d->optind - 1][1] == '-')\n\t\t\t{\n\t\t\t  /* --option */\n#if defined _LIBC && defined USE_IN_LIBIO\n\t\t\t  n = __asprintf (&buf, \"\\\n%s: option '--%s' doesn't allow an argument\\n\",\n\t\t\t\t\t  argv[0], pfound->name);\n#else\n\t\t\t  fprintf (stderr, \"\\\n%s: option '--%s' doesn't allow an argument\\n\",\n\t\t\t\t   argv[0], pfound->name);\n#endif\n\t\t\t}\n\t\t      else\n\t\t\t{\n\t\t\t  /* +option or -option */\n#if defined _LIBC && defined USE_IN_LIBIO\n\t\t\t  n = __asprintf (&buf, \"\\\n%s: option '%c%s' doesn't allow an argument\\n\",\n\t\t\t\t\t  argv[0], argv[d->optind - 1][0],\n\t\t\t\t\t  pfound->name);\n#else\n\t\t\t  fprintf (stderr, \"\\\n%s: option '%c%s' doesn't allow an argument\\n\",\n\t\t\t\t   argv[0], argv[d->optind - 1][0],\n\t\t\t\t   pfound->name);\n#endif\n\t\t\t}\n\n#if defined _LIBC && defined USE_IN_LIBIO\n\t\t      if (n >= 0)\n\t\t\t{\n\t\t\t  _IO_flockfile (stderr);\n\n\t\t\t  int old_flags2 = ((_IO_FILE *) stderr)->_flags2;\n\t\t\t  ((_IO_FILE *) stderr)->_flags2\n\t\t\t    |= _IO_FLAGS2_NOTCANCEL;\n\n\t\t\t  __fxprintf (NULL, \"%s\", buf);\n\n\t\t\t  ((_IO_FILE *) stderr)->_flags2 = old_flags2;\n\t\t\t  _IO_funlockfile (stderr);\n\n\t\t\t  free (buf);\n\t\t\t}\n#endif\n\t\t    }\n\n\t\t  d->__nextchar += strlen (d->__nextchar);\n\n\t\t  d->optopt = pfound->val;\n\t\t  return '?';\n\t\t}\n\t    }\n\t  else if (pfound->has_arg == 1)\n\t    {\n\t      if (d->optind < argc)\n\t\td->optarg = argv[d->optind++];\n\t      else\n\t\t{\n\t\t  if (print_errors)\n\t\t    {\n#if defined _LIBC && defined USE_IN_LIBIO\n\t\t      char *buf;\n\n\t\t      if (__asprintf (&buf, \"\\\n%s: option '%s' requires an argument\\n\",\n\t\t\t\t      argv[0], argv[d->optind - 1]) >= 0)\n\t\t\t{\n\t\t\t  _IO_flockfile (stderr);\n\n\t\t\t  int old_flags2 = ((_IO_FILE *) stderr)->_flags2;\n\t\t\t  ((_IO_FILE *) stderr)->_flags2\n\t\t\t    |= _IO_FLAGS2_NOTCANCEL;\n\n\t\t\t  __fxprintf (NULL, \"%s\", buf);\n\n\t\t\t  ((_IO_FILE *) stderr)->_flags2 = old_flags2;\n\t\t\t  _IO_funlockfile (stderr);\n\n\t\t\t  free (buf);\n\t\t\t}\n#else\n\t\t      fprintf (stderr,\n\t\t\t       \"%s: option '%s' requires an argument\\n\",\n\t\t\t       argv[0], argv[d->optind - 1]);\n#endif\n\t\t    }\n\t\t  d->__nextchar += strlen (d->__nextchar);\n\t\t  d->optopt = pfound->val;\n\t\t  return optstring[0] == ':' ? ':' : '?';\n\t\t}\n\t    }\n\t  d->__nextchar += strlen (d->__nextchar);\n\t  if (longind != NULL)\n\t    *longind = option_index;\n\t  if (pfound->flag)\n\t    {\n\t      *(pfound->flag) = pfound->val;\n\t      return 0;\n\t    }\n\t  return pfound->val;\n\t}\n\n      /* Can't find it as a long option.  If this is not getopt_long_only,\n\t or the option starts with '--' or is not a valid short\n\t option, then it's an error.\n\t Otherwise interpret it as a short option.  */\n      if (!long_only || argv[d->optind][1] == '-'\n\t  || strchr (optstring, *d->__nextchar) == NULL)\n\t{\n\t  if (print_errors)\n\t    {\n#if defined _LIBC && defined USE_IN_LIBIO\n\t      char *buf;\n\t      int n;\n#endif\n\n\t      if (argv[d->optind][1] == '-')\n\t\t{\n\t\t  /* --option */\n#if defined _LIBC && defined USE_IN_LIBIO\n\t\t  n = __asprintf (&buf, \"%s: unrecognized option '--%s'\\n\",\n\t\t\t\t  argv[0], d->__nextchar);\n#else\n\t\t  fprintf (stderr, \"%s: unrecognized option '--%s'\\n\",\n\t\t\t   argv[0], d->__nextchar);\n#endif\n\t\t}\n\t      else\n\t\t{\n\t\t  /* +option or -option */\n#if defined _LIBC && defined USE_IN_LIBIO\n\t\t  n = __asprintf (&buf, \"%s: unrecognized option '%c%s'\\n\",\n\t\t\t\t  argv[0], argv[d->optind][0], d->__nextchar);\n#else\n\t\t  fprintf (stderr, \"%s: unrecognized option '%c%s'\\n\",\n\t\t\t   argv[0], argv[d->optind][0], d->__nextchar);\n#endif\n\t\t}\n\n#if defined _LIBC && defined USE_IN_LIBIO\n\t      if (n >= 0)\n\t\t{\n\t\t  _IO_flockfile (stderr);\n\n\t\t  int old_flags2 = ((_IO_FILE *) stderr)->_flags2;\n\t\t  ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;\n\n\t\t  __fxprintf (NULL, \"%s\", buf);\n\n\t\t  ((_IO_FILE *) stderr)->_flags2 = old_flags2;\n\t\t  _IO_funlockfile (stderr);\n\n\t\t  free (buf);\n\t\t}\n#endif\n\t    }\n\t  d->__nextchar = (char *) \"\";\n\t  d->optind++;\n\t  d->optopt = 0;\n\t  return '?';\n\t}\n    }\n\n  /* Look at and handle the next short option-character.  */\n\n  {\n    char c = *d->__nextchar++;\n    char *temp = strchr (optstring, c);\n\n    /* Increment `optind' when we start to process its last character.  */\n    if (*d->__nextchar == '\\0')\n      ++d->optind;\n\n    if (temp == NULL || c == ':')\n      {\n\tif (print_errors)\n\t  {\n#if defined _LIBC && defined USE_IN_LIBIO\n\t    char *buf;\n\t    int n;\n#endif\n\n#if defined _LIBC && defined USE_IN_LIBIO\n\t    n = __asprintf (&buf, \"%s: invalid option -- '%c'\\n\",\n\t\t\t    argv[0], c);\n#else\n\t    fprintf (stderr, \"%s: invalid option -- '%c'\\n\", argv[0], c);\n#endif\n\n#if defined _LIBC && defined USE_IN_LIBIO\n\t    if (n >= 0)\n\t      {\n\t\t_IO_flockfile (stderr);\n\n\t\tint old_flags2 = ((_IO_FILE *) stderr)->_flags2;\n\t\t((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;\n\n\t\t__fxprintf (NULL, \"%s\", buf);\n\n\t\t((_IO_FILE *) stderr)->_flags2 = old_flags2;\n\t\t_IO_funlockfile (stderr);\n\n\t\tfree (buf);\n\t      }\n#endif\n\t  }\n\td->optopt = c;\n\treturn '?';\n      }\n    /* Convenience. Treat POSIX -W foo same as long option --foo */\n    if (temp[0] == 'W' && temp[1] == ';')\n      {\n\tchar *nameend;\n\tconst struct option *p;\n\tconst struct option *pfound = NULL;\n\tint exact = 0;\n\tint ambig = 0;\n\tint indfound = 0;\n\tint option_index;\n\n\t/* This is an option that requires an argument.  */\n\tif (*d->__nextchar != '\\0')\n\t  {\n\t    d->optarg = d->__nextchar;\n\t    /* If we end this ARGV-element by taking the rest as an arg,\n\t       we must advance to the next element now.  */\n\t    d->optind++;\n\t  }\n\telse if (d->optind == argc)\n\t  {\n\t    if (print_errors)\n\t      {\n#if defined _LIBC && defined USE_IN_LIBIO\n\t\tchar *buf;\n\n\t\tif (__asprintf (&buf,\n\t\t\t\t\"%s: option requires an argument -- '%c'\\n\",\n\t\t\t\targv[0], c) >= 0)\n\t\t  {\n\t\t    _IO_flockfile (stderr);\n\n\t\t    int old_flags2 = ((_IO_FILE *) stderr)->_flags2;\n\t\t    ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;\n\n\t\t    __fxprintf (NULL, \"%s\", buf);\n\n\t\t    ((_IO_FILE *) stderr)->_flags2 = old_flags2;\n\t\t    _IO_funlockfile (stderr);\n\n\t\t    free (buf);\n\t\t  }\n#else\n\t\tfprintf (stderr,\n\t\t\t \"%s: option requires an argument -- '%c'\\n\",\n\t\t\t argv[0], c);\n#endif\n\t      }\n\t    d->optopt = c;\n\t    if (optstring[0] == ':')\n\t      c = ':';\n\t    else\n\t      c = '?';\n\t    return c;\n\t  }\n\telse\n\t  /* We already incremented `d->optind' once;\n\t     increment it again when taking next ARGV-elt as argument.  */\n\t  d->optarg = argv[d->optind++];\n\n\t/* optarg is now the argument, see if it's in the\n\t   table of longopts.  */\n\n\tfor (d->__nextchar = nameend = d->optarg; *nameend && *nameend != '=';\n\t     nameend++)\n\t  /* Do nothing.  */ ;\n\n\t/* Test all long options for either exact match\n\t   or abbreviated matches.  */\n\tfor (p = longopts, option_index = 0; p->name; p++, option_index++)\n\t  if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar))\n\t    {\n\t      if ((unsigned int) (nameend - d->__nextchar) == strlen (p->name))\n\t\t{\n\t\t  /* Exact match found.  */\n\t\t  pfound = p;\n\t\t  indfound = option_index;\n\t\t  exact = 1;\n\t\t  break;\n\t\t}\n\t      else if (pfound == NULL)\n\t\t{\n\t\t  /* First nonexact match found.  */\n\t\t  pfound = p;\n\t\t  indfound = option_index;\n\t\t}\n\t      else\n\t\t/* Second or later nonexact match found.  */\n\t\tambig = 1;\n\t    }\n\tif (ambig && !exact)\n\t  {\n\t    if (print_errors)\n\t      {\n#if defined _LIBC && defined USE_IN_LIBIO\n\t\tchar *buf;\n\n\t\tif (__asprintf (&buf, \"%s: option '-W %s' is ambiguous\\n\",\n\t\t\t\targv[0], argv[d->optind]) >= 0)\n\t\t  {\n\t\t    _IO_flockfile (stderr);\n\n\t\t    int old_flags2 = ((_IO_FILE *) stderr)->_flags2;\n\t\t    ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;\n\n\t\t    __fxprintf (NULL, \"%s\", buf);\n\n\t\t    ((_IO_FILE *) stderr)->_flags2 = old_flags2;\n\t\t    _IO_funlockfile (stderr);\n\n\t\t    free (buf);\n\t\t  }\n#else\n\t\tfprintf (stderr, \"%s: option '-W %s' is ambiguous\\n\",\n\t\t\t argv[0], argv[d->optind]);\n#endif\n\t      }\n\t    d->__nextchar += strlen (d->__nextchar);\n\t    d->optind++;\n\t    return '?';\n\t  }\n\tif (pfound != NULL)\n\t  {\n\t    option_index = indfound;\n\t    if (*nameend)\n\t      {\n\t\t/* Don't test has_arg with >, because some C compilers don't\n\t\t   allow it to be used on enums.  */\n\t\tif (pfound->has_arg)\n\t\t  d->optarg = nameend + 1;\n\t\telse\n\t\t  {\n\t\t    if (print_errors)\n\t\t      {\n#if defined _LIBC && defined USE_IN_LIBIO\n\t\t\tchar *buf;\n\n\t\t\tif (__asprintf (&buf, \"\\\n%s: option '-W %s' doesn't allow an argument\\n\",\n\t\t\t\t\targv[0], pfound->name) >= 0)\n\t\t\t  {\n\t\t\t    _IO_flockfile (stderr);\n\n\t\t\t    int old_flags2 = ((_IO_FILE *) stderr)->_flags2;\n\t\t\t    ((_IO_FILE *) stderr)->_flags2\n\t\t\t      |= _IO_FLAGS2_NOTCANCEL;\n\n\t\t\t    __fxprintf (NULL, \"%s\", buf);\n\n\t\t\t    ((_IO_FILE *) stderr)->_flags2 = old_flags2;\n\t\t\t    _IO_funlockfile (stderr);\n\n\t\t\t    free (buf);\n\t\t\t  }\n#else\n\t\t\tfprintf (stderr, \"\\\n%s: option '-W %s' doesn't allow an argument\\n\",\n\t\t\t\t argv[0], pfound->name);\n#endif\n\t\t      }\n\n\t\t    d->__nextchar += strlen (d->__nextchar);\n\t\t    return '?';\n\t\t  }\n\t      }\n\t    else if (pfound->has_arg == 1)\n\t      {\n\t\tif (d->optind < argc)\n\t\t  d->optarg = argv[d->optind++];\n\t\telse\n\t\t  {\n\t\t    if (print_errors)\n\t\t      {\n#if defined _LIBC && defined USE_IN_LIBIO\n\t\t\tchar *buf;\n\n\t\t\tif (__asprintf (&buf, \"\\\n%s: option '%s' requires an argument\\n\",\n\t\t\t\t\targv[0], argv[d->optind - 1]) >= 0)\n\t\t\t  {\n\t\t\t    _IO_flockfile (stderr);\n\n\t\t\t    int old_flags2 = ((_IO_FILE *) stderr)->_flags2;\n\t\t\t    ((_IO_FILE *) stderr)->_flags2\n\t\t\t      |= _IO_FLAGS2_NOTCANCEL;\n\n\t\t\t    __fxprintf (NULL, \"%s\", buf);\n\n\t\t\t    ((_IO_FILE *) stderr)->_flags2 = old_flags2;\n\t\t\t    _IO_funlockfile (stderr);\n\n\t\t\t    free (buf);\n\t\t\t  }\n#else\n\t\t\tfprintf (stderr,\n\t\t\t\t \"%s: option '%s' requires an argument\\n\",\n\t\t\t\t argv[0], argv[d->optind - 1]);\n#endif\n\t\t      }\n\t\t    d->__nextchar += strlen (d->__nextchar);\n\t\t    return optstring[0] == ':' ? ':' : '?';\n\t\t  }\n\t      }\n\t    d->__nextchar += strlen (d->__nextchar);\n\t    if (longind != NULL)\n\t      *longind = option_index;\n\t    if (pfound->flag)\n\t      {\n\t\t*(pfound->flag) = pfound->val;\n\t\treturn 0;\n\t      }\n\t    return pfound->val;\n\t  }\n\t  d->__nextchar = NULL;\n\t  return 'W';\t/* Let the application handle it.   */\n      }\n    if (temp[1] == ':')\n      {\n\tif (temp[2] == ':')\n\t  {\n\t    /* This is an option that accepts an argument optionally.  */\n\t    if (*d->__nextchar != '\\0')\n\t      {\n\t\td->optarg = d->__nextchar;\n\t\td->optind++;\n\t      }\n\t    else\n\t      d->optarg = NULL;\n\t    d->__nextchar = NULL;\n\t  }\n\telse\n\t  {\n\t    /* This is an option that requires an argument.  */\n\t    if (*d->__nextchar != '\\0')\n\t      {\n\t\td->optarg = d->__nextchar;\n\t\t/* If we end this ARGV-element by taking the rest as an arg,\n\t\t   we must advance to the next element now.  */\n\t\td->optind++;\n\t      }\n\t    else if (d->optind == argc)\n\t      {\n\t\tif (print_errors)\n\t\t  {\n#if defined _LIBC && defined USE_IN_LIBIO\n\t\t    char *buf;\n\n\t\t    if (__asprintf (&buf, \"\\\n%s: option requires an argument -- '%c'\\n\",\n\t\t\t\t    argv[0], c) >= 0)\n\t\t      {\n\t\t\t_IO_flockfile (stderr);\n\n\t\t\tint old_flags2 = ((_IO_FILE *) stderr)->_flags2;\n\t\t\t((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;\n\n\t\t\t__fxprintf (NULL, \"%s\", buf);\n\n\t\t\t((_IO_FILE *) stderr)->_flags2 = old_flags2;\n\t\t\t_IO_funlockfile (stderr);\n\n\t\t\tfree (buf);\n\t\t      }\n#else\n\t\t    fprintf (stderr,\n\t\t\t     \"%s: option requires an argument -- '%c'\\n\",\n\t\t\t     argv[0], c);\n#endif\n\t\t  }\n\t\td->optopt = c;\n\t\tif (optstring[0] == ':')\n\t\t  c = ':';\n\t\telse\n\t\t  c = '?';\n\t      }\n\t    else\n\t      /* We already incremented `optind' once;\n\t\t increment it again when taking next ARGV-elt as argument.  */\n\t      d->optarg = argv[d->optind++];\n\t    d->__nextchar = NULL;\n\t  }\n      }\n    return c;\n  }\n}\n\n\nint _getopt_internal ( int argc, char *const *argv, const char *optstring,\n          const struct option *longopts, int *longind, int long_only ) {\n    int result;\n\n    getopt_data.optind = optind;\n    getopt_data.opterr = opterr;\n\n    result = _getopt_internal_r (argc, argv, optstring, longopts,\n                longind, long_only, &getopt_data);\n\n    optind = getopt_data.optind;\n    optarg = getopt_data.optarg;\n    optopt = getopt_data.optopt;\n\n    return result;\n}\n\nint getopt( int argc, char* const * argv, const char* optstring ) {\n    return _getopt_internal( argc,\n               argv,\n               optstring,\n               (const struct option *) 0,\n               (int *) 0,\n               0 );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/getopt/getopt_int.h",
    "content": "\n \n#ifndef _GETOPT_INT_H_\n#define _GETOPT_INT_H_\n\nstruct _getopt_data\n{\n  int optind;\n  int opterr;\n  int optopt;\n  char *optarg;\n\n  int __initialized;\n\n  char *__nextchar;\n  enum\n    {\n      REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER\n    } __ordering;\n\n  int __posixly_correct;\n\n  int __first_nonopt;\n  int __last_nonopt;\n\n  int __nonoption_flags_max_len;\n  int __nonoption_flags_len;\n};\n\n#define _GETOPT_DATA_INITIALIZER        { 1, 1 }\n\nextern int _getopt_internal (int ___argc, char *const *___argv,\n                 const char *__shortopts,\n                     const struct option *__longopts, int *__longind,\n                 int __long_only);\n\nextern int _getopt_internal_r (int ___argc, char *const *___argv,\n                               const char *__shortopts,\n                               const struct option *__longopts, int *__longind,\n                               int __long_only, struct _getopt_data *__data);\n\nextern int _getopt_long_r (int ___argc, char *const *___argv,\n                           const char *__shortopts,\n                           const struct option *__longopts, int *__longind,\n                           struct _getopt_data *__data);\n\nextern int _getopt_long_only_r (int ___argc, char *const *___argv,\n                                const char *__shortopts,\n                                const struct option *__longopts,\n                                int *__longind,\n                                struct _getopt_data *__data);\n#endif\n"
  },
  {
    "path": "src/sdk/src/libc/src/getopt/getopt_long.c",
    "content": "\n \n#include <string.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <sys/types.h> /* NULL */\n\n#include <getopt.h>\n#include \"getopt_int.h\"\n\nint getopt_long( int argc, char* const * argv, const char* shortopts,\n                 const struct option* longopts, int* longind ){\n    return _getopt_internal (argc, argv, shortopts, longopts, longind, 0);\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/getopt/getopt_long_only.c",
    "content": "\n \n#include <string.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <sys/types.h> /* NULL */\n\n#include <getopt.h>\n#include \"getopt_int.h\"\n\nint getopt_long_only( int argc, char* const * argv,\n    const char* shortopts, const struct option* longopts, int* longind ){\n    return _getopt_internal (argc, argv, shortopts, longopts, longind, 1);\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/locale/localeconv.c",
    "content": "\n \n\n#include <locale.h>\n#include <limits.h>\n\nstatic const struct lconv _locale = {\n    .decimal_point = \".\",\n    .thousands_sep = \"\",\n    .grouping = \"\",\n    .int_curr_symbol = \"\",\n    .currency_symbol = \"\",\n    .mon_decimal_point = \".\",\n    .mon_thousands_sep = \"\",\n    .mon_grouping = \"\",\n    .positive_sign = \"+\",\n    .negative_sign = \"-\",\n    .int_frac_digits = CHAR_MAX,\n    .frac_digits = CHAR_MAX,\n    .p_cs_precedes = CHAR_MAX,\n    .p_sep_by_space = CHAR_MAX,\n    .n_cs_precedes = CHAR_MAX,\n    .n_sep_by_space = CHAR_MAX,\n    .p_sign_posn = CHAR_MAX,\n    .n_sign_posn = CHAR_MAX,\n    .int_p_cs_precedes = CHAR_MAX,\n    .int_p_sep_by_space = CHAR_MAX,\n    .int_n_cs_precedes = CHAR_MAX,\n    .int_n_sep_by_space = CHAR_MAX,\n    .int_p_sign_posn = CHAR_MAX,\n    .int_n_sign_posn = CHAR_MAX\n};\n\nstruct lconv* localeconv( void ) {\n    return ( struct lconv* ) &_locale;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/locale/setlocale.c",
    "content": "\n \n\n#include <locale.h>\n#include <stdlib.h>\n\nchar* setlocale( int category, const char* locale ) {\n    /* TODO */\n\n    return NULL;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/math/s_ldexp.c",
    "content": "\n \n\n#include <math.h>\n#include <errno.h>\n\ndouble ldexp( double value, int exp ) {\n    if ( !finite(value) || value == 0.0 ) return value;\n    value = scalbn(value,exp);\n    if ( !finite(value) || value == 0.0 ) errno = ERANGE;\n    return value;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/math/s_modf.c",
    "content": "\n \n\n/*\n * modf(double x, double *iptr)\n * return fraction part of x, and return x's integral part in *iptr.\n * Method:\n *\tBit twiddling.\n *\n * Exception:\n *\tNo exception.\n */\n\n#include <math.h>\n#include <sys/types.h>\n\n#define EXTRACT_WORDS(ix0,ix1,d)        \\\ndo {                \\\n  ieee_double_shape_type ew_u;          \\\n  ew_u.value = (d);           \\\n  (ix0) = ew_u.parts.msw;         \\\n  (ix1) = ew_u.parts.lsw;         \\\n} while (0)\n\n#define INSERT_WORDS(d,ix0,ix1)         \\\ndo {                \\\n  ieee_double_shape_type iw_u;          \\\n  iw_u.parts.msw = (ix0);         \\\n  iw_u.parts.lsw = (ix1);         \\\n  (d) = iw_u.value;           \\\n} while (0)\n\ntypedef union\n{\n  double value;\n  struct\n  {\n    uint32_t lsw;\n    uint32_t msw;\n  } parts;\n} ieee_double_shape_type;\n\nstatic const double one = 1.0;\n\ndouble modf(double x, double *iptr) {\n\tint32_t i0,i1,j0;\n\tuint32_t i;\n\tEXTRACT_WORDS(i0,i1,x);\n\tj0 = ((i0>>20)&0x7ff)-0x3ff;\t/* exponent of x */\n\tif(j0<20) {\t\t\t/* integer part in high x */\n\t    if(j0<0) {\t\t\t/* |x|<1 */\n\t        INSERT_WORDS(*iptr,i0&0x80000000,0);\t/* *iptr = +-0 */\n\t\treturn x;\n\t    } else {\n\t\ti = (0x000fffff)>>j0;\n\t\tif(((i0&i)|i1)==0) {\t\t/* x is integral */\n\t\t    *iptr = x;\n\t\t    INSERT_WORDS(x,i0&0x80000000,0);\t/* return +-0 */\n\t\t    return x;\n\t\t} else {\n\t\t    INSERT_WORDS(*iptr,i0&(~i),0);\n\t\t    return x - *iptr;\n\t\t}\n\t    }\n\t} else if (j0>51) {\t\t/* no fraction part */\n\t    *iptr = x*one;\n\t    /* We must handle NaNs separately.  */\n\t    if (j0 == 0x400 && ((i0 & 0xfffff) | i1))\n\t      return x*one;\n\t    INSERT_WORDS(x,i0&0x80000000,0);\t/* return +-0 */\n\t    return x;\n\t} else {\t\t\t/* fraction part in low x */\n\t    i = ((uint32_t)(0xffffffff))>>(j0-20);\n\t    if((i1&i)==0) { \t\t/* x is integral */\n\t\t*iptr = x;\n\t\tINSERT_WORDS(x,i0&0x80000000,0);\t/* return +-0 */\n\t\treturn x;\n\t    } else {\n\t        INSERT_WORDS(*iptr,i0,i1&(~i));\n\t\treturn x - *iptr;\n\t    }\n\t}\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/network/inet_aton.c",
    "content": "\n \n\n#include <stdlib.h>\n#include <netinet/in.h>\n#include <arpa/inet.h>\n\nint inet_aton( const char* cp, struct in_addr* inp ) {\n    int i;\n    unsigned int ip = 0;\n    char* tmp= ( char* )cp;\n\n    for ( i = 24; ; ) {\n        long j;\n\n        j = strtoul( tmp, &tmp, 0 );\n\n        if ( *tmp == 0 ) {\n            ip |= j;\n\n            break;\n        } else if ( *tmp == '.' ) {\n            if ( j > 255 ) {\n                return 0;\n            }\n\n            ip |= ( j << i );\n\n            if ( i > 0 ) {\n                i -= 8;\n            }\n\n            ++tmp;\n\n            continue;\n        }\n\n        return 0;\n    }\n\n    inp->s_addr = htonl( ip );\n\n    return 1;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/network/inet_ntoa.c",
    "content": "\n \n\n#include <stdlib.h>\n#include <netinet/in.h>\n#include <arpa/inet.h>\n#include <stdio.h>\n\nchar* inet_ntoa( struct in_addr in ) {\n    unsigned int ip;\n    static char __inet_ntoa_result[18];\n    int i;\n    uint8_t bytes[4];\n    uint8_t* addrbyte;\n\n    ip = in.s_addr;\n\n    addrbyte = (uint8_t *)&ip;\n\n    for(i = 0; i < 4; i++) {\n        bytes[i] = *addrbyte++;\n    }\n\n    snprintf (__inet_ntoa_result, 18, \"%d.%d.%d.%d\", bytes[0], bytes[1], bytes[2], bytes[3]);\n\n    return __inet_ntoa_result;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/opendir.c",
    "content": "\n \n\n#include <dirent.h>\n#include <stdlib.h>\n#include <fcntl.h>\n\nDIR* opendir( const char* name ) {\n    DIR* dir;\n\n    dir = ( DIR* )malloc( sizeof( DIR ) );\n\n    if ( dir == NULL ) {\n        return NULL;\n    }\n\n    dir->fd = open( name, O_RDONLY );\n\n    if ( dir->fd < 0 ) {\n        free( dir );\n        return NULL;\n    }\n\n    return dir;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/os/debug.c",
    "content": "\n \n\n#include <os.h>\n\n"
  },
  {
    "path": "src/sdk/src/libc/src/os/ipc.c",
    "content": "\n \n\n\n#include <os.h>\n\n"
  },
  {
    "path": "src/sdk/src/libc/src/os/module.c",
    "content": "\n \n\n\n#include <os.h>\n\n\n"
  },
  {
    "path": "src/sdk/src/libc/src/os/os.c",
    "content": "\n \n\n#include <os.h>\n\n"
  },
  {
    "path": "src/sdk/src/libc/src/os/region.c",
    "content": "\n \n\n#include <os.h>\n"
  },
  {
    "path": "src/sdk/src/libc/src/os/semaphore.c",
    "content": "\n \n\n#include <os.h>\n"
  },
  {
    "path": "src/sdk/src/libc/src/os/syscall.c",
    "content": "\n \n\n#include <os.h>\n\n\nint syscall0( int number ){\n\tint ret;\n\tasm volatile (\"\t\t   \\\n\t\tmov %1, %%eax\t\\n \\\n\t\tint $0x80\t\t\\n \\\n\t\tmov %%eax, %0\" \n\t\t: \"=g\" (ret) \n\t\t: \"g\" (number)\n\t);\n\treturn ret;\n}\n\n\nint syscall1( int number, uint32_t p1 ){\n\tint ret;\n\tasm volatile (\"\t\t   \\\n\t\tmov %1, %%eax\t\\n \\\n\t\tmov %2, %%ebx\t\\n \\\n\t\tint $0x80\t\t\\n \\\n\t\tmov %%eax, %0\" \n\t\t: \"=g\" (ret) \n\t\t: \"g\" (number), \"g\" (p1)\n\t);\n\treturn ret;\n}\n\n\nint syscall2( int number, uint32_t p1, uint32_t p2 ){\n\tint ret;\n\n\tasm volatile (\"\t\t   \\\n\t\tmov %1, %%eax\t\\n \\\n\t\tmov %2, %%ebx\t\\n \\\n\t\tmov %3, %%ecx\t\\n \\\n\t\tint $0x80\t\\n \\\n\t\tmov %%eax, %0\"\t\n\t\t: \"=g\" (ret) \n\t\t: \"g\" (number), \"g\" (p1), \"g\" (p2)\n\t);\n\treturn ret;\n}\n\n\nint syscall3( int number, uint32_t p1, uint32_t p2, uint32_t p3 ){\n\tint ret;\n\tasm volatile (\"\t\t\t   \\\n\t\tmov %1, %%eax\t\t\\n \\\n\t\tmov %2, %%ebx\t\t\\n \\\n\t\tmov %3, %%ecx\t\t\\n \\\n\t\tmov %4, %%edx\t\t\\n \\\n\t\tint $0x80\t\t\\n \\\n\t\tmov %%eax, %0\" \n\t\t: \"=g\" (ret) \n\t\t: \"g\" (number),\"g\" (p1), \"g\" (p2),  \"g\" (p3)\n\t);\n\treturn ret;\n}\n\n\nint syscall4( int number, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4 ){\n\tint ret;\n\tasm volatile (\"\t\t\t   \\\n\t\tmov %1, %%eax\t\t\\n \\\n\t\tmov %2, %%ebx\t\t\\n \\\n\t\tmov %3, %%ecx\t\t\\n \\\n\t\tmov %4, %%edx\t\t\\n \\\n\t\tmov %5, %%edi\t\t\\n \\\n\t\tint $0x80\t\t\\n \\\n\t\tmov %%eax, %0\" \n\t\t: \"=g\" (ret) \n\t\t: \"g\" (number),\"g\" (p1), \"g\" (p2),  \"g\" (p3),  \"g\" (p4)\n\t);\n\treturn ret;\n}\n\n\nint syscall5( int number, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5 ){\n\tint ret;\n\tasm volatile (\"\t\t\t   \\\n\t\tmov %1, %%eax\t\t\\n \\\n\t\tmov %2, %%ebx\t\t\\n \\\n\t\tmov %3, %%ecx\t\t\\n \\\n\t\tmov %4, %%edx\t\t\\n \\\n\t\tmov %5, %%edi\t\t\\n \\\n\t\tmov %6, %%esi\t\t\\n \\\n\t\tint $0x80\t\t\\n \\\n\t\tmov %%eax, %0\" \n\t\t: \"=g\" (ret) \n\t\t: \"g\" (number),\"g\" (p1), \"g\" (p2),  \"g\" (p3),  \"g\" (p4),  \"g\" (p5)\n\t);\n\treturn ret;\n}\n\n\n"
  },
  {
    "path": "src/sdk/src/libc/src/os/sysinfo.c",
    "content": "\n \n\n#include <errno.h>\n\n#include <os.h>\n"
  },
  {
    "path": "src/sdk/src/libc/src/os/thread.c",
    "content": "\n \n\n\n#include <os.h>\n\n\n"
  },
  {
    "path": "src/sdk/src/libc/src/pwd/endpwent.c",
    "content": "\n \n\n#include <pwd.h>\n\nextern int _passwd_db_position;\n\nvoid endpwent( void ) {\n    _passwd_db_position = 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/pwd/getpwent.c",
    "content": "\n \n\n#include <pwd.h>\n\n\ntypedef struct passwd_myos passwd_myos;\nstruct passwd_myos {\n    char name[64];\n    char password[64];\n    int uid;\n    int gid;\n    char gecos[64];\n    char dir[512];\n    char shell[64];\n};\n\npasswd_myos myos_pass;\n\npasswd_myos* myos_user_getN(const char* name){\n\tint ret=syscall2(68,(uint32_t)name,(uint32_t)&myos_pass);\n\tif (ret!=0)\n\t\treturn &myos_pass;\n\telse\n\t\treturn NULL;\n}\n\npasswd_myos* myos_user_getID(int id){\n\tint ret=syscall2(69,id,(uint32_t)&myos_pass);\n\tif (ret!=0)\n\t\treturn &myos_pass;\n\telse\n\t\treturn NULL;\n}\n\nint _passwd_db_position = 0;\n\nstruct passwd __tmp_passwd;\n\nvoid build_tmp_passwd(){\n\t__tmp_passwd.pw_name=myos_pass.name;\n\t__tmp_passwd.pw_passwd=myos_pass.password;\n\t__tmp_passwd.pw_uid=myos_pass.uid;\n\t__tmp_passwd.pw_gid=myos_pass.gid;\n\t__tmp_passwd.pw_gecos=myos_pass.gecos;\n\t__tmp_passwd.pw_dir=myos_pass.dir;\n\t__tmp_passwd.pw_shell=myos_pass.shell;\n}\n\n\nstruct passwd* getpwent( void ) {\n\n\tpasswd_myos* pass=myos_user_getID(_passwd_db_position);\n\tif (pass==NULL)\n\t\treturn NULL;\n\t\n\tbuild_tmp_passwd();\n\t_passwd_db_position++;\n\treturn &__tmp_passwd;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/pwd/getpwnam.c",
    "content": "\n \n\n#include <pwd.h>\n\n\ntypedef struct passwd_myos passwd_myos;\nstruct passwd_myos {\n    char name[64];\n    char password[64];\n    int uid;\n    int gid;\n    char gecos[64];\n    char dir[512];\n    char shell[64];\n};\n\nextern struct passwd __tmp_passwd;\npasswd_myos* myos_user_getN(const char* name);\nvoid build_tmp_passwd();\n\nstruct passwd* getpwnam( const char* name ) {\n\n\tpasswd_myos* pass=myos_user_getN(name);\n\tif (pass==NULL)\n\t\treturn NULL;\n\t\n\tbuild_tmp_passwd();\n\treturn &__tmp_passwd;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/pwd/getpwuid.c",
    "content": "\n \n\n#include <pwd.h>\n\n\ntypedef struct passwd_myos passwd_myos;\nstruct passwd_myos {\n    char name[64];\n    char password[64];\n    int uid;\n    int gid;\n    char gecos[64];\n    char dir[512];\n    char shell[64];\n};\n\nextern struct passwd __tmp_passwd;\n\npasswd_myos* myos_user_getID(int id);\n\n\nstruct passwd* getpwuid( uid_t uid ) {\n\n\tpasswd_myos* pass=myos_user_getID(uid);\n\tif (pass==NULL)\n\t\treturn NULL;\n\t\n\tbuild_tmp_passwd();\n\treturn &__tmp_passwd;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/pwd/setpwent.c",
    "content": "\n \n\n#include <pwd.h>\n\nextern int _passwd_db_position;\n\nvoid setpwent( void ) {\n    _passwd_db_position = 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/readdir.c",
    "content": "\n \n\n#include <dirent.h>\n#include <unistd.h>\n#include <errno.h>\n\nstruct dirent* readdir( DIR* dir ) {\n    int error;\n\n    if ( dir == NULL ) {\n        return NULL;\n    }\n\n    error = getdents( dir->fd, &dir->entry, sizeof( struct dirent ) );\n\n    if ( error == 0 ) {\n        return NULL;\n    }\n\n    return &dir->entry;\n}\n\nint readdir_r( DIR* dir, struct dirent* entry, struct dirent** result ) {\n    int error;\n\n    if ( ( dir == NULL ) ||\n         ( entry == NULL ) ) {\n        errno = -EINVAL;\n        return -1;\n    }\n\n    error = getdents( dir->fd, entry, sizeof( struct dirent ) );\n\n    if ( error == 0 ) {\n        *result = NULL;\n    } else {\n        *result = entry;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/rewinddir.c",
    "content": "\n \n\n#include <dirent.h>\n#include <errno.h>\n\n#include <os.h>\n\nvoid rewinddir( DIR* dirp ) {\n    int error;\n\n    error = syscall1( SYS_rewinddir, dirp->fd );\n\n    if ( error < 0 ) {\n        errno = -error;\n    }\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/signal/kill.c",
    "content": "\n \n\n#include <signal.h>\n#include <errno.h>\n\n#include <os.h>\n\nint kill( pid_t pid, int signal ) {\n    int error;\n\n    error = syscall2(\n        SYS_kill,\n        pid,\n        signal\n    );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/signal/killpg.c",
    "content": "\n \n\n#include <signal.h>\n\nint killpg( int pgrp, int signal ) {\n    return -1;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/signal/raise.c",
    "content": "\n \n\n#include <signal.h>\n\n\n\nint raise( int signal ) {\n    printf( \"raise(): Not yet implemented!\\n\" );\n\n    return -1;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/signal/sigaction.c",
    "content": "\n \n\n#include <errno.h>\n#include <signal.h>\n\n#include <os.h>\n\nint sigaction( int signum, const struct sigaction* act, struct sigaction* oldact ) {\n    int error;\n\n    error = syscall3(\n        SYS_sigaction,\n        signum,\n        ( int )act,\n        ( int )oldact\n    );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/signal/sigaddset.c",
    "content": "\n \n\n#include <signal.h>\n#include <errno.h>\n\nint sigaddset( sigset_t* set, int signum ) {\n    if ( ( set == NULL ) ||\n         ( signum < 1 ) ||\n         ( signum >= _NSIG ) ) {\n        errno = -EINVAL;\n        return -1;\n    }\n\n    *set |= ( 1ULL << ( signum - 1 ) );\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/signal/sigdelset.c",
    "content": "\n \n\n#include <signal.h>\n#include <errno.h>\n\nint sigdelset( sigset_t* set, int signum ) {\n    if ( ( set == NULL ) ||\n         ( signum < 1 ) ||\n         ( signum >= _NSIG ) ) {\n        errno = -EINVAL;\n        return -1;\n    }\n\n    *set &= ~( 1ULL << ( signum - 1 ) );\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/signal/sigemptyset.c",
    "content": "\n \n\n#include <signal.h>\n#include <errno.h>\n\nint sigemptyset( sigset_t* set ) {\n    if ( set == NULL ) {\n        errno = -EINVAL;\n        return -1;\n    }\n\n    *set = 0;\n\n    return 0;\n}\n\n"
  },
  {
    "path": "src/sdk/src/libc/src/signal/sigfillset.c",
    "content": "\n \n\n#include <signal.h>\n#include <errno.h>\n#include <string.h>\n\nint sigfillset( sigset_t* set ) {\n    if ( set == NULL ) {\n        errno = -EINVAL;\n        return -1;\n    }\n\n    memset( ( void* )set, 0xFF, sizeof( sigset_t ) );\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/signal/sigismember.c",
    "content": "\n \n\n#include <signal.h>\n#include <errno.h>\n\nint sigismember( const sigset_t* set, int signum ) {\n    if ( ( set == NULL ) ||\n         ( signum < 1 ) ||\n         ( signum >= _NSIG ) ) {\n        errno = -EINVAL;\n        return -1;\n    }\n\n    if ( ( ( *set ) & ( 1ULL << ( signum - 1 ) ) ) != 0 ) {\n        return 1;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/signal/signal.c",
    "content": "\n \n\n#include <signal.h>\n#include <errno.h>\n\nsighandler_t signal( int signum, sighandler_t handler ) {\n    int error;\n    struct sigaction act;\n    struct sigaction oldact;\n\n    if ( ( handler == SIG_ERR ) ||\n         ( signum < 0 ) ||\n         ( signum >= _NSIG ) ) {\n        errno = -EINVAL;\n        return SIG_ERR;\n    }\n\n    act.sa_handler = handler;\n\n    error = sigemptyset( &act.sa_mask );\n\n    if ( error < 0 ) {\n        return SIG_ERR;\n    }\n\n    error = sigaddset( &act.sa_mask, signum );\n\n    if ( error < 0 ) {\n        return SIG_ERR;\n    }\n\n    act.sa_flags = SA_RESTART;\n\n    if ( sigaction( signum, &act, &oldact ) < 0 ) {\n        return SIG_ERR;\n    }\n\n    return oldact.sa_handler;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/signal/sigprocmask.c",
    "content": "\n \n\n#include <signal.h>\n#include <errno.h>\n\n#include <os.h>\n\nint sigprocmask( int how, const sigset_t* set, sigset_t* oldset ) {\n    int error;\n\n    error = syscall3(\n        SYS_sigprocmask,\n        how,\n        ( int )set,\n        ( int )oldset\n    );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/sscanf.c",
    "content": "/**\r\n *\tMyOS\r\n *\tCopyright (C) 2010 - 2011 Samy Pess\r\n *\t\r\n *\tThis program is free software: you can redistribute it and/or modify\r\n *  it under the terms of the GNU General Public License as published by\r\n *  the Free Software Foundation, either version 3 of the License, or\r\n *  (at your option) any later version.\r\n *  \r\n *  This program is distributed in the hope that it will be useful,\r\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n *  GNU General Public License for more details.\r\n *  \r\n *  You should have received a copy of the GNU General Public License\r\n *  along with this program.  If not, see <http://www.gnu.org/licenses/>.\r\n**/\r\n#include <stdarg.h>\r\n#include <stdio.h>\r\n#include <sys/types.h>\r\n#include <stdarg.h>\r\n\r\n\r\n/**\r\n * simple_strtoul - convert a string to an unsigned long\r\n * @cp: The start of the string\r\n * @endp: A pointer to the end of the parsed string will be placed here\r\n * @base: The number base to use\r\n */\r\nunsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)\r\n{\r\n\tunsigned long result = 0,value;\r\n\r\n\tif (!base) {\r\n\t\tbase = 10;\r\n\t\tif (*cp == '0') {\r\n\t\t\tbase = 8;\r\n\t\t\tcp++;\r\n\t\t\tif ((*cp == 'x') && isxdigit(cp[1])) {\r\n\t\t\t\tcp++;\r\n\t\t\t\tbase = 16;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\twhile (isxdigit(*cp) &&\r\n\t       (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) {\r\n\t\tresult = result*base + value;\r\n\t\tcp++;\r\n\t}\r\n\tif (endp)\r\n\t\t*endp = (char *)cp;\r\n\treturn result;\r\n}\r\n\r\n/**\r\n * simple_strtol - convert a string to a signed long\r\n * @cp: The start of the string\r\n * @endp: A pointer to the end of the parsed string will be placed here\r\n * @base: The number base to use\r\n */\r\nlong simple_strtol(const char *cp,char **endp,unsigned int base)\r\n{\r\n\tif(*cp=='-')\r\n\t\treturn -simple_strtoul(cp+1,endp,base);\r\n\treturn simple_strtoul(cp,endp,base);\r\n}\r\n\r\n/**\r\n * simple_strtoull - convert a string to an unsigned long long\r\n * @cp: The start of the string\r\n * @endp: A pointer to the end of the parsed string will be placed here\r\n * @base: The number base to use\r\n */\r\nunsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base)\r\n{\r\n\tunsigned long long result = 0,value;\r\n\r\n\tif (!base) {\r\n\t\tbase = 10;\r\n\t\tif (*cp == '0') {\r\n\t\t\tbase = 8;\r\n\t\t\tcp++;\r\n\t\t\tif ((*cp == 'x') && isxdigit(cp[1])) {\r\n\t\t\t\tcp++;\r\n\t\t\t\tbase = 16;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\twhile (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)\r\n\t    ? toupper(*cp) : *cp)-'A'+10) < base) {\r\n\t\tresult = result*base + value;\r\n\t\tcp++;\r\n\t}\r\n\tif (endp)\r\n\t\t*endp = (char *)cp;\r\n\treturn result;\r\n}\r\n\r\n/**\r\n * simple_strtoll - convert a string to a signed long long\r\n * @cp: The start of the string\r\n * @endp: A pointer to the end of the parsed string will be placed here\r\n * @base: The number base to use\r\n */\r\nlong long simple_strtoll(const char *cp,char **endp,unsigned int base)\r\n{\r\n\tif(*cp=='-')\r\n\t\treturn -simple_strtoull(cp+1,endp,base);\r\n\treturn simple_strtoull(cp,endp,base);\r\n}\r\n\r\nstatic int skip_atoi(const char **s)\r\n{\r\n\tint i=0;\r\n\r\n\twhile (isdigit(**s))\r\n\t\ti = i*10 + *((*s)++) - '0';\r\n\treturn i;\r\n}\r\n\r\n/**\r\n * vsscanf - Unformat a buffer into a list of arguments\r\n * @buf:\tinput buffer\r\n * @fmt:\tformat of buffer\r\n * @args:\targuments\r\n */\r\nint vsscanf(const char * buf, const char * fmt, va_list args)\r\n{\r\n\tconst char *str = buf;\r\n\tchar *next;\r\n\tchar digit;\r\n\tint num = 0;\r\n\tint qualifier;\r\n\tint base;\r\n\tint field_width;\r\n\tint is_sign = 0;\r\n\r\n\twhile(*fmt && *str) {\r\n\t\t/* skip any white space in format */\r\n\t\t/* white space in format matchs any amount of\r\n\t\t * white space, including none, in the input.\r\n\t\t */\r\n\t\tif (isspace(*fmt)) {\r\n\t\t\twhile (isspace(*fmt))\r\n\t\t\t\t++fmt;\r\n\t\t\twhile (isspace(*str))\r\n\t\t\t\t++str;\r\n\t\t}\r\n\r\n\t\t/* anything that is not a conversion must match exactly */\r\n\t\tif (*fmt != '%' && *fmt) {\r\n\t\t\tif (*fmt++ != *str++)\r\n\t\t\t\tbreak;\r\n\t\t\tcontinue;\r\n\t\t}\r\n\r\n\t\tif (!*fmt)\r\n\t\t\tbreak;\r\n\t\t++fmt;\r\n\r\n\t\t/* skip this conversion.\r\n\t\t * advance both strings to next white space\r\n\t\t */\r\n\t\tif (*fmt == '*') {\r\n\t\t\twhile (!isspace(*fmt) && *fmt)\r\n\t\t\t\tfmt++;\r\n\t\t\twhile (!isspace(*str) && *str)\r\n\t\t\t\tstr++;\r\n\t\t\tcontinue;\r\n\t\t}\r\n\r\n\t\t/* get field width */\r\n\t\tfield_width = -1;\r\n\t\tif (isdigit(*fmt))\r\n\t\t\tfield_width = skip_atoi(&fmt);\r\n\r\n\t\t/* get conversion qualifier */\r\n\t\tqualifier = -1;\r\n\t\tif (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||\r\n\t\t    *fmt == 'Z' || *fmt == 'z') {\r\n\t\t\tqualifier = *fmt;\r\n\t\t\tfmt++;\r\n\t\t}\r\n\t\tbase = 10;\r\n\t\tis_sign = 0;\r\n\r\n\t\tif (!*fmt || !*str)\r\n\t\t\tbreak;\r\n\r\n\t\tswitch(*fmt++) {\r\n\t\tcase 'c':\r\n\t\t{\r\n\t\t\tchar *s = (char *) va_arg(args,char*);\r\n\t\t\tif (field_width == -1)\r\n\t\t\t\tfield_width = 1;\r\n\t\t\tdo {\r\n\t\t\t\t*s++ = *str++;\r\n\t\t\t} while (--field_width > 0 && *str);\r\n\t\t\tnum++;\r\n\t\t}\r\n\t\tcontinue;\r\n\t\tcase 's':\r\n\t\t{\r\n\t\t\tchar *s = (char *) va_arg(args, char *);\r\n\t\t\tif(field_width == -1)\r\n\t\t\t\tfield_width = sizeof(int);\r\n\t\t\t/* first, skip leading white space in buffer */\r\n\t\t\twhile (isspace(*str))\r\n\t\t\t\tstr++;\r\n\r\n\t\t\t/* now copy until next white space */\r\n\t\t\twhile (*str && !isspace(*str) && field_width--) {\r\n\t\t\t\t*s++ = *str++;\r\n\t\t\t}\r\n\t\t\t*s = '\\0';\r\n\t\t\tnum++;\r\n\t\t}\r\n\t\tcontinue;\r\n\t\tcase 'n':\r\n\t\t\t/* return number of characters read so far */\r\n\t\t{\r\n\t\t\tint *i = (int *)va_arg(args,int*);\r\n\t\t\t*i = str - buf;\r\n\t\t}\r\n\t\tcontinue;\r\n\t\tcase 'o':\r\n\t\t\tbase = 8;\r\n\t\t\tbreak;\r\n\t\tcase 'x':\r\n\t\tcase 'X':\r\n\t\t\tbase = 16;\r\n\t\t\tbreak;\r\n\t\tcase 'i':\r\n                        base = 0;\r\n\t\tcase 'd':\r\n\t\t\tis_sign = 1;\r\n\t\tcase 'u':\r\n\t\t\tbreak;\r\n\t\tcase '%':\r\n\t\t\t/* looking for '%' in str */\r\n\t\t\tif (*str++ != '%')\r\n\t\t\t\treturn num;\r\n\t\t\tcontinue;\r\n\t\tdefault:\r\n\t\t\t/* invalid format; stop here */\r\n\t\t\treturn num;\r\n\t\t}\r\n\r\n\t\t/* have some sort of integer conversion.\r\n\t\t * first, skip white space in buffer.\r\n\t\t */\r\n\t\twhile (isspace(*str))\r\n\t\t\tstr++;\r\n\r\n\t\tdigit = *str;\r\n\t\tif (is_sign && digit == '-')\r\n\t\t\tdigit = *(str + 1);\r\n\r\n\t\tif (!digit\r\n                    || (base == 16 && !isxdigit(digit))\r\n                    || (base == 10 && !isdigit(digit))\r\n                    || (base == 8 && (!isdigit(digit) || digit > '7'))\r\n                    || (base == 0 && !isdigit(digit)))\r\n\t\t\t\tbreak;\r\n\r\n\t\tswitch(qualifier) {\r\n\t\tcase 'h':\r\n\t\t\tif (is_sign) {\r\n\t\t\t\tshort *s = (short *) va_arg(args,short *);\r\n\t\t\t\t*s = (short) simple_strtol(str,&next,base);\r\n\t\t\t} else {\r\n\t\t\t\tunsigned short *s = (unsigned short *) va_arg(args, unsigned short *);\r\n\t\t\t\t*s = (unsigned short) simple_strtoul(str, &next, base);\r\n\t\t\t}\r\n\t\t\tbreak;\r\n\t\tcase 'l':\r\n\t\t\tif (is_sign) {\r\n\t\t\t\tlong *l = (long *) va_arg(args,long *);\r\n\t\t\t\t*l = simple_strtol(str,&next,base);\r\n\t\t\t} else {\r\n\t\t\t\tunsigned long *l = (unsigned long*) va_arg(args,unsigned long*);\r\n\t\t\t\t*l = simple_strtoul(str,&next,base);\r\n\t\t\t}\r\n\t\t\tbreak;\r\n\t\tcase 'L':\r\n\t\t\tif (is_sign) {\r\n\t\t\t\tlong long *l = (long long*) va_arg(args,long long *);\r\n\t\t\t\t*l = simple_strtoll(str,&next,base);\r\n\t\t\t} else {\r\n\t\t\t\tunsigned long long *l = (unsigned long long*) va_arg(args,unsigned long long*);\r\n\t\t\t\t*l = simple_strtoull(str,&next,base);\r\n\t\t\t}\r\n\t\t\tbreak;\r\n\t\tcase 'Z':\r\n\t\tcase 'z':\r\n\t\t{\r\n\t\t\tsize_t *s = (size_t*) va_arg(args,size_t*);\r\n\t\t\t*s = (size_t) simple_strtoul(str,&next,base);\r\n\t\t}\r\n\t\tbreak;\r\n\t\tdefault:\r\n\t\t\tif (is_sign) {\r\n\t\t\t\tint *i = (int *) va_arg(args, int*);\r\n\t\t\t\t*i = (int) simple_strtol(str,&next,base);\r\n\t\t\t} else {\r\n\t\t\t\tunsigned int *i = (unsigned int*) va_arg(args, unsigned int*);\r\n\t\t\t\t*i = (unsigned int) simple_strtoul(str,&next,base);\r\n\t\t\t}\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\tnum++;\r\n\r\n\t\tif (!next)\r\n\t\t\tbreak;\r\n\t\tstr = next;\r\n\t}\r\n\treturn num;\r\n}\r\n\r\n/**\r\n * sscanf - Unformat a buffer into a list of arguments\r\n * @buf:\tinput buffer\r\n * @fmt:\tformatting of buffer\r\n * @...:\tresulting arguments\r\n */\r\nint sscanf(const char * buf, const char * fmt, ...)\r\n{\r\n\tva_list args;\r\n\tint i;\r\n\r\n\tva_start(args,fmt);\r\n\ti = vsscanf(buf,fmt,args);\r\n\tva_end(args);\r\n\treturn i;\r\n}\r\n\r\nint fscanf(FILE*stream,const char * fmt, ...){\r\n\tchar*buf;\r\n\tbuf=fgets(buf,512,stream);\r\n\tva_list args;\r\n\tint i;\r\n\r\n\tva_start(args,fmt);\r\n\ti = vsscanf(buf,fmt,args);\r\n\tva_end(args);\r\n\treturn i;\r\n}\r\n\r\n\r\nint scanf(const char * fmt, ...){\r\n\tchar*buf;\r\n\tbuf=fgets(buf,512,stdin);\r\n\tva_list args;\r\n\tint i;\r\n\r\n\tva_start(args,fmt);\r\n\ti = vsscanf(buf,fmt,args);\r\n\tva_end(args);\r\n\treturn i;\r\n}\r\n"
  },
  {
    "path": "src/sdk/src/libc/src/start.c",
    "content": "#include <unistd.h>\n#include <stdlib.h>\n#include <stdio.h>\n#include <os.h>\n\n#define MAX_ENV_COUNT 256\n\n\nint main(int argc, char *argv []);\n\nint errno;\n\nchar** environ={\n\t\"PATH\",\"/bin/\",\n\tNULL,NULL\t\n};\n\nint __environ_allocated;\n\n\nvoid _start(int argc, char** argv) {\n\tstdout=fdopen(0,\"rw\");\n\tstdin=fdopen(1,\"rw\");\n\tstderr=fdopen(2,\"rw\");\n\tint error;\n    environ = 0;\n    __environ_allocated = 0;\n\n    /* Call the main function of the application */\n\n    error = main( argc, argv);\n\n    /* Exit the process */\n\n    exit( error );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/clearerr.c",
    "content": "\n \n\n#include <stdio.h>\n\nvoid clearerr( FILE* stream ) {\n    stream->flags &= ~( __FILE_EOF | __FILE_ERROR );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/fclose.c",
    "content": "\n \n\n#include <stdio.h>\n#include <stdlib.h>\n#include <unistd.h>\n\nint fclose( FILE* stream ) {\n    int result;\n\n    result = fflush( stream );\n    result |= close( stream->fd );\n\n    if ( ( ( stream->flags & __FILE_DONTFREEBUF ) == 0 ) &&\n         ( stream->buffer != NULL ) ) {\n        free( stream->buffer );\n    }\n\n    free( stream );\n\n    return result;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/fdopen.c",
    "content": "\n \n\n#include <stdio.h>\n#include <errno.h>\n\nint __parse_mode( const char* mode );\nFILE* __init_file( int fd, int close_on_error, int mode );\n\nFILE* fdopen( int fd, const char* mode ) {\n    int flags;\n\n    if ( fd < 0 ) {\n        errno = -EINVAL;\n        return NULL;\n    }\n\n    flags = __parse_mode( mode );\n\n    return __init_file( fd, 0, flags );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/feof.c",
    "content": "\n \n\n#include <stdio.h>\n\nint feof( FILE* stream ) {\n    if ( stream->has_ungotten ) {\n        return 0;\n    }\n\n    return ( stream->flags & __FILE_EOF );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/ferror.c",
    "content": "\n \n\n#include <stdio.h>\n\nint ferror( FILE* stream ) {\n    return ( stream->flags & __FILE_ERROR );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/fflush.c",
    "content": "\n \n\n#include <stdio.h>\n#include <unistd.h>\n\nint fflush( FILE* stream ) {\n    if ( stream->flags & __FILE_BUFINPUT ) {\n        int tmp;\n\n        tmp = ( int )stream->buffer_pos - ( int )stream->buffer_data_size;\n\n        if ( tmp != 0 ) {\n            lseek( stream->fd, tmp, SEEK_CUR );\n        }\n\n        stream->buffer_pos = 0;\n        stream->buffer_data_size = 0;\n    } else {\n        if ( stream->buffer_pos > 0 ) {\n            if ( write( stream->fd, stream->buffer, stream->buffer_pos ) != stream->buffer_pos ) {\n\t\t\t\twrite(0,\"\\nerror file \\n\",strlen(\"\\nerror file \\n\"));\n                stream->flags |= __FILE_ERROR;\n                return -1;\n            }\n\t\t\tmemset(stream->buffer,0,_IO_BUFSIZE);\n            stream->buffer_pos = 0;\n        }\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/fgetc.c",
    "content": "\n \n\n#include <stdio.h>\n#include <unistd.h>\n\n#include \"stdio_internal.h\"\n\nint fgetc( FILE* stream ) {\n    unsigned char c;\n\n    /* Check if we can read from the stream */\n\n    if ( ( ( stream->flags & __FILE_CAN_READ ) == 0 ) ||\n         ( __set_stream_flags( stream, __FILE_BUFINPUT ) ) ) {\n        stream->flags |= __FILE_ERROR;\n        printf(\"EOF ! \\n\");\n        return EOF;\n    }\n\n    /* Check the unget buffer */\n\n    if ( stream->has_ungotten ) {\n        stream->has_ungotten = 0;\n        printf(\"un get ! \\n\");\n        return stream->unget_buffer;\n    }\n\n    /* Check the end of the file */\n\n    if ( feof( stream ) ) {\n\t\tprintf(\"EOF ! \\n\");\n        return EOF;\n    }\n\n    /* Fill the buffer if it's empty */\n\n    if ( stream->buffer_pos >= stream->buffer_data_size ) {\n        ssize_t length;\n\n        length = read( stream->fd, stream->buffer, stream->buffer_size );\n        if ( length == 0 ) {\n            stream->flags |= __FILE_EOF;\n            printf(\"EOF ! \\n\");\n            return EOF;\n        } else if ( length < 0 ) {\n            stream->flags |= __FILE_ERROR;\n            printf(\"EOF ! \\n\");\n            return EOF;\n        }\n        stream->buffer_pos = 0;\n        stream->buffer_data_size = length;\n    }\n\n    /* Get one character from the buffer */\n\n    c = stream->buffer[ stream->buffer_pos ];\n\n    stream->buffer_pos++;\n\n    return c;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/fgets.c",
    "content": "\n \n\n#include <stdio.h>\n\nchar* fgets( char* s, int size, FILE* stream ) {\n    char* orig = s;\n    int l;\n\n    for ( l = size; l > 1; ) {\n        register int c = fgetc( stream );\n\t\t//printf(\"c:  %c \\n\");\n        if ( c == EOF ) {\n            break;\n        }\n\n        *s = c;\n        ++s;\n        --l;\n\n        if ( c == '\\n' ) {\n            break;\n        }\n    }\n\n    if ( ( l == size ) || ( ferror( stream ) ) ) {\n        return 0;\n    }\n\n    *s = 0;\n\n    return orig;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/fileno.c",
    "content": "\n \n\n#include <stdio.h>\n\nint fileno( FILE* stream ) {\n    return stream->fd;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/fopen.c",
    "content": "\n \n\n#include <stdio.h>\n#include <stdlib.h>\n#include <fcntl.h>\n#include <unistd.h>\n\nint __parse_mode( const char* mode ) {\n    int mode_flags = 0;\n\n    for ( ;; ) {\n        switch ( *mode ) {\n            case 0 : return mode_flags;\n            case 'b': break;\n            case 'r': mode_flags = O_RDONLY; break;\n            case 'w': mode_flags = O_WRONLY | O_CREAT | O_TRUNC; break;\n            case 'a': mode_flags = O_WRONLY | O_CREAT | O_APPEND; break;\n            case '+': mode_flags = ( mode_flags & ( ~O_WRONLY ) ) | O_RDWR; break;\n            default : break;\n        }\n\n        ++mode;\n    }\n}\n\nFILE* __init_file( int fd, int close_on_error, int mode ) {\n    FILE* stream;\n\n    stream = ( FILE* )malloc( sizeof( FILE ) );\n\n    if ( stream == NULL ) {\n        if ( close_on_error ) {\n            close( fd );\n        }\n\n        return NULL;\n    }\n\n    stream->buffer = ( char* )malloc( _IO_BUFSIZE );\n\n    if ( stream->buffer == NULL ) {\n        free( stream );\n\n        if ( close_on_error ) {\n              close( fd );\n        }\n\n        return NULL;\n    }\n\n    stream->fd = fd;\n    stream->flags = 0;\n    stream->buffer_pos = 0;\n    stream->buffer_size = _IO_BUFSIZE;\n    stream->buffer_data_size = 0;\n\n    switch ( mode & O_RDWR ) {\n        case O_RDWR :   stream->flags |= ( __FILE_CAN_WRITE | __FILE_CAN_READ ); break;\n        case O_RDONLY : stream->flags |= __FILE_CAN_READ; break;\n        case O_WRONLY : stream->flags |= __FILE_CAN_WRITE; break;\n        default : break;\n    }\n\n    stream->has_ungotten = 0;\n\n    return stream;\n}\n\nFILE* fopen( const char* path, const char* mode ) {\n    int fd;\n    int flags;\n\n    flags = __parse_mode( mode );\n\n    fd = open( path, flags, 0666 );\n\n    if ( fd < 0 ) {\n        return NULL;\n    }\n\n    return __init_file( fd, 1, flags );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/fpurge.c",
    "content": "\n \n\n#include <stdio.h>\n\n\n\nint fpurge( FILE* stream ) {\n    if ( stream->flags & __FILE_NOBUF ) {\n        return 0;\n    }\n\n    stream->has_ungotten = 0;\n\n    if ( stream->flags & __FILE_BUFINPUT ) {\n        stream->buffer_pos = stream->buffer_data_size;\n    } else {\n        stream->buffer_pos = 0;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/fputc.c",
    "content": "\n \n\n#include <stdio.h>\n#include <unistd.h>\n\n#include \"stdio_internal.h\"\n\nint fputc( int c, FILE* stream ) {\n    /* Check if we can write to the stream */\n\n    if ( ( ( stream->flags & __FILE_CAN_WRITE ) == 0 ) ||\n         ( __set_stream_flags( stream, 0 ) ) ) {\n        stream->flags |= __FILE_ERROR;\n        return EOF;\n    }\n\n    /* Make sure we have free space in the buffer */\n\n    if ( stream->buffer_pos >= stream->buffer_size - 1 ) {\n        if ( fflush( stream ) ) {\n            stream->flags |= __FILE_ERROR;\n            return EOF;\n        }\n    }\n\n    if ( stream->flags & __FILE_NOBUF ) {\n        if ( write( stream->fd, &c, 1 ) != 1 ) {\n            stream->flags |= __FILE_ERROR;\n            return EOF;\n        }\n\n        return 0;\n    }\n\n    stream->buffer[ stream->buffer_pos++ ] = c;\n\n    if ( ( ( stream->flags & __FILE_BUFLINEWISE ) && ( c == '\\n' ) ) ||\n         ( stream->flags & __FILE_NOBUF ) ) {\n        if ( fflush( stream ) ) {\n            stream->flags |= __FILE_ERROR;\n            return EOF;\n        }\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/fputs.c",
    "content": "\n \n\n#include <stdio.h>\n#include <unistd.h>\n\nint fputs( const char* s, FILE* stream ) {\n    while ( *s ) {\n        fputc( *s++, stream );\n    }\n\n    fflush( stream );\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/fread.c",
    "content": "\n \n\n#include <stdio.h>\n#include <string.h>\n#include <unistd.h>\n\nsize_t fread( void* ptr, size_t size, size_t nmemb, FILE* stream ) {\n    int res;\n    unsigned long i, j;\n\n    j = size * nmemb;\n    i = 0;\n\n    if ( ( stream->flags & __FILE_CAN_READ ) == 0 ) {\n        stream->flags |= __FILE_ERROR;\n        return 0;\n    }\n\n    if ( ( j == 0 ) ||\n         ( ( j / nmemb ) != size ) ) {\n        return 0;\n    }\n\n    if ( stream->has_ungotten ) {\n        stream->has_ungotten = 0;\n        *( char* )ptr = stream->unget_buffer;\n        ++i;\n\n        if ( j == 1 ) {\n            return 1;\n        }\n    }\n\n    for ( ; i < j; ++i ) {\n        res = fgetc( stream );\n\n        if ( res == EOF ) {\n            return i / size;\n        } else {\n            ( ( unsigned char* )ptr )[ i ] = ( unsigned char )res;\n        }\n    }\n\n    return nmemb;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/freopen.c",
    "content": "\n \n\n#include <stdio.h>\n#include <errno.h>\n#include <fcntl.h>\n#include <unistd.h>\n\nint __parse_mode( const char* mode );\n\nFILE* freopen( const char* path, const char* mode, FILE* stream ) {\n    int flags;\n\n    if ( stream == NULL ) {\n        errno = -EINVAL;\n        return NULL;\n    }\n\n    flags = __parse_mode( mode );\n\n    fflush( stream );\n    close( stream->fd );\n\n    stream->fd = open( path, flags, 0666 );\n\n    if ( stream->fd != -1 ) {\n        stream->flags = 0;\n\n        switch ( flags & 3 ) {\n          case O_RDWR :   stream->flags |= ( __FILE_CAN_READ | __FILE_CAN_WRITE ); break;\n          case O_RDONLY : stream->flags |= __FILE_CAN_READ; break;\n          case O_WRONLY : stream->flags |= __FILE_CAN_WRITE; break;\n        }\n    }\n\n    return stream;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/fseek.c",
    "content": "\n \n\n#include <stdio.h>\n#include <unistd.h>\n\nint fseeko( FILE* stream, off_t offset, int whence ) {\n    fflush( stream );\n\n    stream->buffer_pos = 0;\n    stream->buffer_data_size = 0;\n    stream->flags &= ~( __FILE_EOF | __FILE_ERROR );\n    stream->has_ungotten = 0;\n\n    return ( lseek( stream->fd, offset, whence ) != -1 ? 0 : -1 );\n}\n\nint fseek( FILE* stream, long offset, int whence ) {\n    return fseeko( stream, ( off_t )offset, whence );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/ftell.c",
    "content": "\n \n\n#include <stdio.h>\n#include <unistd.h>\n#include <errno.h>\n#include <limits.h>\n\noff_t ftello( FILE* stream ) {\n    off_t l;\n\n    if ( stream->flags & ( __FILE_EOF | __FILE_ERROR ) ) {\n        return -1;\n    }\n\n    l = lseek( stream->fd, 0, SEEK_CUR );\n\n    if ( l == ( off_t )-1 ) {\n        return -1;\n    }\n\n    if ( stream->flags & __FILE_BUFINPUT ) {\n        return l - ( stream->buffer_data_size - stream->buffer_pos ) - stream->has_ungotten;\n    } else {\n        return l + stream->buffer_pos;\n    }\n}\n\nlong ftell( FILE* stream ) {\n    off_t l;\n\n    l = ftello( stream );\n\n    if ( l > LONG_MAX ) {\n        errno = EOVERFLOW;\n        return -1;\n    }\n\n    return ( long )l;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/fwrite.c",
    "content": "\n \n\n#include <stdio.h>\n#include <unistd.h>\n#include <errno.h>\n#include <sys/types.h>\n\nsize_t fwrite( const void* ptr, size_t size, size_t nmemb, FILE* stream ) {\n    ssize_t res;\n    unsigned long len=size * nmemb;\n    long i;\n\n    if ( ( stream->flags & __FILE_CAN_WRITE ) == 0 ) {\n        stream->flags |= __FILE_ERROR;\n        return 0;\n    }\n\n    if ( ( nmemb == 0 ) ||\n         ( ( len / nmemb ) != size ) ) {\n        return 0;\n    }\n\n    if ( ( len > stream->buffer_size ) || ( stream->flags & __FILE_NOBUF ) ) {\n        if ( fflush( stream ) ) {\n            return 0;\n        }\n\n        res = write( stream->fd, ptr, len );\n    } else {\n        register const unsigned char* c = ptr;\n\n        for ( i = len; i > 0; --i, ++c ) {\n            if ( fputc( *c, stream ) ) {\n                res = len - i;\n                goto abort;\n            }\n        }\n\n        res = len;\n    }\n\n    if ( res < 0 ) {\n        stream->flags |= __FILE_ERROR;\n        return 0;\n    }\n\nabort:\n    return size ? res / size : 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/getc.c",
    "content": "\n \n#include <stdio.h>\n\nint getc( FILE* stream ) {\n    return fgetc( stream );\n}\n\nint gets(char* buf){\n\tfgets(buf,512,stdin); \n\treturn 1;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/perror.c",
    "content": "\n \n\n#include <stdio.h>\n#include <string.h>\n#include <errno.h>\n\nvoid perror( const char* s ) {\n    if ( s != NULL ) {\n        fprintf( stderr, \"%s\", s );\n    }\n\n    fprintf( stderr, \": %s\\n\", strerror( errno ) );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/putc.c",
    "content": "\n \n\n#include <stdarg.h>\n#include <stdio.h>\n#include <unistd.h>\n\nint putc( int c, FILE* stream ) {\n    return fputc( c, stream );\n}\n\n\n\nint \tsupport_vfprintf(FILE* stream, const char* format, va_list ap);\n\nint vfprintf(FILE* stream, const char* format, va_list arg)\n{\n\treturn support_vfprintf( stream, format, arg );\n}\n\nint printf(const char* format, ...)\n{\n\tint rc;\n\tva_list ap;\n\tva_start(ap, format);\n\t\trc = vfprintf( stdout, format, ap );\n\tva_end(ap);\n  return rc;\n}\n\n\nint fprintf(FILE*stream,const char* format, ...)\n{\n\tint rc;\n\tva_list ap;\n\tva_start(ap, format);\n\t\trc = vfprintf(stream, format, ap );\n\tva_end(ap);\n  return rc;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/putchar.c",
    "content": "\n \n\n#include <stdio.h>\n\nint putchar( int c ) {\n    return fputc( c, stdout );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/puts.c",
    "content": "\n \n\n#include <stdio.h>\n\nint puts( const char* s ) {\n    printf(\"%s\\n\", s );\n    //fflush( stdout );\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/remove.c",
    "content": "\n \n\n#include <stdio.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <sys/stat.h>\n\nint remove( const char* path ) {\n  struct stat st;\n\n  if ( stat( path, &st) != 0 ) {\n    return -1;\n  }\n\n  if ( S_ISDIR( st.st_mode ) ) {\n    return rmdir( path );\n  } else {\n    return unlink( path );\n  }\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/rename.c",
    "content": "\n \n\n#include <errno.h>\n#include <unistd.h>\n\n\nint rename( const char* oldpath, const char* newpath ) {\n    printf( \"TODO: rename not yet implemented! (from: %s to: %s)\\n\", oldpath, newpath );\n\n    errno = -ENOSYS;\n\n    return -1;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/rewind.c",
    "content": "\n \n\n#include <stdio.h>\n\nvoid rewind( FILE* stream ) {\n    clearerr( stream );\n    fseek( stream, 0L, SEEK_SET );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/setvbuf.c",
    "content": "\n \n\n#include <stdio.h>\n#include <unistd.h>\n#include <stdlib.h>\n#include <sys/types.h>\n\nstatic int set_flags( FILE* stream, int flags ) {\n    switch ( flags ) {\n        case _IONBF :\n            stream->flags = ( stream->flags & ~( __FILE_BUFLINEWISE ) ) | __FILE_NOBUF;\n            return 0;\n\n        case _IOLBF :\n            stream->flags = ( stream->flags & ~( __FILE_NOBUF ) ) | __FILE_BUFLINEWISE;\n            return 0;\n\n        case _IOFBF :\n            stream->flags = stream->flags & ~( __FILE_NOBUF | __FILE_BUFLINEWISE );\n            return 0;\n\n        default :\n            return -1;\n    }\n}\n\nint setvbuf( FILE* stream, char* buf, int flags, size_t size ) {\n    if ( buf != NULL ) {\n        if ( ( stream->flags & __FILE_DONTFREEBUF ) == 0 ) {\n            free( stream->buffer );\n        }\n\n        stream->buffer = buf;\n        stream->flags |= __FILE_DONTFREEBUF;\n    } else {\n        char *tmp;\n\n        if ( size == 0 ) {\n            return set_flags( stream, flags );\n        }\n\n        tmp = ( char* )malloc( size );\n\n        if ( tmp == NULL ) {\n            return -1;\n        }\n\n        if ( ( stream->flags & __FILE_DONTFREEBUF ) == 0 ) {\n            free( stream->buffer );\n        }\n\n        stream->buffer = tmp;\n        stream->flags &= ~__FILE_DONTFREEBUF;\n    }\n\n    stream->buffer_size = size;\n    stream->buffer_pos = 0;\n    stream->buffer_data_size = 0;\n\n    return set_flags( stream, flags );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/stdio_internal.c",
    "content": "\n \n\n#include <stdio.h>\n\n#include \"stdio_internal.h\"\n\nint __set_stream_flags( FILE* stream, int new_flags ) {\n    if ( ( stream->flags & __FILE_BUFINPUT ) != new_flags) {\n        int error;\n\n        error = fflush( stream );\n\n        stream->flags = ( stream->flags & ~__FILE_BUFINPUT ) | new_flags;\n\n        return error;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/stdio_internal.h",
    "content": "\n \n\n#ifndef _STDIO_INTERNAL_H_\n#define _STDIO_INTERNAL_H_\n\nint __set_stream_flags( FILE* stream, int new_flags );\n\n#endif /* _STDIO_INTERNAL_H_ */\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/streams.c",
    "content": "\n \n\n#include <stdio.h>\n\nstatic char __stdin_buffer[ _IO_BUFSIZE ];\nstatic char __stdout_buffer[ _IO_BUFSIZE ];\nstatic char __stderr_buffer[ _IO_BUFSIZE ];\n\nstatic FILE _stdin = {\n    .fd = 0,\n    .flags = __FILE_CAN_READ | __FILE_DONTFREEBUF | __FILE_BUFLINEWISE | __FILE_BUFINPUT,\n    .buffer = __stdin_buffer,\n    .buffer_pos = 0,\n    .buffer_size = _IO_BUFSIZE,\n    .buffer_data_size = 0,\n    .has_ungotten = 0,\n    .unget_buffer = -1\n};\n\nstatic FILE _stdout = {\n    .fd = 1,\n    .flags = __FILE_CAN_WRITE | __FILE_BUFLINEWISE | __FILE_DONTFREEBUF,\n    .buffer = __stdout_buffer,\n    .buffer_pos = 0,\n    .buffer_size = _IO_BUFSIZE,\n    .buffer_data_size = 0,\n    .has_ungotten = 0,\n    .unget_buffer = -1\n};\n\nstatic FILE _stderr = {\n    .fd = 2,\n    .flags = __FILE_CAN_WRITE | __FILE_DONTFREEBUF | __FILE_NOBUF,\n    .buffer = __stderr_buffer,\n    .buffer_pos = 0,\n    .buffer_size = _IO_BUFSIZE,\n    .buffer_data_size = 0,\n    .has_ungotten = 0,\n    .unget_buffer = -1\n};\n\nFILE* stdin = &_stdin;\nFILE* stdout = &_stdout;\nFILE* stderr = &_stderr;\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/support_bufio.c",
    "content": "\n\n#include <string.h>\n\n/*\n *  This file not a part of the standard C99 library but\n *  I'm keeping the helper functions for printf and\n *  sprintf here.\n *\n *  So this file consists of formatting and printing (to \n *  screen and to a buffer) of strings and numbers.\n *\n */\n\n// ---------------- LENGTH OF NUMBERS AND STRINGS ---\n\nint  bufcon_leni(int num)\n{\n  int p;\n  int sign;\n\n      if ( num < 0 ) \n      {\n        p = -num;\n      \tsign = 1;\n      }\n      else\n      {\n        p = num;\n      \tsign = 0;\n      }\n  \n\tif ( p < 10 ) return sign + 1;\n\tif ( p < 100 ) return sign + 2;\n\tif ( p < 1000 ) return sign + 3;\n\tif ( p < 10000 ) return sign + 4;\n\tif ( p < 100000 ) return sign + 5;\n\tif ( p < 1000000 ) return sign + 6;\n\tif ( p < 10000000 ) return sign + 7;\n\tif ( p < 100000000 ) return sign + 8;\n\tif ( p < 1000000000 ) return sign + 9;\n\n  return 10;\n}\n\n\nint  bufcon_lenui(unsigned int p)\n{\n\n\tif ( p < 10 ) return 1;\n\tif ( p < 100 ) return 2;\n\tif ( p < 1000 ) return 3;\n\tif ( p < 10000 ) return 4;\n\tif ( p < 100000 ) return 5;\n\tif ( p < 1000000 ) return 6;\n\tif ( p < 10000000 ) return 7;\n\tif ( p < 100000000 ) return 8;\n\tif ( p < 1000000000 ) return 9;\n\n  return 10;\n}\n\nint  bufcon_lenp(unsigned int p)\n{\n\tif ( p < 0x10 ) return 1;\n\tif ( p < 0x100 ) return 2;\n\tif ( p < 0x1000 ) return 3;\n\tif ( p < 0x10000 ) return 4;\n\tif ( p < 0x100000 ) return 5;\n\tif ( p < 0x1000000 ) return 6;\n\tif ( p < 0x10000000 ) return 7;\n\n  return 8;\n}\n\nint  bufcon_lenx( unsigned int  p )\n{\n  return (bufcon_lenp( p ) + 2);\n}\n\nint  bufcon_lens( char *s )\n{\n   int i = 0;\n   while ( s[i] != 0 ) i++; \n   return i;\n}\n\n\n\n\n// ---------------- BUFFER MANIPULATION -------------\n\nchar*  bufcon_putc( char *buffer, unsigned char c )\n{\n  unsigned char str[2];\n   \n     str[0] = c;\n     str[1] = 0;\n     \n     strcat( buffer,(const char*)str );\n     \n  return buffer;\n}\n\nchar*  bufcon_puts( char *buffer, char *str )\n{\n  strcat( buffer, str );\n  return buffer;\n}\n\nchar*  bufcon_puti( char *buffer, int num )\n{\n  unsigned int divisor;\n  unsigned int current;\n  unsigned int remainder;\n  unsigned int found;\n \n  if ( num < 0 )\n  {\n    bufcon_putc( buffer, '-' );\n    current = -num;\n  }\n  else current = num;\n \n  divisor = 1000000000;\n  found = 0;\n  \n  while (divisor > 0)\n  {\n    remainder = current % divisor;\n      current = current / divisor;\n\n    if ( current != 0 ) found = 1;\n    if ( found   != 0 ) bufcon_putc( buffer, current + '0' );\n\n    divisor = divisor / 10;\n    current = remainder;\n  }\n\n  if ( found == 0 ) bufcon_putc( buffer, current + '0' );\n\n  return buffer;\n}\n\nchar*  bufcon_putui( char *buffer, unsigned int num )\n{\n  unsigned int divisor;\n  unsigned int current;\n  unsigned int remainder;\n  unsigned int found;\n \n  current = num;\n \n  divisor = 1000000000;\n  found = 0;\n  \n  while (divisor > 0)\n  {\n    remainder = current % divisor;\n      current = current / divisor;\n\n    if ( current != 0 ) found = 1;\n    if ( found   != 0 ) bufcon_putc( buffer, current + '0' );\n\n    divisor = divisor / 10;\n    current = remainder;\n  }\n\n  if ( found == 0 ) bufcon_putc( buffer, current + '0' );\n\n  return buffer;\n}\n\n\nchar*  bufcon_putp( char *buffer, unsigned int p )\n{\n   int offset;\n   unsigned char c;\n   int found = 0;\n\n   for ( offset = 28; offset >= 0; offset -= 4 )\n   {\n     c = (p>>offset) & 0xF;\n     if ( c != 0 ) found = 1;\n     if ( found == 1 )\n     {\n     \tif ( c < 10 ) bufcon_putc( buffer, c + '0' );\n     \t         else bufcon_putc( buffer, c - 10 + 'a' );\n     }\n   }\n   \n   if (found == 0 ) bufcon_putc( buffer, '0' );\n   \n   return buffer;\n}\n\nchar*  bufcon_putx( char *buffer, unsigned int p )\n{\n   int offset;\n   unsigned char c;\n   int found = 0;\n\n   bufcon_puts( buffer, \"0x\" );\n\n   for ( offset = 28; offset >= 0; offset -= 4 )\n   {\n     c = (p>>offset) & 0xF;\n     if ( c != 0 ) found = 1;\n     if ( found == 1 )\n     {\n       if ( c < 10 ) bufcon_putc( buffer, c + '0' );\n        \telse bufcon_putc( buffer, c - 10 + 'a' );\n     }\n   }\n  \n   if (found == 0 ) bufcon_putc( buffer, '0' );\n  \n   return buffer;\n}\n\nchar*  bufcon_putX( char *buffer, unsigned int p )\n{\n   int offset;\n   unsigned char c;\n   int found = 0;\n\n   bufcon_puts( buffer, \"0x\" );\n\n   for ( offset = 28; offset >= 0; offset -= 4 )\n   {\n     c = (p>>offset) & 0xF;\n     if ( c != 0 ) found = 1;\n     if ( found == 1 )\n     {\n        if ( c < 10 ) bufcon_putc( buffer, c + '0' );\n     \t         else bufcon_putc( buffer, c - 10 + 'A' );\n     }\n   }\n   \n   if (found == 0 ) bufcon_putc( buffer, '0' );\n   \n   return buffer;\n}\n\n\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/support_pf.c",
    "content": "\n\n#include <stdarg.h>\n#include <stdio.h>\n#include <string.h>\n\nint  bufcon_leni(int num);\nint  bufcon_lenui(unsigned int p);\nint  bufcon_lenp(unsigned int p);\nint  bufcon_lenx( unsigned int  p );\nint  bufcon_lens( char *s );\nchar*  bufcon_putc( char *buffer, unsigned char c );\nchar*  bufcon_puts( char *buffer, char *str );\nchar*  bufcon_puti( char *buffer, int num );\nchar*  bufcon_putui( char *buffer, unsigned int num );\nchar*  bufcon_putp( char *buffer, unsigned int p );\nchar*  bufcon_putx( char *buffer, unsigned int p );\nchar*  bufcon_putX( char *buffer, unsigned int p );\n\nvoid  supcon_putX( unsigned int num );\nvoid  supcon_putx( unsigned int num );\nvoid  supcon_putp( unsigned int num, char offset );\nvoid  supcon_putui( unsigned int num );\nvoid  supcon_puti( int num );\nvoid supcon_putc( unsigned char c );\nvoid supcon_puts( unsigned char *c );\nint  supcon_lenx( unsigned int  p );\nint  supcon_lenp(unsigned int p);\nint  supcon_lenui(unsigned int p);\nint  supcon_leni(int num);\n\n \nint printf_buffer(int i)\n{\n\tint j;\n\tif ( i <= 0 ) return 0;\n\tfor ( j = 0; j < i; j++) supcon_putc(' ');\n\treturn 0;\n}\n\n\n#define STATE_OFF\t0\n#define STATE_PAD\t1\n\nint \tsupport_vfprintf(FILE* stream, const char* format, va_list ap)\n{\n\tint d, i;\n\tint index;\n\tchar c,  *s;\n\tint modifier;\n\tint state;\n\n\tint off_length;\n\tint pad_length;\n\n\tmodifier = 0;\n\tstate    = STATE_OFF;\n\t\n\toff_length = 0;\n\tpad_length = 0;\n\n\twhile (*format)\n\t{\n\t  switch(*format++) \n\t  {\n\t     case 's':       \n\t\t\tif (modifier == 0) { supcon_putc(*(format-1)); break; }\n\t\t\ts = va_arg(ap, char*);\n\t\t\tprintf_buffer( off_length - strlen(s) );\n\t\t\tsupcon_puts((unsigned char*)s);\n\t\t\tmodifier = 0;\n\t\t\toff_length = 0;\n\t\t\tpad_length = 0;\n\t\t\tstate = STATE_OFF;\n\t\t\tbreak;\n\t     case 'd':        \n\t     case 'i':        \n\t\t\tif (modifier == 0) { supcon_putc(*(format-1)); break; }\n\t\t\ti = va_arg(ap, int);\n\t\t\tprintf_buffer( off_length - supcon_leni(i) - pad_length );\n\t\t\tfor ( index = 0; index < pad_length - supcon_leni(i); index++)\n\t\t\t  supcon_putc( '0' );\n\t\t  \n\t\t\tsupcon_puti(i);\n\t\t\tmodifier = 0;\n\t\t\toff_length = 0;\n\t\t\tpad_length = 0;\n\t\t\tstate = STATE_OFF;\n\t\t\tbreak;\n\t     case 'u':        \n\t\t\tif (modifier == 0) { supcon_putc(*(format-1)); break; }\n\t\t\ti = va_arg(ap, int);\n\t\t\tprintf_buffer( off_length - supcon_lenui(i) - pad_length );\n\t\t\tfor ( index = 0; index < pad_length - supcon_lenui(i); index++)\n\t\t\t  supcon_putc( '0' );\n\t\t\t  \n\t\t\tsupcon_putui(i);\n\t\t\tmodifier = 0;\n\t\t\toff_length = 0;\n\t\t\tpad_length = 0;\n\t\t\tstate = STATE_OFF;\n\t\t\tbreak;\n\t     case 'p':         \n\t\t\tif (modifier == 0) { supcon_putc(*(format-1)); break; }\n\t\t\td = va_arg(ap, int);\n\t\t\tprintf_buffer( off_length - supcon_lenp(d) - pad_length );\n\t\t\tfor ( index = 0; index < pad_length - supcon_lenp(d); index++ )\n\t\t\t   supcon_putc( '0' );\n\t\t\t   \n\t\t\tsupcon_putp(d,'A');\n\t\t\tmodifier = 0;\n\t\t\toff_length = 0;\n\t\t\tpad_length = 0;\n\t\t\tstate = STATE_OFF;\n\t\t\tbreak;\n\t     case 'x':         \n\t\t\tif (modifier == 0) { supcon_putc(*(format-1)); break; }\n\t\t\td = va_arg(ap, int);\n\t\t\t\n\t\t\tprintf_buffer( off_length - supcon_lenx(d) - 2 );\n\t\t\tsupcon_puts((unsigned char*)\"0x\");\n\t\t\tfor ( index = 0; index < pad_length-supcon_lenx(d)-2; index++ )\n\t\t\t   supcon_putc( '0' );\n\t\n\t\t\tsupcon_putx(d);\n\t\t\tmodifier = 0;\n\t\t\toff_length = 0;\n\t\t\tpad_length = 0;\n\t\t\tstate = STATE_OFF;\n\t\t\tbreak;\n\t     case 'l':         \n\t\t\tif (modifier == 0) { supcon_putc(*(format-1)); break; }\n\t\t\tbreak;\n\t     case 'X':         \n\t\t\tif (modifier == 0) { supcon_putc(*(format-1)); break; }\n\t\t\td = va_arg(ap, int);\n\t\t\tprintf_buffer( off_length - supcon_lenx(d) - 2 );\n\t\t\tsupcon_puts((unsigned char*)\"0x\");\n\t\t\tfor ( index = 0; index < pad_length-supcon_lenx(d)-2; index++ )\n\t\t\t   supcon_putc( '0' );\n\t\t\t   \n\t\t\tsupcon_putX(d);\n\t\t\t\n\t\t\tmodifier = 0;\n\t\t\toff_length = 0;\n\t\t\tpad_length = 0;\n\t\t\tstate = STATE_OFF;\n\t\t\tbreak;\n\t     case 'c':          \n\t\t\tif (modifier == 0) { supcon_putc(*(format-1)); break; }\n\t\t\tc = (char) va_arg(ap, int);\n\t\t\tprintf_buffer( off_length - 1 );\n\t\t\tsupcon_putc(c);\n\t\t\tmodifier = 0;\n\t\t\toff_length = 0;\n\t\t\tpad_length = 0;\n\t\t\tstate = STATE_OFF;\n\t\t\tbreak;\n\t     case '%':\n\t\t\tmodifier = 1;\n\t\t\toff_length = 0;\n\t\t\tpad_length = 0;\n\t\t\tstate = STATE_OFF;\n\t\t\tbreak;\n\t     case '.':\n\t\t\tif (modifier == 0) { supcon_putc(*(format-1)); break; }\n\t\t\tif ( state == STATE_PAD ) \n\t\t\t{\n\t\t\t\tmodifier = 0;\n\t\t\t\toff_length = 0;\n\t\t\t\tpad_length = 0;\n\t\t\t\tstate = STATE_OFF;\n\t\t\t\tbreak; \n\t\t\t}\n\t\n\t\t\tstate = STATE_PAD;\n\t\t\tbreak;\n\t     \n\t     case '0':\n\t     case '1':\n\t     case '2':\n\t     case '3':\n\t     case '4':\n\t     case '5':\n\t     case '6':\n\t     case '7':\n\t     case '8':\n\t     case '9':\n\t   \t\tif ( modifier != 1 )\n\t\t\t{\n\t\t\t  supcon_putc( *(format-1) );\n\t  \t  \t  modifier = 0;\n\t\t\t  off_length = 0;\n\t\t\t  pad_length = 0;\n\t\t\t  state = STATE_OFF;\n\t\t\t  break;\n\t\t\t}\n\t\t\tif ( state == STATE_OFF )\n\t\t\t  off_length = off_length * 10 + ((*(format-1)) - '0');\n\t\t\tif ( state == STATE_PAD )\n\t\t\t  pad_length = pad_length * 10 + ((*(format-1)) - '0');\n\t     \t\tbreak;\n\n\t     default:     \n\t\t\tprintf_buffer( off_length - 1 );\n\t\t\tsupcon_putc( *(format-1) );\n\t\t\tmodifier = 0;\n\t\t\toff_length = 0;\n\t\t\tpad_length = 0;\n\t\t\tstate = STATE_OFF;\n\t\t\tbreak;\n\t }\n\t}\n   return 0;\n}\n\n// ---------------------------------\n\n\nint sprintf_buffer(char *s, int i)\n{\n\tint j;\n\tif ( i <= 0 ) return 0;\n\tfor ( j = 0; j < i; j++) strcat(s,\" \");\n\treturn 0;\n}\n\nint vsnprintf(char* str, size_t size, const char *format, va_list arg_ptr) {\n\treturn support_vsprintf(str,format,arg_ptr);\n}\n\nint snprintf(char *str,size_t size,const char *format,...)\n{\n  int n;\n  va_list arg_ptr;\n  va_start(arg_ptr, format);\n  n=vsnprintf(str,size,format,arg_ptr);\n  va_end (arg_ptr);\n  return n;\n}\n\nint \tsupport_vsprintf(char* buffer, const char* format, va_list ap)\n{\n\tint d, i;\n\tint index;\n\tchar c,  *s;\n\tint modifier;\n\tint state;\n\n\tint off_length;\n\tint pad_length;\n\n\tmodifier = 0;\n\tstate    = STATE_OFF;\n\t\n\toff_length = 0;\n\tpad_length = 0;\n\n\tbuffer[0] = 0;\n\n\twhile (*format)\n\t{\n\t  switch(*format++) \n\t  {\n\t     case 's':       \n\t\tif (modifier == 0) { bufcon_putc( buffer, *(format-1)); break; }\n\t\ts = va_arg(ap, char*);\n\t\tsprintf_buffer( buffer, off_length - strlen(s) );\n\t\tbufcon_puts( buffer, s);\n\t\tmodifier = 0;\n\t\toff_length = 0;\n\t\tpad_length = 0;\n\t\tstate = STATE_OFF;\n\t\tbreak;\n\t     case 'd':        \n\t     case 'i':        \n\t\tif (modifier == 0) { bufcon_putc( buffer, *(format-1)); break; }\n\t\ti = va_arg(ap, int);\n\t\tsprintf_buffer( buffer, off_length - supcon_leni(i) - pad_length );\n\t\tfor ( index = 0; index < pad_length - supcon_leni(i); index++)\n\t\t  bufcon_putc( buffer, '0' );\n\t\t  \n\t\tbufcon_puti(buffer, i);\n\t\tmodifier = 0;\n\t\toff_length = 0;\n\t\tpad_length = 0;\n\t\tstate = STATE_OFF;\n\t\tbreak;\n\t     case 'u':        \n\t\tif (modifier == 0) { bufcon_putc( buffer, *(format-1)); break; }\n\t\ti = va_arg(ap, int);\n\t\tsprintf_buffer( buffer, off_length - supcon_lenui(i) - pad_length );\n\t\tfor ( index = 0; index < pad_length - supcon_lenui(i); index++)\n\t\t  bufcon_putc( buffer, '0' );\n\t\t  \n\t\tbufcon_putui( buffer, i);\n\t\tmodifier = 0;\n\t\toff_length = 0;\n\t\tpad_length = 0;\n\t\tstate = STATE_OFF;\n\t\tbreak;\n\t     case 'p':         \n\t\tif (modifier == 0) { bufcon_putc( buffer, *(format-1)); break; }\n\t\td = va_arg(ap, int);\n\t\tsprintf_buffer( buffer, off_length - supcon_lenp(d) - pad_length );\n\t\tfor ( index = 0; index < pad_length - supcon_lenp(d); index++ )\n\t\t   bufcon_putc( buffer, '0' );\n\t\t   \n\t\tbufcon_putp( buffer, d);\n\t\tmodifier = 0;\n\t\toff_length = 0;\n\t\tpad_length = 0;\n\t\tstate = STATE_OFF;\n\t\tbreak;\n\n\t     case 'l':         \n\t\t\tif (modifier == 0) { supcon_putc(*(format-1)); break; }\n\t\t\tbreak;\n\n\t     case 'x':         \n\t\tif (modifier == 0) { bufcon_putc( buffer, *(format-1)); break; }\n\t\td = va_arg(ap, int);\n\t\t\n\t\tsprintf_buffer( buffer, off_length - supcon_lenx(d) - 2 );\n\t\t/*bufcon_puts(buffer,\"0x\");\n\t\tfor ( index = 0; index < pad_length-supcon_lenx(d)-2; index++ )\n\t\t   bufcon_putc( buffer, '0' );*/\n\n\t\tbufcon_putx( buffer, d);\n\t\tmodifier = 0;\n\t\toff_length = 0;\n\t\tpad_length = 0;\n\t\tstate = STATE_OFF;\n\t\tbreak;\n\t     case 'X':         \n\t\tif (modifier == 0) { bufcon_putc( buffer, *(format-1)); break; }\n\t\td = va_arg(ap, int);\n\t\tsprintf_buffer( buffer, off_length - supcon_lenx(d) - 2 );\n\t\t/*bufcon_puts(buffer,\"0x\");\n\t\tfor ( index = 0; index < pad_length-supcon_lenx(d)-2; index++ )\n\t\t   bufcon_putc( buffer, '0' );*/\n\t\t   \n\t\tbufcon_putX(buffer,d);\n\t\t\n\t\tmodifier = 0;\n\t\toff_length = 0;\n\t\tpad_length = 0;\n\t\tstate = STATE_OFF;\n\t\tbreak;\n\t     case 'c':          \n\t\tif (modifier == 0) { bufcon_putc( buffer, *(format-1)); break; }\n\t\tc = (char) va_arg(ap, int);\n\t\tsprintf_buffer( buffer, off_length - 1 );\n\t\tbufcon_putc(buffer, c);\n\t\tmodifier = 0;\n\t\toff_length = 0;\n\t\tpad_length = 0;\n\t\tstate = STATE_OFF;\n\t\tbreak;\n\t     case '%':\n\t\tmodifier = 1;\n\t\toff_length = 0;\n\t\tpad_length = 0;\n\t\tstate = STATE_OFF;\n\t\tbreak;\n\t     case '.':\n\t\tif (modifier == 0) { bufcon_putc( buffer, *(format-1)); break; }\n\t\tif ( state == STATE_PAD ) \n\t\t{\n\t\t\tmodifier = 0;\n\t\t\toff_length = 0;\n\t\t\tpad_length = 0;\n\t\t\tstate = STATE_OFF;\n\t\t\tbreak; \n\t\t}\n\n\t\tstate = STATE_PAD;\n\t\tbreak;\n\t     \n\t     case '0':\n\t     case '1':\n\t     case '2':\n\t     case '3':\n\t     case '4':\n\t     case '5':\n\t     case '6':\n\t     case '7':\n\t     case '8':\n\t     case '9':\n\t     \t\tif ( modifier != 1 )\n\t\t\t{\n\t\t\t  bufcon_putc( buffer, *(format-1) );\n\t  \t  \t  modifier = 0;\n\t\t\t  off_length = 0;\n\t\t\t  pad_length = 0;\n\t\t\t  state = STATE_OFF;\n\t\t\t  break;\n\t\t\t}\n\t\t\tif ( state == STATE_OFF )\n\t\t\t  off_length = off_length * 10 + ((*(format-1)) - '0');\n\t\t\tif ( state == STATE_PAD )\n\t\t\t  pad_length = pad_length * 10 + ((*(format-1)) - '0');\n\t     \t\tbreak;\n\t     \n\t     default:     \n\t\tsprintf_buffer( buffer, off_length - 1 );\n\t\tbufcon_putc( buffer, *(format-1) );\n\t\tmodifier = 0;\n\t\toff_length = 0;\n\t\tpad_length = 0;\n\t\tstate = STATE_OFF;\n\t\tbreak;\n\t }\n\t}\n   return 0;\n}\n\n\n\n\n \n\n\n\n\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/support_supcon.c",
    "content": "\n#include <string.h>\n#include <stdio.h>\n\n// ---------------- LENGTH OF NUMBERS AND STRINGS ---\n\nint  supcon_leni(int num)\n{\n  int p;\n  int sign;\n\n      if ( num < 0 ) \n      {\n        p = -num;\n      \tsign = 1;\n      }\n      else\n      {\n        p = num;\n      \tsign = 0;\n      }\n  \n\tif ( p < 10 ) return sign + 1;\n\tif ( p < 100 ) return sign + 2;\n\tif ( p < 1000 ) return sign + 3;\n\tif ( p < 10000 ) return sign + 4;\n\tif ( p < 100000 ) return sign + 5;\n\tif ( p < 1000000 ) return sign + 6;\n\tif ( p < 10000000 ) return sign + 7;\n\tif ( p < 100000000 ) return sign + 8;\n\tif ( p < 1000000000 ) return sign + 9;\n\n  return 10;\n}\n\n\nint  supcon_lenui(unsigned int p)\n{\n\n\tif ( p < 10 ) return 1;\n\tif ( p < 100 ) return 2;\n\tif ( p < 1000 ) return 3;\n\tif ( p < 10000 ) return 4;\n\tif ( p < 100000 ) return 5;\n\tif ( p < 1000000 ) return 6;\n\tif ( p < 10000000 ) return 7;\n\tif ( p < 100000000 ) return 8;\n\tif ( p < 1000000000 ) return 9;\n\t\n  return 10;\n}\n\nint  supcon_lenp(unsigned int p)\n{\n\tif ( p < 0x10 ) return 1;\n\tif ( p < 0x100 ) return 2;\n\tif ( p < 0x1000 ) return 3;\n\tif ( p < 0x10000 ) return 4;\n\tif ( p < 0x100000 ) return 5;\n\tif ( p < 0x1000000 ) return 6;\n\tif ( p < 0x10000000 ) return 7;\n\n  return 8;\n}\n\nint  supcon_lenx( unsigned int  p )\n{\n  return (supcon_lenp( p ));\n}\n\n\n\n// ---------------------- USEFUL STUFF ---------------------------------\n\nvoid supcon_puts( unsigned char *c )\n{\n\tfputs((const char *)c,stdout);\n}\n\nvoid supcon_putc( unsigned char c )\n{\n\tchar buffer[2];\n\t\t buffer[0] = c;\n\t\t buffer[1] = 0;\n\n\tfputs((const char *)buffer,stdout);\n}\n\n\nvoid  supcon_puti( int num )\n{\n  int sign;\n  int temp;\n  char buffer[ 128 ];\t// You're generous. \n  int position = 126;\n\n  // Short circuit unnecessary work.\n  if ( num == 0 ) \n  {\n\tfputs(\"0\",stdout);\n\treturn;\n  }\n\n\n  // Prepare to do work.\n  if ( num < 0 )\n  {\n\tsign = 1;\n\ttemp = -num;\n  }\n  else\n  {\n\tsign = 0;\n\ttemp = num;\n  }\n  \n\n  buffer[127] = 0;\n  \n  // Now reduce it.\n  while ( temp > 0 )\n  {\n\tbuffer[ position-- ] = '0' + (temp % 10);\n\ttemp = temp / 10;\n  }\n\t\t  \n  if ( sign == 1 ) buffer[ position-- ] = '-';\n  \n  // Now print it.\n  fputs(buffer + position + 1 ,stdout);\n}\n\nvoid  supcon_putui( unsigned int num )\n{\n  char buffer[ 128 ];\t// You're generous. \n  int position = 126;\n  unsigned int temp = num;\n\n  // Short circuit unnecessary work.\n  if ( num == 0 ) \n  {\n\t  fputs(\"0\",stdout);\n\treturn;\n  }\n\n  buffer[127] = 0;\n  \n  // Now reduce it.\n  while ( temp > 0 )\n  {\n\tbuffer[ position-- ] = '0' + (temp % 10);\n\ttemp = temp / 10;\n  }\n\t\t  \n  // Now print it.\n  fputs(buffer + position + 1 ,stdout);\n}\n\n\nvoid  supcon_putp( unsigned int num, char offset )\n{\n  char buffer[ 128 ];\t// You're generous. \n  int position = 126;\n  unsigned int temp = num;\n  int value;\n\n  // Short circuit unnecessary work.\n  if ( num == 0 ) \n  {\n\tfputs(\"0\",stdout);\n\treturn;\n  }\n\n  buffer[127] = 0;\n  \n  // Now reduce it.\n  while ( temp > 0 )\n  {\n\tvalue = temp % 16;\n\tif ( value < 10 ) buffer[ position-- ] = '0' + value;\n\t\t\t\telse  buffer[ position-- ] = offset - 10 + value;\t\n\ttemp = temp / 16;\n  }\n\t\t  \n  // Now print it.\n    fputs(buffer + position + 1 ,stdout);\n\n}\n\nvoid  supcon_putx( unsigned int num )\n{\n   supcon_putp( num, 'a' );\n}\n\nvoid  supcon_putX( unsigned int num )\n{\n   supcon_putp( num, 'A' );\n}\n\n\n\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdio/ungetc.c",
    "content": "\n \n#include <stdio.h>\n\nint ungetc( int c, FILE* stream ) {\n    if ( ( stream->has_ungotten ) ||\n         ( c < 0 ) ||\n         ( c > 255 ) ) {\n        return EOF;\n    }\n\n    stream->has_ungotten = 1;\n    stream->unget_buffer = ( unsigned char )c;\n    stream->flags &= ~( __FILE_EOF | __FILE_ERROR );\n\n    return c;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdlib/abort.c",
    "content": "\n \n\n#include <stdio.h>\n#include <stdlib.h>\n#include <unistd.h>\n\nvoid abort( void ) {\n    fprintf( stderr, \"Application aborted!\\n\" );\n    exit( -1 );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdlib/abs.c",
    "content": "\n \n\n#include <stdlib.h>\n\nint abs( int j ) {\n    if ( j < 0 ) {\n        return -j;\n    } else {\n        return j;\n    }\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdlib/atof.c",
    "content": "\n \n\n#include <stdlib.h>\n\ndouble atof( const char* s ) {\n    return strtod( s, ( char** )NULL );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdlib/atoi.c",
    "content": "\n \n\n#include <ctype.h>\n#include <stdlib.h>\n\nint atoi( const char* s ) {\n    int v = 0;\n    int sign = 0;\n\n    while ( ( *s == ' ' ) || ( ( unsigned int )( *s - 9 ) < 5u ) ) {\n        ++s;\n    }\n\n    switch ( *s ) {\n        case '-' : sign = -1;\n        case '+' : ++s;\n    }\n\n    while ( ( unsigned int )( *s - '0' ) < 10u ) {\n        v = v * 10 + *s - '0';\n        ++s;\n    }\n\n    return sign ? -v : v;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdlib/atol.c",
    "content": "\n \n\n#include <ctype.h>\n#include <stdlib.h>\n\nlong atol( const char* s ) {\n    long v = 0;\n    int sign = 0;\n\n    while ( ( *s == ' ' ) || ( ( unsigned int )( *s - 9 ) < 5u ) ) {\n        ++s;\n    }\n\n    switch ( *s ) {\n        case '-' : sign = -1;\n        case '+' : ++s;\n    }\n\n    while ( ( unsigned int )( *s - '0' ) < 10u ) {\n        v = v * 10 + *s - '0';\n        ++s;\n    }\n\n    return sign ? -v : v;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdlib/atoll.c",
    "content": "\n \n\n#include <ctype.h>\n#include <stdlib.h>\n\nlong long int atoll( const char* s ) {\n    long long int v = 0;\n    int sign = 1;\n\n    while ( *s == ' '  ||  ( unsigned int )( *s - 9 ) < 5u ) {\n        ++s;\n    }\n\n    switch ( *s ) {\n        case '-': sign = -1;\n        case '+': ++s;\n    }\n\n    while ( ( unsigned int )( *s - '0' ) < 10u ) {\n        v=  v * 10 + *s - '0';\n        ++s;\n    }\n\n    return sign == -1 ? -v : v;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdlib/bsearch.c",
    "content": "\n \n#include <stdlib.h>\n\nvoid* bsearch( const void* key, const void* base, size_t nmemb, size_t size, int ( *compare )( const void*, const void* ) ) {\n    size_t m;\n\n    while ( nmemb ) {\n        int tmp;\n        void* p;\n\n        m = nmemb / 2;\n        p = ( void* )( ( ( const char* )base ) + ( m * size ) );\n\n        if ( ( tmp = ( *compare )( key, p ) ) < 0 ) {\n            nmemb = m;\n        } else if ( tmp > 0 ) {\n            base = p + size;\n            nmemb -= m + 1;\n        } else {\n          return p;\n        }\n    }\n\n    return NULL;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdlib/getenv.c",
    "content": "\n \n\n#include <stdlib.h>\n#include <string.h>\n\nextern char** environ;\n\nchar* getenv( const char* name ) {\n\treturn NULL;\n\t\n    int i;\n    size_t length;\n    size_t name_length;\n\n    name_length = strlen( name );\n\n    for ( i = 0; environ[ i ] != NULL; i++ ) {\n        length = strlen( environ[ i ] );\n\n        if ( length < ( name_length + 1 ) ) {\n            continue;\n        }\n\n        if ( ( strncmp( environ[ i ], name, name_length ) == 0 ) &&\n             ( environ[ i ][ name_length ] == '=' ) ) {\n            return &environ[ i ][ name_length + 1 ];\n        }\n    }\n\n    return NULL;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdlib/labs.c",
    "content": "\n \n\n#include <stdlib.h>\n\nlong labs( long j ) {\n    if ( j < 0 ) {\n        return -j;\n    } else {\n        return j;\n    }\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdlib/llabs.c",
    "content": "\n \n\n#include <stdlib.h>\n\nlong long llabs( long long j ) {\n    if ( j < 0 ) {\n        return -j;\n    } else {\n        return j;\n    }\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdlib/malloc.c",
    "content": "\n \n#include <stdlib.h>\n#include <stdio.h>\n\n#define MALLOC_MINSIZE\t16\n#define PAGESIZE\t4096\n\nstruct malloc_header {\n\tunsigned long size:31;\t/* taille totale de l'enregistrement */\n\tunsigned long used:1;\n} __attribute__ ((packed));\n\n\nextern char *b_heap;\nextern char *e_heap;\n\n\n\nchar *b_heap = 0;\t/* pointe sur le debut du heap */\nchar *e_heap = 0;\t\t/* pointe sur le sommet du heap */\n\nvoid* sbrk( int increment );\n\nvoid* malloc(unsigned long size)\n{\n\tunsigned long realsize;\t\t/* taille totale de l'enregistrement */\n\tunsigned long i;\n\tstruct malloc_header *bl, *newbl;\n\n\trealsize = sizeof(struct malloc_header) + size;\n\tif ((i = realsize % MALLOC_MINSIZE)) {\n\t\trealsize = realsize - i + MALLOC_MINSIZE;\n\t}\n\n\t/* \n\t * On recherche un bloc libre de 'size' octets en parcourant tous les\n\t * blocs du heap a partir du debut\n\t */\n\tif (b_heap == 0) {\t/* Initialisation du heap */\n\t\tif ((b_heap = sbrk(realsize)) == (char*) -1) \n\t\t\treturn (char*) -1;\n\n\t\te_heap = b_heap + realsize;;\n\n\t\tbl = (struct malloc_header *) b_heap;\n\t\tbl->size = realsize;\n\t\tbl->used = 0;\n\t}\n\telse {\n\t\tbl = (struct malloc_header *) b_heap;\n\n\t\twhile (bl->used || bl->size < realsize) {\n\t\t\tbl = (struct malloc_header *) ((char *) bl + bl->size);\n\n\t\t\tif (bl == (struct malloc_header *) e_heap) {\n\t\t\t\tif ((int)(e_heap = sbrk(realsize)) < 0) {\n\t\t\t\t\treturn (char*) -1;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tbl = (struct malloc_header *) e_heap;\n\t\t\t\t\tbl->size = realsize;\n\t\t\t\t\tbl->used = 0;\n\t\t\t\t\te_heap += realsize;\n\t\t\t\t}\n\t\t\t} else if (bl > (struct malloc_header *) e_heap) {\n\t\t\t\treturn (char *) -1;\t/* BUG ! */ \n\t\t\t}\n\t\t}\n\t}\n\n\t/* \n\t * On a trouve un bloc libre dont la taille est >= 'size'\n\t * On fait de sorte que chaque bloc ait une taille minimale\n\t */\n\tif (bl->size - realsize < MALLOC_MINSIZE) {\n\t\tbl->used = 1;\n\t} else {\n\t\tnewbl = (struct malloc_header *) ((char *) bl + realsize);\n\t\tnewbl->size = bl->size - realsize;\n\t\tnewbl->used = 0;\n\n\t\tbl->size = realsize;\n\t\tbl->used = 1;\n\t}\n\t\n\t/* retourne un pointeur sur la zone de donnees */\n\treturn (char *) bl + sizeof(struct malloc_header);\n}\n\t\n\nvoid free(void *v_addr)\n{\n\tstruct malloc_header *bl, *nextbl;\n\n\t/* Calcul du debut du bloc */\n\tbl = (struct malloc_header *) (v_addr - sizeof(struct malloc_header));\n\n\t/* \n\t * On merge le bloc nouvellement libere avec le bloc suivant ci celui-ci\n\t * est aussi libre\n\t */\n\twhile ((nextbl = (struct malloc_header *) ((char *) bl + bl->size))\n             && nextbl < (struct malloc_header *) e_heap\n\t     && nextbl->used == 0) \n\t\t\tbl->size += nextbl->size;\n\n\t/* On libere le bloc alloue */\n\tbl->used = 0;\n}\n\n\nvoid* realloc(void* ptr,size_t nsize)\n{\n\tif (ptr==0){\n\t\treturn malloc(nsize);\n\t}\n\telse if (nsize==0)\n\t\treturn ptr;\n\t\t\n\tstruct malloc_header *bl=ptr-sizeof(struct malloc_header);\n\tunsigned long size=bl->size;\n\tvoid *newptr=malloc(size+nsize);\n\tmemcpy(newptr,ptr,size);\n\tfree(ptr);\n\treturn newptr;\n}\n\t\nvoid* calloc(size_t n1,size_t n2){\n\treturn malloc(n1*n2);\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdlib/mkstemp.c",
    "content": "#include <unistd.h>\n#include <fcntl.h>\n#include <string.h>\n#include <stdlib.h>\n#include <errno.h>\n\n#ifndef O_NOFOLLOW\n#define O_NOFOLLOW 0\n#endif\n\nint mkstemp( char* template ) {\n    int i;\n    char* tmp;\n    int result;\n    unsigned int rnd;\n\n    tmp = template + strlen( template ) - 6;\n\n    if ( tmp < template ) {\n        errno = EINVAL;\n        return -1;\n    }\n\n    for ( i = 0; i < 6; i++ ) {\n        if ( tmp[ i ] != 'X' ) {\n            errno = EINVAL;\n            return -1;\n        }\n    }\n\n    for ( ;; ) {\n        for ( i = 0; i < 6; i++ ) {\n            int hexdigit;\n\n            rnd = random();\n            hexdigit = ( rnd >> ( i * 5 ) ) & 0x1F;\n            tmp[ i ] = hexdigit > 9 ? ( hexdigit + 'a' - 10 ) : ( hexdigit + '0' );\n        }\n\n        result = open( template, O_CREAT | O_RDWR | O_EXCL | O_NOFOLLOW, 0600 );\n\n        if ( ( result >= 0 ) ||\n             ( errno != EEXIST ) ) {\n            break;\n        }\n    }\n\n    return result;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdlib/mktemp.c",
    "content": "#include <unistd.h>\n#include <fcntl.h>\n#include <string.h>\n#include <stdlib.h>\n\nchar* mktemp( char* template ) {\n    int fd;\n\n    fd = mkstemp( template );\n\n    if ( fd < 0 ) {\n        return NULL;\n    }\n\n    close( fd );\n\n    unlink( template );\n\n    return template;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdlib/qsort.c",
    "content": "\n \n\n#include <stdlib.h>\n#include <sys/types.h>\n\nstatic void exch(char* base,size_t size,size_t a,size_t b) {\n  char* x=base+a*size;\n  char* y=base+b*size;\n  while (size) {\n    char z=*x;\n    *x=*y;\n    *y=z;\n    --size; ++x; ++y;\n  }\n}\n\n/* Quicksort with 3-way partitioning, ala Sedgewick */\n/* Blame him for the scary variable names */\n/* http://www.cs.princeton.edu/~rs/talks/QuicksortIsOptimal.pdf */\nstatic void quicksort(char* base,size_t size,ssize_t l,ssize_t r,\n          int (*compar)(const void*,const void*)) {\n  ssize_t i=l-1, j=r, p=l-1, q=r, k;\n  char* v=base+r*size;\n  if (r<=l) return;\n  for (;;) {\n    while (++i != r && compar(base+i*size,v)<0) ;\n    while (compar(v,base+(--j)*size)<0) if (j == l) break;\n    if (i >= j) break;\n    exch(base,size,i,j);\n    if (compar(base+i*size,v)==0) exch(base,size,++p,i);\n    if (compar(v,base+j*size)==0) exch(base,size,j,--q);\n  }\n  exch(base,size,i,r); j = i-1; ++i;\n  for (k=l; k<p; k++, j--) exch(base,size,k,j);\n  for (k=r-1; k>q; k--, i++) exch(base,size,i,k);\n  quicksort(base,size,l,j,compar);\n  quicksort(base,size,i,r,compar);\n}\n\nvoid qsort(void* base,size_t nmemb,size_t size,int (*compar)(const void*,const void*)) {\n  /* check for integer overflows */\n  if (nmemb >= (((size_t)-1)>>1) ||\n      size >= (((size_t)-1)>>1)) return;\n#if 0\n  if (sizeof(size_t) < sizeof(unsigned long long)) {\n    if ((unsigned long long)size * nmemb > (size_t)-1) return;\n  } else {\n    if (size*nmemb/nmemb != size) return;\n  }\n#endif\n  if (nmemb>1)\n    quicksort(base,size,0,nmemb-1,compar);\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdlib/rand.c",
    "content": "\n \n\n#include <stdlib.h>\n\nunsigned int _seed2 = 0xDEADBEEF;\n\nint rand( void ) {\n    unsigned int next = _seed2;\n    unsigned int result;\n\n    next *= 1103515245;\n    next += 12345;\n    result = ( unsigned int  ) ( next / 65536 ) % 2048;\n\n    next *= 1103515245;\n    next += 12345;\n    result <<= 10;\n    result ^= ( unsigned int ) ( next / 65536 ) % 1024;\n\n    next *= 1103515245;\n    next += 12345;\n    result <<= 10;\n    result ^= ( unsigned int ) ( next / 65536 ) % 1024;\n\n    _seed2 = next;\n\n    return result;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdlib/random.c",
    "content": "\n \n\nunsigned int _seed = 0xDEADBEEF;\n\nlong int random( void ) {\n    unsigned int next = _seed;\n    unsigned long int result;\n\n    next *= 1103515245;\n    next += 12345;\n    result = ( unsigned int  ) ( next / 65536 ) % 2048;\n\n    next *= 1103515245;\n    next += 12345;\n    result <<= 10;\n    result ^= ( unsigned int ) ( next / 65536 ) % 1024;\n\n    next *= 1103515245;\n    next += 12345;\n    result <<= 10;\n    result ^= ( unsigned int ) ( next / 65536 ) % 1024;\n\n    _seed = next;\n\n    return result;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdlib/srand.c",
    "content": "\n \n\n#include <stdlib.h>\n\nextern unsigned int _seed2;\n\nvoid srand(unsigned int seed){\n    _seed2 = seed;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdlib/srandom.c",
    "content": "\n \n\n#include <stdlib.h>\n\nextern unsigned int _seed;\n\nvoid srandom(unsigned int seed){\n    _seed = seed;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdlib/strtod.c",
    "content": "\n \n\n#include <string.h>\n#include <stdlib.h>\n#include <ctype.h>\n\ndouble strtod( const char* s, char** endptr ) {\n    register const char*  p     = s;\n    register long double  value = 0.L;\n    int                   sign  = +1;\n    long double           factor;\n    unsigned int          expo;\n\n    while ( isspace(*p) ) {\n        p++;\n    }\n\n    switch ( *p ) {\n        case '-': sign = -1;\n        case '+': p++;\n        default : break;\n    }\n\n    while ( (unsigned int)(*p - '0') < 10u )\n        value = value*10 + (*p++ - '0');\n\n    if ( *p == '.' ) {\n        factor = 1.;\n\n        p++;\n        while ( (unsigned int)(*p - '0') < 10u ) {\n            factor *= 0.1;\n            value  += (*p++ - '0') * factor;\n        }\n    }\n\n    if ( (*p | 32) == 'e' ) {\n        expo   = 0;\n        factor = 10.L;\n\n        switch (*++p) {\n        case '-': factor = 0.1;\n        case '+': p++;\n                  break;\n        case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':\n                  break;\n        default : value = 0.L;\n                  p     = s;\n                  goto done;\n        }\n\n        while ( (unsigned int)(*p - '0') < 10u )\n            expo = 10 * expo + (*p++ - '0');\n\n        while ( 1 ) {\n            if ( expo & 1 )\n                value *= factor;\n            if ( (expo >>= 1) == 0 )\n                break;\n            factor *= factor;\n        }\n    }\n\ndone:\n    if ( endptr != NULL )\n        *endptr = (char*)p;\n\n    return value * sign;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdlib/strtol.c",
    "content": "\n \n\n#include <ctype.h>\n#include <errno.h>\n#include <limits.h>\n#include <stdlib.h>\n\n#if __WORDSIZE == 64\n#define ABS_LONG_MIN 9223372036854775808UL\n#else\n#define ABS_LONG_MIN 2147483648UL\n#endif\n\nlong int strtol( const char* nptr, char** endptr, int base ) {\n    int neg = 0;\n    unsigned long int v;\n    const char* orig = nptr;\n\n    while ( isspace( *nptr ) ) {\n        nptr++;\n    }\n\n    if ( ( *nptr == '-' ) && ( isalnum( nptr[ 1 ] ) ) ) {\n        neg = -1;\n        ++nptr;\n    }\n\n    v = strtoul( nptr, endptr, base );\n\n    if ( ( endptr ) && ( *endptr == nptr) ) {\n        *endptr = ( char* )orig;\n    }\n\n    if ( v >= ABS_LONG_MIN ) {\n        if ( ( v == ABS_LONG_MIN ) && ( neg ) ) {\n            return v;\n        }\n\n        return ( neg ? LONG_MIN : LONG_MAX );\n    }\n\n    return ( neg ? -v : v );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdlib/strtoll.c",
    "content": "\n \n\n#include <ctype.h>\n#include <stdlib.h>\n#include <limits.h>\n#include <errno.h>\n#include <inttypes.h>\n\nlong long int strtoll( const char* nptr, char** endptr, int base ) {\n  int neg = 0;\n  unsigned long long int v;\n  const char* orig = nptr;\n\n  while ( isspace( *nptr ) ) {\n      nptr++;\n  }\n\n  if ( *nptr == '-' && isalnum( nptr[ 1 ] ) ) {\n      neg = -1;\n      nptr++;\n  }\n\n  v = strtoull( nptr, endptr, base );\n\n  if ( endptr && *endptr == nptr ) {\n      *endptr = ( char* )orig;\n  }\n\n  if ( v > LLONG_MAX ) {\n    if ( v == 0x8000000000000000ull && neg ) {\n      errno = 0;\n      return v;\n    }\n\n    errno=ERANGE;\n\n    return ( neg ? LLONG_MIN : LLONG_MAX );\n  }\n\n  return ( neg ? -v : v );\n}\n\nintmax_t strtoimax( const char* nptr, char** endptr, int base )\t__attribute__(( alias( \"strtoll\" ) ));\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdlib/strtoul.c",
    "content": "\n \n\n#include <ctype.h>\n#include <stdlib.h>\n#include <errno.h>\n#include <limits.h>\n\nunsigned long int strtoul( const char* ptr, char** endptr, int base ) {\n    int neg = 0, overflow = 0;\n    unsigned long int v=0;\n    const char* orig;\n    const char* nptr = ptr;\n\n    while ( isspace( *nptr ) ) {\n        ++nptr;\n    }\n\n    if ( *nptr == '-') {\n        neg = 1;\n        nptr++;\n    } else if ( *nptr == '+' ) {\n        ++nptr;\n    }\n\n    orig = nptr;\n\n    if ( ( base == 16 ) && ( nptr[ 0 ] == '0' ) ) {\n        goto skip0x;\n    }\n\n    if ( base ) {\n        register unsigned int b = base - 2;\n\n        if ( b > 34 ) {\n            return 0;\n        }\n    } else {\n        if ( *nptr == '0' ) {\n            base = 8;\n\nskip0x:\n            if ( ( nptr[ 1 ] == 'x' || nptr[ 1 ] == 'X' ) && isxdigit( nptr[ 2 ] ) ) {\n                nptr += 2;\n                base = 16;\n            }\n        } else {\n            base = 10;\n        }\n    }\n\n    while ( *nptr ) {\n        register unsigned char c = *nptr;\n\n        c = ( c >= 'a' ? c - 'a' + 10 : c >= 'A' ? c - 'A' + 10 : c <= '9' ? c - '0' : 0xFF );\n\n        if ( c >= base ) break; /* out of base */\n\n        {\n            register unsigned long x=(v&0xff)*base+c;\n            register unsigned long w=(v>>8)*base+(x>>8);\n\n            if ( w > ( ULONG_MAX >> 8 ) ) {\n                overflow = 1;\n            }\n\n            v = ( w << 8 ) + ( x & 0xFF );\n        }\n\n        ++nptr;\n    }\n\n    if ( nptr == orig ) {     /* no conversion done */\n        nptr = ptr;\n        v = 0;\n    }\n\n    if ( endptr != NULL ) {\n        *endptr = ( char* )nptr;\n    }\n\n    if ( overflow ) {\n        return ULONG_MAX;\n    }\n\n    return ( neg ? -v : v );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/stdlib/strtoull.c",
    "content": "\n \n\n#include <ctype.h>\n#include <stdlib.h>\n#include <errno.h>\n#include <limits.h>\n#include <inttypes.h>\n\nunsigned long long int strtoull( const char* ptr, char** endptr, int base ) {\n    int neg = 0, overflow = 0;\n    long long int v = 0;\n    const char* orig;\n    const char* nptr = ptr;\n\n    while ( isspace( *nptr ) ) {\n        ++nptr;\n    }\n\n    if ( *nptr == '-' ) {\n        neg=1;\n        nptr++;\n    } else if ( *nptr == '+' ) {\n        ++nptr;\n    }\n\n    orig = nptr;\n\n    if ( ( base == 16 ) && ( nptr[ 0 ] == '0' ) ) {\n        goto skip0x;\n    }\n\n    if ( base ) {\n        register unsigned int b = base - 2;\n\n        if ( b > 34 ) {\n            errno = EINVAL;\n            return 0;\n        }\n    } else {\n        if ( *nptr == '0' ) {\n            base = 8;\n\nskip0x:\n            if ( ( ( *( nptr + 1 ) == 'x' ) || ( *( nptr + 1 ) == 'X' ) ) && isxdigit( nptr[ 2 ] ) ) {\n                nptr += 2;\n                base = 16;\n            }\n        } else {\n            base = 10;\n        }\n    }\n\n    while ( *nptr ) {\n        register unsigned char c = *nptr;\n\n        c = ( c >= 'a' ? c - 'a' + 10 : c >= 'A' ? c - 'A' + 10 : c <= '9' ? c - '0' : 0xFF );\n\n        if ( c >= base ) {\n            break;\t/* out of base */\n        }\n\n        {\n            register unsigned long x = ( v & 0xFF ) * base + c;\n            register unsigned long long w = ( v >> 8 ) * base + ( x >> 8 );\n\n            if ( w > ( ULLONG_MAX >> 8 ) ) {\n                overflow = 1;\n            }\n\n            v = ( w << 8 ) + ( x & 0xFF );\n        }\n\n        ++nptr;\n    }\n\n    if ( nptr == orig ) {\t\t/* no conversion done */\n        nptr = ptr;\n        errno = EINVAL;\n        v = 0;\n    }\n\n    if ( endptr != NULL ) {\n        *endptr = (char *)nptr;\n    }\n\n    if ( overflow ) {\n        errno = ERANGE;\n        return ULLONG_MAX;\n    }\n\n    return ( neg ? -v : v );\n}\n\nuintmax_t strtoumax( const char* nptr, char** endptr, int base ) __attribute__(( alias( \"strtoull\" ) ));\n"
  },
  {
    "path": "src/sdk/src/libc/src/string/memchr.c",
    "content": "\n \n\n#include <string.h>\n\nvoid* memchr( const void* s, int c, size_t n ) {\n    const unsigned char* src = ( const unsigned char* )s;\n    unsigned char ch = c;\n\n    for ( ; n != 0; n-- ) {\n        if ( *src == ch ) {\n            return ( void* )src;\n        }\n\n        src++;\n    }\n\n    return NULL;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/string/memcmp.c",
    "content": "\n \n\n#include <string.h>\n\nint memcmp( const void* p1, const void* p2, size_t c ) {\n    const unsigned char* su1, *su2;\n    signed char res = 0;\n\n    for ( su1 = p1, su2 = p2; 0 < c; ++su1, ++su2, c-- ) {\n        if ( ( res = *su1 - *su2 ) != 0 ) {\n            break;\n        }\n    }\n\n    return res;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/string/memcpy.c",
    "content": "\n \n\n#include <string.h>\n\nvoid* memcpy( void* d, const void* s, size_t n ) {\n    char* dest;\n    char* src;\n\n    dest = ( char* )d;\n    src = ( char* )s;\n\n    while ( n-- ) {\n        *dest++ = *src++;\n    }\n\n    return d;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/string/memmove.c",
    "content": "\n \n\n#include <string.h>\n\nvoid* memmove( void* dest, const void* src, size_t n ) {\n    char* _dest;\n    char* _src;\n\n    if ( dest < src ) {\n        _dest = ( char* )dest;\n        _src = ( char* )src;\n\n        while ( n-- ) {\n            *_dest++ = *_src++;\n        }\n    } else {\n        _dest = ( char* )dest + n;\n        _src = ( char* )src + n;\n\n        while ( n-- ) {\n            *--_dest = *--_src;\n        }\n    }\n\n    return dest;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/string/memset.c",
    "content": "\n \n\n#include <string.h>\n\nvoid* memset( void* s, int c, size_t n ) {\n    char* _src;\n\n    _src = ( char* )s;\n\n    while ( n-- ) {\n        *_src++ = c;\n    }\n\n    return s;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/string/strcasecmp.c",
    "content": "\n \n\n#include <string.h>\n#include <ctype.h>\n\nint strcasecmp( const char* s1, const char* s2 ) {\n    int result;\n\n    while ( 1 ) {\n        result = tolower( *s1 ) - tolower( *s2++ );\n\n        if ( ( result != 0 ) || ( *s1++ == 0 ) ) {\n            break;\n        }\n    }\n\n    return result;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/string/strcat.c",
    "content": "\n \n\n#include <string.h>\n\nchar* strcat( char* d, const char* s ) {\n  char* tmp = d;\n\n  while ( *d ) d++;\n  while ( ( *d++ = *s++ ) != 0 ) ;\n\n  return tmp;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/string/strchr.c",
    "content": "\n \n\n#include <string.h>\n\nchar* strchr( const char* s, int c ) {\n  for ( ; *s != ( char )c; s++ ) {\n    if ( *s == 0 ) {\n      return NULL;\n    }\n  }\n\n  return ( char* )s;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/string/strcmp.c",
    "content": "\n \n\n#include <string.h>\n\nint strcmp( const char* s1, const char* s2 ) {\n    int result;\n\n    while ( 1 ) {\n        result = *s1 - *s2++;\n\n        if ( ( result != 0 ) || ( *s1++ == 0 ) ) {\n            break;\n        }\n    }\n\n    return result;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/string/strcpy.c",
    "content": "\n \n\n#include <string.h>\n#include <stdarg.h>\n\n\nchar* strcpy( char* d, const char* s ) {\n    char* tmp = d;\n\n    while ( ( *d++ = *s++ ) != 0 ) ;\n\n    return tmp;\n}\n\nint support_vsprintf(char* buffer, const char* format, va_list ap);\n\nint vsprintf(char* s, const char* format, va_list arg)\n{\n\treturn support_vsprintf( s, format, arg );\n}\n\n\nint sprintf(char *buffer, const char* format, ...)\n{\n\tint rc;\n\tva_list ap;\n\tva_start(ap, format);\n\t\trc = vsprintf( buffer, format, ap );\n\tva_end(ap);\n   return 0;\n\n}\n\n"
  },
  {
    "path": "src/sdk/src/libc/src/string/strcspn.c",
    "content": "\n \n\n#include <string.h>\n#include <sys/types.h>\n\nsize_t strcspn( const char* s, const char* reject ) {\n    size_t l = 0;\n    int a = 1;\n    int i;\n    int al = strlen( reject );\n\n    while ( ( a ) && ( *s ) ) {\n        for ( i = 0; ( a ) && ( i < al ); i++ ) {\n            if ( *s == reject[ i ] ) {\n                a = 0;\n            }\n        }\n\n        if ( a ) {\n            l++;\n        }\n\n        s++;\n    }\n\n    return l;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/string/strdup.c",
    "content": "\n \n\n#include <stdlib.h>\n#include <string.h>\n\nchar* strdup( const char* s ) {\n    char* s2;\n    size_t length;\n\n    length = strlen( s );\n    s2 = ( char* )malloc( length + 1 );\n\n    if ( s2 == NULL ) {\n        return NULL;\n    }\n\n    memcpy( s2, s, length + 1 );\n\n    return s2;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/string/strerror.c",
    "content": "\n \n\n#include <string.h>\n\nstatic char* error_strings[] = {\n    \"Cannot allocate memory\", /* ENOMEM */\n    \"Invalid argument\", /* EINVAL */\n    \"Input/output error\", /* EIO */\n    \"Timer expired\", /* ETIME */\n    \"Function not implemented\", /* ENOSYS */\n    \"No such file or directory\", /* ENOENT */\n    \"File exists\", /* EEXIST */\n    \"Device or resource busy\", /* EBUSY */\n    \"Is a directory\", /* EISDIR */\n    \"Inode not found\", /* ENOINO */\n    \"Executable format error\", /* ENOEXEC */\n    \"Bad file descriptor\", /* EBADF */\n    \"Hardware error\", /* EHW */\n    \"Numerical result out of range\", /* ERANGE */\n    \"No such device or address\", /* ENXIO */\n    \"Numerical argument out of domain\", /* EDOM */\n    \"No such device\", /* ENODEV */\n    \"Interrupted system call\", /* EINTR */\n    \"Inappropriate ioctl for device\", /* ENOTTY */\n    \"Operation not permitted\", /* EPERM */\n    \"Read-only file system\", /* EROFS */\n    \"Too many levels of symbolic links\", /* ELOOP */\n    \"Not a directory\", /* ENOTDIR */\n    \"Directory not empty\", /* ENOTEMPTY */\n    \"Resource temporarily unavailable\", /* EAGAIN */\n    \"Argument list too long\", /* E2BIG */\n    \"Connection timed out\", /* ETIMEDOUT */\n    \"Value too large for defined data type\", /* EOVERFLOW */\n    \"No space left on device\", /* ENOSPC */\n    \"No child processes\", /* ECHILD */\n    \"File name too long\", /* ENAMETOOLONG */\n    \"Illegal seek\", /* ESPIPE */\n    \"Permission denied\" /* EACCES */\n};\n\nchar* strerror( int errnum ) {\n    if ( errnum < 0 ) {\n        errnum = -errnum;\n    }\n\n    errnum--;\n\n    if ( ( errnum < 0 ) ||\n         ( errnum >= ( sizeof( error_strings ) / sizeof( error_strings[ 0 ] ) ) ) ) {\n        return NULL;\n    }\n\n    return error_strings[ errnum ];\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/string/strlen.c",
    "content": "\n \n\n#include <string.h>\n\nsize_t strlen( const char* s ) {\n    size_t r = 0;\n\n    for( ; *s++ != 0; r++ ) { }\n\n    return r;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/string/strncasecmp.c",
    "content": "\n \n\n#include <string.h>\n#include <ctype.h>\n\nint strncasecmp( const char* s1, const char* s2, size_t c ) {\n    int result = 0;\n\n    while ( c ) {\n        result = toupper( *s1 ) - toupper( *s2++ );\n\n        if ( ( result != 0 ) || ( *s1++ == 0 ) ) {\n            break;\n        }\n\n        c--;\n    }\n\n    return result;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/string/strncat.c",
    "content": "\n \n\n#include <string.h>\n\nchar* strncat( char* d, const char* s, size_t c ) {\n  char* tmp = d;\n\n  if ( c > 0 ) {\n    while ( *d ) d++;\n    while ( ( *d++ = *s++ ) ) {\n      if ( --c == 0 ) {\n        *d = 0;\n        break;\n      }\n    }\n  }\n\n  return tmp;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/string/strncmp.c",
    "content": "\n \n\n#include <string.h>\n\nint strncmp( const char* s1, const char* s2, size_t c ) {\n    int result = 0;\n\n    while ( c ) {\n        result = *s1 - *s2++;\n\n        if ( ( result != 0 ) || ( *s1++ == 0 ) ) {\n            break;\n        }\n\n        c--;\n    }\n\n    return result;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/string/strncpy.c",
    "content": "\n \n\n#include <string.h>\n\nchar* strncpy( char* d, const char* s, size_t c ) {\n    size_t i;\n    char* tmp = d;\n\n    for ( i = 0; i < c; i++ ) {\n        *d++ = *s;\n\n        if ( *s++ == 0 ) {\n            break;\n        }\n    }\n\n    for ( ; i < c; i++ ) {\n        *d++ = 0;\n    }\n\n    return tmp;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/string/strndup.c",
    "content": "\n \n\n#include <stdlib.h>\n#include <string.h>\n#include <sys/param.h>\n\nchar* strndup( const char* s, size_t n ) {\n    char* s2;\n    size_t len;\n\n    len = strlen( s );\n    len = MIN( len, n );\n\n    s2 = ( char* )malloc( len + 1 );\n\n    if ( s2 == NULL ) {\n        return NULL;\n    }\n\n    memcpy( s2, s, len );\n    s2[ len ] = '\\0';\n\n    return s2;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/string/strnlen.c",
    "content": "\n \n\n#include <string.h>\n\nsize_t strnlen( const char* s, size_t count ) {\n    const char* sc;\n\n    for ( sc = s; count-- && ( *sc != 0 ); ++sc ) { }\n\n    return ( sc - s );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/string/strpbrk.c",
    "content": "\n \n#include <string.h>\n\nchar* strpbrk( const char* s, const char* accept ) {\n    register int i, l = strlen( accept );\n\n    for ( ; *s != 0; s++ )\n        for ( i = 0; i < l; i++ )\n            if (*s == accept[i])\n                return (char*)s;\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/string/strrchr.c",
    "content": "\n \n\n#include <string.h>\n\nchar* strrchr( const char* s, int c ) {\n  const char* end = s + strlen( s );\n\n  do {\n    if ( *end == ( char )c ) {\n      return ( char * )end;\n    }\n  } while ( --end >= s );\n\n  return NULL;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/string/strsignal.c",
    "content": "\n \n\n#include <string.h>\n\nstatic char* signal_names[] = {\n    \"Hangup\",\n    \"Interrupt\",\n    \"Quit\",\n    \"Illegal instruction\",\n    \"Trace/breakpoint trap\",\n    \"Aborted\",\n    \"Aborted\",\n    \"Bus error\",\n    \"Floating point exception\",\n    \"Killed\",\n    \"User defined signal 1\",\n    \"Segmentation fault\",\n    \"User defined signal 2\",\n    \"Broken pipe\",\n    \"Alarm clock\",\n    \"Terminated\",\n    \"Stack fault\",\n    \"Child exited\",\n    \"Continued\",\n    \"Stopped (signal)\",\n    \"Stopped\",\n    \"Stopped (tty input)\",\n    \"Stopped (tty output)\",\n    \"Urgent I/O condition\",\n    \"CPU time limit exceeded\",\n    \"File size limit exceeded\",\n    \"Virtual timer expired\",\n    \"Profiling timer expired\",\n    \"Window changed\",\n    \"I/O possible\",\n    \"Power failure\",\n    \"Bad system call\"\n};\n\nchar* strsignal( int signum ) {\n    if ( signum <= 0 ) {\n        return NULL;\n    }\n\n    signum--;\n\n    if ( signum >= ( sizeof( signal_names ) / sizeof( signal_names[ 0 ] ) ) ) {\n        return NULL;\n    }\n\n    return signal_names[ signum ];\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/string/strspn.c",
    "content": "\n \n\n#include <string.h>\n\nsize_t strspn( const char* s, const char* accept ) {\n    size_t l = 0;\n    int a = 1;\n    int i;\n    int al = strlen( accept );\n\n    while( ( a ) && ( *s ) )    {\n        for ( a = i = 0; ( !a ) && ( i < al ); i++ ) {\n            if ( *s == accept[ i ] ) {\n                a = 1;\n            }\n        }\n\n        if ( a ) {\n            l++;\n        }\n\n        s++;\n    }\n\n    return l;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/string/strstr.c",
    "content": "\n \n\n#include <string.h>\n\nchar* strstr( const char* s1, const char* s2 ) {\n    int l1, l2;\n\n    l2 = strlen( s2 );\n\n    if ( !l2 ) {\n        return ( char * )s1;\n    }\n\n    l1 = strlen( s1 );\n\n    while ( l1 >= l2 ) {\n        l1--;\n\n        if ( !memcmp( s1, s2, l2 ) ) {\n            return ( char * )s1;\n        }\n\n        s1++;\n    }\n\n    return NULL;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/string/strtok.c",
    "content": "\n \n\n#include <string.h>\n\nstatic char* strtok_pos;\n\nchar* strtok( char* s, const char* delim ) {\n    return strtok_r( s, delim, &strtok_pos );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/string/strtok_r.c",
    "content": "\n \n\n#include <string.h>\n\nchar* strtok_r( char* s, const char* delim, char** ptrptr ) {\n    char* tmp = NULL;\n\n    if ( s == NULL ) {\n        s = *ptrptr;\n    }\n\n    s += strspn( s, delim );\n\n    if ( *s ) {\n        tmp = s;\n        s += strcspn( s, delim );\n\n        if ( *s ) {\n            *s++ = 0;\n        }\n    }\n\n    *ptrptr = s;\n\n    return tmp;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/sys/chmod.c",
    "content": "\n \n\n#include <sys/stat.h>\n\nint chmod( const char* path, mode_t mode ) {\n    /* TODO */\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/sys/connect.c",
    "content": "\n \n\n#include <errno.h>\n#include <sys/socket.h>\n\n#include <os.h>\n\nint connect( int fd, const struct sockaddr* address, socklen_t addrlen ) {\n    int error;\n\n    error = syscall3( SYS_connect, fd, ( int )address, addrlen );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/sys/fstat.c",
    "content": "\n \n\n#include <errno.h>\n#include <sys/stat.h>\n\n#include <os.h>\n\nint fstat( int fd, struct stat* stat ) {\n    int error;\n\n    error = syscall2( SYS_fstat, fd, ( int )stat );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/sys/ioctl.c",
    "content": "\n \n#include <errno.h>\n#include <sys/ioctl.h>\n\n#include <os.h>\n\nint ioctl( int fd, int request, ... ) {\n    int error;\n\n    error = syscall3( SYS_ioctl, fd, request, *( ( ( ( int* )&request ) ) + 1 ) );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return error;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/sys/lstat.c",
    "content": "\n \n\n#include <errno.h>\n#include <sys/stat.h>\n\n#include <os.h>\n\nint lstat( const char* path, struct stat* stat ) {\n    int error;\n\n    error = syscall2( SYS_lstat, ( int )path, ( int )stat );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/sys/mkdir.c",
    "content": "\n \n\n#include <errno.h>\n#include <sys/stat.h>\n\n#include <os.h>\n\nint mkdir( const char* pathname, mode_t mode ) {\n    int error;\n\n    error = syscall2( SYS_mkdir, ( int )pathname, ( int )mode );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/sys/mount.c",
    "content": "\n \n\n#include <errno.h>\n#include <sys/mount.h>\n\n#include <os.h>\n\nint mount(\n    const char* source,\n    const char* target,\n    const char* filesystemtype,\n    unsigned long mountflags,\n    const void* data\n) {\n    int error;\n\n    error = syscall4(\n        SYS_mount,\n        ( int )source,\n        ( int )target,\n        ( int )filesystemtype,\n        ( int )mountflags\n    );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/sys/select.c",
    "content": "\n \n\n#include <errno.h>\n#include <sys/select.h>\n\n#include <os.h>\n\nint select( int fds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, struct timeval* timeout ) {\n    int error;\n\n    error = syscall5(\n        SYS_select,\n        fds,\n        ( int )readfds,\n        ( int )writefds,\n        ( int )exceptfds,\n        ( int )timeout\n    );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return error;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/sys/socket.c",
    "content": "\n \n\n#include <errno.h>\n#include <sys/socket.h>\n\n#include <os.h>\n\nint socket( int domain, int type, int protocol ) {\n    int error;\n\n    error = syscall3( SYS_socket, domain, type, protocol );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return error;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/sys/stat.c",
    "content": "\n \n#include <errno.h>\n#include <sys/stat.h>\n\n#include <os.h>\n\nint stat( const char* path, struct stat* stat ) {\n    int error;\n\n    error = syscall2( SYS_stat, ( int )path, ( int )stat );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/sys/stime.c",
    "content": "\n \n\n#include <errno.h>\n#include <sys/time.h>\n\n#include <os.h>\n\nint stime( time_t *t ) {\n    int error;\n\n    error = syscall1( SYS_stime, ( int )t );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/sys/umask.c",
    "content": "\n \n\n#include <sys/stat.h>\n\nmode_t umask( mode_t mask ) {\n    /* TODO */\n    return 0666;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/sys/umount.c",
    "content": "\n \n\n#include <errno.h>\n#include <sys/mount.h>\n\n#include <os.h>\n\nint umount(\n    const char* dir\n) {\n    int error;\n\n    error = syscall1(\n        SYS_unmount,\n        ( int )dir\n    );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/sys/utime.c",
    "content": "\n \n\n#include <errno.h>\n#include <utime.h>\n\n#include <os.h>\n\nint utime( const char* filename, const struct utimbuf* times ) {\n    int error;\n    struct utimbuf current;\n\n    if ( times == NULL ) {\n        current.actime = time( NULL );\n        current.modtime = current.actime;\n\n        times = ( const struct utimbuf* )&current;\n    }\n\n    error = syscall2( SYS_utime, ( int )filename, ( int )times  );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/sys/utimes.c",
    "content": "\n \n\n#include <errno.h>\n#include <utime.h>\n\n#include <os.h>\n\nint utimes( const char* filename, const timeval_t times[2] ) {\n    struct utimbuf tmp;\n\n    /* NOTE: no microsecond precision */\n    tmp.actime = times[ 0 ].tv_sec;\n    tmp.modtime = times[ 1 ].tv_sec;\n\n    /* This is a wrapper around utime() */\n    return utime( filename, &tmp );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/sys/wait.c",
    "content": "\n \n\n#include <sys/wait.h>\n\npid_t wait( int* status ) {\n    return wait4( -1, status, 0, NULL );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/sys/wait3.c",
    "content": "\n \n\n#include <sys/wait.h>\n\npid_t wait3( int* status, int options, struct rusage* rusage ) {\n    return wait4( -1, status, options, rusage );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/sys/wait4.c",
    "content": "\n \n\n#include <errno.h>\n#include <sys/wait.h>\n\n#include <os.h>\n\npid_t wait4( pid_t pid, int* status, int options, struct rusage* rusage ) {\n    int error;\n\n    error = syscall4(\n        SYS_wait4,\n        pid,\n        ( int )status,\n        options,\n        ( int )rusage\n    );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return error;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/sys/waitpid.c",
    "content": "\n \n \n\n#include <sys/wait.h>\n\n#include <os.h>\n\npid_t waitpid( pid_t pid, int* status, int options ) {\n    return wait4( pid, status, options, NULL );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/termios/tcflow.c",
    "content": "\n \n\n#include <termios.h>\n\nint tcflow( int fd, int action ) {\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/termios/tcflush.c",
    "content": "\n \n\n#include <termios.h>\n\nint tcflush( int fd, int queue_selector ) {\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/termios/tcgetattr.c",
    "content": "\n \n\n#include <termios.h>\n#include <errno.h>\n#include <stddef.h>\n#include <sys/ioctl.h>\n\nint tcgetattr( int fd, struct termios* tio ) {\n    int error;\n\n    if ( tio == NULL ) {\n        errno = EINVAL;\n        return -1;\n    }\n\n    error = ioctl( fd, TCGETA, tio );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/termios/tcgetpgrp.c",
    "content": "#include <unistd.h>\n\npid_t tcgetpgrp( int fd ) {\n    /* NOTE: This is a temp. hack to get bash working :) */\n\n    return getpid();\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/termios/tcsetattr.c",
    "content": "\n \n\n#include <termios.h>\n#include <errno.h>\n#include <stddef.h>\n#include <sys/ioctl.h>\n\nint tcsetattr( int fd, int optional_actions, const struct termios* tio ) {\n    int error;\n\n    if ( tio == NULL ) {\n        errno = EINVAL;\n        return -1;\n    }\n\n    switch ( optional_actions ) {\n        case TCSANOW :\n            error = ioctl( fd, TCSETA, tio );\n            break;\n\n        case TCSADRAIN :\n            error = ioctl( fd, TCSETAW, tio );\n            break;\n\n        case TCSAFLUSH :\n            error = ioctl( fd, TCSETAF, tio );\n            break;\n\n        default :\n            error = -EINVAL;\n            break;\n    }\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/termios/tcsetpgrp.c",
    "content": "#include <unistd.h>\n\nint tcsetpgrp( int fd, pid_t pgrp ) {\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/time/asctime.c",
    "content": "\n \n\n#include <time.h>\n\nstatic char asctime_buffer[ 32 ];\n\nchar* asctime( const tm_t* tm ) {\n    return asctime_r( tm, asctime_buffer );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/time/asctime_r.c",
    "content": "\n \n\n#include <time.h>\n\nchar* asctime_r( const tm_t* tm, char* buf ) {\n    strftime( buf, 26, \"%a %b %d %H:%M:%S %Y\\n\", tm );\n\n    return buf;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/time/ctime.c",
    "content": "\n \n\n#include <time.h>\n\nchar* ctime( const time_t* timep ) {\n    return asctime( localtime( timep ) );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/time/ctime_r.c",
    "content": "\n \n\n#include <time.h>\n\nchar* ctime_r( const time_t* timep, char *buf) {\n    buf = asctime( localtime( timep ) );\n\n    return buf;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/time/gettimeofday.c",
    "content": "\n \n\n#include <sys/time.h>\n\n#include <os.h>\n\nint gettimeofday( struct timeval* tv, struct timezone* tz ) {\n    int ret;\n    uint64_t time;\n\n    ret = syscall1( SYS_get_system_time, ( int )&time );\n\n    if ( ret >= 0 ) {\n        if ( tv != NULL ) {\n            tv->tv_sec = time / 1000000;\n            tv->tv_usec = time % 1000000;\n        }\n    }\n\n    return ret;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/time/gmtime.c",
    "content": "\n \n\n#include <time.h>\n\nstatic tm_t ret;\n\ntm_t* gmtime( const time_t* timep ) {\n    return gmtime_r( timep, &ret );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/time/gmtime_r.c",
    "content": "\n \n\n#include <time.h>\n\n#include \"time_int.h\"\n\ntm_t* gmtime_r( const time_t* timep, tm_t* result ) {\n    if ( _gmtime( *timep, result ) < 0 ) {\n        return NULL;\n    }\n\n    return result;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/time/localtime.c",
    "content": "\n \n#include <time.h>\n\nstatic tm_t ret;\n\ntm_t* localtime( const time_t* timep ) {\n    gmtime_r( timep, &ret );\n    /* TODO: timezones, tzset(3), tzname, etc */\n    return &ret;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/time/localtime_r.c",
    "content": "\n \n\n#include <time.h>\n\ntm_t* localtime_r( const time_t* timep, tm_t* result ) {\n    gmtime_r( timep, result );\n    return result;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/time/mktime.c",
    "content": "\n \n\n#include <time.h>\n\n#include \"time_int.h\"\n\ntime_t mktime( tm_t* tm ) {\n    if ( tm->tm_year > 2100 ) {\n        return -1;\n    }\n\n    return daysdiff( tm->tm_year, tm->tm_mon, tm->tm_mday ) * SECONDS_PER_DAY +\n           tm->tm_hour * SECONDS_PER_HOUR + tm->tm_min * SECONDS_PER_MINUTE + tm->tm_sec;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/time/nanosleep.c",
    "content": "\n \n\n#include <time.h>\n#include <errno.h>\n#include <sys/types.h>\n\n#include <os.h>\n\nint nanosleep( const struct timespec* req, struct timespec* rem ) {\n    int error;\n    uint64_t microsecs;\n    uint64_t remaining;\n\n    microsecs = ( uint64_t )req->tv_sec * 1000000 + ( uint64_t )req->tv_nsec / 1000;\n\n    if ( microsecs == 0 ) {\n        microsecs = 1;\n    }\n\n    error = syscall2( SYS_sleep_thread, ( int )&microsecs, ( int )&remaining );\n\n    if ( error < 0 ) {\n        errno = -error;\n\n        if ( rem != NULL ) {\n            rem->tv_sec = remaining / 1000000;\n            rem->tv_nsec = ( remaining % 1000000 ) * 1000;\n        }\n\n        return -1;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/time/strftime.c",
    "content": "\n \n\n#include <string.h>\n#include <stdio.h>\n#include <time.h>\n\n#define APPEND( str ) \\\n        ret += strlen(str); \\\n        if(ret > max){ \\\n            return 0; \\\n        } \\\n        strcat(s, (const char*) str);\n\n#define STRFT_ALTFORM 0x01\n\nconst char* month_names[ 12 ] = { \"January\", \"February\", \"March\",\n                                  \"April\", \"May\", \"June\",\n                                  \"July\", \"August\", \"September\",\n                                  \"October\", \"November\", \"December\" };\n\nconst char* smonth_names[ 12 ] = { \"Jan\", \"Feb\", \"Mar\",\n                                   \"Apr\", \"May\", \"Jun\",\n                                   \"Jul\", \"Aug\", \"Sep\",\n                                   \"Oct\", \"Nov\", \"Dec\" };\n\nconst char* day_names[ 7 ] = { \"Sunday\", \"Monday\",\n                               \"Tuesday\", \"Wednesday\",\n                               \"Thursday\", \"Friday\",\n                               \"Saturday\" };\n\nconst char* sday_names[ 7 ] = { \"Sun\", \"Mon\", \"Tue\",\n                                \"Wed\", \"Thu\", \"Fri\",\n                                \"Sat\" };\n\nsize_t strftime(char* s, size_t max, const char* format,\n                const tm_t* tm){\n    size_t ret = 0;\n    int state;\n    int flags; \n    char tmp[max];\n\n    s[0] = '\\0'; /* Initialize s */\n    max--; /* Reserve space for '\\0' at the end */\n    state = flags = 0;\n\n    for( ; *format != '\\0'; format++){\n        switch(state){\n            case 0:\n                if(*format != '%'){\n                    if(ret < max){\n                        s[ret++] = *format;\n                        s[ret] = '\\0';\n                    } else {\n                        s[ret] = '\\0';\n                        return 0;\n                    }\n                    break;\n                }\n                state++;\n                format++;\n            case 1:\n                if(*format == '%'){\n                    if(ret < max){\n                        s[ret++] = '%';\n                        s[ret] = '\\0';\n                    } else {\n                        s[ret] = '\\0';\n                        return 0;\n                    }\n                    state = flags = 0;\n                    break;\n                }\n                /* TODO: locale-independent, we need locales first :)\n                if(*format == 'E'){\n                } */\n                if(*format == 'O'){\n                    flags |= STRFT_ALTFORM;\n                    /* TODO: use this */\n                }\n                /* TODO: glibc modifiers: _-0^# */\n                state++;\n            case 2:\n                switch(*format){\n                    case 'a':\n                        APPEND(sday_names[tm->tm_wday]);\n                        break;\n                    case 'A':\n                        APPEND(day_names[tm->tm_wday]);\n                        break;\n                    case 'h':\n                    case 'b':\n                        APPEND(smonth_names[tm->tm_mon]);\n                        break;\n                    case 'B':\n                        APPEND(month_names[tm->tm_mon]);\n                        break;\n                    case 'c':\n                        /* The preferred date and time representation for the current locale. */\n                        strftime(tmp, max-ret, \"%a %b %e %H:%M:%S %Z %Y\", tm);\n                        APPEND(tmp);\n                        break;\n                    case 'C':\n                        snprintf(tmp, max, \"%d\", tm->tm_year / 100);\n                        APPEND(tmp);\n                        break;\n                    case 'd':\n                        snprintf(tmp, max, \"%02d\", tm->tm_mday);\n                        APPEND(tmp);\n                        break;\n                    case 'D':\n                        strftime(tmp, max-ret, \"%m/%d/%y\", tm);\n                        APPEND(tmp);\n                        break;\n                    case 'e':\n                        snprintf(tmp, max, \"%2d\", tm->tm_mday);\n                        APPEND(tmp);\n                        break;\n                    case 'F':\n                        strftime(tmp, max-ret, \"%Y-%m-%d\", tm);\n                        APPEND(tmp);\n                        break;\n                    case 'G':\n/* The ISO 8601 year with century as a decimal number.  The 4-digit year corresponding to the ISO  week  number\n   (see  %V).  This has the same format and value as %y, except that if the ISO week number belongs to the\n   previous or next year, that year is used instead. (TZ)*/\n                        break;\n                    case 'g':\n                        /* Like %G, but without century, that is, with a 2-digit year (00-99). (TZ) */\n                        break;\n                    case 'H':\n                        snprintf(tmp, max, \"%02d\", tm->tm_hour);\n                        APPEND(tmp);\n                        break;\n                    case 'I':\n                        snprintf(tmp, max, \"%02d\", tm->tm_hour % 12);\n                        APPEND(tmp);\n                        break;\n                    case 'j':\n                        /* Day of the year, 001-366 */\n                        snprintf(tmp, max, \"%03d\", tm->tm_yday + 1);\n                        APPEND(tmp);\n                        break;\n                    case 'k':\n                        snprintf(tmp, max, \"%2d\", tm->tm_hour);\n                        APPEND(tmp);\n                        break;\n                    case 'l':\n                        snprintf(tmp, max, \"%2d\", tm->tm_hour % 12);\n                        APPEND(tmp);\n                        break;\n                    case 'm':\n                        snprintf(tmp, max, \"%02d\", tm->tm_mon + 1);\n                        APPEND(tmp);\n                        break;\n                    case 'M':\n                        snprintf(tmp, max, \"%02d\", tm->tm_min);\n                        APPEND(tmp);\n                        break;\n                    case 'n':\n                        APPEND(\"\\n\");\n                        break;\n                    case 'p':\n                        if(tm->tm_hour >= 12){\n                            APPEND(\"PM\");\n                        }else{\n                            APPEND(\"AM\");\n                        }\n                        break;\n                    case 'P':\n                        if(tm->tm_hour >= 12){\n                            APPEND(\"pm\");\n                        }else{\n                            APPEND(\"am\");\n                        }\n                        break;\n                    case 'r':\n                        strftime(tmp, max-ret, \"%I:%M:%S %p\", tm);\n                        APPEND(tmp);\n                        break;\n                    case 'R':\n                        strftime(tmp, max-ret, \"%H:%M\", tm);\n                        APPEND(tmp);\n                        break;\n                    case 's':\n                        snprintf(tmp, max, \"%llu\", mktime((tm_t*) tm));\n                        APPEND(tmp);\n                        break;\n                    case 'S':\n                        snprintf(tmp, max, \"%02d\", tm->tm_sec);\n                        APPEND(tmp);\n                        break;\n                    case 't':\n                        APPEND(\"\\t\");\n                        break;\n                    case 'T':\n                        strftime(tmp, max-ret, \"%H:%M:%S\", tm);\n                        APPEND(tmp);\n                        break;\n                    case 'u':\n                        /* Day of the week, 1-7, Monday=1 */\n                        snprintf(tmp, max, \"%d\", 1 + (tm->tm_wday + 6 ) % 7);\n                        APPEND(tmp);\n                        break;\n                    case 'U':\n/* The week number of the current year as a decimal number, range 00 to 53, starting with the first  Sunday  as\n   the first day of week 01.*/\n                        break;\n                    case 'V':\n/*  The  ISO  8601:1988 week number of the current year as a decimal number, range 01 to 53, where week 1 is the\n    first week that has at least 4 days in the current year, and with Monday as the first day of the week.   See\n    also %U and %W. */\n                        break;\n                    case 'w':\n                        /* Day of the week, 0-6, Sunday=0 */\n                        snprintf(tmp, max, \"%d\", tm->tm_wday);\n                        APPEND(tmp);\n                        break;\n                    case 'W':\n/* The  week  number of the current year as a decimal number, range 00 to 53, starting with the first Monday as\n   the first day of week 01. */\n                        break;\n                    case 'x':\n                        /* The preferred date representation for the current locale without the time. */\n                        strftime(tmp, max-ret, \"%a %b %e %Z %Y\", tm);\n                        APPEND(tmp);\n                        break;\n                    case 'X':\n                        /* The preferred time representation for the current locale without the date. */\n                        strftime(tmp, max-ret, \"%H:%M:%S\", tm);\n                        APPEND(tmp);\n                        break;\n                    case 'y':\n                        /* The year as a decimal number without a century (range 00 to 99). */\n                        snprintf(tmp, max, \"%02d\", tm->tm_year % 100);\n                        APPEND(tmp);\n                        break;\n                    case 'Y':\n                        /* The year as a decimal number including the century. */\n                        snprintf(tmp, max, \"%d\", tm->tm_year);\n                        APPEND(tmp);\n                        break;\n                    case 'z':\n/* The  time-zone  as  hour  offset   from   GMT.    Required   to   emit   RFC 822-conformant   dates   (using\n   \"%a, %d %b %Y %H:%M:%S %z\"). (GNU) */\n                        break;\n                    case 'Z':\n                        /* The time zone or name or abbreviation. */\n                        break;\n                    default:\n                        break;\n                }\n            state = flags = 0;\n        }\n    }\n\n    s[ret] = '\\0';\n\n    return ret;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/time/time.c",
    "content": "\n \n\n#include <sys/time.h>\n\n#include <os.h>\n\ntime_t time( time_t* t ) {\n    int ret;\n    uint64_t time;\n\n    ret = syscall1( SYS_get_system_time, ( int )&time );\n\n    if ( ret < 0 ) {\n        time = 0;\n    } else {\n        time /= 1000000;\n    }\n\n    if ( t != NULL ) {\n        *t = time;\n    }\n\n    return time;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/time/time_int.c",
    "content": "\n \n\n#include <string.h>\n\n#include \"time_int.h\"\n\nconst unsigned short int monthdays[ 13 ] = {\n    0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365\n};\n\nconst unsigned short int monthdays2[ 13 ] = {\n    0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366\n};\n\nconst unsigned short int sumofdays[ 60 ] = {\n    0, 366, 731, 1096, 1461, 1827, 2192, 2557, 2922, 3288, 3653, 4018, 4383, 4749,\n    5114, 5479, 5844, 6210, 6575, 6940, 7305, 7671, 8036, 8401, 8766, 9132, 9497,\n    9862, 10227, 10593, 10958, 11323, 11688, 12054, 12419, 12784, 13149, 13515,\n    13880, 14245, 14610, 14976, 15341, 15706, 16071, 16437, 16802, 17167, 17532,\n    17898, 18263, 18628, 18993, 19359, 19724, 20089, 20454, 20820, 21185, 21550\n};\n\nint _gmtime( time_t timeval, tm_t* ret ) {\n    int i;\n\n    ret->tm_sec = timeval % SECONDS_PER_MINUTE;\n    timeval /= SECONDS_PER_MINUTE;\n    ret->tm_min = timeval % MINUTES_PER_HOUR;\n    timeval /= MINUTES_PER_HOUR;\n    ret->tm_hour = timeval % HOURS_PER_DAY;\n    timeval /= HOURS_PER_DAY;\n\n    /* 1970(Epoch) is a leap year, and every 4th year too.\n       2000 is also a leap year, because its divisible by 400.\n       timeval now holds the difference of whole days.\n       1 Jan 1970 was a Thursday. */\n\n    ret->tm_wday = (4 + timeval) % 7;\n\n    /* TODO: return NULL when year does not fit. */\n    ret->tm_year = EPOCH;\n\n    for ( i = 0; i < 60; i++ ) {\n        if ( sumofdays[ i ] > timeval ) {\n            ret->tm_year = EPOCH + i - 1;\n            timeval -= sumofdays[ i - 1 ];\n\n            break;\n        }\n    }\n\n    ret->tm_yday = ( int )timeval;\n\n    if ( ret->tm_year % 4 == 0 ) {\n        for ( ret->tm_mon = 0; ret->tm_mon < 12; ret->tm_mon++ ) {\n            if ( monthdays2[ ret->tm_mon ] > timeval ) {\n                timeval -= monthdays2[ --ret->tm_mon ];\n                break;\n            }\n        }\n    } else {\n        for ( ret->tm_mon = 0; ret->tm_mon < 12; ret->tm_mon++ ) {\n            if ( monthdays[ ret->tm_mon ] > timeval ) {\n                timeval -= monthdays[ --ret->tm_mon ];\n                break;\n            }\n        }\n    }\n\n    ret->tm_mday = ( int )timeval + 1;\n    ret->tm_isdst = -1;\n\n    return 0;\n}\n\nint daysdiff( int year, int month, int day ) {\n    int i, days = 0;\n\n    for ( i = EPOCH; i < year; i++ ) {\n        if ( i % 4 == 0 ) { /* If it is a leap year */\n            days += 366;\n        } else {\n            days += 365;\n        }\n    }\n\n    if ( year % 4 == 0 ) {\n        days += monthdays2[ month ];\n    } else {\n        days += monthdays[ month ];\n    }\n\n    days += day - 1;\n\n    return days;\n}\n\nint dayofweek( int year, int month, int day ) {\n    /* The UNIX Epoch(1 Jan 1970) was a Thursday */\n    return ( 4 + daysdiff( year, month, day ) ) % 7;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/time/time_int.h",
    "content": "\n \n#ifndef _TIME_INT_H_\n#define _TIME_INT_H_\n#include <time.h> /* Time structures */\n\n#define EPOCH 1970 /* Counting only time elapsed since 1 Jan 1970 */\n\n#define SECONDS_PER_DAY 86400\n#define SECONDS_PER_HOUR 3600\n#define SECONDS_PER_MINUTE 60\n#define MINUTES_PER_HOUR 60\n#define HOURS_PER_DAY 24\n\n/* The number of days that come before each month */\nextern const unsigned short int monthdays[ 13 ]; /* Common year */\nextern const unsigned short int monthdays2[ 13 ]; /* Leap year */\n/* The number of days passed in N years after 1970 or any leap year */\nextern const unsigned short int sumofdays[ 60 ];\n\n/* Converts a UNIX timestamp to a broken-down time */\nint _gmtime(time_t time, tm_t* ret);\n\n/* Returns the day of the week, 0=Sunday */\nint dayofweek(int year, int month, int day);\n\n/* Returns the number of days since the epoch */\nint daysdiff(int year, int month, int day);\n\n#endif // _TIME_INT_H_\n"
  },
  {
    "path": "src/sdk/src/libc/src/time/tzset.c",
    "content": "\n \n\nvoid tzset( void ) {\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/trio/trio.c",
    "content": "\n\n/*\n * TODO:\n *  - Scan is probably too permissive about its modifiers.\n *  - C escapes in %#[] ?\n *  - Multibyte characters (done for format parsing, except scan groups)\n *  - Complex numbers? (C99 _Complex)\n *  - Boolean values? (C99 _Bool)\n *  - C99 NaN(n-char-sequence) missing. The n-char-sequence can be used\n *    to print the mantissa, e.g. NaN(0xc000000000000000)\n *  - Should we support the GNU %a alloc modifier? GNU has an ugly hack\n *    for %a, because C99 used %a for other purposes. If specified as\n *    %as or %a[ it is interpreted as the alloc modifier, otherwise as\n *    the C99 hex-float. This means that you cannot scan %as as a hex-float\n *    immediately followed by an 's'.\n *  - Scanning of collating symbols.\n */\n\n/*************************************************************************\n * Trio include files\n */\n#include \"triodef.h\"\n#include \"trio.h\"\n#include \"triop.h\"\n\n#if defined(TRIO_EMBED_NAN)\n# define TRIO_PUBLIC_NAN static\n# if TRIO_FEATURE_FLOAT\n#  define TRIO_FUNC_NAN\n#  define TRIO_FUNC_NINF\n#  define TRIO_FUNC_PINF\n#  define TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT\n#  define TRIO_FUNC_ISINF\n# endif\n#endif\n#include \"trionan.h\"\n\n#if defined(TRIO_EMBED_STRING)\n# define TRIO_PUBLIC_STRING static\n# define TRIO_FUNC_LENGTH\n# define TRIO_FUNC_LENGTH_MAX\n# define TRIO_FUNC_TO_LONG\n# if TRIO_FEATURE_LOCALE\n#  define TRIO_FUNC_COPY_MAX\n# endif\n# if TRIO_FEATURE_DYNAMICSTRING\n#  define TRIO_FUNC_XSTRING_DUPLICATE\n# endif\n# if TRIO_EXTENSION && TRIO_FEATURE_SCANF\n#  define TRIO_FUNC_EQUAL_LOCALE\n# endif\n# if TRIO_FEATURE_ERRNO\n#  define TRIO_FUNC_ERROR\n# endif\n# if TRIO_FEATURE_FLOAT && TRIO_FEATURE_SCANF\n#  define TRIO_FUNC_TO_DOUBLE\n# endif\n# if TRIO_FEATURE_DYNAMICSTRING\n#  define TRIO_FUNC_STRING_EXTRACT\n# endif\n# if TRIO_FEATURE_DYNAMICSTRING\n#  define TRIO_FUNC_STRING_TERMINATE\n# endif\n# if TRIO_FEATURE_USER_DEFINED\n#  define TRIO_FUNC_DUPLICATE\n# endif\n# if TRIO_FEATURE_DYNAMICSTRING\n#  define TRIO_FUNC_STRING_DESTROY\n# endif\n# if TRIO_FEATURE_USER_DEFINED\n#  define TRIO_FUNC_DESTROY\n# endif\n# if TRIO_FEATURE_USER_DEFINED || (TRIO_FEATURE_FLOAT && TRIO_FEATURE_SCANF)\n#  define TRIO_FUNC_EQUAL\n# endif\n# if TRIO_FEATURE_USER_DEFINED || TRIO_FEATURE_SCANF\n#  define TRIO_FUNC_EQUAL_CASE\n# endif\n# if (TRIO_EXTENSION && TRIO_FEATURE_SCANF)\n#  define TRIO_FUNC_EQUAL_MAX\n# endif\n# if TRIO_FEATURE_SCANF\n#  define TRIO_FUNC_TO_UPPER\n# endif\n# if TRIO_FEATURE_DYNAMICSTRING\n#  define TRIO_FUNC_XSTRING_APPEND_CHAR\n# endif\n#endif\n#include \"triostr.h\"\n\n/**************************************************************************\n *\n * Definitions\n *\n *************************************************************************/\n\n#include <limits.h>\n#if TRIO_FEATURE_FLOAT\n# include <math.h>\n# include <float.h>\n#endif\n\n#if defined(__STDC_ISO_10646__) || defined(MB_LEN_MAX) || defined(USE_MULTIBYTE) || TRIO_FEATURE_WIDECHAR\n# if !defined(TRIO_PLATFORM_WINCE)\n//#  define TRIO_COMPILER_SUPPORTS_MULTIBYTE\n#  if !defined(MB_LEN_MAX)\n#   define MB_LEN_MAX 6\n#  endif\n# endif\n#endif\n\n#if (TRIO_COMPILER_VISUALC - 0 >= 1100) || defined(TRIO_COMPILER_BORLAND)\n# define TRIO_COMPILER_SUPPORTS_VISUALC_INT\n#endif\n\n#if TRIO_FEATURE_FLOAT\n# if defined(PREDEF_STANDARD_C99) \\\n  || defined(PREDEF_STANDARD_UNIX03)\n#  if !defined(HAVE_FLOORL)\n#   define HAVE_FLOORL\n#  endif\n#  if !defined(HAVE_CEILL)\n#   define HAVE_CEILL\n#  endif\n#  if !defined(HAVE_POWL)\n#   define HAVE_POWL\n#  endif\n#  if !defined(HAVE_FMODL)\n#   define HAVE_FMODL\n#  endif\n#  if !defined(HAVE_LOG10L)\n#   define HAVE_LOG10L\n#  endif\n# endif\n# if defined(TRIO_COMPILER_VISUALC)\n#  if defined(floorl)\n#   define HAVE_FLOORL\n#  endif\n#  if defined(ceill)\n#   define HAVE_CEILL\n#  endif\n#  if defined(powl)\n#   define HAVE_POWL\n#  endif\n#  if defined(fmodl)\n#   define HAVE_FMODL\n#  endif\n#  if defined(log10l)\n#   define HAVE_LOG10L\n#  endif\n# endif\n#endif\n\n/*************************************************************************\n * Generic definitions\n */\n\n#if !(defined(DEBUG) || defined(NDEBUG))\n# define NDEBUG\n#endif\n\n#include <assert.h>\n#include <ctype.h>\n#if defined(PREDEF_STANDARD_C99) && !defined(isascii)\n# define isascii(x) ((x) & 0x7F)\n#endif\n#if defined(TRIO_COMPILER_ANCIENT)\n# include <varargs.h>\n#else\n# include <stdarg.h>\n#endif\n#include <stddef.h>\n#if defined(TRIO_PLATFORM_WINCE)\nextern int errno;\n#else\n# include <errno.h>\n#endif\n\n#ifndef NULL\n# define NULL 0\n#endif\n#define NIL ((char)0)\n#ifndef FALSE\n# define FALSE (1 == 0)\n# define TRUE (! FALSE)\n#endif\n#define BOOLEAN_T int\n\n/* mincore() can be used for debugging purposes */\n#define VALID(x) (NULL != (x))\n\n#if TRIO_FEATURE_ERRORCODE\n  /*\n   * Encode the error code and the position. This is decoded\n   * with TRIO_ERROR_CODE and TRIO_ERROR_POSITION.\n   */\n# define TRIO_ERROR_RETURN(x,y) (- ((x) + ((y) << 8)))\n#else\n# define TRIO_ERROR_RETURN(x,y) (-1)\n#endif\n\ntypedef unsigned long trio_flags_t;\n\n\n/*************************************************************************\n * Platform specific definitions\n */\n#if defined(TRIO_PLATFORM_UNIX)\n# include <unistd.h>\n# include <signal.h>\n# include <locale.h>\n# if !defined(TRIO_FEATURE_LOCALE)\n#  define USE_LOCALE\n# endif\n#endif /* TRIO_PLATFORM_UNIX */\n#if defined(TRIO_PLATFORM_VMS)\n# include <unistd.h>\n#endif\n#if defined(TRIO_PLATFORM_WIN32)\n# if defined(TRIO_PLATFORM_WINCE)\nint read(int handle, char *buffer, unsigned int length);\nint write(int handle, const char *buffer, unsigned int length);\n# else\n#  include <io.h>\n#  define read _read\n#  define write _write\n# endif\n#endif /* TRIO_PLATFORM_WIN32 */\n\n#if TRIO_FEATURE_WIDECHAR\n# if defined(PREDEF_STANDARD_C94)\n#  include <wchar.h>\n#  include <wctype.h>\ntypedef wchar_t trio_wchar_t;\ntypedef wint_t trio_wint_t;\n# else\ntypedef char trio_wchar_t;\ntypedef int trio_wint_t;\n#  define WCONST(x) L ## x\n#  define WEOF EOF\n#  define iswalnum(x) isalnum(x)\n#  define iswalpha(x) isalpha(x)\n#  define iswcntrl(x) iscntrl(x)\n#  define iswdigit(x) isdigit(x)\n#  define iswgraph(x) isgraph(x)\n#  define iswlower(x) islower(x)\n#  define iswprint(x) isprint(x)\n#  define iswpunct(x) ispunct(x)\n#  define iswspace(x) isspace(x)\n#  define iswupper(x) isupper(x)\n#  define iswxdigit(x) isxdigit(x)\n# endif\n#endif\n\n\n/*************************************************************************\n * Compiler dependent definitions\n */\n\n/* Support for long long */\n#ifndef __cplusplus\n# if !defined(USE_LONGLONG)\n#  if defined(TRIO_COMPILER_GCC) && !defined(__STRICT_ANSI__)\n#   define USE_LONGLONG\n#  else\n#   if defined(TRIO_COMPILER_SUNPRO)\n#    define USE_LONGLONG\n#   else\n#    if defined(TRIO_COMPILER_MSVC) && (_MSC_VER >= 1400)\n#     define USE_LONGLONG\n#    else\n#     if defined(_LONG_LONG) || defined(_LONGLONG)\n#      define USE_LONGLONG\n#     endif\n#    endif\n#   endif\n#  endif\n# endif\n#endif\n\n/* The extra long numbers */\n#if defined(USE_LONGLONG)\ntypedef signed long long int trio_longlong_t;\ntypedef unsigned long long int trio_ulonglong_t;\n#else\n# if defined(TRIO_COMPILER_SUPPORTS_VISUALC_INT)\ntypedef signed __int64 trio_longlong_t;\ntypedef unsigned __int64 trio_ulonglong_t;\n# else\ntypedef TRIO_SIGNED long int trio_longlong_t;\ntypedef unsigned long int trio_ulonglong_t;\n# endif\n#endif\n\n/* Maximal and fixed integer types */\n#if defined(PREDEF_STANDARD_C99)\n# include <stdint.h>\ntypedef intmax_t trio_intmax_t;\ntypedef uintmax_t trio_uintmax_t;\ntypedef int8_t trio_int8_t;\ntypedef int16_t trio_int16_t;\ntypedef int32_t trio_int32_t;\ntypedef int64_t trio_int64_t;\n#else\n# if defined(PREDEF_STANDARD_UNIX98)\n#  include <inttypes.h>\ntypedef intmax_t trio_intmax_t;\ntypedef uintmax_t trio_uintmax_t;\ntypedef int8_t trio_int8_t;\ntypedef int16_t trio_int16_t;\ntypedef int32_t trio_int32_t;\ntypedef int64_t trio_int64_t;\n# else\n#  if defined(TRIO_COMPILER_SUPPORTS_VISUALC_INT)\ntypedef trio_longlong_t trio_intmax_t;\ntypedef trio_ulonglong_t trio_uintmax_t;\ntypedef __int8 trio_int8_t;\ntypedef __int16 trio_int16_t;\ntypedef __int32 trio_int32_t;\ntypedef __int64 trio_int64_t;\n#  else\ntypedef trio_longlong_t trio_intmax_t;\ntypedef trio_ulonglong_t trio_uintmax_t;\n#   if defined(TRIO_INT8_T)\ntypedef TRIO_INT8_T trio_int8_t;\n#   else\ntypedef TRIO_SIGNED char trio_int8_t;\n#   endif\n#   if defined(TRIO_INT16_T)\ntypedef TRIO_INT16_T trio_int16_t;\n#   else\ntypedef TRIO_SIGNED short trio_int16_t;\n#   endif\n#   if defined(TRIO_INT32_T)\ntypedef TRIO_INT32_T trio_int32_t;\n#   else\ntypedef TRIO_SIGNED int trio_int32_t;\n#   endif\n#   if defined(TRIO_INT64_T)\ntypedef TRIO_INT64_T trio_int64_t;\n#   else\ntypedef trio_longlong_t trio_int64_t;\n#   endif\n#  endif\n# endif\n#endif\n\n#if defined(HAVE_FLOORL)\n# define trio_floor(x) floorl((x))\n#else\n# define trio_floor(x) floor((double)(x))\n#endif\n\n#if defined(HAVE_CEILL)\n# define trio_ceil(x) ceill((x))\n#else\n# define trio_ceil(x) ceil((double)(x))\n#endif\n\n#if defined(HAVE_FMODL)\n# define trio_fmod(x,y) fmodl((x),(y))\n#else\n# define trio_fmod(x,y) fmod((double)(x),(double)(y))\n#endif\n\n#if defined(HAVE_POWL)\n# define trio_pow(x,y) powl((x),(y))\n#else\n# define trio_pow(x,y) pow((double)(x),(double)(y))\n#endif\n\n#if defined(HAVE_LOG10L)\n# define trio_log10(x) log10l((x))\n#else\n# define trio_log10(x) log10((double)(x))\n#endif\n\n#if TRIO_FEATURE_FLOAT\n# define TRIO_FABS(x) (((x) < 0.0) ? -(x) : (x))\n#endif\n\n/*************************************************************************\n * Internal Definitions\n */\n\n#if TRIO_FEATURE_FLOAT\n\n# if !defined(DECIMAL_DIG)\n#  define DECIMAL_DIG DBL_DIG\n# endif\n\n/* Long double sizes */\n# ifdef LDBL_DIG\n#  define MAX_MANTISSA_DIGITS LDBL_DIG\n#  define MAX_EXPONENT_DIGITS 4\n#  define MAX_DOUBLE_DIGITS LDBL_MAX_10_EXP\n# else\n#  define MAX_MANTISSA_DIGITS DECIMAL_DIG\n#  define MAX_EXPONENT_DIGITS 3\n#  define MAX_DOUBLE_DIGITS DBL_MAX_10_EXP\n# endif\n\n# if defined(TRIO_COMPILER_ANCIENT) || !defined(LDBL_DIG)\n#  undef LDBL_DIG\n#  undef LDBL_MANT_DIG\n#  undef LDBL_EPSILON\n#  define LDBL_DIG DBL_DIG\n#  define LDBL_MANT_DIG DBL_MANT_DIG\n#  define LDBL_EPSILON DBL_EPSILON\n# endif\n\n#endif /* TRIO_FEATURE_FLOAT */\n\n/* The maximal number of digits is for base 2 */\n#define MAX_CHARS_IN(x) (sizeof(x) * CHAR_BIT)\n/* The width of a pointer. The number of bits in a hex digit is 4 */\n#define POINTER_WIDTH ((sizeof(\"0x\") - 1) + sizeof(trio_pointer_t) * CHAR_BIT / 4)\n\n#if TRIO_FEATURE_FLOAT\n/* Infinite and Not-A-Number for floating-point */\n# define INFINITE_LOWER \"inf\"\n# define INFINITE_UPPER \"INF\"\n# define LONG_INFINITE_LOWER \"infinite\"\n# define LONG_INFINITE_UPPER \"INFINITE\"\n# define NAN_LOWER \"nan\"\n# define NAN_UPPER \"NAN\"\n#endif\n\n/* Various constants */\nenum {\n  TYPE_PRINT = 1,\n#if TRIO_FEATURE_SCANF\n  TYPE_SCAN  = 2,\n#endif\n\n  /* Flags. FLAGS_LAST must be less than ULONG_MAX */\n  FLAGS_NEW                 = 0,\n  FLAGS_STICKY              = 1,\n  FLAGS_SPACE               = 2 * FLAGS_STICKY,\n  FLAGS_SHOWSIGN            = 2 * FLAGS_SPACE,\n  FLAGS_LEFTADJUST          = 2 * FLAGS_SHOWSIGN,\n  FLAGS_ALTERNATIVE         = 2 * FLAGS_LEFTADJUST,\n  FLAGS_SHORT               = 2 * FLAGS_ALTERNATIVE,\n  FLAGS_SHORTSHORT          = 2 * FLAGS_SHORT,\n  FLAGS_LONG                = 2 * FLAGS_SHORTSHORT,\n  FLAGS_QUAD                = 2 * FLAGS_LONG,\n  FLAGS_LONGDOUBLE          = 2 * FLAGS_QUAD,\n  FLAGS_SIZE_T              = 2 * FLAGS_LONGDOUBLE,\n  FLAGS_PTRDIFF_T           = 2 * FLAGS_SIZE_T,\n  FLAGS_INTMAX_T            = 2 * FLAGS_PTRDIFF_T,\n  FLAGS_NILPADDING          = 2 * FLAGS_INTMAX_T,\n  FLAGS_UNSIGNED            = 2 * FLAGS_NILPADDING,\n  FLAGS_UPPER               = 2 * FLAGS_UNSIGNED,\n  FLAGS_WIDTH               = 2 * FLAGS_UPPER,\n  FLAGS_WIDTH_PARAMETER     = 2 * FLAGS_WIDTH,\n  FLAGS_PRECISION           = 2 * FLAGS_WIDTH_PARAMETER,\n  FLAGS_PRECISION_PARAMETER = 2 * FLAGS_PRECISION,\n  FLAGS_BASE                = 2 * FLAGS_PRECISION_PARAMETER,\n  FLAGS_BASE_PARAMETER      = 2 * FLAGS_BASE,\n  FLAGS_FLOAT_E             = 2 * FLAGS_BASE_PARAMETER,\n  FLAGS_FLOAT_G             = 2 * FLAGS_FLOAT_E,\n  FLAGS_QUOTE               = 2 * FLAGS_FLOAT_G,\n  FLAGS_WIDECHAR            = 2 * FLAGS_QUOTE,\n  FLAGS_IGNORE              = 2 * FLAGS_WIDECHAR,\n  FLAGS_IGNORE_PARAMETER    = 2 * FLAGS_IGNORE,\n  FLAGS_VARSIZE_PARAMETER   = 2 * FLAGS_IGNORE_PARAMETER,\n  FLAGS_FIXED_SIZE          = 2 * FLAGS_VARSIZE_PARAMETER,\n  FLAGS_LAST                = FLAGS_FIXED_SIZE,\n  /* Reused flags */\n  FLAGS_EXCLUDE             = FLAGS_SHORT,\n  FLAGS_USER_DEFINED        = FLAGS_IGNORE,\n  FLAGS_USER_DEFINED_PARAMETER = FLAGS_IGNORE_PARAMETER,\n  FLAGS_ROUNDING            = FLAGS_INTMAX_T,\n  /* Compounded flags */\n  FLAGS_ALL_VARSIZES        = FLAGS_LONG | FLAGS_QUAD | FLAGS_INTMAX_T | FLAGS_PTRDIFF_T | FLAGS_SIZE_T,\n  FLAGS_ALL_SIZES           = FLAGS_ALL_VARSIZES | FLAGS_SHORTSHORT | FLAGS_SHORT,\n\n  NO_POSITION  = -1,\n  NO_WIDTH     =  0,\n  NO_PRECISION = -1,\n  NO_SIZE      = -1,\n\n  /* Do not change these */\n  NO_BASE      = -1,\n  MIN_BASE     =  2,\n  MAX_BASE     = 36,\n  BASE_BINARY  =  2,\n  BASE_OCTAL   =  8,\n  BASE_DECIMAL = 10,\n  BASE_HEX     = 16,\n\n  /* Maximal number of allowed parameters */\n  MAX_PARAMETERS = 64,\n  /* Maximal number of characters in class */\n  MAX_CHARACTER_CLASS = UCHAR_MAX + 1,\n\n#if TRIO_FEATURE_USER_DEFINED\n  /* Maximal string lengths for user-defined specifiers */\n  MAX_USER_NAME = 64,\n  MAX_USER_DATA = 256,\n#endif\n  \n  /* Maximal length of locale separator strings */\n  MAX_LOCALE_SEPARATOR_LENGTH = MB_LEN_MAX,\n  /* Maximal number of integers in grouping */\n  MAX_LOCALE_GROUPS = 64\n};\n\n#define NO_GROUPING ((int)CHAR_MAX)\n\n/* Fundamental formatting parameter types */\n#define FORMAT_SENTINEL  -1\t/* marks end of parameters array */\n#define FORMAT_UNKNOWN   0\n#define FORMAT_INT       1\n#define FORMAT_DOUBLE    2\n#define FORMAT_CHAR      3\n#define FORMAT_STRING    4\n#define FORMAT_POINTER   5\n#define FORMAT_COUNT     6\n#define FORMAT_PARAMETER 7\n#define FORMAT_GROUP     8\n#define FORMAT_ERRNO     9\n#define FORMAT_USER_DEFINED 10\n\n/* Character constants */\n#define CHAR_IDENTIFIER '%'\n#define CHAR_ALT_IDENTIFIER '$'\n#define CHAR_BACKSLASH '\\\\'\n#define CHAR_QUOTE '\\\"'\n#define CHAR_ADJUST ' '\n\n#if TRIO_EXTENSION\n/* Character class expressions */\n# define CLASS_ALNUM \"[:alnum:]\"\n# define CLASS_ALPHA \"[:alpha:]\"\n# define CLASS_BLANK \"[:blank:]\"\n# define CLASS_CNTRL \"[:cntrl:]\"\n# define CLASS_DIGIT \"[:digit:]\"\n# define CLASS_GRAPH \"[:graph:]\"\n# define CLASS_LOWER \"[:lower:]\"\n# define CLASS_PRINT \"[:print:]\"\n# define CLASS_PUNCT \"[:punct:]\"\n# define CLASS_SPACE \"[:space:]\"\n# define CLASS_UPPER \"[:upper:]\"\n# define CLASS_XDIGIT \"[:xdigit:]\"\n#endif\n\n/*\n * SPECIFIERS:\n *\n *\n * a  Hex-float\n * A  Hex-float\n * c  Character\n * C  Widechar character (wint_t)\n * d  Decimal\n * e  Float\n * E  Float\n * F  Float\n * F  Float\n * g  Float\n * G  Float\n * i  Integer\n * m  Error message\n * n  Count\n * o  Octal\n * p  Pointer\n * s  String\n * S  Widechar string (wchar_t *)\n * u  Unsigned\n * x  Hex\n * X  Hex\n * [] Group\n * <> User-defined\n *\n * Reserved:\n *\n * D  Binary Coded Decimal %D(length,precision) (OS/390)\n */\n#define SPECIFIER_CHAR 'c'\n#define SPECIFIER_STRING 's'\n#define SPECIFIER_DECIMAL 'd'\n#define SPECIFIER_INTEGER 'i'\n#define SPECIFIER_UNSIGNED 'u'\n#define SPECIFIER_OCTAL 'o'\n#define SPECIFIER_HEX 'x'\n#define SPECIFIER_HEX_UPPER 'X'\n#if TRIO_FEATURE_FLOAT\n# define SPECIFIER_FLOAT_E 'e'\n# define SPECIFIER_FLOAT_E_UPPER 'E'\n# define SPECIFIER_FLOAT_F 'f'\n# define SPECIFIER_FLOAT_F_UPPER 'F'\n# define SPECIFIER_FLOAT_G 'g'\n# define SPECIFIER_FLOAT_G_UPPER 'G'\n#endif\n#define SPECIFIER_POINTER 'p'\n#if TRIO_FEATURE_SCANF\n# define SPECIFIER_GROUP '['\n# define SPECIFIER_UNGROUP ']'\n#endif\n#define SPECIFIER_COUNT 'n'\n#if TRIO_UNIX98\n# define SPECIFIER_CHAR_UPPER 'C'\n# define SPECIFIER_STRING_UPPER 'S'\n#endif\n#define SPECIFIER_HEXFLOAT 'a'\n#define SPECIFIER_HEXFLOAT_UPPER 'A'\n#define SPECIFIER_ERRNO 'm'\n#if TRIO_FEATURE_BINARY\n# define SPECIFIER_BINARY 'b'\n# define SPECIFIER_BINARY_UPPER 'B'\n#endif\n#if TRIO_FEATURE_USER_DEFINED\n# define SPECIFIER_USER_DEFINED_BEGIN '<'\n# define SPECIFIER_USER_DEFINED_END '>'\n# define SPECIFIER_USER_DEFINED_SEPARATOR ':'\n# define SPECIFIER_USER_DEFINED_EXTRA '|'\n#endif\n\n/*\n * QUALIFIERS:\n *\n *\n * Numbers = d,i,o,u,x,X\n * Float = a,A,e,E,f,F,g,G\n * String = s\n * Char = c\n *\n *\n * 9$ Position\n *      Use the 9th parameter. 9 can be any number between 1 and\n *      the maximal argument\n *\n * 9 Width\n *      Set width to 9. 9 can be any number, but must not be postfixed\n *      by '$'\n *\n * h  Short\n *    Numbers:\n *      (unsigned) short int\n *\n * hh Short short\n *    Numbers:\n *      (unsigned) char\n *\n * l  Long\n *    Numbers:\n *      (unsigned) long int\n *    String:\n *      as the S specifier\n *    Char:\n *      as the C specifier\n *\n * ll Long Long\n *    Numbers:\n *      (unsigned) long long int\n *\n * L  Long Double\n *    Float\n *      long double\n *\n * #  Alternative\n *    Float:\n *      Decimal-point is always present\n *    String:\n *      non-printable characters are handled as \\number\n *\n *    Spacing\n *\n * +  Sign\n *\n * -  Alignment\n *\n * .  Precision\n *\n * *  Parameter\n *    print: use parameter\n *    scan: no parameter (ignore)\n *\n * q  Quad\n *\n * Z  size_t\n *\n * w  Widechar\n *\n * '  Thousands/quote\n *    Numbers:\n *      Integer part grouped in thousands\n *    Binary numbers:\n *      Number grouped in nibbles (4 bits)\n *    String:\n *      Quoted string\n *\n * j  intmax_t\n * t  prtdiff_t\n * z  size_t\n *\n * !  Sticky\n * @  Parameter (for both print and scan)\n *\n * I  n-bit Integer\n *    Numbers:\n *      The following options exists\n *        I8  = 8-bit integer\n *        I16 = 16-bit integer\n *        I32 = 32-bit integer\n *        I64 = 64-bit integer\n */\n#define QUALIFIER_POSITION '$'\n#define QUALIFIER_SHORT 'h'\n#define QUALIFIER_LONG 'l'\n#define QUALIFIER_LONG_UPPER 'L'\n#define QUALIFIER_ALTERNATIVE '#'\n#define QUALIFIER_SPACE ' '\n#define QUALIFIER_PLUS '+'\n#define QUALIFIER_MINUS '-'\n#define QUALIFIER_DOT '.'\n#define QUALIFIER_STAR '*'\n#define QUALIFIER_CIRCUMFLEX '^' /* For scanlists */\n#define QUALIFIER_SIZE_T 'z'\n#define QUALIFIER_PTRDIFF_T 't'\n#define QUALIFIER_INTMAX_T 'j'\n#define QUALIFIER_QUAD 'q'\n#define QUALIFIER_SIZE_T_UPPER 'Z'\n#if TRIO_MISC\n# define QUALIFIER_WIDECHAR 'w'\n#endif\n#define QUALIFIER_FIXED_SIZE 'I'\n#define QUALIFIER_QUOTE '\\''\n#define QUALIFIER_STICKY '!'\n#define QUALIFIER_VARSIZE '&' /* This should remain undocumented */\n#define QUALIFIER_ROUNDING_UPPER 'R'\n#if TRIO_EXTENSION\n# define QUALIFIER_PARAM '@' /* Experimental */\n# define QUALIFIER_COLON ':' /* For scanlists */\n# define QUALIFIER_EQUAL '=' /* For scanlists */\n#endif\n\n\n/*************************************************************************\n *\n * Internal Structures\n *\n *************************************************************************/\n\n/* Parameters */\ntypedef struct {\n  /* An indication of which entry in the data union is used */\n  int type;\n  /* The flags */\n  trio_flags_t flags;\n  /* The width qualifier */\n  int width;\n  /* The precision qualifier */\n  int precision;\n  /* The base qualifier */\n  int base;\n  /* Base from specifier */\n  int baseSpecifier;\n  /* The size for the variable size qualifier */\n  int varsize;\n  /* Offset of the first character of the specifier */\n  int beginOffset;\n  /* Offset of the first character after the specifier */\n  int endOffset;\n  /* Position in the argument list that this parameter refers to */\n  int position;\n  /* The data from the argument list */\n  union {\n    char *string;\n#if TRIO_FEATURE_WIDECHAR\n    trio_wchar_t *wstring;\n#endif\n    trio_pointer_t pointer;\n    union {\n      trio_intmax_t as_signed;\n      trio_uintmax_t as_unsigned;\n    } number;\n#if TRIO_FEATURE_FLOAT\n    double doubleNumber;\n    double *doublePointer;\n    trio_long_double_t longdoubleNumber;\n    trio_long_double_t *longdoublePointer;\n#endif\n    int errorNumber;\n  } data;\n#if TRIO_FEATURE_USER_DEFINED\n  /* For the user-defined specifier */\n  union {\n    char namespace[MAX_USER_NAME];\n    int handler;        /* if flags & FLAGS_USER_DEFINED_PARAMETER */\n  } user_defined;\n  char user_data[MAX_USER_DATA];\n#endif\n} trio_parameter_t;\n\n/* Container for customized functions */\ntypedef struct {\n  union {\n    trio_outstream_t out;\n    trio_instream_t in;\n  } stream;\n  trio_pointer_t closure;\n} trio_custom_t;\n\n/* General trio \"class\" */\ntypedef struct _trio_class_t {\n  /*\n   * The function to write characters to a stream.\n   */\n  void (*OutStream) TRIO_PROTO((struct _trio_class_t *, int));\n  /*\n   * The function to read characters from a stream.\n   */\n  void (*InStream) TRIO_PROTO((struct _trio_class_t *, int *));\n  /*\n   * The current location in the stream.\n   */\n  trio_pointer_t location;\n  /*\n   * The character currently being processed.\n   */\n  int current;\n  /*\n   * The number of characters that would have been written/read\n   * if there had been sufficient space.\n   */\n  int processed;\n  /*\n   * The number of characters that are actually written/read.\n   * Processed and committed will only differ for the *nprintf\n   * and *nscanf functions.\n   */\n  int committed;\n  /*\n   * The upper limit of characters that may be written/read.\n   */\n  int max;\n  /*\n   * The last output error that was detected.\n   */\n  int error;\n} trio_class_t;\n\n/* References (for user-defined callbacks) */\ntypedef struct _trio_reference_t {\n  trio_class_t *data;\n  trio_parameter_t *parameter;\n} trio_reference_t;\n\n#if TRIO_FEATURE_USER_DEFINED\n/* Registered entries (for user-defined callbacks) */\ntypedef struct _trio_userdef_t {\n  struct _trio_userdef_t *next;\n  trio_callback_t callback;\n  char *name;\n} trio_userdef_t;\n#endif\n\n/*************************************************************************\n *\n * Internal Variables\n *\n *************************************************************************/\n\nstatic TRIO_CONST char rcsid[] = \"@(#)$Id: trio.c,v 1.112 2008/11/09 10:52:26 breese Exp $\";\n\n#if TRIO_FEATURE_FLOAT\n/*\n * Need this to workaround a parser bug in HP C/iX compiler that fails\n * to resolves macro definitions that includes type 'long double',\n * e.g: va_arg(arg_ptr, long double)\n */\n# if defined(TRIO_PLATFORM_MPEIX)\nstatic TRIO_CONST trio_long_double_t ___dummy_long_double = 0;\n# endif\n#endif\n\nstatic TRIO_CONST char internalNullString[] = \"(nil)\";\n\n#if defined(USE_LOCALE)\nstatic struct lconv *internalLocaleValues = NULL;\n#endif\n\n/*\n * UNIX98 says \"in a locale where the radix character is not defined,\n * the radix character defaults to a period (.)\"\n */\n#if TRIO_FEATURE_FLOAT || TRIO_FEATURE_LOCALE || defined(USE_LOCALE)\nstatic int internalDecimalPointLength = 1;\nstatic char internalDecimalPoint = '.';\nstatic char internalDecimalPointString[MAX_LOCALE_SEPARATOR_LENGTH + 1] = \".\";\n#endif\n#if TRIO_FEATURE_QUOTE || TRIO_FEATURE_LOCALE || TRIO_EXTENSION\nstatic int internalThousandSeparatorLength = 1;\nstatic char internalThousandSeparator[MAX_LOCALE_SEPARATOR_LENGTH + 1] = \",\";\nstatic char internalGrouping[MAX_LOCALE_GROUPS] = { (char)NO_GROUPING };\n#endif\n\nstatic TRIO_CONST char internalDigitsLower[] = \"0123456789abcdefghijklmnopqrstuvwxyz\";\nstatic TRIO_CONST char internalDigitsUpper[] = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n#if TRIO_FEATURE_SCANF\nstatic BOOLEAN_T internalDigitsUnconverted = TRUE;\nstatic int internalDigitArray[128];\n# if TRIO_EXTENSION\nstatic BOOLEAN_T internalCollationUnconverted = TRUE;\nstatic char internalCollationArray[MAX_CHARACTER_CLASS][MAX_CHARACTER_CLASS];\n# endif\n#endif\n\n#if TRIO_FEATURE_USER_DEFINED\nstatic TRIO_VOLATILE trio_callback_t internalEnterCriticalRegion = NULL;\nstatic TRIO_VOLATILE trio_callback_t internalLeaveCriticalRegion = NULL;\nstatic trio_userdef_t *internalUserDef = NULL;\n#endif\n\n\n/*************************************************************************\n *\n * Internal Functions\n *\n ************************************************************************/\n\n#if defined(TRIO_EMBED_NAN)\n# include \"trionan.c\"\n#endif\n\n#if defined(TRIO_EMBED_STRING)\n# include \"triostr.c\"\n#endif\n\n/*************************************************************************\n * TrioIsQualifier\n *\n * Description:\n *  Remember to add all new qualifiers to this function.\n *  QUALIFIER_POSITION must not be added.\n */\nTRIO_PRIVATE BOOLEAN_T\nTrioIsQualifier\nTRIO_ARGS1((character),\n\t   TRIO_CONST char character)\n{\n  /* QUALIFIER_POSITION is not included */\n  switch (character)\n    {\n    case '0': case '1': case '2': case '3': case '4':\n    case '5': case '6': case '7': case '8': case '9':\n    case QUALIFIER_PLUS:\n    case QUALIFIER_MINUS:\n    case QUALIFIER_SPACE:\n    case QUALIFIER_DOT:\n    case QUALIFIER_STAR:\n    case QUALIFIER_ALTERNATIVE:\n    case QUALIFIER_SHORT:\n    case QUALIFIER_LONG:\n    case QUALIFIER_CIRCUMFLEX:\n    case QUALIFIER_LONG_UPPER:\n    case QUALIFIER_SIZE_T:\n    case QUALIFIER_PTRDIFF_T:\n    case QUALIFIER_INTMAX_T:\n    case QUALIFIER_QUAD:\n    case QUALIFIER_SIZE_T_UPPER:\n#if defined(QUALIFIER_WIDECHAR)\n    case QUALIFIER_WIDECHAR:\n#endif\n    case QUALIFIER_QUOTE:\n    case QUALIFIER_STICKY:\n    case QUALIFIER_VARSIZE:\n#if defined(QUALIFIER_PARAM)\n    case QUALIFIER_PARAM:\n#endif\n    case QUALIFIER_FIXED_SIZE:\n    case QUALIFIER_ROUNDING_UPPER:\n      return TRUE;\n    default:\n      return FALSE;\n    }\n}\n\n/*************************************************************************\n * TrioSetLocale\n */\n#if defined(USE_LOCALE)\nTRIO_PRIVATE void\nTrioSetLocale(TRIO_NOARGS)\n{\n  internalLocaleValues = (struct lconv *)localeconv();\n  if (internalLocaleValues)\n    {\n      if ((internalLocaleValues->decimal_point) &&\n\t  (internalLocaleValues->decimal_point[0] != NIL))\n\t{\n\t  internalDecimalPointLength = trio_length(internalLocaleValues->decimal_point);\n\t  if (internalDecimalPointLength == 1)\n\t    {\n\t      internalDecimalPoint = internalLocaleValues->decimal_point[0];\n\t    }\n\t  else\n\t    {\n\t      internalDecimalPoint = NIL;\n\t      trio_copy_max(internalDecimalPointString,\n\t\t\t    sizeof(internalDecimalPointString),\n\t\t\t    internalLocaleValues->decimal_point);\n\t    }\n\t}\n# if TRIO_EXTENSION\n      if ((internalLocaleValues->thousands_sep) &&\n\t  (internalLocaleValues->thousands_sep[0] != NIL))\n\t{\n\t  trio_copy_max(internalThousandSeparator,\n\t\t\tsizeof(internalThousandSeparator),\n\t\t\tinternalLocaleValues->thousands_sep);\n\t  internalThousandSeparatorLength = trio_length(internalThousandSeparator);\n\t}\n# endif\n# if TRIO_EXTENSION\n      if ((internalLocaleValues->grouping) &&\n\t  (internalLocaleValues->grouping[0] != NIL))\n\t{\n\t  trio_copy_max(internalGrouping,\n\t\t\tsizeof(internalGrouping),\n\t\t\tinternalLocaleValues->grouping);\n\t}\n# endif\n    }\n}\n#endif /* defined(USE_LOCALE) */\n\n#if TRIO_FEATURE_FLOAT && TRIO_FEATURE_QUOTE\nTRIO_PRIVATE int\nTrioCalcThousandSeparatorLength\nTRIO_ARGS1((digits),\n\t   int digits)\n{\n  int count = 0;\n  int step = NO_GROUPING;\n  char *groupingPointer = internalGrouping;\n\n  while (digits > 0)\n    {\n      if (*groupingPointer == CHAR_MAX)\n\t{\n\t  /* Disable grouping */\n\t  break; /* while */\n\t}\n      else if (*groupingPointer == 0)\n\t{\n\t  /* Repeat last group */\n\t  if (step == NO_GROUPING)\n\t    {\n\t      /* Error in locale */\n\t      break; /* while */\n\t    }\n\t}\n      else\n\t{\n\t  step = *groupingPointer++;\n\t}\n      if (digits > step)\n\tcount += internalThousandSeparatorLength;\n      digits -= step;\n    }\n  return count;\n}\n#endif /* TRIO_FEATURE_FLOAT && TRIO_FEATURE_QUOTE */\n\n#if TRIO_FEATURE_QUOTE\nTRIO_PRIVATE BOOLEAN_T\nTrioFollowedBySeparator\nTRIO_ARGS1((position),\n\t   int position)\n{\n  int step = 0;\n  char *groupingPointer = internalGrouping;\n\n  position--;\n  if (position == 0)\n    return FALSE;\n  while (position > 0)\n    {\n      if (*groupingPointer == CHAR_MAX)\n\t{\n\t  /* Disable grouping */\n\t  break; /* while */\n\t}\n      else if (*groupingPointer != 0)\n\t{\n\t  step = *groupingPointer++;\n\t}\n      if (step == 0)\n\tbreak;\n      position -= step;\n    }\n  return (position == 0);\n}\n#endif /* TRIO_FEATURE_QUOTE */\n\n/*************************************************************************\n * TrioGetPosition\n *\n * Get the %n$ position.\n */\nTRIO_PRIVATE int\nTrioGetPosition\nTRIO_ARGS2((format, offsetPointer),\n\t   TRIO_CONST char *format,\n\t   int *offsetPointer)\n{\n#if TRIO_FEATURE_POSITIONAL\n  char *tmpformat;\n  int number = 0;\n  int offset = *offsetPointer;\n\n  number = (int)trio_to_long(&format[offset], &tmpformat, BASE_DECIMAL);\n  offset = (int)(tmpformat - format);\n  if ((number != 0) && (QUALIFIER_POSITION == format[offset++]))\n    {\n      *offsetPointer = offset;\n      /*\n       * number is decreased by 1, because n$ starts from 1, whereas\n       * the array it is indexing starts from 0.\n       */\n      return number - 1;\n    }\n#endif\n  return NO_POSITION;\n}\n\n/*************************************************************************\n * TrioFindNamespace\n *\n * Find registered user-defined specifier.\n * The prev argument is used for optimization only.\n */\n#if TRIO_FEATURE_USER_DEFINED\nTRIO_PRIVATE trio_userdef_t *\nTrioFindNamespace\nTRIO_ARGS2((name, prev),\n\t   TRIO_CONST char *name,\n\t   trio_userdef_t **prev)\n{\n  trio_userdef_t *def;\n  \n  if (internalEnterCriticalRegion)\n    (void)internalEnterCriticalRegion(NULL);\n  \n  for (def = internalUserDef; def; def = def->next)\n    {\n      /* Case-sensitive string comparison */\n      if (trio_equal_case(def->name, name))\n\tbreak;\n      \n      if (prev)\n\t*prev = def;\n    }\n  \n  if (internalLeaveCriticalRegion)\n    (void)internalLeaveCriticalRegion(NULL);\n  \n  return def;\n}\n#endif\n\n/*************************************************************************\n * TrioPower\n *\n * Description:\n *  Calculate pow(base, exponent), where number and exponent are integers.\n */\n#if TRIO_FEATURE_FLOAT\nTRIO_PRIVATE trio_long_double_t\nTrioPower\nTRIO_ARGS2((number, exponent),\n\t   int number,\n\t   int exponent)\n{\n  trio_long_double_t result;\n\n  if (number == 10)\n    {\n      switch (exponent)\n\t{\n\t  /* Speed up calculation of common cases */\n\tcase 0:\n\t  result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E-1);\n\t  break;\n\tcase 1:\n\t  result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+0);\n\t  break;\n\tcase 2:\n\t  result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+1);\n\t  break;\n\tcase 3:\n\t  result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+2);\n\t  break;\n\tcase 4:\n\t  result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+3);\n\t  break;\n\tcase 5:\n\t  result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+4);\n\t  break;\n\tcase 6:\n\t  result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+5);\n\t  break;\n\tcase 7:\n\t  result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+6);\n\t  break;\n\tcase 8:\n\t  result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+7);\n\t  break;\n\tcase 9:\n\t  result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+8);\n\t  break;\n\tdefault:\n\t  result = trio_pow((trio_long_double_t)number,\n\t\t\t    (trio_long_double_t)exponent);\n\t  break;\n\t}\n    }\n  else\n    {\n      return trio_pow((trio_long_double_t)number,\n\t\t      (trio_long_double_t)exponent);\n    }\n  return result;\n}\n#endif /* TRIO_FEATURE_FLOAT */\n\n/*************************************************************************\n * TrioLogarithm\n */\n#if TRIO_FEATURE_FLOAT\nTRIO_PRIVATE trio_long_double_t\nTrioLogarithm\nTRIO_ARGS2((number, base),\n\t   trio_long_double_t number,\n\t   int base)\n{\n  trio_long_double_t result;\n\n  if (number <= 0.0)\n    {\n      /* xlC crashes on log(0) */\n      result = (number == 0.0) ? trio_ninf() : trio_nan();\n    }\n  else\n    {\n      if (base == 10)\n\t{\n\t  result = trio_log10(number);\n\t}\n      else\n\t{\n\t  result = trio_log10(number) / trio_log10((double)base);\n\t}\n    }\n  return result;\n}\n#endif /* TRIO_FEATURE_FLOAT */\n\n/*************************************************************************\n * TrioLogarithmBase\n */\n#if TRIO_FEATURE_FLOAT\nTRIO_PRIVATE double\nTrioLogarithmBase\nTRIO_ARGS1((base),\n\t   int base)\n{\n  switch (base)\n    {\n    case BASE_BINARY : return 1.0;\n    case BASE_OCTAL  : return 3.0;\n    case BASE_DECIMAL: return 3.321928094887362345;\n    case BASE_HEX    : return 4.0;\n    default          : return TrioLogarithm((double)base, 2);\n    }\n}\n#endif /* TRIO_FEATURE_FLOAT */\n\n/*************************************************************************\n * TrioParseQualifiers\n *\n * Description:\n *  Parse the qualifiers of a potential conversion specifier\n */\nTRIO_PRIVATE int\nTrioParseQualifiers\nTRIO_ARGS4((type, format, offset, parameter),\n\t   int type,\n\t   TRIO_CONST char *format,\n\t   int offset,\n\t   trio_parameter_t *parameter)\n{\n  char ch;\n  int dots = 0;  /* Count number of dots in modifier part */\n  char *tmpformat;\n\n  parameter->beginOffset = offset - 1;\n  parameter->flags = FLAGS_NEW;\n  parameter->position = TrioGetPosition(format, &offset);\n\n  /* Default values */\n  parameter->width = NO_WIDTH;\n  parameter->precision = NO_PRECISION;\n  parameter->base = NO_BASE;\n  parameter->varsize = NO_SIZE;\n\n  while (TrioIsQualifier(format[offset]))\n    {\n      ch = format[offset++];\n\n      switch (ch)\n        {\n\tcase QUALIFIER_SPACE:\n\t  parameter->flags |= FLAGS_SPACE;\n\t  break;\n\n\tcase QUALIFIER_PLUS:\n\t  parameter->flags |= FLAGS_SHOWSIGN;\n\t  break;\n\n\tcase QUALIFIER_MINUS:\n\t  parameter->flags |= FLAGS_LEFTADJUST;\n\t  parameter->flags &= ~FLAGS_NILPADDING;\n\t  break;\n\n\tcase QUALIFIER_ALTERNATIVE:\n\t  parameter->flags |= FLAGS_ALTERNATIVE;\n\t  break;\n\n\tcase QUALIFIER_DOT:\n\t  if (dots == 0) /* Precision */\n\t    {\n\t      dots++;\n\n\t      /* Skip if no precision */\n\t      if (QUALIFIER_DOT == format[offset])\n\t\tbreak;\n\n\t      /* After the first dot we have the precision */\n\t      parameter->flags |= FLAGS_PRECISION;\n\t      if ((QUALIFIER_STAR == format[offset])\n#if defined(QUALIFIER_PARAM)\n\t\t  || (QUALIFIER_PARAM == format[offset])\n#endif\n\t\t  )\n\t\t{\n\t\t  offset++;\n\t\t  parameter->flags |= FLAGS_PRECISION_PARAMETER;\n\t\t  parameter->precision = TrioGetPosition(format, &offset);\n\t\t}\n\t      else\n\t\t{\n\t\t  parameter->precision = trio_to_long(&format[offset],\n\t\t\t\t\t\t      &tmpformat,\n\t\t\t\t\t\t      BASE_DECIMAL);\n\t\t  offset = (int)(tmpformat - format);\n\t\t}\n\t    }\n\t  else if (dots == 1) /* Base */\n\t    {\n\t      dots++;\n\n\t      /* After the second dot we have the base */\n\t      parameter->flags |= FLAGS_BASE;\n\t      if ((QUALIFIER_STAR == format[offset])\n#if defined(QUALIFIER_PARAM)\n\t\t  || (QUALIFIER_PARAM == format[offset])\n#endif\n\t\t  )\n\t\t{\n\t\t  offset++;\n\t\t  parameter->flags |= FLAGS_BASE_PARAMETER;\n\t\t  parameter->base = TrioGetPosition(format, &offset);\n\t\t}\n\t      else\n\t\t{\n\t\t  parameter->base = trio_to_long(&format[offset],\n\t\t\t\t\t\t &tmpformat,\n\t\t\t\t\t\t BASE_DECIMAL);\n\t\t  if (parameter->base > MAX_BASE)\n\t\t    return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);\n\t\t  offset = (int)(tmpformat - format);\n\t\t}\n\t    }\n\t  else\n\t    {\n\t      return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);\n\t    }\n\t  break; /* QUALIFIER_DOT */\n\n#if defined(QUALIFIER_PARAM)\n\tcase QUALIFIER_PARAM:\n\t  parameter->type = TYPE_PRINT;\n\t  /* FALLTHROUGH */\n#endif\n\tcase QUALIFIER_STAR:\n\t  /* This has different meanings for print and scan */\n\t  if (TYPE_PRINT == type)\n\t    {\n\t      /* Read with from parameter */\n\t      parameter->flags |= (FLAGS_WIDTH | FLAGS_WIDTH_PARAMETER);\n\t      int width = TrioGetPosition(format, &offset);\n\t      if (NO_POSITION != width) parameter->width = width;\n\t      /* else keep parameter->width = NO_WIDTH which != NO_POSITION */\n\t    }\n#if TRIO_FEATURE_SCANF\n\t  else\n\t    {\n\t      /* Scan, but do not store result */\n\t      parameter->flags |= FLAGS_IGNORE;\n\t    }\n#endif\n\t  break; /* QUALIFIER_STAR */\n\n\tcase '0':\n\t  if (! (parameter->flags & FLAGS_LEFTADJUST))\n\t    parameter->flags |= FLAGS_NILPADDING;\n\t  /* FALLTHROUGH */\n\tcase '1': case '2': case '3': case '4':\n\tcase '5': case '6': case '7': case '8': case '9':\n\t  parameter->flags |= FLAGS_WIDTH;\n\t  /*\n\t   * &format[offset - 1] is used to \"rewind\" the read\n\t   * character from format\n\t   */\n\t  parameter->width = trio_to_long(&format[offset - 1],\n\t\t\t\t\t  &tmpformat,\n\t\t\t\t\t  BASE_DECIMAL);\n\t  offset = (int)(tmpformat - format);\n\t  break;\n\n\tcase QUALIFIER_SHORT:\n\t  if (parameter->flags & FLAGS_SHORTSHORT)\n\t    return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);\n\t  else if (parameter->flags & FLAGS_SHORT)\n\t    parameter->flags |= FLAGS_SHORTSHORT;\n\t  else\n\t    parameter->flags |= FLAGS_SHORT;\n\t  break;\n\n\tcase QUALIFIER_LONG:\n\t  if (parameter->flags & FLAGS_QUAD)\n\t    return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);\n\t  else if (parameter->flags & FLAGS_LONG)\n\t    parameter->flags |= FLAGS_QUAD;\n\t  else\n\t    parameter->flags |= FLAGS_LONG;\n\t  break;\n\n#if TRIO_FEATURE_LONGDOUBLE\n\tcase QUALIFIER_LONG_UPPER:\n\t  parameter->flags |= FLAGS_LONGDOUBLE;\n\t  break;\n#endif\n\n#if TRIO_FEATURE_SIZE_T\n\tcase QUALIFIER_SIZE_T:\n\t  parameter->flags |= FLAGS_SIZE_T;\n\t  /* Modify flags for later truncation of number */\n\t  if (sizeof(size_t) == sizeof(trio_ulonglong_t))\n\t    parameter->flags |= FLAGS_QUAD;\n\t  else if (sizeof(size_t) == sizeof(long))\n\t    parameter->flags |= FLAGS_LONG;\n\t  break;\n#endif\n\n#if TRIO_FEATURE_PTRDIFF_T\n\tcase QUALIFIER_PTRDIFF_T:\n\t  parameter->flags |= FLAGS_PTRDIFF_T;\n\t  if (sizeof(ptrdiff_t) == sizeof(trio_ulonglong_t))\n\t    parameter->flags |= FLAGS_QUAD;\n\t  else if (sizeof(ptrdiff_t) == sizeof(long))\n\t    parameter->flags |= FLAGS_LONG;\n\t  break;\n#endif\n\n#if TRIO_FEATURE_INTMAX_T\n\tcase QUALIFIER_INTMAX_T:\n\t  parameter->flags |= FLAGS_INTMAX_T;\n\t  if (sizeof(trio_intmax_t) == sizeof(trio_ulonglong_t))\n\t    parameter->flags |= FLAGS_QUAD;\n\t  else if (sizeof(trio_intmax_t) == sizeof(long))\n\t    parameter->flags |= FLAGS_LONG;\n\t  break;\n#endif\n\n#if TRIO_FEATURE_QUAD\n\tcase QUALIFIER_QUAD:\n\t  parameter->flags |= FLAGS_QUAD;\n\t  break;\n#endif\n\n#if TRIO_FEATURE_FIXED_SIZE\n\tcase QUALIFIER_FIXED_SIZE:\n\t  if (parameter->flags & FLAGS_FIXED_SIZE)\n\t    return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);\n\n\t  if (parameter->flags & (FLAGS_ALL_SIZES |\n\t\t\t\t  FLAGS_LONGDOUBLE |\n\t\t\t\t  FLAGS_WIDECHAR |\n\t\t\t\t  FLAGS_VARSIZE_PARAMETER))\n\t    return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);\n\n\t  if ((format[offset] == '6') &&\n\t      (format[offset + 1] == '4'))\n\t    {\n\t      parameter->varsize = sizeof(trio_int64_t);\n\t      offset += 2;\n\t    }\n\t  else if ((format[offset] == '3') &&\n\t\t   (format[offset + 1] == '2'))\n\t    {\n\t      parameter->varsize = sizeof(trio_int32_t);\n\t      offset += 2;\n\t    }\n\t  else if ((format[offset] == '1') &&\n\t\t   (format[offset + 1] == '6'))\n\t    {\n\t      parameter->varsize = sizeof(trio_int16_t);\n\t      offset += 2;\n\t    }\n\t  else if (format[offset] == '8')\n\t    {\n\t      parameter->varsize = sizeof(trio_int8_t);\n\t      offset++;\n\t    }\n\t  else\n\t    return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);\n\n\t  parameter->flags |= FLAGS_FIXED_SIZE;\n\t  break;\n#endif /* TRIO_FEATURE_FIXED_SIZE */\n\n#if defined(QUALIFIER_WIDECHAR)\n\tcase QUALIFIER_WIDECHAR:\n\t  parameter->flags |= FLAGS_WIDECHAR;\n\t  break;\n#endif\n\n#if TRIO_FEATURE_SIZE_T_UPPER\n\tcase QUALIFIER_SIZE_T_UPPER:\n\t  break;\n#endif\n\n#if TRIO_FEATURE_QUOTE\n\tcase QUALIFIER_QUOTE:\n\t  parameter->flags |= FLAGS_QUOTE;\n\t  break;\n#endif\n\n#if TRIO_FEATURE_STICKY\n\tcase QUALIFIER_STICKY:\n\t  parameter->flags |= FLAGS_STICKY;\n\t  break;\n#endif\n\n#if TRIO_FEATURE_VARSIZE\n\tcase QUALIFIER_VARSIZE:\n\t  parameter->flags |= FLAGS_VARSIZE_PARAMETER;\n\t  break;\n#endif\n\n#if TRIO_FEATURE_ROUNDING\n\tcase QUALIFIER_ROUNDING_UPPER:\n\t  parameter->flags |= FLAGS_ROUNDING;\n\t  break;\n#endif\n\n\tdefault:\n\t  /* Bail out completely to make the error more obvious */\n\t  return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);\n\t}\n    } /* while qualifier */\n\n  parameter->endOffset = offset;\n\n  return 0;\n}\n\n/*************************************************************************\n * TrioParseSpecifier\n *\n * Description:\n *  Parse the specifier part of a potential conversion specifier\n */\nTRIO_PRIVATE int\nTrioParseSpecifier\nTRIO_ARGS4((type, format, offset, parameter),\n\t   int type,\n\t   TRIO_CONST char *format,\n\t   int offset,\n\t   trio_parameter_t *parameter)\n{\n  parameter->baseSpecifier = NO_BASE;\n\n  switch (format[offset++])\n    {\n#if defined(SPECIFIER_CHAR_UPPER)\n    case SPECIFIER_CHAR_UPPER:\n      parameter->flags |= FLAGS_WIDECHAR;\n      /* FALLTHROUGH */\n#endif\n    case SPECIFIER_CHAR:\n      if (parameter->flags & FLAGS_LONG)\n\tparameter->flags |= FLAGS_WIDECHAR;\n      else if (parameter->flags & FLAGS_SHORT)\n\tparameter->flags &= ~FLAGS_WIDECHAR;\n      parameter->type = FORMAT_CHAR;\n      break;\n\n#if defined(SPECIFIER_STRING_UPPER)\n    case SPECIFIER_STRING_UPPER:\n      parameter->flags |= FLAGS_WIDECHAR;\n      /* FALLTHROUGH */\n#endif\n    case SPECIFIER_STRING:\n      if (parameter->flags & FLAGS_LONG)\n\tparameter->flags |= FLAGS_WIDECHAR;\n      else if (parameter->flags & FLAGS_SHORT)\n\tparameter->flags &= ~FLAGS_WIDECHAR;\n      parameter->type = FORMAT_STRING;\n      break;\n\n#if defined(SPECIFIER_GROUP)\n    case SPECIFIER_GROUP:\n      if (TYPE_SCAN == type)\n\t{\n\t  int depth = 1;\n\t  parameter->type = FORMAT_GROUP;\n\t  if (format[offset] == QUALIFIER_CIRCUMFLEX)\n\t    offset++;\n\t  if (format[offset] == SPECIFIER_UNGROUP)\n\t    offset++;\n\t  if (format[offset] == QUALIFIER_MINUS)\n\t    offset++;\n\t  /* Skip nested brackets */\n\t  while (format[offset] != NIL)\n\t    {\n\t      if (format[offset] == SPECIFIER_GROUP)\n\t\t{\n\t\t  depth++;\n\t\t}\n\t      else if (format[offset] == SPECIFIER_UNGROUP)\n\t      {\n\t\tif (--depth <= 0)\n\t\t  {\n\t\t    offset++;\n\t\t    break;\n\t\t  }\n\t      }\n\t      offset++;\n\t    }\n\t}\n      break;\n#endif /* defined(SPECIFIER_GROUP) */\n\n    case SPECIFIER_INTEGER:\n      parameter->type = FORMAT_INT;\n      break;\n\n    case SPECIFIER_UNSIGNED:\n      parameter->flags |= FLAGS_UNSIGNED;\n      parameter->type = FORMAT_INT;\n      break;\n\n    case SPECIFIER_DECIMAL:\n      parameter->baseSpecifier = BASE_DECIMAL;\n      parameter->type = FORMAT_INT;\n      break;\n\n    case SPECIFIER_OCTAL:\n      parameter->flags |= FLAGS_UNSIGNED;\n      parameter->baseSpecifier = BASE_OCTAL;\n      parameter->type = FORMAT_INT;\n      break;\n\n#if TRIO_FEATURE_BINARY\n    case SPECIFIER_BINARY_UPPER:\n      parameter->flags |= FLAGS_UPPER;\n      /* FALLTHROUGH */\n    case SPECIFIER_BINARY:\n      parameter->flags |= FLAGS_NILPADDING;\n      parameter->baseSpecifier = BASE_BINARY;\n      parameter->type = FORMAT_INT;\n      break;\n#endif\n\n    case SPECIFIER_HEX_UPPER:\n      parameter->flags |= FLAGS_UPPER;\n      /* FALLTHROUGH */\n    case SPECIFIER_HEX:\n      parameter->flags |= FLAGS_UNSIGNED;\n      parameter->baseSpecifier = BASE_HEX;\n      parameter->type = FORMAT_INT;\n      break;\n\n#if defined(SPECIFIER_FLOAT_E)\n# if defined(SPECIFIER_FLOAT_E_UPPER)\n    case SPECIFIER_FLOAT_E_UPPER:\n      parameter->flags |= FLAGS_UPPER;\n      /* FALLTHROUGH */\n# endif\n    case SPECIFIER_FLOAT_E:\n      parameter->flags |= FLAGS_FLOAT_E;\n      parameter->type = FORMAT_DOUBLE;\n      break;\n#endif\n\n#if defined(SPECIFIER_FLOAT_G)\n# if defined(SPECIFIER_FLOAT_G_UPPER)\n    case SPECIFIER_FLOAT_G_UPPER:\n      parameter->flags |= FLAGS_UPPER;\n      /* FALLTHROUGH */\n# endif\n    case SPECIFIER_FLOAT_G:\n      parameter->flags |= FLAGS_FLOAT_G;\n      parameter->type = FORMAT_DOUBLE;\n      break;\n#endif\n\n#if defined(SPECIFIER_FLOAT_F)\n# if defined(SPECIFIER_FLOAT_F_UPPER)\n    case SPECIFIER_FLOAT_F_UPPER:\n      parameter->flags |= FLAGS_UPPER;\n      /* FALLTHROUGH */\n# endif\n    case SPECIFIER_FLOAT_F:\n      parameter->type = FORMAT_DOUBLE;\n      break;\n#endif\n\n#if defined(TRIO_COMPILER_VISUALC)\n# pragma warning( push )\n# pragma warning( disable : 4127 ) /* Conditional expression is constant */\n#endif\n    case SPECIFIER_POINTER:\n      if (sizeof(trio_pointer_t) == sizeof(trio_ulonglong_t))\n\tparameter->flags |= FLAGS_QUAD;\n      else if (sizeof(trio_pointer_t) == sizeof(long))\n\tparameter->flags |= FLAGS_LONG;\n      parameter->type = FORMAT_POINTER;\n      break;\n#if defined(TRIO_COMPILER_VISUALC)\n# pragma warning( pop )\n#endif\n\n    case SPECIFIER_COUNT:\n      parameter->type = FORMAT_COUNT;\n      break;\n\n#if TRIO_FEATURE_HEXFLOAT\n    case SPECIFIER_HEXFLOAT_UPPER:\n      parameter->flags |= FLAGS_UPPER;\n      /* FALLTHROUGH */\n    case SPECIFIER_HEXFLOAT:\n      parameter->baseSpecifier = BASE_HEX;\n      parameter->type = FORMAT_DOUBLE;\n      break;\n#endif\n\n#if TRIO_FEATURE_ERRNO\n    case SPECIFIER_ERRNO:\n      parameter->type = FORMAT_ERRNO;\n      break;\n#endif\n\n#if TRIO_FEATURE_USER_DEFINED\n    case SPECIFIER_USER_DEFINED_BEGIN:\n      {\n\tunsigned int max;\n\tint without_namespace = TRUE;\n\tchar* tmpformat = (char *)&format[offset];\n\tint ch;\n\n\tparameter->type = FORMAT_USER_DEFINED;\n\tparameter->user_defined.namespace[0] = NIL;\n\n\twhile ((ch = format[offset]) != NIL)\n\t  {\n\t    offset++;\n\t    if ((ch == SPECIFIER_USER_DEFINED_END) || (ch == SPECIFIER_USER_DEFINED_EXTRA))\n\t      {\n\t\tif (without_namespace)\n\t\t  /* No namespace, handler will be passed as an argument */\n\t\t  parameter->flags |= FLAGS_USER_DEFINED_PARAMETER;\n\n\t\t/* Copy the user data */\n\t\tmax = (unsigned int)(&format[offset] - tmpformat);\n\t\tif (max > MAX_USER_DATA)\n\t\t  max = MAX_USER_DATA;\n\t\ttrio_copy_max(parameter->user_data, max, tmpformat);\n\n\t\t/* Skip extra data (which is only there to keep the compiler happy) */\n\t\twhile ((ch != NIL) && (ch != SPECIFIER_USER_DEFINED_END))\n\t\t  ch = format[offset++];\n\n\t\tbreak; /* while */\n\t      }\n\n\t    if (ch == SPECIFIER_USER_DEFINED_SEPARATOR)\n\t      {\n\t\twithout_namespace = FALSE;\n\t\t/* Copy the namespace for later looking-up */\n\t\tmax = (int)(&format[offset] - tmpformat);\n\t\tif (max > MAX_USER_NAME)\n\t\t  max = MAX_USER_NAME;\n\t\ttrio_copy_max(parameter->user_defined.namespace, max, tmpformat);\n\t\ttmpformat = (char *)&format[offset];\n\t      }\n\t  }\n\n\tif (ch != SPECIFIER_USER_DEFINED_END)\n\t  return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);\n      }\n      break;\n#endif /* TRIO_FEATURE_USER_DEFINED */\n\n    default:\n      /* Bail out completely to make the error more obvious */\n      return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);\n  }\n\n  parameter->endOffset = offset;\n\n  return 0;\n}\n\n/*************************************************************************\n * TrioParse\n *\n * Description:\n *  Parse the format string\n */\nTRIO_PRIVATE int\nTrioParse\nTRIO_ARGS5((type, format, parameters, arglist, argarray),\n\t   int type,\n\t   TRIO_CONST char *format,\n\t   trio_parameter_t *parameters,\n\t   va_list arglist,\n\t   trio_pointer_t *argarray)\n{\n  /* Count the number of times a parameter is referenced */\n  unsigned short usedEntries[MAX_PARAMETERS];\n  /* Parameter counters */\n  int parameterPosition;\n  int maxParam = -1;\n  /* Utility variables */\n  int offset;  /* Offset into formatting string */\n  BOOLEAN_T positional;  /* Does the specifier have a positional? */\n#if TRIO_FEATURE_STICKY\n  BOOLEAN_T gotSticky = FALSE;  /* Are there any sticky modifiers at all? */\n#endif\n  /*\n   * indices specifies the order in which the parameters must be\n   * read from the va_args (this is necessary to handle positionals)\n   */\n  int indices[MAX_PARAMETERS];\n  int pos = 0;\n  /* Various variables */\n#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)\n  int charlen;\n#endif\n  int save_errno;\n  int i = -1;\n  int num;\n\n  /*\n   * The 'parameters' array is not initialized, but we need to\n   * know which entries we have used.\n   */\n  memset(usedEntries, 0, sizeof(usedEntries));\n\n  save_errno = errno;\n  offset = 0;\n  parameterPosition = 0;\n#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)\n  (void)mblen(NULL, 0);\n#endif\n  \n  while (format[offset])\n    {\n      trio_parameter_t parameter = {};\n      int status;\n\n#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)\n      if (! isascii(format[offset]))\n\t{\n\t  /*\n\t   * Multibyte characters cannot be legal specifiers or\n\t   * modifiers, so we skip over them.\n\t   */\n\t  charlen = mblen(&format[offset], MB_LEN_MAX);\n\t  offset += (charlen > 0) ? charlen : 1;\n\t  continue; /* while */\n\t}\n#endif /* TRIO_COMPILER_SUPPORTS_MULTIBYTE */\n\n      switch(format[offset++]) {\n\n      case CHAR_IDENTIFIER:\n\t{\n\t  if (CHAR_IDENTIFIER == format[offset])\n\t    {\n\t      /* skip double \"%\" */\n\t      offset++;\n\t      continue; /* while */\n\t    }\n\n\t  status = TrioParseQualifiers(type, format, offset, &parameter);\n\t  if (status < 0)\n\t    return status; /* Return qualifier syntax error */\n\n\t  status = TrioParseSpecifier(type, format, parameter.endOffset, &parameter);\n\t  if (status < 0)\n\t    return status; /* Return specifier syntax error */\n\t}\n\tbreak;\n\n#if TRIO_EXTENSION\n      case CHAR_ALT_IDENTIFIER:\n\t{\n\t  status = TrioParseQualifiers(type, format, offset, &parameter);\n\t  if (status < 0)\n\t    continue; /* False alert, not a user defined specifier */\n\n\t  status = TrioParseSpecifier(type, format, parameter.endOffset, &parameter);\n\t  if ((status < 0) || (FORMAT_USER_DEFINED != parameter.type))\n\t    continue; /* False alert, not a user defined specifier */\n\t}\n\tbreak;\n#endif\n\n      default:\n\tcontinue; /* while */\n      }\n\n      /* now handle the parsed conversion specification */\n      positional = (NO_POSITION != parameter.position);\n\n      /*\n       * Parameters only need the type and value. The value is\n       * read later.\n       */\n      if (parameter.flags & FLAGS_WIDTH_PARAMETER)\n      {\n\t  if (parameter.width == NO_WIDTH)\n\t  {\n\t      parameter.width = parameterPosition++;\n\t  }\n\t  else\n\t  {\n\t      if (! positional)\n\t\t  parameter.position = parameter.width + 1;\n\t  }\n\n\t  usedEntries[parameter.width] += 1;\n\t  if (parameter.width > maxParam) maxParam = parameter.width;\n\t  parameters[pos].type = FORMAT_PARAMETER;\n\t  parameters[pos].flags = 0;\n\t  indices[parameter.width] = pos;\n\t  parameter.width = pos++;\n      }\n      if (parameter.flags & FLAGS_PRECISION_PARAMETER)\n      {\n\t  if (parameter.precision == NO_PRECISION)\n\t  {\n\t      parameter.precision = parameterPosition++;\n\t  }\n\t  else\n\t  {\n\t      if (! positional)\n\t\t  parameter.position = parameter.precision + 1;\n\t  }\n\n\t  usedEntries[parameter.precision] += 1;\n\t  if (parameter.precision > maxParam) maxParam = parameter.precision;\n\t  parameters[pos].type = FORMAT_PARAMETER;\n\t  parameters[pos].flags = 0;\n\t  indices[parameter.precision] = pos;\n\t  parameter.precision = pos++;\n      }\n      if (parameter.flags & FLAGS_BASE_PARAMETER)\n      {\n\t  if (parameter.base == NO_BASE)\n\t  {\n\t      parameter.base = parameterPosition++;\n\t  }\n\t  else\n\t  {\n\t      if (! positional)\n\t\t  parameter.position = parameter.base + 1;\n\t  }\n\n\t  usedEntries[parameter.base] += 1;\n\t  if (parameter.base > maxParam) maxParam = parameter.base;\n\t  parameters[pos].type = FORMAT_PARAMETER;\n\t  parameters[pos].flags = 0;\n\t  indices[parameter.base] = pos;\n\t  parameter.base = pos++;\n      }\n#if TRIO_FEATURE_VARSIZE\n      if (parameter.flags & FLAGS_VARSIZE_PARAMETER)\n      {\n\t  parameter.varsize = parameterPosition++;\n\n\t  usedEntries[parameter.varsize] += 1;\n\t  if (parameter.varsize > maxParam) maxParam = parameter.varsize;\n\t  parameters[pos].type = FORMAT_PARAMETER;\n\t  parameters[pos].flags = 0;\n\t  indices[parameter.varsize] = pos;\n\t  parameter.varsize = pos++;\n      }\n#endif\n#if TRIO_FEATURE_USER_DEFINED\n      if (parameter.flags & FLAGS_USER_DEFINED_PARAMETER)\n      {\n\t  parameter.user_defined.handler = parameterPosition++;\n\n\t  usedEntries[parameter.user_defined.handler] += 1;\n\t  if (parameter.user_defined.handler > maxParam) maxParam = parameter.user_defined.handler;\n\t  parameters[pos].type = FORMAT_PARAMETER;\n\t  parameters[pos].flags = FLAGS_USER_DEFINED;\n\t  indices[parameter.user_defined.handler] = pos;\n\t  parameter.user_defined.handler = pos++;\n      }\n#endif\n\n      if (NO_POSITION == parameter.position) {\n\t  parameter.position = parameterPosition++;\n      }\n\n      if (parameter.position > maxParam) maxParam = parameter.position;\n\n      if (parameter.position >= MAX_PARAMETERS)\n      {\n\t/* Bail out completely to make the error more obvious */\n\treturn TRIO_ERROR_RETURN(TRIO_ETOOMANY, offset);\n      }\n\n      indices[parameter.position] = pos;\n\n      /*  Count the number of times this entry has been used */\n      usedEntries[parameter.position] += 1;\n\n      /* Find last sticky parameters */\n#if TRIO_FEATURE_STICKY\n      if (parameter.flags & FLAGS_STICKY) {\n\tgotSticky = TRUE;\n      } else if (gotSticky) {\n\tfor (i = pos - 1; i >= 0; i--)\n\t{\n\t  if (parameters[i].type == FORMAT_PARAMETER)\n\t    continue;\n\t  if ((parameters[i].flags & FLAGS_STICKY) &&\n\t      (parameters[i].type == parameter.type))\n\t  {\n\t    /* Do not overwrite current qualifiers */\n\t    parameter.flags |= (parameters[i].flags & (unsigned long)~FLAGS_STICKY);\n\t    if (parameter.width == NO_WIDTH)\n\t      parameter.width = parameters[i].width;\n\t    if (parameter.precision == NO_PRECISION)\n\t      parameter.precision = parameters[i].precision;\n\t    if (parameter.base == NO_BASE)\n\t      parameter.base = parameters[i].base;\n\t    break;\n\t  }\n\t}\n      }\n#endif\n\n      if (parameter.base == NO_BASE) parameter.base = BASE_DECIMAL;\n\n      offset = parameter.endOffset;\n\n      memcpy(&parameters[pos++], &parameter, sizeof(parameter));\n    } /* while format characters left */\n\n  parameters[pos].type = FORMAT_SENTINEL;  /* end parameter array with sentinel */\n  parameters[pos].beginOffset = offset;\n\n  for (num = 0; num <= maxParam; num++)\n    {\n      if (usedEntries[num] != 1)\n\t{\n\t  if (usedEntries[num] == 0) /* gap detected */\n\t    return TRIO_ERROR_RETURN(TRIO_EGAP, num);\n\t  else /* double references detected */\n\t    return TRIO_ERROR_RETURN(TRIO_EDBLREF, num);\n\t}\n      \n      i = indices[num];\n\n      /*\n       * FORMAT_PARAMETERS are only present if they must be read,\n       * so it makes no sense to check the ignore flag (besides,\n       * the flags variable is not set for that particular type)\n       */\n      if ((parameters[i].type != FORMAT_PARAMETER) &&\n\t  (parameters[i].flags & FLAGS_IGNORE))\n\tcontinue; /* for all arguments */\n\n      /*\n       * The stack arguments are read according to ANSI C89\n       * default argument promotions:\n       *\n       *  char           = int\n       *  short          = int\n       *  unsigned char  = unsigned int\n       *  unsigned short = unsigned int\n       *  float          = double\n       *\n       * In addition to the ANSI C89 these types are read (the\n       * default argument promotions of C99 has not been\n       * considered yet)\n       *\n       *  long long\n       *  long double\n       *  size_t\n       *  ptrdiff_t\n       *  intmax_t\n       */\n      switch (parameters[i].type)\n\t{\n\tcase FORMAT_GROUP:\n\tcase FORMAT_STRING:\n#if TRIO_FEATURE_WIDECHAR\n\t  if (parameters[i].flags & FLAGS_WIDECHAR)\n\t    {\n\t      parameters[i].data.wstring = (argarray == NULL)\n\t\t? va_arg(arglist, trio_wchar_t *)\n\t\t: (trio_wchar_t *)(argarray[num]);\n\t    }\n\t  else\n#endif\n\t    {\n\t      parameters[i].data.string = (argarray == NULL)\n\t\t? va_arg(arglist, char *)\n\t\t: (char *)(argarray[num]);\n\t    }\n\t  break;\n\n#if TRIO_FEATURE_USER_DEFINED\n\tcase FORMAT_USER_DEFINED:\n#endif\n\tcase FORMAT_POINTER:\n\tcase FORMAT_COUNT:\n\tcase FORMAT_UNKNOWN:\n\t  parameters[i].data.pointer = (argarray == NULL)\n\t    ? va_arg(arglist, trio_pointer_t )\n\t    : argarray[num];\n\t  break;\n\n\tcase FORMAT_CHAR:\n\tcase FORMAT_INT:\n#if TRIO_FEATURE_SCANF\n\t  if (TYPE_SCAN == type)\n\t    {\n              if (argarray == NULL)\n                parameters[i].data.pointer = \n                  (trio_pointer_t)va_arg(arglist, trio_pointer_t);\n              else\n                {\n                  if (parameters[i].type == FORMAT_CHAR)\n                    parameters[i].data.pointer =\n                      (trio_pointer_t)((char *)argarray[num]);\n                  else if (parameters[i].flags & FLAGS_SHORT)\n                    parameters[i].data.pointer =\n                      (trio_pointer_t)((short *)argarray[num]);\n                  else\n                    parameters[i].data.pointer =\n                      (trio_pointer_t)((int *)argarray[num]);\n                }\n\t    }\n\t  else\n#endif /* TRIO_FEATURE_SCANF */\n\t    {\n#if TRIO_FEATURE_VARSIZE || TRIO_FEATURE_FIXED_SIZE\n\t      if (parameters[i].flags\n\t\t  & (FLAGS_VARSIZE_PARAMETER | FLAGS_FIXED_SIZE))\n\t\t{\n\t\t  int varsize;\n\t\t  if (parameters[i].flags & FLAGS_VARSIZE_PARAMETER)\n\t\t    {\n\t\t      /*\n\t\t       * Variable sizes are mapped onto the fixed sizes, in\n\t\t       * accordance with integer promotion.\n\t\t       *\n\t\t       * Please note that this may not be portable, as we\n\t\t       * only guess the size, not the layout of the numbers.\n\t\t       * For example, if int is little-endian, and long is\n\t\t       * big-endian, then this will fail.\n\t\t       */\n\t\t      varsize = (int)parameters[parameters[i].varsize].data.number.as_unsigned;\n\t\t    }\n\t\t  else\n\t\t    {\n\t\t      /* Used for the I<bits> modifiers */\n\t\t      varsize = parameters[i].varsize;\n\t\t    }\n\t\t  parameters[i].flags &= ~FLAGS_ALL_VARSIZES;\n\t\t  \n\t\t  if (varsize <= (int)sizeof(int))\n\t\t    ;\n\t\t  else if (varsize <= (int)sizeof(long))\n\t\t    parameters[i].flags |= FLAGS_LONG;\n#if TRIO_FEATURE_INTMAX_T\n\t\t  else if (varsize <= (int)sizeof(trio_longlong_t))\n\t\t    parameters[i].flags |= FLAGS_QUAD;\n\t\t  else\n\t\t    parameters[i].flags |= FLAGS_INTMAX_T;\n#else\n\t\t  else\n\t\t    parameters[i].flags |= FLAGS_QUAD;\n#endif\n\t\t}\n#endif /* TRIO_FEATURE_VARSIZE */\n#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER\n\t      if (parameters[i].flags & FLAGS_SIZE_T)\n\t\tparameters[i].data.number.as_unsigned = (argarray == NULL)\n\t\t  ? (trio_uintmax_t)va_arg(arglist, size_t)\n\t\t  : (trio_uintmax_t)(*((size_t *)argarray[num]));\n\t      else\n#endif\n#if TRIO_FEATURE_PTRDIFF_T\n\t      if (parameters[i].flags & FLAGS_PTRDIFF_T)\n\t\tparameters[i].data.number.as_unsigned = (argarray == NULL)\n\t\t  ? (trio_uintmax_t)va_arg(arglist, ptrdiff_t)\n\t\t  : (trio_uintmax_t)(*((ptrdiff_t *)argarray[num]));\n\t      else\n#endif\n#if TRIO_FEATURE_INTMAX_T\n\t      if (parameters[i].flags & FLAGS_INTMAX_T)\n\t\tparameters[i].data.number.as_unsigned = (argarray == NULL)\n\t\t  ? (trio_uintmax_t)va_arg(arglist, trio_intmax_t)\n\t\t  : (trio_uintmax_t)(*((trio_intmax_t *)argarray[num]));\n\t      else\n#endif\n\t      if (parameters[i].flags & FLAGS_QUAD)\n\t\tparameters[i].data.number.as_unsigned = (argarray == NULL)\n\t\t  ? (trio_uintmax_t)va_arg(arglist, trio_ulonglong_t)\n\t\t  : (trio_uintmax_t)(*((trio_ulonglong_t *)argarray[num]));\n\t      else if (parameters[i].flags & FLAGS_LONG)\n\t\tparameters[i].data.number.as_unsigned = (argarray == NULL)\n\t\t  ? (trio_uintmax_t)va_arg(arglist, long)\n\t\t  : (trio_uintmax_t)(*((long *)argarray[num]));\n\t      else\n\t\t{\n\t\t  if (argarray == NULL)\n\t\t    parameters[i].data.number.as_unsigned = (trio_uintmax_t)va_arg(arglist, int);\n\t\t  else\n\t\t    {\n\t\t      if (parameters[i].type == FORMAT_CHAR)\n\t\t\tparameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((char *)argarray[num]));\n\t\t      else if (parameters[i].flags & FLAGS_SHORT)\n\t\t\tparameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((short *)argarray[num]));\n\t\t      else\n\t\t\tparameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((int *)argarray[num]));\n\t\t    }\n\t\t}\n\t    }\n\t  break;\n\n\tcase FORMAT_PARAMETER:\n\t  /*\n\t   * The parameter for the user-defined specifier is a pointer,\n\t   * whereas the rest (width, precision, base) uses an integer.\n\t   */\n\t  if (parameters[i].flags & FLAGS_USER_DEFINED)\n\t    parameters[i].data.pointer = (argarray == NULL)\n\t      ? va_arg(arglist, trio_pointer_t )\n\t      : argarray[num];\n\t  else\n\t    parameters[i].data.number.as_unsigned = (argarray == NULL)\n\t      ? (trio_uintmax_t)va_arg(arglist, int)\n\t      : (trio_uintmax_t)(*((int *)argarray[num]));\n\t  break;\n\n#if TRIO_FEATURE_FLOAT\n\tcase FORMAT_DOUBLE:\n# if TRIO_FEATURE_SCANF\n\t  if (TYPE_SCAN == type)\n\t    {\n\t      if (parameters[i].flags & FLAGS_LONGDOUBLE)\n\t\tparameters[i].data.longdoublePointer = (argarray == NULL)\n\t\t  ? va_arg(arglist, trio_long_double_t *)\n\t\t  : (trio_long_double_t *)argarray[num];\n\t      else\n                {\n\t\t  if (parameters[i].flags & FLAGS_LONG)\n\t\t    parameters[i].data.doublePointer = (argarray == NULL)\n\t\t      ? va_arg(arglist, double *)\n\t\t      : (double *)argarray[num];\n\t\t  else\n\t\t    parameters[i].data.doublePointer = (argarray == NULL)\n\t\t      ? (double *)va_arg(arglist, float *)\n\t\t      : (double *)((float *)argarray[num]);\n                }\n\t    }\n\t  else\n# endif /* TRIO_FEATURE_SCANF */\n\t    {\n\t      if (parameters[i].flags & FLAGS_LONGDOUBLE)\n\t\tparameters[i].data.longdoubleNumber = (argarray == NULL)\n\t\t  ? va_arg(arglist, trio_long_double_t)\n\t\t  : (trio_long_double_t)(*((trio_long_double_t *)argarray[num]));\n\t      else\n\t\t{\n\t\t  if (argarray == NULL)\n\t\t    parameters[i].data.longdoubleNumber =\n\t\t      (trio_long_double_t)va_arg(arglist, double);\n\t\t  else\n\t\t    {\n\t\t      if (parameters[i].flags & FLAGS_SHORT)\n\t\t\tparameters[i].data.longdoubleNumber =\n\t\t\t  (trio_long_double_t)(*((float *)argarray[num]));\n\t\t      else\n\t\t\tparameters[i].data.longdoubleNumber =\n\t\t\t  (trio_long_double_t)(*((double *)argarray[num]));\n\t\t    }\n\t\t}\n\t    }\n\t  break;\n#endif /* TRIO_FEATURE_FLOAT */\n\n#if TRIO_FEATURE_ERRNO\n\tcase FORMAT_ERRNO:\n\t  parameters[i].data.errorNumber = save_errno;\n\t  break;\n#endif\n\n\tdefault:\n\t  break;\n\t}\n    } /* for all specifiers */\n  return num;\n}\n\n\n/*************************************************************************\n *\n * FORMATTING\n *\n ************************************************************************/\n\n\n/*************************************************************************\n * TrioWriteNumber\n *\n * Description:\n *  Output a number.\n *  The complexity of this function is a result of the complexity\n *  of the dependencies of the flags.\n */\nTRIO_PRIVATE void\nTrioWriteNumber\nTRIO_ARGS6((self, number, flags, width, precision, base),\n\t   trio_class_t *self,\n\t   trio_uintmax_t number,\n\t   trio_flags_t flags,\n\t   int width,\n\t   int precision,\n\t   int base)\n{\n  BOOLEAN_T isNegative;\n  BOOLEAN_T isNumberZero;\n  BOOLEAN_T isPrecisionZero;\n  BOOLEAN_T ignoreNumber;\n  char buffer[MAX_CHARS_IN(trio_uintmax_t) * (1 + MAX_LOCALE_SEPARATOR_LENGTH) + 1];\n  char *bufferend;\n  char *pointer;\n  TRIO_CONST char *digits;\n  int i;\n#if TRIO_FEATURE_QUOTE\n  int length;\n  char *p;\n#endif\n  int count;\n  int digitOffset;\n\n  assert(VALID(self));\n  assert(VALID(self->OutStream));\n  assert(((base >= MIN_BASE) && (base <= MAX_BASE)) || (base == NO_BASE));\n\n  digits = (flags & FLAGS_UPPER) ? internalDigitsUpper : internalDigitsLower;\n  if (base == NO_BASE)\n    base = BASE_DECIMAL;\n\n  isNumberZero = (number == 0);\n  isPrecisionZero = (precision == 0);\n  ignoreNumber = (isNumberZero\n\t\t  && isPrecisionZero\n\t\t  && !((flags & FLAGS_ALTERNATIVE) && (base == BASE_OCTAL)));\n\n  if (flags & FLAGS_UNSIGNED)\n    {\n      isNegative = FALSE;\n      flags &= ~FLAGS_SHOWSIGN;\n    }\n  else\n    {\n      isNegative = ((trio_intmax_t)number < 0);\n      if (isNegative)\n\tnumber = -((trio_intmax_t)number);\n    }\n\n  if (flags & FLAGS_QUAD)\n    number &= (trio_ulonglong_t)-1;\n  else if (flags & FLAGS_LONG)\n    number &= (unsigned long)-1;\n  else\n    number &= (unsigned int)-1;\n  \n  /* Build number */\n  pointer = bufferend = &buffer[sizeof(buffer) - 1];\n  *pointer-- = NIL;\n  for (i = 1; i < (int)sizeof(buffer); i++)\n    {\n      digitOffset = number % base;\n      *pointer-- = digits[digitOffset];\n      number /= base;\n      if (number == 0)\n\tbreak;\n\n#if TRIO_FEATURE_QUOTE\n      if ((flags & FLAGS_QUOTE) && TrioFollowedBySeparator(i + 1))\n\t{\n\t  /*\n\t   * We are building the number from the least significant\n\t   * to the most significant digit, so we have to copy the\n\t   * thousand separator backwards\n\t   */\n\t  length = internalThousandSeparatorLength;\n\t  if (((int)(pointer - buffer) - length) > 0)\n\t    {\n\t      p = &internalThousandSeparator[length - 1];\n\t      while (length-- > 0)\n\t\t*pointer-- = *p--;\n\t    }\n\t}\n#endif\n    }\n\n  if (! ignoreNumber)\n    {\n      /* Adjust width */\n      width -= (bufferend - pointer) - 1;\n    }\n\n  /* Adjust precision */\n  if (NO_PRECISION != precision)\n    {\n      precision -= (bufferend - pointer) - 1;\n      if (precision < 0)\n\tprecision = 0;\n      flags |= FLAGS_NILPADDING;\n    }\n\n  /* Calculate padding */\n  count = (! ((flags & FLAGS_LEFTADJUST) || (precision == NO_PRECISION)))\n    ? precision\n    : 0;\n  \n  /* Adjust width further */\n  if (isNegative || (flags & FLAGS_SHOWSIGN) || (flags & FLAGS_SPACE))\n    width--;\n  if ((flags & FLAGS_ALTERNATIVE) && !isNumberZero)\n    {\n      switch (base)\n\t{\n\tcase BASE_BINARY:\n\tcase BASE_HEX:\n\t  width -= 2;\n\t  break;\n\tcase BASE_OCTAL:\n\t  if (!(flags & FLAGS_NILPADDING) || (count == 0))\n\t    width--;\n\t  break;\n\tdefault:\n\t  break;\n\t}\n    }\n\n  /* Output prefixes spaces if needed */\n  if (! ((flags & FLAGS_LEFTADJUST) ||\n\t ((flags & FLAGS_NILPADDING) && (precision == NO_PRECISION))))\n    {\n      while (width-- > count)\n\tself->OutStream(self, CHAR_ADJUST);\n    }\n\n  /* width has been adjusted for signs and alternatives */\n  if (isNegative)\n    self->OutStream(self, '-');\n  else if (flags & FLAGS_SHOWSIGN)\n    self->OutStream(self, '+');\n  else if (flags & FLAGS_SPACE)\n    self->OutStream(self, ' ');\n\n  /* Prefix is not written when the value is zero */\n  if ((flags & FLAGS_ALTERNATIVE) && !isNumberZero)\n    {\n      switch (base)\n\t{\n\tcase BASE_BINARY:\n\t  self->OutStream(self, '0');\n\t  self->OutStream(self, (flags & FLAGS_UPPER) ? 'B' : 'b');\n\t  break;\n\n\tcase BASE_OCTAL:\n\t  if (!(flags & FLAGS_NILPADDING) || (count == 0))\n\t    self->OutStream(self, '0');\n\t  break;\n\n\tcase BASE_HEX:\n\t  self->OutStream(self, '0');\n\t  self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x');\n\t  break;\n\n\tdefault:\n\t  break;\n\t} /* switch base */\n    }\n\n  /* Output prefixed zero padding if needed */\n  if (flags & FLAGS_NILPADDING)\n    {\n      if (precision == NO_PRECISION)\n\tprecision = width;\n      while (precision-- > 0)\n\t{\n\t  self->OutStream(self, '0');\n\t  width--;\n\t}\n    }\n\n  if (! ignoreNumber)\n    {\n      /* Output the number itself */\n      while (*(++pointer))\n\t{\n\t  self->OutStream(self, *pointer);\n\t}\n    }\n\n  /* Output trailing spaces if needed */\n  if (flags & FLAGS_LEFTADJUST)\n    {\n      while (width-- > 0)\n\tself->OutStream(self, CHAR_ADJUST);\n    }\n}\n\n/*************************************************************************\n * TrioWriteStringCharacter\n *\n * Description:\n *  Output a single character of a string\n */\nTRIO_PRIVATE void\nTrioWriteStringCharacter\nTRIO_ARGS3((self, ch, flags),\n\t   trio_class_t *self,\n\t   int ch,\n\t   trio_flags_t flags)\n{\n  if (flags & FLAGS_ALTERNATIVE)\n    {\n      if (! isprint(ch))\n\t{\n\t  /*\n\t   * Non-printable characters are converted to C escapes or\n\t   * \\number, if no C escape exists.\n\t   */\n\t  self->OutStream(self, CHAR_BACKSLASH);\n\t  switch (ch)\n\t    {\n\t    case '\\007': self->OutStream(self, 'a'); break;\n\t    case '\\b': self->OutStream(self, 'b'); break;\n\t    case '\\f': self->OutStream(self, 'f'); break;\n\t    case '\\n': self->OutStream(self, 'n'); break;\n\t    case '\\r': self->OutStream(self, 'r'); break;\n\t    case '\\t': self->OutStream(self, 't'); break;\n\t    case '\\v': self->OutStream(self, 'v'); break;\n\t    case '\\\\': self->OutStream(self, '\\\\'); break;\n\t    default:\n\t      self->OutStream(self, 'x');\n\t      TrioWriteNumber(self, (trio_uintmax_t)ch,\n\t\t\t      FLAGS_UNSIGNED | FLAGS_NILPADDING,\n\t\t\t      2, 2, BASE_HEX);\n\t      break;\n\t    }\n\t}\n      else if (ch == CHAR_BACKSLASH)\n\t{\n\t  self->OutStream(self, CHAR_BACKSLASH);\n\t  self->OutStream(self, CHAR_BACKSLASH);\n\t}\n      else\n\t{\n\t  self->OutStream(self, ch);\n\t}\n    }\n  else\n    {\n      self->OutStream(self, ch);\n    }\n}\n\n/*************************************************************************\n * TrioWriteString\n *\n * Description:\n *  Output a string\n */\nTRIO_PRIVATE void\nTrioWriteString\nTRIO_ARGS5((self, string, flags, width, precision),\n\t   trio_class_t *self,\n\t   TRIO_CONST char *string,\n\t   trio_flags_t flags,\n\t   int width,\n\t   int precision)\n{\n  int length;\n  int ch;\n\n  assert(VALID(self));\n  assert(VALID(self->OutStream));\n\n  if (string == NULL)\n    {\n      string = internalNullString;\n      length = sizeof(internalNullString) - 1;\n#if TRIO_FEATURE_QUOTE\n      /* Disable quoting for the null pointer */\n      flags &= (~FLAGS_QUOTE);\n#endif\n      width = 0;\n    }\n  else\n    {\n      if (precision == 0)\n\t{\n\t  length = trio_length(string);\n\t}\n      else\n\t{\n\t  length = trio_length_max(string, precision);\n\t}\n    }\n  if ((NO_PRECISION != precision) &&\n      (precision < length))\n    {\n      length = precision;\n    }\n  width -= length;\n\n#if TRIO_FEATURE_QUOTE\n  if (flags & FLAGS_QUOTE)\n    self->OutStream(self, CHAR_QUOTE);\n#endif\n\n  if (! (flags & FLAGS_LEFTADJUST))\n    {\n      while (width-- > 0)\n\tself->OutStream(self, CHAR_ADJUST);\n    }\n\n  while (length-- > 0)\n    {\n      /* The ctype parameters must be an unsigned char (or EOF) */\n      ch = (int)((unsigned char)(*string++));\n      TrioWriteStringCharacter(self, ch, flags);\n    }\n\n  if (flags & FLAGS_LEFTADJUST)\n    {\n      while (width-- > 0)\n\tself->OutStream(self, CHAR_ADJUST);\n    }\n#if TRIO_FEATURE_QUOTE\n  if (flags & FLAGS_QUOTE)\n    self->OutStream(self, CHAR_QUOTE);\n#endif\n}\n\n/*************************************************************************\n * TrioWriteWideStringCharacter\n *\n * Description:\n *  Output a wide string as a multi-byte sequence\n */\n#if TRIO_FEATURE_WIDECHAR\nTRIO_PRIVATE int\nTrioWriteWideStringCharacter\nTRIO_ARGS4((self, wch, flags, width),\n\t   trio_class_t *self,\n\t   trio_wchar_t wch,\n\t   trio_flags_t flags,\n\t   int width)\n{\n  int size;\n  int i;\n  int ch;\n  char *string;\n  char buffer[MB_LEN_MAX + 1];\n\n  if (width == NO_WIDTH)\n    width = sizeof(buffer);\n  \n  size = wctomb(buffer, wch);\n  if ((size <= 0) || (size > width) || (buffer[0] == NIL))\n    return 0;\n\n  string = buffer;\n  i = size;\n  while ((width >= i) && (width-- > 0) && (i-- > 0))\n    {\n      /* The ctype parameters must be an unsigned char (or EOF) */\n      ch = (int)((unsigned char)(*string++));\n      TrioWriteStringCharacter(self, ch, flags);\n    }\n  return size;\n}\n#endif /* TRIO_FEATURE_WIDECHAR */\n\n/*************************************************************************\n * TrioWriteWideString\n *\n * Description:\n *  Output a wide character string as a multi-byte string\n */\n#if TRIO_FEATURE_WIDECHAR\nTRIO_PRIVATE void\nTrioWriteWideString\nTRIO_ARGS5((self, wstring, flags, width, precision),\n\t   trio_class_t *self,\n\t   TRIO_CONST trio_wchar_t *wstring,\n\t   trio_flags_t flags,\n\t   int width,\n\t   int precision)\n{\n  int length;\n  int size;\n\n  assert(VALID(self));\n  assert(VALID(self->OutStream));\n\n#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)\n  /* Required by TrioWriteWideStringCharacter */\n  (void)mblen(NULL, 0);\n#endif\n  \n  if (wstring == NULL)\n    {\n      TrioWriteString(self, NULL, flags, width, precision);\n      return;\n    }\n  \n  if (NO_PRECISION == precision)\n    {\n      length = INT_MAX;\n    }\n  else\n    {\n      length = precision;\n      width -= length;\n    }\n\n#if TRIO_FEATURE_QUOTE\n  if (flags & FLAGS_QUOTE)\n    self->OutStream(self, CHAR_QUOTE);\n#endif\n\n  if (! (flags & FLAGS_LEFTADJUST))\n    {\n      while (width-- > 0)\n\tself->OutStream(self, CHAR_ADJUST);\n    }\n\n  while (length > 0)\n    {\n      size = TrioWriteWideStringCharacter(self, *wstring++, flags, length);\n      if (size == 0)\n\tbreak; /* while */\n      length -= size;\n    }\n\n  if (flags & FLAGS_LEFTADJUST)\n    {\n      while (width-- > 0)\n\tself->OutStream(self, CHAR_ADJUST);\n    }\n#if TRIO_FEATURE_QUOTE\n  if (flags & FLAGS_QUOTE)\n    self->OutStream(self, CHAR_QUOTE);\n#endif\n}\n#endif /* TRIO_FEATURE_WIDECHAR */\n\n/*************************************************************************\n * TrioWriteDouble\n *\n * http://wwwold.dkuug.dk/JTC1/SC22/WG14/www/docs/dr_211.htm\n *\n * \"5.2.4.2.2 paragraph #4\n *\n *  The accuracy [...] is implementation defined, as is the accuracy\n *  of the conversion between floating-point internal representations\n *  and string representations performed by the libray routine in\n *  <stdio.h>\"\n */\n/* FIXME: handle all instances of constant long-double number (L)\n *   and *l() math functions.\n */\n#if TRIO_FEATURE_FLOAT\nTRIO_PRIVATE void\nTrioWriteDouble\nTRIO_ARGS6((self, number, flags, width, precision, base),\n\t   trio_class_t *self,\n\t   trio_long_double_t number,\n\t   trio_flags_t flags,\n\t   int width,\n\t   int precision,\n\t   int base)\n{\n  trio_long_double_t integerNumber;\n  trio_long_double_t fractionNumber;\n  trio_long_double_t workNumber;\n  int integerDigits;\n  int fractionDigits;\n  int exponentDigits;\n  int workDigits;\n  int baseDigits;\n  int integerThreshold;\n  int fractionThreshold;\n  int expectedWidth;\n  int exponent = 0;\n  unsigned int uExponent = 0;\n  int exponentBase;\n  trio_long_double_t dblBase;\n  trio_long_double_t dblFractionBase;\n  trio_long_double_t integerAdjust;\n  trio_long_double_t fractionAdjust;\n  trio_long_double_t workFractionNumber;\n  trio_long_double_t workFractionAdjust;\n  int fractionDigitsInspect;\n  BOOLEAN_T isNegative;\n  BOOLEAN_T isExponentNegative = FALSE;\n  BOOLEAN_T requireTwoDigitExponent;\n  BOOLEAN_T isHex;\n  TRIO_CONST char *digits;\n# if TRIO_FEATURE_QUOTE\n  char *groupingPointer;\n# endif\n  int i;\n  int offset;\n  BOOLEAN_T hasOnlyZeroes;\n  int leadingFractionZeroes = -1;\n  register int trailingZeroes;\n  BOOLEAN_T keepTrailingZeroes;\n  BOOLEAN_T keepDecimalPoint;\n  trio_long_double_t epsilon;\n  BOOLEAN_T adjustNumber = FALSE;\n  \n  assert(VALID(self));\n  assert(VALID(self->OutStream));\n  assert(((base >= MIN_BASE) && (base <= MAX_BASE)) || (base == NO_BASE));\n\n  /* Determine sign and look for special quantities */\n  switch (trio_fpclassify_and_signbit(number, &isNegative))\n    {\n    case TRIO_FP_NAN:\n      TrioWriteString(self,\n\t\t      (flags & FLAGS_UPPER)\n\t\t      ? NAN_UPPER\n\t\t      : NAN_LOWER,\n\t\t      flags, width, precision);\n      return;\n      \n    case TRIO_FP_INFINITE:\n      if (isNegative)\n\t{\n\t  /* Negative infinity */\n\t  TrioWriteString(self,\n\t\t\t  (flags & FLAGS_UPPER)\n\t\t\t  ? \"-\" INFINITE_UPPER\n\t\t\t  : \"-\" INFINITE_LOWER,\n\t\t\t  flags, width, precision);\n\t  return;\n\t}\n      else\n\t{\n\t  /* Positive infinity */\n\t  TrioWriteString(self,\n\t\t\t  (flags & FLAGS_UPPER)\n\t\t\t  ? INFINITE_UPPER\n\t\t\t  : INFINITE_LOWER,\n\t\t\t  flags, width, precision);\n\t  return;\n\t}\n\n    default:\n      /* Finitude */\n      break;\n    }\n  \n  /* Normal numbers */\n  if (flags & FLAGS_LONGDOUBLE)\n    {\n      baseDigits = (base == 10)\n\t? LDBL_DIG\n\t: (int)trio_floor(LDBL_MANT_DIG / TrioLogarithmBase(base));\n      epsilon = LDBL_EPSILON;\n    }\n  else if (flags & FLAGS_SHORT)\n    {\n      baseDigits = (base == BASE_DECIMAL)\n\t? FLT_DIG\n\t: (int)trio_floor(FLT_MANT_DIG / TrioLogarithmBase(base));\n      epsilon = FLT_EPSILON;\n    }\n  else\n    {\n      baseDigits = (base == BASE_DECIMAL)\n\t? DBL_DIG\n\t: (int)trio_floor(DBL_MANT_DIG / TrioLogarithmBase(base));\n      epsilon = DBL_EPSILON;\n    }\n\n  digits = (flags & FLAGS_UPPER) ? internalDigitsUpper : internalDigitsLower;\n  isHex = (base == BASE_HEX);\n  if (base == NO_BASE)\n    base = BASE_DECIMAL;\n  dblBase = (trio_long_double_t)base;\n  keepTrailingZeroes = !( (flags & FLAGS_ROUNDING) ||\n\t\t\t  ( (flags & FLAGS_FLOAT_G) &&\n\t\t\t    !(flags & FLAGS_ALTERNATIVE) ) );\n\n# if TRIO_FEATURE_ROUNDING\n  if (flags & FLAGS_ROUNDING)\n    {\n      precision = baseDigits;\n    }\n# endif\n\n  if (precision == NO_PRECISION)\n    {\n      if (isHex)\n\t{\n\t  keepTrailingZeroes = FALSE;\n\t  precision = FLT_MANT_DIG;\n\t}\n      else\n\t{\n\t  precision = FLT_DIG;\n\t}\n    }\n  \n  if (isNegative)\n    {\n      number = -number;\n    }\n\n  if (isHex)\n    {\n      flags |= FLAGS_FLOAT_E;\n    }\n\n reprocess:\n  \n  if (flags & FLAGS_FLOAT_G)\n    {\n      if (precision == 0)\n\tprecision = 1;\n\n      if ( (number < 1.0E-4) ||\n\t   (number >= trio_pow(base, (trio_long_double_t)precision)) )\n\t{\n\t  /* Use scientific notation */\n\t  flags |= FLAGS_FLOAT_E;\n\t}\n      else if (number < 1.0)\n\t{\n\t  /*\n\t   * Use normal notation. If the integer part of the number is\n\t   * zero, then adjust the precision to include leading fractional\n\t   * zeros.\n\t   */\n\t  workNumber = TrioLogarithm(number, base);\n\t  workNumber = TRIO_FABS(workNumber);\n\t  if (workNumber - trio_floor(workNumber) < epsilon)\n\t    workNumber--;\n\t  leadingFractionZeroes = (int)trio_floor(workNumber);\n\t}\n    }\n\n  if (flags & FLAGS_FLOAT_E)\n    {\n      /* Scale the number */\n      workNumber = TrioLogarithm(number, base);\n      if (trio_isinf(workNumber) == -1)\n\t{\n\t  exponent = 0;\n\t  /* Undo setting */\n\t  if (flags & FLAGS_FLOAT_G)\n\t    flags &= ~FLAGS_FLOAT_E;\n\t}\n      else\n\t{\n\t  exponent = (int)trio_floor(workNumber);\n\t  /*\n\t   * The expression A * 10^-B is equivalent to A / 10^B but the former\n\t   * usually gives better accuracy.\n\t   */\n\t  workNumber = number * trio_pow(dblBase, (trio_long_double_t)-exponent);\n\t  if (trio_isinf(workNumber))\n\t    {\n\t      workNumber = number / trio_pow(dblBase, (trio_long_double_t)exponent);\n\t    }\n\t  number = workNumber;\n\t  isExponentNegative = (exponent < 0);\n\t  uExponent = (isExponentNegative) ? -exponent : exponent;\n\t  if (isHex)\n\t    uExponent *= 4; /* log16(2) */\n#if TRIO_FEATURE_QUOTE\n\t  /* No thousand separators */\n\t  flags &= ~FLAGS_QUOTE;\n#endif\n\t}\n    }\n\n  integerNumber = trio_floor(number);\n  fractionNumber = number - integerNumber;\n  \n  /*\n   * Truncated number.\n   *\n   * Precision is number of significant digits for FLOAT_G and number of\n   * fractional digits for others.\n   */\n  integerDigits = 1;\n  if (integerNumber > epsilon)\n    {\n      integerDigits += (int)TrioLogarithm(integerNumber, base);\n    }\n\n  fractionDigits = precision;\n  if (flags & FLAGS_FLOAT_G)\n    {\n      if (leadingFractionZeroes > 0)\n\t{\n\t  fractionDigits += leadingFractionZeroes;\n\t}\n      if ((integerNumber > epsilon) || (number <= epsilon))\n\t{\n\t  fractionDigits -= integerDigits;\n\t}\n    }\n\n  dblFractionBase = TrioPower(base, fractionDigits);\n\n  if (integerNumber < 1.0)\n    {\n      workNumber = number * dblFractionBase + 0.5;\n      if (trio_floor(number * dblFractionBase) != trio_floor(workNumber))\n\t{\n\t  adjustNumber = TRUE;\n\t  /* Remove a leading fraction zero if fraction is rounded up */\n\t  if ((int)TrioLogarithm(number * dblFractionBase, base) != (int)TrioLogarithm(workNumber, base))\n\t    {\n\t      --leadingFractionZeroes;\n\t    }\n\t}\n      workNumber /= dblFractionBase;\n    }\n  else\n    {\n      workNumber = number + 0.5 / dblFractionBase;\n      adjustNumber = (trio_floor(number) != trio_floor(workNumber));\n    }\n  if (adjustNumber)\n    {\n      if ((flags & FLAGS_FLOAT_G) && !(flags & FLAGS_FLOAT_E))\n\t{\n\t  /* The adjustment may require a change to scientific notation */\n\t  if ( (workNumber < 1.0E-4) ||\n\t       (workNumber >= trio_pow(base, (trio_long_double_t)precision)) )\n\t    {\n\t      /* Use scientific notation */\n\t      flags |= FLAGS_FLOAT_E;\n\t      goto reprocess;\n\t    }\n\t}\n      \n      if (flags & FLAGS_FLOAT_E)\n\t{\n\t  workDigits = 1 + TrioLogarithm(trio_floor(workNumber), base);\n\t  if (integerDigits == workDigits)\n\t    {\n\t      /* Adjust if the same number of digits are used */\n\t      number += 0.5 / dblFractionBase;\n\t      integerNumber = trio_floor(number);\n\t      fractionNumber = number - integerNumber;\n\t    }\n\t  else\n\t    {\n\t      /* Adjust if number was rounded up one digit (ie. 0.99 to 1.00) */\n\t      exponent++;\n\t      isExponentNegative = (exponent < 0);\n\t      uExponent = (isExponentNegative) ? -exponent : exponent;\n\t      if (isHex)\n\t\tuExponent *= 4; /* log16(2) */\n\t      workNumber = (number + 0.5 / dblFractionBase) / dblBase;\n\t      integerNumber = trio_floor(workNumber);\n\t      fractionNumber = workNumber - integerNumber;\n\t    }\n\t}\n      else\n\t{\n\t  if (workNumber > 1.0)\n\t    {\n\t      /* Adjust if number was rounded up one digit (ie. 99 to 100) */\n\t      integerNumber = trio_floor(workNumber);\n\t      fractionNumber = 0.0;\n\t      integerDigits = (integerNumber > epsilon)\n\t\t? 1 + (int)TrioLogarithm(integerNumber, base)\n\t\t: 1;\n\t      if (flags & FLAGS_FLOAT_G)\n\t\t{\n\t\t  if (flags & FLAGS_ALTERNATIVE)\n\t\t    {\n\t\t      if ((integerNumber > epsilon) || (number <= epsilon))\n\t\t\t{\n\t\t\t  fractionDigits -= integerDigits;\n\t\t\t}\n\t\t    }\n\t\t  else\n\t\t    {\n\t\t      fractionDigits = 0;\n\t\t    }\n\t\t}\n\t    }\n\t  else\n\t    {\n\t      integerNumber = trio_floor(workNumber);\n\t      fractionNumber = workNumber - integerNumber;\n\t      if (flags & FLAGS_FLOAT_G)\n\t\t{\n\t\t  if (flags & FLAGS_ALTERNATIVE)\n\t\t    {\n\t\t      fractionDigits = precision;\n\t\t      if (leadingFractionZeroes > 0)\n\t\t\t{\n\t\t\t  fractionDigits += leadingFractionZeroes;\n\t\t\t}\n\t\t      if ((integerNumber > epsilon) || (number <= epsilon))\n\t\t\t{\n\t\t\t  fractionDigits -= integerDigits;\n\t\t\t}\n\t\t    }\n\t\t}\n\t    }\n\t}\n    }\n\n  /* Estimate accuracy */\n  integerAdjust = fractionAdjust = 0.5;\n# if TRIO_FEATURE_ROUNDING\n  if (flags & FLAGS_ROUNDING)\n    {\n      if (integerDigits > baseDigits)\n\t{\n\t  integerThreshold = baseDigits;\n\t  fractionDigits = 0;\n\t  dblFractionBase = 1.0;\n\t  fractionThreshold = 0;\n\t  precision = 0; /* Disable decimal-point */\n\t  integerAdjust = TrioPower(base, integerDigits - integerThreshold - 1);\n\t  fractionAdjust = 0.0;\n\t}\n      else\n\t{\n\t  integerThreshold = integerDigits;\n\t  fractionThreshold = fractionDigits - integerThreshold;\n\t  fractionAdjust = 1.0;\n\t}\n    }\n  else\n# endif\n    {\n      integerThreshold = INT_MAX;\n      fractionThreshold = INT_MAX;\n    }\n  \n  /*\n   * Calculate expected width.\n   *  sign + integer part + thousands separators + decimal point\n   *  + fraction + exponent\n   */\n  fractionAdjust /= dblFractionBase;\n  hasOnlyZeroes = (trio_floor((fractionNumber + fractionAdjust) *\n\t\t\t       dblFractionBase) < epsilon);\n  keepDecimalPoint = ( (flags & FLAGS_ALTERNATIVE) ||\n\t\t       !((precision == 0) ||\n\t\t\t (!keepTrailingZeroes && hasOnlyZeroes)) );\n\n  expectedWidth = integerDigits + fractionDigits;\n\n  if (!keepTrailingZeroes)\n    {\n      trailingZeroes = 0;\n      workFractionNumber = fractionNumber;\n      workFractionAdjust = fractionAdjust;\n      fractionDigitsInspect = fractionDigits;\n\n      if (integerDigits > integerThreshold)\n\t{\n\t  fractionDigitsInspect = 0;\n\t}\n      else if (fractionThreshold  <= fractionDigits)\n\t{\n\t  fractionDigitsInspect = fractionThreshold + 1;\n\t}\n\n      trailingZeroes = fractionDigits - fractionDigitsInspect;\n      for (i = 0; i < fractionDigitsInspect; i++)\n\t{\n\t  workFractionNumber *= dblBase;\n\t  workFractionAdjust *= dblBase;\n\t  workNumber = trio_floor(workFractionNumber + workFractionAdjust);\n\t  workFractionNumber -= workNumber;\n\t  offset = (int)trio_fmod(workNumber, dblBase);\n\t  if (offset == 0)\n\t    {\n\t      trailingZeroes++;\n\t    }\n\t  else\n\t    {\n\t      trailingZeroes = 0;\n\t    }\n\t}\n      expectedWidth -= trailingZeroes;\n    }\n  \n  if (keepDecimalPoint)\n    {\n      expectedWidth += internalDecimalPointLength;\n    }\n  \n#if TRIO_FEATURE_QUOTE\n  if (flags & FLAGS_QUOTE)\n    {\n      expectedWidth += TrioCalcThousandSeparatorLength(integerDigits);\n    }\n#endif\n  \n  if (isNegative || (flags & FLAGS_SHOWSIGN) || (flags & FLAGS_SPACE))\n    {\n      expectedWidth += sizeof(\"-\") - 1;\n    }\n  \n  exponentDigits = 0;\n  if (flags & FLAGS_FLOAT_E)\n    {\n      exponentDigits = (uExponent == 0)\n\t? 1\n\t: (int)trio_ceil(TrioLogarithm((double)(uExponent + 1),\n\t\t\t\t       (isHex) ? 10 : base));\n    }\n  requireTwoDigitExponent = ((base == BASE_DECIMAL) && (exponentDigits == 1));\n  if (exponentDigits > 0)\n    {\n      expectedWidth += exponentDigits;\n      expectedWidth += (requireTwoDigitExponent\n\t\t\t? sizeof(\"E+0\") - 1\n\t\t\t: sizeof(\"E+\") - 1);\n    }\n  \n  if (isHex)\n    {\n      expectedWidth += sizeof(\"0X\") - 1;\n    }\n  \n  /* Output prefixing */\n  if (flags & FLAGS_NILPADDING)\n    {\n      /* Leading zeros must be after sign */\n      if (isNegative)\n\tself->OutStream(self, '-');\n      else if (flags & FLAGS_SHOWSIGN)\n\tself->OutStream(self, '+');\n      else if (flags & FLAGS_SPACE)\n\tself->OutStream(self, ' ');\n      if (isHex)\n\t{\n\t  self->OutStream(self, '0');\n\t  self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x');\n\t}\n      if (!(flags & FLAGS_LEFTADJUST))\n\t{\n\t  for (i = expectedWidth; i < width; i++)\n\t    {\n\t      self->OutStream(self, '0');\n\t    }\n\t}\n    }\n  else\n    {\n      /* Leading spaces must be before sign */\n      if (!(flags & FLAGS_LEFTADJUST))\n\t{\n\t  for (i = expectedWidth; i < width; i++)\n\t    {\n\t      self->OutStream(self, CHAR_ADJUST);\n\t    }\n\t}\n      if (isNegative)\n\tself->OutStream(self, '-');\n      else if (flags & FLAGS_SHOWSIGN)\n\tself->OutStream(self, '+');\n      else if (flags & FLAGS_SPACE)\n\tself->OutStream(self, ' ');\n      if (isHex)\n\t{\n\t  self->OutStream(self, '0');\n\t  self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x');\n\t}\n    }\n  \n  /* Output the integer part and thousand separators */\n  for (i = 0; i < integerDigits; i++)\n    {\n      workNumber = trio_floor(((integerNumber + integerAdjust)\n\t\t\t       / TrioPower(base, integerDigits - i - 1)));\n      if (i > integerThreshold)\n\t{\n\t  /* Beyond accuracy */\n\t  self->OutStream(self, digits[0]);\n\t}\n      else\n\t{\n\t  self->OutStream(self, digits[(int)trio_fmod(workNumber, dblBase)]);\n\t}\n\n#if TRIO_FEATURE_QUOTE\n      if (((flags & (FLAGS_FLOAT_E | FLAGS_QUOTE)) == FLAGS_QUOTE)\n\t  && TrioFollowedBySeparator(integerDigits - i))\n\t{\n\t  for (groupingPointer = internalThousandSeparator;\n\t       *groupingPointer != NIL;\n\t       groupingPointer++)\n\t    {\n\t      self->OutStream(self, *groupingPointer);\n\t    }\n\t}\n#endif\n    }\n  \n  /* Insert decimal point and build the fraction part */\n  trailingZeroes = 0;\n\n  if (keepDecimalPoint)\n    {\n      if (internalDecimalPoint)\n\t{\n\t  self->OutStream(self, internalDecimalPoint);\n\t}\n      else\n\t{\n\t  for (i = 0; i < internalDecimalPointLength; i++)\n\t    {\n\t      self->OutStream(self, internalDecimalPointString[i]);\n\t    }\n\t}\n    }\n\n  for (i = 0; i < fractionDigits; i++)\n    {\n      if ((integerDigits > integerThreshold) || (i > fractionThreshold))\n\t{\n\t  /* Beyond accuracy */\n\t  trailingZeroes++;\n\t}\n      else\n\t{\n\t  fractionNumber *= dblBase;\n\t  fractionAdjust *= dblBase;\n\t  workNumber = trio_floor(fractionNumber + fractionAdjust);\n\t  if (workNumber > fractionNumber)\n\t    {\n\t      /* fractionNumber should never become negative */\n\t      fractionNumber = 0.0;\n\t      fractionAdjust = 0.0;\n\t    }\n\t  else\n\t    {\n\t      fractionNumber -= workNumber;\n\t    }\n\t  offset = (int)trio_fmod(workNumber, dblBase);\n\t  if (offset == 0)\n\t    {\n\t      trailingZeroes++;\n\t    }\n\t  else\n\t    {\n\t      while (trailingZeroes > 0)\n\t\t{\n\t\t  /* Not trailing zeroes after all */\n\t\t  self->OutStream(self, digits[0]);\n\t\t  trailingZeroes--;\n\t\t}\n\t      self->OutStream(self, digits[offset]);\n\t    }\n\t}\n    }\n  \n  if (keepTrailingZeroes)\n    {\n      while (trailingZeroes > 0)\n\t{\n\t  self->OutStream(self, digits[0]);\n\t  trailingZeroes--;\n\t}\n    }\n  \n  /* Output exponent */\n  if (exponentDigits > 0)\n    {\n      self->OutStream(self,\n\t\t      isHex\n\t\t      ? ((flags & FLAGS_UPPER) ? 'P' : 'p')\n\t\t      : ((flags & FLAGS_UPPER) ? 'E' : 'e'));\n      self->OutStream(self, (isExponentNegative) ? '-' : '+');\n\n      /* The exponent must contain at least two digits */\n      if (requireTwoDigitExponent)\n        self->OutStream(self, '0');\n\n      if (isHex)\n\tbase = 10;\n      exponentBase = (int)TrioPower(base, exponentDigits - 1);\n      for (i = 0; i < exponentDigits; i++)\n\t{\n\t  self->OutStream(self, digits[(uExponent / exponentBase) % base]);\n\t  exponentBase /= base;\n\t}\n    }\n  /* Output trailing spaces */\n  if (flags & FLAGS_LEFTADJUST)\n    {\n      for (i = expectedWidth; i < width; i++)\n\t{\n\t  self->OutStream(self, CHAR_ADJUST);\n\t}\n    }\n}\n#endif /* TRIO_FEATURE_FLOAT */\n\n/*************************************************************************\n * TrioFormatProcess\n *\n * Description:\n *  This is the main engine for formatting output\n */\nTRIO_PRIVATE int\nTrioFormatProcess\nTRIO_ARGS3((data, format, parameters),\n\t   trio_class_t *data,\n\t   TRIO_CONST char *format,\n\t   trio_parameter_t *parameters)\n{\n  int i;\n#if TRIO_FEATURE_ERRNO\n  TRIO_CONST char *string;\n#endif\n  trio_pointer_t pointer;\n  trio_flags_t flags;\n  int width;\n  int precision;\n  int base;\n  int offset;\n  \n  offset = 0;\n  i = 0;\n\n  for (;;)\n    {\n      /* Skip the parameter entries */\n      while (parameters[i].type == FORMAT_PARAMETER)\n\ti++;\n\n      /* Copy non conversion-specifier part of format string */\n      while (offset < parameters[i].beginOffset)\n        {\n\t  if (CHAR_IDENTIFIER == format[offset] && CHAR_IDENTIFIER == format[offset + 1])\n\t    {\n\t      data->OutStream(data, CHAR_IDENTIFIER);\n\t      offset += 2;\n\t    }\n\t  else\n\t    {\n\t      data->OutStream(data, format[offset++]);\n\t    }\n\t}\n\n      /* Abort if we reached end of format string */\n      if (parameters[i].type == FORMAT_SENTINEL)\n\tbreak;\n\n      /* Ouput parameter */\n      flags = parameters[i].flags;\n\n      /* Find width */\n      width = parameters[i].width;\n      if (flags & FLAGS_WIDTH_PARAMETER)\n\t{\n\t  /* Get width from parameter list */\n\t  width = (int)parameters[width].data.number.as_signed;\n\t  if (width < 0)\n\t    {\n\t      /*\n\t       * A negative width is the same as the - flag and\n\t       * a positive width.\n\t       */\n\t      flags |= FLAGS_LEFTADJUST;\n\t      flags &= ~FLAGS_NILPADDING;\n\t      width = -width;\n\t    }\n\t}\n\n      /* Find precision */\n      if (flags & FLAGS_PRECISION)\n\t{\n\t  precision = parameters[i].precision;\n\t  if (flags & FLAGS_PRECISION_PARAMETER)\n\t    {\n\t      /* Get precision from parameter list */\n\t      precision = (int)parameters[precision].data.number.as_signed;\n\t      if (precision < 0)\n\t\t{\n\t\t  /*\n\t\t   * A negative precision is the same as no\n\t\t   * precision\n\t\t   */\n\t\t  precision = NO_PRECISION;\n\t\t}\n\t    }\n\t}\n      else\n\t{\n\t  precision = NO_PRECISION;\n\t}\n\n      /* Find base */\n      if (NO_BASE != parameters[i].baseSpecifier)\n\t{\n\t  /* Base from specifier has priority */\n\t  base = parameters[i].baseSpecifier;\n\t}\n      else if (flags & FLAGS_BASE_PARAMETER)\n\t{\n\t  /* Get base from parameter list */\n\t  base = parameters[i].base;\n\t  base = (int)parameters[base].data.number.as_signed;\n\t}\n      else\n\t{\n\t  /* Use base from format string */\n\t  base = parameters[i].base;\n\t}\n\n      switch (parameters[i].type)\n        {\n\tcase FORMAT_CHAR:\n#if TRIO_FEATURE_QUOTE\n\t  if (flags & FLAGS_QUOTE)\n\t    data->OutStream(data, CHAR_QUOTE);\n#endif\n\t  if (! (flags & FLAGS_LEFTADJUST))\n\t    {\n\t      while (--width > 0)\n\t\tdata->OutStream(data, CHAR_ADJUST);\n\t    }\n#if TRIO_FEATURE_WIDECHAR\n\t  if (flags & FLAGS_WIDECHAR)\n\t    {\n\t      TrioWriteWideStringCharacter(data,\n\t\t\t\t\t   (trio_wchar_t)parameters[i].data.number.as_signed,\n\t\t\t\t\t   flags,\n\t\t\t\t\t   NO_WIDTH);\n\t    }\n\t  else\n#endif\n\t  {\n\t    TrioWriteStringCharacter(data,\n\t\t\t\t     (int)parameters[i].data.number.as_signed,\n\t\t\t\t     flags);\n\t  }\n\n\t  if (flags & FLAGS_LEFTADJUST)\n\t    {\n\t      while(--width > 0)\n\t\tdata->OutStream(data, CHAR_ADJUST);\n\t    }\n#if TRIO_FEATURE_QUOTE\n\t  if (flags & FLAGS_QUOTE)\n\t    data->OutStream(data, CHAR_QUOTE);\n#endif\n\n\t  break; /* FORMAT_CHAR */\n\n\tcase FORMAT_INT:\n\t  TrioWriteNumber(data,\n\t\t\t  parameters[i].data.number.as_unsigned,\n\t\t\t  flags,\n\t\t\t  width,\n\t\t\t  precision,\n\t\t\t  base);\n\n\t  break; /* FORMAT_INT */\n\n#if TRIO_FEATURE_FLOAT\n\tcase FORMAT_DOUBLE:\n\t  TrioWriteDouble(data,\n\t\t\t  parameters[i].data.longdoubleNumber,\n\t\t\t  flags,\n\t\t\t  width,\n\t\t\t  precision,\n\t\t\t  base);\n\t  break; /* FORMAT_DOUBLE */\n#endif\n\n\tcase FORMAT_STRING:\n#if TRIO_FEATURE_WIDECHAR\n\t  if (flags & FLAGS_WIDECHAR)\n\t    {\n\t      TrioWriteWideString(data,\n\t\t\t\t  parameters[i].data.wstring,\n\t\t\t\t  flags,\n\t\t\t\t  width,\n\t\t\t\t  precision);\n\t    }\n\t  else\n#endif\n\t    {\n\t      TrioWriteString(data,\n\t\t\t      parameters[i].data.string,\n\t\t\t      flags,\n\t\t\t      width,\n\t\t\t      precision);\n\t    }\n\t  break; /* FORMAT_STRING */\n\n\tcase FORMAT_POINTER:\n\t  {\n\t    trio_reference_t reference;\n\n\t    reference.data = data;\n\t    reference.parameter = &parameters[i];\n\t    trio_print_pointer(&reference, parameters[i].data.pointer);\n\t  }\n\t  break; /* FORMAT_POINTER */\n\n\tcase FORMAT_COUNT:\n\t  pointer = parameters[i].data.pointer;\n\t  if (NULL != pointer)\n\t    {\n\t      /*\n\t       * C99 paragraph 7.19.6.1.8 says \"the number of\n\t       * characters written to the output stream so far by\n\t       * this call\", which is data->committed\n\t       */\n#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER\n\t      if (flags & FLAGS_SIZE_T)\n\t\t*(size_t *)pointer = (size_t)data->committed;\n\t      else\n#endif\n#if TRIO_FEATURE_PTRDIFF_T\n\t      if (flags & FLAGS_PTRDIFF_T)\n\t\t*(ptrdiff_t *)pointer = (ptrdiff_t)data->committed;\n\t      else\n#endif\n#if TRIO_FEATURE_INTMAX_T\n\t      if (flags & FLAGS_INTMAX_T)\n\t\t*(trio_intmax_t *)pointer = (trio_intmax_t)data->committed;\n\t      else\n#endif\n\t      if (flags & FLAGS_QUAD)\n\t\t{\n\t\t  *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)data->committed;\n\t\t}\n\t      else if (flags & FLAGS_LONG)\n\t\t{\n\t\t  *(long int *)pointer = (long int)data->committed;\n\t\t}\n\t      else if (flags & FLAGS_SHORT)\n\t\t{\n\t\t  *(short int *)pointer = (short int)data->committed;\n\t\t}\n\t      else\n\t\t{\n\t\t  *(int *)pointer = (int)data->committed;\n\t\t}\n\t    }\n\t  break; /* FORMAT_COUNT */\n\n\tcase FORMAT_PARAMETER:\n\t  break; /* FORMAT_PARAMETER */\n\n#if TRIO_FEATURE_ERRNO\n\tcase FORMAT_ERRNO:\n\t  string = trio_error(parameters[i].data.errorNumber);\n\t  if (string)\n\t    {\n\t      TrioWriteString(data,\n\t\t\t      string,\n\t\t\t      flags,\n\t\t\t      width,\n\t\t\t      precision);\n\t    }\n\t  else\n\t  {\n\t    data->OutStream(data, '#');\n\t    TrioWriteNumber(data,\n\t\t\t    (trio_uintmax_t)parameters[i].data.errorNumber,\n\t\t\t    flags,\n\t\t\t    width,\n\t\t\t    precision,\n\t\t\t    BASE_DECIMAL);\n\t  }\n\t  break; /* FORMAT_ERRNO */\n#endif /* TRIO_FEATURE_ERRNO */\n\n#if TRIO_FEATURE_USER_DEFINED\n\tcase FORMAT_USER_DEFINED:\n\t  {\n\t    trio_reference_t reference;\n\t    trio_userdef_t *def = NULL;\n\n\t    if (parameters[i].flags & FLAGS_USER_DEFINED_PARAMETER)\n\t      {\n\t\t/* Use handle */\n\t\tif ((i > 0) ||\n\t\t    (parameters[i - 1].type == FORMAT_PARAMETER))\n\t\t  def = (trio_userdef_t *)parameters[i - 1].data.pointer;\n\t      }\n\t    else\n\t      {\n\t\t/* Look up namespace */\n\t\tdef = TrioFindNamespace(parameters[i].user_defined.namespace, NULL);\n\t      }\n\t    if (def)\n\t      {\n\t\treference.data = data;\n\t\treference.parameter = &parameters[i];\n\t\tdef->callback(&reference);\n\t      }\n\t  }\n\t  break;\n#endif /* TRIO_FEATURE_USER_DEFINED */\n\n\tdefault:\n\t  break;\n\t} /* switch parameter type */\n\n      /* Prepare for next */\n      offset = parameters[i].endOffset;\n      i++;\n    }\n\n  return data->processed;\n}\n\n/*************************************************************************\n * TrioFormatRef\n */\n#if TRIO_EXTENSION\nTRIO_PRIVATE int\nTrioFormatRef\nTRIO_ARGS4((reference, format, arglist, argarray),\n\t   trio_reference_t *reference,\n\t   TRIO_CONST char *format,\n\t   va_list arglist,\n\t   trio_pointer_t *argarray)\n{\n  int status;\n  trio_parameter_t parameters[MAX_PARAMETERS];\n\n  status = TrioParse(TYPE_PRINT, format, parameters, arglist, argarray);\n  if (status < 0)\n    return status;\n\n  status = TrioFormatProcess(reference->data, format, parameters);\n  if (reference->data->error != 0)\n    {\n      status = reference->data->error;\n    }\n  return status;\n}\n#endif /* TRIO_EXTENSION */\n\n/*************************************************************************\n * TrioFormat\n */\nTRIO_PRIVATE int\nTrioFormat\nTRIO_ARGS6((destination, destinationSize, OutStream, format, arglist, argarray),\n\t   trio_pointer_t destination,\n\t   size_t destinationSize,\n\t   void (*OutStream) TRIO_PROTO((trio_class_t *, int)),\n\t   TRIO_CONST char *format,\n\t   va_list arglist,\n\t   trio_pointer_t *argarray)\n{\n  int status;\n  trio_class_t data;\n  trio_parameter_t parameters[MAX_PARAMETERS];\n\n  assert(VALID(OutStream));\n  assert(VALID(format));\n\n  memset(&data, 0, sizeof(data));\n  data.OutStream = OutStream;\n  data.location = destination;\n  data.max = destinationSize;\n  data.error = 0;\n\n#if defined(USE_LOCALE)\n  if (NULL == internalLocaleValues)\n    {\n      TrioSetLocale();\n    }\n#endif\n\n  status = TrioParse(TYPE_PRINT, format, parameters, arglist, argarray);\n  if (status < 0)\n    return status;\n\n  status = TrioFormatProcess(&data, format, parameters);\n  if (data.error != 0)\n    {\n      status = data.error;\n    }\n  return status;\n}\n\n/*************************************************************************\n * TrioOutStreamFile\n */\n#if TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO\nTRIO_PRIVATE void\nTrioOutStreamFile\nTRIO_ARGS2((self, output),\n\t   trio_class_t *self,\n\t   int output)\n{\n  FILE *file;\n\n  assert(VALID(self));\n  assert(VALID(self->location));\n\n  file = (FILE *)self->location;\n  self->processed++;\n  if (fputc(output, file) == EOF)\n    {\n      self->error = TRIO_ERROR_RETURN(TRIO_EOF, 0);\n    }\n  else\n    {\n      self->committed++;\n    }\n}\n#endif /* TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO */\n\n/*************************************************************************\n * TrioOutStreamFileDescriptor\n */\n#if TRIO_FEATURE_FD\nTRIO_PRIVATE void\nTrioOutStreamFileDescriptor\nTRIO_ARGS2((self, output),\n\t   trio_class_t *self,\n\t   int output)\n{\n  int fd;\n  char ch;\n\n  assert(VALID(self));\n\n  fd = *((int *)self->location);\n  ch = (char)output;\n  self->processed++;\n  if (write(fd, &ch, sizeof(char)) == -1)\n    {\n      self->error = TRIO_ERROR_RETURN(TRIO_ERRNO, 0);\n    }\n  else\n    {\n      self->committed++;\n    }\n}\n#endif /* TRIO_FEATURE_FD */\n\n/*************************************************************************\n * TrioOutStreamCustom\n */\n#if TRIO_FEATURE_CLOSURE\nTRIO_PRIVATE void\nTrioOutStreamCustom\nTRIO_ARGS2((self, output),\n\t   trio_class_t *self,\n\t   int output)\n{\n  int status;\n  trio_custom_t *data;\n\n  assert(VALID(self));\n  assert(VALID(self->location));\n\n  data = (trio_custom_t *)self->location;\n  if (data->stream.out)\n    {\n      status = (data->stream.out)(data->closure, output);\n      if (status >= 0)\n\t{\n\t  self->committed++;\n\t}\n      else\n\t{\n\t  if (self->error == 0)\n\t    {\n\t      self->error = TRIO_ERROR_RETURN(TRIO_ECUSTOM, -status);\n\t    }\n\t}\n    }\n  self->processed++;\n}\n#endif /* TRIO_FEATURE_CLOSURE */\n\n/*************************************************************************\n * TrioOutStreamString\n */\nTRIO_PRIVATE void\nTrioOutStreamString\nTRIO_ARGS2((self, output),\n\t   trio_class_t *self,\n\t   int output)\n{\n  char **buffer;\n\n  assert(VALID(self));\n  assert(VALID(self->location));\n\n  buffer = (char **)self->location;\n  **buffer = (char)output;\n  (*buffer)++;\n  self->processed++;\n  self->committed++;\n}\n\n/*************************************************************************\n * TrioOutStreamStringMax\n */\nTRIO_PRIVATE void\nTrioOutStreamStringMax\nTRIO_ARGS2((self, output),\n\t   trio_class_t *self,\n\t   int output)\n{\n  char **buffer;\n\n  assert(VALID(self));\n  assert(VALID(self->location));\n  \n  buffer = (char **)self->location;\n\n  if (self->processed < self->max)\n    {\n      **buffer = (char)output;\n      (*buffer)++;\n      self->committed++;\n    }\n  self->processed++;\n}\n\n/*************************************************************************\n * TrioOutStreamStringDynamic\n */\n#if TRIO_FEATURE_DYNAMICSTRING\nTRIO_PRIVATE void\nTrioOutStreamStringDynamic\nTRIO_ARGS2((self, output),\n\t   trio_class_t *self,\n\t   int output)\n{\n  assert(VALID(self));\n  assert(VALID(self->location));\n\n  if (self->error == 0)\n    {\n      trio_xstring_append_char((trio_string_t *)self->location,\n\t\t\t       (char)output);\n      self->committed++;\n    }\n  /* The processed variable must always be increased */\n  self->processed++;\n}\n#endif /* TRIO_FEATURE_DYNAMICSTRING */\n\n/*************************************************************************\n *\n * Formatted printing functions\n *\n ************************************************************************/\n\n#if defined(TRIO_DOCUMENTATION)\n# include \"doc/doc_printf.h\"\n#endif\n/** @addtogroup Printf\n    @{\n*/\n\n/*************************************************************************\n * printf\n */\n\n/**\n   Print to standard output stream.\n\n   @param format Formatting string.\n   @param ... Arguments.\n   @return Number of printed characters.\n */\n#if TRIO_FEATURE_STDIO\nTRIO_PUBLIC int\nprintf\nTRIO_VARGS2((format, va_alist),\n\t    TRIO_CONST char *format,\n\t    TRIO_VA_DECL)\n{\n  int status;\n  va_list args;\n\n  assert(VALID(format));\n  \n  TRIO_VA_START(args, format);\n  status = TrioFormat(stdout, 0, TrioOutStreamFile, format, args, NULL);\n  TRIO_VA_END(args);\n\n  fflush( stdout );\n\n  return status;\n}\n#endif /* TRIO_FEATURE_STDIO */\n\n/**\n   Print to standard output stream.\n\n   @param format Formatting string.\n   @param args Arguments.\n   @return Number of printed characters.\n */\n#if TRIO_FEATURE_STDIO\nTRIO_PUBLIC int\nvprintf\nTRIO_ARGS2((format, args),\n\t   TRIO_CONST char *format,\n\t   va_list args)\n{\n  int ret;\n\n  assert(VALID(format));\n\n  ret = TrioFormat(stdout, 0, TrioOutStreamFile, format, args, NULL);\n\n  fflush( stdout );\n\n  return ret;\n}\n#endif /* TRIO_FEATURE_STDIO */\n\n/**\n   Print to standard output stream.\n\n   @param format Formatting string.\n   @param args Arguments.\n   @return Number of printed characters.\n */\n#if TRIO_FEATURE_STDIO\nTRIO_PUBLIC int\ntrio_printfv\nTRIO_ARGS2((format, args),\n\t   TRIO_CONST char *format,\n\t   trio_pointer_t * args)\n{\n  static va_list unused;\n  \n  assert(VALID(format));\n\n  return TrioFormat(stdout, 0, TrioOutStreamFile, format, unused, args);\n}\n#endif /* TRIO_FEATURE_STDIO */\n\n/*************************************************************************\n * fprintf\n */\n\n/**\n   Print to file.\n\n   @param file File pointer.\n   @param format Formatting string.\n   @param ... Arguments.\n   @return Number of printed characters.\n */\n#if TRIO_FEATURE_FILE\nTRIO_PUBLIC int\nfprintf\nTRIO_VARGS3((file, format, va_alist),\n\t    FILE *file,\n\t    TRIO_CONST char *format,\n\t    TRIO_VA_DECL)\n{\n  int status;\n  va_list args;\n\n  assert(VALID(file));\n  assert(VALID(format));\n  \n  TRIO_VA_START(args, format);\n  status = TrioFormat(file, 0, TrioOutStreamFile, format, args, NULL);\n  TRIO_VA_END(args);\n  return status;\n}\n#endif /* TRIO_FEATURE_FILE */\n\n/**\n   Print to file.\n\n   @param file File pointer.\n   @param format Formatting string.\n   @param args Arguments.\n   @return Number of printed characters.\n */\n#if TRIO_FEATURE_FILE\nTRIO_PUBLIC int\nvfprintf\nTRIO_ARGS3((file, format, args),\n\t   FILE *file,\n\t   TRIO_CONST char *format,\n\t   va_list args)\n{\n  assert(VALID(file));\n  assert(VALID(format));\n  \n  return TrioFormat(file, 0, TrioOutStreamFile, format, args, NULL);\n}\n#endif /* TRIO_FEATURE_FILE */\n\n/**\n   Print to file.\n\n   @param file File pointer.\n   @param format Formatting string.\n   @param args Arguments.\n   @return Number of printed characters.\n */\n#if TRIO_FEATURE_FILE\nTRIO_PUBLIC int\ntrio_fprintfv\nTRIO_ARGS3((file, format, args),\n\t   FILE *file,\n\t   TRIO_CONST char *format,\n\t   trio_pointer_t * args)\n{\n  static va_list unused;\n  \n  assert(VALID(file));\n  assert(VALID(format));\n  \n  return TrioFormat(file, 0, TrioOutStreamFile, format, unused, args);\n}\n#endif /* TRIO_FEATURE_FILE */\n\n/*************************************************************************\n * dprintf\n */\n\n/**\n   Print to file descriptor.\n\n   @param fd File descriptor.\n   @param format Formatting string.\n   @param ... Arguments.\n   @return Number of printed characters.\n */\n#if TRIO_FEATURE_FD\nTRIO_PUBLIC int\ntrio_dprintf\nTRIO_VARGS3((fd, format, va_alist),\n\t    int fd,\n\t    TRIO_CONST char *format,\n\t    TRIO_VA_DECL)\n{\n  int status;\n  va_list args;\n\n  assert(VALID(format));\n  \n  TRIO_VA_START(args, format);\n  status = TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, args, NULL);\n  TRIO_VA_END(args);\n  return status;\n}\n#endif /* TRIO_FEATURE_FD */\n\n/**\n   Print to file descriptor.\n\n   @param fd File descriptor.\n   @param format Formatting string.\n   @param args Arguments.\n   @return Number of printed characters.\n */\n#if TRIO_FEATURE_FD\nTRIO_PUBLIC int\ntrio_vdprintf\nTRIO_ARGS3((fd, format, args),\n\t   int fd,\n\t   TRIO_CONST char *format,\n\t   va_list args)\n{\n  assert(VALID(format));\n  \n  return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, args, NULL);\n}\n#endif /* TRIO_FEATURE_FD */\n\n/**\n   Print to file descriptor.\n\n   @param fd File descriptor.\n   @param format Formatting string.\n   @param args Arguments.\n   @return Number of printed characters.\n */\n#if TRIO_FEATURE_FD\nTRIO_PUBLIC int\ntrio_dprintfv\nTRIO_ARGS3((fd, format, args),\n\t   int fd,\n\t   TRIO_CONST char *format,\n\t   trio_pointer_t *args)\n{\n  static va_list unused;\n  \n  assert(VALID(format));\n  \n  return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, unused, args);\n}\n#endif /* TRIO_FEATURE_FD */\n\n/*************************************************************************\n * cprintf\n */\n#if TRIO_FEATURE_CLOSURE\nTRIO_PUBLIC int\ntrio_cprintf\nTRIO_VARGS4((stream, closure, format, va_alist),\n\t    trio_outstream_t stream,\n\t    trio_pointer_t closure,\n\t    TRIO_CONST char *format,\n\t    TRIO_VA_DECL)\n{\n  int status;\n  va_list args;\n  trio_custom_t data;\n\n  assert(VALID(stream));\n  assert(VALID(format));\n\n  TRIO_VA_START(args, format);\n  data.stream.out = stream;\n  data.closure = closure;\n  status = TrioFormat(&data, 0, TrioOutStreamCustom, format, args, NULL);\n  TRIO_VA_END(args);\n  return status;\n}\n#endif /* TRIO_FEATURE_CLOSURE */\n\n#if TRIO_FEATURE_CLOSURE\nTRIO_PUBLIC int\ntrio_vcprintf\nTRIO_ARGS4((stream, closure, format, args),\n\t   trio_outstream_t stream,\n\t   trio_pointer_t closure,\n\t   TRIO_CONST char *format,\n\t   va_list args)\n{\n  trio_custom_t data;\n\n  assert(VALID(stream));\n  assert(VALID(format));\n\n  data.stream.out = stream;\n  data.closure = closure;\n  return TrioFormat(&data, 0, TrioOutStreamCustom, format, args, NULL);\n}\n#endif /* TRIO_FEATURE_CLOSURE */\n\n#if TRIO_FEATURE_CLOSURE\nTRIO_PUBLIC int\ntrio_cprintfv\nTRIO_ARGS4((stream, closure, format, args),\n\t   trio_outstream_t stream,\n\t   trio_pointer_t closure,\n\t   TRIO_CONST char *format,\n\t   void **args)\n{\n  static va_list unused;\n  trio_custom_t data;\n\n  assert(VALID(stream));\n  assert(VALID(format));\n\n  data.stream.out = stream;\n  data.closure = closure;\n  return TrioFormat(&data, 0, TrioOutStreamCustom, format, unused, args);\n}\n#endif /* TRIO_FEATURE_CLOSURE */\n\n/*************************************************************************\n * sprintf\n */\n\n/**\n   Print to string.\n\n   @param buffer Output string.\n   @param format Formatting string.\n   @param ... Arguments.\n   @return Number of printed characters.\n */\nTRIO_PUBLIC int\nsprintf\nTRIO_VARGS3((buffer, format, va_alist),\n\t    char *buffer,\n\t    TRIO_CONST char *format,\n\t    TRIO_VA_DECL)\n{\n  int status;\n  va_list args;\n\n  assert(VALID(buffer));\n  assert(VALID(format));\n  \n  TRIO_VA_START(args, format);\n  status = TrioFormat(&buffer, 0, TrioOutStreamString, format, args, NULL);\n  *buffer = NIL; /* Terminate with NIL character */\n  TRIO_VA_END(args);\n  return status;\n}\n\n/**\n   Print to string.\n\n   @param buffer Output string.\n   @param format Formatting string.\n   @param args Arguments.\n   @return Number of printed characters.\n */\nTRIO_PUBLIC int\nvsprintf\nTRIO_ARGS3((buffer, format, args),\n\t   char *buffer,\n\t   TRIO_CONST char *format,\n\t   va_list args)\n{\n  int status;\n\n  assert(VALID(buffer));\n  assert(VALID(format));\n\n  status = TrioFormat(&buffer, 0, TrioOutStreamString, format, args, NULL);\n  *buffer = NIL;\n  return status;\n}\n\n/**\n   Print to string.\n\n   @param buffer Output string.\n   @param format Formatting string.\n   @param args Arguments.\n   @return Number of printed characters.\n */\nTRIO_PUBLIC int\ntrio_sprintfv\nTRIO_ARGS3((buffer, format, args),\n\t   char *buffer,\n\t   TRIO_CONST char *format,\n\t   trio_pointer_t *args)\n{\n  static va_list unused;\n  int status;\n  \n  assert(VALID(buffer));\n  assert(VALID(format));\n\n  status = TrioFormat(&buffer, 0, TrioOutStreamString, format, unused, args);\n  *buffer = NIL;\n  return status;\n}\n\n/*************************************************************************\n * snprintf\n */\n\n/**\n   Print at most @p max characters to string.\n\n   @param buffer Output string.\n   @param max Maximum number of characters to print.\n   @param format Formatting string.\n   @param ... Arguments.\n   @return Number of printed characters.\n */\nTRIO_PUBLIC int\nsnprintf\nTRIO_VARGS4((buffer, max, format, va_alist),\n\t    char *buffer,\n\t    size_t max,\n\t    TRIO_CONST char *format,\n\t    TRIO_VA_DECL)\n{\n  int status;\n  va_list args;\n\n  assert(VALID(buffer));\n  assert(VALID(format));\n\n  TRIO_VA_START(args, format);\n  status = TrioFormat(&buffer, max > 0 ? max - 1 : 0,\n\t\t      TrioOutStreamStringMax, format, args, NULL);\n  if (max > 0)\n    *buffer = NIL;\n  TRIO_VA_END(args);\n  return status;\n}\n\n/**\n   Print at most @p max characters to string.\n\n   @param buffer Output string.\n   @param max Maximum number of characters to print.\n   @param format Formatting string.\n   @param args Arguments.\n   @return Number of printed characters.\n */\nTRIO_PUBLIC int\nvsnprintf\nTRIO_ARGS4((buffer, max, format, args),\n\t   char *buffer,\n\t   size_t max,\n\t   TRIO_CONST char *format,\n\t   va_list args)\n{\n  int status;\n\n  assert(VALID(buffer));\n  assert(VALID(format));\n\n  status = TrioFormat(&buffer, max > 0 ? max - 1 : 0,\n\t\t      TrioOutStreamStringMax, format, args, NULL);\n  if (max > 0)\n    *buffer = NIL;\n  return status;\n}\n\n/**\n   Print at most @p max characters to string.\n\n   @param buffer Output string.\n   @param max Maximum number of characters to print.\n   @param format Formatting string.\n   @param args Arguments.\n   @return Number of printed characters.\n */\nTRIO_PUBLIC int\ntrio_snprintfv\nTRIO_ARGS4((buffer, max, format, args),\n\t   char *buffer,\n\t   size_t max,\n\t   TRIO_CONST char *format,\n\t   trio_pointer_t *args)\n{\n  static va_list unused;\n  int status;\n  \n  assert(VALID(buffer));\n  assert(VALID(format));\n\n  status = TrioFormat(&buffer, max > 0 ? max - 1 : 0,\n\t\t      TrioOutStreamStringMax, format, unused, args);\n  if (max > 0)\n    *buffer = NIL;\n  return status;\n}\n\n/*************************************************************************\n * snprintfcat\n * Appends the new string to the buffer string overwriting the '\\0'\n * character at the end of buffer.\n */\n#if TRIO_EXTENSION\nTRIO_PUBLIC int\ntrio_snprintfcat\nTRIO_VARGS4((buffer, max, format, va_alist),\n\t    char *buffer,\n\t    size_t max,\n\t    TRIO_CONST char *format,\n\t    TRIO_VA_DECL)\n{\n  int status;\n  va_list args;\n  size_t buf_len;\n\n  TRIO_VA_START(args, format);\n\n  assert(VALID(buffer));\n  assert(VALID(format));\n\n  buf_len = trio_length(buffer);\n  buffer = &buffer[buf_len];\n\n  status = TrioFormat(&buffer, max - 1 - buf_len,\n\t\t      TrioOutStreamStringMax, format, args, NULL);\n  TRIO_VA_END(args);\n  *buffer = NIL;\n  return status;\n}\n#endif\n\n#if TRIO_EXTENSION\nTRIO_PUBLIC int\ntrio_vsnprintfcat\nTRIO_ARGS4((buffer, max, format, args),\n\t   char *buffer,\n\t   size_t max,\n\t   TRIO_CONST char *format,\n\t   va_list args)\n{\n  int status;\n  size_t buf_len;\n  \n  assert(VALID(buffer));\n  assert(VALID(format));\n\n  buf_len = trio_length(buffer);\n  buffer = &buffer[buf_len];\n  status = TrioFormat(&buffer, max - 1 - buf_len,\n\t\t      TrioOutStreamStringMax, format, args, NULL);\n  *buffer = NIL;\n  return status;\n}\n#endif\n\n/*************************************************************************\n * trio_aprintf\n */\n\n#if TRIO_DEPRECATED && TRIO_FEATURE_DYNAMICSTRING\nTRIO_PUBLIC char *\ntrio_aprintf\nTRIO_VARGS2((format, va_alist),\n\t    TRIO_CONST char *format,\n\t    TRIO_VA_DECL)\n{\n  va_list args;\n  trio_string_t *info;\n  char *result = NULL;\n\n  assert(VALID(format));\n  \n  info = trio_xstring_duplicate(\"\");\n  if (info)\n    {\n      TRIO_VA_START(args, format);\n      (void)TrioFormat(info, 0, TrioOutStreamStringDynamic,\n\t\t       format, args, NULL);\n      TRIO_VA_END(args);\n\n      trio_string_terminate(info);\n      result = trio_string_extract(info);\n      trio_string_destroy(info);\n    }\n  return result;\n}\n#endif /* TRIO_DEPRECATED && TRIO_FEATURE_DYNAMICSTRING */\n\n#if TRIO_DEPRECATED && TRIO_FEATURE_DYNAMICSTRING\nTRIO_PUBLIC char *\ntrio_vaprintf\nTRIO_ARGS2((format, args),\n\t   TRIO_CONST char *format,\n\t   va_list args)\n{\n  trio_string_t *info;\n  char *result = NULL;\n  \n  assert(VALID(format));\n  \n  info = trio_xstring_duplicate(\"\");\n  if (info)\n    {\n      (void)TrioFormat(info, 0, TrioOutStreamStringDynamic,\n\t\t       format, args, NULL);\n      trio_string_terminate(info);\n      result = trio_string_extract(info);\n      trio_string_destroy(info);\n    }\n  return result;\n}\n#endif /* TRIO_DEPRECATED && TRIO_FEATURE_DYNAMICSTRING */\n\n/**\n   Allocate and print to string.\n   The memory allocated and returned by @p result must be freed by the\n   calling application.\n\n   @param result Output string.\n   @param format Formatting string.\n   @param ... Arguments.\n   @return Number of printed characters.\n */\n#if TRIO_FEATURE_DYNAMICSTRING\nTRIO_PUBLIC int\nasprintf\nTRIO_VARGS3((result, format, va_alist),\n\t    char **result,\n\t    TRIO_CONST char *format,\n\t    TRIO_VA_DECL)\n{\n  va_list args;\n  int status;\n  trio_string_t *info;\n\n  assert(VALID(format));\n\n  *result = NULL;\n  \n  info = trio_xstring_duplicate(\"\");\n  if (info == NULL)\n    {\n      status = TRIO_ERROR_RETURN(TRIO_ENOMEM, 0);\n    }\n  else\n    {\n      TRIO_VA_START(args, format);\n      status = TrioFormat(info, 0, TrioOutStreamStringDynamic,\n\t\t\t  format, args, NULL);\n      TRIO_VA_END(args);\n      if (status >= 0)\n\t{\n\t  trio_string_terminate(info);\n\t  *result = trio_string_extract(info);\n\t}\n      trio_string_destroy(info);\n    }\n  return status;\n}\n#endif /* TRIO_FEATURE_DYNAMICSTRING */\n\n/**\n   Allocate and print to string.\n   The memory allocated and returned by @p result must be freed by the\n   calling application.\n\n   @param result Output string.\n   @param format Formatting string.\n   @param args Arguments.\n   @return Number of printed characters.\n */\n#if TRIO_FEATURE_DYNAMICSTRING\nTRIO_PUBLIC int\ntrio_vasprintf\nTRIO_ARGS3((result, format, args),\n\t   char **result,\n\t   TRIO_CONST char *format,\n\t   va_list args)\n{\n  int status;\n  trio_string_t *info;\n  \n  assert(VALID(format));\n\n  *result = NULL;\n  \n  info = trio_xstring_duplicate(\"\");\n  if (info == NULL)\n    {\n      status = TRIO_ERROR_RETURN(TRIO_ENOMEM, 0);\n    }\n  else\n    {\n      status = TrioFormat(info, 0, TrioOutStreamStringDynamic,\n\t\t\t  format, args, NULL);\n      if (status >= 0)\n\t{\n\t  trio_string_terminate(info);\n\t  *result = trio_string_extract(info);\n\t}\n      trio_string_destroy(info);\n    }\n  return status;\n}\n#endif /* TRIO_FEATURE_DYNAMICSTRING */\n\n/**\n   Allocate and print to string.\n   The memory allocated and returned by @p result must be freed by the\n   calling application.\n\n   @param result Output string.\n   @param format Formatting string.\n   @param args Arguments.\n   @return Number of printed characters.\n */\n#if TRIO_FEATURE_DYNAMICSTRING\nTRIO_PUBLIC int\ntrio_asprintfv\nTRIO_ARGS3((result, format, args),\n           char **result,\n           TRIO_CONST char *format,\n           trio_pointer_t * args)\n{\n  static va_list unused;\n  int status;\n  trio_string_t *info;\n  \n  assert(VALID(format));\n\n  *result = NULL;\n\n  info = trio_xstring_duplicate(\"\");\n  if (info == NULL)\n    {\n      status = TRIO_ERROR_RETURN(TRIO_ENOMEM, 0);\n    }\n  else\n    {\n      status = TrioFormat(info, 0, TrioOutStreamStringDynamic,\n                          format, unused, args);\n      if (status >= 0)\n        {\n          trio_string_terminate(info);\n          *result = trio_string_extract(info);\n        }\n      trio_string_destroy(info);\n    }\n  return status;\n}\n#endif /* TRIO_FEATURE_DYNAMICSTRING */\n\n/** @} End of Printf documentation module */\n\n/*************************************************************************\n *\n * CALLBACK\n *\n ************************************************************************/\n\n#if defined(TRIO_DOCUMENTATION)\n# include \"doc/doc_register.h\"\n#endif\n/**\n   @addtogroup UserDefined\n   @{\n*/\n\n#if TRIO_FEATURE_USER_DEFINED\n\n/*************************************************************************\n * trio_register\n */\n\n/**\n   Register new user-defined specifier.\n\n   @param callback\n   @param name\n   @return Handle.\n */\nTRIO_PUBLIC trio_pointer_t \ntrio_register\nTRIO_ARGS2((callback, name),\n\t   trio_callback_t callback,\n\t   TRIO_CONST char *name)\n{\n  trio_userdef_t *def;\n  trio_userdef_t *prev = NULL;\n\n  if (callback == NULL)\n    return NULL;\n\n  if (name)\n    {\n      /* Handle built-in namespaces */\n      if (name[0] == ':')\n\t{\n\t  if (trio_equal(name, \":enter\"))\n\t    {\n\t      internalEnterCriticalRegion = callback;\n\t    }\n\t  else if (trio_equal(name, \":leave\"))\n\t    {\n\t      internalLeaveCriticalRegion = callback;\n\t    }\n\t  return NULL;\n\t}\n      \n      /* Bail out if namespace is too long */\n      if (trio_length(name) >= MAX_USER_NAME)\n\treturn NULL;\n      \n      /* Bail out if namespace already is registered */\n      def = TrioFindNamespace(name, &prev);\n      if (def)\n\treturn NULL;\n    }\n  \n  def = (trio_userdef_t *)TRIO_MALLOC(sizeof(trio_userdef_t));\n  if (def)\n    {\n      if (internalEnterCriticalRegion)\n\t(void)internalEnterCriticalRegion(NULL);\n      \n      if (name)\n\t{\n\t  /* Link into internal list */\n\t  if (prev == NULL)\n\t    internalUserDef = def;\n\t  else\n\t    prev->next = def;\n\t}\n      /* Initialize */\n      def->callback = callback;\n      def->name = (name == NULL)\n\t? NULL\n\t: trio_duplicate(name);\n      def->next = NULL;\n\n      if (internalLeaveCriticalRegion)\n\t(void)internalLeaveCriticalRegion(NULL);\n    }\n  return (trio_pointer_t)def;\n}\n\n/**\n   Unregister an existing user-defined specifier.\n\n   @param handle\n */\nvoid\ntrio_unregister\nTRIO_ARGS1((handle),\n\t   trio_pointer_t handle)\n{\n  trio_userdef_t *self = (trio_userdef_t *)handle;\n  trio_userdef_t *def;\n  trio_userdef_t *prev = NULL;\n\n  assert(VALID(self));\n\n  if (self->name)\n    {\n      def = TrioFindNamespace(self->name, &prev);\n      if (def)\n\t{\n\t  if (internalEnterCriticalRegion)\n\t    (void)internalEnterCriticalRegion(NULL);\n\t  \n\t  if (prev == NULL)\n\t    internalUserDef = internalUserDef->next;\n\t  else\n\t    prev->next = def->next;\n\t  \n\t  if (internalLeaveCriticalRegion)\n\t    (void)internalLeaveCriticalRegion(NULL);\n\t}\n      trio_destroy(self->name);\n    }\n  TRIO_FREE(self);\n}\n\n/*************************************************************************\n * trio_get_format [public]\n */\nTRIO_CONST char *\ntrio_get_format\nTRIO_ARGS1((ref),\n\t   trio_pointer_t ref)\n{\n#if TRIO_FEATURE_USER_DEFINED\n  assert(((trio_reference_t *)ref)->parameter->type == FORMAT_USER_DEFINED);\n#endif\n  \n  return (((trio_reference_t *)ref)->parameter->user_data);\n}\n\n/*************************************************************************\n * trio_get_argument [public]\n */\ntrio_pointer_t \ntrio_get_argument\nTRIO_ARGS1((ref),\n\t   trio_pointer_t ref)\n{\n#if TRIO_FEATURE_USER_DEFINED\n  assert(((trio_reference_t *)ref)->parameter->type == FORMAT_USER_DEFINED);\n#endif\n  \n  return ((trio_reference_t *)ref)->parameter->data.pointer;\n}\n\n/*************************************************************************\n * trio_get_width / trio_set_width [public]\n */\nint\ntrio_get_width\nTRIO_ARGS1((ref),\n\t   trio_pointer_t ref)\n{\n  return ((trio_reference_t *)ref)->parameter->width;\n}\n\nvoid\ntrio_set_width\nTRIO_ARGS2((ref, width),\n\t   trio_pointer_t ref,\n\t   int width)\n{\n  ((trio_reference_t *)ref)->parameter->width = width;\n}\n\n/*************************************************************************\n * trio_get_precision / trio_set_precision [public]\n */\nint\ntrio_get_precision\nTRIO_ARGS1((ref),\n\t   trio_pointer_t ref)\n{\n  return (((trio_reference_t *)ref)->parameter->precision);\n}\n\nvoid\ntrio_set_precision\nTRIO_ARGS2((ref, precision),\n\t   trio_pointer_t ref,\n\t   int precision)\n{\n  ((trio_reference_t *)ref)->parameter->precision = precision;\n}\n\n/*************************************************************************\n * trio_get_base / trio_set_base [public]\n */\nint\ntrio_get_base\nTRIO_ARGS1((ref),\n\t   trio_pointer_t ref)\n{\n  return (((trio_reference_t *)ref)->parameter->base);\n}\n\nvoid\ntrio_set_base\nTRIO_ARGS2((ref, base),\n\t   trio_pointer_t ref,\n\t   int base)\n{\n  ((trio_reference_t *)ref)->parameter->base = base;\n}\n\n/*************************************************************************\n * trio_get_long / trio_set_long [public]\n */\nint\ntrio_get_long\nTRIO_ARGS1((ref),\n\t   trio_pointer_t ref)\n{\n  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LONG)\n    ? TRUE\n    : FALSE;\n}\n\nvoid\ntrio_set_long\nTRIO_ARGS2((ref, is_long),\n\t   trio_pointer_t ref,\n\t   int is_long)\n{\n  if (is_long)\n    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_LONG;\n  else\n    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LONG;\n}\n\n/*************************************************************************\n * trio_get_longlong / trio_set_longlong [public]\n */\nint\ntrio_get_longlong\nTRIO_ARGS1((ref),\n\t   trio_pointer_t ref)\n{\n  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_QUAD)\n    ? TRUE\n    : FALSE;\n}\n\nvoid\ntrio_set_longlong\nTRIO_ARGS2((ref, is_longlong),\n\t   trio_pointer_t ref,\n\t   int is_longlong)\n{\n  if (is_longlong)\n    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_QUAD;\n  else\n    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_QUAD;\n}\n\n/*************************************************************************\n * trio_get_longdouble / trio_set_longdouble [public]\n */\n# if TRIO_FEATURE_FLOAT\nint\ntrio_get_longdouble\nTRIO_ARGS1((ref),\n\t   trio_pointer_t ref)\n{\n  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LONGDOUBLE)\n    ? TRUE\n    : FALSE;\n}\n\nvoid\ntrio_set_longdouble\nTRIO_ARGS2((ref, is_longdouble),\n\t   trio_pointer_t ref,\n\t   int is_longdouble)\n{\n  if (is_longdouble)\n    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_LONGDOUBLE;\n  else\n    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LONGDOUBLE;\n}\n# endif /* TRIO_FEATURE_FLOAT */\n\n/*************************************************************************\n * trio_get_short / trio_set_short [public]\n */\nint\ntrio_get_short\nTRIO_ARGS1((ref),\n\t   trio_pointer_t ref)\n{\n  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHORT)\n    ? TRUE\n    : FALSE;\n}\n\nvoid\ntrio_set_short\nTRIO_ARGS2((ref, is_short),\n\t   trio_pointer_t ref,\n\t   int is_short)\n{\n  if (is_short)\n    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHORT;\n  else\n    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHORT;\n}\n\n/*************************************************************************\n * trio_get_shortshort / trio_set_shortshort [public]\n */\nint\ntrio_get_shortshort\nTRIO_ARGS1((ref),\n\t   trio_pointer_t ref)\n{\n  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHORTSHORT)\n    ? TRUE\n    : FALSE;\n}\n\nvoid\ntrio_set_shortshort\nTRIO_ARGS2((ref, is_shortshort),\n\t   trio_pointer_t ref,\n\t   int is_shortshort)\n{\n  if (is_shortshort)\n    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHORTSHORT;\n  else\n    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHORTSHORT;\n}\n\n/*************************************************************************\n * trio_get_alternative / trio_set_alternative [public]\n */\nint\ntrio_get_alternative\nTRIO_ARGS1((ref),\n\t   trio_pointer_t ref)\n{\n  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_ALTERNATIVE)\n    ? TRUE\n    : FALSE;\n}\n\nvoid\ntrio_set_alternative\nTRIO_ARGS2((ref, is_alternative),\n\t   trio_pointer_t ref,\n\t   int is_alternative)\n{\n  if (is_alternative)\n    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_ALTERNATIVE;\n  else\n    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_ALTERNATIVE;\n}\n\n/*************************************************************************\n * trio_get_alignment / trio_set_alignment [public]\n */\nint\ntrio_get_alignment\nTRIO_ARGS1((ref),\n\t   trio_pointer_t ref)\n{\n  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LEFTADJUST)\n    ? TRUE\n    : FALSE;\n}\n\nvoid\ntrio_set_alignment\nTRIO_ARGS2((ref, is_leftaligned),\n\t   trio_pointer_t ref,\n\t   int is_leftaligned)\n{\n  if (is_leftaligned)\n    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_LEFTADJUST;\n  else\n    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LEFTADJUST;\n}\n\n/*************************************************************************\n * trio_get_spacing /trio_set_spacing [public]\n */\nint\ntrio_get_spacing\nTRIO_ARGS1((ref),\n\t   trio_pointer_t ref)\n{\n  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SPACE)\n    ? TRUE\n    : FALSE;\n}\n\nvoid\ntrio_set_spacing\nTRIO_ARGS2((ref, is_space),\n\t   trio_pointer_t ref,\n\t   int is_space)\n{\n  if (is_space)\n    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SPACE;\n  else\n    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SPACE;\n}\n\n/*************************************************************************\n * trio_get_sign / trio_set_sign [public]\n */\nint\ntrio_get_sign\nTRIO_ARGS1((ref),\n\t   trio_pointer_t ref)\n{\n  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHOWSIGN)\n    ? TRUE\n    : FALSE;\n}\n\nvoid\ntrio_set_sign\nTRIO_ARGS2((ref, is_sign),\n\t   trio_pointer_t ref,\n\t   int is_sign)\n{\n  if (is_sign)\n    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHOWSIGN;\n  else\n    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHOWSIGN;\n}\n\n/*************************************************************************\n * trio_get_padding / trio_set_padding [public]\n */\nint\ntrio_get_padding\nTRIO_ARGS1((ref),\n\t   trio_pointer_t ref)\n{\n  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_NILPADDING)\n    ? TRUE\n    : FALSE;\n}\n\nvoid\ntrio_set_padding\nTRIO_ARGS2((ref, is_padding),\n\t   trio_pointer_t ref,\n\t   int is_padding)\n{\n  if (is_padding)\n    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_NILPADDING;\n  else\n    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_NILPADDING;\n}\n\n/*************************************************************************\n * trio_get_quote / trio_set_quote [public]\n */\n# if TRIO_FEATURE_QUOTE\nint\ntrio_get_quote\nTRIO_ARGS1((ref),\n\t   trio_pointer_t ref)\n{\n  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_QUOTE)\n    ? TRUE\n    : FALSE;\n}\n\nvoid\ntrio_set_quote\nTRIO_ARGS2((ref, is_quote),\n\t   trio_pointer_t ref,\n\t   int is_quote)\n{\n  if (is_quote)\n    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_QUOTE;\n  else\n    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_QUOTE;\n}\n#endif /* TRIO_FEATURE_QUOTE */\n\n/*************************************************************************\n * trio_get_upper / trio_set_upper [public]\n */\nint\ntrio_get_upper\nTRIO_ARGS1((ref),\n\t   trio_pointer_t ref)\n{\n  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_UPPER)\n    ? TRUE\n    : FALSE;\n}\n\nvoid\ntrio_set_upper\nTRIO_ARGS2((ref, is_upper),\n\t   trio_pointer_t ref,\n\t   int is_upper)\n{\n  if (is_upper)\n    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_UPPER;\n  else\n    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_UPPER;\n}\n\n/*************************************************************************\n * trio_get_largest / trio_set_largest [public]\n */\n#if TRIO_FEATURE_INTMAX_T\nint\ntrio_get_largest\nTRIO_ARGS1((ref),\n\t   trio_pointer_t ref)\n{\n  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_INTMAX_T)\n    ? TRUE\n    : FALSE;\n}\n\nvoid\ntrio_set_largest\nTRIO_ARGS2((ref, is_largest),\n\t   trio_pointer_t ref,\n\t   int is_largest)\n{\n  if (is_largest)\n    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_INTMAX_T;\n  else\n    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_INTMAX_T;\n}\n#endif /* TRIO_FEATURE_INTMAX_T */\n\n/*************************************************************************\n * trio_get_ptrdiff / trio_set_ptrdiff [public]\n */\n#if TRIO_FEATURE_PTRDIFF_T\nint\ntrio_get_ptrdiff\nTRIO_ARGS1((ref),\n\t   trio_pointer_t ref)\n{\n  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_PTRDIFF_T)\n    ? TRUE\n    : FALSE;\n}\n\nvoid\ntrio_set_ptrdiff\nTRIO_ARGS2((ref, is_ptrdiff),\n\t   trio_pointer_t ref,\n\t   int is_ptrdiff)\n{\n  if (is_ptrdiff)\n    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_PTRDIFF_T;\n  else\n    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_PTRDIFF_T;\n}\n#endif /* TRIO_FEATURE_PTRDIFF_T */\n\n/*************************************************************************\n * trio_get_size / trio_set_size [public]\n */\n#if TRIO_FEATURE_SIZE_T\nint\ntrio_get_size\nTRIO_ARGS1((ref),\n\t   trio_pointer_t ref)\n{\n  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SIZE_T)\n    ? TRUE\n    : FALSE;\n}\n\nvoid\ntrio_set_size\nTRIO_ARGS2((ref, is_size),\n\t   trio_pointer_t ref,\n\t   int is_size)\n{\n  if (is_size)\n    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SIZE_T;\n  else\n    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SIZE_T;\n}\n#endif /* TRIO_FEATURE_SIZE_T */\n\n/*************************************************************************\n * trio_print_int [public]\n */\nvoid\ntrio_print_int\nTRIO_ARGS2((ref, number),\n\t   trio_pointer_t ref,\n\t   int number)\n{\n  trio_reference_t *self = (trio_reference_t *)ref;\n\n  TrioWriteNumber(self->data,\n\t\t  (trio_uintmax_t)number,\n\t\t  self->parameter->flags,\n\t\t  self->parameter->width,\n\t\t  self->parameter->precision,\n\t\t  self->parameter->base);\n}\n\n/*************************************************************************\n * trio_print_uint [public]\n */\nvoid\ntrio_print_uint\nTRIO_ARGS2((ref, number),\n\t   trio_pointer_t ref,\n\t   unsigned int number)\n{\n  trio_reference_t *self = (trio_reference_t *)ref;\n\n  TrioWriteNumber(self->data,\n\t\t  (trio_uintmax_t)number,\n\t\t  self->parameter->flags | FLAGS_UNSIGNED,\n\t\t  self->parameter->width,\n\t\t  self->parameter->precision,\n\t\t  self->parameter->base);\n}\n\n/*************************************************************************\n * trio_print_double [public]\n */\n#if TRIO_FEATURE_FLOAT\nvoid\ntrio_print_double\nTRIO_ARGS2((ref, number),\n\t   trio_pointer_t ref,\n\t   double number)\n{\n  trio_reference_t *self = (trio_reference_t *)ref;\n\n  TrioWriteDouble(self->data,\n\t\t  number,\n\t\t  self->parameter->flags,\n\t\t  self->parameter->width,\n\t\t  self->parameter->precision,\n\t\t  self->parameter->base);\n}\n#endif /* TRIO_FEATURE_FLOAT */\n\n/*************************************************************************\n * trio_print_string [public]\n */\nvoid\ntrio_print_string\nTRIO_ARGS2((ref, string),\n\t   trio_pointer_t ref,\n\t   char *string)\n{\n  trio_reference_t *self = (trio_reference_t *)ref;\n\n  TrioWriteString(self->data,\n\t\t  string,\n\t\t  self->parameter->flags,\n\t\t  self->parameter->width,\n\t\t  self->parameter->precision);\n}\n\n/*************************************************************************\n * trio_print_ref [public]\n */\nint\ntrio_print_ref\nTRIO_VARGS3((ref, format, va_alist),\n\t    trio_pointer_t ref,\n\t    TRIO_CONST char *format,\n\t    TRIO_VA_DECL)\n{\n  int status;\n  va_list arglist;\n\n  assert(VALID(format));\n  \n  TRIO_VA_START(arglist, format);\n  status = TrioFormatRef((trio_reference_t *)ref, format, arglist, NULL);\n  TRIO_VA_END(arglist);\n  return status;\n}\n\n/*************************************************************************\n * trio_vprint_ref [public]\n */\nint\ntrio_vprint_ref\nTRIO_ARGS3((ref, format, arglist),\n\t   trio_pointer_t ref,\n\t   TRIO_CONST char *format,\n\t   va_list arglist)\n{\n  assert(VALID(format));\n  \n  return TrioFormatRef((trio_reference_t *)ref, format, arglist, NULL);\n}\n\n/*************************************************************************\n * trio_printv_ref [public]\n */\nint\ntrio_printv_ref\nTRIO_ARGS3((ref, format, argarray),\n\t   trio_pointer_t ref,\n\t   TRIO_CONST char *format,\n\t   trio_pointer_t *argarray)\n{\n  static va_list unused;\n  \n  assert(VALID(format));\n  \n  return TrioFormatRef((trio_reference_t *)ref, format, unused, argarray);\n}\n\n#endif\n\n/*************************************************************************\n * trio_print_pointer [public]\n */\nvoid\ntrio_print_pointer\nTRIO_ARGS2((ref, pointer),\n\t   trio_pointer_t ref,\n\t   trio_pointer_t pointer)\n{\n  trio_reference_t *self = (trio_reference_t *)ref;\n  trio_flags_t flags;\n  trio_uintmax_t number;\n\n  if (NULL == pointer)\n    {\n      TRIO_CONST char *string = internalNullString;\n      while (*string)\n\tself->data->OutStream(self->data, *string++);\n    }\n  else\n    {\n      /*\n       * The subtraction of the null pointer is a workaround\n       * to avoid a compiler warning. The performance overhead\n       * is negligible (and likely to be removed by an\n       * optimizing compiler). The (char *) casting is done\n       * to please ANSI C++.\n       */\n      number = (trio_uintmax_t)((char *)pointer - (char *)0);\n      /* Shrink to size of pointer */\n      number &= (trio_uintmax_t)-1;\n      flags = self->parameter->flags;\n      flags |= (FLAGS_UNSIGNED | FLAGS_ALTERNATIVE |\n\t        FLAGS_NILPADDING);\n      TrioWriteNumber(self->data,\n\t\t      number,\n\t\t      flags,\n\t\t      POINTER_WIDTH,\n\t\t      NO_PRECISION,\n\t\t      BASE_HEX);\n    }\n}\n\n/** @} End of UserDefined documentation module */\n\n/*************************************************************************\n *\n * LOCALES\n *\n ************************************************************************/\n\n/*************************************************************************\n * trio_locale_set_decimal_point\n *\n * Decimal point can only be one character. The input argument is a\n * string to enable multibyte characters. At most MB_LEN_MAX characters\n * will be used.\n */\n#if TRIO_FEATURE_LOCALE\nTRIO_PUBLIC void\ntrio_locale_set_decimal_point\nTRIO_ARGS1((decimalPoint),\n\t   char *decimalPoint)\n{\n#if defined(USE_LOCALE)\n  if (NULL == internalLocaleValues)\n    {\n      TrioSetLocale();\n    }\n#endif\n  internalDecimalPointLength = trio_length(decimalPoint);\n  if (internalDecimalPointLength == 1)\n    {\n      internalDecimalPoint = *decimalPoint;\n    }\n  else\n    {\n      internalDecimalPoint = NIL;\n      trio_copy_max(internalDecimalPointString,\n\t\t    sizeof(internalDecimalPointString),\n\t\t    decimalPoint);\n    }\n}\n#endif\n\n/*************************************************************************\n * trio_locale_set_thousand_separator\n *\n * See trio_locale_set_decimal_point\n */\n#if TRIO_FEATURE_LOCALE || TRIO_EXTENSION\nTRIO_PUBLIC void\ntrio_locale_set_thousand_separator\nTRIO_ARGS1((thousandSeparator),\n\t   char *thousandSeparator)\n{\n# if defined(USE_LOCALE)\n  if (NULL == internalLocaleValues)\n    {\n      TrioSetLocale();\n    }\n# endif\n  trio_copy_max(internalThousandSeparator,\n\t\tsizeof(internalThousandSeparator),\n\t\tthousandSeparator);\n  internalThousandSeparatorLength = trio_length(internalThousandSeparator);\n}\n#endif\n\n/*************************************************************************\n * trio_locale_set_grouping\n *\n * Array of bytes. Reversed order.\n *\n *  CHAR_MAX : No further grouping\n *  0        : Repeat last group for the remaining digits (not necessary\n *             as C strings are zero-terminated)\n *  n        : Set current group to n\n *\n * Same order as the grouping attribute in LC_NUMERIC.\n */\n#if TRIO_FEATURE_LOCALE || TRIO_EXTENSION\nTRIO_PUBLIC void\ntrio_locale_set_grouping\nTRIO_ARGS1((grouping),\n\t   char *grouping)\n{\n# if defined(USE_LOCALE)\n  if (NULL == internalLocaleValues)\n    {\n      TrioSetLocale();\n    }\n# endif\n  trio_copy_max(internalGrouping,\n\t\tsizeof(internalGrouping),\n\t\tgrouping);\n}\n#endif\n\n\n/*************************************************************************\n *\n * SCANNING\n *\n ************************************************************************/\n\n#if TRIO_FEATURE_SCANF\n\n/*************************************************************************\n * TrioSkipWhitespaces\n */\nTRIO_PRIVATE int\nTrioSkipWhitespaces\nTRIO_ARGS1((self),\n\t   trio_class_t *self)\n{\n  int ch;\n\n  ch = self->current;\n  while (isspace(ch))\n    {\n      self->InStream(self, &ch);\n    }\n  return ch;\n}\n\n/*************************************************************************\n * TrioGetCollation\n */\n#if TRIO_EXTENSION\nTRIO_PRIVATE void\nTrioGetCollation(TRIO_NOARGS)\n{\n  int i;\n  int j;\n  int k;\n  char first[2];\n  char second[2];\n\n  /* This is computationally expensive */\n  first[1] = NIL;\n  second[1] = NIL;\n  for (i = 0; i < MAX_CHARACTER_CLASS; i++)\n    {\n      k = 0;\n      first[0] = (char)i;\n      for (j = 0; j < MAX_CHARACTER_CLASS; j++)\n\t{\n\t  second[0] = (char)j;\n\t  if (trio_equal_locale(first, second))\n\t    internalCollationArray[i][k++] = (char)j;\n\t}\n      internalCollationArray[i][k] = NIL;\n    }\n}\n#endif\n\n/*************************************************************************\n * TrioGetCharacterClass\n *\n * FIXME:\n *  multibyte\n */\nTRIO_PRIVATE int\nTrioGetCharacterClass\nTRIO_ARGS4((format, offsetPointer, flagsPointer, characterclass),\n\t   TRIO_CONST char *format,\n\t   int *offsetPointer,\n\t   trio_flags_t *flagsPointer,\n\t   int *characterclass)\n{\n  int offset = *offsetPointer;\n  int i;\n  char ch;\n  char range_begin;\n  char range_end;\n\n  *flagsPointer &= ~FLAGS_EXCLUDE;\n\n  if (format[offset] == QUALIFIER_CIRCUMFLEX)\n    {\n      *flagsPointer |= FLAGS_EXCLUDE;\n      offset++;\n    }\n  /*\n   * If the ungroup character is at the beginning of the scanlist,\n   * it will be part of the class, and a second ungroup character\n   * must follow to end the group.\n   */\n  if (format[offset] == SPECIFIER_UNGROUP)\n    {\n      characterclass[(int)SPECIFIER_UNGROUP]++;\n      offset++;\n    }\n  /*\n   * Minus is used to specify ranges. To include minus in the class,\n   * it must be at the beginning of the list\n   */\n  if (format[offset] == QUALIFIER_MINUS)\n    {\n      characterclass[(int)QUALIFIER_MINUS]++;\n      offset++;\n    }\n  /* Collect characters */\n  for (ch = format[offset];\n       (ch != SPECIFIER_UNGROUP) && (ch != NIL);\n       ch = format[++offset])\n    {\n      switch (ch)\n\t{\n\tcase QUALIFIER_MINUS: /* Scanlist ranges */\n\t  \n\t  /*\n\t   * Both C99 and UNIX98 describes ranges as implementation-\n\t   * defined.\n\t   *\n\t   * We support the following behaviour (although this may\n\t   * change as we become wiser)\n\t   * - only increasing ranges, ie. [a-b] but not [b-a]\n\t   * - transitive ranges, ie. [a-b-c] == [a-c]\n\t   * - trailing minus, ie. [a-] is interpreted as an 'a'\n\t   *   and a '-'\n\t   * - duplicates (although we can easily convert these\n\t   *   into errors)\n\t   */\n\t  range_begin = format[offset - 1];\n\t  range_end = format[++offset];\n\t  if (range_end == SPECIFIER_UNGROUP)\n\t    {\n\t      /* Trailing minus is included */\n\t      characterclass[(int)ch]++;\n\t      ch = range_end;\n\t      break; /* for */\n\t    }\n\t  if (range_end == NIL)\n\t    return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);\n\t  if (range_begin > range_end)\n\t    return TRIO_ERROR_RETURN(TRIO_ERANGE, offset);\n\t    \n\t  for (i = (int)range_begin; i <= (int)range_end; i++)\n\t    characterclass[i]++;\n\t    \n\t  ch = range_end;\n\t  break;\n\t  \n#if TRIO_EXTENSION\n\n\tcase SPECIFIER_GROUP:\n\t  \n\t  switch (format[offset + 1])\n\t    {\n\t    case QUALIFIER_DOT: /* Collating symbol */\n\t      /*\n\t       * FIXME: This will be easier to implement when multibyte\n\t       * characters have been implemented. Until now, we ignore\n\t       * this feature.\n\t       */\n\t      for (i = offset + 2; ; i++)\n\t\t{\n\t\t  if (format[i] == NIL)\n\t\t    /* Error in syntax */\n\t\t    return -1;\n\t\t  else if (format[i] == QUALIFIER_DOT)\n\t\t    break; /* for */\n\t\t}\n\t      if (format[++i] != SPECIFIER_UNGROUP)\n\t\treturn -1;\n\t      \n\t      offset = i;\n\t      break;\n\t  \n\t    case QUALIFIER_EQUAL: /* Equivalence class expressions */\n\t      {\n\t\tunsigned int j;\n\t\tunsigned int k;\n\t    \n\t\tif (internalCollationUnconverted)\n\t\t  {\n\t\t    /* Lazy evaluation of collation array */\n\t\t    TrioGetCollation();\n\t\t    internalCollationUnconverted = FALSE;\n\t\t  }\n\t\tfor (i = offset + 2; ; i++)\n\t\t  {\n\t\t    if (format[i] == NIL)\n\t\t      /* Error in syntax */\n\t\t      return -1;\n\t\t    else if (format[i] == QUALIFIER_EQUAL)\n\t\t      break; /* for */\n\t\t    else\n\t\t      {\n\t\t\t/* Mark any equivalent character */\n\t\t\tk = (unsigned int)format[i];\n\t\t\tfor (j = 0; internalCollationArray[k][j] != NIL; j++)\n\t\t\t  characterclass[(int)internalCollationArray[k][j]]++;\n\t\t      }\n\t\t  }\n\t\tif (format[++i] != SPECIFIER_UNGROUP)\n\t\t  return -1;\n\t\t\n\t\toffset = i;\n\t      }\n\t      break;\n\t  \n\t    case QUALIFIER_COLON: /* Character class expressions */\n\t  \n\t      if (trio_equal_max(CLASS_ALNUM, sizeof(CLASS_ALNUM) - 1,\n\t\t\t\t &format[offset]))\n\t\t{\n\t\t  for (i = 0; i < MAX_CHARACTER_CLASS; i++)\n\t\t    if (isalnum(i))\n\t\t      characterclass[i]++;\n\t\t  offset += sizeof(CLASS_ALNUM) - 1;\n\t\t}\n\t      else if (trio_equal_max(CLASS_ALPHA, sizeof(CLASS_ALPHA) - 1,\n\t\t\t\t      &format[offset]))\n\t\t{\n\t\t  for (i = 0; i < MAX_CHARACTER_CLASS; i++)\n\t\t    if (isalpha(i))\n\t\t      characterclass[i]++;\n\t\t  offset += sizeof(CLASS_ALPHA) - 1;\n\t\t}\n\t      else if (trio_equal_max(CLASS_CNTRL, sizeof(CLASS_CNTRL) - 1,\n\t\t\t\t      &format[offset]))\n\t\t{\n\t\t  for (i = 0; i < MAX_CHARACTER_CLASS; i++)\n\t\t    if (iscntrl(i))\n\t\t      characterclass[i]++;\n\t\t  offset += sizeof(CLASS_CNTRL) - 1;\n\t\t}\n\t      else if (trio_equal_max(CLASS_DIGIT, sizeof(CLASS_DIGIT) - 1,\n\t\t\t\t      &format[offset]))\n\t\t{\n\t\t  for (i = 0; i < MAX_CHARACTER_CLASS; i++)\n\t\t    if (isdigit(i))\n\t\t      characterclass[i]++;\n\t\t  offset += sizeof(CLASS_DIGIT) - 1;\n\t\t}\n\t      else if (trio_equal_max(CLASS_GRAPH, sizeof(CLASS_GRAPH) - 1,\n\t\t\t\t      &format[offset]))\n\t\t{\n\t\t  for (i = 0; i < MAX_CHARACTER_CLASS; i++)\n\t\t    if (isgraph(i))\n\t\t      characterclass[i]++;\n\t\t  offset += sizeof(CLASS_GRAPH) - 1;\n\t\t}\n\t      else if (trio_equal_max(CLASS_LOWER, sizeof(CLASS_LOWER) - 1,\n\t\t\t\t      &format[offset]))\n\t\t{\n\t\t  for (i = 0; i < MAX_CHARACTER_CLASS; i++)\n\t\t    if (islower(i))\n\t\t      characterclass[i]++;\n\t\t  offset += sizeof(CLASS_LOWER) - 1;\n\t\t}\n\t      else if (trio_equal_max(CLASS_PRINT, sizeof(CLASS_PRINT) - 1,\n\t\t\t\t      &format[offset]))\n\t\t{\n\t\t  for (i = 0; i < MAX_CHARACTER_CLASS; i++)\n\t\t    if (isprint(i))\n\t\t      characterclass[i]++;\n\t\t  offset += sizeof(CLASS_PRINT) - 1;\n\t\t}\n\t      else if (trio_equal_max(CLASS_PUNCT, sizeof(CLASS_PUNCT) - 1,\n\t\t\t\t      &format[offset]))\n\t\t{\n\t\t  for (i = 0; i < MAX_CHARACTER_CLASS; i++)\n\t\t    if (ispunct(i))\n\t\t      characterclass[i]++;\n\t\t  offset += sizeof(CLASS_PUNCT) - 1;\n\t\t}\n\t      else if (trio_equal_max(CLASS_SPACE, sizeof(CLASS_SPACE) - 1,\n\t\t\t\t      &format[offset]))\n\t\t{\n\t\t  for (i = 0; i < MAX_CHARACTER_CLASS; i++)\n\t\t    if (isspace(i))\n\t\t      characterclass[i]++;\n\t\t  offset += sizeof(CLASS_SPACE) - 1;\n\t\t}\n\t      else if (trio_equal_max(CLASS_UPPER, sizeof(CLASS_UPPER) - 1,\n\t\t\t\t      &format[offset]))\n\t\t{\n\t\t  for (i = 0; i < MAX_CHARACTER_CLASS; i++)\n\t\t    if (isupper(i))\n\t\t      characterclass[i]++;\n\t\t  offset += sizeof(CLASS_UPPER) - 1;\n\t\t}\n\t      else if (trio_equal_max(CLASS_XDIGIT, sizeof(CLASS_XDIGIT) - 1,\n\t\t\t\t      &format[offset]))\n\t\t{\n\t\t  for (i = 0; i < MAX_CHARACTER_CLASS; i++)\n\t\t    if (isxdigit(i))\n\t\t      characterclass[i]++;\n\t\t  offset += sizeof(CLASS_XDIGIT) - 1;\n\t\t}\n\t      else\n\t\t{\n\t\t  characterclass[(int)ch]++;\n\t\t}\n\t      break;\n\n\t    default:\n\t      characterclass[(int)ch]++;\n\t      break;\n\t    }\n\t  break;\n\t  \n#endif /* TRIO_EXTENSION */\n\t  \n\tdefault:\n\t  characterclass[(int)ch]++;\n\t  break;\n\t}\n    }\n  return 0;\n}\n\n/*************************************************************************\n * TrioReadNumber\n *\n * We implement our own number conversion in preference of strtol and\n * strtoul, because we must handle 'long long' and thousand separators.\n */\nTRIO_PRIVATE BOOLEAN_T\nTrioReadNumber\nTRIO_ARGS5((self, target, flags, width, base),\n\t   trio_class_t *self,\n\t   trio_uintmax_t *target,\n\t   trio_flags_t flags,\n\t   int width,\n\t   int base)\n{\n  trio_uintmax_t number = 0;\n  int digit;\n  int count;\n  BOOLEAN_T isNegative = FALSE;\n  BOOLEAN_T gotNumber = FALSE;\n  int j;\n\n  assert(VALID(self));\n  assert(VALID(self->InStream));\n  assert((base >= MIN_BASE && base <= MAX_BASE) || (base == NO_BASE));\n\n  if (internalDigitsUnconverted)\n    {\n      /* Lazy evaluation of digits array */\n      memset(internalDigitArray, -1, sizeof(internalDigitArray));\n      for (j = 0; j < (int)sizeof(internalDigitsLower) - 1; j++)\n\t{\n\t  internalDigitArray[(int)internalDigitsLower[j]] = j;\n\t  internalDigitArray[(int)internalDigitsUpper[j]] = j;\n\t}\n      internalDigitsUnconverted = FALSE;\n    }\n  \n  TrioSkipWhitespaces(self);\n  \n  if (!(flags & FLAGS_UNSIGNED))\n    {\n      /* Leading sign */\n      if (self->current == '+')\n\t{\n\t  self->InStream(self, NULL);\n\t}\n      else if (self->current == '-')\n\t{\n\t  self->InStream(self, NULL);\n\t  isNegative = TRUE;\n\t}\n    }\n  \n  count = self->processed;\n  \n  if (flags & FLAGS_ALTERNATIVE)\n    {\n      switch (base)\n\t{\n\tcase NO_BASE:\n\tcase BASE_OCTAL:\n\tcase BASE_HEX:\n\tcase BASE_BINARY:\n\t  if (self->current == '0')\n\t    {\n\t      self->InStream(self, NULL);\n\t      if (self->current)\n\t\t{\n\t\t  if ((base == BASE_HEX) &&\n\t\t      (trio_to_upper(self->current) == 'X'))\n\t\t    {\n\t\t      self->InStream(self, NULL);\n\t\t    }\n\t\t  else if ((base == BASE_BINARY) &&\n\t\t\t   (trio_to_upper(self->current) == 'B'))\n\t\t    {\n\t\t      self->InStream(self, NULL);\n\t\t    }\n\t\t}\n\t    }\n\t  else\n\t    return FALSE;\n\t  break;\n\tdefault:\n\t  break;\n\t}\n    }\n\n  while (((width == NO_WIDTH) || (self->processed - count < width)) &&\n\t (! ((self->current == EOF) || isspace(self->current))))\n    {\n      if (isascii(self->current))\n\t{\n\t  digit = internalDigitArray[self->current];\n\t  /* Abort if digit is not allowed in the specified base */\n\t  if ((digit == -1) || (digit >= base))\n\t    break;\n\t}\n#if TRIO_FEATURE_QUOTE\n      else if (flags & FLAGS_QUOTE)\n\t{\n\t  /* Compare with thousands separator */\n\t  for (j = 0; internalThousandSeparator[j] && self->current; j++)\n\t    {\n\t      if (internalThousandSeparator[j] != self->current)\n\t\tbreak;\n\n\t      self->InStream(self, NULL);\n\t    }\n\t  if (internalThousandSeparator[j])\n\t    break; /* Mismatch */\n\t  else\n\t    continue; /* Match */\n\t}\n#endif\n      else\n\tbreak;\n            \n      number *= base;\n      number += digit;\n      gotNumber = TRUE; /* we need at least one digit */\n\n      self->InStream(self, NULL);\n    }\n\n  /* Was anything read at all? */\n  if (!gotNumber)\n    return FALSE;\n  \n  if (target)\n    *target = (isNegative) ? (trio_uintmax_t)(-((trio_intmax_t)number)) : number;\n  return TRUE;\n}\n\n/*************************************************************************\n * TrioReadChar\n */\nTRIO_PRIVATE int\nTrioReadChar\nTRIO_ARGS4((self, target, flags, width),\n\t   trio_class_t *self,\n\t   char *target,\n\t   trio_flags_t flags,\n\t   int width)\n{\n  int i;\n  char ch;\n  trio_uintmax_t number;\n  \n  assert(VALID(self));\n  assert(VALID(self->InStream));\n\n  for (i = 0;\n       (self->current != EOF) && (i < width);\n       i++)\n    {\n      ch = (char)self->current;\n      self->InStream(self, NULL);\n      if ((flags & FLAGS_ALTERNATIVE) && (ch == CHAR_BACKSLASH))\n\t{\n\t  switch (self->current)\n\t    {\n\t    case '\\\\': ch = '\\\\'; break;\n\t    case 'a': ch = '\\007'; break;\n\t    case 'b': ch = '\\b'; break;\n\t    case 'f': ch = '\\f'; break;\n\t    case 'n': ch = '\\n'; break;\n\t    case 'r': ch = '\\r'; break;\n\t    case 't': ch = '\\t'; break;\n\t    case 'v': ch = '\\v'; break;\n\t    default:\n\t      if (isdigit(self->current))\n\t\t{\n\t\t  /* Read octal number */\n\t\t  if (!TrioReadNumber(self, &number, 0, 3, BASE_OCTAL))\n\t\t    return 0;\n\t\t  ch = (char)number;\n\t\t}\n\t      else if (trio_to_upper(self->current) == 'X')\n\t\t{\n\t\t  /* Read hexadecimal number */\n\t\t  self->InStream(self, NULL);\n\t\t  if (!TrioReadNumber(self, &number, 0, 2, BASE_HEX))\n\t\t    return 0;\n\t\t  ch = (char)number;\n\t\t}\n\t      else\n\t\t{\n\t\t  ch = (char)self->current;\n\t\t}\n\t      break;\n\t    }\n\t}\n      \n      if (target)\n\ttarget[i] = ch;\n    }\n  return i + 1;\n}\n\n/*************************************************************************\n * TrioReadString\n */\nTRIO_PRIVATE BOOLEAN_T\nTrioReadString\nTRIO_ARGS4((self, target, flags, width),\n\t   trio_class_t *self,\n\t   char *target,\n\t   trio_flags_t flags,\n\t   int width)\n{\n  int i;\n  \n  assert(VALID(self));\n  assert(VALID(self->InStream));\n\n  TrioSkipWhitespaces(self);\n    \n  /*\n   * Continue until end of string is reached, a whitespace is encountered,\n   * or width is exceeded\n   */\n  for (i = 0;\n       ((width == NO_WIDTH) || (i < width)) &&\n       (! ((self->current == EOF) || isspace(self->current)));\n       i++)\n    {\n      if (TrioReadChar(self, (target ? &target[i] : 0), flags, 1) == 0)\n\tbreak; /* for */\n    }\n  if (target)\n    target[i] = NIL;\n  return TRUE;\n}\n\n/*************************************************************************\n * TrioReadWideChar\n */\n#if TRIO_FEATURE_WIDECHAR\nTRIO_PRIVATE int\nTrioReadWideChar\nTRIO_ARGS4((self, target, flags, width),\n\t   trio_class_t *self,\n\t   trio_wchar_t *target,\n\t   trio_flags_t flags,\n\t   int width)\n{\n  int i;\n  int j;\n  int size;\n  int amount = 0;\n  trio_wchar_t wch;\n  char buffer[MB_LEN_MAX + 1];\n  \n  assert(VALID(self));\n  assert(VALID(self->InStream));\n\n  for (i = 0;\n       (self->current != EOF) && (i < width);\n       i++)\n    {\n      if (isascii(self->current))\n\t{\n\t  if (TrioReadChar(self, buffer, flags, 1) == 0)\n\t    return 0;\n\t  buffer[1] = NIL;\n\t}\n      else\n\t{\n\t  /*\n\t   * Collect a multibyte character, by enlarging buffer until\n\t   * it contains a fully legal multibyte character, or the\n\t   * buffer is full.\n\t   */\n\t  j = 0;\n\t  do\n\t    {\n\t      buffer[j++] = (char)self->current;\n\t      buffer[j] = NIL;\n\t      self->InStream(self, NULL);\n\t    }\n\t  while ((j < (int)sizeof(buffer)) && (mblen(buffer, (size_t)j) != j));\n\t}\n      if (target)\n\t{\n\t  size = mbtowc(&wch, buffer, sizeof(buffer));\n\t  if (size > 0)\n\t    target[i] = wch;\n\t}\n      amount += size;\n      self->InStream(self, NULL);\n    }\n  return amount;\n}\n#endif /* TRIO_FEATURE_WIDECHAR */\n\n/*************************************************************************\n * TrioReadWideString\n */\n#if TRIO_FEATURE_WIDECHAR\nTRIO_PRIVATE BOOLEAN_T\nTrioReadWideString\nTRIO_ARGS4((self, target, flags, width),\n\t   trio_class_t *self,\n\t   trio_wchar_t *target,\n\t   trio_flags_t flags,\n\t   int width)\n{\n  int i;\n  int size;\n  \n  assert(VALID(self));\n  assert(VALID(self->InStream));\n\n  TrioSkipWhitespaces(self);\n\n#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)\n  /* Required by TrioReadWideChar */\n  (void)mblen(NULL, 0);\n#endif\n  \n  /*\n   * Continue until end of string is reached, a whitespace is encountered,\n   * or width is exceeded\n   */\n  for (i = 0;\n       ((width == NO_WIDTH) || (i < width)) &&\n       (! ((self->current == EOF) || isspace(self->current)));\n       )\n    {\n      size = TrioReadWideChar(self, &target[i], flags, 1);\n      if (size == 0)\n\tbreak; /* for */\n\n      i += size;\n    }\n  if (target)\n    target[i] = WCONST('\\0');\n  return TRUE;\n}\n#endif /* TRIO_FEATURE_WIDECHAR */\n\n/*************************************************************************\n * TrioReadGroup\n *\n * FIXME: characterclass does not work with multibyte characters\n */\nTRIO_PRIVATE BOOLEAN_T\nTrioReadGroup\nTRIO_ARGS5((self, target, characterclass, flags, width),\n\t   trio_class_t *self,\n\t   char *target,\n\t   int *characterclass,\n\t   trio_flags_t flags,\n\t   int width)\n{\n  int ch;\n  int i;\n  \n  assert(VALID(self));\n  assert(VALID(self->InStream));\n\n  ch = self->current;\n  for (i = 0;\n       ((width == NO_WIDTH) || (i < width)) &&\n       (! ((ch == EOF) ||\n\t   (((flags & FLAGS_EXCLUDE) != 0) ^ (characterclass[ch] == 0))));\n       i++)\n    {\n      if (target)\n\ttarget[i] = (char)ch;\n      self->InStream(self, &ch);\n    }\n  \n  if (target)\n    target[i] = NIL;\n  return TRUE;\n}\n\n/*************************************************************************\n * TrioReadDouble\n *\n * FIXME:\n *  add long double\n *  handle base\n */\n#if TRIO_FEATURE_FLOAT\nTRIO_PRIVATE BOOLEAN_T\nTrioReadDouble\nTRIO_ARGS4((self, target, flags, width),\n\t   trio_class_t *self,\n\t   trio_pointer_t target,\n\t   trio_flags_t flags,\n\t   int width)\n{\n  int ch;\n  char doubleString[512];\n  int offset = 0;\n  int start;\n# if TRIO_FEATURE_QUOTE\n  int j;\n# endif\n  BOOLEAN_T isHex = FALSE;\n  trio_long_double_t infinity;\n\n  doubleString[0] = 0;\n  \n  if ((width == NO_WIDTH) || (width > (int)sizeof(doubleString) - 1))\n    width = sizeof(doubleString) - 1;\n  \n  TrioSkipWhitespaces(self);\n  \n  /*\n   * Read entire double number from stream. trio_to_double requires\n   * a string as input, but InStream can be anything, so we have to\n   * collect all characters.\n   */\n  ch = self->current;\n  if ((ch == '+') || (ch == '-'))\n    {\n      doubleString[offset++] = (char)ch;\n      self->InStream(self, &ch);\n      width--;\n    }\n\n  start = offset;\n  switch (ch)\n    {\n    case 'n':\n    case 'N':\n      /* Not-a-number */\n      if (offset != 0)\n\tbreak;\n      /* FALLTHROUGH */\n    case 'i':\n    case 'I':\n      /* Infinity */\n      while (isalpha(ch) && (offset - start < width))\n\t{\n\t  doubleString[offset++] = (char)ch;\n\t  self->InStream(self, &ch);\n\t}\n      doubleString[offset] = NIL;\n\n      /* Case insensitive string comparison */\n      if (trio_equal(&doubleString[start], INFINITE_UPPER) ||\n\t  trio_equal(&doubleString[start], LONG_INFINITE_UPPER))\n\t{\n\t  infinity = ((start == 1) && (doubleString[0] == '-'))\n\t    ? trio_ninf()\n\t    : trio_pinf();\n\t  if (flags & FLAGS_LONGDOUBLE)\n\t    {\n\t      *((trio_long_double_t *)target) = infinity;\n\t    }\n\t  else if (flags & FLAGS_LONG)\n\t    {\n\t      *((double *)target) = infinity;\n\t    }\n\t  else\n\t    {\n\t      *((float *)target) = infinity;\n\t    }\n\t  return TRUE;\n\t}\n      if (trio_equal(doubleString, NAN_UPPER))\n\t{\n\t  /* NaN must not have a preceeding + nor - */\n\t  if (flags & FLAGS_LONGDOUBLE)\n\t    {\n\t      *((trio_long_double_t *)target) = trio_nan();\n\t    }\n\t  else if (flags & FLAGS_LONG)\n\t    {\n\t      *((double *)target) = trio_nan();\n\t    }\n\t  else\n\t    {\n\t      *((float *)target) = trio_nan();\n\t    }\n\t  return TRUE;\n\t}\n      return FALSE;\n\n    case '0':\n      doubleString[offset++] = (char)ch;\n      self->InStream(self, &ch);\n      if (trio_to_upper(ch) == 'X')\n\t{\n\t  isHex = TRUE;\n\t  doubleString[offset++] = (char)ch;\n\t  self->InStream(self, &ch);\n\t}\n      break;\n      \n    default:\n      break;\n    }\n  \n  while ((ch != EOF) && (offset - start < width))\n    {\n      /* Integer part */\n      if (isHex ? isxdigit(ch) : isdigit(ch))\n\t{\n\t  doubleString[offset++] = (char)ch;\n\t  self->InStream(self, &ch);\n\t}\n# if TRIO_FEATURE_QUOTE\n      else if (flags & FLAGS_QUOTE)\n\t{\n\t  /* Compare with thousands separator */\n\t  for (j = 0; internalThousandSeparator[j] && self->current; j++)\n\t    {\n\t      if (internalThousandSeparator[j] != self->current)\n\t\tbreak;\n\n\t      self->InStream(self, &ch);\n\t    }\n\t  if (internalThousandSeparator[j])\n\t    break; /* Mismatch */\n\t  else\n\t    continue; /* Match */\n\t}\n# endif\n      else\n\tbreak; /* while */\n    }\n  if (ch == '.')\n    {\n      /* Decimal part */\n      doubleString[offset++] = (char)ch;\n      self->InStream(self, &ch);\n      while ((isHex ? isxdigit(ch) : isdigit(ch)) &&\n\t     (offset - start < width))\n\t{\n\t  doubleString[offset++] = (char)ch;\n\t  self->InStream(self, &ch);\n\t}\n    }\n  if (isHex ? (trio_to_upper(ch) == 'P') : (trio_to_upper(ch) == 'E'))\n    {\n      /* Exponent */\n      doubleString[offset++] = (char)ch;\n      self->InStream(self, &ch);\n      if ((ch == '+') || (ch == '-'))\n\t{\n\t  doubleString[offset++] = (char)ch;\n\t  self->InStream(self, &ch);\n\t}\n      while (isdigit(ch) && (offset - start < width))\n\t{\n\t  doubleString[offset++] = (char)ch;\n\t  self->InStream(self, &ch);\n\t}\n    }\n\n  if ((offset == start) || (*doubleString == NIL))\n    return FALSE;\n\n  doubleString[offset] = 0;\n  \n  if (flags & FLAGS_LONGDOUBLE)\n    {\n      *((trio_long_double_t *)target) = trio_to_long_double(doubleString, NULL);\n    }\n  else if (flags & FLAGS_LONG)\n    {\n      *((double *)target) = trio_to_double(doubleString, NULL);\n    }\n  else\n    {\n      *((float *)target) = trio_to_float(doubleString, NULL);\n    }\n  return TRUE;\n}\n#endif /* TRIO_FEATURE_FLOAT */\n\n/*************************************************************************\n * TrioReadPointer\n */\nTRIO_PRIVATE BOOLEAN_T\nTrioReadPointer\nTRIO_ARGS3((self, target, flags),\n\t   trio_class_t *self,\n\t   trio_pointer_t *target,\n\t   trio_flags_t flags)\n{\n  trio_uintmax_t number;\n  char buffer[sizeof(internalNullString)];\n\n  flags |= (FLAGS_UNSIGNED | FLAGS_ALTERNATIVE | FLAGS_NILPADDING);\n  \n  if (TrioReadNumber(self,\n\t\t     &number,\n\t\t     flags,\n\t\t     POINTER_WIDTH,\n\t\t     BASE_HEX))\n    {\n      if (target)\n\t{\n#if defined(TRIO_COMPILER_GCC) || defined(TRIO_COMPILER_MIPSPRO)\n\t  /*\n\t   * The strange assignment of number is a workaround for a compiler\n\t   * warning\n\t   */\n\t  *target = &((char *)0)[number];\n#else\n\t  *target = (trio_pointer_t)number;\n#endif\n\t}\n      return TRUE;\n    }\n  else if (TrioReadString(self,\n\t\t\t  (flags & FLAGS_IGNORE)\n\t\t\t  ? NULL\n\t\t\t  : buffer,\n\t\t\t  0,\n\t\t\t  sizeof(internalNullString) - 1))\n    {  \n      if (trio_equal_case(buffer, internalNullString))\n\t{\n\t  if (target)\n\t    *target = NULL;\n\t  return TRUE;\n\t}\n    }\n  return FALSE;\n}\n\n/*************************************************************************\n * TrioScanProcess\n */\nTRIO_PRIVATE int\nTrioScanProcess\nTRIO_ARGS3((data, format, parameters),\n\t   trio_class_t *data,\n\t   TRIO_CONST char *format,\n\t   trio_parameter_t *parameters)\n{\n  int assignment;\n  int ch;\n  int offset; /* Offset of format string */\n  int i; /* Offset of current parameter */\n  trio_flags_t flags;\n  int width;\n  int base;\n  trio_pointer_t pointer;\n\n  assignment = 0;\n  i = 0;\n  offset = 0;\n  data->InStream(data, &ch);\n\n  for (;;)\n    {\n      /* Skip the parameter entries */\n      while (parameters[i].type == FORMAT_PARAMETER)\n\t{\n\t  assert(i <= MAX_PARAMETERS);\n\t  i++;\n\t}\n\n      /* Compare non conversion-specifier part of format string */\n      while (offset < parameters[i].beginOffset)\n\t{\n\t  if ((CHAR_IDENTIFIER == format[offset]) &&\n\t      (CHAR_IDENTIFIER == format[offset + 1]))\n\t    {\n\t      /* Two % in format matches one % in input stream */\n\t      if (CHAR_IDENTIFIER == ch)\n\t\t{\n\t\t  data->InStream(data, &ch);\n\t\t  offset += 2;\n\t\t  continue; /* while format chars left */\n\t\t}\n\t      else\n\t\treturn TRIO_ERROR_RETURN(TRIO_EINVAL, offset);\n\t    }\n\t  else /* Not an % identifier */\n\t    {\n\t      if (isspace((int)format[offset]))\n\t\t{\n\t\t  /* Whitespaces may match any amount of whitespaces */\n\t\t  ch = TrioSkipWhitespaces(data);\n\t\t}\n\t      else if (ch == format[offset])\n\t\t{\n\t\t  data->InStream(data, &ch);\n\t\t}\n\t      else\n\t\treturn assignment;\n\n\t      offset++;\n\t    }\n\t}\n\n      if (parameters[i].type == FORMAT_SENTINEL)\n\tbreak;\n\n      if ((EOF == ch) && (parameters[i].type != FORMAT_COUNT))\n\treturn (assignment > 0) ? assignment : EOF;\n\n      flags = parameters[i].flags;\n\n      /* Find width */\n      width = parameters[i].width;\n      if (flags & FLAGS_WIDTH_PARAMETER)\n\t{\n\t  /* Get width from parameter list */\n\t  width = (int)parameters[width].data.number.as_signed;\n\t}\n\n      /* Find base */\n      if (NO_BASE != parameters[i].baseSpecifier)\n\t{\n\t  /* Base from specifier has priority */\n\t  base = parameters[i].baseSpecifier;\n\t}\n      else if (flags & FLAGS_BASE_PARAMETER)\n\t{\n\t  /* Get base from parameter list */\n\t  base = parameters[i].base;\n\t  base = (int)parameters[base].data.number.as_signed;\n\t}\n      else\n\t{\n\t  /* Use base from format string */\n\t  base = parameters[i].base;\n\t}\n\n      switch (parameters[i].type)\n\t{\n\tcase FORMAT_INT:\n\t  {\n\t    trio_uintmax_t number;\n\n\t    if (0 == base)\n\t      base = BASE_DECIMAL;\n\n\t    if (!TrioReadNumber(data,\n\t\t\t\t&number,\n\t\t\t\tflags,\n\t\t\t\twidth,\n\t\t\t\tbase))\n\t      return assignment;\n\n\t    if (!(flags & FLAGS_IGNORE))\n\t      {\n\t\tassignment++;\n\n\t\tpointer = parameters[i].data.pointer;\n#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER\n\t\tif (flags & FLAGS_SIZE_T)\n\t\t  *(size_t *)pointer = (size_t)number;\n\t\telse\n#endif\n#if TRIO_FEATURE_PTRDIFF_T\n\t\tif (flags & FLAGS_PTRDIFF_T)\n\t\t  *(ptrdiff_t *)pointer = (ptrdiff_t)number;\n\t\telse\n#endif\n#if TRIO_FEATURE_INTMAX_T\n\t\tif (flags & FLAGS_INTMAX_T)\n\t\t  *(trio_intmax_t *)pointer = (trio_intmax_t)number;\n\t\telse\n#endif\n\t\tif (flags & FLAGS_QUAD)\n\t\t  *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)number;\n\t\telse if (flags & FLAGS_LONG)\n\t\t  *(long int *)pointer = (long int)number;\n\t\telse if (flags & FLAGS_SHORT)\n\t\t  *(short int *)pointer = (short int)number;\n\t\telse\n\t\t  *(int *)pointer = (int)number;\n\t      }\n\t  }\n\t  break; /* FORMAT_INT */\n\n\tcase FORMAT_STRING:\n#if TRIO_FEATURE_WIDECHAR\n\t  if (flags & FLAGS_WIDECHAR)\n\t    {\n\t      if (!TrioReadWideString(data,\n\t\t\t\t      (flags & FLAGS_IGNORE)\n\t\t\t\t      ? NULL\n\t\t\t\t      : parameters[i].data.wstring,\n\t\t\t\t      flags,\n\t\t\t\t      width))\n\t\treturn assignment;\n\t    }\n\t  else\n#endif\n\t    {\n\t      if (!TrioReadString(data,\n\t\t\t\t  (flags & FLAGS_IGNORE)\n\t\t\t\t  ? NULL\n\t\t\t\t  : parameters[i].data.string,\n\t\t\t\t  flags,\n\t\t\t\t  width))\n\t\treturn assignment;\n\t    }\n\t  if (!(flags & FLAGS_IGNORE))\n\t    assignment++;\n\t  break; /* FORMAT_STRING */\n\n#if TRIO_FEATURE_FLOAT\n\tcase FORMAT_DOUBLE:\n\t  {\n\t    if (flags & FLAGS_IGNORE)\n\t      {\n\t\tpointer = NULL;\n\t      }\n\t    else\n\t      {\n\t\tpointer = (flags & FLAGS_LONGDOUBLE)\n\t\t  ? (trio_pointer_t)parameters[i].data.longdoublePointer\n\t\t  : (trio_pointer_t)parameters[i].data.doublePointer;\n\t      }\n\t    if (!TrioReadDouble(data, pointer, flags, width))\n\t      {\n\t\treturn assignment;\n\t      }\n\t    if (!(flags & FLAGS_IGNORE))\n\t      {\n\t\tassignment++;\n\t      }\n\t    break; /* FORMAT_DOUBLE */\n\t  }\n#endif\n\n\tcase FORMAT_GROUP:\n\t  {\n\t    int characterclass[MAX_CHARACTER_CLASS + 1];\n\t    int rc;\n\n\t    /* Skip over modifiers */\n\t    while (format[offset] != SPECIFIER_GROUP)\n\t      {\n\t\toffset++;\n\t      }\n\t    /* Skip over group specifier */\n\t    offset++;\n\n\t    memset(characterclass, 0, sizeof(characterclass));\n\t    rc = TrioGetCharacterClass(format,\n\t\t\t\t       &offset,\n\t\t\t\t       &flags,\n\t\t\t\t       characterclass);\n\t    if (rc < 0)\n\t      return rc;\n\n\t    if (!TrioReadGroup(data,\n\t\t\t       (flags & FLAGS_IGNORE)\n\t\t\t       ? NULL\n\t\t\t       : parameters[i].data.string,\n\t\t\t       characterclass,\n\t\t\t       flags,\n\t\t\t       parameters[i].width))\n\t      return assignment;\n\t    if (!(flags & FLAGS_IGNORE))\n\t      assignment++;\n\t  }\n\t  break; /* FORMAT_GROUP */\n\n\tcase FORMAT_COUNT:\n\t  pointer = parameters[i].data.pointer;\n\t  if (NULL != pointer)\n\t    {\n\t      int count = data->committed;\n\t      if (ch != EOF)\n\t\tcount--; /* a character is read, but is not consumed yet */\n#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER\n\t      if (flags & FLAGS_SIZE_T)\n\t\t*(size_t *)pointer = (size_t)count;\n\t      else\n#endif\n#if TRIO_FEATURE_PTRDIFF_T\n\t      if (flags & FLAGS_PTRDIFF_T)\n\t\t*(ptrdiff_t *)pointer = (ptrdiff_t)count;\n\t      else\n#endif\n#if TRIO_FEATURE_INTMAX_T\n\t      if (flags & FLAGS_INTMAX_T)\n\t\t*(trio_intmax_t *)pointer = (trio_intmax_t)count;\n\t      else\n#endif\n\t      if (flags & FLAGS_QUAD)\n\t\t{\n\t\t  *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)count;\n\t\t}\n\t      else if (flags & FLAGS_LONG)\n\t\t{\n\t\t  *(long int *)pointer = (long int)count;\n\t\t}\n\t      else if (flags & FLAGS_SHORT)\n\t\t{\n\t\t  *(short int *)pointer = (short int)count;\n\t\t}\n\t      else\n\t\t{\n\t\t  *(int *)pointer = (int)count;\n\t\t}\n\t    }\n\t  break; /* FORMAT_COUNT */\n\n\tcase FORMAT_CHAR:\n#if TRIO_FEATURE_WIDECHAR\n\t  if (flags & FLAGS_WIDECHAR)\n\t    {\n\t      if (TrioReadWideChar(data,\n\t\t\t\t   (flags & FLAGS_IGNORE)\n\t\t\t\t   ? NULL\n\t\t\t\t   : parameters[i].data.wstring,\n\t\t\t\t   flags,\n\t\t\t\t   (width == NO_WIDTH) ? 1 : width) == 0)\n\t\treturn assignment;\n\t    }\n\t  else\n#endif\n\t    {\n\t      if (TrioReadChar(data,\n\t\t\t       (flags & FLAGS_IGNORE)\n\t\t\t       ? NULL\n\t\t\t       : parameters[i].data.string,\n\t\t\t       flags,\n\t\t\t       (width == NO_WIDTH) ? 1 : width) == 0)\n\t\treturn assignment;\n\t    }\n\t  if (!(flags & FLAGS_IGNORE))\n\t    assignment++;\n\t  break; /* FORMAT_CHAR */\n\n\tcase FORMAT_POINTER:\n\t  if (!TrioReadPointer(data,\n\t\t\t       (flags & FLAGS_IGNORE)\n\t\t\t       ? NULL\n\t\t\t       : (trio_pointer_t *)parameters[i].data.pointer,\n\t\t\t       flags))\n\t    return assignment;\n\t  if (!(flags & FLAGS_IGNORE))\n\t    assignment++;\n\t  break; /* FORMAT_POINTER */\n\n\tcase FORMAT_PARAMETER:\n\t  break; /* FORMAT_PARAMETER */\n\n\tdefault:\n\t  return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);\n\t}\n\n      ch = data->current;\n      offset = parameters[i].endOffset;\n      i++;\n    }\n  return assignment;\n}\n\n/*************************************************************************\n * TrioScan\n */\nTRIO_PRIVATE int\nTrioScan\nTRIO_ARGS6((source, sourceSize, InStream, format, arglist, argarray),\n\t   trio_pointer_t source,\n\t   size_t sourceSize,\n\t   void (*InStream) TRIO_PROTO((trio_class_t *, int *)),\n\t   TRIO_CONST char *format,\n\t   va_list arglist,\n\t   trio_pointer_t *argarray)\n{\n  int status;\n  trio_parameter_t parameters[MAX_PARAMETERS];\n  trio_class_t data;\n\n  assert(VALID(InStream));\n  assert(VALID(format));\n\n  memset(&data, 0, sizeof(data));\n  data.InStream = InStream;\n  data.location = (trio_pointer_t)source;\n  data.max = sourceSize;\n  data.error = 0;\n\n#if defined(USE_LOCALE)\n  if (NULL == internalLocaleValues)\n    {\n      TrioSetLocale();\n    }\n#endif\n  \n  status = TrioParse(TYPE_SCAN, format, parameters, arglist, argarray);\n  if (status < 0)\n    return status;\n\n  status = TrioScanProcess(&data, format, parameters);\n  if (data.error != 0)\n    {\n      status = data.error;\n    }\n  return status;\n}\n\n/*************************************************************************\n * TrioInStreamFile\n */\n#if TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO\nTRIO_PRIVATE void\nTrioInStreamFile\nTRIO_ARGS2((self, intPointer),\n\t   trio_class_t *self,\n\t   int *intPointer)\n{\n  FILE *file = (FILE *)self->location;\n\n  assert(VALID(self));\n  assert(VALID(file));\n\n  self->current = fgetc(file);\n  if (self->current == EOF)\n    {\n      self->error = (ferror(file))\n\t? TRIO_ERROR_RETURN(TRIO_ERRNO, 0)\n\t: TRIO_ERROR_RETURN(TRIO_EOF, 0);\n    }\n  else\n    {\n      self->processed++;\n      self->committed++;\n    }\n  \n  if (VALID(intPointer))\n    {\n      *intPointer = self->current;\n    }\n}\n#endif /* TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO */\n\n/*************************************************************************\n * TrioInStreamFileDescriptor\n */\n#if TRIO_FEATURE_FD\nTRIO_PRIVATE void\nTrioInStreamFileDescriptor\nTRIO_ARGS2((self, intPointer),\n\t   trio_class_t *self,\n\t   int *intPointer)\n{\n  int fd = *((int *)self->location);\n  int size;\n  unsigned char input;\n\n  assert(VALID(self));\n\n  size = read(fd, &input, sizeof(char));\n  if (size == -1)\n    {\n      self->error = TRIO_ERROR_RETURN(TRIO_ERRNO, 0);\n      self->current = EOF;\n    }\n  else\n    {\n      self->current = (size == 0) ? EOF : input;\n    }\n  if (self->current != EOF)\n    {\n      self->committed++;\n      self->processed++;\n    }\n  \n  if (VALID(intPointer))\n    {\n      *intPointer = self->current;\n    }\n}\n#endif /* TRIO_FEATURE_FD */\n\n/*************************************************************************\n * TrioInStreamCustom\n */\n#if TRIO_FEATURE_CLOSURE\nTRIO_PRIVATE void\nTrioInStreamCustom\nTRIO_ARGS2((self, intPointer),\n\t   trio_class_t *self,\n\t   int *intPointer)\n{\n  trio_custom_t *data;\n  \n  assert(VALID(self));\n  assert(VALID(self->location));\n\n  data = (trio_custom_t *)self->location;\n\n  self->current = (data->stream.in == NULL)\n    ? NIL\n    : (data->stream.in)(data->closure);\n  \n  if (self->current == NIL)\n    {\n      self->current = EOF;\n    }\n  else\n    {\n      self->processed++;\n      self->committed++;\n    }\n  \n  if (VALID(intPointer))\n    {\n      *intPointer = self->current;\n    }\n}\n#endif /* TRIO_FEATURE_CLOSURE */\n\n/*************************************************************************\n * TrioInStreamString\n */\nTRIO_PRIVATE void\nTrioInStreamString\nTRIO_ARGS2((self, intPointer),\n\t   trio_class_t *self,\n\t   int *intPointer)\n{\n  unsigned char **buffer;\n\n  assert(VALID(self));\n  assert(VALID(self->location));\n\n  buffer = (unsigned char **)self->location;\n  self->current = (*buffer)[0];\n  if (self->current == NIL)\n    {\n      self->current = EOF;\n    }\n  else\n    {\n      (*buffer)++;\n      self->processed++;\n      self->committed++;\n    }\n  \n  if (VALID(intPointer))\n    {\n      *intPointer = self->current;\n    }\n}\n\n/*************************************************************************\n *\n * Formatted scanning functions\n *\n ************************************************************************/\n\n#if defined(TRIO_DOCUMENTATION)\n# include \"doc/doc_scanf.h\"\n#endif\n/** @addtogroup Scanf\n    @{\n*/\n\n/*************************************************************************\n * scanf\n */\n\n/**\n   Scan characters from standard input stream.\n\n   @param format Formatting string.\n   @param ... Arguments.\n   @return Number of scanned characters.\n */\n#if TRIO_FEATURE_STDIO\nTRIO_PUBLIC int\nscanf\nTRIO_VARGS2((format, va_alist),\n\t    TRIO_CONST char *format,\n\t    TRIO_VA_DECL)\n{\n  int status;\n  va_list args;\n\n  assert(VALID(format));\n  \n  TRIO_VA_START(args, format);\n  status = TrioScan((trio_pointer_t)stdin, 0,\n\t\t    TrioInStreamFile,\n\t\t    format, args, NULL);\n  TRIO_VA_END(args);\n  return status;\n}\n#endif /* TRIO_FEATURE_STDIO */\n\n/**\n   Scan characters from standard input stream.\n\n   @param format Formatting string.\n   @param args Arguments.\n   @return Number of scanned characters.\n */\n#if TRIO_FEATURE_STDIO\nTRIO_PUBLIC int\nvscanf\nTRIO_ARGS2((format, args),\n\t   TRIO_CONST char *format,\n\t   va_list args)\n{\n  assert(VALID(format));\n  \n  return TrioScan((trio_pointer_t)stdin, 0,\n\t\t  TrioInStreamFile,\n\t\t  format, args, NULL);\n}\n#endif /* TRIO_FEATURE_STDIO */\n\n/**\n   Scan characters from standard input stream.\n\n   @param format Formatting string.\n   @param args Arguments.\n   @return Number of scanned characters.\n */\n#if TRIO_FEATURE_STDIO\nTRIO_PUBLIC int\ntrio_scanfv\nTRIO_ARGS2((format, args),\n\t   TRIO_CONST char *format,\n\t   trio_pointer_t *args)\n{\n  static va_list unused;\n  \n  assert(VALID(format));\n  \n  return TrioScan((trio_pointer_t)stdin, 0,\n\t\t  TrioInStreamFile,\n\t\t  format, unused, args);\n}\n#endif /* TRIO_FEATURE_STDIO */\n\n/*************************************************************************\n * fscanf\n */\n\n/**\n   Scan characters from file.\n\n   @param file File pointer.\n   @param format Formatting string.\n   @param ... Arguments.\n   @return Number of scanned characters.\n */\n#if TRIO_FEATURE_FILE\nTRIO_PUBLIC int\nfscanf\nTRIO_VARGS3((file, format, va_alist),\n\t    FILE *file,\n\t    TRIO_CONST char *format,\n\t    TRIO_VA_DECL)\n{\n  int status;\n  va_list args;\n\n  assert(VALID(file));\n  assert(VALID(format));\n  \n  TRIO_VA_START(args, format);\n  status = TrioScan((trio_pointer_t)file, 0,\n\t\t    TrioInStreamFile,\n\t\t    format, args, NULL);\n  TRIO_VA_END(args);\n  return status;\n}\n#endif /* TRIO_FEATURE_FILE */\n\n/**\n   Scan characters from file.\n\n   @param file File pointer.\n   @param format Formatting string.\n   @param args Arguments.\n   @return Number of scanned characters.\n */\n#if TRIO_FEATURE_FILE\nTRIO_PUBLIC int\nvfscanf\nTRIO_ARGS3((file, format, args),\n\t   FILE *file,\n\t   TRIO_CONST char *format,\n\t   va_list args)\n{\n  assert(VALID(file));\n  assert(VALID(format));\n  \n  return TrioScan((trio_pointer_t)file, 0,\n\t\t  TrioInStreamFile,\n\t\t  format, args, NULL);\n}\n#endif /* TRIO_FEATURE_FILE */\n\n/**\n   Scan characters from file.\n\n   @param file File pointer.\n   @param format Formatting string.\n   @param args Arguments.\n   @return Number of scanned characters.\n */\n#if TRIO_FEATURE_FILE\nTRIO_PUBLIC int\ntrio_fscanfv\nTRIO_ARGS3((file, format, args),\n\t   FILE *file,\n\t   TRIO_CONST char *format,\n\t   trio_pointer_t *args)\n{\n  static va_list unused;\n  \n  assert(VALID(file));\n  assert(VALID(format));\n  \n  return TrioScan((trio_pointer_t)file, 0,\n\t\t  TrioInStreamFile,\n\t\t  format, unused, args);\n}\n#endif /* TRIO_FEATURE_FILE */\n\n/*************************************************************************\n * dscanf\n */\n\n/**\n   Scan characters from file descriptor.\n\n   @param fd File descriptor.\n   @param format Formatting string.\n   @param ... Arguments.\n   @return Number of scanned characters.\n */\n#if TRIO_FEATURE_FD\nTRIO_PUBLIC int\ntrio_dscanf\nTRIO_VARGS3((fd, format, va_alist),\n\t    int fd,\n\t    TRIO_CONST char *format,\n\t    TRIO_VA_DECL)\n{\n  int status;\n  va_list args;\n\n  assert(VALID(format));\n  \n  TRIO_VA_START(args, format);\n  status = TrioScan((trio_pointer_t)&fd, 0,\n\t\t    TrioInStreamFileDescriptor,\n\t\t    format, args, NULL);\n  TRIO_VA_END(args);\n  return status;\n}\n#endif /* TRIO_FEATURE_FD */\n\n/**\n   Scan characters from file descriptor.\n\n   @param fd File descriptor.\n   @param format Formatting string.\n   @param args Arguments.\n   @return Number of scanned characters.\n */\n#if TRIO_FEATURE_FD\nTRIO_PUBLIC int\ntrio_vdscanf\nTRIO_ARGS3((fd, format, args),\n\t   int fd,\n\t   TRIO_CONST char *format,\n\t   va_list args)\n{\n  assert(VALID(format));\n  \n  return TrioScan((trio_pointer_t)&fd, 0,\n\t\t  TrioInStreamFileDescriptor,\n\t\t  format, args, NULL);\n}\n#endif /* TRIO_FEATURE_FD */\n\n/**\n   Scan characters from file descriptor.\n\n   @param fd File descriptor.\n   @param format Formatting string.\n   @param args Arguments.\n   @return Number of scanned characters.\n */\n#if TRIO_FEATURE_FD\nTRIO_PUBLIC int\ntrio_dscanfv\nTRIO_ARGS3((fd, format, args),\n\t   int fd,\n\t   TRIO_CONST char *format,\n\t   trio_pointer_t *args)\n{\n  static va_list unused;\n  \n  assert(VALID(format));\n  \n  return TrioScan((trio_pointer_t)&fd, 0,\n\t\t  TrioInStreamFileDescriptor,\n\t\t  format, unused, args);\n}\n#endif /* TRIO_FEATURE_FD */\n\n/*************************************************************************\n * cscanf\n */\n#if TRIO_FEATURE_CLOSURE\nTRIO_PUBLIC int\ntrio_cscanf\nTRIO_VARGS4((stream, closure, format, va_alist),\n\t    trio_instream_t stream,\n\t    trio_pointer_t closure,\n\t    TRIO_CONST char *format,\n\t    TRIO_VA_DECL)\n{\n  int status;\n  va_list args;\n  trio_custom_t data;\n\n  assert(VALID(stream));\n  assert(VALID(format));\n  \n  TRIO_VA_START(args, format);\n  data.stream.in = stream;\n  data.closure = closure;\n  status = TrioScan(&data, 0, TrioInStreamCustom, format, args, NULL);\n  TRIO_VA_END(args);\n  return status;\n}\n#endif /* TRIO_FEATURE_CLOSURE */\n\n#if TRIO_FEATURE_CLOSURE\nTRIO_PUBLIC int\ntrio_vcscanf\nTRIO_ARGS4((stream, closure, format, args),\n\t   trio_instream_t stream,\n\t   trio_pointer_t closure,\n\t   TRIO_CONST char *format,\n\t   va_list args)\n{\n  trio_custom_t data;\n  \n  assert(VALID(stream));\n  assert(VALID(format));\n\n  data.stream.in = stream;\n  data.closure = closure;\n  return TrioScan(&data, 0, TrioInStreamCustom, format, args, NULL);\n}\n#endif /* TRIO_FEATURE_CLOSURE */\n\n#if TRIO_FEATURE_CLOSURE\nTRIO_PUBLIC int\ntrio_cscanfv\nTRIO_ARGS4((stream, closure, format, args),\n\t   trio_instream_t stream,\n\t   trio_pointer_t closure,\n\t   TRIO_CONST char *format,\n\t   trio_pointer_t *args)\n{\n  static va_list unused;\n  trio_custom_t data;\n  \n  assert(VALID(stream));\n  assert(VALID(format));\n\n  data.stream.in = stream;\n  data.closure = closure;\n  return TrioScan(&data, 0, TrioInStreamCustom, format, unused, args);\n}\n#endif /* TRIO_FEATURE_CLOSURE */\n\n/*************************************************************************\n * sscanf\n */\n\n/**\n   Scan characters from string.\n\n   @param buffer Input string.\n   @param format Formatting string.\n   @param ... Arguments.\n   @return Number of scanned characters.\n */\nTRIO_PUBLIC int\nsscanf\nTRIO_VARGS3((buffer, format, va_alist),\n\t    TRIO_CONST char *buffer,\n\t    TRIO_CONST char *format,\n\t    TRIO_VA_DECL)\n{\n  int status;\n  va_list args;\n\n  assert(VALID(buffer));\n  assert(VALID(format));\n  \n  TRIO_VA_START(args, format);\n  status = TrioScan((trio_pointer_t)&buffer, 0,\n\t\t    TrioInStreamString,\n\t\t    format, args, NULL);\n  TRIO_VA_END(args);\n  return status;\n}\n\n/**\n   Scan characters from string.\n\n   @param buffer Input string.\n   @param format Formatting string.\n   @param args Arguments.\n   @return Number of scanned characters.\n */\nTRIO_PUBLIC int\nvsscanf\nTRIO_ARGS3((buffer, format, args),\n\t   TRIO_CONST char *buffer,\n\t   TRIO_CONST char *format,\n\t   va_list args)\n{\n  assert(VALID(buffer));\n  assert(VALID(format));\n  \n  return TrioScan((trio_pointer_t)&buffer, 0,\n\t\t  TrioInStreamString,\n\t\t  format, args, NULL);\n}\n\n/**\n   Scan characters from string.\n\n   @param buffer Input string.\n   @param format Formatting string.\n   @param args Arguments.\n   @return Number of scanned characters.\n */\nTRIO_PUBLIC int\ntrio_sscanfv\nTRIO_ARGS3((buffer, format, args),\n\t   TRIO_CONST char *buffer,\n\t   TRIO_CONST char *format,\n\t   trio_pointer_t *args)\n{\n  static va_list unused;\n  \n  assert(VALID(buffer));\n  assert(VALID(format));\n  \n  return TrioScan((trio_pointer_t)&buffer, 0,\n\t\t  TrioInStreamString,\n\t\t  format, unused, args);\n}\n\n#endif /* TRIO_FEATURE_SCANF */\n\n/** @} End of Scanf documentation module */\n\n/*************************************************************************\n * trio_strerror\n */\nTRIO_PUBLIC TRIO_CONST char *\ntrio_strerror\nTRIO_ARGS1((errorcode),\n\t   int errorcode)\n{\n#if TRIO_FEATURE_STRERR\n  /* Textual versions of the error codes */\n  switch (TRIO_ERROR_CODE(errorcode))\n    {\n    case TRIO_EOF:\n      return \"End of file\";\n    case TRIO_EINVAL:\n      return \"Invalid argument\";\n    case TRIO_ETOOMANY:\n      return \"Too many arguments\";\n    case TRIO_EDBLREF:\n      return \"Double reference\";\n    case TRIO_EGAP:\n      return \"Reference gap\";\n    case TRIO_ENOMEM:\n      return \"Out of memory\";\n    case TRIO_ERANGE:\n      return \"Invalid range\";\n    case TRIO_ECUSTOM:\n      return \"Custom error\";\n    default:\n      return \"Unknown\";\n    }\n#else\n  return \"Unknown\";\n#endif\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/trio/trio.h",
    "content": "\n\n#ifndef TRIO_TRIO_H\n#define TRIO_TRIO_H\n\n#if !defined(WITHOUT_TRIO)\n\n/*\n * Use autoconf defines if present. Packages using trio must define\n * HAVE_CONFIG_H as a compiler option themselves.\n */\n#if defined(HAVE_CONFIG_H)\n# include <config.h>\n#endif\n\n#include \"triop.h\"\n\n#include <stdio.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*\n * Error codes.\n *\n * Remember to add a textual description to trio_strerror.\n */\nenum {\n  TRIO_EOF      = 1,\n  TRIO_EINVAL   = 2,\n  TRIO_ETOOMANY = 3,\n  TRIO_EDBLREF  = 4,\n  TRIO_EGAP     = 5,\n  TRIO_ENOMEM   = 6,\n  TRIO_ERANGE   = 7,\n  TRIO_ERRNO    = 8,\n  TRIO_ECUSTOM  = 9\n};\n\n/* Error macros */\n#define TRIO_ERROR_CODE(x) ((-(x)) & 0x00FF)\n#define TRIO_ERROR_POSITION(x) ((-(x)) >> 8)\n#define TRIO_ERROR_NAME(x) trio_strerror(x)\n\ntypedef int (*trio_outstream_t) TRIO_PROTO((trio_pointer_t, int));\ntypedef int (*trio_instream_t) TRIO_PROTO((trio_pointer_t));\n\nTRIO_CONST char *trio_strerror TRIO_PROTO((int));\n\n/*************************************************************************\n * Print Functions\n */\n\nint trio_printf TRIO_PROTO((TRIO_CONST char *format, ...));\nint trio_vprintf TRIO_PROTO((TRIO_CONST char *format, va_list args));\nint trio_printfv TRIO_PROTO((TRIO_CONST char *format, void **args));\n\nint trio_fprintf TRIO_PROTO((FILE *file, TRIO_CONST char *format, ...));\nint trio_vfprintf TRIO_PROTO((FILE *file, TRIO_CONST char *format, va_list args));\nint trio_fprintfv TRIO_PROTO((FILE *file, TRIO_CONST char *format, void **args));\n\nint trio_dprintf TRIO_PROTO((int fd, TRIO_CONST char *format, ...));\nint trio_vdprintf TRIO_PROTO((int fd, TRIO_CONST char *format, va_list args));\nint trio_dprintfv TRIO_PROTO((int fd, TRIO_CONST char *format, void **args));\n\nint trio_cprintf TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure,\n\t\t\t     TRIO_CONST char *format, ...));\nint trio_vcprintf TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure,\n\t\t\t      TRIO_CONST char *format, va_list args));\nint trio_cprintfv TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure,\n\t\t\t      TRIO_CONST char *format, void **args));\n\nint trio_sprintf TRIO_PROTO((char *buffer, TRIO_CONST char *format, ...));\nint trio_vsprintf TRIO_PROTO((char *buffer, TRIO_CONST char *format, va_list args));\nint trio_sprintfv TRIO_PROTO((char *buffer, TRIO_CONST char *format, void **args));\n\nint trio_snprintf TRIO_PROTO((char *buffer, size_t max, TRIO_CONST char *format, ...));\nint trio_vsnprintf TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format,\n\t\t   va_list args));\nint trio_snprintfv TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format,\n\t\t   void **args));\n\nint trio_snprintfcat TRIO_PROTO((char *buffer, size_t max, TRIO_CONST char *format, ...));\nint trio_vsnprintfcat TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format,\n                      va_list args));\n\n#if defined(TRIO_DEPRECATED)\nchar *trio_aprintf TRIO_PROTO((TRIO_CONST char *format, ...));\nchar *trio_vaprintf TRIO_PROTO((TRIO_CONST char *format, va_list args));\n#endif\n\nint trio_asprintf TRIO_PROTO((char **ret, TRIO_CONST char *format, ...));\nint trio_vasprintf TRIO_PROTO((char **ret, TRIO_CONST char *format, va_list args));\nint trio_asprintfv TRIO_PROTO((char **result, TRIO_CONST char *format, trio_pointer_t * args));\n\n/*************************************************************************\n * Scan Functions\n */\nint trio_scanf TRIO_PROTO((TRIO_CONST char *format, ...));\nint trio_vscanf TRIO_PROTO((TRIO_CONST char *format, va_list args));\nint trio_scanfv TRIO_PROTO((TRIO_CONST char *format, void **args));\n\nint trio_fscanf TRIO_PROTO((FILE *file, TRIO_CONST char *format, ...));\nint trio_vfscanf TRIO_PROTO((FILE *file, TRIO_CONST char *format, va_list args));\nint trio_fscanfv TRIO_PROTO((FILE *file, TRIO_CONST char *format, void **args));\n\nint trio_dscanf TRIO_PROTO((int fd, TRIO_CONST char *format, ...));\nint trio_vdscanf TRIO_PROTO((int fd, TRIO_CONST char *format, va_list args));\nint trio_dscanfv TRIO_PROTO((int fd, TRIO_CONST char *format, void **args));\n\nint trio_cscanf TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure,\n\t\t\t    TRIO_CONST char *format, ...));\nint trio_vcscanf TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure,\n\t\t\t     TRIO_CONST char *format, va_list args));\nint trio_cscanfv TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure,\n\t\t\t     TRIO_CONST char *format, void **args));\n\nint trio_sscanf TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, ...));\nint trio_vsscanf TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, va_list args));\nint trio_sscanfv TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, void **args));\n\n/*************************************************************************\n * Locale Functions\n */\nvoid trio_locale_set_decimal_point TRIO_PROTO((char *decimalPoint));\nvoid trio_locale_set_thousand_separator TRIO_PROTO((char *thousandSeparator));\nvoid trio_locale_set_grouping TRIO_PROTO((char *grouping));\n\n/*************************************************************************\n * Renaming\n */\n#ifdef TRIO_REPLACE_STDIO\n/* Replace the <stdio.h> functions */\n#ifndef HAVE_PRINTF\n# define printf trio_printf\n#endif\n#ifndef HAVE_VPRINTF\n# define vprintf trio_vprintf\n#endif\n#ifndef HAVE_FPRINTF\n# define fprintf trio_fprintf\n#endif\n#ifndef HAVE_VFPRINTF\n# define vfprintf trio_vfprintf\n#endif\n#ifndef HAVE_SPRINTF\n# define sprintf trio_sprintf\n#endif\n#ifndef HAVE_VSPRINTF\n# define vsprintf trio_vsprintf\n#endif\n#ifndef HAVE_SNPRINTF\n# define snprintf trio_snprintf\n#endif\n#ifndef HAVE_VSNPRINTF\n# define vsnprintf trio_vsnprintf\n#endif\n#ifndef HAVE_SCANF\n# define scanf trio_scanf\n#endif\n#ifndef HAVE_VSCANF\n# define vscanf trio_vscanf\n#endif\n#ifndef HAVE_FSCANF\n# define fscanf trio_fscanf\n#endif\n#ifndef HAVE_VFSCANF\n# define vfscanf trio_vfscanf\n#endif\n#ifndef HAVE_SSCANF\n# define sscanf trio_sscanf\n#endif\n#ifndef HAVE_VSSCANF\n# define vsscanf trio_vsscanf\n#endif\n/* These aren't stdio functions, but we make them look similar */\n#define dprintf trio_dprintf\n#define vdprintf trio_vdprintf\n#define aprintf trio_aprintf\n#define vaprintf trio_vaprintf\n#define asprintf trio_asprintf\n#define vasprintf trio_vasprintf\n#define dscanf trio_dscanf\n#define vdscanf trio_vdscanf\n#endif\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /* WITHOUT_TRIO */\n\n#endif /* TRIO_TRIO_H */\n"
  },
  {
    "path": "src/sdk/src/libc/src/trio/triodef.h",
    "content": "\n\n#ifndef TRIO_TRIODEF_H\n#define TRIO_TRIODEF_H\n\n/*************************************************************************\n * Compiler support detection\n */\n\n#if defined(__GNUC__)\n# define TRIO_COMPILER_GCC\n#endif\n\n#if defined(__SUNPRO_CC)\n# define TRIO_COMPILER_SUNPRO __SUNPRO_CC\n#else\n# if defined(__SUNPRO_C)\n#  define TRIO_COMPILER_SUNPRO __SUNPRO_C\n# endif\n#endif\n\n#if defined(__xlC__) || defined(__IBMC__) || defined(__IBMCPP__)\n# define TRIO_COMPILER_XLC\n#else\n# if defined(_AIX) && !defined(__GNUC__)\n#  define TRIO_COMPILER_XLC /* Workaround for old xlc */\n# endif\n#endif\n\n#if defined(__DECC) || defined(__DECCXX)\n# define TRIO_COMPILER_DECC\n#else\n# if defined(__osf__) && defined(__LANGUAGE_C__) && !defined(__GNUC__)\n#  define TRIO_COMPILER_DECC /* Workaround for old DEC C compilers */\n# endif\n#endif\n\n#if defined(__HP_aCC) || defined(__HP_cc)\n# define TRIO_COMPILER_HP\n#endif\n\n#if defined(sgi) || defined(__sgi)\n# define TRIO_COMPILER_MIPSPRO\n#endif\n\n#if defined(_MSC_VER)\n# define TRIO_COMPILER_MSVC\n#endif\n\n#if defined(__BORLANDC__)\n# define TRIO_COMPILER_BCB\n#endif\n\n/*************************************************************************\n * Platform support detection\n */\n\n#if defined(VMS) || defined(__VMS)\n# define TRIO_PLATFORM_VMS\n#endif\n\n#if defined(unix) || defined(__unix) || defined(__unix__)\n# define TRIO_PLATFORM_UNIX\n#endif\n\n#if defined(TRIO_COMPILER_XLC) || defined(_AIX)\n# define TRIO_PLATFORM_UNIX\n#endif\n\n#if defined(TRIO_COMPILER_DECC) || defined(__osf___)\n# if !defined(TRIO_PLATFORM_VMS)\n#  define TRIO_PLATFORM_UNIX\n# endif\n#endif\n\n#if defined(__NetBSD__)\n# define TRIO_PLATFORM_UNIX\n#endif\n\n#if defined(__Lynx__)\n# define TRIO_PLATFORM_UNIX\n# define TRIO_PLATFORM_LYNX\n#endif\n\n#if defined(__APPLE__) && defined(__MACH__)\n# define TRIO_PLATFORM_UNIX\n#endif\n\n#if defined(__QNX__)\n# define TRIO_PLATFORM_UNIX\n# define TRIO_PLATFORM_QNX\n#endif\n\n#if defined(__CYGWIN__)\n# define TRIO_PLATFORM_UNIX\n#endif\n\n#if defined(AMIGA) && defined(TRIO_COMPILER_GCC)\n# define TRIO_PLATFORM_UNIX\n#endif\n\n#if defined(TRIO_COMPILER_MSVC) || defined(WIN32) || defined(_WIN32)\n# define TRIO_PLATFORM_WIN32\n#endif\n\n#if defined(_WIN32_WCE)\n# define TRIO_PLATFORM_WINCE\n#endif\n\n#if defined(mpeix) || defined(__mpexl)\n# define TRIO_PLATFORM_MPEIX\n#endif\n\n#if defined(_AIX)\n# define TRIO_PLATFORM_AIX\n#endif\n\n#if defined(__hpux)\n# define TRIO_PLATFORM_HPUX\n#endif\n\n#if defined(sun) || defined(__sun__)\n# if defined(__SVR4) || defined(__svr4__)\n#  define TRIO_PLATFORM_SOLARIS\n# else\n#  define TRIO_PLATFORM_SUNOS\n# endif\n#endif\n\n/*************************************************************************\n * Standards support detection\n */\n\n#if defined(__STDC__) \\\n || defined(_MSC_EXTENSIONS) \\\n || defined(TRIO_COMPILER_BORLAND)\n# define PREDEF_STANDARD_C89\n#endif\n#if defined(__STDC_VERSION__)\n# define PREDEF_STANDARD_C90\n#endif\n#if (__STDC_VERSION__ - 0 >= 199409L)\n# define PREDEF_STANDARD_C94\n#endif\n#if (__STDC_VERSION__ - 0 >= 199901L)\n# define PREDEF_STANDARD_C99\n#endif\n#if defined(TRIO_COMPILER_SUNPRO) && (TRIO_COMPILER_SUNPRO >= 0x420)\n# if !defined(PREDEF_STANDARD_C94)\n#  define PREDEF_STANDARD_C94\n# endif\n#endif\n\n#if defined(__cplusplus)\n# define PREDEF_STANDARD_CXX\n#endif\n#if __cplusplus - 0 >= 199711L\n# define PREDEF_STANDARD_CXX89\n#endif\n\n#if defined(TRIO_PLATFORM_UNIX)\n# include <unistd.h>\n#endif\n\n#if defined(_POSIX_VERSION)\n# define PREDEF_STANDARD_POSIX _POSIX_VERSION\n# if (_POSIX_VERSION >= 199506L)\n#  define PREDEF_STANDARD_POSIX_1996\n# endif\n#endif\n\n#if (_XOPEN_VERSION - 0 >= 3) || defined(_XOPEN_XPG3)\n# define PREDEF_STANDARD_XPG3\n#endif\n#if (_XOPEN_VERSION - 0 >= 4) || defined(_XOPEN_XPG4)\n# define PREDEF_STANDARD_XPG4\n#endif\n#if (_XOPEN_VERSION - 0 > 4) \\\n || (defined(_XOPEN_UNIX) && (_XOPEN_VERSION - 0 == 4))\n# define PREDEF_STANDARD_UNIX95\n#endif\n#if (_XOPEN_VERSION - 0 >= 500)\n# define PREDEF_STANDARD_UNIX98\n#endif\n#if (_XOPEN_VERSION - 0 >= 600)\n# define PREDEF_STANDARD_UNIX03\n#endif\n\n/*************************************************************************\n * Generic defines\n */\n\n#if !defined(TRIO_PUBLIC)\n# define TRIO_PUBLIC\n#endif\n#if !defined(TRIO_PRIVATE)\n# define TRIO_PRIVATE static\n#endif\n\n#if !(defined(PREDEF_STANDARD_C89) || defined(PREDEF_STANDARD_CXX))\n# define TRIO_COMPILER_ANCIENT\n#endif\n\n#if defined(TRIO_COMPILER_ANCIENT)\n# define TRIO_CONST\n# define TRIO_VOLATILE\n# define TRIO_SIGNED\ntypedef double trio_long_double_t;\ntypedef char * trio_pointer_t;\n# define TRIO_SUFFIX_LONG(x) x\n# define TRIO_PROTO(x) ()\n# define TRIO_NOARGS\n# define TRIO_ARGS1(list,a1) list a1;\n# define TRIO_ARGS2(list,a1,a2) list a1; a2;\n# define TRIO_ARGS3(list,a1,a2,a3) list a1; a2; a3;\n# define TRIO_ARGS4(list,a1,a2,a3,a4) list a1; a2; a3; a4;\n# define TRIO_ARGS5(list,a1,a2,a3,a4,a5) list a1; a2; a3; a4; a5;\n# define TRIO_ARGS6(list,a1,a2,a3,a4,a5,a6) list a1; a2; a3; a4; a5; a6;\n# define TRIO_VARGS2(list,a1,a2) list a1; a2\n# define TRIO_VARGS3(list,a1,a2,a3) list a1; a2; a3\n# define TRIO_VARGS4(list,a1,a2,a3,a4) list a1; a2; a3; a4\n# define TRIO_VARGS5(list,a1,a2,a3,a4,a5) list a1; a2; a3; a4; a5\n# define TRIO_VA_DECL va_dcl\n# define TRIO_VA_START(x,y) va_start(x)\n# define TRIO_VA_END(x) va_end(x)\n#else /* ANSI C */\n# define TRIO_CONST const\n# define TRIO_VOLATILE volatile\n# define TRIO_SIGNED signed\ntypedef long double trio_long_double_t;\ntypedef void * trio_pointer_t;\n# define TRIO_SUFFIX_LONG(x) x ## L\n# define TRIO_PROTO(x) x\n# define TRIO_NOARGS void\n# define TRIO_ARGS1(list,a1) (a1)\n# define TRIO_ARGS2(list,a1,a2) (a1,a2)\n# define TRIO_ARGS3(list,a1,a2,a3) (a1,a2,a3)\n# define TRIO_ARGS4(list,a1,a2,a3,a4) (a1,a2,a3,a4)\n# define TRIO_ARGS5(list,a1,a2,a3,a4,a5) (a1,a2,a3,a4,a5)\n# define TRIO_ARGS6(list,a1,a2,a3,a4,a5,a6) (a1,a2,a3,a4,a5,a6)\n# define TRIO_VARGS2 TRIO_ARGS2\n# define TRIO_VARGS3 TRIO_ARGS3\n# define TRIO_VARGS4 TRIO_ARGS4\n# define TRIO_VARGS5 TRIO_ARGS5\n# define TRIO_VA_DECL ...\n# define TRIO_VA_START(x,y) va_start(x,y)\n# define TRIO_VA_END(x) va_end(x)\n#endif\n\n#if defined(PREDEF_STANDARD_C99) || defined(PREDEF_STANDARD_CXX)\n# define TRIO_INLINE inline\n#else\n# if defined(TRIO_COMPILER_GCC)\n#  define TRIO_INLINE __inline__\n# endif\n# if defined(TRIO_COMPILER_MSVC)\n#  define TRIO_INLINE _inline\n# endif\n# if defined(TRIO_COMPILER_BCB)\n#  define TRIO_INLINE __inline\n# endif\n#endif\n#if !defined(TRIO_INLINE)\n# define TRIO_INLINE\n#endif\n\n/*************************************************************************\n * Workarounds\n */\n\n#if defined(TRIO_PLATFORM_VMS)\n/*\n * Computations done with constants at compile time can trigger these\n * even when compiling with IEEE enabled.\n */\n# pragma message disable (UNDERFLOW, FLOATOVERFL)\n\n# if (__CRTL_VER < 80210001)\n/*\n * Although the compiler supports C99 language constructs, the C\n * run-time library does not contain all C99 functions.\n */\n#  if defined(PREDEF_STANDARD_C99)\n#   undef PREDEF_STANDARD_C99\n#  endif\n# endif\n#endif\n\n/*\n * Not all preprocessors supports the LL token.\n */\n#if defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB)\n#else\n# define TRIO_COMPILER_SUPPORTS_LL\n#endif\n\n#endif /* TRIO_TRIODEF_H */\n"
  },
  {
    "path": "src/sdk/src/libc/src/trio/trionan.c",
    "content": "\n\n/*************************************************************************\n * Include files\n */\n#include \"triodef.h\"\n#include \"trionan.h\"\n\n#include <math.h>\n#include <string.h>\n#include <limits.h>\n#if !defined(TRIO_PLATFORM_SYMBIAN)\n# include <float.h>\n#endif\n#if defined(TRIO_PLATFORM_UNIX)\n# include <signal.h>\n#endif\n#if defined(TRIO_COMPILER_DECC)\n# include <fp_class.h>\n#endif\n#include <assert.h>\n\n#if defined(TRIO_DOCUMENTATION)\n# include \"doc/doc_nan.h\"\n#endif\n/** @addtogroup SpecialQuantities\n    @{\n*/\n\n/*************************************************************************\n * Definitions\n */\n\n#if !defined(TRIO_PUBLIC_NAN)\n# define TRIO_PUBLIC_NAN TRIO_PUBLIC\n#endif\n#if !defined(TRIO_PRIVATE_NAN)\n# define TRIO_PRIVATE_NAN TRIO_PRIVATE\n#endif\n\n#define TRIO_TRUE (1 == 1)\n#define TRIO_FALSE (0 == 1)\n\n/*\n * We must enable IEEE floating-point on Alpha\n */\n#if defined(__alpha) && !defined(_IEEE_FP)\n# if defined(TRIO_COMPILER_DECC)\n#  if defined(TRIO_PLATFORM_VMS)\n#   error \"Must be compiled with option /IEEE_MODE=UNDERFLOW_TO_ZERO/FLOAT=IEEE\"\n#  else\n#   if !defined(_CFE)\n#    error \"Must be compiled with option -ieee\"\n#   endif\n#  endif\n# else\n#  if defined(TRIO_COMPILER_GCC)\n#   error \"Must be compiled with option -mieee\"\n#  endif\n# endif\n#endif /* __alpha && ! _IEEE_FP */\n\n/*\n * In ANSI/IEEE 754-1985 64-bits double format numbers have the\n * following properties (amoungst others)\n *\n *   o FLT_RADIX == 2: binary encoding\n *   o DBL_MAX_EXP == 1024: 11 bits exponent, where one bit is used\n *     to indicate special numbers (e.g. NaN and Infinity), so the\n *     maximum exponent is 10 bits wide (2^10 == 1024).\n *   o DBL_MANT_DIG == 53: The mantissa is 52 bits wide, but because\n *     numbers are normalized the initial binary 1 is represented\n *     implicitly (the so-called \"hidden bit\"), which leaves us with\n *     the ability to represent 53 bits wide mantissa.\n */\n#if defined(__STDC_IEC_559__)\n# define TRIO_IEEE_754\n#else\n# if (FLT_RADIX - 0 == 2) && (DBL_MAX_EXP - 0 == 1024) && (DBL_MANT_DIG - 0 == 53)\n#  define TRIO_IEEE_754\n# endif\n#endif\n\n/*\n * Determine which fpclassify_and_sign() function to use.\n */\n#if defined(TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT)\n# if defined(PREDEF_STANDARD_C99) && defined(fpclassify)\n#  define TRIO_FUNC_C99_FPCLASSIFY_AND_SIGNBIT\n# else\n#  if defined(TRIO_COMPILER_DECC)\n#   define TRIO_FUNC_DECC_FPCLASSIFY_AND_SIGNBIT\n#  else\n#   if defined(TRIO_COMPILER_VISUALC) || defined(TRIO_COMPILER_BORLAND)\n#    define TRIO_FUNC_MS_FPCLASSIFY_AND_SIGNBIT\n#   else\n#    if defined(TRIO_COMPILER_HP) && defined(FP_PLUS_NORM)\n#     define TRIO_FUNC_HP_FPCLASSIFY_AND_SIGNBIT\n#    else\n#     if defined(TRIO_COMPILER_XLC) && defined(FP_PLUS_NORM)\n#      define TRIO_FUNC_XLC_FPCLASSIFY_AND_SIGNBIT\n#     else\n#      define TRIO_FUNC_INTERNAL_FPCLASSIFY_AND_SIGNBIT\n#     endif\n#    endif\n#   endif\n#  endif\n# endif\n#endif\n\n/*\n * Determine how to generate negative zero.\n */\n#if defined(TRIO_FUNC_NZERO)\n# if defined(TRIO_IEEE_754)\n#  define TRIO_NZERO_IEEE_754\n# else\n#  define TRIO_NZERO_FALLBACK\n# endif\n#endif\n\n/*\n * Determine how to generate positive infinity.\n */\n#if defined(TRIO_FUNC_PINF)\n# if defined(INFINITY) && defined(__STDC_IEC_559__)\n#  define TRIO_PINF_C99_MACRO\n# else\n#  if defined(TRIO_IEEE_754)\n#   define TRIO_PINF_IEEE_754\n#  else\n#   define TRIO_PINF_FALLBACK\n#  endif\n# endif\n#endif\n\n/*\n * Determine how to generate NaN.\n */\n#if defined(TRIO_FUNC_NAN)\n# if defined(PREDEF_STANDARD_C99) && !defined(TRIO_COMPILER_DECC)\n#  define TRIO_NAN_C99_FUNCTION\n# else\n#  if defined(NAN) && defined(__STDC_IEC_559__)\n#   define TRIO_NAN_C99_MACRO\n#  else\n#   if defined(TRIO_IEEE_754)\n#    define TRIO_NAN_IEEE_754\n#   else\n#    define TRIO_NAN_FALLBACK\n#   endif\n#  endif\n# endif\n#endif\n\n/*\n * Resolve internal dependencies.\n */\n#if defined(TRIO_FUNC_INTERNAL_FPCLASSIFY_AND_SIGNBIT)\n# define TRIO_FUNC_INTERNAL_ISNAN\n# define TRIO_FUNC_INTERNAL_ISINF\n# if defined(TRIO_IEEE_754)\n#  define TRIO_FUNC_INTERNAL_IS_SPECIAL_QUANTITY\n#  define TRIO_FUNC_INTERNAL_IS_NEGATIVE\n# endif\n#endif\n\n#if defined(TRIO_NZERO_IEEE_754) \\\n || defined(TRIO_PINF_IEEE_754) \\\n || defined(TRIO_NAN_IEEE_754)\n# define TRIO_FUNC_INTERNAL_MAKE_DOUBLE\n#endif\n\n#if defined(TRIO_FUNC_INTERNAL_ISNAN)\n# if defined(PREDEF_STANDARD_XPG3)\n#  define TRIO_INTERNAL_ISNAN_XPG3\n# else\n#  if defined(TRIO_IEEE_754)\n#   define TRIO_INTERNAL_ISNAN_IEEE_754\n#  else\n#   define TRIO_INTERNAL_ISNAN_FALLBACK\n#  endif\n# endif\n#endif\n\n#if defined(TRIO_FUNC_INTERNAL_ISINF)\n# if defined(TRIO_IEEE_754)\n#  define TRIO_INTERNAL_ISINF_IEEE_754\n# else\n#  define TRIO_INTERNAL_ISINF_FALLBACK\n# endif\n#endif\n\n/*************************************************************************\n * Constants\n */\n\n#if !defined(TRIO_EMBED_NAN)\nstatic TRIO_CONST char rcsid[] = \"@(#)$Id: trionan.c,v 1.33 2005/05/29 11:57:25 breese Exp $\";\n#endif\n\n#if defined(TRIO_FUNC_INTERNAL_MAKE_DOUBLE) \\\n || defined(TRIO_FUNC_INTERNAL_IS_SPECIAL_QUANTITY) \\\n || defined(TRIO_FUNC_INTERNAL_IS_NEGATIVE)\n/*\n * Endian-agnostic indexing macro.\n *\n * The value of internalEndianMagic, when converted into a 64-bit\n * integer, becomes 0x0706050403020100 (we could have used a 64-bit\n * integer value instead of a double, but not all platforms supports\n * that type). The value is automatically encoded with the correct\n * endianess by the compiler, which means that we can support any\n * kind of endianess. The individual bytes are then used as an index\n * for the IEEE 754 bit-patterns and masks.\n */\n#define TRIO_DOUBLE_INDEX(x) (((unsigned char *)&internalEndianMagic)[7-(x)])\nstatic TRIO_CONST double internalEndianMagic = 7.949928895127363e-275;\n#endif\n\n#if defined(TRIO_FUNC_INTERNAL_IS_SPECIAL_QUANTITY)\n/* Mask for the exponent */\nstatic TRIO_CONST unsigned char ieee_754_exponent_mask[] = {\n  0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\n};\n\n/* Mask for the mantissa */\nstatic TRIO_CONST unsigned char ieee_754_mantissa_mask[] = {\n  0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF\n};\n#endif\n\n#if defined(TRIO_FUNC_INTERNAL_IS_NEGATIVE)\n/* Mask for the sign bit */\nstatic TRIO_CONST unsigned char ieee_754_sign_mask[] = {\n  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\n};\n#endif\n\n#if defined(TRIO_NZERO_IEEE_754)\n/* Bit-pattern for negative zero */\nstatic TRIO_CONST unsigned char ieee_754_negzero_array[] = {\n  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\n};\n#endif\n\n#if defined(TRIO_PINF_IEEE_754)\n/* Bit-pattern for infinity */\nstatic TRIO_CONST unsigned char ieee_754_infinity_array[] = {\n  0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\n};\n#endif\n\n#if defined(TRIO_NAN_IEEE_754)\n/* Bit-pattern for quiet NaN */\nstatic TRIO_CONST unsigned char ieee_754_qnan_array[] = {\n  0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\n};\n#endif\n\n\n/*************************************************************************\n * Internal functions\n */\n\n/*\n * internal_make_double\n */\n#if defined(TRIO_FUNC_INTERNAL_MAKE_DOUBLE)\n\nTRIO_PRIVATE_NAN double\ninternal_make_double\nTRIO_ARGS1((values),\n\t   TRIO_CONST unsigned char *values)\n{\n  TRIO_VOLATILE double result;\n  int i;\n\n  for (i = 0; i < (int)sizeof(double); i++) {\n    ((TRIO_VOLATILE unsigned char *)&result)[TRIO_DOUBLE_INDEX(i)] = values[i];\n  }\n  return result;\n}\n\n#endif\n\n/*\n * internal_is_special_quantity\n */\n#if defined(TRIO_FUNC_INTERNAL_IS_SPECIAL_QUANTITY)\n\nTRIO_PRIVATE_NAN int\ninternal_is_special_quantity\nTRIO_ARGS2((number, has_mantissa),\n\t   double number,\n\t   int *has_mantissa)\n{\n  unsigned int i;\n  unsigned char current;\n  int is_special_quantity = TRIO_TRUE;\n\n  *has_mantissa = 0;\n\n  for (i = 0; i < (unsigned int)sizeof(double); i++) {\n    current = ((unsigned char *)&number)[TRIO_DOUBLE_INDEX(i)];\n    is_special_quantity\n      &= ((current & ieee_754_exponent_mask[i]) == ieee_754_exponent_mask[i]);\n    *has_mantissa |= (current & ieee_754_mantissa_mask[i]);\n  }\n  return is_special_quantity;\n}\n\n#endif\n\n/*\n * internal_is_negative\n */\n#if defined(TRIO_FUNC_INTERNAL_IS_NEGATIVE)\n\nTRIO_PRIVATE_NAN int\ninternal_is_negative\nTRIO_ARGS1((number),\n\t   double number)\n{\n  unsigned int i;\n  int is_negative = TRIO_FALSE;\n\n  for (i = 0; i < (unsigned int)sizeof(double); i++) {\n    is_negative |= (((unsigned char *)&number)[TRIO_DOUBLE_INDEX(i)]\n\t\t    & ieee_754_sign_mask[i]);\n  }\n  return is_negative;\n}\n\n#endif\n\n#if defined(TRIO_FUNC_C99_FPCLASSIFY_AND_SIGNBIT)\n\nTRIO_PRIVATE_NAN TRIO_INLINE int\nc99_fpclassify_and_signbit\nTRIO_ARGS2((number, is_negative),\n\t   double number,\n\t   int *is_negative)\n{\n  *is_negative = signbit(number);\n  switch (fpclassify(number)) {\n  case FP_NAN:\n    return TRIO_FP_NAN;\n  case FP_INFINITE:\n    return TRIO_FP_INFINITE;\n  case FP_SUBNORMAL:\n    return TRIO_FP_SUBNORMAL;\n  case FP_ZERO:\n    return TRIO_FP_ZERO;\n  default:\n    return TRIO_FP_NORMAL;\n  }\n}\n\n#endif /* TRIO_FUNC_C99_FPCLASSIFY_AND_SIGNBIT */\n\n#if defined(TRIO_FUNC_DECC_FPCLASSIFY_AND_SIGNBIT)\n\nTRIO_PRIVATE_NAN TRIO_INLINE int\ndecc_fpclassify_and_signbit\nTRIO_ARGS2((number, is_negative),\n\t  double number,\n\t  int *is_negative)\n{\n  switch (fp_class(number)) {\n  case FP_QNAN:\n  case FP_SNAN:\n    *is_negative = TRIO_FALSE; /* NaN has no sign */\n    return TRIO_FP_NAN;\n  case FP_POS_INF:\n    *is_negative = TRIO_FALSE;\n    return TRIO_FP_INFINITE;\n  case FP_NEG_INF:\n    *is_negative = TRIO_TRUE;\n    return TRIO_FP_INFINITE;\n  case FP_POS_DENORM:\n    *is_negative = TRIO_FALSE;\n    return TRIO_FP_SUBNORMAL;\n  case FP_NEG_DENORM:\n    *is_negative = TRIO_TRUE;\n    return TRIO_FP_SUBNORMAL;\n  case FP_POS_ZERO:\n    *is_negative = TRIO_FALSE;\n    return TRIO_FP_ZERO;\n  case FP_NEG_ZERO:\n    *is_negative = TRIO_TRUE;\n    return TRIO_FP_ZERO;\n  case FP_POS_NORM:\n    *is_negative = TRIO_FALSE;\n    return TRIO_FP_NORMAL;\n  case FP_NEG_NORM:\n    *is_negative = TRIO_TRUE;\n    return TRIO_FP_NORMAL;\n  default:\n    *is_negative = (number < 0.0);\n    return TRIO_FP_NORMAL;\n  }\n}\n\n#endif /* TRIO_FUNC_DECC_FPCLASSIFY_AND_SIGNBIT */\n\n#if defined(TRIO_FUNC_MS_FPCLASSIFY_AND_SIGNBIT)\n\nTRIO_PRIVATE_NAN int\nms_fpclassify_and_signbit\nTRIO_ARGS2((number, is_negative),\n\t  double number,\n\t  int *is_negative)\n{\n  int result;\n# if defined(TRIO_COMPILER_BORLAND)\n  /*\n   * The floating-point precision may be changed by the Borland _fpclass()\n   * function, so we have to save and restore the floating-point control mask.\n   */\n  unsigned int mask;\n  /* Remember the old mask */\n  mask = _control87(0, 0);\n# endif\n  \n  switch (_fpclass(number)) {\n  case _FPCLASS_QNAN:\n  case _FPCLASS_SNAN:\n    *is_negative = TRIO_FALSE; /* NaN has no sign */\n    result = TRIO_FP_NAN;\n    break;\n  case _FPCLASS_PINF:\n    *is_negative = TRIO_FALSE;\n    result = TRIO_FP_INFINITE;\n    break;\n  case _FPCLASS_NINF:\n    *is_negative = TRIO_TRUE;\n    result = TRIO_FP_INFINITE;\n    break;\n  case _FPCLASS_PD:\n    *is_negative = TRIO_FALSE;\n    result = TRIO_FP_SUBNORMAL;\n    break;\n  case _FPCLASS_ND:\n    *is_negative = TRIO_TRUE;\n    result = TRIO_FP_SUBNORMAL;\n    break;\n  case _FPCLASS_PZ:\n    *is_negative = TRIO_FALSE;\n    result = TRIO_FP_ZERO;\n    break;\n  case _FPCLASS_NZ:\n    *is_negative = TRIO_TRUE;\n    result = TRIO_FP_ZERO;\n    break;\n  case _FPCLASS_PN:\n    *is_negative = TRIO_FALSE;\n    result = TRIO_FP_NORMAL;\n    break;\n  case _FPCLASS_NN:\n    *is_negative = TRIO_TRUE;\n    result = TRIO_FP_NORMAL;\n    break;\n  default:\n    *is_negative = (number < 0.0);\n    result = TRIO_FP_NORMAL;\n    break;\n  }\n  \n# if defined(TRIO_COMPILER_BORLAND)\n  /* Restore the old precision */\n  (void)_control87(mask, MCW_PC);\n# endif\n  \n  return result;\n}\n\n#endif /* TRIO_FUNC_MS_FPCLASSIFY_AND_SIGNBIT */\n\n#if defined(TRIO_FUNC_HP_FPCLASSIFY_AND_SIGNBIT)\n\nTRIO_PRIVATE_NAN TRIO_INLINE int\nhp_fpclassify_and_signbit\nTRIO_ARGS2((number, is_negative),\n\t  double number,\n\t  int *is_negative)\n{\n  /*\n   * HP-UX 9.x and 10.x have an fpclassify() function, that is different\n   * from the C99 fpclassify() macro supported on HP-UX 11.x.\n   */\n  switch (fpclassify(number)) {\n  case FP_QNAN:\n  case FP_SNAN:\n    *is_negative = TRIO_FALSE; /* NaN has no sign */\n    return TRIO_FP_NAN;\n  case FP_PLUS_INF:\n    *is_negative = TRIO_FALSE;\n    return TRIO_FP_INFINITE;\n  case FP_MINUS_INF:\n    *is_negative = TRIO_TRUE;\n    return TRIO_FP_INFINITE;\n  case FP_PLUS_DENORM:\n    *is_negative = TRIO_FALSE;\n    return TRIO_FP_SUBNORMAL;\n  case FP_MINUS_DENORM:\n    *is_negative = TRIO_TRUE;\n    return TRIO_FP_SUBNORMAL;\n  case FP_PLUS_ZERO:\n    *is_negative = TRIO_FALSE;\n    return TRIO_FP_ZERO;\n  case FP_MINUS_ZERO:\n    *is_negative = TRIO_TRUE;\n    return TRIO_FP_ZERO;\n  case FP_PLUS_NORM:\n    *is_negative = TRIO_FALSE;\n    return TRIO_FP_NORMAL;\n  case FP_MINUS_NORM:\n    *is_negative = TRIO_TRUE;\n    return TRIO_FP_NORMAL;\n  default:\n    *is_negative = (number < 0.0);\n    return TRIO_FP_NORMAL;\n  }\n}\n\n#endif /* TRIO_FUNC_HP_FPCLASSIFY_AND_SIGNBIT */\n\n#if defined(TRIO_FUNC_XLC_FPCLASSIFY_AND_SIGNBIT)\n\nTRIO_PRIVATE_NAN TRIO_INLINE int\nxlc_fpclassify_and_signbit\nTRIO_ARGS2((number, is_negative),\n\t  double number,\n\t  int *is_negative)\n{\n  /*\n   * AIX has class() for C, and _class() for C++\n   */\n# if defined(__cplusplus)\n#  define AIX_CLASS(n) _class(n)\n# else\n#  define AIX_CLASS(n) class(n)\n# endif\n\n  switch (AIX_CLASS(number)) {\n  case FP_QNAN:\n  case FP_SNAN:\n    *is_negative = TRIO_FALSE; /* NaN has no sign */\n    return TRIO_FP_NAN;\n  case FP_PLUS_INF:\n    *is_negative = TRIO_FALSE;\n    return TRIO_FP_INFINITE;\n  case FP_MINUS_INF:\n    *is_negative = TRIO_TRUE;\n    return TRIO_FP_INFINITE;\n  case FP_PLUS_DENORM:\n    *is_negative = TRIO_FALSE;\n    return TRIO_FP_SUBNORMAL;\n  case FP_MINUS_DENORM:\n    *is_negative = TRIO_TRUE;\n    return TRIO_FP_SUBNORMAL;\n  case FP_PLUS_ZERO:\n    *is_negative = TRIO_FALSE;\n    return TRIO_FP_ZERO;\n  case FP_MINUS_ZERO:\n    *is_negative = TRIO_TRUE;\n    return TRIO_FP_ZERO;\n  case FP_PLUS_NORM:\n    *is_negative = TRIO_FALSE;\n    return TRIO_FP_NORMAL;\n  case FP_MINUS_NORM:\n    *is_negative = TRIO_TRUE;\n    return TRIO_FP_NORMAL;\n  default:\n    *is_negative = (number < 0.0);\n    return TRIO_FP_NORMAL;\n  }\n}\n\n#endif /* TRIO_FUNC_XLC_FPCLASSIFY_AND_SIGNBIT */\n\n#if defined(TRIO_FUNC_INTERNAL_ISNAN)\n\nTRIO_PRIVATE_NAN TRIO_INLINE int\ninternal_isnan\nTRIO_ARGS1((number),\n\t   double number)\n{\n# if defined(TRIO_INTERNAL_ISNAN_XPG3) || defined(TRIO_PLATFORM_SYMBIAN)\n  /*\n   * XPG3 defines isnan() as a function.\n   */\n  return isnan(number);\n\n# endif\n  \n# if defined(TRIO_INTERNAL_ISNAN_IEEE_754)\n  \n  /*\n   * Examine IEEE 754 bit-pattern. A NaN must have a special exponent\n   * pattern, and a non-empty mantissa.\n   */\n  int has_mantissa;\n  int is_special_quantity;\n\n  is_special_quantity = internal_is_special_quantity(number, &has_mantissa);\n  \n  return (is_special_quantity && has_mantissa);\n  \n# endif\n\n# if defined(TRIO_INTERNAL_ISNAN_FALLBACK)\n  \n  /*\n   * Fallback solution\n   */\n  int status;\n  double integral, fraction;\n  \n#  if defined(TRIO_PLATFORM_UNIX)\n  void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);\n#  endif\n  \n  status = (/*\n\t     * NaN is the only number which does not compare to itself\n\t     */\n\t    ((TRIO_VOLATILE double)number != (TRIO_VOLATILE double)number) ||\n\t    /*\n\t     * Fallback solution if NaN compares to NaN\n\t     */\n\t    ((number != 0.0) &&\n\t     (fraction = modf(number, &integral),\n\t      integral == fraction)));\n  \n#  if defined(TRIO_PLATFORM_UNIX)\n  signal(SIGFPE, signal_handler);\n#  endif\n  \n  return status;\n  \n# endif\n}\n\n#endif /* TRIO_FUNC_INTERNAL_ISNAN */\n\n#if defined(TRIO_FUNC_INTERNAL_ISINF)\n\nTRIO_PRIVATE_NAN TRIO_INLINE int\ninternal_isinf\nTRIO_ARGS1((number),\n\t   double number)\n{\n# if defined(TRIO_PLATFORM_SYMBIAN)\n\n  return isinf(number);\n\n# endif\n\n# if defined(TRIO_INTERNAL_ISINF_IEEE_754)\n  /*\n   * Examine IEEE 754 bit-pattern. Infinity must have a special exponent\n   * pattern, and an empty mantissa.\n   */\n  int has_mantissa;\n  int is_special_quantity;\n\n  is_special_quantity = internal_is_special_quantity(number, &has_mantissa);\n  \n  return (is_special_quantity && !has_mantissa)\n    ? ((number < 0.0) ? -1 : 1)\n    : 0;\n\n# endif\n\n# if defined(TRIO_INTERNAL_ISINF_FALLBACK)\n  \n  /*\n   * Fallback solution.\n   */\n  int status;\n  \n#  if defined(TRIO_PLATFORM_UNIX)\n  void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);\n#  endif\n  \n  double infinity = trio_pinf();\n  \n  status = ((number == infinity)\n\t    ? 1\n\t    : ((number == -infinity) ? -1 : 0));\n  \n#  if defined(TRIO_PLATFORM_UNIX)\n  signal(SIGFPE, signal_handler);\n#  endif\n  \n  return status;\n\n# endif\n}\n\n#endif /* TRIO_FUNC_INTERNAL_ISINF */\n\n/*************************************************************************\n * Public functions\n */\n\n#if defined(TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT)\n\nTRIO_PUBLIC_NAN int\ntrio_fpclassify_and_signbit\nTRIO_ARGS2((number, is_negative),\n\t   double number,\n\t   int *is_negative)\n{\n  /* The TRIO_FUNC_xxx_FPCLASSIFY_AND_SIGNBIT macros are mutually exclusive */\n  \n#if defined(TRIO_FUNC_C99_FPCLASSIFY_AND_SIGNBIT)\n\n  return c99_fpclassify_and_signbit(number, is_negative);\n\n#endif\n\n#if defined(TRIO_FUNC_DECC_FPCLASSIFY_AND_SIGNBIT)\n\n  return decc_fpclassify_and_signbit(number, is_negative);\n\n#endif\n\n#if defined(TRIO_FUNC_MS_FPCLASSIFY_AND_SIGNBIT)\n\n  return ms_fpclassify_and_signbit(number, is_negative);\n\n#endif\n\n#if defined(TRIO_FUNC_HP_FPCLASSIFY_AND_SIGNBIT)\n\n  return hp_fpclassify_and_signbit(number, is_negative);\n\n#endif\n\n#if defined(TRIO_FUNC_XLC_FPCLASSIFY_AND_SIGNBIT)\n\n  return xlc_fpclassify_and_signbit(number, is_negative);\n\n#endif\n\n#if defined(TRIO_FUNC_INTERNAL_FPCLASSIFY_AND_SIGNBIT)\n  \n  /*\n   * Fallback solution.\n   */\n  int rc;\n  \n  if (number == 0.0) {\n    /*\n     * In IEEE 754 the sign of zero is ignored in comparisons, so we\n     * have to handle this as a special case by examining the sign bit\n     * directly.\n     */\n# if defined(TRIO_IEEE_754)\n    *is_negative = internal_is_negative(number);\n# else\n    *is_negative = TRIO_FALSE; /* FIXME */\n# endif\n    return TRIO_FP_ZERO;\n  }\n  if (internal_isnan(number)) {\n    *is_negative = TRIO_FALSE;\n    return TRIO_FP_NAN;\n  }\n  rc = internal_isinf(number);\n  if (rc != 0) {\n    *is_negative = (rc == -1);\n    return TRIO_FP_INFINITE;\n  }\n  if ((number > 0.0) && (number < DBL_MIN)) {\n    *is_negative = TRIO_FALSE;\n    return TRIO_FP_SUBNORMAL;\n  }\n  if ((number < 0.0) && (number > -DBL_MIN)) {\n    *is_negative = TRIO_TRUE;\n    return TRIO_FP_SUBNORMAL;\n  }\n  *is_negative = (number < 0.0);\n  return TRIO_FP_NORMAL;\n\n#endif\n}\n\n#endif\n\n/**\n   Check for NaN.\n\n   @param number An arbitrary floating-point number.\n   @return Boolean value indicating whether or not the number is a NaN.\n*/\n#if defined(TRIO_FUNC_ISNAN)\n\nTRIO_PUBLIC_NAN int\ntrio_isnan\nTRIO_ARGS1((number),\n\t   double number)\n{\n  int dummy;\n  \n  return (trio_fpclassify_and_signbit(number, &dummy) == TRIO_FP_NAN);\n}\n\n#endif\n\n/**\n   Check for infinity.\n\n   @param number An arbitrary floating-point number.\n   @return 1 if positive infinity, -1 if negative infinity, 0 otherwise.\n*/\n#if defined(TRIO_FUNC_ISINF)\n\nTRIO_PUBLIC_NAN int\ntrio_isinf\nTRIO_ARGS1((number),\n\t   double number)\n{\n  int is_negative;\n  \n  if (trio_fpclassify_and_signbit(number, &is_negative) == TRIO_FP_INFINITE)\n    {\n      return (is_negative) ? -1 : 1;\n    }\n  else\n    {\n      return 0;\n    }\n}\n\n#endif\n\n/**\n   Check for finity.\n\n   @param number An arbitrary floating-point number.\n   @return Boolean value indicating whether or not the number is a finite.\n*/\n#if defined(TRIO_FUNC_ISFINITE)\n\nTRIO_PUBLIC_NAN int\ntrio_isfinite\nTRIO_ARGS1((number),\n\t   double number)\n{\n  int dummy;\n  \n  switch (trio_fpclassify_and_signbit(number, &dummy))\n    {\n    case TRIO_FP_INFINITE:\n    case TRIO_FP_NAN:\n      return 0;\n    default:\n      return 1;\n    }\n}\n\n#endif\n\n/**\n   Examine the sign of a number.\n\n   @param number An arbitrary floating-point number.\n   @return Boolean value indicating whether or not the number has the\n   sign bit set (i.e. is negative).\n*/\n#if defined(TRIO_FUNC_SIGNBIT)\n\nTRIO_PUBLIC_NAN int\ntrio_signbit\nTRIO_ARGS1((number),\n\t   double number)\n{\n  int is_negative;\n  \n  (void)trio_fpclassify_and_signbit(number, &is_negative);\n  return is_negative;\n}\n\n#endif\n\n/**\n   Examine the class of a number.\n\n   @param number An arbitrary floating-point number.\n   @return Enumerable value indicating the class of @p number\n*/\n#if defined(TRIO_FUNC_FPCLASSIFY)\n\nTRIO_PUBLIC_NAN int\ntrio_fpclassify\nTRIO_ARGS1((number),\n\t   double number)\n{\n  int dummy;\n  \n  return trio_fpclassify_and_signbit(number, &dummy);\n}\n\n#endif\n\n/**\n   Generate negative zero.\n\n   @return Floating-point representation of negative zero.\n*/\n#if defined(TRIO_FUNC_NZERO)\n\nTRIO_PUBLIC_NAN double\ntrio_nzero(TRIO_NOARGS)\n{\n# if defined(TRIO_NZERO_IEEE_754)\n  \n  return internal_make_double(ieee_754_negzero_array);\n\n# endif\n  \n# if defined(TRIO_NZERO_FALLBACK)\n  \n  TRIO_VOLATILE double zero = 0.0;\n\n  return -zero;\n  \n# endif\n}\n\n#endif\n\n/**\n   Generate positive infinity.\n\n   @return Floating-point representation of positive infinity.\n*/\n#if defined(TRIO_FUNC_PINF)\n\nTRIO_PUBLIC_NAN double\ntrio_pinf(TRIO_NOARGS)\n{\n  /* Cache the result */\n  static double pinf_value = 0.0;\n\n  if (pinf_value == 0.0) {\n\n# if defined(TRIO_PINF_C99_MACRO)\n    \n    pinf_value = (double)INFINITY;\n\n# endif\n    \n# if defined(TRIO_PINF_IEEE_754)\n    \n    pinf_value = internal_make_double(ieee_754_infinity_array);\n\n# endif\n\n# if defined(TRIO_PINF_FALLBACK)\n    /*\n     * If HUGE_VAL is different from DBL_MAX, then HUGE_VAL is used\n     * as infinity. Otherwise we have to resort to an overflow\n     * operation to generate infinity.\n     */\n#  if defined(TRIO_PLATFORM_UNIX)\n    void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);\n#  endif\n\n    pinf_value = HUGE_VAL;\n    if (HUGE_VAL == DBL_MAX) {\n      /* Force overflow */\n      pinf_value += HUGE_VAL;\n    }\n    \n#  if defined(TRIO_PLATFORM_UNIX)\n    signal(SIGFPE, signal_handler);\n#  endif\n\n# endif\n  }\n  return pinf_value;\n}\n\n#endif\n\n/**\n   Generate negative infinity.\n\n   @return Floating-point value of negative infinity.\n*/\n#if defined(TRIO_FUNC_NINF)\n\nTRIO_PUBLIC_NAN double\ntrio_ninf(TRIO_NOARGS)\n{\n  static double ninf_value = 0.0;\n\n  if (ninf_value == 0.0) {\n    /*\n     * Negative infinity is calculated by negating positive infinity,\n     * which can be done because it is legal to do calculations on\n     * infinity (for example,  1 / infinity == 0).\n     */\n    ninf_value = -trio_pinf();\n  }\n  return ninf_value;\n}\n\n#endif\n\n/**\n   Generate NaN.\n\n   @return Floating-point representation of NaN.\n*/\n#if defined(TRIO_FUNC_NAN)\n\nTRIO_PUBLIC_NAN double\ntrio_nan(TRIO_NOARGS)\n{\n  /* Cache the result */\n  static double nan_value = 0.0;\n\n  if (nan_value == 0.0) {\n    \n# if defined(TRIO_NAN_C99_FUNCTION) || defined(TRIO_PLATFORM_SYMBIAN)\n    \n    nan_value = nan(\"\");\n\n# endif\n    \n# if defined(TRIO_NAN_C99_MACRO)\n    \n    nan_value = (double)NAN;\n\n# endif\n\n# if defined(TRIO_NAN_IEEE_754)\n    \n    nan_value = internal_make_double(ieee_754_qnan_array);\n\n# endif\n    \n# if defined(TRIO_NAN_FALLBACK)\n    /*\n     * There are several ways to generate NaN. The one used here is\n     * to divide infinity by infinity. I would have preferred to add\n     * negative infinity to positive infinity, but that yields wrong\n     * result (infinity) on FreeBSD.\n     *\n     * This may fail if the hardware does not support NaN, or if\n     * the Invalid Operation floating-point exception is unmasked.\n     */\n#  if defined(TRIO_PLATFORM_UNIX)\n    void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);\n#  endif\n    \n    nan_value = trio_pinf() / trio_pinf();\n    \n#  if defined(TRIO_PLATFORM_UNIX)\n    signal(SIGFPE, signal_handler);\n#  endif\n\n# endif\n  }\n  return nan_value;\n}\n\n#endif\n\n/** @} SpecialQuantities */\n\n/*************************************************************************\n * For test purposes.\n *\n * Add the following compiler option to include this test code.\n *\n *  Unix : -DSTANDALONE\n *  VMS  : /DEFINE=(STANDALONE)\n */\n#if defined(STANDALONE)\n# include <stdio.h>\n\nstatic TRIO_CONST char *\ngetClassification\nTRIO_ARGS1((type),\n\t   int type)\n{\n  switch (type) {\n  case TRIO_FP_INFINITE:\n    return \"FP_INFINITE\";\n  case TRIO_FP_NAN:\n    return \"FP_NAN\";\n  case TRIO_FP_NORMAL:\n    return \"FP_NORMAL\";\n  case TRIO_FP_SUBNORMAL:\n    return \"FP_SUBNORMAL\";\n  case TRIO_FP_ZERO:\n    return \"FP_ZERO\";\n  default:\n    return \"FP_UNKNOWN\";\n  }\n}\n\nstatic void\nprint_class\nTRIO_ARGS2((prefix, number),\n\t   TRIO_CONST char *prefix,\n\t   double number)\n{\n  printf(\"%-6s: %s %-15s %g\\n\",\n\t prefix,\n\t trio_signbit(number) ? \"-\" : \"+\",\n\t getClassification(trio_fpclassify(number)),\n\t number);\n}\n\nint main(TRIO_NOARGS)\n{\n  double my_nan;\n  double my_pinf;\n  double my_ninf;\n# if defined(TRIO_PLATFORM_UNIX)\n  void (*signal_handler) TRIO_PROTO((int));\n# endif\n\n  my_nan = trio_nan();\n  my_pinf = trio_pinf();\n  my_ninf = trio_ninf();\n\n  print_class(\"Nan\", my_nan);\n  print_class(\"PInf\", my_pinf);\n  print_class(\"NInf\", my_ninf);\n  print_class(\"PZero\", 0.0);\n  print_class(\"NZero\", -0.0);\n  print_class(\"PNorm\", 1.0);\n  print_class(\"NNorm\", -1.0);\n  print_class(\"PSub\", 1.01e-307 - 1.00e-307);\n  print_class(\"NSub\", 1.00e-307 - 1.01e-307);\n  \n  printf(\"NaN : %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\\n\",\n\t my_nan,\n\t ((unsigned char *)&my_nan)[0],\n\t ((unsigned char *)&my_nan)[1],\n\t ((unsigned char *)&my_nan)[2],\n\t ((unsigned char *)&my_nan)[3],\n\t ((unsigned char *)&my_nan)[4],\n\t ((unsigned char *)&my_nan)[5],\n\t ((unsigned char *)&my_nan)[6],\n\t ((unsigned char *)&my_nan)[7],\n\t trio_isnan(my_nan), trio_isinf(my_nan), trio_isfinite(my_nan));\n  printf(\"PInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\\n\",\n\t my_pinf,\n\t ((unsigned char *)&my_pinf)[0],\n\t ((unsigned char *)&my_pinf)[1],\n\t ((unsigned char *)&my_pinf)[2],\n\t ((unsigned char *)&my_pinf)[3],\n\t ((unsigned char *)&my_pinf)[4],\n\t ((unsigned char *)&my_pinf)[5],\n\t ((unsigned char *)&my_pinf)[6],\n\t ((unsigned char *)&my_pinf)[7],\n\t trio_isnan(my_pinf), trio_isinf(my_pinf), trio_isfinite(my_pinf));\n  printf(\"NInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\\n\",\n\t my_ninf,\n\t ((unsigned char *)&my_ninf)[0],\n\t ((unsigned char *)&my_ninf)[1],\n\t ((unsigned char *)&my_ninf)[2],\n\t ((unsigned char *)&my_ninf)[3],\n\t ((unsigned char *)&my_ninf)[4],\n\t ((unsigned char *)&my_ninf)[5],\n\t ((unsigned char *)&my_ninf)[6],\n\t ((unsigned char *)&my_ninf)[7],\n\t trio_isnan(my_ninf), trio_isinf(my_ninf), trio_isfinite(my_ninf));\n  \n# if defined(TRIO_PLATFORM_UNIX)\n  signal_handler = signal(SIGFPE, SIG_IGN);\n# endif\n  \n  my_pinf = DBL_MAX + DBL_MAX;\n  my_ninf = -my_pinf;\n  my_nan = my_pinf / my_pinf;\n\n# if defined(TRIO_PLATFORM_UNIX)\n  signal(SIGFPE, signal_handler);\n# endif\n  \n  printf(\"NaN : %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\\n\",\n\t my_nan,\n\t ((unsigned char *)&my_nan)[0],\n\t ((unsigned char *)&my_nan)[1],\n\t ((unsigned char *)&my_nan)[2],\n\t ((unsigned char *)&my_nan)[3],\n\t ((unsigned char *)&my_nan)[4],\n\t ((unsigned char *)&my_nan)[5],\n\t ((unsigned char *)&my_nan)[6],\n\t ((unsigned char *)&my_nan)[7],\n\t trio_isnan(my_nan), trio_isinf(my_nan), trio_isfinite(my_nan));\n  printf(\"PInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\\n\",\n\t my_pinf,\n\t ((unsigned char *)&my_pinf)[0],\n\t ((unsigned char *)&my_pinf)[1],\n\t ((unsigned char *)&my_pinf)[2],\n\t ((unsigned char *)&my_pinf)[3],\n\t ((unsigned char *)&my_pinf)[4],\n\t ((unsigned char *)&my_pinf)[5],\n\t ((unsigned char *)&my_pinf)[6],\n\t ((unsigned char *)&my_pinf)[7],\n\t trio_isnan(my_pinf), trio_isinf(my_pinf), trio_isfinite(my_pinf));\n  printf(\"NInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\\n\",\n\t my_ninf,\n\t ((unsigned char *)&my_ninf)[0],\n\t ((unsigned char *)&my_ninf)[1],\n\t ((unsigned char *)&my_ninf)[2],\n\t ((unsigned char *)&my_ninf)[3],\n\t ((unsigned char *)&my_ninf)[4],\n\t ((unsigned char *)&my_ninf)[5],\n\t ((unsigned char *)&my_ninf)[6],\n\t ((unsigned char *)&my_ninf)[7],\n\t trio_isnan(my_ninf), trio_isinf(my_ninf), trio_isfinite(my_ninf));\n  \n  return 0;\n}\n#endif\n"
  },
  {
    "path": "src/sdk/src/libc/src/trio/trionan.h",
    "content": "\n\n#ifndef TRIO_TRIONAN_H\n#define TRIO_TRIONAN_H\n\n#include \"triodef.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#if !defined(TRIO_PUBLIC_NAN)\n# if !defined(TRIO_PUBLIC)\n#  define TRIO_PUBLIC\n# endif\n# define TRIO_PUBLIC_NAN TRIO_PUBLIC\n#endif\n  \nenum {\n  TRIO_FP_INFINITE,\n  TRIO_FP_NAN,\n  TRIO_FP_NORMAL,\n  TRIO_FP_SUBNORMAL,\n  TRIO_FP_ZERO\n};\n\n/*************************************************************************\n * Dependencies\n */\n\n#if defined(TRIO_EMBED_NAN)\n\n/*\n * The application that trionan is embedded in must define which functions\n * it uses.\n *\n * The following resolves internal dependencies.\n */\n  \n# if defined(TRIO_FUNC_ISNAN) \\\n  || defined(TRIO_FUNC_ISINF)\n#  if !defined(TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT)\n#   define TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT\n#  endif\n# endif\n\n# if defined(TRIO_FUNC_NAN)\n#  if !defined(TRIO_FUNC_PINF)\n#   define TRIO_FUNC_PINF\n#  endif\n# endif\n  \n# if defined(TRIO_FUNC_NINF)\n#  if !defined(TRIO_FUNC_PINF)\n#   define TRIO_FUNC_PINF\n#  endif\n# endif\n\n#else\n\n/*\n * When trionan is not embedded all all functions are defined.\n */\n  \n# define TRIO_FUNC_NAN\n# define TRIO_FUNC_PINF\n# define TRIO_FUNC_NINF\n# define TRIO_FUNC_NZERO\n# define TRIO_FUNC_ISNAN\n# define TRIO_FUNC_ISINF\n# define TRIO_FUNC_ISFINITE\n# define TRIO_FUNC_SIGNBIT\n# define TRIO_FUNC_FPCLASSIFY\n# define TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT\n  \n#endif\n\n/*************************************************************************\n * Functions\n */\n\n/*\n * Return NaN (Not-a-Number).\n */\n#if defined(TRIO_FUNC_NAN)\nTRIO_PUBLIC_NAN double\ntrio_nan\nTRIO_PROTO((void));\n#endif\n\n/*\n * Return positive infinity.\n */\n#if defined(TRIO_FUNC_PINF)\nTRIO_PUBLIC_NAN double\ntrio_pinf\nTRIO_PROTO((void));\n#endif\n\n/*\n * Return negative infinity.\n */\n#if defined(TRIO_FUNC_NINF)\nTRIO_PUBLIC_NAN double\ntrio_ninf\nTRIO_PROTO((void));\n#endif\n\n/*\n * Return negative zero.\n */\n#if defined(TRIO_FUNC_NZERO)\nTRIO_PUBLIC_NAN double\ntrio_nzero\nTRIO_PROTO((TRIO_NOARGS));\n#endif\n\n/*\n * If number is a NaN return non-zero, otherwise return zero.\n */\n#if defined(TRIO_FUNC_ISNAN)\nTRIO_PUBLIC_NAN int\ntrio_isnan\nTRIO_PROTO((double number));\n#endif\n\n/*\n * If number is positive infinity return 1, if number is negative\n * infinity return -1, otherwise return 0.\n */\n#if defined(TRIO_FUNC_ISINF)\nTRIO_PUBLIC_NAN int\ntrio_isinf\nTRIO_PROTO((double number));\n#endif\n\n/*\n * If number is finite return non-zero, otherwise return zero.\n */\n#if defined(TRIO_FUNC_ISFINITE)\nTRIO_PUBLIC_NAN int\ntrio_isfinite\nTRIO_PROTO((double number));\n#endif\n\n#if defined(TRIO_FUNC_SIGNBIT)\nTRIO_PUBLIC_NAN int\ntrio_signbit\nTRIO_PROTO((double number));\n#endif\n\n#if defined(TRIO_FUNC_FPCLASSIFY)\nTRIO_PUBLIC_NAN int\ntrio_fpclassify\nTRIO_PROTO((double number));\n#endif\n\n#if defined(TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT)\nTRIO_PUBLIC_NAN int\ntrio_fpclassify_and_signbit\nTRIO_PROTO((double number, int *is_negative));\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* TRIO_TRIONAN_H */\n"
  },
  {
    "path": "src/sdk/src/libc/src/trio/triop.h",
    "content": "\n\n#ifndef TRIO_TRIOP_H\n#define TRIO_TRIOP_H\n\n#include \"triodef.h\"\n\n#include <stdlib.h>\n#if defined(TRIO_COMPILER_ANCIENT)\n# include <varargs.h>\n#else\n# include <stdarg.h>\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*************************************************************************\n * Supported standards\n */\n\n/*\n * TRIO_C99 (=0 or =1)\n *\n * Define this to 0 to disable C99 format specifier extensions, or\n * define to 1 to enable them.  The format specifiers that are\n * disabled by this switch are labelled with [C99] in the format\n * specifier documentation.\n */\n#if !defined(TRIO_C99)\n# define TRIO_C99 1\n#endif\n\n/*\n * TRIO_BSD (=0 or =1)\n *\n * Define this to 0 to disable BSD format specifier extensions, or\n * define to 1 to enable them.  The format specifiers that are\n * disabled by this switch are labelled with [BSD] in the format\n * specifier documentation.\n */\n#if !defined(TRIO_BSD)\n# define TRIO_BSD 1\n#endif\n\n/*\n * TRIO_GNU (=0 or =1)\n *\n * Define this to 0 to disable GNU format specifier extensions, or\n * define to 1 to enable them.  The format specifiers that are\n * disabled by this switch are labelled with [GNU] in the format\n * specifier documentation.\n */\n#if !defined(TRIO_GNU)\n# define TRIO_GNU 1\n#endif\n\n/*\n * TRIO_MISC (=0 or =1)\n *\n * Define this to 0 to disable miscellaneous format specifier\n * extensions, or define to 1 to enable them.  The format specifiers\n * that are disabled by this switch are labelled with [MISC] in the\n * format specifier documentation.\n */\n#if !defined(TRIO_MISC)\n# define TRIO_MISC 1\n#endif\n\n/*\n * TRIO_UNIX98 (=0 or =1)\n *\n * Define this to 0 to disable UNIX98 format specifier extensions,\n * or define to 1 to enable them.  The format specifiers that are\n * disabled by this switch are labelled with [UNIX98] in the format\n * specifier documentation.\n */\n#if !defined(TRIO_UNIX98)\n# define TRIO_UNIX98 1\n#endif\n  \n/*\n * TRIO_MICROSOFT (=0 or =1)\n *\n * Define this to 0 to disable Microsoft Visual C format specifier\n * extensions, or define to 1 to enable them.  The format specifiers\n * that are disabled by this switch are labelled with [MSVC] in the\n * format specifier documentation.\n */\n#if !defined(TRIO_MICROSOFT)\n# define TRIO_MICROSOFT 1\n#endif\n\n/*\n * TRIO_EXTENSION (=0 or =1)\n *\n * Define this to 0 to disable Trio-specific extensions, or define\n * to 1 to enable them.  This has two effects: it controls whether\n * or not the Trio user-defined formating mechanism\n * (trio_register() etc) is supported, and it enables or disables\n * Trio's own format specifier extensions.  The format specifiers\n * that are disabled by this switch are labelled with [TRIO] in\n * the format specifier documentation.\n */\n#if !defined(TRIO_EXTENSION)\n# define TRIO_EXTENSION 1\n#endif\n\n/*\n * TRIO_DEPRECATED (=0 or =1)\n *\n * Define this to 0 to disable deprecated functionality, or define\n * to 1 to enable them.\n */\n#if !defined(TRIO_DEPRECATED)\n# define TRIO_DEPRECATED 1\n#endif\n\n/*************************************************************************\n * Features\n */\n\n#if defined(TRIO_SNPRINTF_ONLY)\n# define TRIO_FEATURE_SCANF 0\n# define TRIO_FEATURE_FILE 0\n# define TRIO_FEATURE_STDIO 0\n# define TRIO_FEATURE_FD 0\n# define TRIO_FEATURE_DYNAMICSTRING 0\n# define TRIO_FEATURE_CLOSURE 0\n# define TRIO_FEATURE_STRERR 0\n# define TRIO_FEATURE_LOCALE 0\n# define TRIO_EMBED_NAN 1\n# define TRIO_EMBED_STRING 1\n#endif\n  \n/*\n * TRIO_FEATURE_SCANF (=0 or =1)\n *\n * Define this to 0 to disable all the scanf() variants, or define to 1\n * to enable them.\n */\n#if !defined(TRIO_FEATURE_SCANF)\n# define TRIO_FEATURE_SCANF 1\n#endif\n  \n/*\n * TRIO_FEATURE_FILE (=0 or =1)\n *\n * Define this to 0 to disable compilation of the trio_fprintf() and\n * trio_fscanf() family of functions, or define to 1 to enable them.\n *\n * This may be useful on an embedded platform with no filesystem.\n * Note that trio_printf() uses fwrite to write to stdout, so if you\n * do not have an implementation of fwrite() at all then you must also\n * define TRIO_FEATURE_STDIO to 0.\n */\n#if !defined(TRIO_FEATURE_FILE)\n# define TRIO_FEATURE_FILE 1\n#endif\n\n/*\n * TRIO_FEATURE_STDIO (=0 or =1)\n *\n * Define this to 0 to disable compilation of the trio_printf() and\n * trio_scanf() family of functions, or define to 1 to enable them.\n *\n * This may be useful on an embedded platform with no standard I/O.\n */\n#if !defined(TRIO_FEATURE_STDIO)\n# define TRIO_FEATURE_STDIO 1\n#endif\n\n/*\n * TRIO_FEATURE_FD (=0 or =1)\n *\n * Define this to 0 to disable compilation of the trio_dprintf() and\n * trio_dscanf() family of functions, or define to 1 to enable them.\n *\n * This may be useful on an embedded platform with no filesystem, or on\n * a platform that supports file I/O using FILE* but not using raw file\n * descriptors.\n */\n#if !defined(TRIO_FEATURE_FD)\n# define TRIO_FEATURE_FD 1\n#endif\n\n/*\n * TRIO_FEATURE_DYNAMICSTRING (=0 or =1)\n *\n * Define this to 0 to disable compilation of the trio_aprintf() \n * family of functions, or define to 1 to enable them.\n *\n * If you define both this and TRIO_MINIMAL to 0, then Trio will never\n * call malloc or free.\n */\n#if !defined(TRIO_FEATURE_DYNAMICSTRING)\n# define TRIO_FEATURE_DYNAMICSTRING 1\n#endif\n\n/*\n * TRIO_FEATURE_CLOSURE (=0 or =1)\n *\n * Define this to 0 to disable compilation of the trio_cprintf() and\n * trio_cscanf() family of functions, or define to 1 to enable them.\n *\n * These functions are rarely needed. This saves a (small) amount of code.\n */\n#if !defined(TRIO_FEATURE_CLOSURE)\n# define TRIO_FEATURE_CLOSURE 1\n#endif\n\n/*\n * TRIO_FEATURE_ERRORCODE (=0 or =1)\n *\n * Define this to 0 to return -1 from the print and scan function on\n * error, or define to 1 to return a negative number with debugging\n * information as part of the return code.\n *\n * If enabled, the return code will be a negative number, which encodes\n * an error code and an error location. These can be decoded with the\n * TRIO_ERROR_CODE and TRIO_ERROR_POSITION macros.\n */\n#if defined(TRIO_ERRORS)\n# define TRIO_FEATURE_ERRORCODE TRIO_ERRORS\n#endif\n#if !defined(TRIO_FEATURE_ERRORCODE)\n# define TRIO_FEATURE_ERRORCODE 1\n#endif\n\n/*\n * TRIO_FEATURE_STRERR (=0 or =1)\n *\n * Define this to 0 if you do not use trio_strerror(), or define to 1 if\n * you do use it.\n *\n * This saves a (small) amount of code.\n */\n#if !defined(TRIO_FEATURE_STRERR)\n# define TRIO_FEATURE_STRERR 1\n#endif\n\n/*\n * TRIO_FEATURE_FLOAT (=0 or =1)\n *\n * Define this to 0 to disable all floating-point support, or define\n * to 1 to enable it.\n *\n * This is useful in restricted embedded platforms that do not support\n * floating-point.  Obviously you cannot use floating-point format\n * specifiers if you define this.\n *\n * Do not compile trionan.c if you disable this.\n */\n#if !defined(TRIO_FEATURE_FLOAT)\n# define TRIO_FEATURE_FLOAT 1\n#endif\n\n/*\n * TRIO_FEATURE_LOCALE (=0 or =1)\n *\n * Define this to 0 to disable customized locale support, or define\n * to 1 to enable it.\n *\n * This saves a (small) amount of code.\n */\n#if !defined(TRIO_FEATURE_LOCALE)\n# define TRIO_FEATURE_LOCALE 1\n#endif\n\n/*\n * TRIO_MINIMAL\n *\n * Define this to disable building the public trionan.h and triostr.h.\n * If you define this, then you must not compile trionan.c and triostr.c\n * separately.\n */\n#if defined(TRIO_MINIMAL)\n# if !defined(TRIO_EMBED_NAN)\n#  define TRIO_EMBED_NAN\n# endif\n# if !defined(TRIO_EMBED_STRING)\n#  define TRIO_EMBED_STRING\n# endif\n#endif\n  \n/* Does not work yet. Do not enable */\n#ifndef TRIO_FEATURE_WIDECHAR\n# define TRIO_FEATURE_WIDECHAR 0\n#endif\n\n/*************************************************************************\n * Mapping standards to internal features\n */\n\n#if !defined(TRIO_FEATURE_HEXFLOAT)\n# define TRIO_FEATURE_HEXFLOAT (TRIO_C99 && TRIO_FEATURE_FLOAT)\n#endif\n\n#if !defined(TRIO_FEATURE_LONGDOUBLE)\n# define TRIO_FEATURE_LONGDOUBLE TRIO_FEATURE_FLOAT\n#endif\n\n#if !defined(TRIO_FEATURE_ERRNO)\n# define TRIO_FEATURE_ERRNO TRIO_GNU\n#endif\n\n#if !defined(TRIO_FEATURE_QUAD)\n# define TRIO_FEATURE_QUAD (TRIO_BSD || TRIO_GNU)\n#endif\n\n#if !defined(TRIO_FEATURE_SIZE_T)\n# define TRIO_FEATURE_SIZE_T TRIO_C99\n#endif\n\n#if !defined(TRIO_FEATURE_SIZE_T_UPPER)\n# define TRIO_FEATURE_SIZE_T_UPPER TRIO_GNU\n#endif\n  \n#if !defined(TRIO_FEATURE_PTRDIFF_T)\n# define TRIO_FEATURE_PTRDIFF_T TRIO_C99\n#endif\n\n#if !defined(TRIO_FEATURE_INTMAX_T)\n# define TRIO_FEATURE_INTMAX_T TRIO_C99\n#endif\n\n#if !defined(TRIO_FEATURE_FIXED_SIZE)\n# define TRIO_FEATURE_FIXED_SIZE TRIO_MICROSOFT\n#endif\n\n#if !defined(TRIO_FEATURE_POSITIONAL)\n# define TRIO_FEATURE_POSITIONAL TRIO_UNIX98\n#endif\n\n#if !defined(TRIO_FEATURE_USER_DEFINED)\n# define TRIO_FEATURE_USER_DEFINED TRIO_EXTENSION\n#endif\n\n#if !defined(TRIO_FEATURE_BINARY)\n# define TRIO_FEATURE_BINARY TRIO_EXTENSION\n#endif\n\n#if !defined(TRIO_FEATURE_QUOTE)\n# define TRIO_FEATURE_QUOTE TRIO_EXTENSION\n#endif\n  \n#if !defined(TRIO_FEATURE_STICKY)\n# define TRIO_FEATURE_STICKY TRIO_EXTENSION\n#endif\n  \n#if !defined(TRIO_FEATURE_VARSIZE)\n# define TRIO_FEATURE_VARSIZE TRIO_EXTENSION\n#endif\n\n#if !defined(TRIO_FEATURE_ROUNDING)\n# define TRIO_FEATURE_ROUNDING TRIO_EXTENSION\n#endif\n  \n/*************************************************************************\n * Memory handling\n */\n#ifndef TRIO_MALLOC\n# define TRIO_MALLOC(n) malloc(n)\n#endif\n#ifndef TRIO_REALLOC\n# define TRIO_REALLOC(x,n) realloc((x),(n))\n#endif\n#ifndef TRIO_FREE\n# define TRIO_FREE(x) free(x)\n#endif\n\n\n/*************************************************************************\n * User-defined specifiers\n */\n\ntypedef int (*trio_callback_t) TRIO_PROTO((trio_pointer_t));\n\ntrio_pointer_t trio_register TRIO_PROTO((trio_callback_t callback, const char *name));\nvoid trio_unregister TRIO_PROTO((trio_pointer_t handle));\n\nTRIO_CONST char *trio_get_format TRIO_PROTO((trio_pointer_t ref));\ntrio_pointer_t trio_get_argument TRIO_PROTO((trio_pointer_t ref));\n\n/* Modifiers */\nint  trio_get_width TRIO_PROTO((trio_pointer_t ref));\nvoid trio_set_width TRIO_PROTO((trio_pointer_t ref, int width));\nint  trio_get_precision TRIO_PROTO((trio_pointer_t ref));\nvoid trio_set_precision TRIO_PROTO((trio_pointer_t ref, int precision));\nint  trio_get_base TRIO_PROTO((trio_pointer_t ref));\nvoid trio_set_base TRIO_PROTO((trio_pointer_t ref, int base));\nint  trio_get_padding TRIO_PROTO((trio_pointer_t ref));\nvoid trio_set_padding TRIO_PROTO((trio_pointer_t ref, int is_padding));\nint  trio_get_short TRIO_PROTO((trio_pointer_t ref)); /* h */\nvoid trio_set_shortshort TRIO_PROTO((trio_pointer_t ref, int is_shortshort));\nint  trio_get_shortshort TRIO_PROTO((trio_pointer_t ref)); /* hh */\nvoid trio_set_short TRIO_PROTO((trio_pointer_t ref, int is_short));\nint  trio_get_long TRIO_PROTO((trio_pointer_t ref)); /* l */\nvoid trio_set_long TRIO_PROTO((trio_pointer_t ref, int is_long));\nint  trio_get_longlong TRIO_PROTO((trio_pointer_t ref)); /* ll */\nvoid trio_set_longlong TRIO_PROTO((trio_pointer_t ref, int is_longlong));\nint  trio_get_longdouble TRIO_PROTO((trio_pointer_t ref)); /* L */\nvoid trio_set_longdouble TRIO_PROTO((trio_pointer_t ref, int is_longdouble));\nint  trio_get_alternative TRIO_PROTO((trio_pointer_t ref)); /* # */\nvoid trio_set_alternative TRIO_PROTO((trio_pointer_t ref, int is_alternative));\nint  trio_get_alignment TRIO_PROTO((trio_pointer_t ref)); /* - */\nvoid trio_set_alignment TRIO_PROTO((trio_pointer_t ref, int is_leftaligned));\nint  trio_get_spacing TRIO_PROTO((trio_pointer_t ref)); /*  TRIO_PROTO((space) */\nvoid trio_set_spacing TRIO_PROTO((trio_pointer_t ref, int is_space));\nint  trio_get_sign TRIO_PROTO((trio_pointer_t ref)); /* + */\nvoid trio_set_sign TRIO_PROTO((trio_pointer_t ref, int is_showsign));\n#if TRIO_FEATURE_QUOTE\nint  trio_get_quote TRIO_PROTO((trio_pointer_t ref)); /* ' */\nvoid trio_set_quote TRIO_PROTO((trio_pointer_t ref, int is_quote));\n#endif\nint  trio_get_upper TRIO_PROTO((trio_pointer_t ref));\nvoid trio_set_upper TRIO_PROTO((trio_pointer_t ref, int is_upper));\n#if TRIO_FEATURE_INTMAX_T\nint  trio_get_largest TRIO_PROTO((trio_pointer_t ref)); /* j */\nvoid trio_set_largest TRIO_PROTO((trio_pointer_t ref, int is_largest));\n#endif\n#if TRIO_FEATURE_PTRDIFF_T\nint  trio_get_ptrdiff TRIO_PROTO((trio_pointer_t ref)); /* t */\nvoid trio_set_ptrdiff TRIO_PROTO((trio_pointer_t ref, int is_ptrdiff));\n#endif\n#if TRIO_FEATURE_SIZE_T\nint  trio_get_size TRIO_PROTO((trio_pointer_t ref)); /* z / Z */\nvoid trio_set_size TRIO_PROTO((trio_pointer_t ref, int is_size));\n#endif\n\n/* Printing */\nint trio_print_ref TRIO_PROTO((trio_pointer_t ref, const char *format, ...));\nint trio_vprint_ref TRIO_PROTO((trio_pointer_t ref, const char *format, va_list args));\nint trio_printv_ref TRIO_PROTO((trio_pointer_t ref, const char *format, trio_pointer_t *args));\n\nvoid trio_print_int TRIO_PROTO((trio_pointer_t ref, int number));\nvoid trio_print_uint TRIO_PROTO((trio_pointer_t ref, unsigned int number));\n/*  void trio_print_long TRIO_PROTO((trio_pointer_t ref, long number)); */\n/*  void trio_print_ulong TRIO_PROTO((trio_pointer_t ref, unsigned long number)); */\nvoid trio_print_double TRIO_PROTO((trio_pointer_t ref, double number));\nvoid trio_print_string TRIO_PROTO((trio_pointer_t ref, char *string));\nvoid trio_print_pointer TRIO_PROTO((trio_pointer_t ref, trio_pointer_t pointer));\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /* TRIO_TRIOP_H */\n"
  },
  {
    "path": "src/sdk/src/libc/src/trio/triostr.c",
    "content": "\n\n#if defined(HAVE_CONFIG_H)\n# include <config.h>\n#endif\n#include <assert.h>\n#include <stdlib.h>\n#include <string.h>\n#include <ctype.h>\n#include \"triodef.h\"\n#include \"triostr.h\"\n#if defined(TRIO_FUNC_TO_LONG_DOUBLE)\n# define USE_MATH\n#endif\n#if defined(USE_MATH)\n# include <math.h>\n#endif\n\n/*************************************************************************\n * Definitions\n */\n\n#if !defined(TRIO_PUBLIC_STRING)\n# define TRIO_PUBLIC_STRING TRIO_PUBLIC\n#endif\n#if !defined(TRIO_PRIVATE_STRING)\n# define TRIO_PRIVATE_STRING TRIO_PRIVATE\n#endif\n\n#if !defined(NULL)\n# define NULL 0\n#endif\n#if !defined(NIL)\n# define NIL ((char)0)\n#endif\n#if !defined(FALSE)\n# define FALSE (1 == 0)\n# define TRUE (! FALSE)\n#endif\n#if !defined(BOOLEAN_T)\n# define BOOLEAN_T int\n#endif\n\n#if defined(USE_MATH)\n# if defined(PREDEF_STANDARD_C99)\n#  if defined(TRIO_COMPILER_DECC)\n#   if (TRIO_COMPILER_DECC - 0 > 80000000)\n/*\n * The OSF/1 runtime that comes with the DECC compiler does not support\n * hexfloats conversion.\n */\n#    define USE_STRTOD\n#    define USE_STRTOF\n#   endif\n#  else\n#   define USE_STRTOD\n#   define USE_STRTOF\n#  endif\n# else\n#  if defined(TRIO_COMPILER_VISUALC)\n#   define USE_STRTOD\n#  endif\n#endif\n#endif\n\n#if defined(TRIO_PLATFORM_UNIX)\n# if defined(PREDEF_STANDARD_UNIX95)\n#  define USE_STRCASECMP\n#  define USE_STRNCASECMP\n# endif\n# if defined(TRIO_PLATFORM_SUNOS)\n#  define USE_SYS_ERRLIST\n# else\n#  define USE_STRERROR\n# endif\n# if defined(TRIO_PLATFORM_QNX)\n#  define strcasecmp(x,y) stricmp(x,y)\n#  define strncasecmp(x,y,n) strnicmp(x,y,n)\n# endif\n#endif\n\n#if defined(TRIO_PLATFORM_WIN32)\n# define USE_STRCASECMP\n# if defined(TRIO_PLATFORM_WINCE)\n#  define strcasecmp(x,y) _stricmp(x,y)\n# else\n#  define strcasecmp(x,y) strcmpi(x,y)\n# endif\n#endif\n\n#if !defined(HAVE_CONFIG_H)\n# if !(defined(TRIO_PLATFORM_SUNOS))\n#  define HAVE_TOLOWER\n#  define HAVE_TOUPPER\n# endif\n#endif\n\n#if defined(USE_MATH)\n# if !defined(HAVE_POWL)\n#  if defined(PREDEF_STANDARD_C99) \\\n   || defined(PREDEF_STANDARD_UNIX03)\n#   define HAVE_POWL\n#  else\n#   if defined(TRIO_COMPILER_VISUALC)\n#    if defined(powl)\n#     define HAVE_POWL\n#    endif\n#   endif\n#  endif\n# endif\n#endif\n\n#if defined(HAVE_POWL)\n# define trio_powl(x,y) powl((x),(y))\n#else\n# define trio_powl(x,y) pow((double)(x),(double)(y))\n#endif\n\n#if defined(TRIO_FUNC_TO_UPPER) \\\n || (defined(TRIO_FUNC_EQUAL) && !defined(USE_STRCASECMP)) \\\n || (defined(TRIO_FUNC_EQUAL_MAX) && !defined(USE_STRNCASECMP)) \\\n || defined(TRIO_FUNC_MATCH) \\\n || defined(TRIO_FUNC_TO_LONG_DOUBLE) \\\n || defined(TRIO_FUNC_UPPER)\n# define TRIO_FUNC_INTERNAL_TO_UPPER\n#endif\n\n/*************************************************************************\n * Structures\n */\n\nstruct _trio_string_t\n{\n  char *content;\n  size_t length;\n  size_t allocated;\n};\n\n/*************************************************************************\n * Constants\n */\n\n#if !defined(TRIO_EMBED_STRING)\nstatic TRIO_CONST char rcsid[] = \"@(#)$Id: triostr.c,v 1.34 2008/11/09 12:17:39 breese Exp $\";\n#endif\n\n/*************************************************************************\n * Static String Functions\n */\n\n#if defined(TRIO_DOCUMENTATION)\n# include \"doc/doc_static.h\"\n#endif\n/** @addtogroup StaticStrings\n    @{\n*/\n\n/*\n * internal_duplicate_max\n */\n#if defined(TRIO_FUNC_DUPLICATE) \\\n || defined(TRIO_FUNC_DUPLICATE_MAX) \\\n || defined(TRIO_FUNC_STRING_DUPLICATE) \\\n || defined(TRIO_FUNC_XSTRING_DUPLICATE)\n\nTRIO_PRIVATE_STRING char *\ninternal_duplicate_max\nTRIO_ARGS2((source, size),\n\t   TRIO_CONST char *source,\n\t   size_t size)\n{\n  char *target;\n\n  assert(source);\n\n  /* Make room for string plus a terminating zero */\n  size++;\n  target = trio_create(size);\n  if (target)\n    {\n      trio_copy_max(target, size, source);\n    }\n  return target;\n}\n\n#endif\n\n/*\n * internal_string_alloc\n */\n#if defined(TRIO_FUNC_STRING_CREATE) \\\n || defined(TRIO_FUNC_STRING_DUPLICATE) \\\n || defined(TRIO_FUNC_XSTRING_DUPLICATE)\n\nTRIO_PRIVATE_STRING trio_string_t *\ninternal_string_alloc(TRIO_NOARGS)\n{\n  trio_string_t *self;\n  \n  self = (trio_string_t *)TRIO_MALLOC(sizeof(trio_string_t));\n  if (self)\n    {\n      self->content = NULL;\n      self->length = 0;\n      self->allocated = 0;\n    }\n  return self;\n}\n\n#endif\n\n/*\n * internal_string_grow\n *\n * The size of the string will be increased by 'delta' characters. If\n * 'delta' is zero, the size will be doubled.\n */\n#if defined(TRIO_FUNC_STRING_CREATE) \\\n || defined(TRIO_FUNC_STRING_APPEND) \\\n || defined(TRIO_FUNC_XSTRING_APPEND) \\\n || defined(TRIO_FUNC_XSTRING_APPEND_CHAR)\n\nTRIO_PRIVATE_STRING BOOLEAN_T\ninternal_string_grow\nTRIO_ARGS2((self, delta),\n\t   trio_string_t *self,\n\t   size_t delta)\n{\n  BOOLEAN_T status = FALSE;\n  char *new_content;\n  size_t new_size;\n\n  new_size = (delta == 0)\n    ? ( (self->allocated == 0) ? 1 : self->allocated * 2 )\n    : self->allocated + delta;\n  \n  new_content = (char *)TRIO_REALLOC(self->content, new_size);\n  if (new_content)\n    {\n      self->content = new_content;\n      self->allocated = new_size;\n      status = TRUE;\n    }\n  return status;\n}\n\n#endif\n\n/*\n * internal_string_grow_to\n *\n * The size of the string will be increased to 'length' plus one characters.\n * If 'length' is less than the original size, the original size will be\n * used (that is, the size of the string is never decreased).\n */\n#if defined(TRIO_FUNC_STRING_APPEND) \\\n || defined(TRIO_FUNC_XSTRING_APPEND)\n\nTRIO_PRIVATE_STRING BOOLEAN_T\ninternal_string_grow_to\nTRIO_ARGS2((self, length),\n\t   trio_string_t *self,\n\t   size_t length)\n{\n  length++; /* Room for terminating zero */\n  return (self->allocated < length)\n    ? internal_string_grow(self, length - self->allocated)\n    : TRUE;\n}\n\n#endif\n\n#if defined(TRIO_FUNC_INTERNAL_TO_UPPER)\n\nTRIO_PRIVATE_STRING TRIO_INLINE int\ninternal_to_upper\nTRIO_ARGS1((source),\n\t   int source)\n{\n# if defined(HAVE_TOUPPER)\n  \n  return toupper(source);\n  \n# else\n\n  /* Does not handle locales or non-contiguous alphabetic characters */\n  return ((source >= (int)'a') && (source <= (int)'z'))\n    ? source - 'a' + 'A'\n    : source;\n  \n# endif\n}\n\n#endif\n\n\n/**\n   Create new string.\n\n   @param size Size of new string.\n   @return Pointer to string, or NULL if allocation failed.\n*/\n#if defined(TRIO_FUNC_CREATE)\n\nTRIO_PUBLIC_STRING char *\ntrio_create\nTRIO_ARGS1((size),\n\t   size_t size)\n{\n  return (char *)TRIO_MALLOC(size);\n}\n\n#endif\n\n/**\n   Destroy string.\n\n   @param string String to be freed.\n*/\n#if defined(TRIO_FUNC_DESTROY)\n\nTRIO_PUBLIC_STRING void\ntrio_destroy\nTRIO_ARGS1((string),\n\t   char *string)\n{\n  if (string)\n    {\n      TRIO_FREE(string);\n    }\n}\n\n#endif\n\n/**\n   Count the number of characters in a string.\n\n   @param string String to measure.\n   @return Number of characters in @p string.\n*/\n#if defined(TRIO_FUNC_LENGTH)\n\nTRIO_PUBLIC_STRING size_t\ntrio_length\nTRIO_ARGS1((string),\n\t   TRIO_CONST char *string)\n{\n  return strlen(string);\n}\n\n#endif\n\n/**\n   Count at most @p max characters in a string.\n\n   @param string String to measure.\n   @param max Maximum number of characters to count.\n   @return The maximum value of @p max and number of characters in @p string.\n*/\n#if defined(TRIO_FUNC_LENGTH)\n\nTRIO_PUBLIC_STRING size_t\ntrio_length_max\nTRIO_ARGS2((string, max),\n\t   TRIO_CONST char *string,\n\t   size_t max)\n{\n  size_t i;\n\n  for (i = 0; i < max; ++i)\n    {\n      if (string[i] == 0)\n\tbreak;\n    }\n  return i;\n}\n\n#endif\n\n/**\n   Append @p source at the end of @p target.\n   \n   @param target Target string.\n   @param source Source string.\n   @return Boolean value indicating success or failure.\n   \n   @pre @p target must point to a memory chunk with sufficient room to\n   contain the @p target string and @p source string.\n   @pre No boundary checking is performed, so insufficient memory will\n   result in a buffer overrun.\n   @post @p target will be zero terminated.\n*/\n#if defined(TRIO_FUNC_APPEND)\n\nTRIO_PUBLIC_STRING int\ntrio_append\nTRIO_ARGS2((target, source),\n\t   char *target,\n\t   TRIO_CONST char *source)\n{\n  assert(target);\n  assert(source);\n  \n  return (strcat(target, source) != NULL);\n}\n\n#endif\n\n/**\n   Append at most @p max characters from @p source to @p target.\n   \n   @param target Target string.\n   @param max Maximum number of characters to append.\n   @param source Source string.\n   @return Boolean value indicating success or failure.\n   \n   @pre @p target must point to a memory chuck with sufficient room to\n   contain the @p target string and the @p source string (at most @p max\n   characters).\n   @pre No boundary checking is performed, so insufficient memory will\n   result in a buffer overrun.\n   @post @p target will be zero terminated.\n*/\n#if defined(TRIO_FUNC_APPEND_MAX)\n\nTRIO_PUBLIC_STRING int\ntrio_append_max\nTRIO_ARGS3((target, max, source),\n\t   char *target,\n\t   size_t max,\n\t   TRIO_CONST char *source)\n{\n  size_t length;\n  \n  assert(target);\n  assert(source);\n\n  length = trio_length(target);\n  \n  if (max > length)\n    {\n      strncat(target, source, max - length - 1);\n    }\n  return TRUE;\n}\n\n#endif\n\n/**\n   Determine if a string contains a substring.\n\n   @param string String to be searched.\n   @param substring String to be found.\n   @return Boolean value indicating success or failure.\n*/\n#if defined(TRIO_FUNC_CONTAINS)\n\nTRIO_PUBLIC_STRING int\ntrio_contains\nTRIO_ARGS2((string, substring),\n\t   TRIO_CONST char *string,\n\t   TRIO_CONST char *substring)\n{\n  assert(string);\n  assert(substring);\n  \n  return (0 != strstr(string, substring));\n}\n\n#endif\n\n/**\n   Copy @p source to @p target.\n   \n   @param target Target string.\n   @param source Source string.\n   @return Boolean value indicating success or failure.\n   \n   @pre @p target must point to a memory chunk with sufficient room to\n   contain the @p source string.\n   @pre No boundary checking is performed, so insufficient memory will\n   result in a buffer overrun.\n   @post @p target will be zero terminated.\n*/\n#if defined(TRIO_FUNC_COPY)\n\nTRIO_PUBLIC_STRING int\ntrio_copy\nTRIO_ARGS2((target, source),\n\t   char *target,\n\t   TRIO_CONST char *source)\n{\n  assert(target);\n  assert(source);\n     \n  (void)strcpy(target, source);\n  return TRUE;\n}\n\n#endif\n\n/**\n   Copy at most @p max characters from @p source to @p target.\n   \n   @param target Target string.\n   @param max Maximum number of characters to append.\n   @param source Source string.\n   @return Boolean value indicating success or failure.\n   \n   @pre @p target must point to a memory chunk with sufficient room to\n   contain the @p source string (at most @p max characters).\n   @pre No boundary checking is performed, so insufficient memory will\n   result in a buffer overrun.\n   @post @p target will be zero terminated.\n*/\n#if defined(TRIO_FUNC_COPY_MAX)\n\nTRIO_PUBLIC_STRING int\ntrio_copy_max\nTRIO_ARGS3((target, max, source),\n\t   char *target,\n\t   size_t max,\n\t   TRIO_CONST char *source)\n{\n  assert(target);\n  assert(source);\n  assert(max > 0); /* Includes != 0 */\n\n  (void)strncpy(target, source, max - 1);\n  target[max - 1] = (char)0;\n  return TRUE;\n}\n\n#endif\n\n/**\n   Duplicate @p source.\n   \n   @param source Source string.\n   @return A copy of the @p source string.\n   \n   @post @p target will be zero terminated.\n*/\n#if defined(TRIO_FUNC_DUPLICATE)\n\nTRIO_PUBLIC_STRING char *\ntrio_duplicate\nTRIO_ARGS1((source),\n\t   TRIO_CONST char *source)\n{\n  return internal_duplicate_max(source, trio_length(source));\n}\n\n#endif\n\n/**\n   Duplicate at most @p max characters of @p source.\n   \n   @param source Source string.\n   @param max Maximum number of characters to duplicate.\n   @return A copy of the @p source string.\n   \n   @post @p target will be zero terminated.\n*/\n#if defined(TRIO_FUNC_DUPLICATE_MAX)\n\nTRIO_PUBLIC_STRING char *\ntrio_duplicate_max\nTRIO_ARGS2((source, max),\n\t   TRIO_CONST char *source,\n\t   size_t max)\n{\n  size_t length;\n\n  assert(source);\n  assert(max > 0);\n\n  length = trio_length(source);\n  if (length > max)\n    {\n      length = max;\n    }\n  return internal_duplicate_max(source, length);\n}\n\n#endif\n\n/**\n   Compare if two strings are equal.\n   \n   @param first First string.\n   @param second Second string.\n   @return Boolean indicating whether the two strings are equal or not.\n   \n   Case-insensitive comparison.\n*/\n#if defined(TRIO_FUNC_EQUAL)\n\nTRIO_PUBLIC_STRING int\ntrio_equal\nTRIO_ARGS2((first, second),\n\t   TRIO_CONST char *first,\n\t   TRIO_CONST char *second)\n{\n  assert(first);\n  assert(second);\n\n  if ((first != NULL) && (second != NULL))\n    {\n# if defined(USE_STRCASECMP)\n      return (0 == strcasecmp(first, second));\n# else\n      while ((*first != NIL) && (*second != NIL))\n\t{\n\t  if (internal_to_upper(*first) != internal_to_upper(*second))\n\t    {\n\t      break;\n\t    }\n\t  first++;\n\t  second++;\n\t}\n      return ((*first == NIL) && (*second == NIL));\n# endif\n    }\n  return FALSE;\n}\n\n#endif\n\n/**\n   Compare if two strings are equal.\n   \n   @param first First string.\n   @param second Second string.\n   @return Boolean indicating whether the two strings are equal or not.\n   \n   Case-sensitive comparison.\n*/\n#if defined(TRIO_FUNC_EQUAL_CASE)\n\nTRIO_PUBLIC_STRING int\ntrio_equal_case\nTRIO_ARGS2((first, second),\n\t   TRIO_CONST char *first,\n\t   TRIO_CONST char *second)\n{\n  assert(first);\n  assert(second);\n\n  if ((first != NULL) && (second != NULL))\n    {\n      return (0 == strcmp(first, second));\n    }\n  return FALSE;\n}\n\n#endif\n\n/**\n   Compare if two strings up until the first @p max characters are equal.\n   \n   @param first First string.\n   @param max Maximum number of characters to compare.\n   @param second Second string.\n   @return Boolean indicating whether the two strings are equal or not.\n   \n   Case-sensitive comparison.\n*/\n#if defined(TRIO_FUNC_EQUAL_CASE_MAX)\n\nTRIO_PUBLIC_STRING int\ntrio_equal_case_max\nTRIO_ARGS3((first, max, second),\n\t   TRIO_CONST char *first,\n\t   size_t max,\n\t   TRIO_CONST char *second)\n{\n  assert(first);\n  assert(second);\n\n  if ((first != NULL) && (second != NULL))\n    {\n      return (0 == strncmp(first, second, max));\n    }\n  return FALSE;\n}\n\n#endif\n\n/**\n   Compare if two strings are equal.\n   \n   @param first First string.\n   @param second Second string.\n   @return Boolean indicating whether the two strings are equal or not.\n\n   Collating characters are considered equal.\n*/\n#if defined(TRIO_FUNC_EQUAL_LOCALE)\n\nTRIO_PUBLIC_STRING int\ntrio_equal_locale\nTRIO_ARGS2((first, second),\n\t   TRIO_CONST char *first,\n\t   TRIO_CONST char *second)\n{\n  assert(first);\n  assert(second);\n\n# if defined(LC_COLLATE)\n  return (strcoll(first, second) == 0);\n# else\n  return trio_equal(first, second);\n# endif\n}\n\n#endif\n\n/**\n   Compare if two strings up until the first @p max characters are equal.\n   \n   @param first First string.\n   @param max Maximum number of characters to compare.\n   @param second Second string.\n   @return Boolean indicating whether the two strings are equal or not.\n   \n   Case-insensitive comparison.\n*/\n#if defined(TRIO_FUNC_EQUAL_MAX)\n\nTRIO_PUBLIC_STRING int\ntrio_equal_max\nTRIO_ARGS3((first, max, second),\n\t   TRIO_CONST char *first,\n\t   size_t max,\n\t   TRIO_CONST char *second)\n{\n  assert(first);\n  assert(second);\n\n  if ((first != NULL) && (second != NULL))\n    {\n# if defined(USE_STRNCASECMP)\n      return (0 == strncasecmp(first, second, max));\n# else\n      /* Not adequately tested yet */\n      size_t cnt = 0;\n      while ((*first != NIL) && (*second != NIL) && (cnt <= max))\n\t{\n\t  if (internal_to_upper(*first) != internal_to_upper(*second))\n\t    {\n\t      break;\n\t    }\n\t  first++;\n\t  second++;\n\t  cnt++;\n\t}\n      return ((cnt == max) || ((*first == NIL) && (*second == NIL)));\n# endif\n    }\n  return FALSE;\n}\n\n#endif\n\n/**\n   Provide a textual description of an error code (errno).\n\n   @param error_number Error number.\n   @return Textual description of @p error_number.\n*/\n#if defined(TRIO_FUNC_ERROR)\n\nTRIO_PUBLIC_STRING TRIO_CONST char *\ntrio_error\nTRIO_ARGS1((error_number),\n\t   int error_number)\n{\n# if defined(USE_STRERROR)\n  \n  return strerror(error_number);\n\n# else\n#  if defined(USE_SYS_ERRLIST)\n\n  extern char *sys_errlist[];\n  extern int sys_nerr;\n\n  return ((error_number < 0) || (error_number >= sys_nerr))\n    ? \"unknown\"\n    : sys_errlist[error_number];\n \n#  else\n  \n  return \"unknown\";\n\n#  endif\n# endif\n}\n\n#endif\n\n/**\n   Format the date/time according to @p format.\n\n   @param target Target string.\n   @param max Maximum number of characters to format.\n   @param format Formatting string.\n   @param datetime Date/time structure.\n   @return Number of formatted characters.\n\n   The formatting string accepts the same specifiers as the standard C\n   function strftime.\n*/\n#if defined(TRIO_FUNC_FORMAT_DATE_MAX)\n\nTRIO_PUBLIC_STRING size_t\ntrio_format_date_max\nTRIO_ARGS4((target, max, format, datetime),\n\t   char *target,\n\t   size_t max,\n\t   TRIO_CONST char *format,\n\t   TRIO_CONST struct tm *datetime)\n{\n  assert(target);\n  assert(format);\n  assert(datetime);\n  assert(max > 0);\n\n  return strftime(target, max, format, datetime);\n}\n\n#endif\n\n/**\n   Calculate a hash value for a string.\n\n   @param string String to be calculated on.\n   @param type Hash function.\n   @return Calculated hash value.\n\n   @p type can be one of the following\n   @li @c TRIO_HASH_PLAIN Plain hash function.\n*/\n#if defined(TRIO_FUNC_HASH)\n\nTRIO_PUBLIC_STRING unsigned long\ntrio_hash\nTRIO_ARGS2((string, type),\n\t   TRIO_CONST char *string,\n\t   int type)\n{\n  unsigned long value = 0L;\n  char ch;\n\n  assert(string);\n  \n  switch (type)\n    {\n    case TRIO_HASH_PLAIN:\n      while ( (ch = *string++) != NIL )\n\t{\n\t  value *= 31;\n\t  value += (unsigned long)ch;\n\t}\n      break;\n    default:\n      assert(FALSE);\n      break;\n    }\n  return value;\n}\n\n#endif\n\n/**\n   Find first occurrence of a character in a string.\n\n   @param string String to be searched.\n   @param character Character to be found.\n   @return A pointer to the found character, or NULL if character was not found.\n */\n#if defined(TRIO_FUNC_INDEX)\n\nTRIO_PUBLIC_STRING char *\ntrio_index\nTRIO_ARGS2((string, character),\n\t   TRIO_CONST char *string,\n\t   int character)\n{\n  assert(string);\n\n  return strchr(string, character);\n}\n\n#endif\n\n/**\n   Find last occurrence of a character in a string.\n\n   @param string String to be searched.\n   @param character Character to be found.\n   @return A pointer to the found character, or NULL if character was not found.\n */\n#if defined(TRIO_FUNC_INDEX_LAST)\n\nTRIO_PUBLIC_STRING char *\ntrio_index_last\nTRIO_ARGS2((string, character),\n\t   TRIO_CONST char *string,\n\t   int character)\n{\n  assert(string);\n\n  return strchr(string, character);\n}\n\n#endif\n\n/**\n   Convert the alphabetic letters in the string to lower-case.\n\n   @param target String to be converted.\n   @return Number of processed characters (converted or not).\n*/\n#if defined(TRIO_FUNC_LOWER)\n\nTRIO_PUBLIC_STRING int\ntrio_lower\nTRIO_ARGS1((target),\n\t   char *target)\n{\n  assert(target);\n\n  return trio_span_function(target, target, trio_to_lower);\n}\n\n#endif\n\n/**\n   Compare two strings using wildcards.\n\n   @param string String to be searched.\n   @param pattern Pattern, including wildcards, to search for.\n   @return Boolean value indicating success or failure.\n\n   Case-insensitive comparison.\n   \n   The following wildcards can be used\n   @li @c * Match any number of characters.\n   @li @c ? Match a single character.\n*/\n#if defined(TRIO_FUNC_MATCH)\n\nTRIO_PUBLIC_STRING int\ntrio_match\nTRIO_ARGS2((string, pattern),\n\t   TRIO_CONST char *string,\n\t   TRIO_CONST char *pattern)\n{\n  assert(string);\n  assert(pattern);\n  \n  for (; ('*' != *pattern); ++pattern, ++string)\n    {\n      if (NIL == *string)\n\t{\n\t  return (NIL == *pattern);\n\t}\n      if ((internal_to_upper((int)*string) != internal_to_upper((int)*pattern))\n\t  && ('?' != *pattern))\n\t{\n\t  return FALSE;\n\t}\n    }\n  /* two-line patch to prevent *too* much recursiveness: */\n  while ('*' == pattern[1])\n    pattern++;\n\n  do\n    {\n      if ( trio_match(string, &pattern[1]) )\n\t{\n\t  return TRUE;\n\t}\n    }\n  while (*string++);\n  \n  return FALSE;\n}\n\n#endif\n\n/**\n   Compare two strings using wildcards.\n\n   @param string String to be searched.\n   @param pattern Pattern, including wildcards, to search for.\n   @return Boolean value indicating success or failure.\n\n   Case-sensitive comparison.\n   \n   The following wildcards can be used\n   @li @c * Match any number of characters.\n   @li @c ? Match a single character.\n*/\n#if defined(TRIO_FUNC_MATCH_CASE)\n\nTRIO_PUBLIC_STRING int\ntrio_match_case\nTRIO_ARGS2((string, pattern),\n\t   TRIO_CONST char *string,\n\t   TRIO_CONST char *pattern)\n{\n  assert(string);\n  assert(pattern);\n  \n  for (; ('*' != *pattern); ++pattern, ++string)\n    {\n      if (NIL == *string)\n\t{\n\t  return (NIL == *pattern);\n\t}\n      if ((*string != *pattern)\n\t  && ('?' != *pattern))\n\t{\n\t  return FALSE;\n\t}\n    }\n  /* two-line patch to prevent *too* much recursiveness: */\n  while ('*' == pattern[1])\n    pattern++;\n\n  do\n    {\n      if ( trio_match_case(string, &pattern[1]) )\n\t{\n\t  return TRUE;\n\t}\n    }\n  while (*string++);\n  \n  return FALSE;\n}\n\n#endif\n\n/**\n   Execute a function on each character in string.\n\n   @param target Target string.\n   @param source Source string.\n   @param Function Function to be executed.\n   @return Number of processed characters.\n*/\n#if defined(TRIO_FUNC_SPAN_FUNCTION)\n\nTRIO_PUBLIC_STRING size_t\ntrio_span_function\nTRIO_ARGS3((target, source, Function),\n\t   char *target,\n\t   TRIO_CONST char *source,\n\t   int (*Function) TRIO_PROTO((int)))\n{\n  size_t count = 0;\n\n  assert(target);\n  assert(source);\n  assert(Function);\n  \n  while (*source != NIL)\n    {\n      *target++ = Function(*source++);\n      count++;\n    }\n  return count;\n}\n\n#endif\n\n/**\n   Search for a substring in a string.\n\n   @param string String to be searched.\n   @param substring String to be found.\n   @return Pointer to first occurrence of @p substring in @p string, or NULL\n   if no match was found.\n*/\n#if defined(TRIO_FUNC_SUBSTRING)\n\nTRIO_PUBLIC_STRING char *\ntrio_substring\nTRIO_ARGS2((string, substring),\n\t   TRIO_CONST char *string,\n\t   TRIO_CONST char *substring)\n{\n  assert(string);\n  assert(substring);\n\n  return strstr(string, substring);\n}\n\n#endif\n\n/**\n   Search for a substring in the first @p max characters of a string.\n\n   @param string String to be searched.\n   @param max Maximum characters to be searched.\n   @param substring String to be found.\n   @return Pointer to first occurrence of @p substring in @p string, or NULL\n   if no match was found.\n*/\n#if defined(TRIO_FUNC_SUBSTRING_MAX)\n\nTRIO_PUBLIC_STRING char *\ntrio_substring_max\nTRIO_ARGS3((string, max, substring),\n\t   TRIO_CONST char *string,\n\t   size_t max,\n\t   TRIO_CONST char *substring)\n{\n  size_t count;\n  size_t size;\n  char *result = NULL;\n\n  assert(string);\n  assert(substring);\n  \n  size = trio_length(substring);\n  if (size <= max)\n    {\n      for (count = 0; count <= max - size; count++)\n\t{\n\t  if (trio_equal_max(substring, size, &string[count]))\n\t    {\n\t      result = (char *)&string[count];\n\t      break;\n\t    }\n\t}\n    }\n  return result;\n}\n\n#endif\n\n/**\n   Tokenize string.\n\n   @param string String to be tokenized.\n   @param delimiters String containing list of delimiting characters.\n   @return Start of new token.\n\n   @warning @p string will be destroyed.\n*/\n#if defined(TRIO_FUNC_TOKENIZE)\n\nTRIO_PUBLIC_STRING char *\ntrio_tokenize\nTRIO_ARGS2((string, delimiters),\n\t   char *string,\n\t   TRIO_CONST char *delimiters)\n{\n  assert(delimiters);\n  \n  return strtok(string, delimiters);\n}\n\n#endif\n\n/**\n   Convert string to floating-point number.\n\n   @param source String to be converted.\n   @param endp Pointer to end of the converted string.\n   @return A floating-point number.\n\n   The following Extended Backus-Naur form is used\n   @verbatim\n   double        ::= [ <sign> ]\n                     ( <number> |\n                       <number> <decimal_point> <number> |\n                       <decimal_point> <number> )\n                     [ <exponential> [ <sign> ] <number> ]\n   number        ::= 1*( <digit> )\n   digit         ::= ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' )\n   exponential   ::= ( 'e' | 'E' )\n   sign          ::= ( '-' | '+' )\n   decimal_point ::= '.'\n   @endverbatim\n*/\n#if defined(TRIO_FUNC_TO_LONG_DOUBLE)\n\n/* FIXME: Add EBNF for hex-floats */\nTRIO_PUBLIC_STRING trio_long_double_t\ntrio_to_long_double\nTRIO_ARGS2((source, endp),\n\t   TRIO_CONST char *source,\n\t   char **endp)\n{\n# if defined(USE_STRTOLD)\n  return strtold(source, endp);\n# else\n  int isNegative = FALSE;\n  int isExponentNegative = FALSE;\n  trio_long_double_t integer = 0.0;\n  trio_long_double_t fraction = 0.0;\n  unsigned long exponent = 0;\n  trio_long_double_t base;\n  trio_long_double_t fracdiv = 1.0;\n  trio_long_double_t value = 0.0;\n\n  /* First try hex-floats */\n  if ((source[0] == '0') && ((source[1] == 'x') || (source[1] == 'X')))\n    {\n      base = 16.0;\n      source += 2;\n      while (isxdigit((int)*source))\n\t{\n\t  integer *= base;\n\t  integer += (isdigit((int)*source)\n\t\t      ? (*source - '0')\n\t\t      : 10 + (internal_to_upper((int)*source) - 'A'));\n\t  source++;\n\t}\n      if (*source == '.')\n\t{\n\t  source++;\n\t  while (isxdigit((int)*source))\n\t    {\n\t      fracdiv /= base;\n\t      fraction += fracdiv * (isdigit((int)*source)\n\t\t\t\t     ? (*source - '0')\n\t\t\t\t     : 10 + (internal_to_upper((int)*source) - 'A'));\n\t      source++;\n\t    }\n\t  if ((*source == 'p') || (*source == 'P'))\n\t    {\n\t      source++;\n\t      if ((*source == '+') || (*source == '-'))\n\t\t{\n\t\t  isExponentNegative = (*source == '-');\n\t\t  source++;\n\t\t}\n\t      while (isdigit((int)*source))\n\t\t{\n\t\t  exponent *= 10;\n\t\t  exponent += (*source - '0');\n\t\t  source++;\n\t\t}\n\t    }\n\t}\n      /* For later use with exponent */\n      base = 2.0;\n    }\n  else /* Then try normal decimal floats */\n    {\n      base = 10.0;\n      isNegative = (*source == '-');\n      /* Skip sign */\n      if ((*source == '+') || (*source == '-'))\n\tsource++;\n\n      /* Integer part */\n      while (isdigit((int)*source))\n\t{\n\t  integer *= base;\n\t  integer += (*source - '0');\n\t  source++;\n\t}\n\n      if (*source == '.')\n\t{\n\t  source++; /* skip decimal point */\n\t  while (isdigit((int)*source))\n\t    {\n\t      fracdiv /= base;\n\t      fraction += (*source - '0') * fracdiv;\n\t      source++;\n\t    }\n\t}\n      if ((*source == 'e')\n\t  || (*source == 'E')\n#  if TRIO_MICROSOFT\n\t  || (*source == 'd')\n\t  || (*source == 'D')\n#  endif\n\t  )\n\t{\n\t  source++; /* Skip exponential indicator */\n\t  isExponentNegative = (*source == '-');\n\t  if ((*source == '+') || (*source == '-'))\n\t    source++;\n\t  while (isdigit((int)*source))\n\t    {\n\t      exponent *= (int)base;\n\t      exponent += (*source - '0');\n\t      source++;\n\t    }\n\t}\n    }\n  \n  value = integer + fraction;\n  if (exponent != 0)\n    {\n      if (isExponentNegative)\n\tvalue /= trio_powl(base, (trio_long_double_t)exponent);\n      else\n\tvalue *= trio_powl(base, (trio_long_double_t)exponent);\n    }\n  if (isNegative)\n    value = -value;\n\n  if (endp)\n    *endp = (char *)source;\n  return value;\n# endif\n}\n\n#endif\n\n/**\n   Convert string to floating-point number.\n\n   @param source String to be converted.\n   @param endp Pointer to end of the converted string.\n   @return A floating-point number.\n\n   See @ref trio_to_long_double.\n*/\n#if defined(TRIO_FUNC_TO_DOUBLE)\n\nTRIO_PUBLIC_STRING double\ntrio_to_double\nTRIO_ARGS2((source, endp),\n\t   TRIO_CONST char *source,\n\t   char **endp)\n{\n#if defined(USE_STRTOD)\n  return strtod(source, endp);\n#else\n  return (double)trio_to_long_double(source, endp);\n#endif\n}\n\n#endif\n\n/**\n   Convert string to floating-point number.\n\n   @param source String to be converted.\n   @param endp Pointer to end of the converted string.\n   @return A floating-point number.\n\n   See @ref trio_to_long_double.\n*/\n#if defined(TRIO_FUNC_TO_FLOAT)\n\nTRIO_PUBLIC_STRING float\ntrio_to_float\nTRIO_ARGS2((source, endp),\n\t   TRIO_CONST char *source,\n\t   char **endp)\n{\n#  if defined(USE_STRTOF)\n  return strtof(source, endp);\n#  else\n  return (float)trio_to_long_double(source, endp);\n#  endif\n}\n\n#endif\n\n/**\n   Convert string to signed integer.\n\n   @param string String to be converted.\n   @param endp Pointer to end of converted string.\n   @param base Radix number of number.\n*/\n#if defined(TRIO_FUNC_TO_LONG)\n\nTRIO_PUBLIC_STRING long\ntrio_to_long\nTRIO_ARGS3((string, endp, base),\n\t   TRIO_CONST char *string,\n\t   char **endp,\n\t   int base)\n{\n  assert(string);\n  assert((base >= 2) && (base <= 36));\n  \n  return strtol(string, endp, base);\n}\n\n#endif\n\n/**\n   Convert one alphabetic letter to lower-case.\n\n   @param source The letter to be converted.\n   @return The converted letter.\n*/\n#if defined(TRIO_FUNC_TO_LOWER)\n\nTRIO_PUBLIC_STRING int\ntrio_to_lower\nTRIO_ARGS1((source),\n\t   int source)\n{\n# if defined(HAVE_TOLOWER)\n  \n  return tolower(source);\n  \n# else\n\n  /* Does not handle locales or non-contiguous alphabetic characters */\n  return ((source >= (int)'A') && (source <= (int)'Z'))\n    ? source - 'A' + 'a'\n    : source;\n  \n# endif\n}\n\n#endif\n\n/**\n   Convert string to unsigned integer.\n\n   @param string String to be converted.\n   @param endp Pointer to end of converted string.\n   @param base Radix number of number.\n*/\n#if defined(TRIO_FUNC_TO_UNSIGNED_LONG)\n\nTRIO_PUBLIC_STRING unsigned long\ntrio_to_unsigned_long\nTRIO_ARGS3((string, endp, base),\n\t   TRIO_CONST char *string,\n\t   char **endp,\n\t   int base)\n{\n  assert(string);\n  assert((base >= 2) && (base <= 36));\n  \n  return strtoul(string, endp, base);\n}\n\n#endif\n\n/**\n   Convert one alphabetic letter to upper-case.\n\n   @param source The letter to be converted.\n   @return The converted letter.\n*/\n#if defined(TRIO_FUNC_TO_UPPER)\n\nTRIO_PUBLIC_STRING int\ntrio_to_upper\nTRIO_ARGS1((source),\n\t   int source)\n{\n  return internal_to_upper(source);\n}\n\n#endif\n\n/**\n   Convert the alphabetic letters in the string to upper-case.\n\n   @param target The string to be converted.\n   @return The number of processed characters (converted or not).\n*/\n#if defined(TRIO_FUNC_UPPER)\n\nTRIO_PUBLIC_STRING int\ntrio_upper\nTRIO_ARGS1((target),\n\t   char *target)\n{\n  assert(target);\n\n  return trio_span_function(target, target, internal_to_upper);\n}\n\n#endif\n\n/** @} End of StaticStrings */\n\n\n/*************************************************************************\n * Dynamic String Functions\n */\n\n#if defined(TRIO_DOCUMENTATION)\n# include \"doc/doc_dynamic.h\"\n#endif\n/** @addtogroup DynamicStrings\n    @{\n*/\n\n/**\n   Create a new dynamic string.\n   \n   @param initial_size Initial size of the buffer.\n   @return Newly allocated dynamic string, or NULL if memory allocation failed.\n*/\n#if defined(TRIO_FUNC_STRING_CREATE)\n\nTRIO_PUBLIC_STRING trio_string_t *\ntrio_string_create\nTRIO_ARGS1((initial_size),\n\t   int initial_size)\n{\n  trio_string_t *self;\n\n  self = internal_string_alloc();\n  if (self)\n    {\n      if (internal_string_grow(self,\n\t\t\t (size_t)((initial_size > 0) ? initial_size : 1)))\n\t{\n\t  self->content[0] = (char)0;\n\t  self->allocated = initial_size;\n\t}\n      else\n\t{\n\t  trio_string_destroy(self);\n\t  self = NULL;\n\t}\n    }\n  return self;\n}\n\n#endif\n\n/**\n   Deallocate the dynamic string and its contents.\n   \n   @param self Dynamic string\n*/\n#if defined(TRIO_FUNC_STRING_DESTROY)\n\nTRIO_PUBLIC_STRING void\ntrio_string_destroy\nTRIO_ARGS1((self),\n\t   trio_string_t *self)\n{\n  assert(self);\n  \n  if (self)\n    {\n      trio_destroy(self->content);\n      TRIO_FREE(self);\n    }\n}\n\n#endif\n\n/**\n   Get a pointer to the content.\n   \n   @param self Dynamic string.\n   @param offset Offset into content.\n   @return Pointer to the content.\n   \n   @p Offset can be zero, positive, or negative. If @p offset is zero,\n   then the start of the content will be returned. If @p offset is positive,\n   then a pointer to @p offset number of characters from the beginning of the\n   content is returned. If @p offset is negative, then a pointer to @p offset\n   number of characters from the ending of the string, starting at the\n   terminating zero, is returned.\n*/\n#if defined(TRIO_FUNCT_STRING_GET)\n\nTRIO_PUBLIC_STRING char *\ntrio_string_get\nTRIO_ARGS2((self, offset),\n\t   trio_string_t *self,\n\t   int offset)\n{\n  char *result = NULL;\n  \n  assert(self);\n\n  if (self->content != NULL)\n    {\n      if (self->length == 0)\n\t{\n\t  (void)trio_string_length(self);\n\t}\n      if (offset >= 0)\n\t{\n\t  if (offset > (int)self->length)\n\t    {\n\t      offset = self->length;\n\t    }\n\t}\n      else\n\t{\n\t  offset += self->length + 1;\n\t  if (offset < 0)\n\t    {\n\t      offset = 0;\n\t    }\n\t}\n      result = &(self->content[offset]);\n    }\n  return result;\n}\n\n#endif\n\n/**\n   Extract the content.\n   \n   @param self Dynamic String\n   @return Content of dynamic string.\n   \n   The content is removed from the dynamic string. This enables destruction\n   of the dynamic string without deallocation of the content.\n*/\n#if defined(TRIO_FUNC_STRING_EXTRACT)\n\nTRIO_PUBLIC_STRING char *\ntrio_string_extract\nTRIO_ARGS1((self),\n\t   trio_string_t *self)\n{\n  char *result;\n  \n  assert(self);\n\n  result = self->content;\n  /* FIXME: Allocate new empty buffer? */\n  self->content = NULL;\n  self->length = self->allocated = 0;\n  return result;\n}\n\n#endif\n\n/**\n   Set the content of the dynamic string.\n   \n   @param self Dynamic String\n   @param buffer The new content.\n   \n   Sets the content of the dynamic string to a copy @p buffer.\n   An existing content will be deallocated first, if necessary.\n   \n   @remark\n   This function will make a copy of @p buffer.\n   You are responsible for deallocating @p buffer yourself.\n*/\n#if defined(TRIO_FUNC_XSTRING_SET)\n\nTRIO_PUBLIC_STRING void\ntrio_xstring_set\nTRIO_ARGS2((self, buffer),\n\t   trio_string_t *self,\n\t   char *buffer)\n{\n  assert(self);\n\n  trio_destroy(self->content);\n  self->content = trio_duplicate(buffer);\n}\n\n#endif\n\n/*\n * trio_string_size\n */\n#if defined(TRIO_FUNC_STRING_SIZE)\n\nTRIO_PUBLIC_STRING int\ntrio_string_size\nTRIO_ARGS1((self),\n\t   trio_string_t *self)\n{\n  assert(self);\n\n  return self->allocated;\n}\n\n#endif\n\n/*\n * trio_string_terminate\n */\n#if defined(TRIO_FUNC_STRING_TERMINATE)\n\nTRIO_PUBLIC_STRING void\ntrio_string_terminate\nTRIO_ARGS1((self),\n\t   trio_string_t *self)\n{\n  trio_xstring_append_char(self, 0);\n}\n\n#endif\n\n/**\n   Append the second string to the first.\n   \n   @param self Dynamic string to be modified.\n   @param other Dynamic string to copy from.\n   @return Boolean value indicating success or failure.\n*/\n#if defined(TRIO_FUNC_STRING_APPEND)\n\nTRIO_PUBLIC_STRING int\ntrio_string_append\nTRIO_ARGS2((self, other),\n\t   trio_string_t *self,\n\t   trio_string_t *other)\n{\n  size_t length;\n  \n  assert(self);\n  assert(other);\n\n  length = self->length + other->length;\n  if (!internal_string_grow_to(self, length))\n    goto error;\n  trio_copy(&self->content[self->length], other->content);\n  self->length = length;\n  return TRUE;\n  \n error:\n  return FALSE;\n}\n\n#endif\n\n\n/*\n * trio_xstring_append\n */\n#if defined(TRIO_FUNC_XSTRING_APPEND)\n\nTRIO_PUBLIC_STRING int\ntrio_xstring_append\nTRIO_ARGS2((self, other),\n\t   trio_string_t *self,\n\t   TRIO_CONST char *other)\n{\n  size_t length;\n  \n  assert(self);\n  assert(other);\n\n  length = self->length + trio_length(other);\n  if (!internal_string_grow_to(self, length))\n    goto error;\n  trio_copy(&self->content[self->length], other);\n  self->length = length;\n  return TRUE;\n  \n error:\n  return FALSE;\n}\n\n#endif\n\n/*\n * trio_xstring_append_char\n */\n#if defined(TRIO_FUNC_XSTRING_APPEND_CHAR)\n\nTRIO_PUBLIC_STRING int\ntrio_xstring_append_char\nTRIO_ARGS2((self, character),\n\t   trio_string_t *self,\n\t   char character)\n{\n  assert(self);\n\n  if ((int)self->length >= trio_string_size(self))\n    {\n      if (!internal_string_grow(self, 0))\n\tgoto error;\n    }\n  self->content[self->length] = character;\n  self->length++;\n  return TRUE;\n  \n error:\n  return FALSE;\n}\n\n#endif\n\n/**\n   Search for the first occurrence of second parameter in the first.\n   \n   @param self Dynamic string to be modified.\n   @param other Dynamic string to copy from.\n   @return Boolean value indicating success or failure.\n*/\n#if defined(TRIO_FUNC_STRING_CONTAINS)\n\nTRIO_PUBLIC_STRING int\ntrio_string_contains\nTRIO_ARGS2((self, other),\n\t   trio_string_t *self,\n\t   trio_string_t *other)\n{\n  assert(self);\n  assert(other);\n\n  return trio_contains(self->content, other->content);\n}\n\n#endif\n\n/*\n * trio_xstring_contains\n */\n#if defined(TRIO_FUNC_XSTRING_CONTAINS)\n\nTRIO_PUBLIC_STRING int\ntrio_xstring_contains\nTRIO_ARGS2((self, other),\n\t   trio_string_t *self,\n\t   TRIO_CONST char *other)\n{\n  assert(self);\n  assert(other);\n\n  return trio_contains(self->content, other);\n}\n\n#endif\n\n/*\n * trio_string_copy\n */\n#if defined(TRIO_FUNC_STRING_COPY)\n\nTRIO_PUBLIC_STRING int\ntrio_string_copy\nTRIO_ARGS2((self, other),\n\t   trio_string_t *self,\n\t   trio_string_t *other)\n{\n  assert(self);\n  assert(other);\n\n  self->length = 0;\n  return trio_string_append(self, other);\n}\n\n#endif\n\n\n/*\n * trio_xstring_copy\n */\n#if defined(TRIO_FUNC_XSTRING_COPY)\n\nTRIO_PUBLIC_STRING int\ntrio_xstring_copy\nTRIO_ARGS2((self, other),\n\t   trio_string_t *self,\n\t   TRIO_CONST char *other)\n{\n  assert(self);\n  assert(other);\n\n  self->length = 0;\n  return trio_xstring_append(self, other);\n}\n\n#endif\n\n/*\n * trio_string_duplicate\n */\n#if defined(TRIO_FUNC_STRING_DUPLICATE)\n\nTRIO_PUBLIC_STRING trio_string_t *\ntrio_string_duplicate\nTRIO_ARGS1((other),\n\t   trio_string_t *other)\n{\n  trio_string_t *self;\n  \n  assert(other);\n\n  self = internal_string_alloc();\n  if (self)\n    {\n      self->content = internal_duplicate_max(other->content, other->length);\n      if (self->content)\n\t{\n\t  self->length = other->length;\n\t  self->allocated = self->length + 1;\n\t}\n      else\n\t{\n\t  self->length = self->allocated = 0;\n\t}\n    }\n  return self;\n}\n\n#endif\n\n/*\n * trio_xstring_duplicate\n */\n#if defined(TRIO_FUNC_XSTRING_DUPLICATE)\n\nTRIO_PUBLIC_STRING trio_string_t *\ntrio_xstring_duplicate\nTRIO_ARGS1((other),\n\t   TRIO_CONST char *other)\n{\n  trio_string_t *self;\n  \n  assert(other);\n\n  self = internal_string_alloc();\n  if (self)\n    {\n      self->content = internal_duplicate_max(other, trio_length(other));\n      if (self->content)\n\t{\n\t  self->length = trio_length(self->content);\n\t  self->allocated = self->length + 1;\n\t}\n      else\n\t{\n\t  self->length = self->allocated = 0;\n\t}\n    }\n  return self;\n}\n\n#endif\n\n/*\n * trio_string_equal\n */\n#if defined(TRIO_FUNC_STRING_EQUAL)\n\nTRIO_PUBLIC_STRING int\ntrio_string_equal\nTRIO_ARGS2((self, other),\n\t   trio_string_t *self,\n\t   trio_string_t *other)\n{\n  assert(self);\n  assert(other);\n\n  return trio_equal(self->content, other->content);\n}\n\n#endif\n\n\n/*\n * trio_xstring_equal\n */\n#if defined(TRIO_FUNC_XSTRING_EQUAL)\n\nTRIO_PUBLIC_STRING int\ntrio_xstring_equal\nTRIO_ARGS2((self, other),\n\t   trio_string_t *self,\n\t   TRIO_CONST char *other)\n{\n  assert(self);\n  assert(other);\n\n  return trio_equal(self->content, other);\n}\n\n#endif\n\n/*\n * trio_string_equal_max\n */\n#if defined(TRIO_FUNC_STRING_EQUAL_MAX)\n\nTRIO_PUBLIC_STRING int\ntrio_string_equal_max\nTRIO_ARGS3((self, max, other),\n\t   trio_string_t *self,\n\t   size_t max,\n\t   trio_string_t *other)\n{\n  assert(self);\n  assert(other);\n\n  return trio_equal_max(self->content, max, other->content);\n}\n#endif\n\n/*\n * trio_xstring_equal_max\n */\n#if defined(TRIO_FUNC_XSTRING_EQUAL_MAX)\n\nTRIO_PUBLIC_STRING int\ntrio_xstring_equal_max\nTRIO_ARGS3((self, max, other),\n\t   trio_string_t *self,\n\t   size_t max,\n\t   TRIO_CONST char *other)\n{\n  assert(self);\n  assert(other);\n\n  return trio_equal_max(self->content, max, other);\n}\n\n#endif\n\n/*\n * trio_string_equal_case\n */\n#if defined(TRIO_FUNC_STRING_EQUAL_CASE)\n\nTRIO_PUBLIC_STRING int\ntrio_string_equal_case\nTRIO_ARGS2((self, other),\n\t   trio_string_t *self,\n\t   trio_string_t *other)\n{\n  assert(self);\n  assert(other);\n\n  return trio_equal_case(self->content, other->content);\n}\n\n#endif\n\n/*\n * trio_xstring_equal_case\n */\n#if defined(TRIO_FUNC_XSTRING_EQUAL_CASE)\n\nTRIO_PUBLIC_STRING int\ntrio_xstring_equal_case\nTRIO_ARGS2((self, other),\n\t   trio_string_t *self,\n\t   TRIO_CONST char *other)\n{\n  assert(self);\n  assert(other);\n\n  return trio_equal_case(self->content, other);\n}\n\n#endif\n\n/*\n * trio_string_equal_case_max\n */\n#if defined(TRIO_FUNC_STRING_EQUAL_CASE_MAX)\n\nTRIO_PUBLIC_STRING int\ntrio_string_equal_case_max\nTRIO_ARGS3((self, max, other),\n\t   trio_string_t *self,\n\t   size_t max,\n\t   trio_string_t *other)\n{\n  assert(self);\n  assert(other);\n\n  return trio_equal_case_max(self->content, max, other->content);\n}\n\n#endif\n\n/*\n * trio_xstring_equal_case_max\n */\n#if defined(TRIO_FUNC_XSTRING_EQUAL_CASE_MAX)\n\nTRIO_PUBLIC_STRING int\ntrio_xstring_equal_case_max\nTRIO_ARGS3((self, max, other),\n\t   trio_string_t *self,\n\t   size_t max,\n\t   TRIO_CONST char *other)\n{\n  assert(self);\n  assert(other);\n\n  return trio_equal_case_max(self->content, max, other);\n}\n\n#endif\n\n/*\n * trio_string_format_data_max\n */\n#if defined(TRIO_FUNC_STRING_FORMAT_DATE_MAX)\n\nTRIO_PUBLIC_STRING size_t\ntrio_string_format_date_max\nTRIO_ARGS4((self, max, format, datetime),\n\t   trio_string_t *self,\n\t   size_t max,\n\t   TRIO_CONST char *format,\n\t   TRIO_CONST struct tm *datetime)\n{\n  assert(self);\n\n  return trio_format_date_max(self->content, max, format, datetime);\n}\n\n#endif\n\n/*\n * trio_string_index\n */\n#if defined(TRIO_FUNC_STRING_INDEX)\n\nTRIO_PUBLIC_STRING char *\ntrio_string_index\nTRIO_ARGS2((self, character),\n\t   trio_string_t *self,\n\t   int character)\n{\n  assert(self);\n\n  return trio_index(self->content, character);\n}\n\n#endif\n\n/*\n * trio_string_index_last\n */\n#if defined(TRIO_FUNC_STRING_INDEX_LAST)\n\nTRIO_PUBLIC_STRING char *\ntrio_string_index_last\nTRIO_ARGS2((self, character),\n\t   trio_string_t *self,\n\t   int character)\n{\n  assert(self);\n\n  return trio_index_last(self->content, character);\n}\n\n#endif\n\n/*\n * trio_string_length\n */\n#if defined(TRIO_FUNC_STRING_LENGTH)\n\nTRIO_PUBLIC_STRING int\ntrio_string_length\nTRIO_ARGS1((self),\n\t   trio_string_t *self)\n{\n  assert(self);\n\n  if (self->length == 0)\n    {\n      self->length = trio_length(self->content);\n    }\n  return self->length;\n}\n\n#endif\n\n/*\n * trio_string_lower\n */\n#if defined(TRIO_FUNC_STRING_LOWER)\n\nTRIO_PUBLIC_STRING int\ntrio_string_lower\nTRIO_ARGS1((self),\n\t   trio_string_t *self)\n{\n  assert(self);\n\n  return trio_lower(self->content);\n}\n\n#endif\n\n/*\n * trio_string_match\n */\n#if defined(TRIO_FUNC_STRING_MATCH)\n\nTRIO_PUBLIC_STRING int\ntrio_string_match\nTRIO_ARGS2((self, other),\n\t   trio_string_t *self,\n\t   trio_string_t *other)\n{\n  assert(self);\n  assert(other);\n\n  return trio_match(self->content, other->content);\n}\n\n#endif\n\n/*\n * trio_xstring_match\n */\n#if defined(TRIO_FUNC_XSTRING_MATCH)\n\nTRIO_PUBLIC_STRING int\ntrio_xstring_match\nTRIO_ARGS2((self, other),\n\t   trio_string_t *self,\n\t   TRIO_CONST char *other)\n{\n  assert(self);\n  assert(other);\n\n  return trio_match(self->content, other);\n}\n\n#endif\n\n/*\n * trio_string_match_case\n */\n#if defined(TRIO_FUNC_STRING_MATCH_CASE)\n\nTRIO_PUBLIC_STRING int\ntrio_string_match_case\nTRIO_ARGS2((self, other),\n\t   trio_string_t *self,\n\t   trio_string_t *other)\n{\n  assert(self);\n  assert(other);\n\n  return trio_match_case(self->content, other->content);\n}\n\n#endif\n\n/*\n * trio_xstring_match_case\n */\n#if defined(TRIO_FUNC_XSTRING_MATCH_CASE)\n\nTRIO_PUBLIC_STRING int\ntrio_xstring_match_case\nTRIO_ARGS2((self, other),\n\t   trio_string_t *self,\n\t   TRIO_CONST char *other)\n{\n  assert(self);\n  assert(other);\n\n  return trio_match_case(self->content, other);\n}\n\n#endif\n\n/*\n * trio_string_substring\n */\n#if defined(TRIO_FUNC_STRING_SUBSTRING)\n\nTRIO_PUBLIC_STRING char *\ntrio_string_substring\nTRIO_ARGS2((self, other),\n\t   trio_string_t *self,\n\t   trio_string_t *other)\n{\n  assert(self);\n  assert(other);\n\n  return trio_substring(self->content, other->content);\n}\n\n#endif\n\n/*\n * trio_xstring_substring\n */\n#if defined(TRIO_FUNC_XSTRING_SUBSTRING)\n\nTRIO_PUBLIC_STRING char *\ntrio_xstring_substring\nTRIO_ARGS2((self, other),\n\t   trio_string_t *self,\n\t   TRIO_CONST char *other)\n{\n  assert(self);\n  assert(other);\n\n  return trio_substring(self->content, other);\n}\n\n#endif\n\n/*\n * trio_string_upper\n */\n#if defined(TRIO_FUNC_STRING_UPPER)\n\nTRIO_PUBLIC_STRING int\ntrio_string_upper\nTRIO_ARGS1((self),\n\t   trio_string_t *self)\n{\n  assert(self);\n\n  return trio_upper(self->content);\n}\n\n#endif\n\n/** @} End of DynamicStrings */\n"
  },
  {
    "path": "src/sdk/src/libc/src/trio/triostr.h",
    "content": "\n\n#ifndef TRIO_TRIOSTR_H\n#define TRIO_TRIOSTR_H\n\n/*\n * Documentation is located in triostr.c\n */\n\n#include <assert.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n#include \"triodef.h\"\n#include \"triop.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nenum {\n  TRIO_HASH_NONE = 0,\n  TRIO_HASH_PLAIN,\n  TRIO_HASH_TWOSIGNED\n};\n\n#if !defined(TRIO_PUBLIC_STRING)\n# if !defined(TRIO_PUBLIC)\n#  define TRIO_PUBLIC\n# endif\n# define TRIO_PUBLIC_STRING TRIO_PUBLIC\n#endif\n\n/*************************************************************************\n * Dependencies\n */\n\n#if defined(TRIO_EMBED_STRING)\n\n/*\n * The application that triostr is embedded in must define which functions\n * it uses.\n *\n * The following resolves internal dependencies.\n */\n  \n# if defined(TRIO_FUNC_XSTRING_SET)\n#  if !defined(TRIO_FUNC_DUPLICATE)\n#   define TRIO_FUNC_DUPLICATE\n#  endif\n# endif\n\n# if defined(TRIO_FUNC_DUPLICATE) \\\n  || defined(TRIO_FUNC_DUPLICATE_MAX) \\\n  || defined(TRIO_FUNC_STRING_DUPLICATE) \\\n  || defined(TRIO_FUNC_XSTRING_DUPLICATE)\n#  if !defined(TRIO_FUNC_CREATE)\n#   define TRIO_FUNC_CREATE\n#  endif\n#  if !defined(TRIO_FUNC_COPY_MAX)\n#   define TRIO_FUNC_COPY_MAX\n#  endif\n# endif\n\n# if defined(TRIO_FUNC_STRING_CREATE)\n#  if !defined(TRIO_FUNC_STRING_DESTROY)\n#   define TRIO_FUNC_STRING_DESTROY\n#  endif\n# endif\n\n# if defined(TRIO_FUNC_STRING_DESTROY) \\\n  || defined(TRIO_FUNC_XSTRING_SET)\n#  if !defined(TRIO_FUNC_DESTROY)\n#   define TRIO_FUNC_DESTROY\n#  endif\n# endif\n\n# if defined(TRIO_FUNC_EQUAL_LOCALE) \\\n  || defined(TRIO_FUNC_STRING_EQUAL) \\\n  || defined(TRIO_FUNC_XSTRING_EQUAL)\n#  if !defined(TRIO_FUNC_EQUAL)\n#   define TRIO_FUNC_EQUAL\n#  endif\n# endif\n\n# if defined(TRIO_FUNC_EQUAL_CASE) \\\n  || defined(TRIO_FUNC_STRING_EQUAL_CASE) \\\n  || defined(TRIO_FUNC_XSTRING_EQUAL_CASE)\n#  if !defined(TRIO_FUNC_EQUAL_CASE)\n#   define TRIO_FUNC_EQUAL_CASE\n#  endif\n# endif\n\n# if defined(TRIO_FUNC_SUBSTRING_MAX) \\\n  || defined(TRIO_FUNC_STRING_EQUAL_MAX) \\\n  || defined(TRIO_FUNC_XSTRING_EQUAL_MAX)\n#  if !defined(TRIO_FUNC_EQUAL_MAX)\n#   define TRIO_FUNC_EQUAL_MAX\n#  endif\n# endif\n\n# if defined(TRIO_FUNC_TO_DOUBLE) \\\n  || defined(TRIO_FUNC_TO_FLOAT)\n#  if !defined(TRIO_FUNC_TO_LONG_DOUBLE)\n#   define TRIO_FUNC_TO_LONG_DOUBLE\n#  endif\n# endif\n\n# if defined(TRIO_FUNC_STRING_TERMINATE)\n#  if !defined(TRIO_FUNC_XSTRING_APPEND_CHAR)\n#   define TRIO_FUNC_XSTRING_APPEND_CHAR\n#  endif\n# endif\n\n# if defined(TRIO_FUNC_XSTRING_APPEND_CHAR)\n#  if !defined(TRIO_FUNC_STRING_SIZE)\n#   define TRIO_FUNC_STRING_SIZE\n#  endif\n# endif\n\n#else\n\n/*\n * When triostr is not embedded all functions are defined.\n */\n\n# define TRIO_FUNC_APPEND\n# define TRIO_FUNC_APPEND_MAX\n# define TRIO_FUNC_CONTAINS\n# define TRIO_FUNC_COPY\n# define TRIO_FUNC_COPY_MAX\n# define TRIO_FUNC_CREATE\n# define TRIO_FUNC_DESTROY\n# define TRIO_FUNC_DUPLICATE\n# define TRIO_FUNC_DUPLICATE_MAX\n# define TRIO_FUNC_EQUAL\n# define TRIO_FUNC_EQUAL_CASE\n# define TRIO_FUNC_EQUAL_CASE_MAX\n# define TRIO_FUNC_EQUAL_LOCALE\n# define TRIO_FUNC_EQUAL_MAX\n# define TRIO_FUNC_ERROR\n# if !defined(TRIO_PLATFORM_WINCE)\n#  define TRIO_FUNC_FORMAT_DATE_MAX\n# endif\n# define TRIO_FUNC_HASH\n# define TRIO_FUNC_INDEX\n# define TRIO_FUNC_INDEX_LAST\n# define TRIO_FUNC_LENGTH\n# define TRIO_FUNC_LENGTH_MAX\n# define TRIO_FUNC_LOWER\n# define TRIO_FUNC_MATCH\n# define TRIO_FUNC_MATCH_CASE\n# define TRIO_FUNC_SPAN_FUNCTION\n# define TRIO_FUNC_SUBSTRING\n# define TRIO_FUNC_SUBSTRING_MAX\n# define TRIO_FUNC_TO_DOUBLE\n# define TRIO_FUNC_TO_FLOAT\n# define TRIO_FUNC_TO_LONG\n# define TRIO_FUNC_TO_LONG_DOUBLE\n# define TRIO_FUNC_TO_LOWER\n# define TRIO_FUNC_TO_UNSIGNED_LONG\n# define TRIO_FUNC_TO_UPPER\n# define TRIO_FUNC_TOKENIZE\n# define TRIO_FUNC_UPPER\n\n# define TRIO_FUNC_STRING_APPEND\n# define TRIO_FUNC_STRING_CONTAINS\n# define TRIO_FUNC_STRING_COPY\n# define TRIO_FUNC_STRING_CREATE\n# define TRIO_FUNC_STRING_DESTROY\n# define TRIO_FUNC_STRING_DUPLICATE\n# define TRIO_FUNC_STRING_EQUAL\n# define TRIO_FUNC_STRING_EQUAL_CASE\n# define TRIO_FUNC_STRING_EQUAL_CASE_MAX\n# define TRIO_FUNC_STRING_EQUAL_MAX\n# define TRIO_FUNC_STRING_EXTRACT\n# if !defined(TRIO_PLATFORM_WINCE)\n#  define TRIO_FUNC_STRING_FORMAT_DATE_MAX\n# endif\n# define TRIO_FUNC_STRING_GET\n# define TRIO_FUNC_STRING_INDEX\n# define TRIO_FUNC_STRING_INDEX_LAST\n# define TRIO_FUNC_STRING_LENGTH\n# define TRIO_FUNC_STRING_LOWER\n# define TRIO_FUNC_STRING_MATCH\n# define TRIO_FUNC_STRING_MATCH_CASE\n# define TRIO_FUNC_STRING_SIZE\n# define TRIO_FUNC_STRING_SUBSTRING\n# define TRIO_FUNC_STRING_TERMINATE\n# define TRIO_FUNC_STRING_UPPER\n\n# define TRIO_FUNC_XSTRING_APPEND\n# define TRIO_FUNC_XSTRING_APPEND_CHAR\n# define TRIO_FUNC_XSTRING_CONTAINS\n# define TRIO_FUNC_XSTRING_COPY\n# define TRIO_FUNC_XSTRING_DUPLICATE\n# define TRIO_FUNC_XSTRING_EQUAL\n# define TRIO_FUNC_XSTRING_EQUAL_CASE\n# define TRIO_FUNC_XSTRING_EQUAL_CASE_MAX\n# define TRIO_FUNC_XSTRING_EQUAL_MAX\n# define TRIO_FUNC_XSTRING_MATCH\n# define TRIO_FUNC_XSTRING_MATCH_CASE\n# define TRIO_FUNC_XSTRING_SET\n# define TRIO_FUNC_XSTRING_SUBSTRING\n\n#endif\n\n\n/*************************************************************************\n * String functions\n */\n\n#if defined(TRIO_FUNC_APPEND)\nTRIO_PUBLIC_STRING int\ntrio_append\nTRIO_PROTO((char *target, TRIO_CONST char *source));\n#endif\n\n#if defined(TRIO_FUNC_APPEND_MAX)\nTRIO_PUBLIC_STRING int\ntrio_append_max\nTRIO_PROTO((char *target, size_t max, TRIO_CONST char *source));\n#endif\n\n#if defined(TRIO_FUNC_CONTAINS)\nTRIO_PUBLIC_STRING int\ntrio_contains\nTRIO_PROTO((TRIO_CONST char *string, TRIO_CONST char *substring));\n#endif\n\n#if defined(TRIO_FUNC_COPY)\nTRIO_PUBLIC_STRING int\ntrio_copy\nTRIO_PROTO((char *target, TRIO_CONST char *source));\n#endif\n\n#if defined(TRIO_FUNC_COPY_MAX)\nTRIO_PUBLIC_STRING int\ntrio_copy_max\nTRIO_PROTO((char *target, size_t max, TRIO_CONST char *source));\n#endif\n\n#if defined(TRIO_FUNC_CREATE)\nTRIO_PUBLIC_STRING char *\ntrio_create\nTRIO_PROTO((size_t size));\n#endif\n\n#if defined(TRIO_FUNC_DESTROY)\nTRIO_PUBLIC_STRING void\ntrio_destroy\nTRIO_PROTO((char *string));\n#endif\n\n#if defined(TRIO_FUNC_DUPLICATE)\nTRIO_PUBLIC_STRING char *\ntrio_duplicate\nTRIO_PROTO((TRIO_CONST char *source));\n#endif\n\n#if defined(TRIO_FUNC_DUPLICATE_MAX)\nTRIO_PUBLIC_STRING char *\ntrio_duplicate_max\nTRIO_PROTO((TRIO_CONST char *source, size_t max));\n#endif\n\n#if defined(TRIO_FUNC_EQUAL)\nTRIO_PUBLIC_STRING int\ntrio_equal\nTRIO_PROTO((TRIO_CONST char *first, TRIO_CONST char *second));\n#endif\n\n#if defined(TRIO_FUNC_EQUAL_CASE)\nTRIO_PUBLIC_STRING int\ntrio_equal_case\nTRIO_PROTO((TRIO_CONST char *first, TRIO_CONST char *second));\n#endif\n\n#if defined(TRIO_FUNC_EQUAL_CASE_MAX)\nTRIO_PUBLIC_STRING int\ntrio_equal_case_max\nTRIO_PROTO((TRIO_CONST char *first, size_t max, TRIO_CONST char *second));\n#endif\n\n#if defined(TRIO_FUNC_EQUAL_LOCALE)\nTRIO_PUBLIC_STRING int\ntrio_equal_locale\nTRIO_PROTO((TRIO_CONST char *first, TRIO_CONST char *second));\n#endif\n\n#if defined(TRIO_FUNC_EQUAL_MAX)\nTRIO_PUBLIC_STRING int\ntrio_equal_max\nTRIO_PROTO((TRIO_CONST char *first, size_t max, TRIO_CONST char *second));\n#endif\n\n#if defined(TRIO_FUNC_ERROR)\nTRIO_PUBLIC_STRING TRIO_CONST char *\ntrio_error\nTRIO_PROTO((int));\n#endif\n\n#if defined(TRIO_FUNC_FORMAT_DATE_MAX)\nTRIO_PUBLIC_STRING size_t\ntrio_format_date_max\nTRIO_PROTO((char *target, size_t max, TRIO_CONST char *format, TRIO_CONST struct tm *datetime));\n#endif\n\n#if defined(TRIO_FUNC_HASH)\nTRIO_PUBLIC_STRING unsigned long\ntrio_hash\nTRIO_PROTO((TRIO_CONST char *string, int type));\n#endif\n\n#if defined(TRIO_FUNC_INDEX)\nTRIO_PUBLIC_STRING char *\ntrio_index\nTRIO_PROTO((TRIO_CONST char *string, int character));\n#endif\n\n#if defined(TRIO_FUNC_INDEX_LAST)\nTRIO_PUBLIC_STRING char *\ntrio_index_last\nTRIO_PROTO((TRIO_CONST char *string, int character));\n#endif\n\n#if defined(TRIO_FUNC_LENGTH)\nTRIO_PUBLIC_STRING size_t\ntrio_length\nTRIO_PROTO((TRIO_CONST char *string));\n#endif\n\n#if defined(TRIO_FUNC_LENGTH_MAX)\nTRIO_PUBLIC_STRING size_t\ntrio_length_max\nTRIO_PROTO((TRIO_CONST char *string, size_t max));\n#endif\n\n#if defined(TRIO_FUNC_LOWER)\nTRIO_PUBLIC_STRING int\ntrio_lower\nTRIO_PROTO((char *target));\n#endif\n\n#if defined(TRIO_FUNC_MATCH)\nTRIO_PUBLIC_STRING int\ntrio_match\nTRIO_PROTO((TRIO_CONST char *string, TRIO_CONST char *pattern));\n#endif\n\n#if defined(TRIO_FUNC_MATCH_CASE)\nTRIO_PUBLIC_STRING int\ntrio_match_case\nTRIO_PROTO((TRIO_CONST char *string, TRIO_CONST char *pattern));\n#endif\n\n#if defined(TRIO_FUNC_SPAN_FUNCTION)\nTRIO_PUBLIC_STRING size_t\ntrio_span_function\nTRIO_PROTO((char *target, TRIO_CONST char *source, int (*Function) TRIO_PROTO((int))));\n#endif\n\n#if defined(TRIO_FUNC_SUBSTRING)\nTRIO_PUBLIC_STRING char *\ntrio_substring\nTRIO_PROTO((TRIO_CONST char *string, TRIO_CONST char *substring));\n#endif\n\n#if defined(TRIO_FUNC_SUBSTRING_MAX)\nTRIO_PUBLIC_STRING char *\ntrio_substring_max\nTRIO_PROTO((TRIO_CONST char *string, size_t max, TRIO_CONST char *substring));\n#endif\n\n#if defined(TRIO_FUNC_TO_DOUBLE)\nTRIO_PUBLIC_STRING double\ntrio_to_double\nTRIO_PROTO((TRIO_CONST char *source, char **endp));\n#endif\n\n#if defined(TRIO_FUNC_TO_FLOAT)\nTRIO_PUBLIC_STRING float\ntrio_to_float\nTRIO_PROTO((TRIO_CONST char *source, char **endp));\n#endif\n\n#if defined(TRIO_FUNC_TO_LONG)\nTRIO_PUBLIC_STRING long\ntrio_to_long\nTRIO_PROTO((TRIO_CONST char *source, char **endp, int base));\n#endif\n\n#if defined(TRIO_FUNC_TO_LOWER)\nTRIO_PUBLIC_STRING int\ntrio_to_lower\nTRIO_PROTO((int source));\n#endif\n\n#if defined(TRIO_FUNC_TO_LONG_DOUBLE)\nTRIO_PUBLIC_STRING trio_long_double_t\ntrio_to_long_double\nTRIO_PROTO((TRIO_CONST char *source, char **endp));\n#endif\n\n#if defined(TRIO_FUNC_TO_UNSIGNED_LONG)\nTRIO_PUBLIC_STRING unsigned long\ntrio_to_unsigned_long\nTRIO_PROTO((TRIO_CONST char *source, char **endp, int base));\n#endif\n\n#if defined(TRIO_FUNC_TO_UPPER)\nTRIO_PUBLIC_STRING int\ntrio_to_upper\nTRIO_PROTO((int source));\n#endif\n\n#if defined(TRIO_FUNC_TOKENIZE)\nTRIO_PUBLIC_STRING char *\ntrio_tokenize\nTRIO_PROTO((char *string, TRIO_CONST char *delimiters));\n#endif\n\n#if defined(TRIO_FUNC_UPPER)\nTRIO_PUBLIC_STRING int\ntrio_upper\nTRIO_PROTO((char *target));\n#endif\n\n/*************************************************************************\n * Dynamic string functions\n */\n\n/*\n * Opaque type for dynamic strings\n */\n\ntypedef struct _trio_string_t trio_string_t;\n\n#if defined(TRIO_FUNC_STRING_APPEND)\nTRIO_PUBLIC_STRING int\ntrio_string_append\nTRIO_PROTO((trio_string_t *self, trio_string_t *other));\n#endif\n\n#if defined(TRIO_FUNC_STRING_CONTAINS)\nTRIO_PUBLIC_STRING int\ntrio_string_contains\nTRIO_PROTO((trio_string_t *self, trio_string_t *other));\n#endif\n\n#if defined(TRIO_FUNC_STRING_COPY)\nTRIO_PUBLIC_STRING int\ntrio_string_copy\nTRIO_PROTO((trio_string_t *self, trio_string_t *other));\n#endif\n\n#if defined(TRIO_FUNC_STRING_CREATE)\nTRIO_PUBLIC_STRING trio_string_t *\ntrio_string_create\nTRIO_PROTO((int initial_size));\n#endif\n\n#if defined(TRIO_FUNC_STRING_DESTROY)\nTRIO_PUBLIC_STRING void\ntrio_string_destroy\nTRIO_PROTO((trio_string_t *self));\n#endif\n\n#if defined(TRIO_FUNC_STRING_DUPLICATE)\nTRIO_PUBLIC_STRING trio_string_t *\ntrio_string_duplicate\nTRIO_PROTO((trio_string_t *other));\n#endif\n\n#if defined(TRIO_FUNC_STRING_EQUAL)\nTRIO_PUBLIC_STRING int\ntrio_string_equal\nTRIO_PROTO((trio_string_t *self, trio_string_t *other));\n#endif\n\n#if defined(TRIO_FUNC_STRING_EQUAL_MAX)\nTRIO_PUBLIC_STRING int\ntrio_string_equal_max\nTRIO_PROTO((trio_string_t *self, size_t max, trio_string_t *second));\n#endif\n\n#if defined(TRIO_FUNC_STRING_EQUAL_CASE)\nTRIO_PUBLIC_STRING int\ntrio_string_equal_case\nTRIO_PROTO((trio_string_t *self, trio_string_t *other));\n#endif\n\n#if defined(TRIO_FUNC_STRING_EQUAL_CASE_MAX)\nTRIO_PUBLIC_STRING int\ntrio_string_equal_case_max\nTRIO_PROTO((trio_string_t *self, size_t max, trio_string_t *other));\n#endif\n\n#if defined(TRIO_FUNC_STRING_EXTRACT)\nTRIO_PUBLIC_STRING char *\ntrio_string_extract\nTRIO_PROTO((trio_string_t *self));\n#endif\n\n#if defined(TRIO_FUNC_STRING_FORMAT_DATE_MAX)\nTRIO_PUBLIC_STRING size_t\ntrio_string_format_date_max\nTRIO_PROTO((trio_string_t *self, size_t max, TRIO_CONST char *format, TRIO_CONST struct tm *datetime));\n#endif\n\n#if defined(TRIO_FUNC_STRING_GET)\nTRIO_PUBLIC_STRING char *\ntrio_string_get\nTRIO_PROTO((trio_string_t *self, int offset));\n#endif\n\n#if defined(TRIO_FUNC_STRING_INDEX)\nTRIO_PUBLIC_STRING char *\ntrio_string_index\nTRIO_PROTO((trio_string_t *self, int character));\n#endif\n\n#if defined(TRIO_FUNC_STRING_INDEX_LAST)\nTRIO_PUBLIC_STRING char *\ntrio_string_index_last\nTRIO_PROTO((trio_string_t *self, int character));\n#endif\n\n#if defined(TRIO_FUNC_STRING_LENGTH)\nTRIO_PUBLIC_STRING int\ntrio_string_length\nTRIO_PROTO((trio_string_t *self));\n#endif\n\n#if defined(TRIO_FUNC_STRING_LOWER)\nTRIO_PUBLIC_STRING int\ntrio_string_lower\nTRIO_PROTO((trio_string_t *self));\n#endif\n\n#if defined(TRIO_FUNC_STRING_MATCH)\nTRIO_PUBLIC_STRING int\ntrio_string_match\nTRIO_PROTO((trio_string_t *self, trio_string_t *other));\n#endif\n\n#if defined(TRIO_FUNC_STRING_MATCH_CASE)\nTRIO_PUBLIC_STRING int\ntrio_string_match_case\nTRIO_PROTO((trio_string_t *self, trio_string_t *other));\n#endif\n\n#if defined(TRIO_FUNC_STRING_SIZE)\nTRIO_PUBLIC_STRING int\ntrio_string_size\nTRIO_PROTO((trio_string_t *self));\n#endif\n\n#if defined(TRIO_FUNC_STRING_SUBSTRING)\nTRIO_PUBLIC_STRING char *\ntrio_string_substring\nTRIO_PROTO((trio_string_t *self, trio_string_t *other));\n#endif\n\n#if defined(TRIO_FUNC_STRING_TERMINATE)\nTRIO_PUBLIC_STRING void\ntrio_string_terminate\nTRIO_PROTO((trio_string_t *self));\n#endif\n\n#if defined(TRIO_FUNC_STRING_UPPER)\nTRIO_PUBLIC_STRING int\ntrio_string_upper\nTRIO_PROTO((trio_string_t *self));\n#endif\n\n#if defined(TRIO_FUNC_XSTRING_APPEND)\nTRIO_PUBLIC_STRING int\ntrio_xstring_append\nTRIO_PROTO((trio_string_t *self, TRIO_CONST char *other));\n#endif\n\n#if defined(TRIO_FUNC_XSTRING_APPEND_CHAR)\nTRIO_PUBLIC_STRING int\ntrio_xstring_append_char\nTRIO_PROTO((trio_string_t *self, char character));\n#endif\n\n#if defined(TRIO_FUNC_XSTRING_CONTAINS)\nTRIO_PUBLIC_STRING int\ntrio_xstring_contains\nTRIO_PROTO((trio_string_t *self, TRIO_CONST char *other));\n#endif\n\n#if defined(TRIO_FUNC_XSTRING_COPY)\nTRIO_PUBLIC_STRING int\ntrio_xstring_copy\nTRIO_PROTO((trio_string_t *self, TRIO_CONST char *other));\n#endif\n\n#if defined(TRIO_FUNC_XSTRING_DUPLICATE)\nTRIO_PUBLIC_STRING trio_string_t *\ntrio_xstring_duplicate\nTRIO_PROTO((TRIO_CONST char *other));\n#endif\n\n#if defined(TRIO_FUNC_XSTRING_EQUAL)\nTRIO_PUBLIC_STRING int\ntrio_xstring_equal\nTRIO_PROTO((trio_string_t *self, TRIO_CONST char *other));\n#endif\n\n#if defined(TRIO_FUNC_XSTRING_EQUAL_MAX)\nTRIO_PUBLIC_STRING int\ntrio_xstring_equal_max\nTRIO_PROTO((trio_string_t *self, size_t max, TRIO_CONST char *other));\n#endif\n\n#if defined(TRIO_FUNC_XSTRING_EQUAL_CASE)\nTRIO_PUBLIC_STRING int\ntrio_xstring_equal_case\nTRIO_PROTO((trio_string_t *self, TRIO_CONST char *other));\n#endif\n\n#if defined(TRIO_FUNC_XSTRING_EQUAL_CASE_MAX)\nTRIO_PUBLIC_STRING int\ntrio_xstring_equal_case_max\nTRIO_PROTO((trio_string_t *self, size_t max, TRIO_CONST char *other));\n#endif\n\n#if defined(TRIO_FUNC_XSTRING_MATCH)\nTRIO_PUBLIC_STRING int\ntrio_xstring_match\nTRIO_PROTO((trio_string_t *self, TRIO_CONST char *other));\n#endif\n\n#if defined(TRIO_FUNC_XSTRING_MATCH_CASE)\nTRIO_PUBLIC_STRING int\ntrio_xstring_match_case\nTRIO_PROTO((trio_string_t *self, TRIO_CONST char *other));\n#endif\n\n#if defined(TRIO_FUNC_XSTRING_SET)\nTRIO_PUBLIC_STRING void\ntrio_xstring_set\nTRIO_PROTO((trio_string_t *self, char *buffer));\n#endif\n\n#if defined(TRIO_FUNC_XSTRING_SUBSTRING)\nTRIO_PUBLIC_STRING char *\ntrio_xstring_substring\nTRIO_PROTO((trio_string_t *self, TRIO_CONST char *other));\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* TRIO_TRIOSTR_H */\n"
  },
  {
    "path": "src/sdk/src/libc/src/udivmoddi4.c",
    "content": "\n \n\ntypedef int SItype __attribute__(( mode( SI ) ));\ntypedef unsigned int USItype __attribute__(( mode( SI ) ));\ntypedef int DItype __attribute__(( mode( DI ) ));\ntypedef unsigned int UDItype __attribute__(( mode( DI ) ));\n\n#define Wtype SItype\n#define UWtype USItype\n#define DWtype DItype\n#define UDWtype UDItype\n\n#define W_TYPE_SIZE 32\n\nstruct DWstruct {\n    Wtype low;\n    Wtype high;\n};\n\ntypedef union {\n    struct DWstruct s;\n    DWtype ll;\n} DWunion;\n\n#define udiv_qrnnd(q, r, n1, n0, dv) \\\n    __asm__(\"div{l} %4\" \\\n        : \"=a\" ((USItype) (q)), \"=d\" ((USItype) (r)) \\\n        : \"0\" ((USItype) (n0)), \"1\" ((USItype) (n1)), \"rm\" ((USItype) (dv)))\n\n#define sub_ddmmss(sh, sl, ah, al, bh, bl) \\\n    __asm__(\"sub{l} {%5,%1|%1,%5}\\n\\tsbb{l} {%3,%0|%0,%3}\" \\\n        : \"=r\" ((USItype) (sh)), \"=&r\" ((USItype) (sl)) \\\n        : \"0\" ((USItype) (ah)), \"g\" ((USItype) (bh)), \\\n          \"1\" ((USItype) (al)), \"g\" ((USItype) (bl)))\n\n#define umul_ppmm(w1, w0, u, v) \\\n    __asm__(\"mul{l} %3\" \\\n        : \"=a\" ((USItype) (w0)), \"=d\" ((USItype) (w1)) \\\n        : \"%0\" ((USItype) (u)), \"rm\" ((USItype) (v)))\n\n#define count_leading_zeros(count, x)   ((count) = __builtin_clz (x))\n\nstatic inline __attribute__(( __always_inline__ ))\nUDWtype __udivmoddi4( UDWtype n, UDWtype d, UDWtype* rp ) {\n    const DWunion nn = {.ll = n};\n    const DWunion dd = {.ll = d};\n    DWunion rr;\n    UWtype d0, d1, n0, n1, n2;\n    UWtype q0, q1;\n    UWtype b, bm;\n\n    d0 = dd.s.low;\n    d1 = dd.s.high;\n    n0 = nn.s.low;\n    n1 = nn.s.high;\n\n    if ( d1 == 0 ) {\n        if ( d0 > n1 ) {\n            /* 0q = nn / 0D */\n\n            udiv_qrnnd (q0, n0, n1, n0, d0);\n            q1 = 0;\n\n            /* Remainder in n0.  */\n        } else {\n            /* qq = NN / 0d */\n\n            if (d0 == 0)\n                d0 = 1 / d0;    /* Divide intentionally by zero.  */\n\n            udiv_qrnnd (q1, n1, 0, n1, d0);\n            udiv_qrnnd (q0, n0, n1, n0, d0);\n\n            /* Remainder in n0.  */\n        }\n\n        if (rp != 0) {\n            rr.s.low = n0;\n            rr.s.high = 0;\n            *rp = rr.ll;\n        }\n    } else {\n        if ( d1 > n1 )  {\n            /* 00 = nn / DD */\n\n            q0 = 0;\n            q1 = 0;\n\n            /* Remainder in n1n0.  */\n            if (rp != 0) {\n                rr.s.low = n0;\n                rr.s.high = n1;\n                *rp = rr.ll;\n            }\n        } else {\n            /* 0q = NN / dd */\n\n            count_leading_zeros (bm, d1);\n\n            if (bm == 0) {\n                /* From (n1 >= d1) /\\ (the most significant bit of d1 is set),\n                  conclude (the most significant bit of n1 is set) /\\ (the\n                  quotient digit q0 = 0 or 1).\n\n                This special case is necessary, not an optimization.  */\n\n                /* The condition on the next line takes advantage of that\n                  n1 >= d1 (true due to program flow).  */\n                if (n1 > d1 || n0 >= d0) {\n                    q0 = 1;\n                    sub_ddmmss (n1, n0, n1, n0, d1, d0);\n                } else\n                    q0 = 0;\n\n                q1 = 0;\n\n                if (rp != 0) {\n                    rr.s.low = n0;\n                    rr.s.high = n1;\n                    *rp = rr.ll;\n                }\n            } else {\n                UWtype m1, m0;\n                /* Normalize.  */\n\n                b = W_TYPE_SIZE - bm;\n\n                d1 = (d1 << bm) | (d0 >> b);\n                d0 = d0 << bm;\n                n2 = n1 >> b;\n                n1 = (n1 << bm) | (n0 >> b);\n                n0 = n0 << bm;\n\n                udiv_qrnnd (q0, n1, n2, n1, d1);\n                umul_ppmm (m1, m0, q0, d0);\n\n                if (m1 > n1 || (m1 == n1 && m0 > n0)) {\n                    q0--;\n                    sub_ddmmss (m1, m0, m1, m0, d1, d0);\n                }\n\n                q1 = 0;\n\n                /* Remainder in (n1n0 - m1m0) >> bm.  */\n                if (rp != 0) {\n                    sub_ddmmss (n1, n0, n1, n0, m1, m0);\n                    rr.s.low = (n1 << b) | (n0 >> bm);\n                    rr.s.high = n1 >> bm;\n                    *rp = rr.ll;\n                }\n            }\n        }\n    }\n\n    const DWunion ww = {{.low = q0, .high = q1}};\n\n    return ww.ll;\n}\n\nDWtype __moddi3( DWtype u, DWtype v ) {\n  Wtype c = 0;\n  DWunion uu = {.ll = u};\n  DWunion vv = {.ll = v};\n  DWtype w;\n\n  if ( uu.s.high < 0 )\n    c = ~c,\n    uu.ll = -uu.ll;\n\n  if ( vv.s.high < 0 )\n    vv.ll = -vv.ll;\n\n  ( void )__udivmoddi4( uu.ll, vv.ll, ( UDWtype* )&w );\n\n  if ( c )\n    w = -w;\n\n  return w;\n}\n\nUDWtype __umoddi3( UDWtype u, UDWtype v ) {\n    UDWtype w;\n\n    ( void )__udivmoddi4( u, v, &w );\n\n    return w;\n}\n\nDWtype __divdi3( DWtype u, DWtype v ) {\n  Wtype c = 0;\n  DWunion uu = {.ll = u};\n  DWunion vv = {.ll = v};\n  DWtype w;\n\n  if (uu.s.high < 0)\n    c = ~c,\n    uu.ll = -uu.ll;\n\n  if (vv.s.high < 0)\n    c = ~c,\n    vv.ll = -vv.ll;\n\n  w = __udivmoddi4( uu.ll, vv.ll, ( UDWtype* )0 );\n\n  if (c)\n    w = -w;\n\n  return w;\n}\n\nUDWtype __udivdi3( UDWtype n, UDWtype d ) {\n    return __udivmoddi4( n, d, ( UDWtype* )0 );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/access.c",
    "content": "#include <unistd.h>\n#include <errno.h>\n#include <os.h>\n\nint access( const char* pathname, int mode ) {\n    int error;\n\n    error = syscall2(\n        SYS_access,\n        ( int )pathname,\n        mode\n    );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/alarm.c",
    "content": "#include <unistd.h>\n\n\nunsigned int alarm( unsigned int seconds ) {\n    /* TODO */\n\n    printf( \"TODO: alarm() not yet implemented!\\n\" );\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/chdir.c",
    "content": "\n \n\n#include <errno.h>\n#include <unistd.h>\n\n#include <os.h>\n\nint chdir( const char* path ) {\n    int error;\n\n    error = syscall1( SYS_chdir, ( int )path );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/chown.c",
    "content": "#include <unistd.h>\n\n\nint chown( const char* path, uid_t owner, gid_t group ) {\n    /* TODO */\n\n    printf( \"TODO: chown() not yet implemented!\\n\" );\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/close.c",
    "content": "\n \n\n#include <errno.h>\n#include <unistd.h>\n\n#include <os.h>\n\nint close( int fd ) {\n    int error;\n\n    error = syscall1( SYS_close, fd );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/dup.c",
    "content": "\n \n\n#include <errno.h>\n#include <unistd.h>\n\n#include <os.h>\n\nint dup( int old_fd ) {\n    int error;\n\n    error = syscall1( SYS_dup, old_fd );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return error;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/dup2.c",
    "content": "\n \n\n#include <errno.h>\n#include <unistd.h>\n\n#include <os.h>\n\nint dup2( int old_fd, int new_fd ) {\n    int error;\n\n    error = syscall2( SYS_dup2, old_fd, new_fd );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return error;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/execlp.c",
    "content": "#include <unistd.h>\n#include <stdarg.h>\n#include <errno.h>\n#include <alloca.h>\n\nint execlp( const char* file, const char* arg, ... ) {\n    int i;\n    int n;\n    va_list ap;\n    va_list bak;\n    char* tmp;\n    char** argv;\n\n    va_start( ap, arg );\n    __va_copy( bak, ap );\n\n    n = 2;\n\n    while ( ( tmp = va_arg( ap, char* ) ) != NULL ) {\n        ++n;\n    }\n\n    va_end( ap );\n\n    argv = ( char** )alloca( n * sizeof( char* ) );\n\n    if ( argv != NULL ) {\n        argv[ 0 ]= ( char* )arg;\n\n        for ( i = 0 ; i < n; ++i ) {\n            argv[ i + 1 ] = va_arg( bak, char* );\n        }\n\n        va_end( bak );\n\n        return execvp( file, argv );\n    }\n\n    va_end( bak );\n\n    errno = ENOMEM;\n\n    return -1;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/execv.c",
    "content": "#include <unistd.h>\n\nextern char** environ;\n\nint execv( const char* file, char* const argv[] ) {\n    return execve( file, argv, environ );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/execve.c",
    "content": "\n \n\n#include <errno.h>\n#include <unistd.h>\n\n#include <os.h>\n\nint execve( const char* filename, char* const argv[], char* const envp[] ) {\n    int error;\n\n    error = syscall3( SYS_execve, ( int )filename, ( int )argv, ( int )envp );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return error;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/execvp.c",
    "content": "#include <unistd.h>\n#include <stdlib.h>\n#include <errno.h>\n#include <string.h>\n#include <stdio.h>\n\nextern char** environ;\n\nint execvp( const char* filename, char* const argv[] ) {\n    char* path;\n    char* separator;\n    char tmp_path[ 128 ];\n    char tmp_exec[ 128 ];\n\n    execve( filename, argv, environ );\n\n    path = getenv( \"PATH\" );\n\n    if ( path == NULL ) {\n        return -1;\n    }\n\n    do {\n        separator = strchr( path, ':' );\n\n        if ( separator == NULL ) {\n            memcpy( tmp_path, path, strlen( path ) + 1 );\n        } else {\n            size_t length = ( separator - path );\n\n            memcpy( tmp_path, path, length );\n            tmp_path[ length ] = 0;\n        }\n\n        snprintf( tmp_exec, sizeof( tmp_exec ), \"%s/%s\", tmp_path, filename );\n        execve( tmp_exec, argv, environ );\n\n        path = separator + 1;\n    } while ( separator != NULL );\n\n    return -1;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/exit.c",
    "content": "#include <unistd.h>\n#include <stdlib.h>\n#include <stdio.h>\n#include <sys/types.h>\n\n#include <os.h>\n\ntypedef void ( *atexit_func_t )( void );\n\nstatic uint32_t atexit_count = 0;\nstatic atexit_func_t atexit_functions[ ATEXIT_MAX ];\n\nint atexit( void ( *function )( void ) ) {\n    if ( atexit_count >= ATEXIT_MAX ) {\n        return -1;\n    }\n\n    atexit_functions[ atexit_count++ ] = function;\n\n    return 0;\n}\n\n\n\nvoid exit( int status ) {\n    uint32_t i;\n\n    for ( i = 0; i < atexit_count; i++ ) {\n        atexit_functions[ i ]();\n    }\n\n    fflush( stdout );\n    syscall1( SYS_exit, status );\n\tfor (;;);\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/fchdir.c",
    "content": "\n \n\n#include <errno.h>\n#include <unistd.h>\n\n#include <os.h>\n\nint fchdir( int fd ) {\n    int error;\n\n    error = syscall1( SYS_fchdir, fd );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/fork.c",
    "content": "#include <unistd.h>\n\n#include <os.h>\n\npid_t fork( void ) {\n    return syscall0( SYS_fork );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/fpathconf.c",
    "content": "\n \n\n#include <errno.h>\n#include <unistd.h>\n\nlong fpathconf( int fd, int name ) {\n    /* TODO */\n\n    return -1;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/ftruncate.c",
    "content": "#include <unistd.h>\n\n\nint ftruncate( int fd, off_t length ) {\n    /* TODO */\n\n    printf( \"TODO: ftruncate() not yet implemented!\\n\" );\n\n    return -1;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/getcwd.c",
    "content": "\n \n\n#include <stdlib.h>\n#include <unistd.h>\n#include <dirent.h>\n#include <errno.h>\n#include <string.h>\n#include <limits.h>\n#include <sys/stat.h>\n#include <sys/param.h>\n\nchar* getcwd( char* buf, size_t size ) {\n    static const char dots[] = \"../../../../../../../../../../../../../../../../../../../../../../../\\\n        ../../../../../../../../../../../../../../../../../../../../../../../../../../\\\n        ../../../../../../../../../../../../../../../../../../../../../../../../../..\";\n    const char* dotp = &dots[ sizeof( dots ) ];\n    const char* dotlist = dots;\n    size_t dotsize = sizeof( dots ) - 1;\n    dev_t rootdev, thisdev;\n    ino_t rootino, thisino;\n    char* path;\n    register char* pathp;\n    struct stat st;\n    size_t allocated = size;\n\n    if ( size == 0 ) {\n        if ( buf != NULL ) {\n            return NULL;\n        }\n\n        allocated = PATH_MAX + 1;\n    }\n\n    if ( buf != NULL ) {\n        path = buf;\n    } else {\n        path = malloc( allocated );\n\n        if ( path == NULL ) {\n            return NULL;\n        }\n    }\n\n    pathp = path + allocated;\n    *--pathp = '\\0';\n\n    if ( stat( \".\", &st ) < 0 ) {\n        goto lose2;\n    }\n\n    thisdev = st.st_dev;\n    thisino = st.st_ino;\n\n    if ( stat( \"/\", &st ) < 0 ) {\n        goto lose2;\n    }\n\n    rootdev = st.st_dev;\n    rootino = st.st_ino;\n\n    while ( !( thisdev == rootdev && thisino == rootino ) ) {\n        register DIR *dirstream;\n        struct dirent* d;\n        dev_t dotdev;\n        ino_t dotino;\n        char mount_point;\n\n        /* Look at the parent directory.  */\n\n        if ( dotp == dotlist ) {\n            /* My, what a deep directory tree you have, Grandma.  */\n\n            char* new;\n\n            if ( dotlist == dots ) {\n                new = malloc( dotsize * 2 + 1 );\n\n                if ( new == NULL ) {\n                    goto lose;\n                }\n\n#ifdef HAVE_MEMPCPY\n                dotp = mempcpy( new, dots, dotsize );\n#else\n                memcpy( new, dots, dotsize );\n                dotp = &new[ dotsize ];\n#endif\n            } else {\n                new = realloc( ( void* )dotlist, dotsize * 2 + 1 );\n\n                if ( new == NULL ) {\n                    goto lose;\n                }\n\n                dotp = &new[ dotsize ];\n            }\n#ifdef HAVE_MEMPCPY\n            *( ( char* )mempcpy( ( char* )dotp, new, dotsize ) ) = '\\0';\n            dotsize *= 2;\n#else\n            memcpy( ( char* )dotp, new, dotsize );\n            dotsize *= 2;\n            new[ dotsize ] = '\\0';\n#endif\n            dotlist = new;\n        }\n\n        dotp -= 3;\n\n        /* Figure out if this directory is a mount point. */\n\n        if ( stat( dotp, &st ) < 0 ) {\n            goto lose;\n        }\n\n        dotdev = st.st_dev;\n        dotino = st.st_ino;\n        mount_point = dotdev != thisdev;\n\n        /* Search for the last directory. */\n\n        dirstream = opendir( dotp );\n\n        if ( dirstream == NULL ) {\n            goto lose;\n        }\n\n        while ( ( d = readdir( dirstream ) ) != NULL ) {\n            if ( d->d_name[ 0 ] == '.' &&\n                 ( d->d_name[ 1 ] == '\\0' || (d->d_name[ 1 ] == '.' && d->d_name[ 2 ] == '\\0' ) ) ) {\n                continue;\n            }\n\n            if ( mount_point || ( ino_t )d->d_ino == thisino ) {\n                char name[ dotlist + dotsize - dotp + 1 + _D_ALLOC_NAMLEN( d ) ];\n\n#ifdef HAVE_MEMPCPY\n                char *tmp = mempcpy( name, dotp, dotlist + dotsize - dotp );\n                *tmp++ = '/';\n                strcpy( tmp, d->d_name );\n#else\n                memcpy( name, dotp, dotlist + dotsize - dotp );\n                name[ dotlist + dotsize - dotp ] = '/';\n                strcpy( &name[ dotlist + dotsize - dotp + 1 ], d->d_name );\n#endif\n\n                /* We don't fail here if we cannot stat() a directory entry.\n                   This can happen when (network) filesystems fail.  If this\n                   entry is in fact the one we are looking for we will find\n                   out soon as we reach the end of the directory without\n                   having found anything.  */\n\n                if ( stat( name, &st ) >= 0 &&\n                     st.st_dev == thisdev && st.st_ino == thisino ) {\n                    break;\n                }\n            }\n        }\n\n        if ( d == NULL ) {\n            ( void )closedir( dirstream );\n\n            goto lose;\n        } else {\n            size_t namlen = _D_EXACT_NAMLEN( d );\n\n            if ( ( size_t )( pathp - path ) <= namlen ) {\n                if (size != 0) {\n                    ( void )closedir( dirstream );\n                    goto lose;\n                } else {\n                    char* tmp;\n                    size_t oldsize = allocated;\n\n                    allocated = 2 * MAX( allocated, namlen );\n                    tmp = realloc( path, allocated );\n\n                    if ( tmp == NULL ) {\n                        ( void )closedir( dirstream );\n                        goto lose;\n                    }\n\n                    /* Move current contents up to the end of the buffer.\n                       This is guaranteed to be non-overlapping.  */\n\n                    pathp = memcpy(\n                        tmp + allocated - ( path + oldsize - pathp ),\n                        tmp + ( pathp - path ),\n                        path + oldsize - pathp\n                    );\n\n                    path = tmp;\n                }\n            }\n\n            pathp -= namlen;\n            ( void )memcpy( pathp, d->d_name, namlen );\n            *--pathp = '/';\n            ( void )closedir( dirstream );\n        }\n\n        thisdev = dotdev;\n        thisino = dotino;\n    }\n\n    if ( pathp == &path[ allocated - 1 ] ) {\n        *--pathp = '/';\n    }\n\n    if ( dotlist != dots ) {\n        free( ( void* )dotlist );\n    }\n\n    memmove( path, pathp, path + allocated - pathp );\n\n    return path;\n\nlose:\n    if ( dotlist != dots ) {\n        free( ( void* )dotlist );\n    }\n\nlose2:\n    if ( buf == NULL ) {\n        free( path );\n    }\n\n    return NULL;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/getdents.c",
    "content": "\n \n\n#include <errno.h>\n#include <unistd.h>\n\n#include <os.h>\n\nint getdents( int fd, struct dirent* entry, unsigned int count ) {\n    int error;\n\n    error = syscall3( SYS_getdents, fd, ( int )entry, count );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return error;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/getdtablesize.c",
    "content": "#include <unistd.h>\n\nint getdtablesize( void ) {\n    return 1024;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/getegid.c",
    "content": "#include <unistd.h>\n\ngid_t getegid( void ) {\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/geteuid.c",
    "content": "#include <unistd.h>\n\nuid_t geteuid( void ) {\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/getgid.c",
    "content": "#include <unistd.h>\n\ngid_t getgid( void ) {\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/gethostname.c",
    "content": "#include <unistd.h>\n#include <stdio.h>\n\nint gethostname( char* name, size_t len ) {\n    /* TODO */\n\n    snprintf( name, len, \"localhost\" );\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/getpgid.c",
    "content": "#include <unistd.h>\n\npid_t getpgid( pid_t pid ) {\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/getpgrp.c",
    "content": "#include <unistd.h>\n\npid_t getpgrp( void ) {\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/getpid.c",
    "content": "#include <unistd.h>\n\n#include <os.h>\n\npid_t getpid( void ) {\n    return syscall0( SYS_getpid );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/getppid.c",
    "content": "#include <unistd.h>\n\npid_t getppid( void ) {\n    /* TODO! */\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/gettid.c",
    "content": "\n \n\n#include <errno.h>\n#include <unistd.h>\n\n#include <os.h>\n\npid_t gettid( void ) {\n    return syscall0( SYS_gettid );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/getuid.c",
    "content": "#include <unistd.h>\n#include <os.h>\n\nuid_t getuid( void ) {\n\treturn syscall0( SYS_getuid );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/isatty.c",
    "content": "\n \n\n#include <errno.h>\n#include <unistd.h>\n\n#include <os.h>\n\nint isatty( int fd ) {\n    int error;\n\n    error = syscall1( SYS_isatty, fd );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return 0;\n    }\n\n    return error;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/link.c",
    "content": "#include <unistd.h>\n\n\nint link( const char* oldpath, const char* newpath ) {\n    /* TODO */\n\n    printf( \"TODO: link() not yet implemented!\\n\" );\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/lseek.c",
    "content": "\n \n\n#include <errno.h>\n#include <unistd.h>\n\n#include <os.h>\n\noff_t lseek( int fd, off_t offset, int whence ) {\n    int error;\n    off_t result;\n\n    error = syscall4( SYS_lseek, fd, ( int )&offset, whence, ( int )&result );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return ( off_t )-1;\n    }\n\n    return result;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/mmap.c",
    "content": "\n \n\n#include <errno.h>\n#include <unistd.h>\n\n#include <os.h>\n\nvoid * mmap (void *addr,size_t len,int prot,int flags,int fd,off_t offset){\n\treturn (void*)syscall5(SYS_mmap,(uint32_t) len, (uint32_t) prot, (uint32_t) flags,(uint32_t) fd,(uint32_t) offset);\n}\n\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/pipe.c",
    "content": "#include <unistd.h>\n\n\nint pipe( int pipefd[2] ) {\n    /* TODO */\n\n    printf( \"TODO: pipe() not yet implemented!\\n\" );\n\n    return -1;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/pread.c",
    "content": "\n \n\n#include <errno.h>\n#include <unistd.h>\n\n#include <os.h>\n\nssize_t pread( int fd, void* buf, size_t count, off_t offset ) {\n    int error;\n\n    error = syscall4( SYS_pread, fd, ( int )buf, count, ( int )&offset );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return error;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/pwrite.c",
    "content": "\n \n\n#include <errno.h>\n#include <unistd.h>\n\n#include <os.h>\n\nssize_t pwrite( int fd, const void* buf, size_t count, off_t offset ) {\n    int error;\n\n    error = syscall4( SYS_pwrite, fd, ( int )buf, count, ( int )&offset );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return error;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/read.c",
    "content": "\n \n\n#include <errno.h>\n#include <unistd.h>\n\n#include <os.h>\n\nssize_t read( int fd, void* buf, size_t count ) {\n    int error;\n\n    error = syscall3( SYS_read, fd, ( int )buf, count );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return error;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/readlink.c",
    "content": "\n \n\n#include <errno.h>\n#include <stdio.h>\n#include <unistd.h>\n\n#include <os.h>\n\nssize_t readlink( const char* path, char* buf, size_t bufsiz ) {\n    int error;\n\n    error = syscall3( SYS_readlink, ( int )path, ( int )buf, bufsiz );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return error;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/rmdir.c",
    "content": "\n \n\n#include <errno.h>\n#include <unistd.h>\n\n#include <os.h>\n\nint rmdir( const char* pathname ) {\n    int error;\n\n    error = syscall1( SYS_rmdir, ( int )pathname );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/sbrk.c",
    "content": "\n \n#include <os.h>\n\nvoid* sbrk( int increment ) {\n    return ( void* )syscall1( SYS_sbrk, increment );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/setgid.c",
    "content": "#include <unistd.h>\n\nint setgid( gid_t gid ) {\n    return 0;\n}\n\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/setpgid.c",
    "content": "#include <unistd.h>\n\nint setpgid( pid_t pid, pid_t pgid ) {\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/setpgrp.c",
    "content": "#include <unistd.h>\n\nint setpgrp( void ) {\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/setregid.c",
    "content": "#include <unistd.h>\n\nint setregid( gid_t rgid, gid_t egid ) {\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/setreuid.c",
    "content": "#include <unistd.h>\n\nint setreuid( uid_t ruid, uid_t euid ) {\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/setuid.c",
    "content": "#include <unistd.h>\n\nint setuid( uid_t uid ) {\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/sleep.c",
    "content": "#include <unistd.h>\n\n#include <os.h>\n\nunsigned int sleep( unsigned int seconds ) {\n    uint64_t time;\n\n    time = seconds * 1000000;\n\n    syscall2( SYS_sleep_thread, ( int )&time, ( int )NULL );\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/symlink.c",
    "content": "#include <errno.h>\n#include <unistd.h>\n\n#include <os.h>\n\nint symlink( const char* oldpath, const char* newpath ) {\n    int error;\n\n    error = syscall2( SYS_symlink, ( int )oldpath, ( int )newpath );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/ttyname.c",
    "content": "#include <fcntl.h>\n#include <unistd.h>\n#include <stdio.h>\n#include <sys/stat.h>\n\nstatic char ttyname_buffer[ 128 ];\n\nint ttyname_r( int fd, char* buf, size_t buflen ) {\n    int dir;\n    int error;\n    int found;\n\n    struct stat st;\n    struct dirent entry;\n\n    error = fstat( fd, &st );\n\n    if ( error < 0 ) {\n        return -1;\n    }\n\n    dir = open( \"/device/terminal\", O_RDONLY );\n\n    if ( dir < 0 ) {\n        return -1;\n    }\n\n    found = 0;\n\n    while ( getdents( dir, &entry, sizeof( struct dirent ) ) == 1 ) {\n        if ( entry.d_ino == st.st_ino ) {\n            snprintf( buf, buflen, \"/device/terminal/%s\", entry.d_name );\n            found = 1;\n            break;\n        }\n    }\n\n    close( dir );\n\n    if ( !found ) {\n        return -1;\n    }\n\n    return 0;\n}\n\nchar* ttyname( int fd ) {\n    int error;\n\n    error = ttyname_r( fd, ttyname_buffer, sizeof( ttyname_buffer ) );\n\n    if ( error < 0 ) {\n        return NULL;\n    }\n\n    return ttyname_buffer;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/unlink.c",
    "content": "\n \n\n#include <errno.h>\n#include <unistd.h>\n\n#include <os.h>\n\nint unlink( const char* pathname ) {\n    int error;\n\n    error = syscall1( SYS_unlink, ( int )pathname );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/unistd/write.c",
    "content": "#include <errno.h>\n#include <unistd.h>\n\n#include <os.h>\n\nssize_t write( int fd, const void* buf, size_t count ) {\n    int error;\n\n    error = syscall3( SYS_write, fd, ( int )buf, count );\n\n    if ( error < 0 ) {\n        errno = -error;\n        return -1;\n    }\n\n    return error;\n}\n"
  },
  {
    "path": "src/userland/Makefile",
    "content": "\nall:\n\tmake -C \"helloworld\" all\n\nclean:\n\tmake -C \"helloworld\" clean\n\n"
  },
  {
    "path": "src/userland/helloworld/Makefile",
    "content": "SDKDIR=../../sdk\nTARGET = hello\nOBJS=main.o\n\ninclude $(SDKDIR)/build.mak\n\n"
  },
  {
    "path": "src/userland/helloworld/main.c",
    "content": "#include <stdlib.h>\r\n#include <stdio.h>\r\n#include <sys/types.h>\r\n#include <sys/stat.h>\r\n#include <fcntl.h>\r\n#include <dirent.h>\r\n#include <unistd.h>\r\n\r\nint main(int argc,char **argv){\r\n\tprintf(\"hello world ! \\n\");\r\n\treturn 0;\r\n}"
  }
]