@tabsize 4 @author "Henk Robbers" @node "A Home Cooked C compiler" @subject "AHCC V5.6" Welcome to Ansi HCC AHCC is a Pure C compatible C compiler for Atari ST and its offspring. Installation of this distribution Changes since first release Gem integration: Editor Quick guide to the main menu Quick guide to the window menu The KIT Project file Free standing: Disclaimer Compiler/Assembler Linker Shell/Compiler/Assembler/Linker Standard library Object format Important read: Introduction to the notion 'area' specific AHCC features A taste of C99 How to combine C and Assembly in a .C file. Throughout this manual the word Enter applies to Return equally. Henk Robbers. december 2011 @endnode @node "Changes since first" December 1 2017 v5.6 Editor: Lines longer than max characters not having any space were incorrectly split. Fixed. Now splitting is done at any (viable)punctuation, loosing that character. Also a alert is displayed. KIT: field 'split lines' should have been TOUCHEXIT. Fixed. Pure C (standard) ispunct is a nonsense function. New function is_punct in common/aaaa_lib.c moved functions is_alpha and is_alnum to aaaa_lib as well. This kind of split is not considered a change, however: when the file is saved, the new state of the lines is saved as well. Beware!! including the character loss when not corrected. Compiler: Flag missing initializers. (also missing in HCC :-) Fixed message [2]arg nil. (happened with propagated assignments involving bit fields. e.g. a.x=b.y=z where x or y are bit fields.) Generic list routines in its own file and header (list.c, list.h) Fixed 'warn .. r1 in use' for ^ operator (exclusive or). A little bit of cleanup. Linker: No of files reported 1 too many. Fixed. Matching 8 byte names against longer names now works both ways. Standard library: Fixed wrong declarations of 'struct time' and 'struct date'. math.h : moved prototype of 'atof' to a place where it now is declared for AHCC as well. Shell: Improved 'Make All' statistics. Replaced VDI input functions for the mouse (needing physical workstation handle) by approppriate AES functions. (notably: vq_mouse, v_hide_c and v_show_c) Thanks to Olivier landemarre for pointing this out. Small improvement in load/saveconfig (aaaa_lib.c). Applications: CALC: Small improvement in parser: skip spaces between : and %. Specifying a new filename forces a create. (Non functional menu 'new' removed.) Pure C's scanf has problems with text fields > 31: fixed. exactly 32 not fixed, but avoided (too much uncertainties). Shell: ESC in journal, menu Calc (calculator) Applications: CALC & TINYCALC: Generalization of the parse routines. Both programs now use the same routines from /common/ i.e. F_x.c, F_x.h F_x(x, y, text) now can be used as a function of x in programs that display values of x for may x's. i.e. X^2+2*x+1 or (x+1)^2 or x^2+2*x*y+y^2 or (x+y)^2 :-) CALC must only be compiled by AHCC. Pure C's f get/set pos are a little bit unreliable. TINYCALC is now part of CALC in the AHCC source distribution. Whole::= replaced any use of .. scanf by appropriate simpler alternatives. Saves about 2.5K January 17 2017 v5.5 Compiler: Commandline versions: Do not wait for a keypress under MiNT or MagiC. All: Wrong code was generated for comparison to a constant in rare situations, resulting in a tst to a immediate. Now either a branch or no operation is generated. Prevent crashes on ill formed defines. Removed some leftover debug info in messages. include/aes.h Added a few defines for the newest aes's. Fixed a memory violation that has haunted me for many years. It was about improper use of strncpy were strcpy sufficed. Null padding by strncpy caused behaviour popping in and out of harmfulness depending on internal distances. Quite a relief to find this mistake. Standard library: Forgot to include stdlib.c in the source tree. Fixed. atof (strtod) forgot to skip leading spaces. Fixed. printf now only removes dot and all fractional zeros with format %g Synced tos.h and mint.h in both include and sinclude folder. Editor: If a window menu is pulled and the mouse is moved outside the windows work area, the menu is pushed(removed). This prevents a annoying lock up of the screen. Page scrolling scrolled 1 line too many. Fixed. A page down detetects form feed character (decimal 12) displayed as ). Scrolling down stops when a at the beginning of a line is detected or when the last line of a window appears on top. Shell::KIT::FIND save state of buttons 'verbose' and '1 per file' in config. June 10 2016 v5.4 Compiler: Fixed a bug in register health analysis where in certain rare circumstances too many operations were discarded. Shell: (not AHCCST) New menu item: Project-->PRJ from folder. Produce a skeleton project file from file names in a given folder. (only 1 deep). Usefull for constructing new project files for AHCC. Editor: Tile windows when started with 2 previous opened files. Fixed a bug where ^2 could loose sync when searching for next unequal lines. January 21 2016 v5.3 Compiler: Fixed a bug that prevented proper casting of constants by explicit casting. Fixed wrong code for casting the result of a comparison to a real (e.g. R1 = R2 < R3 where all R's are reals). Fixed a regression after v4.f Wrong code was generated for comparing the address of a array to zero (spurious, but must be OK). Fixed an obscure error where AHCC crashed on extremely large (more than about a 1000 ch's) string denotations. A teeny tiny little bit of clean up. Assembler: Fixed a regression since v5 where register masks for movem instructions involving D6 and/or D7 spelled in upper case were wrong. (typo in defs.h) Shell: implement asinh & acosh in tiny calculator in console. Editor: Find 'word' did not reverse neatly. fixed. Unselected ^I did not select anymore. Fixed. Library ahccstdf: Fixed bugs in pow, sinh, asinh, cosh, acosh and tanh. (error in common function _Exp). august 23 2015 v5.2 Shell: Compare folders: Mismatch display order of filenames reversed. Double clicking 'Mismatch': first file is left on top. Compare files: (^2) flipflop between red and green according to equality of selected lines. (red: unequal, green : equal). Compiler: Small code improvements (no effects). Small improvements in the optimizer. Nicer display of options with -v. fixed spurious denying of duplicate typ definitions in some cases. Standard library: Added functions asinh, acosh Library ahccgem: Added function vq_vgdos in vdi_wstn.c Calc: (type Esc in journal) Prompt '>'. Assembler: Deny operands of the form symbol.w . shift Dn interpreted as shift #1,Dn (like Pure Asm). Implement Local statement for labels in macros. accept .w on swap instruction. september 18 2014. v5.1 Shell: KIT::match options: 4 radio buttons word, any, prefix, postfix The latter very useful for finding usage of struct/union members e.g. ->large, not ->larger A few better names in the big window struct. (IT) Comparing folders streamlined. see Compare Folders. Comparing files streamlined. see Compare 2. Editor: Fixed a small bug where UNDO involved the first line in some cases. Optional line numbers: New check button in the KIT. Handled similar to 'small font' and 'boldtags' options. Compiler: Fixed a discrepancy in struct alignment between Pure C and AHCC. (Only important when mixing AHCC and Pure C object files). Fixed a bug where a arg in a register got clobbered whith indirect calling via a call returning in A0. Assembler: pseudo op 'xrest': registerlist proprly flipped (as for movem). january 10 2014. v5 general: Back to small version number. (Greetings mister Thorvalds ;-) Replaced 'string' back to char * for single declarators, to Wstr for declarator lists. (appeared to be a little confusing) 'const char *' remains 'Cstr'. I also wanted to reserve 'string' for other programming dialects. Shell: Some patches provided by Gerhard Stoll regarding page up/down keys on some Tos's or emulators. Compiler: Fixed a very old memory corruption. (at last, sigh). N.B. It was a ephemeral corruption that shifted in and out of harmfullnes whenever internal distances changed. I only published versions that did not harm, but it took sometimes quite a while when this happened. Implemented Pure C style inlining: e.g. a prototype specifying a value; e.g. short ror(short v, short c) 0161170; short rol(short v, short c) 0161570; 'is' or <=> between prorotype and value will be silently accepted. Small changes regarding 'void'. Some invisible reorganization and refactoring. Check on a expression's side effects. Notifications "code has no effect". More fixes regarding 'const' (type qualifiers in general). Accept empty arguments in macros. If the argument is anywhere used, the consequences are for the programmer. New AHCC specific unary operators: __ROL1__, __ROR1__ Rotate operand 1 bit left or right. (For use with bitmap manipulators) Assembler: added missing fmovem control regs. Library: prototype for putenv added to stdlib.h (in include). august 21 2013 v4.15 Shell: Message "Loading ...adb" only if verbosity is set. Tinycalc in the journal. Press ESC in the journal. See prompt >. Type a formula (constants only; It is NOT a scripting language), Press Enter. Implemented treeview window for #include dependencies. Menu Project_name->show dependencies ALT+D Implemented treeview window for Function calls. When 2 v's are checked in the KIT, a treeview is displayed in the journal when AHCC is started. Implemented text versions of the above in the journoul. Fixed a obscure bug where the editor crashed on extremely large files. Typical over 40,000 lines and close to a megabyte in size. Fixed a bug where fileselector match pattern was messed up occasinally. Compiler: Fix in handling of typequalifiers on pointers. Fixed a bug in the -u option (undefine) when a name to be undefined was absent. Full implementation of options: -f Dont set 'fast load' bit. -m Mallocs for ST-ram. -r Load program to ST-ram. including check buttons for them in the KIT (group 'Options for the linker'). I did away with some GCC gibberish __THROW,__BEGIN_DECLS,__END_DECLS,__PROTO I have put these in a new folder/file: include/features.h I moved mint folder from mintlib/include to AHCC's include. Fix a regression since 4.11 concerning explicit cast of pointer to long. Fix a bug where #if !NAME was wrongly interpreted when part of a assembly file. Fix a false negative when comparing multiple #defines for same token seq. Fixed a bug where AHCC could crash or corrupt itself on a C file having no areas. (e.g. emptied by defines) Embedding 'const & volatile' in the existing infrastructure was not very well executed. (I hate K&R) Various fixes. Assembler: Fix a bug in the equ arguments of the form: 'equ label,value'. exg: accept size .l Fix a bug where equ'd registers were not recognised as such. Accept unary ! operater as same as unary ~ (tilde:) binary OR. In operands: a scale factor of 1 is silently accepted and ignored for all CPU types. Linker: Fix a bug that could lead to incorrect or no binaries in rare situations. Library: New: ministart.c ; for small footprint programs not needing library preparation nor arguments nor environment (borrowed from Markus Froeschle). october 3 2012 v4.14 General: Removed leftover traces of a debug session some time ago. Compiler: Fixed a bug where a static string was not properly used (changed without copying) The bug resulted in incorrect compiling of ahccstdi.lib. Assembler: Fixed a regression where incbin statement crashed. september 28 2012 v4.13 Compiler(Coldfire target) Fixed a regression in 4.12 concerning use of 'mov3q' instruction. september 22 2012 v4.12 General: Changed 'xref' to 'pdb' in all source files (pdb = Project Data Base, xref.... is only part of it). Compiler: Fixed non Coldfire code for 'move' in some cases. Also fixed a bug where mov3q could have been used, but was not. Shell: Small fix in handling time/date stamps by make. Pass uppercase masks to fileselecter when run on single TOS. Assembler: Fix dc.l name +/- nnnn where nnnn got lost resulting wrongfully in dc.l name. Library: ahccstd*: Added unlink, strcmpi. may 30 2012 v4.11 Compiler: Revision of registerization of local variables. Produces slightly better code. Also repairs Draconis Marathon. Fixes a bug where a explicit cast of ptr to long or vv was handled incorrectly. A further bugfix (A very very old one, perhaps since v3b1). Assembler: Implemented opcodes: align aline Allow single = for 'equals' in IF expressions. Full implementation of 'equ' expressions. addq.w #n,An addq.b #n,An silently changed to addq.l #n,An. 2 new pseudo opcodes for use with Coldfire compatible programs: xsave reglist xrest reglist The instructions generate the movem sequences required for Coldfire campatibility. You, as a programmer, do not have to count the registers for the lea instructions. The compiler will do that for you and also generate the lea's. Library: Provided 68000/Coldfire usable TOS bindings in case a project did not include the AHCC specific tos.h (The one that uses __syscall__). The library is called "ahcctos.lib". march 20 2012 v4.10 General: Some reorganization of debug code. It is now possible to write intermediate code (IXC, aka "interchange code") to a .i file alongside the object code. This option has been disentangled from other debug code. The IXC might be of interest to the curious user, but it is basically of use to myself when there are problems. I dont need to recompile AHCC and compile other peoples code. I can ask a user to send me the IXC. Shell: Name of loaded project is now shown in the menu bar. always visible. Display menu entry removed. Split menu title 'Project'. No need for menu entry 'Assemble', 'Compile' will do just fine. Entry removed. Use HIDETREE to disable the debug menu. (DISABLED was cleared by Boxkite after a selector action). This caused some confusion. Accept names without extension in the project file. They now default to .c Compiler: Flag an error on a unclosed comment. Detect differences in prototypes regarding qualifiers. e.g: p(const char *); vs p(char *){...} Fixed a subtle bug in the optimizer. (Fixes Marathon) Coldfire: Fixed wrong code where a pushed real was used in a call. Fixed wrong code when casting real to unsigned long. Assembler: accept operands of the form (a,b) and (e,f,g) where a is a 16 bit constant and e is a 8 bit constant. generate a(b) resp. e(f,g) where possible. Library: Added function 'delay'. januari 24 2012 v4.9 Compiler: Fixed a extremely stupid bug where comparisons of the kind 'constant compared to variable' were reversed wrongly. e.g. (0 < i) Fixed a terrible bug where under certain circumstances a ftst insstruction got lost. Accept spurious ampersand to a function name to get a reference to that function. There are FPU instruction that are NOT unary operaters. These are: fmod, modf, ldexp and frexp. Put these function in ahccstd.lib. Fixed wrong code with comma expressions within expressions. Coldfire: Fix in the Coldfire Floating point code table. Do not generate addressing mode 6 (An,Xn) with floating point instructions. Do not generate FScc instructions. Repaired wrong divide for pointer difference calculation. Library: stdio.c: function tmpfile added. string.c: function strtoul added. stdlib.c: function system added. ahccstdf.lib Added support for missing FPU instructions on Coldfire. november 28 2011 v4.8 Compiler: Fix a crash that sometimes could occur when a local initializer was absent or was wrong. Fix a crash when a while expression is wrong or absent. Allow {} around any local initializer. Deny arrays of void. Deny returning of arrays. Fixed a regression since 4.7 leading to incorrect code in rare situations. Fix a error preventing real constants of the form: nE-n from compiling correctly. Coldfire: Fix incorrect code when a temporary was needed from a memory location. Library: Fixed a leftover from Sozobon, where a floating point integral part could not exceed |2^31|. Changed v_pie --> v_pieslice november 14 2011 v4.7 Compiler: Slight reduction of spurious error messages. Wrong code was generated when converting a real to unsigned long. New header file stdbool.h small fixes in compiler.h Fixed a error when a input name is a filename only, no slashes. Fixed a mistake with eliminating the false side of a expression of the form: constant ? x : y where the true side is a binary operation. For Coldfire: Small fix in the new code tables for Coldfire. Affects long mul/div. Cleanup of Coldfire code generator. Intruduction of code table for assignment. Many fixes in the code for Coldfire floating point. In rare cases the optimizer must split a move. If no registers are available a pusher is generated. (Until now a message "no free reg" was displayed in stead.) Fixed a bug in a table causing some registers to be kept alive indefinately, causing the above split. Editor: '_' is a alphanumeric character for bold display. Kit: Replaced checkbox 'word' by 3 radiobuttons: whole word word begin anywhere Which makes it possible to find a string that is the beginning of a word. (e.g. prefixes). Library: gemf.lib Fix a confusion in gemf.h removed #define gl_apid _app The 2 names have NOT the same meaning. ahccgem.lib, ahccgemf.lib Fix in appl_init regarding returning of application identifier. june 24 2011 v4.6 Compiler: Cast condition code to int on unary plus/minus to comparisons. (think about it :-) Also a fix in condition code casting for Coldfire. Fixed a regression since V3.b4 where differences between a function prototype and its actual declaration were not error flagged anymore. Assembler: Coldfire instruction set completed. The set is complete, but check for specific Coldfire restrictions on already existing instructions is not performed yet. This will be done in a future release. You can run the new Digger V8 on object files for checking validity of your Coldfire code. Library: Created library ahccstfi.lib. A standard library for Coldfire but without floating point. Affects particularly printf and scanf. For coldfire compatible programs not needing floating point that one would like to run on a Falcon witout FPU. Added function _crystal() and vdi() and struct _VDIParBlk for programs that submit extra bindings based on the Pure C GEM library. june 14 2011 v4.5 Compiler: Fixed a regression since 4.4 causing a alignment error when a bitfield was followed by a plain char declaration. Optimization of table switch such that large gaps between groups of close case values are dealt with efficiently. Correction in table switch for Coldfire code. Index scaling by shift: long. Promote unprototyped pushing of reals and ints. Fix l and f postfix with real constants. Assembler: Digit zero is NOT a octal prefix in assembly files. Implemented * operand. Implemented 'dcb' statement. 'repeat' statement can now be nested. Macros can have 'repeat' statements. Repeat value can be any constant expression. Repaired equ and = statements. Library: Added atan2 to ahccstd.lib february 17 2011 v4.4 Compiler: Fixed a bug in switch statements when a table is generated. The problem only occurs in leaf functions (no further calls). A argument register was not saved. Fixed a regression where redeclarations of variables were not anymore rejected. Bitfields now also work with option -i (type int is 32 bits). The fields are packed into a 32 bit word. Code rearrangement such that (a##b##c) is now correctly retokenized. Assembler: Fixed a regression where C style #if* directives were handled incorrect resulting in strange error messages. Fixed a regression where local labels within a module were incorrectly matched to equally named local labels in previous modules. Implemented scope for dot prefixed labels. (local between non dotted labels) labels within modules couldnt be exported. Fixed. Library: Added missing function 'ceil' Added SozobonX gemfast replacement 'gemf.lib' The lib is a wrapper around ahcc's gemlib. New include files unistd.h, sys/stat.h, sys/types.h These replace functions in ext.h and hence are included by ext.h. Fixed a bug in sleep(). The bug prevented sleep() from sleeping. Linker: Removed redundant debug messages about doubly defined names that could result in a crash. november 28 2010 v4.3 Compiler: Fixed wrong mode bits in Coldfire 'fmovem.d reglist,(A7)'. Fixed typo in "unknown mnemonic" message. Skip rest of line after above message. Improved code for comparing bitfields to zero and assigning constants to bitfields. Replaced flagwords operated by |= resp. &=~ by bitfield definitions. For instance: in stead of 'flag |= FLAGNAME resp. flag &= ~FLAGNAME', now 'flag.flagname = 1 resp. flag.flagname = 0' without increase of code. Repaired warning 'value too big for field', which was never issued due to a typo. Also made sure the generated code conforms to Pure C in this case. The include folder can now be used by both Pure C and AHCC in all case. The sinclude folder is only needed when compiling AHCC* itself. Assembler: Implemented directives 'ifd' and 'ifnd' as synonyms for 'ifdef' and 'ifndef'. A expression of the form (label1 - label2) can only be resolved when the labels are NOT advance references and when the labels are in the same area (or module). This might be repaired in the next release. It will take some contemplation and time. october 30 2010 v4.2 Compiler: Removed error "bool not allowed". Fixed a rare case where logical expressions with && or || including constants were not handled properly. pe if (VERSION == DEMO_VERSION && c < 0) where upercase identifiers are constants and c is a variable. Fixed wrong code for comparing a double to a integer constant. Fixed assignments of the form a = b = c; where a and b are doubles. Accept '=' with options -I, -D Assembler: Fix in preprocessor. endif directive was not detected properly resulting in "error 1 #endif missing". implemented directives: .extern, .ifne, .iff, .ifeq, .ifle, .iflt, .ifge, .ifgt labels without ':' must begin at position 1 of a line. This assures typos in opcode mnemonics are rejected. Fixed 'wrong processor type' message. Shell: If AHCC cant find header files, setting maximum verbosity will display in the journal which paths AHCC has tried. (Maximum verbosity = all 4 v's in the KIT.) Implemented project file option .S .S options are passed when compiling assembler files. (extension .S) When the option is present it is passed to .S files only. If absent, the .C options are passed to all source files including .S files. Editor: Fix in detecting changes in files with Unix line endings resulting in false positives when closing. Undone changes were falsely reported as change. Not dangerous but Annoying. With option 'visible tabs' active, AHCC now also shows trailing white space. Usefull when comparing files. The small triangle is used. When 'visible tab' is inactive, compare files (^2) no longer takes trailing white space into account. So, when 'compare folders' marks files as changed and ^2 doesnt find a change, you can be sure that its only trailing space that is the difference. october 5 2010 v4.1 Compiler: Further fixes for and completion of Coldfire target. Fixed a rare crash when compiling nnn.c when AHCC also had open in a window a file nnn.s from the same folder. It happened to me while I was rewriting nkcc.s into nkcc.c :-) Cdecl functions returning a pointer do so in both a0 and d0. Assembler: Accept ENDR after REPEAT. Fix a memory leak in the 'ascii' opcode. Library: Set both variables _envp and __EnvStrPtr in ahcstart.c Replaced getenv (gcc version) by getenv from dlibs. Repaired enum HOURGLAS,BUSYBEE in sinclude\np_aes.h & aes.h Removed a few leftover debugging printf's from AHCM Shell: Find multiple, Find in project: Fixed line number counting for files with unix line endings. Editor: Window menu 'leave' behaviour changed. The menu is no longer popped when left via the bottom of the menu. may 27 2010 v4 Editor: Better placement of windows with tiling. Compiler: Finished 68020 compatible Coldfire target. Long mod (%) done by hardware for 68020+ and Coldfire. Fixed a bug in AHCCST concerning assigning a variable to a bit field. Forbid duplication of enum identifiers. Linker: 'nm' list: addresses always in hex. Library: Fixed binding for vsl_ends; Some VDI's acces intout. Changed binding for v_gtext; Intin array static. Replies and setting of errno same as Pure C lib. march 17 2010 v3.b8 This page: Order of history reversed. Compiler: Option -7 preliminary Coldfire V4e target. ========================================= See also: Status of Coldfire support. Fixed Option -c- No nested comments didnt work. Fix in option -*i (32 bit int) error 'no declarer for extern object' changed to warning, default is 'int'. New warning: 'no prototype for 'name'. warning: 'no args matching' only if there are args to match and only for old style prototypes. Removed option -4 (double is float) Removed option -*s (scale 32) It appeared that Pure C does long scaling the same way without being optional. A few small fixes for very rare situations. Removed a spurious call to a diagnostic print routine. Reduces all binaries by about 7Kb. Relaxed a limitation on the number of names in the Pure C object output format. Linker: Improved load map. All symbols are printed. Local symbols are enclosed by < >. Option -n: Write a 'nm' style list of symbels to prog.SYM DRI symbol table in executable: write symbols first 22 characters in stead of first 8. Assembler: Allow size .b in Scc instructions. Detection of '*' comment in lexer. new directives: (from devpac) incbin include a binary file as is at the current position. section allowed operands: text, data or bss. Library: Merged ainclude and sinclude folders. ainclude is now obsolete and removed. The sinclude folder can be used for both Pure C libraries and AHCC libraries. All 16 bit integrals in sinclude are declared as short !!!! FILE structure of AHCCSTD.LIB compatible with the one of Pure C lib. (Needed for fixing AHCCSTD ;-) Fixes in AHCCSTD.LIB Changed name of folder from AHCCLIB to AHCCSTD Update wind_get. (table of number of replies) january 6 2010 v3.b7 General: Changed the naming scheme of all the incarnations of AHCC. The name of the project file is always the same as the name of the executable. See 'distribution'. Shell: Close the project file. (problems saving after ALT+P) Fixed a memory leak when compiling from a open window. Compiler: Create AHCC_ST. A 68000 version without floating point support. The header cache is always freed between make's. It must also be freed between files when caching is switched off. Cached headers take about 30% less space due to redesign of tokenized input format. Another dereference of a zero pointer. Library: Fixes in stricmp, strnicmp & strtol. Consistency check in AHCM (memory allocator). december 16 2009 v3.b6 Compiler: Fixed a dereference of a zero pointer. Couldnt be detected on the Milan. So I will always be needing my TT. december 8 2009 v3.b5 Shell: Very, very usefull: New menu entry Project->Edit ALT+P Loads the current projectfile in the editor. Open->Open .P* removed. menu entry 'Find selection in project' now also in the journal. KIT: button for option -*u (default .super in assembly) Compiler: Improved include file lookup. Now Teradesk compiles directly from its own directory. The need for setting a include dir in the KIT is almost never needed when -I's are in the project file. This is also beneficial for AHCC_P.TTP. There the default to ainclude is removed. Made a lot of error/warning messages a lot more readable. Completely forgot about relative long branches in the output phase. :-( Fixed. Fixed a regression and a closed loop while generating switch tables. (related to allowing long 'case' constants) It happened when a case value forms a negative short. typechecking of call's: p(); or p(void); /* declaration */ ........ p(); /* call */ Is no longer warned. The mixing of old and new args is silently accepted when no arguments are involved. Same for declarations: p() or p(void); followed by p(void){...} or p(){...} Bugfixes for rare cases involving boolean comma expressions and pushers. Assembler: Fixed ordinal in "out of range" message for shifts. Fixed a serious regression when combining C and Assembly in a file. (message: CE: invalid asm area number) Accept include filename between ampersands. For the moment the warning persists and can be ignored. november 25 2009 v3.b4 Assembler: Fixed a memory leak; C preprocessor activated in .S files While doing this, it appeared that AHCC never checked if a preprocessor command was the first of a line. :-( This is now repaired. .global .org .equ and .set second form .ascii .asciil .asciiz .page option -*u default .super repair broken exg An,Dn allow mixed register lists of form: Dn-An ( ascending register number) --> Dn-D7/A0-An An-Dn (descending register number) --> An-A0/D7-Dn Option -*w to set default size for Xn (no dot). default (option not set) is word. Also fixed a bug in determining the Xn size. Compiler: Activated and fixed option -x prepend underscore. Fixed occasionally incorrect line number in messages. #warning __func__ identifier and its synonym __FUNCTION__ case: long constants allowed Fixed stupid mistake in constant validation since v3.b3 Typos in constant folding for <= and >= (wrong way around) Not detected until compiling emutos :-( Negative absolute operands handled correctly. Removed '#' from #warn, #error messages. Less cryptic message for mismatching pointers to function. Sometimes the Help opened the wrong file. Fixed by restructuring the Help DataBase. Allow 'formal' declaration of arrays by specifying empty [] pair. e.g. static char forward[]; It appeared that if flag 'cdecl calling' was set, functions returning a pointer returned in D0, wereas the callee expected the pointer still in A0. Probably a relic of a distant past. Pointers are now always returned in A0. Fixed another bug in 'cdecl' calling in combination with __syscall__. (a2 wasnt preserved) Incrementing a void * wasnt warned nor handled sensibly. Arithmetic to unscalable pointers is warned and not scaled. Fixed wrong handling of absolute Lvalues and references. Fix and improvement of rare optimization incidence. Fixed a bug in implicit dereferencing of callee expressions. e.g. (a ? c : d)(arg); Fixed a terrible regression in constant casting. Casting int to real was lost somewhere. Fixed a bug in long pointer scaling in 68000 mode (-2-) Linker: Fixed a memory bug for libraries with excessive number of names. ( more than 1359 ) Result of a nested project was not correctly passed and the linker was not called. Fixed. 'Linking' message gives name of project file. Object files are linked in the order in which they appear in the project file. Build a ROM image: Option -t=N N is startaddress of text+data sections. bss start will be set at 0. -i=N N is size of image in kilobytes. (zero padding) Make sure ALL areas are of even size. Shell: KIT: button 'inherit options' for nested projects, inherit options from parent project. Editor: Improvement of UNDO behaviour. See Undo. march 19 2009 v3.b3 Fixed a omission while expanding. (K&R 2nd A12.3 don't replace at rescan.) My solution of recursive macro expension yielded false positives. So it is removed. It might be necessary to completely redesign the expansion mechanisms. The current implementation is a Sozobon legacy. AHCC should work fine when you remove all recursive definitions and usage in your sources. A memory bug is killed. A few minor bugs fixed. The Pure C offsetof macro couldn't work in #if's (again, Sozobon legacy). Implemented __offsetof__ operator If your programs use offsetof in a #if conditional and you do not use one stddef.h of AHCC, you must copy the implementation of offsetof from stddef.h in folder INCLUDE to your own stddef.h. Handling of # (stringify) and ## (token catenation) same as Pure C (Not entirely ANSI). Oh well, ANSI is completely bonkers in that respect. februari 2 2009 v3.b2: Macro expansion now detects recursion. (v3.b1 crashed) ===================================== Bugfixes in relative path handling. More flexible use of shel_find result. Builtin macro __FILE__ replaces '\' by '\\'. @endnode @node "A taste of C99" The following C99 features are implemented in AHCC: // Comment _Bool long case constants and switch __func__ identifier. (__FUNCTION__ as a synonym) @endnode @node "combine C and Assembly" Assembly functions can be included into C source files. These functions are specified by the AHCC specific __asm__ keyword. __asm__ shares its syntactical position with the keyword cdecl. Example (you can find one in the file ahcstart.c in ahcclib) void __asm__ asm_function(void) { ... M68K standard assembly ... } C static and global declarations can be directly used in operands where they are syntactically appropriate. Members of unions and structs can be accessed by the operator '@' Because the point was not available, I chose the '@' aka 'at' symbol. When '@' is used on a data declaration the offset within that object is added to the address and the resulting operand is a memory reference. When '@' is used on a struct or union type definition, the offset within the type is produced as a constant. This makes it possible to address members of unions and structs with the indirect addressing modes. The whole construct removes the necessity to repeat struct and member definitions in assembler include files. In stead you can include the C header files. @endnode @node Installation @alias distribution The AHCC distribution ===================== AHCC_HYP.ZIP :: AHCC.HYP AHCC.REF AHCC.STG To be unzipped to your favourite st-guide folder. So you can read them first. Full version for 68020 or higher, 68881/2 and Coldfire V4e ========================================================== AHCC.ZIP :: Unzip will give you folder AHCC.BIN somewhere. If you haven't got Pure C, just use AHCC from this folder. If you have a Pure C Installation, it is best to copy the files from AHCC.BIN to appropriate places in your Pure C folder. This makes it easy to combine AHCC & Pure C object files freely within the same project. You must at least copy AHCC_RT.H to your current include folder. AHCC.BIN\ LIB\ AHCCGEM.LIB ; GEM bindings AHCCGEMF.LIB; GEM bindings for Coldfire AHCCSTD.LIB ; Standard lib AHCCSTDI.LIB; Standard lib for 68000 without floating point AHCCSTDF.LIB; Standard lib for Coldfire AHCCSTFI.LIB; Standard lib for Coldfire without floating point GEMF.LIB ; Sozobon Gemfast wrapper functions AHCSTART.O ; startup code for above Standard libs MINSTART.C ; minimal startup code INCLUDE\ ; include directory for Pure C and AHCC libs SINCLUDE\ ; include directory using short exclusively only needed for compiling AHCC* itself. ------------ AHCC.CFG ; config file for AHCC.PRG AHCC.PRG ; Gem integrated Editor/Shell/ Compiler/Assembler/Linker AHCC.MAP ; its load map AHCC.BUF ; Last Copy/Cut from editor See Buffer AHCC.RSC ; resource AHCC_T.TTP ; commandline version of Compiler/Assembler AHCC_T.MAP ; its load map AHCC_P.TTP ; Shell/Compiler/Assembler/Linker AHCC_P.MAP ; its load map AHCL.TTP ; Commandline Linker AHCL.MAP ; its load map AHCL_P.TTP ; Linker using project file HELLO.C HELLO.PRJ ; Everybody's favourite starter program HELLO_PC.PRJ ; Pure C version All the above binaries are compiled for 68020+ and 68882 You need Falcon/TT or higher to run them. Version for 68000. No floating point support. ============================================= AHCCST.ZIP :: Unzip will give you folder AHCCST.BIN somewhere. If you haven't got Pure C, just use AHCCST from this folder. If you have a Pure C Installation, it is best to copy the files from AHCCST.BIN to appropriate places in your Pure C folder. This makes it easy to combine AHCCST & Pure C object files freely within the same project. You must at least copy AHCC_RT.H to your current include folder. AHCCST.BIN\ LIB\ AHCCGEM.LIB ; GEM bindings AHCCSTDI.LIB; Standard lib without floating point GEMF.LIB ; Sozobon Gemfast wrapper functions AHCSTART.O ; startup code for above Standard lib MINSTART.C ; minimal startup code INCLUDE\ ; include directory for Pure C and AHCC libs SINCLUDE\ ; include directory using short exclusively only needed for compiling AHCC* itself. ------------ AHCCST.CFG ; config file for AHCCST.PRG AHCCST.PRG ; Gem integrated Editor/Shell/ Compiler/Assembler/Linker AHCCST.MAP ; its load map AHCCST.BUF ; Last Copy/Cut from editor See Buffer AHCC.RSC ; resource AHCCST_T.TTP ; commandline version of Compiler/Assembler AHCCST_T.MAP ; its load map AHCCST_P.TTP ; Shell/Compiler/Assembler/Linker AHCCST_P.MAP ; its load map AHCL.TTP ; Commandline Linker AHCL.MAP ; its load map AHCL_P.TTP ; Linker using project file HELLO.C HELLO_ST.PRJ ; Everybody's favourite starter program All the above binaries are compiled for 68000 They can be run on any Atari or clone. Version for Coldfire V4e ========================================================== AHCCCF.ZIP :: Unzip will give you folder AHCCCF.BIN somewhere. AHCCCF.BIN\ LIB\ AHCCGEM.LIB ; GEM bindings AHCCGEMF.LIB; GEM bindings for Coldfire AHCCSTD.LIB ; Standard lib AHCCSTDI.LIB; Standard lib for 68000 without floating point AHCCSTDF.LIB; Standard lib for Coldfire AHCCSTFI.LIB; Standard lib for Coldfire without floating point GEMF.LIB ; Sozobon Gemfast wrapper functions AHCSTART.O ; startup code for above Standard libs MINSTART.C ; minimal startup code INCLUDE\ ; include directory for Pure C and AHCC libs SINCLUDE\ ; include directory using short exclusively only needed for compiling AHCC* itself. ------------ AHCCCF.CFG ; config file for AHCCCF.PRG AHCCCF.PRG ; Gem integrated Editor/Shell/ Compiler/Assembler/Linker AHCCCF.MAP ; its load map AHCCCF.BUF ; Last Copy/Cut from editor See Buffer AHCC.RSC ; resource AHCCCF_T.TTP ; commandline version of Compiler/Assembler AHCCCF_T.MAP ; its load map AHCCCF_P.TTP ; Shell/Compiler/Assembler/Linker AHCCCF_P.MAP ; its load map AHCLCF.TTP ; Commandline Linker AHCLCF.MAP ; its load map AHCLCF_P.TTP ; Linker using project file AHCLCF_P.MAP ; its load map HELLO.C HELLO_CF.PRJ ; Everybody's favourite starter program All the above binaries are compiled for 68020+ and Coldfire You need Falcon/TT or higher to run them. The programs run on Coldfire without emulation. Source distribution ============================================================ AHCC_SRC.ZIP :: AHCC.SRC\ subsystem folders: AHCC\ ; sources of the Compiler/Assembler/Linker AHCCGEM\ ; sources of the GEM bindings AHCCLIB\ ; sources of the Standard lib CALC\ ; Example GEM program (No documentation) COMMON\ ; sources of routines used by all subsystems subject to diverse build environments (Hence not presented in form of a library) DIGGER\ ; sources of TT-Digger (Yes, finaly open :-) SHELL\ ; sources of the Shell of AHCC TEXT\ ; sources of the text functions of all subsystems root: AAAA.C ; Main of all subsystems. Build is governed by the contents of the project files and the resource files. The resource files sit in their respective subsystem folders. AAAA.H ; Main header file AA_INTRO.H WI_TYPES.H ; Header files that must be present in the root AHCC.PRJ ; Project file of complete GEM integrated AHCC AHCC_P.PRJ ; " Shell/Compiler/Assembler/Linker AHCC_T.PRJ ; " commandline /Compiler/Assembler AHCCST.PRJ ; Project file of complete GEM integrated AHCCST AHCCST_P.PRJ; " Shell/Compiler/Assembler/Linker AHCCST_T.PRJ; " commandline /Compiler/Assembler AHCCCF.PRJ ; Project file of complete GEM integrated AHCCCF AHCCCF_P.PRJ; " Shell/Compiler/Assembler/Linker AHCCCF_T.PRJ; " commandline /Compiler/Assembler AHCL.PRJ ; Project file of commandline Linker AHCL_P.PRJ ; " Linker using Project file AHCLCF.PRJ ; Project file of commandline Linker for Coldfire AHCLCF_P.PRJ; " Linker for Coldfire using Project file AHCX.PRJ ; " Editor only. CALC.PRJ ; " Example program CALC_PC.PRJ ; " Example program original Pure C DIGGER.PRJ ; " TT-Digger Unzip will give you folder AHCC.SRC somewhere, from which you can build everything. All programs need the SINCLUDE folder. CALC.PRJ, AHCX.PRJ and DIGGER.PRJ will build in their respective folders CALC, TEXT and DIGGER. AHCC*.* suite will build into SHELL folder. From there you can copy the new binaries into the bin folder of your choice. @endnode @node include The AHCC distribution comes with 3 include directories. This is why: INCLUDE Basically the original Pure C folder. It has some major changes in it to make it usable by AHCC. It can of course be used together with the Pure C libraries. It makes it possible to port a app to AHCC by compiling and linking files 1 by 1. Most important aspect of this folder is that it uses 'int' type for 16 bit integral types. SINCLUDE The most important property of these header files is that ALL ocurrences of int have been replaced by short. This makes it possible to use these header files for programs for which you must define int as 32 bit. These programs can keep using the standard 16 bit libraries of ancient ST. All AHCC subsystems use SINCLUDE. SINCLUDE also contains my personal version of the AES and VDI headers. Soon after I started writing GEM programs in 1988, I got extremely annoyed by the ridiculous, annoying and spurious prefixes. So I removed the lot. All AHCC subsystems rely on these personal headers. @endnode @node "Eextension for Operating Systems" unary operators: __bswp__ byteswap input size: byte, word, long output size: word, long byte: the operand is (sign)extended to word then rotated 8 bits word: the operand is rotated 8 bits long: the low word is rotated 8 bits, the high word is rotated 8 bits and then the high and low words are swapped. identifiers just providing code: __save__ Save d0-d7/a0-a6 on the stack __rest__ Restore d0-d7/a0-a6 from the stack __nop__ No operation (pipeline flushing) __stop__ (Coldfire) halt processor until a interrupt occurs Special notion __SR__ Can be used in assignments to get or set the status register. examples: int sr = __SR__; __SR__ |= 0x0700; __SR__ = sr | 0x700; @endnode @node "specific AHCC features" @alias __syscall__ @alias __offsetof__ @alias "32 bits" AHCC extensions =============== Eextension for Operating Systems Other extensions: Hint! Use these exclusively in header files. __syscall__ operator This operator makes a TOS binding library obsolete. syntax: __syscall__(a, b) __syscall__(a) a: trap number b: optional first item to push on the stack (cdecl) or put in D0 See the most comprehensive example of its usage in TOS.H :-) The operator takes the same syntactical position as cdecl and thus forms part of a complete prototype that is ANSI for the rest of it. AHCC will directly generate trap instruction sequences. __offsetof__ unary operator Works almost exactly as sizeof operator. 1: The left term must be a expression denoting the member of a struct or union object. e.g. a: pobject->member b: (*pobject).member c: object.member 2: The left term is a union or structure type followed by a dot and a member name. e.g. struct node.left the result is a constant of type size_t representing the offset of the member within its union or structure type. In stddef.h you can find the following ANSI macro: #define offsetof(type, member) __offsetof__ type.member The macro can be used for examples 1b, 1c and 2 Note that examples 1a and 1b are equivalent. 16 or 32 bits AHCC can be presented with a default int size. See compiler_options. When AHCC is configured to 16 bit int, it will consider int and short as completely synonymous. When AHCC is configured to 32 bit int, it will consider int and long as completely synonymous. This to avoid useless warnings about pointers. combine C and Assembly AHCC accepts assembly on the function level in .C files. @endnode @node "Project file" The project file is a ascii file that can be produced by AHCC's integrated editor. ::= [ | ¯*® ] [ ¯.L® ¯[® ¯]® ] [ ¯.C® ¯[® ¯]® ] [ ¯.S® ®[® ¯]® ] ¯=® { ¯(® ¯)® } ::= ¯*® | | | | | ::= [ ¯[® ¯]® ] ::= [ ¯[® ¯]® ] ::= another Project file. ::= A linkable object file of the implemented format with extension '.o' ::= A library file of the implemented format with extension '.a' | '.l' | '.lib' ::= A ascii file with extension '.s' ::= A ascii file with extension '.c' ::= | ¯,® @endnode @node "Quick guide to the main menu" File Open ... Open c* Open h* Open s* Open pr* Quit Options Window ... Tile Overlap cycle Function keys ... Open buffer Find multiple ... Folders for compare ... Compare folders Define braces ... At rtn reset_undo autosave config Find in hypertext Project Select ... Deselect PRJ from folder ... (!! Not AHCCST.PRG !!) Edit Reload Config ... Clear help stack Find in project ... Show dependencies Show function tree Compile Compile ... Assemble ... Make Make all Link @endnode @node File @alias Open Quit This menu title only contains Open and Quit entries. All the other file operations are held in the window menu for that file once the file is opened. Open ... The first entry implicitly supplies the fileselector with the wildcard *.* Open The other entries supply *. followed by the extension wildcard as given in the menu entry itself. You can use a resource editor for adapting the wildcards to your own liking. Make sure the editor does NOT change object indices. Quit Leave the program. If any changes in open files are not saved, the program asks you whether this should be done or not. If 'Autosave config' is set, AHCC will write its configuration to AHCC.CFG and the contents of the copy/paste buffer to AHCCBUF.TXT. Both files are loaded when AHCC is started again. When the project help is activated, the project database will be written back without asking and only if the database content has become different. See 'Editor' for more details about the functions of the editor. @endnode @node Options @alias Window Tile Overlap cycle Window ... The KIT is opened with at least the options block visible. See KIT for more details. Tile The open editor text windows are tiled on the screen. Only the first 9 windows are affected. It is particularly useful with 2 windows on a big screen. Overlap All open editor text windows are displayed overlapping. Cycle Top the next open window. @endnode @node "Function keys" @alias "Open buffer" Function keys ... AHCC has 20 built in fixed texts very often needed in C and assigned to function keys F1 to F20. This menu entry displays the texts in the journal. A % in the text indicates where the cursur will be placed after insertion of the text. Open buffer The Copy/paste buffer will be opened in a window. You can edit in this window, but NOT cut, copy or paste :-) You can also select a portion of the buffer contents. See also Paste. @endnode @node "Find multiple" @alias "Compare folders" "Define braces" "Folders for compare" See general information about the KIT. Find multiple ... The KIT is opened having at least the 'Find' block visible. See general information about browsing. Folders for compare ... The KIT is opened having at least the 'Compare Folders' block visible. There you can specify 2 folders for comparison. Compare folders Do the compare of the previously specified folders (see above). When the word 'Mismatch' is selected by the user the 2 files will be opened in windows and the first mismatching lines will be made visible and highlighted. Define braces ... The KIT is opened having at least the 'Define braces' block visible. In this block you can define braces that are words. A single '*' at the end of a word serves as a wildcard. It is mostly used for preprocessor nests : '#if* ... #endif'. @endnode @node "At rtn reset_undo" @alias "autosave config" "Find in hypertext" At rtn reset_undo This options affects the lifetime of the undo buffer. By default the undo buffer is emptied at each mouse click. When set, the undo buffer is also emptied when a new line is created by pressing Enter. Note that there exists a undo buffer for each text window. Autosave config The configuration and the copy/paste buffer are saved to disc when AHCC is quitted. Find in hypertext A selected text is sought for in this hypertext. The text must be a node or alias. @endnode @node "Project manager" @alias Shell Project Select Deselect Edit Reload "PRJ from folder" @alias Config Compile Assemble Make @alias "Show dependencies" "Show function tree" "Make all" "Find in project" Link @alias "Clear help stack" Project management is based on the syntax of the Pure C project manager. The manager comprises the menu title 'Project' and a memu entry showing the name of the current project. Menu entries are: Edit The currently loaded projectfile is loaded in a normal text window ready for editing (or reading :-). Reload The project file is reloded and parsed for subsequant use with "compile' and 'make ...'. Config Open the KIT for further configuration. Clear help stack For if you lost track of the number of HELP's active. Select Load a new project. Via the file selector a new project can be loaded. When affirmed by OK, the old project is erased and the selected project will be loaded. Deselect Unload (erase) current project. PRJ from folder Produce a skeleton project file from file names (*.C, *.S, *.L*) in a selected folder into a selected text file. From this file it should be easy to produce a true project file for use by AHCC. The fileselector will be invoked 2 times: 1: To obtain the name of the folder. 2: To obtain the name of the output file. A extension of .prk is suggested so a existing project file is not likely to be overwritten accidentally. Edit The current project file is opened in a window for editing. Reload Currently changes in the project file are not recognized by AHCC. This will be repaired in the future. For now, you can force the use of a changed project by selecting this menu entry. Config The options blok of the KIT will be displayed. A description of options can be found in section KIT. Find in project Same as 'Find multiple' but the string is sought for in the files belonging to the current project. See also 'KIT'. Show dependencies A tree view of files and dependencies as expressed in the project file will be produced in a window. This tree will only be complete once a 'make all' has been successfully completed. Show function tree A tree view of functions and calls as expressed in the source tree will be produced in a window. This tree will only be complete once a 'make all' has been successfully completed. If the above 2 entries are chosen from the journal window menu, a textmode version is displayed in the journal. This version can be copied and pasted at will. Of course it can alse be saved to a file (The whole journal, that is). Compile Compile the file in the top window when it has either extension .C or .S In contrast to Pure C, AHCC considers the file part of the current project. So the file is compiled within the context of the project. All options from the project file and the KIT are passed to the compiler. So it is not necessary anymore to do a dummy edit and then select 'Make'. Compile ... Same as compile, but the file is selected through the file selector. Extension .C is preset. Assemble Same as compile. Assemble ... Same as compile, but the file is selected through the file selector. Extension .S is preset. Make Compile all files of the project whose source files are newer than the corresponding object files. The process takes in consideration header files mentioned as dependencies in the project file line between parenthesis. If the option 'Auto dependencies' is set in the kit, the process needs a valid project database (.ADB). The use of 'Auto dependencies' is only useful after a 'Make All' has been successfully performed. In case of 'Auto dependencies', dependencies in the project file are ignored. Make all Compile all files of the project. When a 'Make All' does not finish due to user interrupt or errors, a simple Make will suffice for further attempts to produce the program or library. Link Link the current project and produce a executable binary or a library. @endnode @node "Quick guide to the window menu" The window menu: File(window) Save Save as ... Print Print selection Close Abandon Edit Undo CrLf Reveal changes Shift left Shift right Fix tabs To upper case To lower case Replace ... Replace same Buffer Cut Cut&append Copy Append Paste Search Find ... Find same Find same other direction Find selection Find sel. multiple Find sel. in proj. Select all Compare 2 See filecompare. Reveal cursor Reveal end selection Go to line Check braces Find declaration @endnode @node "File(window)" @alias Save Print Close Abandon @alias "Save as" "Print selection" Save Write edited file back to disc if modified. AHCC keeps track of edited lines. If a line has been modified back and forth not resulting in a real change, the line is not marked as modified. Particularly of interest when a file is closed. Save as ... Write the file to disc under a different name. The file selector is invoked for specifying the new name. Print Print selection Write the whole file, or a selection to PRN: Close Close file and remove its window from the screen. If the file is not really modified, the file is closed silently, otherwise a alert is invoked for a choice between cancel, discard changes or save. Abandon. All changes are abondoned and the contents of the file after last 'save' are displayed. @endnode @node Edit @alias Undo CrLf "Reveal changes" "Shift left" "Shift right" @alias "Fix tabs" "To upper case" "To lower case" Replace "Replace same" Undo 1: Undo all changes since the last mouse click, or last Enter depending on 'At rtn reset_undo' setting. 2: After use of HELP for finding declarations, UNDO returns to the place of the HELP action. All such HELP actions are maintained in a help_stack. Each HELP steps the stack up. Each UNDO steps the stack down. Unless some editing has been done in between. In that case the help stack has been canceled and the edit will be undone. Whether a edit UNDO or a HELP UNDO will be performed can be seen in the menu title "Project". When a help stack is active the title reads "Project (Help)". If you lost track and you don't want to take the risk of pressing a UNDO too many, you can clear the stack by pressing shift + UNDO. CrLf This menu entry is checked when the first line of a text is ending with Carriage return AND Line feed characters. Selecting the menu entry will flip the setting. When the file is saved, the setting will be used for line ending in the whole file. Reveal changes When AHCC complains to you that a file is changed and not saved, use this menu entry to find the changed lines. Especially useful when you forgot what you did and didn't really have the intention to change the file. Each invocation of 'Reveal changes' will search further after the last line of the current display. Shift left Remove as much white space from the beginning of all selected lines such that a left shift according to the current tab size setting is achieved. Shift right Insert a physical TAB at the beginning of each selected line. Fix tabs Experimental function. The function acts on a selection and uses 3 parameters that can be set in the KIT in 'Retabulation block' and 'Tab size'. To upper case Convert selected text to upper case. To lower case Convert selected text to lower case. Both functions are restricted to the first line of a selection. Replace ... The KIT will be opened with at least the 'Find' block visible. See KIT for more details. Replace same Replace next or all occurrences of the 'Find' string by the 'Replace' string. When beginning or end of the file is reached during Find or Replace operations, the operation will stop and the direction of operation will be reversed. @endnode @node Buffer @alias Cut "Cut&append" Copy Append Paste Operations to and from the copy/paste byffer. Cut Remove selection from current window and copy to buffer Cut&append Remove selection from current window and append to buffer Copy Copy selection from current window to buffer Append Append selection from current window to buffer Paste Insert from buffer at current cursor position. If a selection is on: Replace selection with content of buffer. If part of the buffer content is selected, this selected part is pasted in stead of the whole buffer. see also 'Open buffer'. @endnode @node Search @alias "Find ..." "Find same" "Find same other direction" "Find selection" @alias "Find sel. multiple" "Find sel. in proj." "Select all" "Compare" @alias "Reveal cursor" "Reveal end selection" "Go to line" "Check braces" @alias "Find declaration" Find ... The KIT is opened having at least the Find&replace block visible. Find same Search for next current find string further in top window. Find same in opposite direction Viz. Find selection Copy selection to Find block and search for it in top window. Find selection multiple Copy selection to Find block and search for it in currently defined directory for multiple find. Find selection in project Copy selection to Find block and search for it in current project. Select all Select all text in top window. Compare 2 Compare 2 files. See filecompare. Repeatedly applying this menu will flipflop between series of equal resp unequal lines. Equal lines are selected in green, unequal files are selected red. Reveal cursor Slide window such that the text cursor becomes visible. Reveal end selection Slide window such that the end of the current selection becomes visible. Go to line. The KIT is opened having at least the Window parameters block visible. Check braces Match the following braces recursively: {} [] (). Matching starts at cursor position and proceeds until the end of the file. Reveal declaration Inspect the project database to see if the selected word is a declaration. If found, open the file in which the declaration is made at the declaration's position. Only file level declarations are considered. @endnode @node KIT The KIT is AHCC's toolbox. It is a large dialogue held in a scrollable window. All items are applied immediately when activated: Buttons by just left clicking, editable text fields by pressing Enter. To make a text field active, place the text cursor in the field by a left click. The KIT can be kept permanently on the screen. The KIT is divided into blocks. Some blocks are revealed automatically through appropriate menu items. The info line of the KIT tells you on which file any KIT action will be performed. Find & replace block Compare folders block Window parameters block Retabulation block Define braces block Options for the Shell block Options for the Compiler block Options for the Linker block @endnode @node "Find & replace block" Column of strings headed by Find: Search strings are their own exit buttons. Type a string in one of the fields and press Enter. If a string is found, it will made visible and selected in its window. Column of radiobuttons headed by R: The selected button tells which find string is used by the Find&replace operation. It ensures that find and replace strings are kept related independant of the current find operation. It prevents inadvertantly replacing a unrelated string by the replace string.  Replace by: If the cursur is placed in this field and Enter is pressed, the string marked by one of the radiobuttons will be sought for and if found replaced by the content of this field. Radio buttons: Top window Search will take place in the window mentioned in the KIT's info line. Project Search will take place in the current project. Multiple: Search will take place in the directory mentioned in the field below the 'Multiple' button. See browse for more information. Check buttons: Word checked: Searches are performed on whole words only. unchecked: Any character sequence matching the string is found. Case checked: Strings are searched for case sensative. unchecked: Strings are searched for independant of case. space checked: Selection of a found string will be including surrounding white space. unchecked: The exact string will be selected. Buttons  & : Indicate the direction of the current search. String below 'multiple' button: Here you specify the directory to which the multiple search will be applied. Right clicking on the field opens the fileselector for a easy way of choosing. In a multitasking environment you can also drag&drop a directory from a desktop window onto the field. See browse for more information, especially for wildcard usage. Check buttons: These are used in 'multiple' and 'project' searches. See browse for more information. deep checked: Scan subdirectories. unchecked: Scan only stated directory. 1 per file checked: Stop searching a file as soon as a string is found. unchecked: Report all occurrences of a string. Verbose: See browse. @endnode @node "Compare folders block" @alias foldercompare It is basically simple. You specify 2 folders in the KIT. Same sort of wildcards apply as for browse. This can be done by typing, by right clicking which opens the file selector or by dropping a path object on the field. Press GO and all files in the folders are compared. If you have checked the 'deep' button, all nested folders will be compared recursively. A report is put in the journal. Mismatch filename1 :: filename2. Unequal files found. Lone filename. A file is in one of the directories only. Right click on these words and the files will be opened in windows in a convenient way. In case of Mismatch, the 2 files will be opened and tiled vertically and ready for applying filecompare by pressing Ctrl + 2. @endnode @node "Window parameters block" Split lines on last space before nth ch: Some texts, mostly originating from wordprocessors, only have hard newlines per paragraph. Because AHCC is not a word processor but a simple editor, no dynamic formatting takes place. You can specify a splitting position here. The default is 248. The splitting is done at load time and is permanent during the session. If you save, the splitting will be permanent over all sessions. ;-) For good reasons a split is not considered a change in the file content. So if you want to keep the lines split, you must use Save as..., or make a small change in the text and save. Note: the split parameter is not used when editing. The feature is added to accomodate texts that are apparently designed with dynamic formatting in mind. In other words: the extreme length is not intended to be a extreme long line. If you really want long lines you can still make them. Tab size: Separation of tab positions. Physical TAB character '\9' expands to next higher tab position by inserting spaces. Visible tab: A 2 character field. first character: the one that replaces the TAB chaeacter. second character: the one that replaces generated spaces. If the first character is space, the second chracter is ignored. Remove trailing space: When a file is saved, any trailing white space in a line will be removed. autoindent: Enter used for creating a new line will start this new line with the heading white space taken from the line preceding the new line. Small font: If there is a font that is half the size of the current font, the former will be switched to. Boldtags: Reserved word (as defined by AHCC's compiler implementation) will be displayed in bold face. Scroll information bars, for vertical and for horizontal scrolling. Each bar has 3 fields and 1 check button. Following the arrows: Number of lines resp. ch. positions to scroll when an arrow is activated. The other elements affect paging. Check button: The whole page minus 1 line resp. character is scrolled. 2 numbers forming a fraction: If the check button is not checked: The part of the screen to be scrolled out of sight when a page element is activated. Go to line: type the new line linenumber in the editable field and press ENTER. @endnode @node "Retabulation block" This block holds the parameters for the 'Fix tabs' operation. Brain dead Unix editors often make variable tab settings impossible by mixing real spaces with physical TABs in a single line. Mostly the physical TAB is a standard 8. Very annoying. For this reason you can set 3 different tab sizes in the KIT. 'Apparent tab size': Set this to what you might think is intended when you have set 'Tab size' to what looks like the correct value. Just experiment a little. Now you must set 'physical tab size' to 'Tab size' and 'Tab size' to what you want it to be. Fix tabs will: replace TABs by 'physical tab size' spaces, then: replace every 'Apparent tab size' spaces by a single TAB, then: redisplay using 'Tab size'. Set the field 'Visible tab' to non space for good understanding. '/ÿ' is a very convenient value. The button 'leading only' restricts the operation to leading white space. It is recommended to not clear this button, because the Fix tab function is not perfect yet for intermediate tabs. @endnode @node "Define braces block" Word: Braces that are made of words. 10 pairs can be defined by the user. A single '*' at the end of a word serves as a wildcard. It is mostly used for preprocessor nests : '#if* ... #endif'. A selection is created by: ALT + left click, double left click, a single right click. All braces are recognised by a selection operation. If a left brace is selected, everything between and including braces will be selected. If a right brace is selected, only in between braces will be selected. A selection can also be made by holding left button and dragging and by SHIFT + left click. These types of selection do not invoke brace matching. @endnode @node "Options for the Shell" Verbosity: The more buttons checked, the more info is produced in the journal. Try it out. Project help: Auto dependencies: Cache headers: Inherit options: for nested projects, inherit options from parent project. Extra wildcard for make: If checked, the following wildcard will be applied when selecting files for inclusion in a make operation. @endnode @node "Options for the Compiler" These are some of the most likely needed options. For a complete overview see Compiler/Assembler. These and more options can be specified in the project file as .C[options] 5 -d Here you can predefine 5 macros Only those of which the button is checked are passed to the compiler. 5 -i Here you can specify 5 include directories Only those of which the button is checked are used by the compiler. @endnode @node "Options for the Linker" These are some of the most likely needed options. For a complete overview see Linker. These and more options can be specified in the project file as .L[options] @endnode @node "Standard library" Replacement standard library functions for Atari ST with Alcyon C v4.14 Version 1.20.0, by Dale Schumacher, last modified 10/19/1988. Translated to ANSI 89 for use with AHCC or Pure C: Version 2.0, by Henk Robbers. Important notice Read this!! header files process control memory allocator (AHCM) memory management (extra) file handling input/output functions coercion string manipulation character functions date/time functions searching and sorting error handling functions variable argument lists miscellaneous functions extra functions revision record @endnode @node "Important notice" AHCCLIB uses exclusively types short and long. NOT int. This is because AHCC can be configured to use a 2-byte int size or a 4-byte int size. AHCCLIB is not meant to be portable. The use of integer types is hence made unambiguously suitable for the TOS platform. As a compensation AHCC will treat short & int as synonymous when set to 2_byte int, and long & int as synonymous when set to 4-byte int. AHCCLIB is runtime compatible to Pure C libraries. AHCCLIB can be used with Pure C header files. If AHCCLIB replaces Pure C libraries, make sure that you also replace the startup code. Last: Due to dependency on properties mentioned in 'Introduction to the notion area', AHHCLIB itself should always be compiled with AHCC. @endnode @node "Introduction to the notion" @alias area Throughout this manual the notion "area" is often used. In AHCC & AHCL a area is the unit of linkage. It can be either TEXT, DATA or BSS. In other contexts the notion just means: 'a certain amount of consecutive memory locations'. This description of course suites very well the special meaning in this paragraphe. Separate areas are produced for each function. DATA & BSS are put into separate areas per file according to storage class. Storage classes are: global data static data global bss static bss string literals double precision real literals The granularity of areas can be increased by interspersing data declarations with function body definitions. At the closure of a function body definition all current data areas are also closed, and new are started. By having a function's data close to its usage, a lot of unnecessary linking in of data not referenced by the function is avoided. Practical implication of this approach is that you can have most of a library's functions in a single file, which dramatically reduces compilation time. The many header files need to be parsed only once for a multitude of library functions. In particular: The whole AHCCLIB compiles on a TT + fastram in just over 1 minute. The AHCCLIB consists of 1 C file per standard header. The nature of areas implies that they should not, and can not be split further. This allows the compiler and the linker to remove fixup data for relative references within an area. @endnode @node "header files" 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 defined in this file. errno.h This file defines the error code constants, the errno variable and related error handling functions. limits.h Various maximum and minimum values are defined by this file. Among these are PATHSIZE and MAXINT. tos.h System calls to 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() or longjmp(). 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. stdlib.h This files defines some standard functions, including AHCCLIBS's memory allocator AHCM 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. ext.h Miscellaneous function ported from Pure C stdbool.h AHCC implements natively ANSI 99 _Bool type, hence this header file which defines bool, true and false @endnode @node "process control" You should include in your program if you use functions in this section. _StkSize, etext, edata, ebss, __text, __data, __bss _initargs main, exit, abort shell, system @endnode @node "memory management" You should include in your program if you use functions in this section. alloca sbrk brk @endnode @node "file handling" You should include in your program if you use functions in this section. Functions on Gemdos handles: mkdir rmdir creat open close dup dup2 remove rename lseek tell Path manipulation: fullpath findfile pfindfile wildcard _splitpath _makepath tmpnam tempnam FILE *stream functions: fopen freopen fdopen fopenp fclose fseek rewind ftell fgetpos fsetpos fileno feof ferror clearerr setbuf setvbuf prelude & postlude handled by startup code: Init_iob Exit_iob @endnode @node "input/output functions" You should include in your program if you use functions in this section. Often implemented as macros, not really in AHCCLIB: getc ungetc putc getchar ungetchar putchar Functions on Gemdos handles: read write getw putw getl putl getln gets puts cputs _printf printf sprintf cprintf vfprintf vprintf vsprintf _scanf scanf sscanf vscanf vsscanf vfscanf _tttty FILE *stream functions: fread fwrite fgets fgetc fungetc fputs fputc fflush fprintf fscanf @endnode @node coercion You should include in your program if you use functions in this section. ltoa ultoa itoa ftoa * atol atoi atof * strtod strtol strtoul see also _printf _scanf et al @endnode @node "string manipulation" You should include in your program if you use functions in this section. memmove memcpy memset memcmp memicmp memccpy memchr bzero strlen strcpy strncpy strpcpy strdup strset strnset substr subnstr strcat strncat strupr strlwr strrev strcmp strncmp stricmp strnicmp strstr stristr strchr strrchr strpos strrpos strspn strcspn strpbrk strrpbrk strtok strtrim stradj strrpl strirpl @endnode @node "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) toupper tolower toascii isalnum,isalpha,isascii,iscntrl,isdigit,isgraph, islower,isprint,ispunct,isspace,isupper,isxdigit isblank @endnode @node "date/time functions" To use the functions in this section, you must include in your source file. time ctime localtime gmtime timezone asctime mktime stime utime clock strftime difftime start_timer time_since @endnode @node "searching and sorting" To use the functions in this section, you must include in your source file. StdCompare qsort hsort bsearch lsearch lfind @endnode @node "error handling functions" To use the functions in this section, you must include in your source file. errno perror perrorf strerror @endnode @node "miscellaneous functions" To use the functions in this section, you must include in your source file. atexit getopt rand srand swab abs labs max min swap assert ctlcnv getenv putenv @endnode @node "extra functions" To use the functions in this section, you must include in your source file. getcurdir chdir chmod getcwd getch getche putch kbhit getpid stat access fsize isatty sleep usleep @endnode @node FILE @alias stream typedef struct { short _cnt; /* # of bytes in buffer */ unsigned char *_ptr; /* current buffer pointer */ unsigned char *_base; /* base of file buffer */ unsigned int _flag; /* file status flags */ short _file; /* file handle */ size_t _bsiz; /* buffer size */ unsigned char _ch; /* tiny buffer, for "unbuffered" i/o */ } FILE; @endnode @node getcurdir short getcurdir(short drive, char *path) Call Dgetpath, return -1 when the path doesn't exist; @endnode @node _StkSize @alias etext edata ebss __text __data __bss long _StkSize = 4096; This variable defines the amount of run-time stack space to be reserved. The default value is 4K, which is enough for small applications. Since dynamic memory is NOT allocated from the stack, this value need only be large enough to handle local variables and deep recursion. The stack area is created by the linker at the end of the BSS. char *etext; char *edata; char *ebss; These variables point to the first byte beyond the end of the text, data and BSS segments respectively. They are provided for compatibility. __text __data __bss These are the linkable names of the first byte of the respective segments. @endnode @node _initargs 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. @endnode @node Init_iob @alias Exit_iob void (*init_streams)(void) = Init_iob; This function defines the standard streams, check to see which of them are devices. The startup module calls this function prior to starting the C program. The following standard streams are initialized by Init_iob(): 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) void (*end_streams)(void) = Exit_iob; Flushes and closes all open streams. Called by exit() @endnode @node atexit typedef void VpV(void); short atexit(VpV *func) Define routines that must be executed when a program ends, either by calling exit(n) or by returning from main. A maximum of 32 atexit functions can be stacked. -1 is returned when the stack is full. @endnode @node main @alias exit abort short main(short 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 the startup code 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() to exit(). Therefore, you should always return from main(), or call exit() directly. void exit(short status) Returns value to the operating system. The exit function is held in the startup code. void abort(void) Prints the message "Abnormal program termination" to stderr and calls exit() with a status code of 3. @endnode @node getpid(void) int getpid(void) Return an integer value unique for this process. @endnode @node getenv char *getenv(const 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! @endnode @node putenv short putenv(const 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. @endnode @node shell void shell() Not yet implemented in AHCCLIB @alias system 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". @endnode @node fork @alias forklp forkle forklpe forkv forkvp forkve forkvpe wait 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. @endnode @node gemdos @alias bios xbios bdos long gemdos(int func, ...) Call operating system trap #1 (GEMDOS) function number with the arguments given. Return value returned by the trap call. long bios(int func, ...) Call operating system trap #13 (BIOS) function number with the arguments given. Return value returned by the trap call. long xbios(int func, ...) 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. @endnode @node setjmp 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. catch & throw are not ported to AHCCLIB 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. @endnode @node "memory allocator" @alias AHCM Welcome to AHCM A Home Cooked Memory allocation system. Why? ù Thread safe by using multiple heaps. ù Internal structures available to the user so you can perform sanity checks and detect leaking. ù A key field which can be used for identifying individual allocations ù A type field which can be used for grouping allocations ù Both fields can be used for controlled freeing ù Reduction of OS heap fragmentation by putting the larger units in blocks a multiple of a given roundup width. 1: Introduction to AHCM 2: Function reference 3: AHCM examples AHCM will make your life easy. The base functions are used in XaAES for almost 3 years without problems. Greetings, Henk Robbers. Amsterdam feb 2005 @endnode @node "Introduction to AHCM" The current memory allocation system of standard C is just too simple and primitive. The lack of block structuring and hence the danger of memory leakage are a constant source of misbehaviour. Another point is that the standard system is totalitarian. There is only 1 heap. AHCM can have any number of heaps, each having different access permissions and different chunk and round sizes. AHCM uses the same 2 level approach as other Atari malloc systems which reduces considerably the number of Gemdos calls. A single application level memory allocation is called a 'unit'. A Gemdos level allocation is called a 'block'. Both entities use next and prior pointers. Additionally each unit is provided with 2 identification fields. These fields make it possible to abandon the pointer driven freeing completely. In stead freeing can be done by catagorizing units. There is no longer the need of the often tedious remembering of the addresses of ALL allocated units and calling free() for each unit in turn. Handling of large units (larger then fits in the heaps chunksize): A Gemdos block of size equal to the nearest higher multiple of the heaps round size is allocated. The large unit is placed at end of the block. The excess at the beginning of the block is put in a free list. No space is wasted. When the large unit is freed, the block is shrunken to the heaps chunk size. The resulting smaller unit is put in the free list. Of course, if nothing has been allocated at the beginning, the whole block is returned to the OS. When a large unit is shrunken by realloc, any part that becomes free and is larger than the chunksize is also given back to the OS in multiples of chunksize. There is now a function that can free a whole bunch of units in a single streak by using one or both of those 2 identification fields. Because TOS and Mint do not provide virtual memory as yet, use of the stack for allocating dynamic memory may cause stack capacity problems. To compensate for this, AHCM provides 3 functions (XA_up, XA_new & XA_down) for use in a stack like manner. Or in a block structured manner if you wish. The system doesn't work automatically; you have to call these functions explicitly. But at least it provides a way of block structured dynamic memory that is easy to do it correctly. The principle is that keeping track of memory is block structured, yet the memory itself is allocated from the heap. For efficiency and organizational reasons, the block structured functions use their own default base structure. If your version of C supports a 'new' function natively, you don't need this option. :-) @endnode @node "Function reference" ù AHCM's structures and definitions: ø XA_memory The base structure describing the heap; required by ALL calls to AHCM ø XA_block The OS level block administration ø XA_unit The user level unit administration ø XA_key Type of the 'key' and 'type' fields ù AHCM's functions: ø XA_set_base Fill out a base structure. ø XA_alloc Allocate (replaces malloc) ø XA_calloc Allocate and zeroize (replaces calloc) ø XA_realloc Reallocate with different size (replaces realloc) ø XA_free Free (replaces free) ø XA_free_all Completely or selectively freeing in a heap. ø XA_up Increment the stack value in the base ø XA_new Allocate using stack value in the base for 'type' ø XA_down Free everything with a type higher than or equal to the stack value in the base, then decrement the stack value in the base ø XA_leaked Go through all allocated units in a heap ø XA_sanity Do some sanity checks on a heap ø XA_report User hook function type for processing results of XA_leaked and XA_sanity @endnode @node XA_set_base Description: Fill out a base structure. Declaration: void XA_set_base (XA_memory *base, size_t chunk, short round, short flags); Parameters: base: Address of the base of the heap to be filled out. Zero if only 1 heap is to be used by the program, in which case the standard base is filled out. chunk: The Gemdos chunk size to be used by this heap. The value can be changed anytime. round: A number representing the power of 2 to which chunk will be rounded up. flags: If zero AHCM will use Malloc(chunk) for allocating memory chunks. Otherwise Mxalloc(chunk, flags) will be used. The flags tell AHCM what kind of memory must be allocated for this heap. Examples of these flags: MX_STRAM 0 MX_TTRAM 1 MX_PREFSTRAM 2 MX_PREFTTRAM 3 MX_HEADER (1 << 3) MX_PRIVATE ((1 << 3) | (1 << 4)) MX_GLOBAL ((1 << 3) | (2 << 4)) MX_SUPERVISOR ((1 << 3) | (3 << 4)) MX_READABLE ((1 << 3) | (4 << 4)) @endnode @node XA_alloc Description: Allocate a amount of memory. Declaration: void * XA_alloc (XA_memory *base, size_t amount, XA_key key, XA_key type); Parameters: base: Address of base of the heap to be used. Zero if only 1 heap is to be used by the program, in which case the standard base is used. amount: The amount of memory in bytes that has to be allocated. key: A number defined by the user. type: Another number defined bu the user. The key should identify each allocation uniquely. The type can be used to group a number of allocations together. It is reported back by the XA_leaked and XA_sanity functions. It can also be used by the XA_free_all function for selective freeing. Return: The address of the user part of the allocated memory. Zero if the memory couldn't be allocated or if some error occurred or was detected. @endnode @node XA_calloc Description: Allocate a zeroized amount of memory. Declaration: void * XA_calloc (XA_memory *base, size_t items, size_t chunk, XA_key key, XA_key type); Parameters: base: Address of base of the heap to be used. Zero if only 1 heap is to be used by the program, in which case the standard base is used. chunk: A amount of memory in bytes. items: The number of 'chunk's that has to be allocated. Note that a single unit is allocated of size items*chunk. key: A number defined by the user. type: Another number defined bu the user. The user part of the allocated memory is zeroized. The key should identify each allocation uniquely. The type can be used to group a number of allocations together. It is reported back by the XA_leaked and XA_sanity functions. It can also be used by the XA_free_all function for selective freeing. Return: The address of the user part of the allocated memory. Zero if the memory couldn't be allocated or if some error occurred or was detected. @endnode @node XA_realloc Description: Reallocate a previously allocated amount of memory with a different size. Declaration: void * XA_realloc (XA_memory *base, void *old, size_t new_amount, XA_key key, XA_key type); Parameters: base: Address of base of the heap to be used. Zero if only 1 heap is to be used by the program, in which case the standard base is used. old: Adress of allocation whose size has to be changed. If old is zero, XA_realloc behaves exactly like XA_alloc. If the address is not of a existing unit the behaviour is undefined. new_amount: The new amount of memory in bytes that has to be allocated. key: A number defined by the user. type: Another number defined bu the user. The key should identify each allocation uniquely. The type can be used to group a number of allocations together. It is reported back by the XA_leaked and XA_sanity functions. It can also be used by the XA_free_all function for selective freeing. The contents of the new allocation will be the same as the old up and including the lesser of the new and the old size. Any excess storage in the larger of the 2 will have undeterminate contents. key and type replace existing key and type. Return: The address of the user part of the allocated memory. The address may or may not be different from the old address. Zero if the memory couldn't be allocated or if some error occurred or was detected. If the old allocation wasnt previously allocated, no action is taken and 0L is returned. @endnode @node XA_up Description: Increment the current stack level in the base. Declaration: void XA_up (XA_memory *base); Parameters: base: Address of base of the heap to be used. Zero if only 1 heap is to be used by the program, in which case the standard base is used. In any case the base must be different from any base used by XA_(c,re)alloc. If you always provide a zero base, this will automatically be the case. @endnode @node XA_new Description: Allocate using stack value set by XA_up Declaration: void *XA_new(XA_memory *base, size_t amount, XA_key key); Parameters: base: Address of base of the heap to be used. Zero if only 1 heap is to be used by the program, in which case the standard base is used. In any case the base must be different from any base used by XA_alloc and XA_calloc. If you always provide a zero base, this will automatically be the case. amount: The amount of memory in bytes that has to be allocated. key: A number defined by the user for unique identification of allocation. Note: The stack value in the base is used as type. @endnode @node XA_down Description: Free everything with a type higher than or equal to the current stack value in the base, then decrement the stack value in the base Declaration: void XA_down (XA_memory *base); Parameters: base: Address of base of the heap to be used. Zero if only 1 heap is to be used by the program, in which case the standard base is used. In any case the base must be different from any base used by XA_(c,re)alloc. If you always provide a zero base, this will automatically be the case. @endnode @node XA_free Description: Free a unit. Declaration: void XA_free (XA_memory *base, void *area); Parameters: base: Address of base of the heap to be used. Zero if only 1 heap is to be used by the program, in which case the standard base is used. area: Address of an area as returned by any of the allocation functions. @endnode @node XA_free_all Description: All or selective freeing in a heap. Declaration: void XA_free_all (XA_memory *base, XA_key key, XA_key type); Parameters: base: Address of base of the heap to be used. Zero if only 1 heap is to be used by the program, in which case the standard base is used. key: All units with specified key must be freed. type: All units with specified type must be freed. If both key and type are passed -1, the whole heap is freed in the fasted way possible. If -1 is specified for key or type, no check is made for that field. Which means that all units of that key cq type are considered. The relation between key and type is 'and' Example: XA_free_all(0, -1, handle) All units having handle as type are freed. @endnode @node XA_report Description: Type of a report function that is called by XA_leaked and XA_sanity when something reportable occurs. A fuction of the type must be written by the user. You may find a example of such a function in AHCM examples. Declaration: typedef void XA_report (XA_memory *base, XA_block *blk, XA_unit *unit, char *txt); Parameters: base: Address of base of the heap to be used. Zero if only 1 heap is to be used by the program, in which case the standard base is used. blk: Block that is subject of the report. (if applicable) unit: Unit that is subject of the report. (if applicable) txt: A character string provided by XA_leaked and XA_sanity so you know where the call to the report function comes from. @endnode @node XA_leaked Description: Report every unit that is still allocated at the point this function is called. Normally one should call this function right before exit(). Declaration: bool XA_leaked (XA_memory *base, XA_key key, XA_key type, XA_report *report); Parameters: base: Address of base of the heap to be used. Zero if only 1 heap is to be used by the program, in which case the standard base is used. report: Address of the report function to be called for each allocated unit. key and type: Usage is same as for XA_free_all. With the exception that units are not freed, but reported in stead. ;-) @endnode @node XA_sanity Description: Do a sanity check on a heap. A function of this type can be written by the user. The XA_sanity in AHCM does some very basic checks and can be considered a example. For each block in the heap: First all sizes of units in the block are added up to see if units fill the block completely. This MUST be the case. Then the used list links are followed up and down (next, prior) If this process reaches the unit at which it started, the links are sane. Same is done for the free list. Declaration: void XA_sanity (XA_memory *base, XA_report *report); Parameters: base: Address of base of the heap to be used. Zero if only 1 heap is to be used by the program, in which case the standard base is used. report: Address of the report function to be called for each unit causing a error. @endnode @node structures @alias definitions types XA_memory XA_block XA_unit XA_key size_t ù size_t should be defined as long (32 bits) in its usual standard way. @index XA_memory ù The base structure describing the heap required by all calls to AHCM: @index XA_memory typedef struct xa_memory { XA_block *first, *last, *cur; long chunk; short round, mode, stack; } XA_memory; ù any list of units, generalizing used and free lists typedef struct xa_list { struct xa_unit *first, *cur, *last; } XA_list; @index XA_block ù Administration of OS level blocks (also called 'chunks') typedef struct xa_block { long size; struct xa_block *next, *prior; XA_list used, free; short mode; XA_unit area[0]; } XA_block; @index XA_key ù The type of the key and type field in the AHCM units has been parameterized. This makes changing the type an easy and safe operation. Currently defined as: typedef short XA_key; @index XA_unit ù Administration of user level blocks (also called 'units') typedef struct xa_unit { long size; struct xa_unit *next,*prior; XA_key key, type; char area[0]; } XA_unit; @endnode @node "AHCM examples" The package contains as a bridge to the functions malloc, calloc, realloc, free & _FreeAll as follows: void *malloc(size_t size) { return XA_alloc(0, size, 0, 0); } void *calloc(size_t items, size_t chunk) { return XA_calloc(0, items, chunk, 0, 0); } void *realloc(void *old, size_t new_size) { return XA_realloc(0, old, new_size, 0, 0); } void free(void *addr) { XA_free(0, addr); } void _FreeAll(void) { XA_free_all(0, -1, -1); } And also as a quick way of using leak detection and identification of individual allocations: void *xmalloc(size_t size, XA_key key) { return XA_alloc(nil, size, key, 0); } void *xcalloc(size_t items, size_t chunk, XA_key key) { return XA_calloc(nil, items, chunk, key, 0); } void *xrealloc(void *old, size_t size, XA_key key) { return XA_realloc(nil, old, size, key, 0); } ======================================================================== Very often the allocated units all are needed at the same time all this time. (Lines or records in file as long as the file is open) This means that no individual freeing is needed. The absence of the need of individual freeing can make the allocation many times more efficient. AHCM makes such an approach possible and not too difficult. The multiple heaps originated from the need for use in asynchronous threads. They appeared to be very useful in single threaded code as well. The advantage of the approach below is that it remains to be dynamic as a whole. The functions in the example are real. I use them in the Pure linker replacement for all symbol tables. #include "ahcm.h" typedef struct membase { XA_memory base; char *memory; size_t memorynow; size_t chunk; char *name; /* For debugging */ } MEMBASE; /* NB! blockprefix and unitprefix are from "ahcm.h" and are important. */ void init_membase(MEMBASE *mb, long chunk, char *name) { mb->chunk = chunk - blockprefix - 2*unitprefix; mb->memorynow = 2*mb->chunk; mb->memory = 0; mb->name = name; XA_set_base(&mb->base, chunk, 0, 0); } void * alloc(MEMBASE *mb, size_t new, char *remark) { char *ret; new = (new + 3) & ~3; /* 4 byte align */ if (mb->memorynow + new > mb->chunk) { mb->memory = XA_alloc(&mb->base, mb->chunk, -1, -1); if (mb->memory == 0) { mem_alert(remark); /* some warning function */ return 0; } mb->memorynow = 0; } ret = mb->memory; mb->memory += new; /* Simply put the units one after mb->memorynow += new; each other without any red tape */ return ret; } void free_membase(MEMBASE *mb) { XA_free_all(&mb->base, -1, -1); mb->memorynow = 2*mb->chunk; /* useful high value for initial */ mb->memory = 0; } void some_function(void) { /* Define a memory base for local use */ MEMBASE mlocal; init_membase(&mlocal, 8192, "efficient local base"); ..................... while (not_ready) { any_pointer *new = alloc(&mlocal, anysize, some_remark); /* Do anything you like with any number of 'new's until you're done */ ............................................................ } ..................... free_membase(&mlocal); /* Free the whole local base in a swoop */ } ========================================================================== Example of a report function: #if __PUREC__ XA_report punit #else void punit (XA_memory *base, XA_block *blk, XA_unit *unit, char *txt) #endif { printf("**** %s: ", txt); if (!unit) printf("nil\n"); else { XA_unit *prior = unit->prior, *next = unit->next; printf(" -%d- %ld :: %ld, p:%ld :: %ld, n:%ld :: %ld, block %ld :: %ld\n", unit->key, unit, unit->size, prior, prior?prior->size:-1, next, next?next->size:-1, blk, blk->size); } } ======================================================================== @endnode @node alloca char *cdecl alloca(size_t 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() and realloc() 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. @endnode @node sbrk void *sbrk(size_t 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 _StkSize. 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. @endnode @node brk short brk(void *address) Set the "break" to
. Return 0 for success. If
is not a valid break value, return -1 and don't move the break. @endnode @node chdir short chdir(const 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. @endnode @node mkdir short mkdir(const char *pathname) Creates a new directory called . A drive letter may be specified. Returns 0 for success, or a negative error code. @endnode @node rmdir short rmdir(const char *pathname) Removes an existing directory called . A drive letter may be specified. Returns 0 for success, or a negative error code. @endnode @node fullpath char *fullpath(char *full, const char *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. @endnode @node getcwd char *getcwd(char *buffer, short 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. @endnode @node access short access(const char *name, short 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 @endnode @node findfile char *findfile(const char *afn, const char *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. @endnode @node pfindfile char *pfindfile(const char *path, const char *afn, const char *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(). @endnode @node wildcard char *wildcard(const 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. @endnode @node _splitpath char *_splitpath ( const char *src, char *drive, char *path, char *file, char *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]. @endnode @node _makepath char *_makepath ( char *dst, const char *drive, const char *path, const char *file, const char *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 '\'. @endnode @node tmpnam 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. @endnode @node tempnam char *tempnam(const char *dir, char *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. @endnode @node stat short stat(const 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. @endnode @node fsize long fsize(const 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. @endnode @node isatty short isatty(short handle) Return non-zero if refers to a character device. Negative handles always refer to character devices. @endnode @node creat int creat(char *filename) 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. @endnode @node chmod short chmod(const char *filename, short 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. The function calls Fattrib. @endnode @node open short open(const char *filename, short iomode, ...) The ellipsis is for optional pmode constants. 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. @endnode @node close short close(short handle) Close file referenced by the file handle . Return 0 for success, or a negative error code. @endnode @node dup short dup(short handle) Return a second file handle which refers to the same file as the given . (cf: dup2) @endnode @node dup2 short dup2(short handle1, short 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. @endnode @node remove short remove(const char *filename) Delete , if it exists. Return 0 for success, or a negative error code. @endnode @node rename short rename(const char *oldname, const char *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. @endnode @node lseek size_t lseek(short h, size_t offset, short 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. @endnode @node tell size_t tell(short h) Return the current file position for the file . @endnode @node fopen FILE *fopen(const char *filename, const 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. @endnode @node freopen FILE *freopen(const char *filename, const 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. @endnode @node fdopen FILE *fdopen(short h, const 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. @endnode @node fopenp FILE *fopenp(const char *filename, const 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) @endnode @node fclose short fclose(FILE *fp) Close the stream , flushing the buffer. Returns 0 on success. @endnode @node setbuf void setbuf(FILE *fp, void *buf) If is NULL, make unbuffered; else points to a buffer of BUFSIZ characters to be used as the stream buffer for . @endnode @node setvbuf short setvbuf(FILE *fp, void *buf, short bmode, size_t 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) @endnode @node fseek short fseek(FILE *fp, long offset, short 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) @endnode @node rewind 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. @endnode @node ftell 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) @endnode @node fgetpos short 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. @endnode @node fsetpos short fsetpos(FILE *fp, const 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. @endnode @node fileno short fileno(FILE *fp) Return the file handle associated with the stream . @endnode @node feof short feof(FILE *fp) Return non-zero if is at end of file. @endnode @node ferror short ferror(FILE *fp) Return non-zero if and error has occurred on . @endnode @node clearerr void clearerr(FILE *fp) Clear the error flag on . @endnode @node read size_t read(short h, void *data, size_t 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. @endnode @node write size_t write(short h, void *data, size_t 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. @endnode @node fread size_t fread(void *data, size_t size, size_t 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. @endnode @node fwrite size_t fwrite(const void *data, size_t size, size_t 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. @endnode @node fgetc short fgetc(FILE *fp) Get a character from . Returns the character or EOF. @endnode @node fungetc short fungetc(short 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. @endnode @node fputc short fputc(short c, FILE *fp) Put the character to the stream . @endnode @node fflush short 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. @endnode @node getc #define getc( c ) fgetc( c ) for compatability @endnode @node ungetc #define ungetc( c) fungetc( c ) for compatability @endnode @node putc #define putc( c, s ) fputc( c, s ) for compatability @endnode @node getw short 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. @endnode @node putw short putw(short n, FILE *fp) Put the 2-byte value to the stream . The high-order byte is written first. @endnode @node getl long 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. @endnode @node putl long putl(long n, FILE *fp) Put the 4-byte value to the stream . The high-order byte is written first. @endnode @node getchar #define getchar() fgetc( stdin ) for compatability @endnode @node ungetchar #define ungetchar( c) fungetc(c, stdin) for compatability @endnode @node putchar #define putchar( c ) fputc( c, stdout ) for compatability @endnode @node getch short getch(void) Machine dependent console input function. This function normally gets a character from the keyboard by calling the GEMDOS "Cnecin" function. @endnode @node getche short getche(void) Same as getch() but calls Cconin() directly. @endnode @node putch short putch(short c) Machine dependent (typically quite fast) console output function. This function normally puts a character to the console by calling the GEMDOS "Cconout" function. The return value of this function is simply the character sent. /* not yet in AHCCLIB: 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. */ @endnode @node kbhit short kbhit(void) Machine dependent function to detect if input is waiting for the getch() function. Returns non-zero if the console has data ready. The function just calls GEMDOS Cconis. @endnode @node getln typedef short InFunc(void *ip); typedef short OutFunc(char c, void *op); char *getln(void *ip, InFunc *get, OutFunc *put, char *buffer, size_t 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,op). 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?). @endnode @node fgets char *fgets(char *data, short 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. @endnode @node fputs short fputs(const char *data, FILE *fp) Write the characters in to the stream . A newline WILL NOT be added. @endnode @node gets 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. @endnode @node puts short puts(const char *data) Write the characters in to stdout. A newline WILL be written after the data. The number of characters actually put is returned. @endnode @node cputs 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. @endnode @node fprintf short fprintf(FILE *fp, const char *fmt, ...) Formatted output to the stream . See the _printf() function for a description of the formatting string. @endnode @node printf short printf(const char *fmt, ...) Formatted output to the stdout stream. See the _printf() function for a description of the formatting string. @endnode @node sprintf short sprintf(char *buf, const char *fmt, ...) Formatted output to the string . See the _printf() function for a description of the formatting string. @endnode @node cprintf short cprintf(const char *fmt, ...) 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. @endnode @node vfprintf short vfprintf(FILE *fp, const char *fmt, va_list args) Formatted output to the stream with a variable argument list. See _printf() for formatting and va_start() for stdarg explaination. @endnode @node vprintf short vprintf(const char *fmt, va_list args) Formatted output to the stdout stream with a variable argument list. See _printf() for formatting and va_start() for stdarg explaination. @endnode @node vsprintf short vsprintf(char *buf, const char *fmt, va_list args) Formatted outout to the string with a variable argument list. See _printf() for formatting and va_start() for stdarg explaination. @endnode @node fscanf short fscanf(FILE *fp, const char *fmt, ...) Formatted input from the stream . See the _scanf() function for a description of the formatting string. @endnode @node scanf short scanf(const char *fmt, ...) Formatted input from the stdin stream. See the _scanf() function for a description of the formatting string. @endnode @node sscanf short sscanf(const char *buf, const char *fmt, ...) Formatted input from the string . See the _scanf() function for a description of the formatting string. @endnode @node vscanf short vscanf(const char *fmt, va_list args) Formatted input from the stdin stream with a variable argument list. See the _scanf() function for a description of the formatting string and va_start() for stdarg explaination. @endnode @node vsscanf short vsscanf(char *buf, const char *fmt, va_list args) Formatted input from the string with a variable argument list. See the _scanf() function for a description of the formatting string and va_start() for stdarg explaination. @endnode @node vfscanf short vfscanf(FILE *fp, const char *fmt, va_list args) Formatted input from the stream with a variable argument list. See the _scanf() function for a description of the formatting string and va_start() for stdarg explaination. @endnode @node _tttty short _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 is 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. @endnode @node _printf size_t _printf(void *op, OutFunc *put, const char *fmt, va_list 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. @endnode @node ltoa char *ltoa(long n, char *buf, short 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. @endnode @node ultoa char *ultoa(unsigned long n, char *buff, short radix) Convert the unsigned long value to a string in using as the number base. A pointer to is returned. @endnode @node itoa char *itoa(short n, char *buf, short 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. @endnode @node ftoa @alias ecvt fcvt short ftoa( double *x, char *resStr, short ndig, short format, short *decPnt, short *sign ); Convert the double precision real to a ascii string. @endnode @node atol long atol(const 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. @endnode @node atoi short atoi(const 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. @endnode @node atof double atof(const char *fval) Convert the string to a double precision real value. The function strtod is directly called. @endnode @node strtod double strtod(const char *s, const char **endptr) Convert a character string to a double precision real value. Any format for expressing real numbers used throuhgout the world is accepted. p.e 1 1.0 0.1 1e5 -.6 E -00010 123456.7890123 etcetera @endnode @node strtol long strtol(const char *number, const char **nptr, short 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. @endnode @node strtoul unsigned long strtoul(const char *number, const char **nptr, short base) Convert the string to an unsigned long value of base . Bases from 0 to 36 are allowed. Leadinwhitespace 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. @endnode @node _scanf short _scanf(void *ip, InFunc *get, UnFunc *unget, const 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|n} 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 n the current position in the input stream 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. @endnode @node ctlcnv 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. @endnode @node memmove void *memmove( void *dest, const void *source, size_t len ) Copies the block to the . bytes are always copied. No terminator is added to . A pointer to is returned. Overlap checking IS done. @endnode @node memcpy void * memcpy( void *dest, const void *source, size_t 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. @endnode @node memset void *memset( void *dest, short data, size_t len ) Set bytes of to . A pointer to is returned. @endnode @node memcmp short memcmp( const void *blk1, const void *blk2, size_t 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. @endnode @node memicmp short memicmp( const char *blk1, const char *blk2, size_t len ) Compare blocks as with memcmp(), but ignore the case of any alphabetic characters. @endnode @node memccpy void *memccpy( char *dst, const char *src, const char c, short 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. @endnode @node memchr void *memchr( const void *buf, short c, size_t cnt ) Search the first bytes of for . Returns a pointer to the matching character, or NULL if not found. @endnode @node bzero void *bzero(void *buf, size_t cnt) Zero characters in . Returns . @endnode @node strlen size_t strlen( const char *string ) Returns the number of characters in a string, not including the terminating '\0'. @endnode @node strcpy char *strcpy(char *dest, const char *source) Copies the string to the including the '\0'. A pointer to the start of is returned. @endnode @node strncpy char *strncpy(char *dest, const char *source, size_t 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. @endnode @node strpcpy 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. @endnode @node strdup char *strdup(const char *string) Create a copy of and return a pointer to the copy. Storage for the copy is obtained from malloc(). @endnode @node strset char *strset(char *string, char c) Fill with up the the terminating '\0' of . @endnode @node strnset char *strnset(char *string, char c, int n) Fill at most characters of with , up to the the terminating '\0' of . @endnode @node substr char *substr(char *dest, char *source, size_t start, size_t end) Copy characters from to starting with character and ending with . A pointer to , which will be '\0' terminated, is returned. @endnode @node subnstr char *subnstr(char *dest, char *source, size_t start, size_t length) Copy characters from to starting with character . A pointer to , which will be '\0' terminated, is returned. @endnode @node strcat char *strcat(char *dest, const 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. @endnode @node strncat char *strncat(char *dest, char *source, size_t 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. @endnode @node strupr char *strupr(char *string) Convert all alphabetic characters in to upper case. @endnode @node strlwr char *strlwr(char *string) Convert all alphabetic characters in to lower case. @endnode @node strrev char *strrev(char *string) Reverse the order of the characters in in place. @endnode @node strcmp short strcmp(const char *str1, const 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 @endnode @node strncmp short strncmp( const char *str1, const char *str2, size_t limit ) Compare strings as with strcmp(), but limit comparison to the characters. @endnode @node stricmp short stricmp(const char *str1, const char *str2) Compare strings as with strcmp(), but ignore the case of any alphabetic characters. @endnode @node strnicmp short strnicmp( const char *str1, const char *str2, size_t limit ) Compare strings as with strncmp(), but ignore the case of any alphabetic characters. @endnode @node strstr char *strstr ( const char *string, const char *pattern ) Return a pointer to the first occurance of in . NULL is returned if is not found. @endnode @node stristr char *stristr(char *string, char *pattern) Same as strstr(), but ignore the case of any alphabetic characters. @endnode @node strchr char *strchr(char *string, short symbol) Return a pointer to the first occurance of in . NULL is returned if is not found. '\0' is included in the search. @endnode @node strrchr char *strrchr(char *string, short symbol) Return a pointer to the last occurance of in . NULL is returned if is not found. '\0' is included in the search. @endnode @node strpos ptrdiff_t strpos(char *string, char symbol) Return the index of the first occurance of in . -1 is returned if is not found. @endnode @node strrpos ptrdiff_t strrpos(char *string, char symbol) Return the index of the last occurance of in . -1 is returned if is notound. @endnode @node strspn size_t strspn ( const char *string, const 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. @endnode @node strcspn size_t strcspn( const char *string, const 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. @endnode @node strpbrk char *strpbrk( const char *string, const char *set ) Return a pointer to the first occurance in of any character in . @endnode @node strrpbrk char *strrpbrk(const char *string, const char *set) Return a pointer to the last occurance in of any character in . @endnode @node strtok char *strtok( char *string, const 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. @endnode @node strtrim char *strtrim(char *string, char *junk) Remove leading and trailing characters found in from . Return a pointer to the modified . @endnode @node stradj char *stradj(char *string, short 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. @endnode @node strrpl short strrpl(char *string, const char *ptrn, const char *rpl, short n) Replace at most occurances of in with . If is -1, replace all. Return the number of replacments. @endnode @node strirpl short strirpl(char *string, const char *ptrn, const char *rpl, short n) Same as strrpl() except ignore the case of alphabetic characters. @endnode @node toupper short toupper(short c) Convert to upper case, if alphabetic. @endnode @node tolower short tolower(short c) Convert to lower case, if alphabetic. @endnode @node toascii short toascii(short c) Convert to 7-bit ascii, putting it into the range 0x00..0x7F. @endnode @node "is...." @alias isalnum isalpha isascii iscntrl isdigit isgraph @alias islower isprint ispunct isspace isupper isxdigit isblank short isalnum(short c) Return non-zero if is '0'..'9','A'..'Z','a'..'z'. short isalpha(short c) Return non-zero if is 'A'..'Z','a'..'z'. short isascii(short c) Return non-zero if is 0x00..0x7F. short iscntrl(short c) Return non-zero if is 0x00..0x1F,0x7F. short isdigit(short c) Return non-zero if is '0'..'9'. short isgraph(short c) Return non-zero if is 0x21..0x7E. short islower(short c) Return non-zero if is 'a'..'z'. short isprint(short c) Return non-zero if is 0x20..0x7E. short ispunct(short c) Return non-zero if is not iscntrl(), isalnum() or isspace(). short isspace(short c) Return non-zero if is 0x09..0x0D,0x20. short isupper(short c) Return non-zero if is 'A'..'Z'. short isxdigit(short c) Return non-zero if is '0'..'9','A'..'F','a'..'f'. short isblank (short c) Return non_zero if is ' ' or '\t'. @endnode @node time 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. @endnode @node ctime char *ctime(const 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. @endnode @node localtime struct tm *localtime(const 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. @endnode @node gmtime @alias timezone long timezone; struct tm *gmtime(time_t *rawtime) Convert to fill struct tm fields. The value held in a variable timezone is subtracted before converted. timezone holds the difference between localtime and Greenwich mean time in seconds. A pointer to an internal structure is returned. Refer to for the values of the various structure fields. @endnode @node asctime char *asctime(const struct tm *time) Convert