NNNNNNз/p щ NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNхххюOчNNNNNNNNNNNNNNNNNNNNNNхххыеееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееёчяяяяя`Ђ   А а @`яЏряАа! #@%`'Ђ) +А-а/1 3@5`7Ђ9 ;А=а?A C@E`GЂI KАMаOQ S@U`WЂY [А]а_a c@e`gряi kАmаoq sряu`wЂy {А}аЃ ѓ@…`‡Ђ‰ ‹АЌаЏ ‘ “@ •` —Ђ ™  ›А ќа џ Ў яяяяяяяЏ яЇ яяя­ряяяя±ряі@ µ` яяя№ряяяяЅа їряБряяяяяяяЗЂ Й  ЛА На П С У@ Х` ЧЂ Щ  ЫА Эа Яб г@е`зЂй лАнапс у@х`чЂщ ыАэая!AaЃ ся ся б!AaЃяяяБб!!#A%aяяя)Ў+Б-б/1сяяO5a7Ѓ9Ў;Б=б?AсяCAEaGЃIЎKБMбOQ!яOUaWЃYЎ[Б]б_сяa!cAeagЃiЎkБmбoq!sAuawЃyЎ{Б}бЃ!ѓA…a‡Ѓ‰Ў‹БЌбЏ‘!“A•a—Ѓ™Ў›БќбџЎ!ЈAҐa§Ѓ©Ў«Б­бЇся±!іAµa·Ѓ№Ў»БЅбїБ!ГAЕaЗЃЙЎЛБНбПСсяУAХaЧЃЩЎЫБЭбЯб!гAяoзЃйЎлБнбпс!уAхaчЃщЎяПэбя " B яo ‚ ў В тя!"!B!b!‚!ў!В!в!"!""#B"%b"'‚")тячяяяяя`Ђ   А а @`яЏряАа! #@%`'Ђ) +А-а/1 3@5`7Ђ9 ;А=а?A C@E`GЂI KАMаOQ S@U`WЂY [А]а_a c@e`gряi kАmаoq sряu`wЂy {А}аЃ ѓ@…`‡Ђ‰ ‹АЌаЏ ‘ “@ •` —Ђ ™  ›А ќа џ Ў яяяяяяяЏ яЇ яяя­ряяяя±ряі@ µ` яяя№ряяяяЅа їряБряяяяяяяЗЂ Й  ЛА На П С У@ Х` ЧЂ Щ  ЫА Эа Яб г@е`зЂй лАнапс у@х`чЂщ ыАэая!AaЃ ся ся б!AaЃяяяБб!!#A%aяяя)Ў+Б-б/1сяяO5a7Ѓ9Ў;Б=б?AсяCAEaGЃIЎKБMбOQ!яOUaWЃYЎ[Б]б_сяa!cAeagЃiЎkБmбoq!sAuawЃyЎ{Б}бЃ!ѓA…a‡Ѓ‰Ў‹БЌбЏ‘!“A•a—Ѓ™Ў›БќбџЎ!ЈAҐa§Ѓ©Ў«Б­бЇся±!іAµa·Ѓ№Ў»БЅбїБ!ГAЕaЗЃЙЎЛБНбПСсяУAХaЧЃЩЎЫБЭбЯб!гAяoзЃйЎлБнбпс!уAхaчЃщЎяПэбя " B яo ‚ ў В тя!"!B!b!‚!ў!В!в!"!""#B"%b"'‚")тяSOZOBONSOZOBON U–. V–.. V–DOC a–INCLUDE z–ЈLIB °–ЕBIN м–. b–.. b–BATCHMONDOC c–ўHCCD DOC f–ЪDLIBS DOC i–g4MAKE DOC r–he,SOZOBON DOC u–t\є BATCHMON v2.1 The simple batch monitor by Ian "I didn't really do this" Lepore ----------------------------------------------------------------------- Release Notes ----------------------------------------------------------------------- Version 2.1 added the following new features: - Support for environment strings. - The ability to change the default and exe paths. - It can be compiled with a vanilla Sozobon C setup. Anything using my custom libraries has been converted to the dLibs functions, or has been included in source form. Version 2.0 added the following new features: - Big batch files. - A couple built-in commands to help lighten up on floppy disk I/O. - Something that works well with TurboST's bugs. ----------------------------------------------------------------------- Batch Files ----------------------------------------------------------------------- Batch files are a series of command statements with optional parameters to be processed by the command. Some commands are processed internally by the monitor; anything that doesn't fall into the internal category is assumed to be a program command, and it is Pexec'd. Batch files can contain variables, and the value of those variables can be supplied at runtime, with the batch monitor substituting the runtime text for the variable symbols as they are encountered in the batch file. The commands in the batch file are not case-sensitive. The first word on each line (command or program name) will be forced to uppercase internally, but the rest of the command line (parms to passed to the called program) are NOT changed in terms of case. When specifying program names, a drive and path specification may be included as part of the program name, if necessary. ----------------------------------------------------------------------- Internal Commands ----------------------------------------------------------------------- The batch monitor recognizes the following internal commands: COM REM - These commands are totally ignored, allowing you to insert comments in your batch files. In addition to these, any line starting with '!', '*', or ';' will be considered a comment, but the character MUST be in column 1. DEL DELETE - These commands delete 1-10 files, as specified on the rest of the command line. Example: DEL myfile1.txt myfile2.txt DELETE %1.tmp %1.obj WAIT PAUSE - These commands stop and wait for you to hit a key. Any parms on the line will be ignored, so you can include comments on the line that pauses the run. RCSTOP NORCSTOP - These commands turn on or off a flag which will stop and prompt you if any program returns a non-zero return code. Some compiler pieces are smart enough to exit with a non-zero code if errors occurred. Some badly written programs always (or randomly) return non-zero. You can use these codes to toggle the status on and off around such programs. When the batch montitor starts, the default is RCSTOP. Example: NORCSTOP Stupid 'badprog' always returns 1! BADPROG.PRG parm1 %1 %2 parm2 RCSTOP Resume RC checking. Note that parms are ignored, so you can put comments on same line as the commands. SETENV - This command allows access to the environment string that will be passed to all called programs. Whatever follows the 'setenv' on the command line is passed to the dLibs 'putenv()' function as is. The rules for 'putenv' are as follows: = The first format (just a variable name) will remove that variable from the current env string if it exists. The second format allows you to set a variable to a string. Example: SETENV PATH=c:\bin\;a:\ SETENV INCLUDE (I have no idea whether this command works. If the dLibs putenv() function works, then this should. I have no easy way of testing it, though.) EXEPATH - This command allows you to set a new path which BATCHMON will use to find the programs specified in the rest of the batch file. Note that this does not affect the DOS default path; any programs run by BATCHMON will inherit the current default path (either the path BATCHMON was run from, or the path specified in the last 'DEFPATH' command). The pathname you specify for this command may include a drive, and it may end with a '\' character or not, at your preference. Examples: EXEPATH c:\bin EXEPATH \sozobon\bin EXEPATH The last example is equivelant to specifying '\'; it sets the path to the root of the current default drive. DEFPATH - This command sets the DOS default path. Unless you have used the EXEPATH command, this will affect BATCHMON (and where it will look for the programs you want run). It will always affect the programs called by BATCHMON; those programs will also inherit the specified default path. If you specify a drive letter as part of the path, that drive will become the new default drive. You may specify a trailing '\' character or not, as you prefer. Examples: DEFPATH \data DEFPATH d:\source\ DEFPATH The last example is equivelant to specifying '\'; it sets the path to the root of the current default drive. Internal commands (and indeed, anything) can be entered in upper, lower, or mixed case in the batch file. The first word on each line (the command or program name) is upper-cased by the program internally, and the rest of the text and variables are left in the original case. Note that the desktop uppercases things typed into a .TTP dialog box. ----------------------------------------------------------------------- Variables ----------------------------------------------------------------------- Variables in the batch file are %0 through %9. The percent sign followed by a single digit will always be interpreted as a variable. A percent sign followed by anything else is not, so you don't have to double up on percent signs to get a single one, as with some systems. On the other hand, there is no way to include the literal text "%1", it will always be interpreted as a variable. The variable '%0' is a special case: It is the name of the batch file that's running. Note that it is the name that was passed to the batch monitor, or typed by the user, and if it didn't have ".BAT" on it at that time, it won't at substitution (even if the monitor had to tack on a ".BAT" to open the file successfully, this doesn't find its way into '%0'). I dunno if the '%0' variable will ever be useful to anyone, but it's a sort of freebie in the way the parser works). The variables '%1' through '%9' correspond to the first through ninth words you passed to the batch monitor at startup (or typed in when prompted). By 'words' I mean groups of characters delimited by spaces. I think it's about time for an example. Suppose you have the following batch file: COM XMPL.BAT - A stupid example file. compile %1.c asm %2.s link newprog=startup %1.obj %2.o %3 And then suppose you click on BATCHMON.TTP from the desktop, and enter the following in the dialog box (or you enter BATCHMON in your shell, followed by these parms): xmpl cprog asmprog some,link,parms Then the batch monitor would do the substitutions as follows: COM XMPL.BAT - A stupid example file. compile cprog.c asm asmprog.s link newprog=startup cprog.obj asmprog.o some,link,parms Notice that the commas weren't delimeters...to the batch monitor. They are to most linkers, and that can be handy. If your batch file contains a '%3' variable (for example), and you only typed 2 parms at runtime, you will see a warning message, and the '%3' will disappear. (You will only be warned on the first occurance of each non-existant variable.) This lets you implement 'optional' variables in your batch files. In the above example, if you didn't enter the third parameter ('some,link,parms'), the last line would have substituted to: link newprog=startup cprog.obj asmprog.o The first word on a line in a batch file cannot be a variable (it won't get substituted); that is, you can't execute a command or program via a variable-supplied name. ----------------------------------------------------------------------- General Notes ----------------------------------------------------------------------- The batch monitor can be run as a .TOS or .TTP. If you run it from desktop as a .PRG you'll get ugly output. You can run it from within a shell, if the shell doesn't have a batch/script facility. The first parm you pass to the BATCHMON program should be the name of a batch file, which usually ends in .BAT (it don't have to, but if you just pass the name MYBATCH the program will assume MYBATCH.BAT). The second through tenth parms (optional) correspond the the variables %1-%9. If you don't pass any parms, the program will prompt you to enter the batch filename and parms. A handy way to use the batch monitor is a method which doesn't use variables. You build a custom .BAT file to compile the application you're working on (don't put any % variables in the batch file), and then install BATCHMON.TTP as an application on the desktop for file type ".BAT". Then, when you double-click on "filename.BAT", it'll fire up the monitor and run the batch file. Make sure the last command in the batch file is a WAIT/PAUSE so you can view the output before returning to desktop. If you're using this method, you can still run batch files which use variables by clicking on BATCHMON.TTP and typing in the batch file name and parms. To give the programs you're running in batch the appearance of commands, it's not necessary to add the .PRG part of the program name. The batch monitor checks for a file type, and if there is one, fine; if not, it adds ".PRG". When you are prompted for input (even single-char Y or N type), you will have to hit . No hotkey input for this kid! The batch monitor does all it's console I/O with BIOS calls. This may defeat any I/O redirection you have in effect, but it sure makes life easier if you have the fast-but-buggy TurboST software installed. Good ol' TurboST makes a lot of DOS console calls buggy. This version of the monitor is a little bigger than the last one (almost 10k!), but it should only matter to a floppy disk user, who'll notice a slightly longer load time. The builtin wait and delete commands should help a lot, though. Also, I haven't checked but I'll bet the runtime memory usage is about 15-17k, I used lots of wasteful buffers (and now, the wasteful dLibs runtime library). This monitor was intended to emulate the one delivered with the original ST developer's package. Not that that was a great batch monitor that deserves emulation, it's just that ALL my batch files (litterally hundreds) are set up for that. ----------------------------------------------------------------------- Notes about use with the Alcyon Compiler ----------------------------------------------------------------------- A typical batch file to compile the application FUNPROG might look like the following example (on my system, drive G is a ramdisk)... CP68 FUNPROG.C g:FUNPROG.I C068 g:FUNPROG.I g:FUNPROG.1 g:FUNPROG.2 g:FUNPROG.3 -f C168 g:FUNPROG.1 g:FUNPROG.2 g:FUNPROG.S DELETE g:FUNPROG.I g:FUNPROG.1 g:FUNPROG.2 MAC -6 -v -og:FUNPROG.o g:FUNPROG.s DELETE g:FUNPROG.S aln -w -v -o FUNPROG.prg apstart.o g:FUNPROG.o libi.bnd DELETE g:FUNPROG.O WAIT A 'generic' batch file to compile a C application whose name is supplied when the batch is started might look like... CP68 %1.C g:%1.I C068 g:%1.I g:%1.1 g:%1.2 g:%1.3 -f C168 g:%1.1 g:%1.2 g:%1.S DELETE g:%1.I g:%1.1 g:%1.2 MAC -6 -v -og:%1.o g:%1.s DELETE g:%1.S aln -w -v -o %1.prg apstart.o g:%1 libi.bnd %2 %3 %4 %5 DELETE g:%1.O WAIT If you started BATCHMON and supplied the single parameter 'FUNPROG', this batch file would run exactly like the previous example. If you supplied the parameters as 'FUNPROG VDI.LIB AES.LIB', the batch would run like the previous example except that your VDI and AES libraries would be added to the linker's command line. ----------------------------------------------------------------------- Notes for use with the Sozobon Compiler ----------------------------------------------------------------------- Sozobon C includes a 'cc' driver program which replaces the need for batch files, if you are using a command shell. Because some of the compiler pieces recognize case-sensitive switches, it is virtually impossible to run Sozobon C directly from the desktop (and from some shells), because all command line parms get forced to uppercase. Using BATCHMON in place of 'cc' allows you to get around these problems, and allows you to direct the intermediate files during the compiler passes to a ramdisk, something which is not available when using 'cc'. Also, the Sozobon compiler pieces make certain assumptions about the paths where things can be found, and allow you to override these assumptions using envstring variables, so BATCHMON includes support for setting env strings. The following examples again assume device G is a ramdisk... If Sozobon has been installed exactly as described in it's docs... hcc %1.c top %1.s g:%1.s jas -o g:%1.o g:%1.s DEFPATH \sozobon\lib ld -o %1.prg dstart.o g:%1.o dlibs.a otherlib.a DELETE %1.s g:%1.s g:%1.o WAIT Notice that DEFPATH in that example was used before the linker, so that the linker can find its input files in the location Sozobon recommends installing them. Here's an example of one of my batch files, in which I use the Atari 'aln' linker as the final step to the Sozobon compiler... hcc %1.c top %1.s g:%1.s jas -o g:%1.o g:%1.s d:\aln -o %1.prg apstart.o g:%1.o libi gemlib vdilib aeslib DELETE %1.s g:%1.s g:%1.o WAIT Note that the aln linker lives on a different drive than the Sozobon stuff, but rather than changing the default or EXE paths, I just explicitly enter the full path to run for aln. As a further example, when I get a new release of Sozobon for testing, I put it in its own folder, and add to the start of the batch file the line 'DEFPATH F:\NEWSOZ'. If you are installing Sozobon on a floppy disk system, you may get some performance mileage out of the following concepts... Put all the executable files in the root directory of the floppy disk, along with the big library files. Put the most-used header files in a ramdisk, leave the rest on floppies, and work your source in the ramdisk or on floppy (whichever feels safer). Your batch file might look like: (ramdisk is C) EXEPATH A:\ ! The following line will cause the source & intermediate ! files to be worked on the ramdisk... DEFPATH C:\ SETENV INCLUDE=C:\;A:\ hcc a:\%1.c top %1.s jas %1.s ! Default path back to a:\ for link (lib files are on A). DEFPATH A:\ ld -o %1.prg dstart.o c:%1.o dlibs.a WAIT ----------------------------------------------------------------------- Statement of Public Domain ----------------------------------------------------------------------- This code is placed into the public domain, and all rights and copyrights to the code are waived. Yep, you can abuse this beast in any way you see fit. You can even include it as part of your commercial application, if you are foolish enough to do so. This code has been distributed both independantly, and as an adjunct to the Sozobon C PD compiler; it does not carry the same copyright restrictions as the rest of the Sozobon compiler, however. I'll be happy to look at any bugs you discover, if you can get your comments to me. I can be reached on the national STadel network (as 'Ian'), and on BIX as userid 'ianl'. Ian Lepore 11-05-88 ееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееее ccd - cc program for GEM Desktop The 'ccd' program is for use with the Sozobon C compiler. It provides a better interface to the compiler for people who use GEM. It is similar to the 'cc' program in the original Sozobon distribution, but is more tailored for use with the GEM Desktop and certain command shells (such as PCOMMAND) which always force command-line parms to uppercase. The major differences are: 1. Options and file names passed to 'ccd' are not case-sensitive. 2. The '-O' option (to enable optimization) is changed to '-Z' to avoid a conflict with the '-o' option (to specify the output file name). 3. 'ccd' always waits for you to press RETURN before exiting to desktop. 4. If you start 'ccd' without specifying any commandline parms, the program will prompt you to enter them interactively. The parms thus entered are still case-blind; the point to this is to get around the small input line provided by the GEM desktop. Using interactive keyin, cc commands of up to 255 characters can be entered. 5. The environment variables described in the Sozobon documentation aren't supported by 'ccd'. All this means is that you should use the recommended directory structure (or place everything in the current folder). To get a summary of the command line options, run 'ccd' with no parm input and enter a '?' at the input prompt. Note that this only fixes the interface to 'ccd'. The other programs in the distribution will still have problems when run from GEM directly. In practice this shouldn't really be a problem. Since you can give the 'ccd' program C source code, assembly code files, object modules, or libraries, simply by using the appropriate filename extensions, you can always get the behavior you want. For example, if you just want to run the assembler on a file use a command line like: -c foo.s which will assemble "foo.s", creating the file "foo.o". Remember to use the "-v" option if you want to see how things are going. I hope this takes care of the problems people are having. I've tried to do some reasonable testing, but if you run into problems, let me know. Tony Andrews Sozobon, Limited. 11/2/88 ееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееее _________________________________________________________________________ | | | Replacement standard library functions for Atari ST with Alcyon C v4.14 | | Version 1.20.0, by Dale Schumacher, last modified 10/19/88. | |_________________________________________________________________________| HEADER FILES: ar.h This header defines the library archive header used by 'ar'. assert.h This header defines the assert() run-time condition checking macro. basepage.h The BASEPAGE struct and the _base variable, which is initialized to point to the current process basepage, are defined in this file. ctype.h The isxxxx() macros and toxxxx() macros are define in this file. errno.h This file defines the error code constants, the errno variable and related error handling functions. fcntl.h This file defines the O_xxxx constants used by open(). limits.h Various maximum and minimum values are defined by this file. Among these are PATHSIZE and MAXINT. macros.h This file contains a few useful macros including min(), max(), abs() and swap(). malloc.h This file is defines the return values for the dynamic memory managment functions, malloc(), et. al. osbind.h Mnemonics for bios(), xbios() and gemdos() calls are defined in this file. setjmp.h This file defines the buffer needed to save your context when using setjmp()/longjmp() or catch()/throw(). stat.h The struct stat and the file mode flag constants are defined in this file. stdarg.h This header defines the type and macros needed for variable argument list processing. stddef.h This is the root header file which should be included in all programs. It defines dLibs, NULL, size_t, ptrdiff_t and the offsetof() macro. stdio.h This header file should be present in nearly all C programs. It contains defines the FILE struct, EOF and contains extern declarations for standard i/o and other commonly used functions. For convenience, the constants TRUE, FALSE and ERROR are also defined in this file, although this is somewhat non-standard. string.h This file defines aliases for string function names (since some string functions have various names on different systems) and extern declarations for all string functions. time.h This file defines time related constants and structures, and extern declarations for the time functions. types.h Thie file contains typedefs for many special and/or non-standard type names. Many of the typedefs in this file define type names which are ANSI and/or System V standard. This file is included by several other header files, and includes . sys\minimum.h This file contains C code for new _main() and _initargs() functions. It is used as a non-portable hack to make very small programs when no standard i/o or argv/argc is needed. sys\until.h This file is provided just for fun. It defines macros needed to implement a "repeat { ... } until(HELL_FREEZES_OVER);" construct. PROCESS CONTROL: long _STKSIZ = 4096L; This variable defines the amount of run-time stack space to be reserved. The default value is 4K, which is more than enough for most applications. Since dynamic memory is NOT allocated from the stack, this value need only be large enough to handle local variables and deep recursion. char *etext; char *edata; char *end; These variables point to the first byte beyond the end of the text, data and BSS segments respectively. They are provided for compatibility. void _initargs(char *cmdline, int cmdlen) Process the command arguments, either parsing the command line or copying XARG arguments, and retrieve the environment string. This function is called from the startup module very early on. Values to be passed to the user's main() function are stored in the global variables "_argc" and "_argv". The startup module initiallizes these variables to indicate that no arguments are available, and sets "_envp" from the value in the basepage. If a program doesn't use arguments, this function can be replaced by one like the one in to make the program smaller. int _main() This function defines the standard streams, check to see which of them are devices, and calls the user's main() function. The startup module calls this function to start the C program. The following standard streams are initialized by _main(): stdin Standard input, may be redirected stdout Standard output, may be redirected stderr Usually the system console stdprn The standard printer (output only) stdaux The communication port (input/output) The global variables "_argc", "_argv" and "_envp" are used to store the values to be passed to the user's main(). If main() returns, exit() is called, with EXIT_SUCCESS status. If a program doesn't use ANY standard i/o, this function can be replaced by one like the one in to make the program smaller. int main(int argc, char *argv[], char *envp) This function is not actually in the standard libraries, but must be present somewhere in the user's code. The parameters passed to it by _main() are the number of arguments in the command line, a pointer to a list of pointers to arguments, and a pointer to the initial environment string. The return value from main() is passed, by _main(), to exit(). Therefore, you should always return() from main(), or call exit() directly. void exit(int status) Flushes and closes all open streams. Returns value to the operating system. void _exit(int status) Exits the program immediately, returning to the OS. void abort() Prints the message "Abnormal program termination" to stderr and calls _exit() with a status code of 3. int getpid() Return an integer value unique for this process. char *getenv(char *var) Search for in the environment. If is found, a pointer to it's value is returned. NULL is returned if is not found. WARNING: The returned pointer points into the environment and must not be modified! int putenv(char *entry) Add to the environment. can be any of the following forms: = = The first form removes from the environment. getenv() will return NULL if looking for this variable. The second form adds to the environment, with a null value. getenv() will return a pointer to a '\0' character if looking for this variable. Many environment handlers don't support such "tag variables", so their use is not recommended. The final form is the most common, and safest to use. is installed (or replaced) with the value . It should be noted that the putenv() function itself is not supported in many systems and therefore may not be portable. In addition, care should be taken to prevent overflowing the space allocated for the environment. Returns TRUE for success or FALSE for failure. NO OVERFLOW CHECKING IS DONE. void shell() Invoke a command line interface shell. If the "SHELL" environment variable is not defined, a prompt showing the current working directory will be given. Each line entered will then be passed to the system() function for execution until the command "exit" is entered to terminate the shell. If "SHELL" is defined, and the "_shell_p" variable is valid, the value of "SHELL" will be passed to the program pointed to by "_shell_p" in order to allow the shell to invoke a command line interaction of its own. If the "_shell_p" variable is not valid, the program defined by "SHELL" will be searched for along the "PATH", and executed with no arguments. If the "SHELL" can't be found, the internal command line described above will be used. int system(char *command) Attempts to pass to the shell program pointed to by the system variable "_shell_p". If a valid shell can't be found there, the "SHELL" environment variable is searched for. If it exists and is not empty, it will be the name of the shell program to execute the given command. If "SHELL" is not valid, the "PATH" variable is used as a list of directories to search for the program name which is the first token of the command. The extensions tried (if none is specified) are ".TTP", ".TOS", ".PRG" and ".APP". int forkl(char *program[, *arg0, *arg1, ..., *argN], NULL) Create a child process. Since it is not possible to do a true Unix-style fork(), the functionality of the fork()/exec() pair is provided by these fork*() functions. A process is created, running concurrently if possible, which executes with the arguments given. A process id number is returned, which can be compared against the return value from wait(). Note that by convention should be the name of the program that is being called, and is often ignored. The fork*() functions all return ERROR if they for failure, or the child pid for success. int forklp(char *program[, *arg0, *arg1, ..., *argN], NULL) Use the environment variable "PATH" to find . (cf: forkl) int forkle(char *program[, *arg0, *arg1, ..., *argN], NULL, *envp) Pass the environment to the child process. (cf: forkl) int forklpe(char *program[, *arg0, *arg1, ..., *argN], NULL, *envp) Use the environment variable "PATH" to find and pass the environment to the child process. (cf: forkl) int forkv(char *program, **argv) Like forkl() except points to a NULL terminated list of pointers to arguments. This is particularly useful if the number of arguments is not known at compile time. int forkvp(char *program, **argv) Use the environment variable "PATH" to find . (cf: forkv) int forkve(char *program, **argv, *envp) Pass the environment to the child process. (cf: forkv) int forkvpe(char *program, **argv, *envp) Use the environment variable "PATH" to find and pass the environment to the child process. (cf: forkv) int wait(int *rvp) Wait for a child process to terminate. Return -1 if there are no children. Normal return is the process id number of the terminated child. is an pointer to the place to store the return value and exit status. The high byte of the word pointed to be will contain the value returned from the child through exit(). The low byte will contain 0 if the process terminated normally, or an error code if abnormally. long gemdos(int func[, arg1, ..., argN]) Call operating system trap #1 (GEMDOS) function number with the arguments given. Return value returned by the trap call. long bios(int func[, arg1, ..., argN]) Call operating system trap #13 (BIOS) function number with the arguments given. Return value returned by the trap call. long xbios(int func[, arg1, ..., argN]) Call operating system trap #14 (XBIOS) function number with the arguments given. Return value returned by the trap call. int bdos(int func, long parameter) Call operating system trap #2 (BDOS) function number with passing the specified . Note that must always be a long value, even if only a 16-bit value is required by the specified BDOS function. int setjmp(jmp_buf context) Save for longjmp(). You MUST include to use. Calling this function saves the current program context in the context buffer provided and returns zero. A later call to the longjmp() function will cause the context to be restored and your program will continue as if it just returned from setjmp(), but this time with the (non-zero) return value specified in the longjmp() call. THE SAVED CONTEXT WILL NOT BE VALID IF YOU EXIT THE FUNCTION THAT CALLED setjmp(). void longjmp(jmp_buf context, int rv) Return to the saved by setjmp(). (cf: setjmp) You MUST include to use. int catch(jmp_buf context, int (*func)()) Execute with saved for throw(). You MUST include to use. Return the value returned by . The main advantage of these functions over catch/throw is the ability to return zero from the function executed, and the logically "cleaner" encapsulation of the non-local jump operation. These functions are patterned after similar functions in LISP. (cf: setjmp/longjmp) void throw(jump_buf context, int rv) Return to saved by catch(). You MUST include to use. MEMORY MANAGEMENT: You should include in your program if you use functions in this section. long _BLKSIZ = 65536; This variable controls the granularity of system memory allocation used by malloc(), et. al. This is the amount of memory that is requested from the system each time a new "heap" is needed to fill dynamic memory requests. To help avoid a GEMDOS bug, only 16 heaps can be active at a time. Therefore, (16 * _BLKSIZ) defines the maximum amount of memory which can be managed by these routines under normal circumstances. The exception is if any single request for memory exceeds _BLKSIZ. In this case, a heap will be allocated larger than _BLKSIZ. char *malloc(unsigned int size) Allocate at least bytes of memory. A pointer to the requested block is returned, or NULL if there is not enough free memory available. char *calloc(unsigned int n, size_t size) Allocate space for an array of element of bytes each. If the storage can be allocated, it is initialized to all zero. NULL is returned is there is not enough free memory. char *lalloc(long size) Allocate at least bytes of memory. A pointer to the requested block is returned, or NULL if there is not enough free memory available. char *realloc(char *addr, unsigned int size) Attempt to change the memory block at to the new . Making a block smaller will always work, but making it larger may fail if there is not enough free memory. If there is not enough memory, NULL is returned and the block will still reside at . If realloc() succeeds, a pointer to the (possibly moved) new block will be returned. If is NULL, realloc() will simply act like malloc(). If is 0, and is not NULL, realloc() will work like free(). void free(char *addr) Release the memory block at back into the free memory pool. WARNING: Unlike some implementations, you may not realloc() a block which has been free()ed. long msize(char *addr) Return the size, in bytes, of the memory block at . Note that the size is a long value, since the block may have been allocated by lalloc(). long memavail() Return the size, in bytes, of the largest block of free memory available for allocation. Note that this value is a long. char *alloca(unsigned int size) Allocate at least bytes of memory from the stack. This is "automatic" variable space and will be freed when the function which called alloca() exits. DO NOT use the other dynamic memory functions like free(), realloc() and msize() on the block returned by this function. A pointer to the requested block is returned, or NULL if there is not enough stack space available. char *sbrk(int amount) Move the "break" by . The break is the line between the top of the heap and the bottom of the stack. The size of the stack/heap area is defined by _STKSIZ. Initially, the heap uses zero bytes. Since malloc() doesn't use the heap, often the heap will stay that way. This function moves the location of the break by bytes, positive or negative, and returns the old value of the break. If this causes a collision with the stack, or a negative value reduces the heap below zero bytes, NULL is returned and the break is not moved. Note that the heap pointer is moved by EXACTLY the specified. If you want to ensure that sbrk() will return word-aligned memory segments, you must make sure that is always even, since the heap is initially aligned properly. int brk(char *address) Set the "break" to
. Return 0 for success. If
is not a valid break value, return -1 and don't move the break. FILE HANDLING: int chdir(char *pathname) Changes the current working directory to . If a drive letter is specified in , the current working directory for that drive is set. Returns 0 for success, or a negative error code. int mkdir(char *pathname) Creates a new directory called . A drive letter may be specified. Returns 0 for success, or a negative error code. int rmdir(char *pathname) Removes an existing directory called . A drive letter may be specified. Returns 0 for success, or a negative error code. char *fullpath(char *full, *part) is a (possibly) ambiguous file/path specification. A non-ambiguous file/path spec is created which includes a drive letter and all intermediate sub-directories. If the partial specification is not valid, NULL is returned, otherwise a pointer to is returned. If NULL is specified for , an internal buffer is used and a pointer to it is returned. char *getcwd(char *buffer, int size) Get the full pathname of the current working directory. This value will ALWAYS end with a '\\' character. is a pointer to a buffer of bytes that will be used to store the current working directory. If is NULL, a buffer of bytes will be malloc()ed. The function returns a pointer to the buffer for success, or NULL for failure, either because malloc() failed, or the value is larger than . This function uses fullpath() to get the pathname, therefore the buffer internal to fullpath() is overwritten. int access(char *name, int amode) Return non-zero if a file with the given can be accessed in the given . Possible values are: 0x00 file exists 0x02 file can be written 0x04 file can be read 0x06 file can be read and written char *findfile(char *afn[, *ext]) Return full file spec for if found. If has no extension, extensions from are tried until a match is found, or the list ends. is a list of extensions separated by '\0' characters and ending with an additional '\0', ie. ".ttp\0.tos\0.prg\0" (note that the final null is added by the compiler to any string constant. If already has an extension, is not used. If no matching files are found, NULL is returned. The pointer returned when a match is found points to a buffer which is internal to fullpath(). If you want to save the value returned, you must make a copy before the buffer is overwritten by subsequent calls. Note: several dLibs functions call filefind(), so don't make too many assumptions about how long the internal buffer is going to stay valid. char *pfindfile(char *path, *afn[, *ext]) Like findfile() but search all directories (separated by ',' or ';') in . If is NULL, the "PATH" environment variable is used instead. If specifies a drive or directory, is not used. The internal buffer for findfile() is used by pfindfile(). char *wildcard(char *pathname) Return matches for a wildcard filename. If is not NULL, the first file which matches will be returned. The may contain wildcards only in the filename portion, not in any sub-directories. Subsequent calls to wildcard() with a NULL argument return the next matching filename. NULL is returned when no more files match. Note: the pointer returned points to an internal buffer which is overwritten with each call. It should not be modified, and should be copied into a safe place if you want to save the value. char *_splitpath(char *src, *drive, *path, *file, *ext) Parse the filename into component parts. Returns . If any of the component pointers is NULL, that component will be parsed, but not saved. If a given component does not exists int the string, the component will be empty, (ie.: ""). The component will be a drive letter followed by a colon, (ie.: "a:"). The component will be the subdirectory names leading up to the filename, but will not include a trailing '\' unless the path the simply the root path "\", and there will only be a leading '\' if the path is fully qualified, or "rooted", ie.: "\this\is\a\path\name". The component is the base filename without any extension, ie.: "filename". The component is the file extention with no leading '.', ie.: "txt". Recommended sizes for the components is Drive[4], Path[128], File[10], Ext[4]. char *_makepath(char *dst, *drive, *path, *file, *ext) Build the filename from component parts. Returns . This function is basically in inverse of _splitpath(), and will accept the components parsed by _splitpath() as input. It will also allow a little more flexibility in that it will treat any component which is a NULL pointer as an empty field, and the component may optionally have a trailing '\'. char *tmpnam(char *s) Generate a unique filename to be used for a temporary file. The filename will have the form "TEMP$nnn.TMP" where "nnn" is a sequence of numeric digits. The name will unique in the current working directory. If is NULL, space will be obtained from malloc() to store the filename and thus must be free()'d by the caller. If is not NULL, the filename will be copied into the buffer provided. This function returns NULL for failure, or a pointer to the filename for success. char *tempnam(char *dir, *pfx) This function is similar to tmpnam(), but is somewhat more flexible. specifies the directory part of the filename. If is NULL, the TMPDIR environment variable will be used. If TMPDIR is not found, the current directory is used. specifies the filename prefix (up to 5 characters). The form of the filename will be "dir\pfxnnn.TMP", similar to tmpnam(). The storage for the filename is always obtained from malloc(), so the caller must free() it after use. This function returns NULL for failure, or a pointer to the fully expanded filename for success. int stat(char *name, struct stat *statbuf) Search for file and load with information about that file, if it is found. Return 0 if found, or ERROR (-1) if no file/directory matched . Volume labels are not included in the search. The file must be included if you use this functions, since it defines struct stat. long fsize(char *name) Return the size of the file in bytes. Note that this is a long value. Return -1L if the file is not found. int isatty(int handle) Return non-zero if refers to a character device. Negative handles always refer to character devices. int creat(char *filename, int pmode) Create a new file with the given . If a file with the name already exists, it will be truncated to zero bytes. Since the OS doesn't do this properly, the file is actually deleted and then re-created. specifies the attributes initially given to the file. Valid values are: 0x00 normal, read/write S_ISRO read only S_IFHID hidden file S_IFSYS system file S_ISVOL volume label If S_ISVOL mode is specified, it must be the only mode given. Other modes may be combined with the | operator. The file contains information useful with this function. int chmod(char *filename, int pmode) Change the mode attribute of to . Values for are the same as for the creat() function. Returns 0 for success, or a negative error code. int open(char *filename, int iomode[, pmode]) Attempt to open with the given . A file handle is returned if the open succeeds. A negative error code is returned for errors. Valid values are: O_RDONLY read mode O_WRONLY write mode O_RDWR read/write mode In addition to the (mutually exclusive) modes above, one or more of the following options may be |-ed with : O_APPEND start file pointer at end of file O_TRUNC if file exists, truncate to 0 length O_CREAT creat() file if none exists (uses ) O_EXCL return EEXIST if file exists and O_CREAT is specified (exclusive mode). Note: It is possible to open the character devices "con:", "aux:", and "prn:" with this call, and negative handles (-1..-3) will be returned. Error returns are always < -3. The file contains iomode constants. The file contains pmode constants. int close(int h) Close file referenced by the file handle . Return 0 for success, or a negative error code. int dup(int handle) Return a second file handle which refers to the same file as the given . (cf: dup2) int dup2(int handle1, int handle2) Force to refer to the same file as . Return 0 for success, or a negative error code. Both dup() and dup2() are direct calls to Fdup() and Fforce() GEMDOS calls. Refer to your GEMDOS documentation for further information. int remove(char *filename) Delete , if it exists. Return 0 for success, or a negative error code. int rename(char *oldname, *newname) Change the name of file to . You may use this function to move files from one directory (pathname) to another, but not from one drive to another. Return 0 for success, or a negative error code. long lseek(int h, long offset, int origin) Move file pointer for file to specified location. specifies the starting point for the distance. Valid values are: SEEK_SET from beginning of file (0) SEEK_CUR from current location (1) SEEK_END from end of file (2) The value is the distance in bytes from the origin. The final file position, or a negative error code, is returned. long tell(int h) Return the current file position for the file . FILE *fopen(char *filename, char *mode) Open as a stream file. This is the normal open way to open a file. The is a string specifying the mode(s) that are relevent to the file open. Valid characters are: r read mode w write mode a append mode b binary mode t text (translated) mode At least one of "r", "w" or "a" must be specified. "t" is assumed and indicates that is translated to on output and vica-versa on input. If the stream is a character device, the translation is slightly different. The output translation is the same, but on input and both become in all cases. The "b", for binary mode, overides "t" and indicated that characters are not translated during i/o operations. "a" represents append mode and means that the file pointer will initially be placed at the end of the file. "w" mode will create a file if it doesn't exists, or zero an existing file. If "r" is the only mode specified, the file must already exist. A (FILE *) is returned if the open succeeds, or NULL if it fails. FILE *freopen(char *filename, char *mode, FILE *fp) Closes the file associated with and opens the new file as with fopen(), except that a new FILE structure is not created. The existing FILE structure pointed to by is re-initialized with the new file information. This is typically used to redirect i/o to standard streams stdin, stdout, stderr, stdprn, stdaux. is returned for success, or NULL for failure. FILE *fdopen(int h, char *mode) Associates a stream with the already open file . The values are the same as for fopen(), but MUST be compatible with the mode in which was open()ed. This functions allows a file opened with the low level open()/creat() calls to be used as a buffered/translated stream. A pointer to a FILE struct is returned, or NULL for errors. FILE *fopenp(char *filename, char *mode) Find somewhere on the PATH and open it with . Refer to the fopen() function for valid values. If you want to use a search path other than the PATH environment variable, use the pfindfile() function to locate the file, and pass that filename to fopen(). (cf: pfindfile, fopen) int fclose(FILE *fp) Close the stream , flushing the buffer. Returns 0 on success. void setbuf(FILE *fp, char *buf) If is NULL, make unbuffered; else points to a buffer of BUFSIZ characters to be used as the stream buffer for . void setvbuf(FILE *fp, char *buf, int bmode, int size) If is NULL or is _IONBF, make unbuffered; otherwise points to a buffer of characters to be used as the stream buffer for . The variable indicates the type of buffering desired, as follows: _IONBF No buffering _IOFBF Full buffering (normal) _IOLBF Line buffering (not supported, same as _IOFBF) int fseek(FILE *fp, long offset, int origin) Operates like lseek(), except it works on streams. Note that stream file positions may be misleading due to translation of characters during i/o. ftell() may be used reliably with fseek() to reposition a file to a prior location. WARNING: fseek() returns 0 for success, non-zero for failure, according to the ANSI standard. Some implementations use 0 for failure. This function is maintained for compatibility with old programs. fsetpos() should be used in new code. (cf: fsetpos) void rewind(FILE *fp) Operates like fseek(fp, 0L, SEEK_SET), except it also clears the end-of-file and error flags for . There is no return value. long ftell(FILE *fp) Operates like tell(), except it works on streams. Note that stream file positions may be misleading due to translation of characters during i/o. This function is maintained for compatibility with old programs. fsetpos() should be used in new code. (cf: fsetpos) int fgetpos(FILE *fp, fpos_t *pos) Get the position of the stream and store it at the location pointed to be . This is the new X3J11 function to replace ftell(). Returns 0 for success and ERROR for failure. int fsetpos(FILE *fp, fpos_t *pos) Set the position of the stream to the valued stored at the location pointed to be . Note that this function is only required to work properly for a value which was previously obtained by fgetpos() on the same stream. This is the new X3J11 function to replace fseek(). Returns 0 for success and ERROR for failure. int fileno(FILE *fp) Return the file handle associated with the stream . int feof(FILE *fp) Return non-zero if is at end of file. int ferror(FILE *fp) Return non-zero if and error has occurred on . void clearerr(FILE *fp) Clear the error flag on . sync() Provided for compatibility. #define'ed as a comment. INPUT/OUTPUT FUNCTIONS: int read(int h, char *data, int length) Read bytes from the file reference by file handle . Data is stored in the buffer pointed to by . The number of bytes actually read is returned, 0 for end of file, or a negative error code. Note that the maximum number of bytes that can be read by this function is MAXINT. long lread(int h, char *data, long length) Same as read(), but uses a long value for number of bytes to read. int write(int h, char *data, int length) Write bytes to the file reference by file handle . Data is written from the buffer pointed to by . The number of bytes actually written is returned, or a negative error code. Note that the maximum number of bytes that can be written by this function is MAXINT. long lwrite(int h, char *data, long length) Same as write(), but uses a long value for number of bytes to write. int fread(char *data, int size, int count, FILE *fp) Read items of characters each from stream . Data is stored in the buffer pointed to by . The number of full items actually read is returned, or a negative error code. This call DOES NOT translate characters, even if the stream is opened in translate mode. int fwrite(char *data, int size, int count, FILE *fp) Write items of characters each to stream . Data is read from the buffer pointed to by . The number of full items actually written is returned, or a negative error code. This call DOES NOT translate characters, even if the stream is opened in translate mode. int fgetc(FILE *fp) Get a character from . Returns the character or EOF. int fungetc(char c, FILE *fp) Push the character back to be gotten by the next fgetc() call on . Only 1 character may be ungotten at a time on each stream. Subsequent calls to fungetc() will write over the currently saved character. int fputc(char c, FILE *fp) Put the character to the stream . int fflush(FILE *fp) Flush the file i/o buffer of the stream . The buffer is automatically flushed when it is full, the stream is closed, or the program terminates through exit(). This function has no effect if the stream in unbuffered. Call this function before switching between reading and writing on a stream which is opened for both. int getc(FILE *fp) Same as fgetc() but implemented as a macro. int ungetc(char c, FILE *fp) Same as fungetc() but implemented as a macro. int putc(char c, FILE *fp) Same as fputc() but implemented as a macro. int getw(FILE *fp) Get a 2-byte value from the stream . The high-order byte is read first. Use feof() to test for end-of-file. int putw(int n, FILE *fp) Put the 2-byte value to the stream . The high-order byte is written first. int getl(FILE *fp) Get a 4-byte value from the stream . The high-order byte is read first. Use feof() to test for end-of-file. int putl(long n, FILE *fp) Put the 4-byte value to the stream . The high-order byte is written first. int getchar() Same as "fgetc(stdin)". int ungetchar(char c) Same as "fungetc(c, stdin)". Note that this name will conflict with any function beginning "ungetch..." due to having only 7 significant characters in external identifiers. int putchar(char c) Same as "fputc(c, stdin)". int cfg_ch(int cfg) Configure getch()/putch() operation. The following are legal values for and may be combined with the | operator: _CIOB Use BIOS level i/o calls _CIOCH 8-bit character codes only (cf:getch) _CIOVT Enable VT-52 escape sequence processing The initial configuration value at run time is _CIOCH. This function returns the previous configuration value, and if is -1 the value is not set. int getch() Machine dependent console input function. This function normally gets a character from the keyboard by calling the GEMDOS "Cconin" function. If cfg_ch() is given the _CIOB option, input is gotten from the BIOS "Bconin" function instead. The BIOS level functions don't process ^C, ^S or ^Q, while the GEMDOS functions do. The most common use for getch() is when keyboard scan codes are needed to process special function keys. The return value from getch() consists of the scan code in the high-order byte, and the ascii character code in the low-order byte. If cfg_ch() is given the _CIOCH option, the return value is always an 8-bit quantity, either the scan code with the 8th bit set, or the ascii code with the 8th bit clear. This is somewhat less informative, since the scan code form is returned only if the ascii value is 0, but is the default configuration value for compatability with Microsoft C. In any case, the global unsigned long variable "_getch" will contain the full character code value returned by the OS. int getche() Same as getch() but calls putch() to echo the character. char putch(char c) Machine dependent (typically quite fast) console output function. This function normally puts a character to the console by calling the GEMDOS "Cconout" function. If cfg_ch() is given the _CIOB option, output is sent to the BIOS "Bconout" function instead. The BIOS level functions don't process ^C, ^S or ^Q, while the GEMDOS functions do. At the BIOS level, the _CIOVT option to cfg_ch() allows VT-52 escape code processing on output. The GEMDOS function always does VT-52 emulation. The BIOS function defaults to skipping this overhead, but if VT-52 emulation is desired, it can still be used through the faster BIOS level routine by using the _CIOVT option. Control codes, like '\b' and '\r', are supported even without VT-52 emulation. The return value of this function is simply the character sent. int kbhit() Machine dependent function to detect if input is waiting for the getch() function. Returns non-zero if the console has data ready. char *getln(char *ip, int (*get)(), int (*put)(), char *buffer, int limit) Get a line of input from the user. Allow simple editing of the line with BS/DEL, ESC, and CR/LF to terminate input. Characters are retreived by a (*get)(ip) and echoed with (*put)(c). A pointer to is returned in any case. This function is no longer needed to handle editable i/o from stdin, since the pseduo-tty driver code built into fgetc() now handles line editing, but this function is still useful if you want to supply your own get/put functions (like curses?). char *fgets(char *data, int limit, FILE *fp) Get data from and puts it in the buffer. At most, -1 characters will be read. Input will also be terminated when a newline is read. will be '\0' terminated and the newline, if read, will be included. A pointer to the start of is returned, or NULL for EOF. void fputs(char *data, FILE *fp) Write the characters in to the stream . A newline WILL NOT be added. char *gets(char *data) Get data from stdin and puts it in the buffer. Input is terminated when a newline is read. The newline will be replaced by a '\0' to terminate the string. A backspace character will remove the preceeding character from the buffer, but will not backspace past the start of the buffer. A pointer to the start of is returned, or NULL for EOF. void puts(char *data) Write the characters in to stdout. A newline WILL be written after the data. void cputs(char *data) Write the characters in directly to the console using the system dependent putch() function. A newline WILL NOT be written after the data. int fprintf(FILE *fp, char *fmt[, arg1, ..., argN]) Formatted output to the stream . See the _printf() function for a description of the formatting string. int printf(char *fmt[, arg1, ..., argN]) Formatted output to the stdout stream. See the _printf() function for a description of the formatting string. int sprintf(char *buf, *fmt[, arg1, ..., argN]) Formatted output to the string . See the _printf() function for a description of the formatting string. int cprintf(char *fmt[, arg1, ..., argN]) Formatted output directly to the console. This functions uses the system dependent putch() for output. See the _printf() function for a description of the formatting string. int vfprintf(FILE *fp, char *fmt, va_list ap) Formatted output to the stream with a variable argument list. See _printf() for formatting and va_start() for stdarg explaination. int vprintf(FILE *fp, va_list ap) Formatted output to the stdout stream with a variable argument list. See _printf() for formatting and va_start() for stdarg explaination. int vsprintf(char *buf, *fmt, va_list ap) Formatted outout to the string with a variable argument list. See _printf() for formatting and va_start() for stdarg explaination. int fscanf(FILE *fp, char *fmt[, arg1, ..., argN]) Formatted input from the stream . See the _scanf() function for a description of the formatting string. int scanf(char *fmt[, arg1, ..., argN]) Formatted input from the stdin stream. See the _scanf() function for a description of the formatting string. int sscanf(char *buf, *fmt[, arg1, ..., argN]) Formatted input from the string . See the _scanf() function for a description of the formatting string. int _tttty(FILE *fp) "Teeny Tiny TTY" driver function. This function is internal to dLibs, but it's name is documented to allow you to replace it with a tty driver of your own. It's operation can be best understood by reading and UNDERSTANDING the code in the routine provided. In brief, this function is supposed to read from , up to a newline character, putting the character in the FILE buffer, and return the number of characters read (similar to _fillbuf() in some systems). If the stream is in binary mode, a full buffer is to be read, with no translation. If the stream is unbuffered, characters are also untranslated, but ^C on input is checked for, however, the code which calls this function will translate carriage return characters into newlines and ^Z will cause EOF. Effectively, this means that line editing is not allowed if the stream in unbuffered, but most translation is done. Note that this mode of operation is the least likely to produce unix-like results, particularly in the way some control characters are echoed. It is recommended that either binary mode, or buffered and translated mode be used. FORMATTING/TYPE CONVERSION: int _printf(char *op, int (*put)(), char *fmt, int *args) This function does all the work for printf(), et al. Many systems don't provide direct access to this function (or it's equivalent), but it is useful for writing your own printf()-like functions. Since this is a non-standard interface, and v[sf]print() is now available, you should probably use the stdarg functions instead. points to a format control string. pointers to a list of arguments. The format string is used to create and output stream with the arguments. The function is used to output each character. The parameter is given to the function to specify the output stream. Calls to are of the form: "(*put)(c, op);" where is the character to output. The format string is composed of characters and format specifications. The '%' character introduces a format specifier. The general form of a format specifier is: %[-][ |+][0][|*][.[|*]][l]{d|i|u|o|x|p|b|c|s} The '-' specifies left justification. The ' ' or '+' specifies the character which preceeds positive numeric values. The '0' specifies that numeric fields will be padded with '0' rather than ' '. The field is a numeric value specifying a minimum field width. The field is a numeric value specifying the maximum number of data characters to display. If '*' is specified for the width or the precision, an "int" value is taken from the argument list and used for that value. If no width is specified, the field width varies according to the data width. If no precision is specified, all data characters are included in the data width. If the data width exceeds the field width, the field width will expand to allow all data characters to be printed. Including the 'l' or capitalizing the trailing character specifies that the associated value is a "long" type. The trailing character specifies the format type, as follows: d Signed decimal integer i same as 'd' u Unsigned decimal integer o Unsigned octal integer x Unsigned hexadecimal integer b Unsigned binary integer p Pointer (displayed in %06.8lX format) c Character s String If the character following the '%' is not recognized, it is simply passed along to the output stream, thus "%%" is used to print a single '%' character. char *ltoa(long n, char *buffer, int radix) Convert the long value to a string in using as the number base. If is negative, '-' will be the first character in . A pointer to is returned. char *ultoa(unsigned long n, char *buffer, int radix) Convert the unsigned long value to a string in using as the number base. A pointer to is returned. char *itoa(int n, char *buffer, int radix) Convert the integer value to a string in using as the number base. If is negative, '-' will be the first character in . A pointer to is returned. long atol(char *number) Convert the string to a long value. Leading whitespace is ignored, a leading +/- is optional. Characters are processed until a non-digit is reached. Return value is undefined in an overflow situation. int atoi(char *number) Convert the string to an int value. Leading whitespace is ignored, a leading +/- is optional. Characters are processed until a non-digit is reached. Return value is undefined in an overflow situation. long strtol(char *number, char **nptr, int base) Convert the string to a long value of base . Bases from 0 to 36 are allowed. Leading whitespace is ignored, and a leading +/- is optional. If the is 0, a leading '0' indicates base 8 and a leading "0x" or "0X" indicates base 16. Characters are processed until a character is found which is not in the specified base. If is non-NULL, it will be set to point to the character which terminated the translation in . Return value is undefined in an overflow situation. unsigned long strtoul(char *number, char **nptr, int base) Convert the string to an unsigned long value of base . Bases from 0 to 36 are allowed. Leading whitespace is ignored. If the is 0, a leading '0' indicates base 8 and a leading "0x" or "0X" indicates base 16. Characters are processed until a character is found which is not in the specified base. If is non-NULL, it will be set to point to the character which terminated the translation in . Return value is undefined in an overflow situation. int _scanf(char *ip, int (*get)(), int (*unget)(), char *fmt, char **args) This function does all the work for scanf(), et al. Many systems don't provide direct access to this function (or it's equivalent), but it is useful for writing your own scanf()-like functions. points to a format control string. pointers to a list of arguments, each of which is the address of a variable in which input data may be stored. The format string is used to control reading of characters from the function. As each character is needed is called in the form "c = (*get)(ip);" where is the character read (negative for errors) and is the auxiliary pointer specified by the parameter. If a character needs to be un-gotten, a call to of the form "(*unget)(c, ip);" is made. The format string is composed of characters and format specifications. Any characters in , except whitespace characters, which are not part of a format specifier are expected to be matched one-to-one by characters in the input stream. Scanning terminates if a mismatch occurs or if any call to results in an error. Whitespace characters match 0 or more whitespace characters in the input stream. The '%' character introduces a format specifier. The general form of a format specifier is: %[*][][l|h]{d|u|o|x|b|i|c|s} The '*' specifies that a field is to be scanned by not stored. No variable pointer should be provided for non-stored format specs. The field specifies that maximum number of characters to be process to fill the given format type. Less than characters will be processed if the field ends before characters have been processed. A field ends when either a whitespace character, or a character which does not fit the specified format, is read. The preceding 'l' (or capitalizing the conversion character) specifies that the associated variable is a "long" type. The trailing character specifies the format type, as follows: d Signed decimal integer u Unsigned decimal integer o Unsigned octal integer x Unsigned hexadecimal integer b Unsigned binary integer i Unsigned decimal/octal/hexadecimal/binary integer c Character s String If a is specified with the 'c' format, exactly characters (including whitespace) are read from the input stream, and written to a string. No '\0' character is added If the character following the '%' is not recognized, it is expected to match the input stream as a non-format character, thus "%%" is used to match a single '%' character. One additional conversion is the brace-format. Shown as "%[...]", the '...' represent a list of characters. If the first character in the list is a '^', the field contains any characters -not- in the list (starting with the 1st character after the '^'). If the first character of the list is not a '^', then the field will only contain those characters found in the list. A right brace character (']') can be included as one of the list of characters by placing it as the first character in the list. If the '^' negation character is the first character, the included brace should be the next character after the '^'. For maximum portability, a range should be explicitly given (a good example would be "%[0123456789]"), but to allow for porting from systems with smarter scanf functions, this version of scanf also supports ranges represented using a - form (eg: "%[0-9]"). To use the first-last form, the character must be lexically less than or equal to the character . If this rule is violated, or if the hyphen is the first or last character of the list, the hyphen will be assumed to be just another character in the list and no range expansion will be done. The resulting string containing the characters in (or not in) the list will be null terminated. It should be noted that, unlike most of the other formats, this conversion does allow the programmer to specify that whitespace characters will be included in the resulting string. char *ctlcnv(char *string) Convert \ notation in to actual characters. This is useful for reading strings from a stream when you want to allow insertion of control character or other characters that may have special meaning otherwise, or may not otherwise be allowed. The following formats are supported: \n newline or linefeed \r carriage return \0 null character (value 0) \b backspace \t horizontal tab \v vertical tab \f form feed \a alarm (bell) \\ backslash \' single quote \" double quote \NNN octal constant \xNN hexadecimal constant \ "folded" line (both characters removed) A pointer to the modified is returned. STRING MANIPULATION: You should include in your program if you use functions in this section. char *memmove(char *dest, char *source, int len) Copies the block to the . bytes are always copied. No terminator is added to . A pointer to is returned. Overlap checking IS done. char *lmemmove(char *dest, char *source, long len) Same as memmove() except a long value is used for . char *memcpy(char *dest, char *source, int len) Copies the block to the . bytes are always copied. No terminator is added to . A pointer to is returned. Overlap checking IS NOT done. char *lmemcpy(char *dest, char *source, long len) Same as memcpy() except a long value is used for . char *memset(char *dest, char data, int len) Set bytes of to . A pointer to is returned. int memcmp(char *blk1, char *blk2, int len) Lexicographically compare the two blocks. Return a value indicating the relationship between the blocks. Possible return values are: negative blk1 < blk2 0 blk1 == blk2 positive blk1 > blk2 bytes are always compared. int memicmp(char *blk1, char *blk2, int len) Compare blocks as with memcmp(), but ignore the case of any alphabetic characters. char *memccpy(char *dst, char *src, char c, int cnt) Copy bytes from to until either bytes have been copied, or the character has been copied. If is found, a pointer to the character following in is returned, or NULL is reaches 0 before is found. char *memchr(char *buf, char c, int cnt) Search the first bytes of for . Returns a pointer to the matching character, or NULL if not found. char *bzero(char *buf, int cnt) Zero characters in . Returns . int strlen(char *string) Returns the number of characters in a string, not including the terminating '\0'. char *strcpy(char *dest, char *source) Copies the string to the including the '\0'. A pointer to the start of is returned. char *strncpy(char *dest, char *source, int limit) Copies the string to the . At most, characters are copied. If ends before characters have been copied, the '\0' is copied, otherwise is not terminated by the copy. char *strpcpy(char *dest, char *start, char *stop) Copies characters from up to into . The character pointed to by is not copied, and MUST be in the same string as . The pointer is returned. char *strdup(char *string) Create a copy of and return a pointer to the copy. Storage for the copy is obtained from malloc(). char *strset(char *string, char c) Fill with up the the terminating '\0' of . char *strnset(char *string, char c, int n) Fill at most characters of with , up the the terminating '\0' of . char *substr(char *dest, char *source, int start, int end) Copy characters from to starting with character and ending with . A pointer to , which will be '\0' terminated, is returned. char *subnstr(char *dest, char *source, int start, int length) Copy characters from to starting with character . A pointer to , which will be '\0' terminated, is returned. char *strcat(char *dest, char *source) Concatenate on the end of . The terminator of will be overwritten by the first character of . The termintor from will be copied. A pointer to the modified is returned. char *strncat(char *dest, char *source, int limit) Concatenate characters from onto . If contains less than characters, the length of source is used for . The terminating '\0' is always added. A pointer to is returned. char *strupr(char *string) Convert all alphabetic characters in to upper case. char *strlwr(char *string) Convert all alphabetic characters in to lower case. char *strrev(char *string) Reverse the order of the characters in in place. int strcmp(char *str1, char *str2) Lexicographically compare the two strings. Return a value indicating the relationship between the strings. Possible return values are: negative str1 < str2 0 str1 == str2 positive str1 > str2 int strncmp(char *str1, char *str2, int limit) Compare strings as with strcmp(), but limit comparison to the characters. int stricmp(char *str1, char *str2) Compare strings as with strcmp(), but ignore the case of any alphabetic characters. int strnicmp(char *str1, char *str2, int limit) Compare strings as with strncmp(), but ignore the case of any alphabetic characters. char *strstr(char *string, char *pattern) Return a pointer to the first occurance of in . NULL is returned if is not found. char *stristr(char *string, char *pattern) Same as strstr(), but ignore the case of any alphabetic characters. char *strchr(char *string, char symbol) Return a pointer to the first occurance of in . NULL is returned if is not found. '\0' is included in the search. char *strrchr(char *string, char symbol) Return a pointer to the last occurance of in . NULL is returned if is not found. '\0' is included in the search. int strpos(char *string, char symbol) Return the index of the first occurance of in . -1 is returned if is not found. int strrpos(char *string, char symbol) Return the index of the last occurance of in . -1 is returned if is not found. int strspn(char *string, char *set) Return the length of the sub-string of that consists entirely of characters found in . The terminating '\0' in is not considered part of the match set. If the first character if is not in , 0 is returned. int strcspn(char *string, char *set) Return the length of the sub-string of that consists entirely of characters not found in . The terminating '\0' in is not considered part of the match set. If the first character if is in , 0 is returned. char *strpbrk(char *string, char *set) Return a pointer to the first occurance in of any character in . char *strrpbrk(char *string, char *set) Return a pointer to the last occurance in of any character in . char *strtok(char *string, char *delim) Return a token from . If is not NULL, it is the beginning of a string from which tokens are to be extracted. Characters found in are skipped over to find the start of a token, characters are then accumulated until a character in is found, or the terminator of is reached. A pointer to the '\0' terminated token is then returned. Note that this function modifies (by inserting '\0's) in the process. Subsequent calls to strtok() may specify NULL as the argument, in which case subsequent tokens are returned, or NULL if there are no more tokens. char *strtrim(char *string, char *junk) Remove leading and trailing characters found in from . Return a pointer to the modified . char *stradj(char *string, int dir) Adjust by adding space if is positive, or removing space if is negative. The magnitude of is the number of character positions to add or remove. Characters are added or removed at the beginning of . A pointer to the modified is returned. int strrpl(char *string, char *ptrn, char *rpl, int n) Replace at most occurances of in with . If is -1, replace all. Return the number of replacments. int strirpl(char *string, char *ptrn, char *rpl, int n) Same as strrpl() except ignore the case of alphabetic characters. CHARACTER FUNCTIONS: To use the functions in this section, you must include in your source file. Please note that the isxxxx() functions, except isascii(), only have defined results if isascii() is true. (ie. they only work properly on values 0x00 through 0x7F) int toupper(int c) Convert to upper case, if alphabetic. This is implemeted as a macro and also as a function. You may force use of the function version rather than the macro (which evaluates its argument twice) by using the "#undef toupper" directive. int tolower(int c) Convert to lower case, if alphabetic. This is implemeted as a macro and also as a function. You may force use of the function version rather than the macro (which evaluates its argument twice) by using the "#undef tolower" directive. MACRO _toupper(int c) This macro should be used only if is known to be lower case. It converts to upper case. Results are undefined if converting a character which is not lower case. MACRO _tolower(int c) This macro should be used only if is known to be upper case. It converts to lower case. Results are undefined if converting a character which is not upper case. MACRO toascii(int c) Convert to 7-bit ascii, putting it into the range 0x00..0x7F. MACRO isalnum(int c) Return non-zero if is '0'..'9','A'..'Z','a'..'z'. MACRO isalpha(int c) Return non-zero if is 'A'..'Z','a'..'z'. MACRO isascii(int c) Return non-zero if is 0x00..0x7F. MACRO iscntrl(int c) Return non-zero if is 0x00..0x1F,0x7F. MACRO isdigit(int c) Return non-zero if is '0'..'9'. MACRO isgraph(int c) Return non-zero if is 0x21..0x7E. MACRO islower(int c) Return non-zero if is 'a'..'z'. MACRO isprint(int c) Return non-zero if is 0x20..0x7E. MACRO ispunct(int c) Return non-zero if is not iscntrl(), isalnum() or isspace(). MACRO isspace(int c) Return non-zero if is 0x09..0x0D,0x20. MACRO isupper(int c) Return non-zero if is 'A'..'Z'. MACRO isxdigit(int c) Return non-zero if is '0'..'9','A'..'F','a'..'f'. DATE/TIME FUNCTIONS: To use the functions in this section, you must include in your source file. time_t time(time_t *rawtime) Get the current system clock date/time value. Altough the value of this function is compatible with the ANSI proposed standard, on some systems (notably System V), this function returns the number of seconds elapsed since 00:00:00 GMT on Jan 1, 1970. This implementation returns an encoded date/time value instead. Therefore any programs which depend on this value being a number of seconds will not work properly. However, other functions in this section which make use of the raw time value returned by time() are implemented to be compatible with this encoding, and will work properly. In addition to returning the raw time value, if the pointer is not NULL, the value is stored in the time_t variable points to. char *ctime(time_t *rawtime) Convert to a string. A 26 character fixed field string is created from the raw time value. The following is an example of what this string might look like: "Wed Jul 08 18:43:07 1987\n\0" A 24-hour clock is used, and due to a limitation in the ST system clock value, only a resolution of 2 seconds is possible. A pointer to the formatted string, which is held in an internal buffer, is returned. struct tm *localtime(time_t *rawtime) Convert to fill time structure fields. A pointer to an internal structure is returned. Refer to for the values of the various structure fields. struct tm *gmtime(time_t *rawtime) Since there is not concept of "time zone" on the ST, this function returns NULL, as specified by the proposed ANSI standard. char *asctime(struct tm *time) Convert