Most of the DJGPP sources are formatted in a standard way; please observe and preserve this formatting when writing new code.
The indentation style generally looks like this:
if (foo) { bar(baz); }
That is, the braces are on a separate line and in the same column as the
if
(or for
, or while
) clause that opens the block.
Here’s how to set up Emacs’s C Mode for this indentation style:
(c-add-style "DJ" '((c-basic-offset . 2) (c-comment-only-line-offset . (0 . 0)) (c-offsets-alist . ((substatement-open . 0) (label . 0) (statement-case-open . +) (statement-cont . +) (arglist-intro . c-lineup-arglist-intro-after-paren) (arglist-close . c-lineup-arglist) )) )) (c-set-style "DJ")
And here’s the list of options for the GNU indent
program, to be
put on your .indent.pro profile file, in case you need to
reformat your sources to comply with the DJGPP style:
/* DJ */ -nbad -bap -nbc -bbo -bl -bli0 -brs -ncdb -nce -cp1 -cs -di2 -nfc1 -fca -hnl -i2 -ip2 -ci0 -lp -npcs -nprs -psl -nsc -nsob
A C application’s namespace should not be polluted with non-ANSI
and non-POSIX functions from the C libraries, unless the application
explicitly uses these symbols. An example of a non-ANSI and non-POSIX
function is uclock
(see (libc)uclock).
But what happens if you wish to call a non-ANSI and/or
non-POSIX function from C library code? The actual implementation
is placed in the C library’s private namespace with a stub function
that calls the implementation. Consider uclock
—
the library would use the __uclock
function internally,
but application code would use the stub uclock
.
Functions that are stubbed have an entry in the include file libc/stubs.h, e.g.:
#define uclock __uclock
Any C library sources defining or calling the implementation
should include libc/stubs.h as the first include file.
This is so that we can refer to, e.g., uclock
as uclock
in the library code, but the library code will actually define/call,
e.g., __uclock
and will not pollute the application namespace.
The stub files are assembly language files generated automagically from libc/stubs.h as part of the C library build process.
NB: The private name, e.g., __uclock
, is not part of
the published API.
If a library function uses one of the _far*
far pointer
functions, it should include libc/farptrgs.h instead of
sys/farptr.h. The inline functions in farptrgs.h use the
GS register instead of FS, to avoid clobbering FS which
might be used by the application.
When manipulating filenames, don’t use the ctype functions from
ctype.h, because they are locale sensitive. For example,
instead of using tolower
(see (libc)tolower),
convert the case with explicit code.
Assertions should not generally be used in library code. To catch an error,
the code should check for the error and return an error code. Using
assert
(see (libc)assert) causes the debug
and final release (‘NDEBUG’ defined) versions of the code to differ,
so that the final release is not as well tested.
Uninitialised static and global data is placed in the .bss
section.
BSS stands for Block Started by Symbol. The .bss
section
is zeroed by the start-up code.
Initialised static and global data is placed in the .data
section.
So it would seem that one can rely on static and global variables being initialised to zero or some specified value. Unfortunately this may not be true, where programs are unexecuted and then restarted — Emacs is the primary example.
Part of Emacs’s build procedure is that Emacs unexecutes (dumps) itself to
a file. The dumping process records the value of each variable at
the time of the dump to a file. The symbols in the .bss
section
are moved to the .data
section. The values at the time of the dump
are recorded, not the original values. So if the library code is
relying on the value of a static or global variable, e.g., to see whether
it needs to initialise some device or allocate memory, then it may break
when the program restarts.
Fortunately there is a way that library code can detect a restart.
The variable __bss_count
contains a counter of the number of times
that the program has been started — it is incremented by the start-up
code. A routine can store __bss_count
and then check whether it needs
to initialise its data by comparing __bss_count
with its stored value.
Here is an example:
#include <string.h> #include <libc/bss.h> extern int do_something_interesting (const int n); static int my_bss_count = -1; static int my_array[20]; int myfunc (const int n) { if (my_bss_count != __bss_count) { my_bss_count = __bss_count; memset(my_array, 0, sizeof(my_array)); } if (n >= 20) return 0; if (!my_array[n]) my_array[n] = do_something_interesting(n); return(my_array[n]); }
For more details see src/libc/crt0/crt1.c in the DJGPP libc sources.
src/gcc.opt controls how the DJGPP sources are compiled. To build the C libraries for profiling, add the profiling options (e.g., ‘-pg’) to gcc.opt, one option per line. The library will need to be rebuilt from scratch for the new options to take effect, so a ‘make clean’ is needed before rebuilding in the directory of interest, e.g.:
cd /path/to/djgpp/sources cd src echo "Adding profiling option to gcc.opt" echo -pg >> gcc.opt cd libc echo "Building a profiling version of libc" make clean make
For example of how some of the sources are built without profiling, please see src/libc/crt0/makefile to see how the profiling support code, src/libc/crt0/mcount.c, is built.
There are currently some problems with profiling support. The math co-processor support code, emu387.dxe, in src/libemu cannot be built with profiling.
When you prepare a patch use ‘diff -upr djgpp.old djgpp.new’ or ‘diff -cpr djgpp.old djgpp.new’. The directory names ‘djgpp.old’ and ‘djgpp.new’ are just examples, but you should preferably use a descriptive name. If you have added any new files the option ‘-N’ comes in handy.
Similarly if you use cvs diff use ‘cvs -z3 diff -up djgpp’ or ‘cvs -z3 diff -cp djgpp’. To get cvs diff to notice any new files you must make cvs aware of them with the cvs add command.
int somefunc (void);
is incorrect;
int somefunc (void);
is correct.
@cindex definition This is a @dfn{definition}.
EINVAL
should be enclosed in ‘@code{}’.
LOGNAME
should be enclosed in
‘@env{}’.
@code{yabbadabbadoo()}, @ref{yabbadabbadoo()}.
@uref
to refer to a URL. texinfo also has @url
for inserting URLs, but @uref
is more useful when texinfo
is formatted into HTML. The Texinfo manual discourages
the use of @url
.
@subheading Portability @portability !ansi, posix
Please note that ‘@portability’ is not used to indicate whether the DJGPP implementation complies with the standards listed. Instead, ‘@port-note’ may be used to describe implementation-specific details:
@port-note ansi The buffer size limit is imposed by DJGPP.
‘@portability’ and ‘@port-note’ are DJGPP-specific extensions
of texinfo (see (texinfo)texinfo) that are expanded into normal
texinfo by mkdoc
. mkdoc
is part of the DJGPP sources. It is
used to build the C library documentation (see (libc)libc).
Therefore, ‘@portability’ and ‘@port-note’ should only be used
in DJGPP’s C library documentation.