Files
FireBee_Setup/devtools/ahcccf.bin/doc/ahcc.stg
2022-10-02 10:09:40 +02:00

6863 lines
204 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

@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.
<project> ::=
[ <output_file> | <20>*<2A> ]
[ <20>.L<> <20>[<5B> <linker_options> <20>]<5D> ]
[ <20>.C<> <20>[<5B> <compiler_options> <20>]<5D> ]
[ <20>.S<> <20>[<5B> <assembler_options> <20>]<5D> ]
<09>=<3D>
{ <module> <20>(<28> <dependency_list> <20>)<29> }
<module> ::=
<09>*<2A>
| <project_file>
| <assembler_module>
| <C_module>
| <object_file>
| <library_file>
<assembler_module> ::=
<assembler_file> [ <20>[<5B> <assembler_options> <20>]<5D> ]
<C_module> ::=
<C_file> [ <20>[<5B> <compiler_options> <20>]<5D> ]
<project_file> ::=
another Project file.
<object_file> ::=
A linkable object file of the implemented format
with extension '.o'
<library_file> ::=
A library file of the implemented format
with extension '.a' | '.l' | '.lib'
<assembler_file> ::=
A ascii file with extension '.s'
<C_file> ::=
A ascii file with extension '.c'
<dependency_list> ::=
<dependency_list> | <20>,<2C> <file>
@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 !!)
<name of project file>
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 <some wildcard>
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.
'/<2F>' 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 <process.h> 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 <stdlib.h> in your program if you use functions
in this section.
alloca
sbrk
brk
@endnode
@node "file handling"
You should include <stdio.h> 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 <stdio.h> 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 <stdlib.h> 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 <string.h> 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 <ctype.h>
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 <time.h>
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 <stdlib.h>
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 <errno.h>
in your source file.
errno
perror
perrorf
strerror
@endnode
@node "miscellaneous functions"
To use the functions in this section, you must include <stdlib.h>
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 <ext.h>
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 <sys\minimum.h> 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 <status> 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 <var> in the environment. If <var> is found, a pointer
to it's value is returned. NULL is returned if <var> 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 <entry> to the environment.
<entry> can be any of the following forms:
<VARIABLE>
<VARIABLE>=
<VARIABLE>=<value>
The first form removes <VARIABLE> from the environment. getenv()
will return NULL if looking for this variable. The second form adds
<VARIABLE> 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. <VARIABLE> is installed (or replaced) with the
value <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 <command> 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 <program> with
the arguments given. A process id number is returned, which can
be compared against the return value from wait(). Note that by
convention <arg0> 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 <program>. (cf: forkl)
int forkle(char *program[, *arg0, *arg1, ..., *argN], NULL, *envp)
Pass the environment <envp> to the child process. (cf: forkl)
int forklpe(char *program[, *arg0, *arg1, ..., *argN], NULL, *envp)
Use the environment variable "PATH" to find <program> and
pass the environment <envp> to the child process. (cf: forkl)
int forkv(char *program, **argv)
Like forkl() except <argv> 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 <program>. (cf: forkv)
int forkve(char *program, **argv, *envp)
Pass the environment <envp> to the child process. (cf: forkv)
int forkvpe(char *program, **argv, *envp)
Use the environment variable "PATH" to find <program> and
pass the environment <envp> 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. <rvp> is an pointer to the place to store
the return value and exit status. The high byte of the word
pointed to be <rvp> 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 <func> with
the arguments given. Return value returned by the trap call.
long bios(int func, ...)
Call operating system trap #13 (BIOS) function number <func> with
the arguments given. Return value returned by the trap call.
long xbios(int func, ...)
Call operating system trap #14 (XBIOS) function number <func> 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 <func> with
passing the specified <parameter>. Note that <parameter> 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 <context> for longjmp(). You MUST include <setjmp.h> 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 <rv> to the <context> saved by setjmp(). (cf: setjmp)
You MUST include <setjmp.h> to use.
catch & throw are not ported to AHCCLIB
int catch(jmp_buf context, int (*func)())
Execute <func> with <context> saved for throw(). You MUST include
<setjmp.h> to use. Return the value returned by <func>. 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 <rv> to <context> saved by catch(). You MUST include
<setjmp.h> to use.
@endnode
@node "memory allocator"
@alias AHCM
Welcome to AHCM
A Home Cooked Memory allocation system.
Why?
<20> Thread safe by using multiple heaps.
<20> Internal structures available to the user so you can
perform sanity checks and detect leaking.
<20> A key field which can be used for identifying individual allocations
<20> A type field which can be used for grouping allocations
<20> Both fields can be used for controlled freeing
<20> 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"
<EFBFBD> AHCM's structures and definitions:
<09> XA_memory The base structure describing the heap;
required by ALL calls to AHCM
<09> XA_block The OS level block administration
<09> XA_unit The user level unit administration
<09> XA_key Type of the 'key' and 'type' fields
<EFBFBD> AHCM's functions:
<09> XA_set_base Fill out a base structure.
<09> XA_alloc Allocate (replaces malloc)
<09> XA_calloc Allocate and zeroize (replaces calloc)
<09> XA_realloc Reallocate with different size (replaces realloc)
<09> XA_free Free (replaces free)
<09> XA_free_all Completely or selectively freeing in a heap.
<09> XA_up Increment the stack value in the base
<09> XA_new Allocate using stack value in the base for 'type'
<09> 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
<09> XA_leaked Go through all allocated units in a heap
<09> XA_sanity Do some sanity checks on a heap
<09> 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
<EFBFBD> size_t should be defined as long (32 bits) in its usual standard way.
@index XA_memory
<EFBFBD> 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;
<EFBFBD> any list of units, generalizing used and free lists
typedef struct xa_list
{
struct xa_unit *first, *cur, *last;
} XA_list;
@index XA_block
<EFBFBD> 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
<EFBFBD> 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
<EFBFBD> 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 <size> 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 <amount>. 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 <amount> 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 <amount> specified. If you want to ensure that sbrk()
will return word-aligned memory segments, you must make sure that
<amount> is always even, since the heap is initially aligned properly.
@endnode
@node brk
short brk(void *address)
Set the "break" to <address>. Return 0 for success. If <address>
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 <pathname>. If a
drive letter is specified in <pathname>, 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 <pathname>. 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 <pathname>. 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)
<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 <full> is returned. If NULL is specified for <full>,
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. <pathbuf> is a
pointer to a buffer of <size> bytes that will be used to store
the current working directory. If <buffer> is NULL, a buffer
of <size> 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 <size>.
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 <name> can be accessed
in the given <amode>. Possible <amode> 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 <afn> if found. If <afn> has no extension,
extensions from <ext> are tried until a match is found, or the list
ends. <ext> 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 <afn> already has an extension, <ext> 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 <path>. If <path> is NULL, the "PATH" environment variable is
used instead. If <afn> specifies a drive or directory, <path> 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 <pathname> is not
NULL, the first file which matches <pathname> will be returned.
The <pathname> 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 <src> filename into component parts. Returns <src>.
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 <src> string, the component will be empty, (ie.: "").
The <drive> component will be a drive letter followed by a colon,
(ie.: "a:"). The <path> 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 <file> component is the base filename
without any extension, ie.: "filename". The <ext> 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 <dst> filename from component parts. Returns <dst>.
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
<path> 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 <s> is NULL, space will be obtained from
malloc() to store the filename and thus must be free()'d by the
caller. If <s> 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.
<dir> specifies the directory part of the filename. If <dir> is
NULL, the TMPDIR environment variable will be used. If TMPDIR is
not found, the current directory is used. <pfx> 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 <name> and load <statbuf> with information
about that file, if it is found. Return 0 if found, or
ERROR (-1) if no file/directory matched <name>. Volume
labels are not included in the search. The file <ext.h>
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 <name> 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 <handle> 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 <filename>. 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 <filename> to <pmode>. Values for
<pmode> 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 <filename> with the given <iomode>. A file handle
is returned if the open succeeds. A negative error code is returned
for errors. Valid <iomode> 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 <iomode>:
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 <pmode>)
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 <stdio.h> file
contains iomode constants. The <stat.h> file contains pmode
constants.
@endnode
@node close
short close(short handle)
Close file referenced by the file handle <h>. 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 <handle>. (cf: dup2)
@endnode
@node dup2
short dup2(short handle1, short handle2)
Force <handle2> to refer to the same file as <handle1>. 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 <filename>, 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 <oldname> to <newname>. 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 <h> to specified location. <origin>
specifies the starting point for the <offset> distance. Valid
<origin> values are:
SEEK_SET from beginning of file (0)
SEEK_CUR from current location (1)
SEEK_END from end of file (2)
The <offset> 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 <h>.
@endnode
@node fopen
FILE *fopen(const char *filename, const char *mode)
Open <filename> as a stream file. This is the normal open way
to open a file. The <mode> is a string specifying the mode(s)
that are relevent to the file open. Valid <mode> 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 <nl> is translated to <cr><lf> 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 <cr> and <lf> both become <nl> 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 <fp> and opens the new file as with
fopen(), except that a new FILE structure is not created. The
existing FILE structure pointed to by <fp> is re-initialized with
the new file information. This is typically used to redirect i/o
to standard streams stdin, stdout, stderr, stdprn, stdaux. <fp>
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 <h>. The <mode>
values are the same as for fopen(), but MUST be compatible with
the mode in which <h> 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 <filename> somewhere on the PATH and open it with <mode>.
Refer to the fopen() function for valid <mode> 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 <fp>, flushing the buffer. Returns 0 on success.
@endnode
@node setbuf
void setbuf(FILE *fp, void *buf)
If <buf> is NULL, make <fp> unbuffered; else <buf> points to a buffer
of BUFSIZ characters to be used as the stream buffer for <fp>.
@endnode
@node setvbuf
short setvbuf(FILE *fp, void *buf, short bmode, size_t size)
If <buf> is NULL or <bmode> is _IONBF, make <fp> unbuffered;
otherwise <buf> points to a buffer of <size> characters to be
used as the stream buffer for <fp>. The <bmode> 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
<nl> 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 <fp>. 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
<nl> 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 <fp> and store it at the location
pointed to be <pos>. 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 <fp> to the valued stored at the
location pointed to be <pos>. Note that this function is only
required to work properly for a <pos> 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 <fp>.
@endnode
@node feof
short feof(FILE *fp)
Return non-zero if <fp> is at end of file.
@endnode
@node ferror
short ferror(FILE *fp)
Return non-zero if and error has occurred on <fp>.
@endnode
@node clearerr
void clearerr(FILE *fp)
Clear the error flag on <fp>.
@endnode
@node read
size_t read(short h, void *data, size_t length)
Read <length> bytes from the file reference by file handle <h>.
Data is stored in the buffer pointed to by <data>. 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 <length> bytes to the file reference by file handle <h>.
Data is written from the buffer pointed to by <data>. 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 <count> items of <size> characters each from stream <fp>.
Data is stored in the buffer pointed to by <data>. 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 <count> items of <size> characters each to stream <fp>.
Data is read from the buffer pointed to by <data>. 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 <fp>. Returns the character or EOF.
@endnode
@node fungetc
short fungetc(short c, FILE *fp)
Push the character <c> back to be gotten by the next fgetc()
call on <fp>. 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 <c> to the stream <fp>.
@endnode
@node fflush
short fflush(FILE *fp)
Flush the file i/o buffer of the stream <fp>. 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 <fp>. 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 <n> to the stream <fp>. The high-order byte
is written first.
@endnode
@node getl
long getl(FILE *fp)
Get a 4-byte value from the stream <fp>. 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 <n> to the stream <fp>. 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
<buffer> 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 <fp> and puts it in the <data> buffer. At most,
<limit>-1 characters will be read. Input will also be terminated
when a newline is read. <data> will be '\0' terminated and the
newline, if read, will be included. A pointer to the start of
<data> is returned, or NULL for EOF.
@endnode
@node fputs
short fputs(const char *data, FILE *fp)
Write the characters in <data> to the stream <fp>. A newline
WILL NOT be added.
@endnode
@node gets
char *gets(char *data)
Get data from stdin and puts it in the <data> 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 <data> is returned, or NULL for EOF.
@endnode
@node puts
short puts(const char *data)
Write the characters in <data> 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 <data> 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 <fp>. See the _printf() function
for a description of the <fmt> 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 <fmt> formatting string.
@endnode
@node sprintf
short sprintf(char *buf, const char *fmt, ...)
Formatted output to the string <buf>. See the _printf() function
for a description of the <fmt> 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 <fmt> formatting string.
@endnode
@node vfprintf
short vfprintf(FILE *fp, const char *fmt, va_list args)
Formatted output to the stream <fp> 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 <buf> 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 <fp>. See the _scanf() function
for a description of the <fmt> 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 <fmt> formatting string.
@endnode
@node sscanf
short sscanf(const char *buf, const char *fmt, ...)
Formatted input from the string <s>. See the _scanf() function
for a description of the <fmt> 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
<fmt> 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 <s> with a variable argument list.
See the _scanf() function for a description of the
<fmt> 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 <fp> with a variable argument list.
See the _scanf() function for a description of the
<fmt> 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 <fp>, 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.
<fmt> points to a format control string. <args> pointers to a
list of arguments. The format string is used to create and output
stream with the arguments. The <put> function is used to output
each character. The <op> parameter is given to the <put> function
to specify the output stream. Calls to <put> are of the form:
"(*put)(c, op);" where <c> 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][<width>|*][.[<precision>|*]][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 <width> field is a numeric value specifying a minimum
field width. The <precision> 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 <n> to a string in <buf> using <radix>
as the number base. If <n> is negative, '-' will be the first
character in <buf>. A pointer to <buf> is returned.
@endnode
@node ultoa
char *ultoa(unsigned long n, char *buff, short radix)
Convert the unsigned long value <n> to a string in <buf> using
<radix> as the number base. A pointer to <buf> is returned.
@endnode
@node itoa
char *itoa(short n, char *buf, short radix)
Convert the integer value <n> to a string in <buf> using <radix>
as the number base. If <n> is negative, '-' will be the first
character in <buf>. A pointer to <buf> 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 <x>
to a ascii string.
@endnode
@node atol
long atol(const char *number)
Convert the string <number> 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 <number> 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 <number> 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 <number> to a long value of base <base>. Bases
from 0 to 36 are allowed. Leading whitespace is ignored, and a
leading +/- is optional. If the <base> 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 <nptr> is non-NULL, it will be set to point
to the character which terminated the translation in <number>.
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 <number> to an unsigned long value of base
<base>. Bases from 0 to 36 are allowed. Leadinwhitespace is
ignored. If the <base> 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
<nptr> is non-NULL, it will be set to point to the character which
terminated the translation in <number>. 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.
<fmt> points to a format control string. <args> 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 <get> function. As each
character is needed <get> is called in the form "c = (*get)(ip);"
where <c> is the character read (negative for errors) and <ip> is
the auxiliary pointer specified by the <ip> parameter. If a
character needs to be un-gotten, a call to <unget> of the form
"(*unget)(c, ip);" is made. The format string is composed of
characters and format specifications. Any characters in <fmt>,
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 <get> 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:
%[*][<width>][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 <width> field specifies that maximum number of
characters to be process to fill the given format type. Less
than <width> characters will be processed if the field ends
before <width> 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 <width> is specified with the 'c' format, exactly <width>
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 <first>-<last>
form (eg: "%[0-9]"). To use the first-last form, the
character <first> must be lexically less than or equal to
the character <last>. 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 \<char> notation in <string> 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
\<nl> "folded" line (both characters removed)
A pointer to the modified <string> is returned.
@endnode
@node memmove
void *memmove( void *dest, const void *source, size_t len )
Copies the <source> block to the <dest>. <len> bytes are
always copied. No terminator is added to <dest>. A pointer
to <dest> is returned. Overlap checking IS done.
@endnode
@node memcpy
void * memcpy( void *dest, const void *source, size_t len )
Copies the <source> block to the <dest>. <len> bytes are
always copied. No terminator is added to <dest>. A pointer
to <dest> is returned. Overlap checking IS NOT done.
@endnode
@node memset
void *memset( void *dest, short data, size_t len )
Set <len> bytes of <dest> to <data>. A pointer to <dest>
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
<len> 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 <src> to <dst> until either <cnt> bytes have been
copied, or the character <c> has been copied. If <c> is found,
a pointer to the character following <c> in <dst> is returned, or
NULL is <cnt> reaches 0 before <c> is found.
@endnode
@node memchr
void *memchr( const void *buf, short c, size_t cnt )
Search the first <cnt> bytes of <buf> for <c>. Returns a pointer to
the matching character, or NULL if not found.
@endnode
@node bzero
void *bzero(void *buf, size_t cnt)
Zero <cnt> characters in <buf>. Returns <buf>.
@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 <source> string to the <dest> including the '\0'. A
pointer to the start of <dest> is returned.
@endnode
@node strncpy
char *strncpy(char *dest, const char *source, size_t limit)
Copies the <source> string to the <dest>. At most, <limit>
characters are copied. If <source> ends before <limit> characters
have been copied, the '\0' is copied, otherwise <dest> is not
terminated by the copy.
@endnode
@node strpcpy
char *strpcpy(char *dest, char *start, char *stop)
Copies characters from <start> up to <stop> into <dest>. The
character pointed to by <stop> is not copied, and MUST be in the
same string as <start>. The <dest> pointer is returned.
@endnode
@node strdup
char *strdup(const char *string)
Create a copy of <string> 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 <string> with <c> up the the terminating '\0' of <string>.
@endnode
@node strnset
char *strnset(char *string, char c, int n)
Fill at most <n> characters of <string> with <c>, up to the the
terminating '\0' of <string>.
@endnode
@node substr
char *substr(char *dest, char *source, size_t start, size_t end)
Copy characters from <source> to <dest> starting with character
<start> and ending with <end>. A pointer to <dest>, which will
be '\0' terminated, is returned.
@endnode
@node subnstr
char *subnstr(char *dest, char *source, size_t start, size_t length)
Copy <length> characters from <source> to <dest> starting with
character <start>. A pointer to <dest>, which will be '\0'
terminated, is returned.
@endnode
@node strcat
char *strcat(char *dest, const char *source)
Concatenate <source> on the end of <dest>. The terminator of
<dest> will be overwritten by the first character of <source>.
The termintor from <source> will be copied. A pointer to
the modified <dest> is returned.
@endnode
@node strncat
char *strncat(char *dest, char *source, size_t limit)
Concatenate <limit> characters from <source> onto <dest>. If
<source> contains less than <limit> characters, the length of
source is used for <limit>. The terminating '\0' is always
added. A pointer to <dest> is returned.
@endnode
@node strupr
char *strupr(char *string)
Convert all alphabetic characters in <string> to upper case.
@endnode
@node strlwr
char *strlwr(char *string)
Convert all alphabetic characters in <string> to lower case.
@endnode
@node strrev
char *strrev(char *string)
Reverse the order of the characters in <string> 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
<limit> 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 <pattern> in <string>.
NULL is returned if <pattern> 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 <symbol> in <string>.
NULL is returned if <symbol> 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 <symbol> in <string>.
NULL is returned if <symbol> 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 <symbol> in <string>.
-1 is returned if <symbol> is not found.
@endnode
@node strrpos
ptrdiff_t strrpos(char *string, char symbol)
Return the index of the last occurance of <symbol> in <string>.
-1 is returned if <symbol> is notound.
@endnode
@node strspn
size_t strspn ( const char *string, const char *set )
Return the length of the sub-string of <string> that consists
entirely of characters found in <set>. The terminating '\0'
in <set> is not considered part of the match set. If the first
character if <string> is not in <set>, 0 is returned.
@endnode
@node strcspn
size_t strcspn( const char *string, const char *set )
Return the length of the sub-string of <string> that consists
entirely of characters not found in <set>. The terminating '\0'
in <set> is not considered part of the match set. If the first
character if <string> is in <set>, 0 is returned.
@endnode
@node strpbrk
char *strpbrk( const char *string, const char *set )
Return a pointer to the first occurance in <string> of any
character in <set>.
@endnode
@node strrpbrk
char *strrpbrk(const char *string, const char *set)
Return a pointer to the last occurance in <string> of any
character in <set>.
@endnode
@node strtok
char *strtok( char *string, const char *delim )
Return a token from <string>. If <string> is not NULL, it is
the beginning of a string from which tokens are to be extracted.
Characters found in <delim> are skipped over to find the start
of a token, characters are then accumulated until a character in
<delim> is found, or the terminator of <string> is reached.
A pointer to the '\0' terminated token is then returned. Note
that this function modifies <string> (by inserting '\0's) in
the process. Subsequent calls to strtok() may specify NULL as
the <string> 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 <junk>
from <string>. Return a pointer to the modified <string>.
@endnode
@node stradj
char *stradj(char *string, short dir)
Adjust <string> by adding space if <dir> is positive, or removing
space if <dir> is negative. The magnitude of <dir> is the number
of character positions to add or remove. Characters are added or
removed at the beginning of <string>. A pointer to the modified
<string> is returned.
@endnode
@node strrpl
short strrpl(char *string, const char *ptrn, const char *rpl, short n)
Replace at most <n> occurances of <ptrn> in <string> with <rpl>.
If <n> 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 <c> to upper case, if alphabetic.
@endnode
@node tolower
short tolower(short c)
Convert <c> to lower case, if alphabetic.
@endnode
@node toascii
short toascii(short c)
Convert <c> 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 <c> is '0'..'9','A'..'Z','a'..'z'.
short isalpha(short c)
Return non-zero if <c> is 'A'..'Z','a'..'z'.
short isascii(short c)
Return non-zero if <c> is 0x00..0x7F.
short iscntrl(short c)
Return non-zero if <c> is 0x00..0x1F,0x7F.
short isdigit(short c)
Return non-zero if <c> is '0'..'9'.
short isgraph(short c)
Return non-zero if <c> is 0x21..0x7E.
short islower(short c)
Return non-zero if <c> is 'a'..'z'.
short isprint(short c)
Return non-zero if <c> is 0x20..0x7E.
short ispunct(short c)
Return non-zero if <c> is not iscntrl(), isalnum() or isspace().
short isspace(short c)
Return non-zero if <c> is 0x09..0x0D,0x20.
short isupper(short c)
Return non-zero if <c> is 'A'..'Z'.
short isxdigit(short c)
Return non-zero if <c> is '0'..'9','A'..'F','a'..'f'.
short isblank (short c)
Return non_zero if <c> 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 <rawtime> pointer is not NULL, the value is stored in
the time_t variable <rawtime> points to.
@endnode
@node ctime
char *ctime(const time_t *rawtime)
Convert <rawtime> 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 <rawtime> to fill time structure fields. A pointer to an
internal structure is returned. Refer to <time.h> for the values
of the various structure fields.
@endnode
@node gmtime
@alias timezone
long timezone;
struct tm *gmtime(time_t *rawtime)
Convert <rawtime> 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 <time.h> for the values of the various structure fields.
@endnode
@node asctime
char *asctime(const struct tm *time)
Convert <time> structure value to a string. The same format, and
the same internal buffer, as for ctime() is used for this function.
@endnode
@node mktime
time_t mktime(struct tm *time)
Convert <time> structure value to raw time format.
@endnode
@node stime
void stime(time_t *rawtime)
Set the system clock to <rawtime>.
The keyboard clock is also set;
@endnode
@node utime
short utime(char *pathname, time_t *rawtime)
Set the modification date of <pathname> to <rawtime>. Returns zero
for success, or a negative error code.
@endnode
@node clock
clock_t clock(void)
Returns the current value of the system clock. The difference
of two clock() times, divded by CLK_TCK, will give you elapsed
seconds.
@endnode
@node strftime
size_t strftime( char *s, size_t max_size, const char *format,
const struct tm *timeptr );
Write a maximum of max_size characters to string <s>
String <format> serves as formatting string like in _printf.
The following formatting options are recognized:
%a abbreviated weekday
%A full weekday
%b abbreviated name of month
%B full name of month
%c date and time
%d day im month (1-31)
%H hour (0-23)
%I hour (0-12)
%j day im year (1-366)
%m month (1-12)
%M minute (00-59)
%p AM/PM
%S second (00-59)
%w weekday (0-6)
%W week im year (0-52)
%x local date
%X local time
%y year without century (0-99)
%Y year with century
%Z name of time xone (z.B. CET)
%% the '%' character
@endnode
@node difftime
double difftime( time_t time2, time_t time1 );
Time difference:
Returns the difference between 2 time
@endnode
@node start_timer
clock_t start_timer(clock_t *t)
Start a 200Hz timer. This timer value can later be checked with
time_since() to determine elapsed time. These functions provide
a very low-overhead way of timing events.
@endnode
@node time_since
clock_t time_since(clock_t *t)
Returns the number of 200Hz ticks since start_timer() was called
for timer <t>.
@endnode
@node sleep
void sleep(unsigned short dt)
Suspend operation for <dt> seconds. This is implemented as a
start_timer()/time_since() tight loop waiting for the specified
amount of time to pass. In a multi-tasking environment, this
function should be replaced by a call which will de-activate
this task for a period of time, allowing other tasks to run.
@endnode
@node usleep
void usleep(unsigned short dt)
Suspend operation for <dt> microseconds. Works like sleep().
@endnode
@node StdCompare
typedef short StdCompare(const void * item1, const void *item2);
The type of the compare function used by
searching and sorting routines.
Pointers to two items are passed to the function, which must
return a number representing their relationship as follows:
negative item1 < item2
0 item1 == item2
positive item1 > item2
@endnode
@node qsort
void qsort (void *base, size_t num, size_t size, StdCompare *cmp)
Perform a recursive quick-sort on an array starting at <base>
containing <num> elements of <size> bytes each. The function
of type StdCompare pointed to by <cmp> is used to compare elements.
The qsort() function requires the use of a temporary data area
that is large enough to hold <size> bytes. The default space
provided is 128 bytes large. If your record size is larger than
128 bytes, YOU MUST provide an alternative storage area. The
global variable "_qbuf" points to the storage qsort() will use.
Setting "_qbuf" to NULL restores use of the internal buffer.
This routine is optimized to avoid N*N sort times for ordered data.
In fact, performance on sorted or reverse-sorted data is actually
"best case" with this algorithm, rather than "worst case" as with
most qsort() implementations.
@endnode
@node hsort
void hsort(void *base, size_t num, size_t size, StdCompare *cmp)
Perform an N*log(N) heap-sort on an array starting at <base>
containing <num> elements of <size> bytes each. The function
of type StdCompare pointed to by <cmp> is used to compare elements.
The hsort() function requires no extra storage, is not recursive,
and has an almost constant N*log(N) sort time. In the average
case, it is about half as fast as qsort() on random data. If
portability is a concern, it should be noted that qsort() is
almost always available, but hsort() is not.
@endnode
@node bsearch
void * bsearch( const void *key, const void *base,
size_t num, size_t size,
StdCompare *cmp);
Perform a binary search for <key> on the sorted data at <base>.
<num>, <size> and <cmp> are like the corresponding parameters
to qsort(). A pointer to the matching element is returned for
success, or NULL for failure. The global variable "_bsearch"
will contain the index of either the matching element, or the
index of the element that the <key> value should be inserted
after. The use of "_bsearch" is not supported by most
implementations of bsearch().
@endnode
@node lsearch
void * lsearch(void *key, void *base,
size_t *num, size_t size,
StdCompare *cmp)
Perform a linear search for <key> on the data at <base>. The
<num>, <size> and <cmp> parameters are like the corresponding
parameters to qsort(). A pointer to the first matching element
is returned for success, or NULL for failure. If <key> is not
found, it will be added to the end of the array and <num> will
be incremented. Note that, unlike bsearch() and qsort(), the
<num> parameter is a POINTER to a location which holds the
number of elements to sort.
@endnode
@node lfind
void * lfind(void *key, void *base,
size_t *num, size_t size,
StdCompare *cmp)
Like lsearch(), but do not add elements which are not found.
Note that <num> is a POINTER, even though it is not modified.
@endnode
@node errno
short errno;
This variable is set to zero when the program is loaded. It is
not zeroed by any library functions, but may be set to a non-zero
error number by many of them (particularly the standard i/o and
system service functions). The meaning of this error number may
be found in the symbolic #defines in <errno.h>
@endnode
@node perror
void perror(char *msg)
Write, to stderr, <msg> (if non-null and non-empty), followed by
": " and a system error messaged derived from the value of errno.
@endnode
@node perrorf
void perrorf(char *fmt, ...)
Write, to stderr, the name of the program, followed by ": ",
followed by a message formatted as by printf() from <fmt> and
the optional arguments, followed by ": " and a system error
message derived from the value of errno. This is a non-standard
extended version of perror(). (cf: printf, perror)
@endnode
@node strerror
char *strerror(short errnum)
Return the system error message for error <errnum>. If <errnum>
is outside the range of valid error numbers, NULL is returned.
@endnode
@node "variable argument lists"
@alias va_list va_start va_arg va_end
The macros in this section are defined in the <stdarg.h> header file.
typedef char * va_list;
This is the type for a variable argument list traversal variable.
#define va_start(list, param) ((ap) = (char *)...)
This macro initializes the va_list variable <list> to begin
traversing variable argument lists. <param> is the last parameter
in the function call before the variable arguments begin. This
parameter MUST NOT be a register variable.
HR: The use of AHCC/PureC specific ... in the macro makes
the use of <param> obsolete. It is kept for comapatability.
Note:
The ... parameter at the end of a parametr list defines a
AHCC specific local parameter name: '__ELLIPSIS__'.
This name is refered to by the va_start macro.
If you use va_start in a function without ellipsis,
the absence is reported by the message: 'undefined __ELLIPSIS__'.
MACRO va_arg(list, type)
This macro retrieves a variable argument of type <type>, updates
the va_list variable <list>, and returns the value of the retrieved
argument. The <type> should not be parenthesised.
MACRO va_end(list)
This macro must be called after all desired variable arguments have
been retrieved, to reset the context of the va_list variable <list>.
@endnode
@node getopt
short getopt(short argc, char **argv, char *optstring)
This function eases the processing of the command line. Each call
returns a character from <optstring>, with optarg set to a parameter
if one is required; or a '?' indicating that an invalid option was
found; or EOF indicating that all options have been processed. The
<argc> and <argv> parameters are (of course) the argc and argv values
passed to main(). The <opstring> is a string of option characters.
If an option takes a parameter, it is followed by a ':' in <optstring>,
and the char *optarg variable (global) will be set to point to the
parameter string from the command line. For example, "bno:v" defines
the valid option characters as 'b', 'n', 'o' and 'v', and 'o' takes
a parameter. All options must be preceeded (in the command line) by
a '-' character. A single '-' character is taken to indicate stdin
as a file, and terminates the argument processing. A "--" string
indicated the end of options, and is skipped over. When option
processing is successfully completed, the global variable optind will
contain the index into argv[] of the next argument to be processed.
Subsequent arguments should be processed with a loop like this:
while(optind < argc)
process(argv[optind++]);
If an error occurs during argument process, an error message is
written to stderr and '?' is returned by getopt(). Your program
should then give a usage message and abort. If the global variable
opterr is set to zero, no error message will be given, but '?' will
still be returned. Note that command lines accepted by getopt() are
quite flexible. The command lines "-b -v -o filename -- - file",
"-vbofilename - file", and "-ofilename -bv - file" all will return
the 'b', 'v', and 'o' options with the parameter to 'o' set to
"filename" and leave the arguments "-" and "file2" for further
processing. Please examine the sample program "echo.c" for an
example of getopt() usage.
@endnode
@node rand
short rand(void)
Return a pseudorandom number in the range 0..32767. This
function uses the system random number generator, but grabs
it's value out of the middle to avoid the exactly 50%
behavior of the lowest order bit. Source code is also provided,
though commented out, showing how to generate your own
random number sequence if the system random numbers aren't
sufficient or for porting these routines to another machine.
@endnode
@node srand
void srand(unsigned short seed)
Seed the random number generator.
@endnode
@node swab
void swab(char *src, char *dst, size_t n)
Swap adjacent bytes while copying <n> bytes from <src> to <dst>.
This allows bulk translation to/from Intel byte ordering. Please
note the backward order of the <src> and <dst> parameters. Don't
blame me... this is how Microsoft specifies it.
@endnode
@node swap
@alias max min abs
short abs(short v);
long labs(long v);
Return the absolute value of <x>.
MACRO max(x,y)
Return the larger of <x> and <y>. This macro evaluates the
larger argument twice and the smaller argument once.
MACRO min(x,y)
Return the smaller of <x> and <y>. This macro evaluates the
smaller argument twice and the larger argument once.
MACRO swap(a,b)
Exchange <a> and <b> by chained XORs. The macro evaluates
each argument several times.
@endnode
@node assert
MACRO assert(condition)
If <condition> is not true at run-time, this macro causes an
assert failure message to be written to stderr, displaying the
line number and source file name, and aborts the program. If
the symbol NDEBUG is #defined (usually with a -D option to cc),
all assert() calls are disabled.
@endnode
@node "revision record"
This is an attempt to record changes to dLibs from past versions.
I make no promises about it's completeness.
v2.0
v1.2
v1.1
v1.0
@endnode
@node "v2.0"
May 2008
This release belongs to the AHCC C89 compiler for ST/TT family.
The main effort of this release comprises work on the strong
typing offered by ANSI C 1989.
This release is in no way compatible to the previous releases
and can not be used by Sozobon or Alcyon.
For this reason the name of the library is changed to "AHCCLIB"
AHCCLIB is mainly provided to be a simple and uncluttered
library for beginners.
AHCC produces object files that are binary compatible to those
produced by Pure C.
As a consequence, this library can be used as a replacement
for the proprietary standard libraries of the Pure C distribution.
Henk Robbers.
@endnode
@node "v1.2"
October 1988.
This release corresponds to the release of the Sozobon C
compiler for the ST, and includes quite a bit of general code
cleanup as dictated by the stricter (and more correct)
requirements of the Sozobon compiler. This code IS still
compatible with Alcyon C, but now it is also compatible
with Sozobon C.
This release fixes many bugs, most minor, some major. Some
of the functions that were improved are: mktime(), stime(),
strtrim(), ctlcnv(), realloc(), fullpath(), findfile(),
lsearch(), tell(), putenv(), exec(), _initargs(), main(),
qsort(), memccpy() and swab().
The header files were somewhat restuctrured, and <stddef.h> and
<stdarg.h> were added, for more ANSI X3J11 compatibility. Also
<sys\minimum.h> was added as a non-portable hack to make very
small programs when no standard i/o or argv/argc is needed.
The blkXXX() functions have now all been renamed to their X3J11
memXXX() names and some were recoded in assembly language.
The stream i/o functions were overhauled, resulting in changes
to the FILE structure and nearly all associated functions. The
new functions handle interactive i/o with the console much more
nicely, emulating (partly) a tty driver which gives essentially
line-oriented operation for standard input on a character device.
You can now backspace to edit, ^U to retype a line, and ^C to
interrupt a program (sorry, only during input) and none of these
characters will appear in the input read by the program. Since
there is never agreement about how such a driver should work, all
the code is encapsulated in the _tttty() function, which is in
a separate object module.
The pfindfile() function now has a path parameter, but the PATH
environment variable will still be used if NULL is specified.
The wildcard() function has also changed slightly in that is
no longer expands the filenames with fullpath().
Some new functions in this release are: mktime(), usleep(),
alloca(), _splitpath(), _makepath(), bzero(), memcpy(),
strpcpy(), strtol(), strtoul(), perror(), perrorf(), strerror(),
fgetpos(), fsetpos(), vprintf(), vfprintf(), vsprintf() and getopt().
@endnode
@node "v1.1"
December 1987.
Process control functions, spawn(), spawne(), spawnp() and
spawnpe() removed. New functions forkl(), forklp(), forkle(),
forklpe(), forkv(), forkvp(), forkve(), forkvpe() and wait()
now handle creation of child processes.
XARG format extended argument passing is supported by all the
process control functions and _initargs().
Many functions which were previously #defined in <stdio.h> to
gemdos() calls are now real functions. This allows you to pass
the address of these functions in function pointer.
Added brk() and sbrk() functions for managing the heap. This
is not typically a good way to allocate memory. The normal
malloc() functions are much better in most cases.
printf() and scanf() now process capital format characters.
This feature is provided to support old programs which use
capital characters to indicate long values. It is NOT*
recommended for use in current code and is not supported
by the ANSI proposed standard. The scanf() function has
been upgraded to support hyphenated ranges and returns what
we think are correct values for various end-cases like end-
of-input and early format conflicts.
findfile() and pfindfile() have been improved and fopenp()
had been added to support use of the PATH. The extension
list given for findfile() and pfindfile() has been changed
slightly. You must now include the '.' portion of the
extension. This is to allow searching for the empty extension.
The header files have been changed and extended to conform
more closely to ANSI and Unix System V. As a result, some
of the structures and actual values for certain flags have
changed. The stat structure and related functions like
access(), stat(), creat(), open(), etc. have been significantly
changed in implementation. The open() function supports
many more mode flags like O_CREAT, O_APPEND, O_TRUNC and O_EXCL.
A few new functions like swab(), tmpnam(), tempnam(), getcwd()
and wildcard() have been added. Only wildcard() is non-standard,
but I think it's useful to have around.
@endnode
@node "v1.0"
Originnnal release. October 1987.
@endnode
@node Editor
Welcome to the AHCC editor pages.
AHCC uses a unusual editor, but not difficult to grasp.
It must be extremely user friendly, because I use it myself, and I can
be a very unfriendly user. ;-)
All dialogues are in a single scrollable window called the KIT
Double or right click ALWAYS results in a selection.
A quick story on the 'find multiple'
'find in project' features: browse
It is very similar to the Pure C facility.
A quick story on the 'compare 2' facility: filecompare
A quick story on the 'compare folder' facility: foldercompare
A consise summary of Cursor movement.
of Mouse buttons.
of Undo capabilities.
@endnode
@node "carriage returns"
As we all know UNIX people hate carriage returns.
I don't know if they are right or wrong, perhaps they just
hate the noise.
Anyhow, AHCC again makes your life easy.
The criterium of having carriage return is the first line.
If the first line has carriage return and you save,
all lines will get carriage return + linefeed.
If the first line has linefeed only and you save,
all lines will have linefeed only.
You can see the state in the window menu edit-->crlf;
the checked status indicates how the file will be saved.
If you want to change the crlf state, click the menu.
For good reasons a change in current crlf mode is not considered a
change in the file content.
So if you only want to remove (or insert) carriage return,
you must use Save as...
@endnode
@node "Undo capabilities"
Every thing that is changed between mouse clicks can be undone.
The undo button is a flipflop. Press again will REDO.
This is the default action.
There is a menu option that changes this behaviour.
Main menu --> Options --> At rtn reset_undo.
If this is checked, everything between physical pressing the return or enter
key, can be undone.
Both options allow for a complete "find/replace all" to be undone.
@endnode
@node "Cursor movement"
A quick summary of the keyboard&mouse usage of AHCC.PRG and AHCC.PRG.
In standard menu shortcut format as far as possible.
Only the combinations not in the menu ar stated here.
Cursor movement:
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
If a selection is on, it is deselected.
no selection selection ON
<09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 1 pos left on start of sel.
 1 pos right after end of sel.
 same pos prev line above start of sel.
 same pos next line below end of sel.
 to start of line................... left of start of sel.
 to end of line..................... right of end of sel.
 1 page up
 1 page down
^ to start of next word select next disjunct occurrence of
the current selection type
^ to start of prev word select previous disjunct occurrence
of the current selection type
^ as  as 
^ as  as 
^ as ^ as ^ but go deeper
^ as ^ as ^ but go deeper
DEL delete ch under the cursor delete whole sel.
^DEL delete part of line
under and right of cursor as DEL
^DEL delete part of line left of cursor as DEL
HOME cursor to first line, first pos.
HOME cursor to last line, last pos.
BS delete ch left of cursor. as DEL
control + shift + cursor arrows: as the window's single arrows.
Miscalaneous:
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
^+ actuate fuller of top window (if there)
^- idem
@endnode
@node "Mouse buttons"
Mouse buttons:
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
!!--> right click: allways same as double clicking left button;
left click: cursor on ch under the mouse or as close as possible to
the highest real character left to the click.
double click: make selection. see 1)
If selecting a left brace all between and including balancing braces is
selected.
If selecting a right brace only in between balancing braces is selected.
clicking and left dragging as in all editors: select.
While dragging, the window contents are scrolled whenever appropriate.
right dragging: continuous selection.
click as in all editors: make or resize selection.
^click: Make line top of window.
^double click: As above + select.
double click: select whole line.
click: an alternative for left click and double click: select.
@endnode
@node selection
^ and ^ are extremely useful for going through all the comments or
all the #if* #endif pairs or all the functions or calls of a source
file.
1) there are some selection types defined:
selected by double click or right button or click.
braces: { } [ ] ( ) /* */ ' ' " ",
word: letters and digits but starting with a letter;
words can be defined as braces via the "Define braces" menu.
white space: vz
lexical other than above and its surrounding space: vz
html braces. You know them: <tag ...> ... </tag>
right click on the leftmost < or the rightmost >
no type, anything selected by shift click, drag, find or replace.
Note: '' and "" cause no directional problem if there is only 1 pair on a line.
2) with ^ next is selected including braces,
with ^ prev is selected excluding braces.
@endnode
@node browsing
@alias browse
Hits are listed in the journal. Select the word 'Found' with the mouse and
the file containing the occurrence is opened. The line of the occurence is
shown selected. If a full path is shown, you can also select the drive
letter to open the file.
First you have to define a path. This path is in the KIT window below the
'Multiple' button in the 'Find' group.
If the KIT isnt already open, open it by choosing Options->find miltiple or
pressing alt + g.
When you hate typing, or have problems remembering trivialities like names,
as I do, right click on the field. This opens the fileselector.
Who needs a fileselector when you're running a multitasking OS and a desktop
that supports drag&drop?
Just drag a directory name into the field.
(The Acorn Risc OS doesnt have a file selector at all)
Don't forget to add a filter to the path.
The simple filter options are a quick borrow from XaAES:
All pattern matching is case insensitive.
Valid patterns are:
? Any single char
* A string of any char or empty
!X Any char except for X
[abcd] One of (any one of a,b,c or d)
Examples:
* All files in dir
*.* All files with a dot !!!
a* All files begining with 'a'
*.c* All files with a extension starting with c
*.o All '.o' files
*.!o All files not ending in '.o'
!z*.? All files not starting with 'z', and having a single character
extension
*.[co] All '.o' and '.c' files
*.[CH]* All files with an extension starting with C or H
When a path is established there are several ways to start a search.
Via the kit: type a find string and click FIND.
Check if 'Multiple' is selected.
In stead of typing you can use control + I in a text window. 1 for selecting
if nothing is selected, a further one to copy the selection in one of the
Find strings (this starts a top window search as well).
The quickest way is: select the find string in a text window and press
control + shift + I. In this case the whole KIT is bypassed. Very useful
when you don't have a big screen.
'deep' button: go recursive through all subdirectories.
'1 per file' button: stop search in a file on the first occurrence.
When the find string is empty, AHCC displays a nice scheme of all the
files in the path. The button 'verbose' is used.
verbose selected: display full path's ready for cicking on the drive letter.
unselected: display only plain names nicely indented.
AHCC uses the 'Knuth, Morris, Pratt' method for searching.
@endnode
@node filecompare
Open the files you want to compare.
Use Alt + T to tile the windows vertically.
Place the cursor in each file at the point you want to start comparing.
Press Cntrl + 2 (2 from the upper row of the keyboard).
New since v5.0: synchronization is performed by the option itself.
If lines under the cursors are unequal
first of a series of equal lines are made visible and will be selected
as 'whole line'.
If lines under the cursors are equal
first of a series of unequal lines are made visible and will be selected
as 'whole line'.
This selection type makes it possible to use Cntrl + cursor left or
cursor right to move up or down the selection a line.
A series of unequal lines may contain a smal number, to a maximum of 4 currently,
of consecutive equal lines.
Repeat ^2 until you are done.
@endnode
@node Disclaimer
Command line programs.
=====================
I have not used a commandline since 1983 and I have no intention
to use one in the future.
I have no, nada, nope affinity with UNIX commandline usage.
I think typing commands is not a proper way of using modern
computers.
The commandline versions of the compiler and linker of course
use exactly the same compiler and linker as the GEM versions,
but I never have tried them out.
The GEM version uses a interface routine that exactly mimics
a commandline though. The routine is derived from a startup
code out of the real world.
There might be problems with relative paths in the commandline
versions. The GEM version ALWAYS passes absolute paths.
@endnode
@node "Shell/Compiler/Assembler/Linker"
The programs AHCC_P.TTP and AHCCST_P.TTP accept a project
file as input parameter plus a few options of which some
cannot be put in the project file.
Usage:
AHCC(ST)_P [options] filename.prj
options:
-v verbosity
-x make all
-c cache headers
-h project help database
-j auto depend
-g warn gotos
-i nested projects inherit options
-n 'nm' type symbol list
-p load map
-f Dont set 'fast load' bit.
-m Mallocs for ST-ram.
-r Load program to ST-ram.
It is often possible to install AHCC(ST)_P with these
options preset in a desktop program.
If you drop a project file on AHCC(ST)_P, the project will be made.
If you press ALT when dropping, a 'Make All' will be performed.
@endnode
@node "Compiler/Assembler"
@subject "A Home Cooked C compiler"
Welcome to AHCC
A Home Cooked C compiler
Greetings, Henk Robbers.
May 2013
Compiler description
Compiler usage
@endnode
@node "Compiler description"
AHCC is a full ANSI C89 compiler based on the original
Sozobon v1.2 sources. But that is very long ago.
Very few lines will be the same, but the overall architecture
has been unchanged because it was good.
People acquainted with the Sozobon sources will recognize
many parts.
AHCC comes in a variety of incarnations of which the GEM
integrated version is the most well tested and most important.
AHCC is binary compatable to Pure C so it is possible
to freely mix AHCC produced and Pure C produced
objects and libraries.
AHCC has a builtin assembler.
It is allowed to use C preprocessor commands in a assembler file.
As long as AHCC is beta, it will be compiled by Pure C
to avoid embarrassing confusions and strange entanglements.
Nevertheless I have hosted AHCC in 3 stages successfully:
Pure C makes AHCC/1 AHCC/1 compiles CALC ok.
AHCC/1 makes AHCC/2 AHCC/2 compiles CALC ok.
AHCC/2 makes AHCC/3 AHCC/3 compiles CALC ok.
In each appropriate stage I checked equality of the binaries.
This distibution also contains the programs CALC, AHCX and TT-Digger.
These programs are compiled by AHCC and seem to work satisfactorily.
@endnode
@node "Compiler usage"
@alias compiler_options assembler_options
Invocation:
AHCC.TTP [options] inputfilename ...
Commandline parameters for AHCC:
AHCC specific options:
-*b no branch reversals
-*c cache headers
-*e don't include ahcc_rt.h (runtime AHCC specific definitions)
-*g warn goto's
-*h project help
-*i default int is 32 bits
-*j auto dependencies
-*p suppress peephole optimizations
-*s ptr scale 32 bits (int*int=long)
-*u Default assembly for superviser mode
-6 Coldfire (type double is 64 bits)
The '*' associates left, so the -* options can be
combined in a single block like this: -*cghjs
Pure C compatible options
implemented by AHCC:
-c allow nested comments
-dX..X define macro; optional followed by =value
-eN maximum no of erors
-fN maximum no of warnings
-h cdecl calling
-iX..X include directory
-k default char is unsigned
-l maximum identifier length
default is 32. Maximum is 256. This is also the
maximum of ALL tokens.
-oX..X Output file name
-uX..X undefine macro
-v verbosity
-x prepend underline to identifiers
-2 generate for MC68020
-7 generate for Coldfire V4e
-8 generate directly for MC68881/2
accepted by AHCC but not implemented:
-a strict ANSI
-b DRI object output
-g size optimization
-j no jump optimization
-m merge identical strings
-p use absolute calls (AHCC always)
-q Pascal calling
-s force frame pointers (AHCC always)
-t stack checking
-w... suppress warning ...
-y add debug info
-z register reloading
@endnode
@node Linker
@subject "A Home Cooked Linker"
Welcome to AHCL
A Home Cooked Linker for Pure C, DRI, GFA objects
Greetings, Henk Robbers.
july 2006
Description:
AHCL is the stand alone linker that is otherwise built into AHCC.
The need for writing AHCL arose when I wanted to test AHCC
without having to recreate a whole bunch of libraries.
AHCL and AHCC are currently written using Pure C.
So producing Pure C compatible objects was a obvious choice.
It also made it very easy to test AHCC output by comparing
(and combining) with Pure C compiled objects.
AHCL.TTP is the genuine commandline program.
AHCL_PRJ.TTP only accepts a single project filename as parameter.
(I hate commandlines so much)
This project file is exactly the same as those used by Pure C
Such files generally have the .PRJ extension.
In single TOS, just drop the project file on AHCL_PRJ.TTP
and the project will be linked.
Linker usage
Pure C format
Acknoledgment
@endnode
@node "Linker usage"
@alias linker_options
Invocation:
AHCL.TTP [options] inputfilename ...
Commandline parameters for AHCL:
-v Verbose
-j Collect (make new Pure C format object)
-n Write 'nm' type symbol list to [-o].sym
-p Write load map to [-o].map
-o... Output file name
-c... Name of text file holding list of input filenames
Options for executable output:
-sN Stack size, where N is a number less than 0xffffff
-g Add symbol table with global symbols
-l Add local symbols additional to -g
Set load flags:
-m Mallocs for TT ram
-f Dont set 'Fast load' bit
-r Load in TT ram
Followed by:
list of input filenames additional to -c
A example .PRJ file for AHCC_P.TTP
menu_1.ttp
.L [-vpg] ; linker options (same as commandline version)
=
menu_1.o
gfa3blib.lib
@endnode
@node "Pure C format"
@alias "Object format"
This description is the result of analysis using TT-Digger.
It is not something published by any firm or organization involved
in the release of Pure C.
There is no difference in format between object files
and libraries. The only difference is the extension.
The library extension causes AHCC to look in certain standard
library directories first.
The format is described hereafter in an ad hoc dynamic Cish
language:
0) (unsigned char) enum fixup_types
{
FIX_0,
FIX_end,
FIX_step,
FIX_text,
FIX_data,
FIX_bss,
FIX_offset,
FIX_global_area,
FIX_global_entry,
FIX_local_area,
FIX_local_entry,
FIX_long_abs,
FIX_word_abs,
FIX_long_pcrel,
FIX_word_pcrel
};
struct
{
1) struct
{
long magic;
image_size,
fixup_size,
string_size,
res0,
d_dbg, /* apparently disp to debug info
relative to start of image */
res2,
unknown;
} header;
2) short image_section[ header.image_size/sizeof(short) ];
3) struct fixup
{
unsigned char type, /* enum fixup_types */
step;
signed short string_number;
} fixup_section[ header.fixup_size/sizeof(struct fixup) ];
4) union string_section
{
char all_strings[ header.string_size ];
5) struct one_string
{
unsigned char size;
char n[ struct one_string.size ];
} string[ ... as often as completely fills string_section ];
};
} object_file;
Comments:
=========
0:
The various fixup types in 'struct fixup.type'.
FIX_step:
Defines a surplus step value in multiples of 256.
FIX_text:
Introduction of TEXT areas.
FIX_data:
Introduction of DATA areas.
FIX_bss:
Introduction of BSS areas.
FIX_offset:
Introduction of OFFSET's.
FIX_end:
The last fixup.
FIX_global_area:
start of a globally linkable area.
FIX_global_entry:
globally addressable entry within an area.
FIX_local_area:
start of a linkable area local to the objectfile.
FIX_local_entry:
Entry within an area that is not visible outside
the object file.
Below are the fixups that really fix up something. :-)
FIX_long_abs:
Fix up a long operand with the start address of
the addressed area.
FIX_word_abs:
Fix up a short operand with the start address of
the addressed area.
FIX_long_pcrel:
Fix up a long operand with the start address of
the addressed area and make it relative to the
program counter.
FIX_word_pcrel:
Fix up a short operand with the start address of
the addressed area and make it relative to the
program counter.
1: The object file header:
magic = 0x4EFA001C
looks like a 'jmp 28(PC)'.
Right over the header to the image.
2: Image section: content of all initialized areas: TEXT and DATA.
3: Fixup section: all the 'struct fixup' records.
Description of fixup record and its usage:
type:
fixup type.
step:
Amount of bytes to be added to the current position
counter for obtaining the position to which the fixup
applies.
string_number:
Number of the string in the string section.
Fixup types
FIX_text, FIX_data, FIX_bss, FIX_offset and FIX_end
all have their string_number set to -1.
Special fixup type FIX_step:
This fixup catenates step and string_number fields to a
24 bit integral field. The field defines a surplus step
value as a multiple of 256 bytes. It allows area sizes
and distances within areas to be up to the current 32 bit
maximum value.
4: String section: all the names within the object.
The string number is really the number of the string,
*NOT* a offset into the section.
So you have to build a pointer array of the strings
by yourself.
The string number then is the index into this array.
5: The format of a single string in the string section.
first byte: length of the string in bytes.
Can be zero, denoting a empty string.
subsequent bytes: value of the string.
Can be empty.
An empty string still has a number!
Empty strings make it possible to have anonymous linkable
references. Anonymous references are distinguished from
each other by their number.
The string number is thus used to distinguish from each other
local names in/of different areas.
Summary: (very short)
Fixup records point to a string by number.
The string number points back to a entry fixup record in the
image section having the same value in its string_number field.
It is imparative that all entries have a unique string_number.
If such a entry fixup is absent, the string identifies the
name of a external reference.
@endnode
@node Acknoledgment
Thanks to Lonny Pursell and Ingo Schmidt
for advices on GFA objects.
Lonny Pursell for his excellent GBE (Gfa Basic editor)
@endnode
@node GFA
The famous basic interpreter and compiler that is
very popular with Atari ST users.
The format produced by the GFA compiler is slightly different
from the widely used DRI format.
(desriptiom later)
@endnode
@pnode "Pure C"
Discontinued fast C compiler for Atari ST
Copyright 1991 Pure Software GmbH
Copyright 1988/1990 Borland International Inc./
Borland Germany GmbH
All rights reserved.
@endnode
@pnode "Henk Robbers"
Henk Robbers.
te Amsterdam
mailto:h.robbers@chello.nl
http://members.ams.chello.nl/h.robbers
tlf: 020 4182901
@endnode