mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-10 13:49:18 +02:00
Final changes before release
This commit is contained in:
parent
438de2d913
commit
90f65781c2
@ -93,12 +93,12 @@ endif
|
||||
# Conversion from types
|
||||
#####################################################################
|
||||
|
||||
.PHONY: all clean dvi help html ps psdist htmldist htm txt pdf refex
|
||||
.PHONY: clean dvi help html ps psdist htmldist pdfdist txtdist \
|
||||
htm txt pdf refex alldist
|
||||
|
||||
.SUFFIXES: .dvi .tex .ps .txt .pdf
|
||||
|
||||
# default show help
|
||||
all: help
|
||||
|
||||
.dvi.ps:
|
||||
$(DVIPS) $<
|
||||
@ -119,6 +119,7 @@ all: help
|
||||
$(PDFLATEX) $*pdf
|
||||
-$(MAKEINDEX) $*pdf
|
||||
$(PDFLATEX) $*pdf
|
||||
mv $*pdf.pdf $*.pdf
|
||||
|
||||
$(TXT) : %.txt: %.dvi
|
||||
|
||||
@ -132,11 +133,19 @@ $(PDF) : %.pdf: %.tex
|
||||
|
||||
help:
|
||||
@echo 'Possible targets :'
|
||||
@echo ' dvi : Make documentation using latex.'
|
||||
@echo ' ps : Make documentation using latex and dvips.'
|
||||
@echo ' html : Make documentation using latex2html.'
|
||||
@echo ' htm : Convert .html to .htm files, zip result'
|
||||
@echo ' clean : Clean up the mess.'
|
||||
@echo ' dvi : Make documentation using latex.'
|
||||
@echo ' ps : Make documentation using latex and dvips.'
|
||||
@echo ' html : Make documentation using latex2html.'
|
||||
@echo ' pdf : Make documentation using pdflatex'
|
||||
@echo ' txt : dvi, convert to text using dvi2tty'
|
||||
@echo ' htm : Convert .html to .htm files, zip result'
|
||||
@echo ' clean : Clean up the mess.'
|
||||
@echo ' linuxexamples : Compile all examples for linux'
|
||||
@echo ' dosexamples : Compile all examples for dos'
|
||||
@echo ' htmldist : html, and rchive result.'
|
||||
@echo ' psdist : ps, and archive result.'
|
||||
@echo ' pdfdist : pdf, and archive result.'
|
||||
|
||||
|
||||
clean:
|
||||
-rm -rf $(HTML)
|
||||
@ -169,13 +178,19 @@ units.dvi: units.tex $(CHAPTERS) unitex.chk
|
||||
|
||||
ref.dvi: ref.tex refex.chk
|
||||
|
||||
units.pdf: units.tex $(CHAPTERS) unitex.chk
|
||||
|
||||
ref.pdf: ref.tex refex.chk
|
||||
|
||||
dvi : $(DVI)
|
||||
|
||||
txt : dvi $(TXT)
|
||||
|
||||
ps : dvi $(PS)
|
||||
|
||||
pdf : unitex.chk refex.chk $(PDF)
|
||||
pdf : $(PDF)
|
||||
|
||||
all : dvi ps pdf txt html
|
||||
|
||||
user: user.chk
|
||||
|
||||
@ -220,13 +235,13 @@ prog.chk: prog.tex
|
||||
|
||||
html: $(HTML)
|
||||
|
||||
htm:
|
||||
htm: html
|
||||
makehtm `find . -name '*.html'`
|
||||
zip fpcdoc `find . -name '*.htm'`
|
||||
zip -q fpcdoc `find . -name '*.htm'` `find . -name '*.gif'`
|
||||
rm `find -name '*.htm'`
|
||||
|
||||
all-formats: ps txt pdf html
|
||||
|
||||
htmdist: htm
|
||||
|
||||
#####################################################################
|
||||
# Installation
|
||||
#####################################################################
|
||||
@ -242,26 +257,52 @@ www-install: psdist htmldist htm
|
||||
ssh tfdec1 '(cd htdocs/fpk/docs ; /usr/local/bin/tar -xzf ../fpcdoc.tar.gz)'
|
||||
|
||||
#####################################################################
|
||||
# Distribution
|
||||
# Archives
|
||||
#####################################################################
|
||||
|
||||
psdist: ps
|
||||
tar -cvzf fpcdocps.tar.gz *.ps
|
||||
zip fpcdocps *.ps
|
||||
psdist: $(PS)
|
||||
tar -cvzf fpcdocps.tar.gz $(PS)
|
||||
zip fpcdocps $(PS)
|
||||
|
||||
pdfdist: pdf
|
||||
zip fpcdocpdf *.pdf
|
||||
zip fpcdocpdf $(PDF)
|
||||
|
||||
dvidist: dvi
|
||||
zip fpcdocdvi $(DVI)
|
||||
|
||||
htmldist: html
|
||||
find . -name '*.html' >htmllist
|
||||
find . -name '*.gif' >>htmllist
|
||||
tar -czvf fpcdoc.tar.gz --files-from=htmllist
|
||||
tar -czf fpcdoc.tar.gz --files-from=htmllist
|
||||
rm -f htmllist
|
||||
|
||||
dist:
|
||||
-mkdir $(DISTDIR)/docs
|
||||
cp Makefile README.DOCS makehtm fpktoc.html $(DISTDIR)/docs
|
||||
cp *.tex *.sty *.perl *.doc $(DISTDIR)/docs
|
||||
|
||||
txtdist: txt
|
||||
zip fpcdoctxt $(TXT)
|
||||
|
||||
alldist: dvidist psdist txtdist pdfdist htmldist htmdist
|
||||
|
||||
distclean: clean
|
||||
-rm -f *.tar.gz *.zip
|
||||
|
||||
#####################################################################
|
||||
# Examples
|
||||
#####################################################################
|
||||
|
||||
examples:
|
||||
$(MAKE) -C crtex
|
||||
$(MAKE) -C dosex
|
||||
$(MAKE) -C crtex
|
||||
$(MAKE) -C dosex
|
||||
$(MAKE) -C optex
|
||||
$(MAKE) -C printex
|
||||
$(MAKE) -C refex
|
||||
$(MAKE) -C sockex
|
||||
$(MAKE) -C stringex
|
||||
|
||||
dosexamples: examples
|
||||
$(MAKE) -C go32ex
|
||||
$(MAKE) -C mouseex
|
||||
|
||||
linuxexamples: examples
|
||||
$(MAKE) -C linuxex
|
||||
$(MAKE) -C sockex
|
||||
|
@ -151,7 +151,7 @@ Not implemented on \linux.}
|
||||
|
||||
\procedure{Delay}{(DTime: Word)}
|
||||
{Delay waits a specified number of milliseconds. The number of specified
|
||||
seconds is a approximation, and may be off a lot, if system load is high.}
|
||||
seconds is an approximation, and may be off a lot, if system load is high.}
|
||||
{None}{\seep{Sound}, \seep{NoSound}}
|
||||
|
||||
\input{crtex/ex15.tex}
|
||||
@ -194,7 +194,7 @@ The cursor doesn't move.}
|
||||
\Function {KeyPressed}{Boolean}
|
||||
{ The Keypressed function scans the keyboard buffer and sees if a key has
|
||||
been pressed. If this is the case, \var{True} is returned. If not,
|
||||
\var{False} is returned. The \var{Shift, Alt, Ctrl} are not reported.
|
||||
\var{False} is returned. The \var{Shift, Alt, Ctrl} keys are not reported.
|
||||
The key is not removed from the buffer, and can hence still be read after
|
||||
the KeyPressed function has been called.
|
||||
}
|
||||
|
@ -11,7 +11,8 @@ begin
|
||||
WriteLn('Line 2');
|
||||
WriteLn('Line 3');
|
||||
WriteLn;
|
||||
WriteLn('Oops, Line 2 is listed twice, let''s delete the line at the cursor postion');
|
||||
WriteLn('Oops, Line 2 is listed twice,',
|
||||
' let''s delete the line at the cursor postion');
|
||||
GotoXY(1,3);
|
||||
ReadKey;
|
||||
DelLine;
|
||||
|
@ -7,5 +7,6 @@ begin
|
||||
WriteLn('Waiting until a key is pressed');
|
||||
repeat
|
||||
until KeyPressed;
|
||||
{The key is not Read, so it should also be outputted at the commandline}
|
||||
{ The key is not Read,
|
||||
so it should also be outputted at the commandline}
|
||||
end.
|
||||
|
@ -4,7 +4,8 @@ uses Crt;
|
||||
{ Program to demonstrate the ClrEol function. }
|
||||
|
||||
begin
|
||||
Write('This line will be cleared from the cursor postion until the right of the screen');
|
||||
Write('This line will be cleared from the',
|
||||
' cursor postion until the right of the screen');
|
||||
GotoXY(27,WhereY);
|
||||
ReadKey;
|
||||
ClrEol;
|
||||
|
83
docs/dos.tex
83
docs/dos.tex
@ -98,39 +98,47 @@ Under \linux, the \var{Fill} array is replaced with the following:
|
||||
This is because the searching meachanism on Unix systems is substantially
|
||||
different from \dos's, and the calls have to be mimicked.
|
||||
\begin{verbatim}
|
||||
{$PACKRECORDS 2}
|
||||
FileRec = Record
|
||||
Handle : word;
|
||||
Mode : word;
|
||||
RecSize : word;
|
||||
_private : array[1..26] of byte;
|
||||
UserData: array[1..16] of byte;
|
||||
Name: array[0..255] of char;
|
||||
End;
|
||||
const
|
||||
filerecnamelength = 255;
|
||||
|
||||
type
|
||||
FileRec = Packed Record
|
||||
Handle,
|
||||
Mode,
|
||||
RecSize : longint;
|
||||
_private : array[1..32] of byte;
|
||||
UserData : array[1..16] of byte;
|
||||
name : array[0..filerecnamelength] of char;
|
||||
End;
|
||||
\end{verbatim}
|
||||
\var{FileRec} is used for internal representation of typed and untyped files.
|
||||
Text files are handled by the following types :
|
||||
\begin{verbatim}
|
||||
TextBuf = array[0..127] of char;
|
||||
const
|
||||
TextRecNameLength = 256;
|
||||
TextRecBufSize = 256;
|
||||
|
||||
TextRec = record
|
||||
handle : word;
|
||||
mode : word;
|
||||
bufSize : word;
|
||||
_private : word;
|
||||
bufpos : word;
|
||||
bufend : word;
|
||||
bufptr : ^textbuf;
|
||||
openfunc : pointer;
|
||||
inoutfunc : pointer;
|
||||
flushfunc : pointer;
|
||||
type
|
||||
TextBuf = array[0..TextRecBufSize-1] of char;
|
||||
TextRec = Packed Record
|
||||
Handle,
|
||||
Mode,
|
||||
bufsize,
|
||||
_private,
|
||||
bufpos,
|
||||
bufend : longint;
|
||||
bufptr : ^textbuf;
|
||||
openfunc,
|
||||
inoutfunc,
|
||||
flushfunc,
|
||||
closefunc : pointer;
|
||||
userdata : array[1..16] of byte;
|
||||
name : array[0..127] of char;
|
||||
buffer : textbuf;
|
||||
End;
|
||||
UserData : array[1..16] of byte;
|
||||
name : array[0..textrecnamelength-1] of char;
|
||||
buffer : textbuf;
|
||||
End;
|
||||
\end{verbatim}
|
||||
The size of the \var{name} field is 255 under \linux.
|
||||
Remark that this is not binary compatible with the Turbo Pascal definition
|
||||
of \var{TextRec}, since the sizes of the different fields are different.
|
||||
\begin{verbatim}
|
||||
Registers = record
|
||||
case i : integer of
|
||||
@ -183,9 +191,15 @@ Other values are possible, but are not documented.
|
||||
\section{Functions and Procedures}
|
||||
|
||||
\procedure{AddDisk}{(Const S : String)}
|
||||
{\var{AddDisk} adds a filenme \var{S} to the internal list of filenames.
|
||||
{\var{AddDisk} adds a filename \var{S} to the internal list of disks. It is
|
||||
implemented for \linux only.
|
||||
This list is used to determine which disks to use in the \seef{DiskFree}
|
||||
and \seef{DiskSize} calls. The names are added sequentially. The dos
|
||||
and \seef{DiskSize} calls.
|
||||
|
||||
The \seef{DiskFree} and \seef{DiskSize} functions need a file on the
|
||||
specified drive, since this is required for the \var{statfs} system call.
|
||||
|
||||
The names are added sequentially. The dos
|
||||
initialization code presets the first three disks to:
|
||||
\begin{itemize}
|
||||
\item \var{'.'} for the current drive,
|
||||
@ -195,7 +209,7 @@ initialization code presets the first three disks to:
|
||||
\end{itemize}
|
||||
The first call to \var{AddDisk} will therefore add a name for the second
|
||||
harddisk, The second call for the third drive, and so on until 23 drives
|
||||
have been added (corresponding to \var{'D:'} to \var{'Z:'})
|
||||
have been added (corresponding to drives \var{'D:'} to \var{'Z:'})
|
||||
}{None}{\seef{DiskFree}, \seef{DiskSize} }
|
||||
|
||||
\function{DiskFree}{(Drive: byte)}{longint}{
|
||||
@ -208,9 +222,10 @@ Typically, the free space is the size of a disk block, multiplied by the
|
||||
number of free blocks on the disk.
|
||||
|
||||
\textbf{For \linux only:}\\
|
||||
The \var{diskfree} and \var{disksize} functions need a file on the specified drive, since this
|
||||
is required for the \var{statfs} system call.
|
||||
These filenames are set in the initialization of the dos unit, and have
|
||||
The \var{diskfree} and \var{disksize} functions need a file on the
|
||||
specified drive, since this is required for the \var{statfs} system call.
|
||||
|
||||
These filenames are set in the initialization of the dos unit, and have
|
||||
been preset to :
|
||||
\begin{itemize}
|
||||
\item \var{'.'} for the current drive,
|
||||
@ -223,7 +238,7 @@ There is room for 1-26 drives. You can add a drive with the
|
||||
|
||||
These settings can be coded in \var{dos.pp}, in the initialization part.
|
||||
}{-1 when a failure occurs, or an invalid \var{drivenr} is given.}
|
||||
{\seef{DiskSize}}
|
||||
{\seef{DiskSize}, \seep{AddDisk}}
|
||||
|
||||
\input{dosex/ex6.tex}
|
||||
|
||||
@ -249,7 +264,7 @@ There is room for 1-26 drives. You can add a drive with the
|
||||
|
||||
These settings can be coded in \var{dos.pp}, in the initialization part.
|
||||
}{-1 when a failure occurs, or an invalid drive number is given.}
|
||||
{\seef{DiskFree}}
|
||||
{\seef{DiskFree}, \seep{AddDisk}}
|
||||
|
||||
For an example, see \seef{DiskFree}.
|
||||
|
||||
|
@ -81,6 +81,7 @@
|
||||
\newcommand{\msdos}{\textsc{ms-dos} }
|
||||
\newcommand{\ostwo}{\textsc{os/2} }
|
||||
\newcommand{\windowsnt}{\textsc{WindowsNT} }
|
||||
\newcommand{\windows}{\textsc{Windows} }
|
||||
\newcommand{\docdescription}[1]{}
|
||||
\newcommand{\docversion}[1]{}
|
||||
\newcommand{\unitdescription}[1]{}
|
||||
|
@ -45,16 +45,16 @@ TGlob = record
|
||||
The following types are used in the signal-processing procedures.
|
||||
\begin{verbatim}
|
||||
{$Packrecords 1}
|
||||
SignalHandler = Procedure ( Sig : Integer);
|
||||
SignalHandler = Procedure ( Sig : Integer);cdecl;
|
||||
PSignalHandler = SignalHandler;
|
||||
SignalRestorer = Procedure;
|
||||
SignalRestorer = Procedure;cdecl;
|
||||
PSignalrestorer = SignalRestorer;
|
||||
|
||||
SigActionRec = Record
|
||||
Sa_Handler : PSignalhandler;
|
||||
Sa_Handler : Signalhandler;
|
||||
Sa_Mask : Longint;
|
||||
Sa_flags : Integer;
|
||||
Sa_Restorer : PSignalRestorer;
|
||||
Sa_Restorer : SignalRestorer;
|
||||
end;
|
||||
PSigActionRec = ^SigActionRec;
|
||||
\end{verbatim}
|
||||
@ -1782,7 +1782,7 @@ given in \var{Mask}, and then suspends the process until a signal is received.
|
||||
{\seep{SigAction}, \seep{SigProcMask}, \seef{SigPending}, \seef{Signal},
|
||||
\seef{Kill}, \seem{SigSuspend}{2} }
|
||||
|
||||
\function{Signal}{(SigNum : Integer; Handler : PSignalHandler)}{PSignalHandler}
|
||||
\function{Signal}{(SigNum : Integer; Handler : SignalHandler)}{SignalHandler}
|
||||
{
|
||||
Signal installs a new signal handler for signal \var{SigNum}. This call has
|
||||
the same functionality as the \textbf{SigAction} call.
|
||||
@ -1796,6 +1796,8 @@ The return value for Signal is the old signal handler, or nil on error.
|
||||
}
|
||||
{\seep{SigAction},\seef{Kill}, \seem{Signal}{2} }
|
||||
|
||||
\input{linuxex/ex58.tex}
|
||||
|
||||
\function{SymLink}{(OldPath,NewPath : pathstr)}{Boolean}
|
||||
{\var{SymLink} makes \var{Newpath} point to the file in \var{OldPath}, which doesn't
|
||||
necessarily exist. The two files DO NOT have the same inode number.
|
||||
|
@ -36,7 +36,7 @@ OBJECTS=ex1 ex2 ex3 ex4 ex5 ex6 ex7 ex8 ex9 ex10 ex11 ex12 ex13 ex14 \
|
||||
ex15 ex16 ex17 ex18 ex19 ex20 ex21 ex22 ex23 ex24 ex25 ex26 ex27 \
|
||||
ex28 ex29 ex30 ex31 ex32 ex33 ex34 ex35 ex36 ex37 ex38 ex39 ex40 \
|
||||
ex41 ex42 ex43 ex44 ex45 ex46 ex47 ex48 ex49 ex51 ex52 ex53 ex54 ex55 \
|
||||
ex56 ex57
|
||||
ex56 ex57 ex58
|
||||
# ex58 ex59 ex60 ex61 ex62 ex63 ex64 ex65 ex66 \
|
||||
# ex67 ex68 ex69 ex70 ex71 ex72 ex73 ex74 ex75 ex76 ex77
|
||||
|
||||
|
@ -58,3 +58,4 @@ ex54.pp contains an example of the IOCtl function.
|
||||
ex55.pp contains an example of the TCGetAttr,TCSetAttr,CFMakeRaw functions.
|
||||
ex56.pp contains an example of the Shell function.
|
||||
ex57.pp contains an example of the SigAction function.
|
||||
ex58.pp contains an example of the Signal function.
|
||||
|
@ -36,7 +36,7 @@ begin
|
||||
writeln ('ctime : ',info.ctime);
|
||||
|
||||
If not SymLink ('test.fil','test.lnk') then
|
||||
writeln ('Link failed !': linuxerror);
|
||||
writeln ('Link failed ! Errno :',linuxerror);
|
||||
|
||||
if not lstat ('test.lnk',info) then
|
||||
begin
|
||||
|
@ -32,5 +32,6 @@ begin
|
||||
writeln('Error: ',linuxerror,'.');
|
||||
halt(1);
|
||||
end;
|
||||
Writeln ('Send USR1 signal or press <ENTER> to exit');
|
||||
readln;
|
||||
end.
|
||||
|
@ -2,11 +2,18 @@ program testopt;
|
||||
|
||||
{ Program to depmonstrate the getopts function. }
|
||||
|
||||
{
|
||||
Valid calls to this program are
|
||||
optex --verbose --add me --delete you
|
||||
optex --append --create child
|
||||
optex -ab -c me -d you
|
||||
and so on
|
||||
}
|
||||
uses getopts;
|
||||
|
||||
var c : char;
|
||||
optionindex : integer;
|
||||
theopts : array[1..7] of option;
|
||||
optionindex : Longint;
|
||||
theopts : array[1..7] of TOption;
|
||||
|
||||
begin
|
||||
with theopts[1] do
|
||||
|
@ -1,5 +1,6 @@
|
||||
#!/bin/sh
|
||||
# Simply paste a header and footer to the program.
|
||||
#
|
||||
cat head.tex > $1.tex
|
||||
cat $1.pp >> $1.tex
|
||||
cat foot.tex >> $1.tex
|
||||
|
668
docs/prog.tex
668
docs/prog.tex
@ -98,6 +98,47 @@ compiler's behaviour from the moment they're encountered until the moment
|
||||
another switch annihilates their behaviour, or the end of the unit or
|
||||
program is reached.
|
||||
|
||||
\subsection{\var{\$A} or \var{\$ALIGN}: Align Data}
|
||||
|
||||
This switch is recognized for Turbo Pascal Compatibility, but is not
|
||||
yet implemented. The alignment of data will be different in any case, since
|
||||
\fpc is a 32-bit compiler.
|
||||
|
||||
\subsection{\var{\$ASMMODE} : Assembler mode}
|
||||
\label{se:AsmReader}
|
||||
|
||||
The \var{\{\$ASMMODE XXX} directive informs the compiler what kind of assembler
|
||||
it can expect in an \var{asm} block. The \var{XXX} should be replaced by one
|
||||
of the following:
|
||||
\begin{description}
|
||||
\item [att\ ] Indicates that \var{asm} blocks contain AT\&T syntax assembler.
|
||||
\item [intel\ ] Indicates that \var{asm} blocks contain Intel syntax
|
||||
assembler.
|
||||
\item [direct\ ] Tells the compiler that asm blocks should be copied
|
||||
directly to the assembler file.
|
||||
\end{description}
|
||||
These switches are local, and retain their value to the end of the unit that
|
||||
is compiled, unless they are replaced by another directive of the same type.
|
||||
The command-line switch that corresponds to this switch is \var{-R}.
|
||||
|
||||
\subsection{\var{\$B} or \var{\$BOOLEVAL}: Complete boolean evaluation}
|
||||
|
||||
This switch is understood by the \fpc compiler, but is ignored. The compiler
|
||||
always uses shortcut evaluation, i.e. the evaluation of a boolean expression
|
||||
is stopped once the result of the total exression is known with certainty.
|
||||
|
||||
So, in the following example, the function \var{Bofu}, which has a boolean
|
||||
result, will never get called.
|
||||
\begin{verbatim}
|
||||
If False and Bofu then
|
||||
...
|
||||
\end{verbatim}
|
||||
|
||||
\subsection{\var{\$C} or \var{\$ASSERTIONS} : Assertion support}
|
||||
|
||||
This switch is recognised for Delphi compatibility only. Assertions are not
|
||||
yet supported by the compiler, but will be implemented in the future.
|
||||
|
||||
\subsection{\var{\$DEFINE} : Define a symbol}
|
||||
|
||||
The directive
|
||||
@ -364,20 +405,9 @@ an environment variable. It's value will be fetched.
|
||||
|
||||
% Assembler type
|
||||
\subsection{\var{\$I386\_XXX} : Specify assembler format}
|
||||
This switch can only be used in the i386 assembler.
|
||||
|
||||
This switch informs the compiler what kind of assembler it can expect in an
|
||||
\var{asm} block. The \var{XXX} should be replaced by one of the following:
|
||||
\begin{description}
|
||||
\item [att\ ] Indicates that \var{asm} blocks contain AT\&T syntax assembler.
|
||||
\item [intel\ ] Indicates that \var{asm} blocks contain Intel syntax
|
||||
assembler.
|
||||
\item [direct\ ] Tells the compiler that asm blocks should be copied
|
||||
directly to the assembler file.
|
||||
\end{description}
|
||||
These switches are local, and retain their value to the end of the unit that
|
||||
is compiled, unless they are replaced by another directive of the same type.
|
||||
The command-line switch that corresponds to this switch is \var{-R}.
|
||||
This switch selects the assembler reader. \var{\{\$I386\_XXX\}}
|
||||
has the same effect as \var{\{\$ASMMODE XXX\}}, \sees{AsmReader}
|
||||
|
||||
\subsection{\var{\$L} or \var{\$LINK} : Link object file}
|
||||
The \var{\{\$L filename\}} or \var{\{\$LINK filename\}} directive
|
||||
@ -445,6 +475,17 @@ ppc386 -k-lc foo.pp
|
||||
|
||||
This switch is recognized for Delphi compatibility only since the generation
|
||||
of type information isn't fully implemented yet.
|
||||
|
||||
\subsection{\var{\$MESSAGE} : Generate info message}
|
||||
|
||||
If the generation of info is turned on, through the \var{-vi} command-line
|
||||
option, then
|
||||
\begin{verbatim}
|
||||
{$MESSAGE This was coded on a rainy day by Bugs Bunny }
|
||||
\end{verbatim}
|
||||
will display an info message when the compiler encounters it. The effect is
|
||||
the same as the \var{\{\$INFO\}} directive.
|
||||
|
||||
|
||||
\subsection{\var{\$MMX} : Intel MMX support}
|
||||
As of version 0.9.8, \fpc supports optimization for the \textbf{MMX} Intel
|
||||
@ -558,6 +599,9 @@ Type
|
||||
saturday, sunday);
|
||||
\end{verbatim}
|
||||
|
||||
{\em Remark:}
|
||||
Sets are always put in 32 bit or 32 bytes, this cannot be changed
|
||||
|
||||
\subsection{\var{\$PACKRECORDS} : Alignment of record elements}
|
||||
|
||||
This directive controls the byte alignment of the elements in a record,
|
||||
@ -578,6 +622,49 @@ contrary to Turbo Pascal, where it is 1.
|
||||
More information of this can be found in the reference guide, in the section
|
||||
about record types.
|
||||
|
||||
{\em Remark:}
|
||||
Sets are always put in 32 bit or 32 bytes, this cannot be changed
|
||||
|
||||
\subsection{\var{\$Q} \var{\$OVERFLOWCHECKS}: Overflow checking}
|
||||
The \var{\{\$Q+\}} or \var{\{\$OVERFLOWCHECKS ON\}} directive turns on
|
||||
integer overflow checking. This means that the compiler inserts code
|
||||
to check for overflow when doing computations with integers.
|
||||
When an overflow occurs, the run-time library will print a message
|
||||
\var{Overflow at xxx}, and exit the program with exit code 215.
|
||||
|
||||
\emph{ Remark: } Overflow checking behaviour is not the same as in
|
||||
Turbo Pascal since all arithmetic operations are done via 32-bit
|
||||
values. Furthermore, the Inc() and Dec() standard system procedures
|
||||
\emph{ are } checked for overflow in \fpc, while in Turbo Pascal they
|
||||
are not.
|
||||
|
||||
Using the \var{\{\$Q-\}} switch switches off the overflow checking code
|
||||
generation.
|
||||
|
||||
The generation of overflow checking code can also be controlled
|
||||
using the \var{-Co} command line compiler option (see \userref).
|
||||
|
||||
\subsection{\var{\$R} or \var{\$RANGECHECKS} : Range checking}
|
||||
By default, the computer doesn't generate code to check the ranges of array
|
||||
indices, enumeration types, subrange types, etc. Specifying the
|
||||
\var{\{\$R+\}} switch tells the computer to generate code to check these
|
||||
indices. If, at run-time, an index or enumeration type is specified that is
|
||||
out of the declared range of the compiler, then a run-time error is
|
||||
generated, and the program exits with exit code 201.
|
||||
|
||||
The \var{\{\$RANGECHECKS OFF\}} switch tells the compiler not to generate range checking
|
||||
code. This may result in faulty program behaviour, but no run-time errors
|
||||
will be generated.
|
||||
|
||||
{\em Remark: } Range checking for sets and enumerations are not yet fully
|
||||
implemented.
|
||||
|
||||
\subsection{\var{\$SATURATION} : Saturation operations}
|
||||
This works only on the intel compiler, and MMX support must be on
|
||||
(\var{\{\$MMX +\}}) for this to have any effect. See the section on
|
||||
saturation support (\sees{SaturationSupport}) for more information
|
||||
on the effect of this directive.
|
||||
|
||||
\subsection{\var{\$STOP} : Generate fatal error message}
|
||||
|
||||
The following code
|
||||
@ -589,6 +676,13 @@ The compiler will immediatly stop the compilation process.
|
||||
|
||||
It has the same effect as the \var{\{\$FATAL\}} directive.
|
||||
|
||||
\subsection{\var{\$T} or \var{\$TYPEDADDRESS} : Typed address operator (@)}
|
||||
|
||||
In the \var{\{\$T+\}} or \var{\{\$TYPEDADDRESS ON\}} state the @ operator,
|
||||
when applied to a variable, returns a result of type \var{\^{}T}, if the
|
||||
type of the variable is \var{T}. In the \var{\{\$T-\}} state, the result is
|
||||
always an untyped pointer, which is assignment compatible with all other
|
||||
pointer types.
|
||||
|
||||
\subsection{\var{\$UNDEF} : Undefine a symbol}
|
||||
|
||||
@ -637,6 +731,33 @@ will display a warning message when the compiler encounters it.
|
||||
Contrary to the command-line option \var{-vw} this
|
||||
is a local switch, this is useful for checking parts of your code.
|
||||
|
||||
\subsection{\var{\$X} or \var{\$EXTENDEDSYNTAX} : Extended syntax}
|
||||
Extended syntax allows you to drop the result of a function. This means that
|
||||
you can use a function call as if it were a procedure. Standard this feature
|
||||
is on. You can switch it off using the \var{\{\$X-\}} or
|
||||
\var{\{\$EXTENDEDSYNTAX OFF\}}directive.
|
||||
|
||||
The following, for instance, will not compile :
|
||||
\begin{verbatim}
|
||||
function Func (var Arg : sometype) : longint;
|
||||
begin
|
||||
... { declaration of Func }
|
||||
end;
|
||||
|
||||
...
|
||||
|
||||
{$X-}
|
||||
Func (A);
|
||||
\end{verbatim}
|
||||
The reason this construct is supported is that you may wish to call a
|
||||
function for certain side-effects it has, but you don't need the function
|
||||
result. In this case you don't need to assign the function result, saving
|
||||
you an extra variable.
|
||||
|
||||
The command-line compiler switch \var{-Sa1} has the same effect as the
|
||||
\var{\{\$X+\}} directive.
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Global switches
|
||||
\section{Global directives}
|
||||
@ -645,25 +766,6 @@ Global directives affect the whole of the compilation process. That is why
|
||||
they also have a command - line counterpart. The command-line counterpart is
|
||||
given for each of the directives.
|
||||
|
||||
\subsection{\var{\$A} or \var{\$ALIGN}: Align Data}
|
||||
|
||||
This switch is recognized for Turbo Pascal Compatibility, but is not
|
||||
yet implemented. The alignment of data will be different in any case, since
|
||||
\fpc is a 32-bit compiler.
|
||||
|
||||
\subsection{\var{\$B} or \var{\$BOOLEVAL}: Complete boolean evaluation}
|
||||
|
||||
This switch is understood by the \fpc compiler, but is ignored. The compiler
|
||||
always uses shortcut evaluation, i.e. the evaluation of a boolean expression
|
||||
is stopped once the result of the total exression is known with certainty.
|
||||
|
||||
So, in the following example, the function \var{Bofu}, which has a boolean
|
||||
result, will never get called.
|
||||
\begin{verbatim}
|
||||
If False and Bofu then
|
||||
...
|
||||
\end{verbatim}
|
||||
|
||||
\subsection{\var{\$D} or \var{\$DEBUGINFO}: Debugging symbols}
|
||||
|
||||
When this switch is on (\var{\{\$DEBUGINFO ON\}}),
|
||||
@ -685,7 +787,8 @@ a warning.
|
||||
The compiler itself doesn't do the emulation of the coprocessor.
|
||||
|
||||
To use coprocessor emulation under \dos go32v1 there is nothing special
|
||||
required, as it is handled automatically.
|
||||
required, as it is handled automatically. (As of version 0.99.10, the
|
||||
go32v1 platform will no longer be supported)
|
||||
|
||||
To use coprocessor emulation under \dos go32v2 you must use the
|
||||
emu387 unit, which contains correct initialization code for the
|
||||
@ -739,40 +842,6 @@ mathematics.
|
||||
This switch is recognised for Turbo Pascal compatibility, but is otherwise
|
||||
ignored.
|
||||
|
||||
\subsection{\var{\$Q} \var{\$OVERFLOWCHECKS}: Overflow checking}
|
||||
The \var{\{\$Q+\}} or \var{\{\$OVERFLOWCHECKS ON\}} directive turns on
|
||||
integer overflow checking. This means that the compiler inserts code
|
||||
to check for overflow when doing computations with integers.
|
||||
When an overflow occurs, the run-time library will print a message
|
||||
\var{Overflow at xxx}, and exit the program with exit code 215.
|
||||
|
||||
\emph{ Remark: } Overflow checking behaviour is not the same as in
|
||||
Turbo Pascal since all arithmetic operations are done via 32-bit
|
||||
values. Furthermore, the Inc() and Dec() standard system procedures
|
||||
\emph{ are } checked for overflow in \fpc, while in Turbo Pascal they
|
||||
are not.
|
||||
|
||||
Using the \var{\{\$Q-\}} switch switches off the overflow checking code
|
||||
generation.
|
||||
|
||||
The generation of overflow checking code can also be controlled
|
||||
using the \var{-Co} command line compiler option (see \userref).
|
||||
|
||||
\subsection{\var{\$R} or \var{\$RANGECHECKS} : Range checking}
|
||||
By default, the computer doesn't generate code to check the ranges of array
|
||||
indices, enumeration types, subrange types, etc. Specifying the
|
||||
\var{\{\$R+\}} switch tells the computer to generate code to check these
|
||||
indices. If, at run-time, an index or enumeration type is specified that is
|
||||
out of the declared range of the compiler, then a run-time error is
|
||||
generated, and the program exits with exit code 201.
|
||||
|
||||
The \var{\{\$RANGECHECKS OFF\}} switch tells the compiler not to generate range checking
|
||||
code. This may result in faulty program behaviour, but no run-time errors
|
||||
will be generated.
|
||||
|
||||
{\em Remark: } Range checking for sets and enumerations are not yet fully
|
||||
implemented.
|
||||
|
||||
\subsection{\var{\$S} : Stack checking}
|
||||
The \var{\{\$S+\}} directive tells the compiler to generate stack checking
|
||||
code. This generates code to check if a stack overflow occurred, i.e. to see
|
||||
@ -785,39 +854,23 @@ Specifying \var{\{\$S-\}} will turn generation of stack-checking code off.
|
||||
The command-line compiler switch \var{-Ct} has the same effect as the
|
||||
\var{\{\$S+\}} directive.
|
||||
|
||||
\subsection{\var{\$T} or \var{\$TYPEDADDRESS} : Typed address operator (@)}
|
||||
|
||||
In the \var{\{\$T+\}} or \var{\{\$TYPEDADDRESS ON\}} state the @ operator,
|
||||
when applied to a variable, returns a result of type \var{\^{}T}, if the
|
||||
type of the variable is \var{T}. In the \var{\{\$T-\}} state, the result is
|
||||
always an untyped pointer, which is assignment compatible with all other
|
||||
pointer types.
|
||||
\subsection{\var{\$W} or \var{\$STACKFRAMES} : Generate stackframes}
|
||||
|
||||
\subsection{\var{\$X} or \var{\$EXTENDEDSYNTAX} : Extended syntax}
|
||||
Extended syntax allows you to drop the result of a function. This means that
|
||||
you can use a function call as if it were a procedure. Standard this feature
|
||||
is on. You can switch it off using the \var{\{\$X-\}} or
|
||||
\var{\{\$EXTENDEDSYNTAX OFF\}}directive.
|
||||
The \var{\{\$W\}} switch directove controls the generation of stackframes.
|
||||
In the on state (\var{\{\$STACKFRAMES ON\}}), the compiler will generate a
|
||||
stackframe for every procedure or function.
|
||||
|
||||
The following, for instance, will not compile :
|
||||
\begin{verbatim}
|
||||
function Func (var Arg : sometype) : longint;
|
||||
begin
|
||||
... { declaration of Func }
|
||||
end;
|
||||
|
||||
...
|
||||
|
||||
{$X-}
|
||||
Func (A);
|
||||
\end{verbatim}
|
||||
The reason this construct is supported is that you may wish to call a
|
||||
function for certain side-effects it has, but you don't need the function
|
||||
result. In this case you don't need to assign the function result, saving
|
||||
you an extra variable.
|
||||
|
||||
The command-line compiler switch \var{-Sa1} has the same effect as the
|
||||
\var{\{\$X+\}} directive.
|
||||
In the off state, the compiler will omit the generation of a stackframe if
|
||||
the following conditions are satisfied:
|
||||
\begin{itemize}
|
||||
\item The procedure has no parameters.
|
||||
\item The procedure has no local variables.
|
||||
\item If the procedure is not an \var{assembler} procedure, it must not have
|
||||
a \var{asm ... end;} block.
|
||||
\item it is not a constuctor or desctructor.
|
||||
\end{itemize}
|
||||
If these conditions are satisfied, the stack frame will be omitted.
|
||||
|
||||
\subsection{\var{\$Y} or \var{\$REFERENCEINFO} : Insert Browser information}
|
||||
|
||||
@ -1524,7 +1577,6 @@ More about this can be found in \seec{Linking} on linking.
|
||||
|
||||
|
||||
\subsection{ Ix86 calling conventions }
|
||||
|
||||
Standard entry code for procedures and functions is as follows on the
|
||||
x86 architecture:
|
||||
\begin{verbatim}
|
||||
@ -1541,7 +1593,7 @@ The generated exit sequence for procedure and functions looks as follows:
|
||||
Where \var{xx} is the total size of the pushed parameters.
|
||||
|
||||
To have more information on function return values take a look at the
|
||||
\seec{RegConvs} section.
|
||||
\sees{RegConvs} section.
|
||||
|
||||
|
||||
\subsection{ M680x0 calling conventions }
|
||||
@ -1564,7 +1616,7 @@ The generated exit sequence for procedure and functions looks as follows:
|
||||
Where \var{xx} is the total size of the pushed parameters.
|
||||
|
||||
To have more information on function return values take a look at the
|
||||
\seec{RegConvs} section.
|
||||
\sees{RegConvs} section.
|
||||
|
||||
|
||||
|
||||
@ -1634,9 +1686,7 @@ However, there are times that you want to C libraries, or to external
|
||||
object files that are generated using a C compiler (or even another pascal
|
||||
compiler). The \fpc compiler can generate calls to a C function,
|
||||
and can generate functions that can be called from C (exported functions).
|
||||
However, these exported functions cannot be called from
|
||||
inside Pascal anymore. More on these calling conventions can be found in
|
||||
\sees{Calling}.
|
||||
More on these calling conventions can be found in \sees{Calling}.
|
||||
|
||||
In general, there are 2 things you must do to use a function that resides in
|
||||
an external library or object file:
|
||||
@ -1646,16 +1696,21 @@ want to use.
|
||||
\item You must tell the compiler where the function resides, i.e. in what
|
||||
object file or what library, so the compiler can link the necessary code in.
|
||||
\end{enumerate}
|
||||
The same holds for variables. To access a variable that resides in an
|
||||
external object file, you ust declare it, and tell the compiler where to
|
||||
find it.
|
||||
The following sections attempt to explain how to do this.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Declaring an external function or procedure
|
||||
\section{Declaring an external function or procedure}
|
||||
\label{se:ExternalDeclaration}
|
||||
\section{Using external functions or procedures}
|
||||
\label{se:ExternalFunction}
|
||||
|
||||
The first step in using external code blocks is declaring the function you
|
||||
want to use. \fpc supports Delphi syntax, i.e. you must use the
|
||||
\var{external} directive.
|
||||
\var{external} directive. The \var{external} directive replaces, in effect,
|
||||
the code block of the function. As such, It cannot be used in an interface
|
||||
section of a unit, but must always reside in the implementation section.
|
||||
|
||||
There exist four variants of the external direcive :
|
||||
\begin{enumerate}
|
||||
@ -1722,19 +1777,95 @@ This method is equivalent to the following statement:
|
||||
\begin{verbatim}
|
||||
Procedure ProcName (Args : TPRocArgs); cdecl; external;
|
||||
\end{verbatim}
|
||||
However, the \var{[ C ]} directive is no longer supoerted as of version
|
||||
0.99.5 of \fpc, therefore you should use the
|
||||
\var{external} directive, with the \var{cdecl} directive, if needed.
|
||||
However, the \var{[ C ]} directive is no longer supported as of version
|
||||
0.99.5 of \fpc, therefore you should use the \var{external} directive,
|
||||
with the \var{cdecl} directive, if needed.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Declaring an external variabl
|
||||
\section{Using external variables}
|
||||
\label{se:ExternalVars}
|
||||
|
||||
Some libaries or code blocks have variables which they export. You can access
|
||||
these variables much in the same way as external functions. To access an
|
||||
external variable, you declare it as follows:
|
||||
|
||||
\begin{verbatim}
|
||||
Var
|
||||
MyVar : MyType; external name 'varname';
|
||||
\end{verbatim}
|
||||
The effect of this declaration is twofold:
|
||||
\begin{enumerate}
|
||||
\item No space is allocated for this variable.
|
||||
\item The name of the variable used in the assebler code is \var{varname}.
|
||||
This is a case sensitive name, so you must be careful.
|
||||
\end{enumerate}
|
||||
The variable will be
|
||||
accessible with it's declared name, i.e. \var{MyVar} in this case.
|
||||
|
||||
A second possibility is the declaration:
|
||||
\begin{verbatim}
|
||||
Var
|
||||
varname : MyType; cvar; external;
|
||||
\end{verbatim}
|
||||
The effect of this declaration is twofold as in the previous case:
|
||||
\begin{enumerate}
|
||||
\item The \var{external} modifier ensures that no space is allocated for
|
||||
this variable.
|
||||
\item The \var{cvar} modifier tells the compiler that the name of the
|
||||
variable used in the assebler code is exactly as specified in the
|
||||
declaration. This is a case sensitive name, so you must be careful.
|
||||
\end{enumerate}
|
||||
In this case, you access the variable with it's C name, but case
|
||||
insensitive. The first possibility allows you to change the name of the
|
||||
external variable for internal use.
|
||||
|
||||
In order to be able to compile such statements, the compiler switch \var{-Sv}
|
||||
must be used.
|
||||
|
||||
As an example, let's look at the following C file (in \file{extvar.c}):
|
||||
\begin{verbatim}
|
||||
/*
|
||||
Declare a variable, allocate storage
|
||||
*/
|
||||
int extvar = 12;
|
||||
\end{verbatim}
|
||||
And the following program (in \file{extdemo.pp}):
|
||||
\begin{verbatim}
|
||||
Program ExtDemo;
|
||||
|
||||
{$L extvar.o}
|
||||
|
||||
Var { Case sensitive declaration !! }
|
||||
extvar : longint; cvar;external;
|
||||
I : longint; external name 'extvar';
|
||||
begin
|
||||
{ Extvar can be used case insensitive !! }
|
||||
Writeln ('Variable ''extvar'' has value : ',ExtVar);
|
||||
Writeln ('Variable ''I'' has value : ',i);
|
||||
end.
|
||||
\end{verbatim}
|
||||
Compiling the C file, and the pascal program:
|
||||
\begin{verbatim}
|
||||
gcc -c -o extvar.o extvar.c
|
||||
ppc386 -Sv extdemo
|
||||
\end{verbatim}
|
||||
Will produce a program \file{extdemo} which will print
|
||||
\begin{verbatim}
|
||||
Variable 'extvar' has value : 12
|
||||
Variable 'I' has value : 12
|
||||
\end{verbatim}
|
||||
on your screen.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Linking an object file in your program
|
||||
\section{Linking to an object file}
|
||||
\label{se:LinkIn}
|
||||
|
||||
Having declared the external function that resides in an object file,
|
||||
Having declared the external function or variable that resides in an object file,
|
||||
you can use it as if it was defined in your own program or unit.
|
||||
To produce an executable, you must still link the object file in.
|
||||
This can be done with the \var{\{\$L 'file.o'\}} directive.
|
||||
This can be done with the \var{\{\$L file.o\}} directive.
|
||||
|
||||
This will cause the linker to link in the object file \file{file.o}. On
|
||||
\linux systems, this filename is case sensitive. Under \dos, case isn't
|
||||
@ -1790,7 +1921,7 @@ end.
|
||||
With just two commands, this can be made into a program :
|
||||
\begin{verbatim}
|
||||
as -o fib.o fib.s
|
||||
pp fibo.pp
|
||||
ppc386 fibo.pp
|
||||
\end{verbatim}
|
||||
This example supposes that you have your assembler routine in \file{fib.s},
|
||||
and your Pascal program in \file{fibo.pp}.
|
||||
@ -1801,16 +1932,19 @@ and your Pascal program in \file{fibo.pp}.
|
||||
\label{se:LinkOut}
|
||||
|
||||
To link your program to a library, the procedure depends on how you declared
|
||||
the external procedure. If you used thediffers a little from the
|
||||
procedure when you link in an object file. although the declaration step
|
||||
remains the same (see \ref{se:ExternalDeclaration} on how to do that).
|
||||
the external procedure.
|
||||
%If you used thediffers a little from the
|
||||
%procedure when you link in an object file. although the declaration step
|
||||
%remains the same (see \ref{se:ExternalFunction} on how to do that).
|
||||
|
||||
In case you used the follwing syntax to declare your procedure:
|
||||
\begin{verbatim}
|
||||
Procedure ProcName (Args : TPRocArgs); external 'Name';
|
||||
\end{verbatim}
|
||||
You don't need to take additional steps to link your file in, the compiler
|
||||
will do all that is needed for you.
|
||||
will do all that is needed for you. On \windowsnt it will link to
|
||||
\file{Name.dll}, on \linux your program will be linked to library
|
||||
\file{libname}, which can be a static or dynamic library.
|
||||
|
||||
In case you used
|
||||
\begin{verbatim}
|
||||
@ -1851,7 +1985,7 @@ end.
|
||||
\end{verbatim}
|
||||
This program can be compiled with :
|
||||
\begin{verbatim}
|
||||
pp prlen.pp
|
||||
ppc386 prlen.pp
|
||||
\end{verbatim}
|
||||
Supposing, of course, that the program source resides in \file{prlen.pp}.
|
||||
|
||||
@ -1860,29 +1994,55 @@ arguments in C. Pascal doesn't support this feature of C.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Making a shared library
|
||||
\section{Making a shared library}
|
||||
\section{Making libraries}
|
||||
\label{se:SharedLib}
|
||||
|
||||
\fpc supports making shared libraries in a straightforward and easy manner.
|
||||
\fpc supports making shared or static libraries in a straightforward and
|
||||
easy manner.
|
||||
If you want to make libraries for other \fpc programmers, you just need to
|
||||
provide a command line switch. If you want C programmers to be able to use
|
||||
your code as well, you will need to adapt your code a little. This process
|
||||
is described first.
|
||||
|
||||
% Adapting your code
|
||||
\subsection{Adapting your code}
|
||||
% Exporting functions.
|
||||
\subsection{Exporting functions}
|
||||
|
||||
When exporting functions from a library, there are 2 things you must take in
|
||||
account:
|
||||
|
||||
\begin{enumerate}
|
||||
\item Calling conventions.
|
||||
\item Naming scheme.
|
||||
\end{enumerate}
|
||||
The calling conventions are controlled by the modifiers \var{cdecl},
|
||||
\var{popstack}, \var{pascal}, \var{stdcall}. See \sees{Calling} for more
|
||||
information on the different kinds of calling scheme.
|
||||
|
||||
The naming conventions can be controlled by 3 modifiers:
|
||||
\begin{description}
|
||||
\item [cdecl:\ ] A function that has a \var{cdecl} modifier, will used
|
||||
with C calling conventions, that is, the caller clears the stack. Also
|
||||
the mangled name will be the name {\em exactly} as in the declaration.
|
||||
\var{cdecl} is part of the function declaration, and hence must be present
|
||||
both in the interface and implementation section of a unit.
|
||||
|
||||
\item [export:\ ] A function that has an export modifier, uses also the
|
||||
exact declaration name as its mangled name. Under \windowsnt and \ostwo,
|
||||
this modifier signals a function that is exported from a DLL.
|
||||
The calling conventions used by a \var{export} procedure depend on the OS.
|
||||
this keyword can be used only in the implementation section.
|
||||
\item [Alias: ] The \var{alias} modifier can be used to give a supplementary
|
||||
assembler name to your function. This doesn't modify the calling conventions
|
||||
of the function.
|
||||
\end{description}
|
||||
|
||||
If you want to make your procedures and functions available to C
|
||||
programmers, you can do this very easily. All you need to do is declare the
|
||||
functions and procedures that you want to make available as \var{Export}, as
|
||||
functions and procedures that you want to make available as \var{export}, as
|
||||
follows:
|
||||
\begin{verbatim}
|
||||
Procedure ExportedProcedure ; export;
|
||||
Procedure ExportedProcedure; export;
|
||||
\end{verbatim}
|
||||
This tells the compiler that it shouldn't clear the stack upon exiting the
|
||||
procedure (see \sees{Calling}), thus enabling a C program to call your
|
||||
function. It also means that your Pascal program can't call this function,
|
||||
since it will be using the C calling mechanism.
|
||||
|
||||
{\em Remark :} You can only declare a function as exported in the
|
||||
\var{Implementation} section of a unit. This function may {\em not} appear
|
||||
@ -1892,11 +2052,11 @@ cannot call an exported function, anyway.
|
||||
However, the generated object file will not contain the name of the function
|
||||
as you declared it. The \fpc compiler ''mangles'' the name you give your
|
||||
function. It makes the name all-uppercase, and adds the types of all
|
||||
parameters to it. For \fpc units, this doesn't matter, since the \file{.ppu}
|
||||
unit file contains all information to map your function declaration onto the
|
||||
mangled name in the object file. For a C programmer, who has no access to
|
||||
the \var{.ppu} file, this is not very convenient. That is why \fpc
|
||||
has the \var{Alias} modifier. The \var{Alias} modifier allows you to specify
|
||||
parameters to it. There are cases when you want to provide a mangled name
|
||||
without changing the calling convention. In such cases, you can use the
|
||||
\var{Alias} modifier.
|
||||
|
||||
The \var{Alias} modifier allows you to specify
|
||||
another name (a nickname) for your function or procedure.
|
||||
|
||||
The prototype for an aliased function or procedure is as follows :
|
||||
@ -1906,19 +2066,31 @@ Procedure AliasedProc; [ Alias : 'AliasName'];
|
||||
The procedure \var{AliasedProc} will also be known as \var{AliasName}. Take
|
||||
care, the name you specify is case sensitive (as C is).
|
||||
|
||||
Of course, you want to combine these two features of \fpc, to export a
|
||||
function under a reasonable name; If you want to do that, you must first
|
||||
specify that the function is to be exported, and then only declare an alias:
|
||||
\begin{verbatim}
|
||||
Procedure ExportToCProc; Export; [Alias : 'procname'];
|
||||
\end{verbatim}
|
||||
After that, any C program will be able to use your procedure or function.
|
||||
|
||||
{\em Remark: }
|
||||
If you use in your unit functions that are in other units, or
|
||||
system functions, then the C program will need to link in the object files
|
||||
from the units too.
|
||||
|
||||
% Exporting variable.
|
||||
\subsection{Exporting variables}
|
||||
|
||||
Similarly as when you export functions, you can export variables.
|
||||
when exportig variables, one should only consider the names of the
|
||||
variables. To declare a variable that should be used by a C program,
|
||||
one declares it with the \var{cvar} modifier:
|
||||
\begin{verbatim}
|
||||
Var MyVar : MyTpe; cvar;
|
||||
\end{verbatim}
|
||||
This will tell the compiler that the assembler name of the variable (the one
|
||||
which is used by C programs) should be exactly as specified in the
|
||||
declaration, i.e., case sensitive.
|
||||
|
||||
It is not allowed to declare multiple variables as \var{cvar} in one
|
||||
statement, i.e. the following code will produce an error:
|
||||
\begin{verbatim}
|
||||
var Z1,Z2 : longint;cvar;
|
||||
\end{verbatim}
|
||||
|
||||
% Compiling libraries
|
||||
\subsection {Compiling libraries}
|
||||
|
||||
@ -1929,27 +2101,27 @@ to transform it into a \var{static} or \var{shared} (\var{dynamical}) library.
|
||||
|
||||
You can do this as follows, for a dynamical library:
|
||||
\begin{verbatim}
|
||||
ppc386 -Uld myunit
|
||||
ppc386 -CD myunit
|
||||
\end{verbatim}
|
||||
On \linux this will leave you with a file \file{libmyunit.so}. On \windows
|
||||
and \ostwo, this will leave you with \file{myunit.dll}.
|
||||
|
||||
If you want a static library, you can do
|
||||
\begin{verbatim}
|
||||
ppc386 -Uls myunit
|
||||
ppc386 -CS myunit
|
||||
\end{verbatim}
|
||||
This will leave you with \file{libmyunit.a} and a file \file{myunit.ppl}.
|
||||
The \file{myunit.ppl} is the unit file needed by the \fpc compiler.
|
||||
The extension \file{.ppl} means that the file describes a unit that resides
|
||||
in a library.
|
||||
This will leave you with \file{libmyunit.a} and a file \file{myunit.ppu}.
|
||||
The \file{myunit.ppu} is the unit file needed by the \fpc compiler.
|
||||
|
||||
The resulting files are then libraries. To make static libraries, you need
|
||||
the \file{ranlib} or \var{ar} program on your system. It is standard on any
|
||||
\linux system, and is provided with the \file{GCC} compiler under \dos.
|
||||
For the dos distribution, a copy of ar is included in the file
|
||||
\file{gnuutils.zip}.
|
||||
|
||||
{\em BEWARE:} This command doesn't include anything but the current unit in
|
||||
thelibrary. Other units are left out, so if you use code from other units,
|
||||
you must dpley them together with your library.
|
||||
the library. Other units are left out, so if you use code from other units,
|
||||
you must deploy them together with your library.
|
||||
|
||||
% Moving units
|
||||
\subsection{Moving units into a library}
|
||||
@ -1957,7 +2129,7 @@ You can put multiple units into a library with the \var{ppumove} command, as
|
||||
follows:
|
||||
|
||||
\begin{verbatim}
|
||||
ppumove unit1 unit2 unit3 name
|
||||
ppumove -e ppl -o name unit1 unit2 unit3
|
||||
\end{verbatim}
|
||||
This will move 3 units in 1 library (called \file{libname.so} on linux,
|
||||
\file{name.dll} on \windows) and it will create 3 files \file{unit1.ppl},
|
||||
@ -1972,13 +2144,74 @@ libraries. It is provided with the compiler.
|
||||
|
||||
When you compile a program or unit, the compiler will by
|
||||
default always look for \file{.ppl} files. If it doesn't find one, it will
|
||||
look for a \file{.ppu} file. You can disable this behaviour by
|
||||
specifying the \var{-Cs} switch. This tells the compiler to make a static
|
||||
binary, and refrains it from looking for units which reside in a library.
|
||||
look for a \file{.ppu} file.
|
||||
|
||||
You can tell the compiler only to use dynamic libraries by specifying
|
||||
the \var{-Cd} switch; the compiler will then only look for \var{.ppl} files,
|
||||
and will give an error if it doesn't find one.
|
||||
To be able to differentiate between units that have been compiled as static
|
||||
or dynamic libraries, there are 2 switches:
|
||||
|
||||
\begin{description}
|
||||
\item [-XD:\ ] This will define the symbol \var{FPC\_LINK\_DYNAMIC}
|
||||
\item [-XS:\ ] This will define the symbol \var{FPC\_LINK\_STATIC}
|
||||
\end{description}
|
||||
Definition of one symbol will automatically undefine the other.
|
||||
|
||||
These two switches can be used in conjunction with the configuration file
|
||||
\file{ppc386.cfg}. The existence of one of these symbols can be used to
|
||||
decide which unit search path to set. For example:
|
||||
\begin{verbatim}
|
||||
# Set unit paths
|
||||
|
||||
#IFDEF FPC_LINK_STATIC
|
||||
-Up/usr/lib/fpc/linuxunits/staticunits
|
||||
#ENDIF
|
||||
#IFDEF FPC_LINK_DYNAMIC
|
||||
-Up/usr/lib/fpc/linuxunits/sharedunits
|
||||
#ENDIF
|
||||
\end{verbatim}
|
||||
With such a configuration file, the compiler will look for it's units in
|
||||
different directories, depending on whether \var{-XD} or \var{-XS} is used.
|
||||
|
||||
\section{Using smart linking}
|
||||
\label{se:SmartLinking}
|
||||
|
||||
You can compile your units using smart linking. When you use smartl linking,
|
||||
the compiler creates a series of code blocks that are as small as possible,
|
||||
i.e. a code block will contain only the code for one procedure or function.
|
||||
|
||||
When you compile a program that uses a smart-linked unit, the compiler will
|
||||
only link in the code that you actually need, and will leave out all other
|
||||
code. This will result in a smaller binary, which is loaded in memory
|
||||
faster, thus speeding up execution.
|
||||
|
||||
To enable smartlinking, one can give the smartlink option on the command
|
||||
line : \var{-Cx}, or one can put the \var{\{\$SMARTLINK ON\}} directive in
|
||||
the unit file:
|
||||
\begin{verbatim}
|
||||
Unit Testunit
|
||||
|
||||
{SMARTLINK ON}
|
||||
Interface
|
||||
...
|
||||
\end{verbatim}
|
||||
Smartlinking will slow down the compilation process, expecially for large
|
||||
units.
|
||||
|
||||
When a unit \file{foo.pp} is smartlinked, the name of the codefile is
|
||||
changed to \file{libfoo.a}.
|
||||
|
||||
Technically speaking, the compiler makes small assembler files for each
|
||||
procedure and function in the unit, as well as for all global defined
|
||||
variables (whether they're in the interface section or not). It then
|
||||
assembles all these small files, and uses \file{ar} to collect the resulting
|
||||
object fioles in one archive.
|
||||
|
||||
Smartlinking and the creation of shared (or dynamic) libraries are mutually
|
||||
exclusive, that is, if you turn on smartlinking, then the creation of shared
|
||||
libraries is turned of. The creation of static libraries is still possible.
|
||||
The reason for this is that it has little sense in making a smarlinked
|
||||
dynamica library. The whole shared library is loaded into memory anyway by
|
||||
the dynamic linker (or \windowsnt), so there would be no gain in size by
|
||||
making it smartinked.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Objects
|
||||
@ -2069,7 +2302,8 @@ what is generated when you compile a unit or a program.
|
||||
\label{se:Units}
|
||||
When you compile a unit, the \fpc compiler generates 2 files :
|
||||
\begin{enumerate}
|
||||
\item A unit description file (with extension \file{.ppu}).
|
||||
\item A unit description file (with extension \file{.ppu}, or \file{.ppw on
|
||||
\windowsnt}).
|
||||
\item An assembly language file (with extension \file{.s}).
|
||||
\end{enumerate}
|
||||
The assembly language file contains the actual source code for the
|
||||
@ -2081,7 +2315,8 @@ units and your program, to form an executable.
|
||||
By default (compiler version 0.9.4 and up), the assembly file is removed
|
||||
after it has been compiled. Only in the case of the \var{-s} command-line
|
||||
option, the assembly file must be left on disk, so the assembler can be
|
||||
called later.
|
||||
called later. You can disable the erasing of the assembler file with the
|
||||
\var{-a} switch.
|
||||
|
||||
The unit file contains all the information the compiler needs to use the
|
||||
unit:
|
||||
@ -2671,9 +2906,9 @@ were evaluted.
|
||||
\subsection{ Constant set inlining }
|
||||
|
||||
Using the \var{in} operator is always more efficient then using the
|
||||
equivalent <>, =, <=, >=, < and > operators. This is because
|
||||
range comparisons can be done more easily with \var{in} then with
|
||||
normal comparison operators.
|
||||
equivalent \verb|<>|, \verb|=|, \verb|<=|, \verb|>=|, \verb|<| and \verb|>|
|
||||
operators. This is because range comparisons can be done more easily with
|
||||
\var{in} then with normal comparison operators.
|
||||
|
||||
\subsection{ Small sets }
|
||||
|
||||
@ -2731,6 +2966,9 @@ look at the reference manual under the \var{record} heading.
|
||||
This feature removes all unreferenced code in the final executable
|
||||
file, making the executable file much smaller.
|
||||
|
||||
Smart linking is switched on with the \var{-Cx} command-line switch, or
|
||||
using the \var{\{\$SMARTLINK ON\}} global directive.
|
||||
|
||||
\emph{ Remark: } Smart linking was implemented starting with
|
||||
version 0.99.6 of \fpc.
|
||||
|
||||
@ -2752,33 +2990,35 @@ case statement execute faster.
|
||||
|
||||
\subsection{ Stack frame omission }
|
||||
|
||||
When using the \var{-Ox} switch, under certain specific conditions,
|
||||
the stack frame (entry and exit code for the routine) will be omitted, and
|
||||
Under certain specific conditions, the stack frame (entry and exit code
|
||||
for the routine, see section \ref{se:Calling}) will be omitted, and
|
||||
the variable will directly be accessed via the stack pointer.
|
||||
|
||||
Conditions for omission of the stack frame :
|
||||
|
||||
\begin{itemize}
|
||||
\item Routine does not call other routines
|
||||
\item Routine does not contain assembler statements
|
||||
\item Routine is not declared using the \var{Interrupt} directive
|
||||
\item Routine is not a constructor or destructor
|
||||
\item The function has no parameters nor local variables.
|
||||
\item Routine does not call other routines.
|
||||
\item Routine does not contain assembler statements. However,
|
||||
a \var{assembler} routine may omit it's stack frame.
|
||||
\item Routine is not declared using the \var{Interrupt} directive.
|
||||
\item Routine is not a constructor or destructor.
|
||||
\end{itemize}
|
||||
|
||||
\subsection{ Register variables }
|
||||
|
||||
When using the \var{-Ox} switch, local variables or parameters
|
||||
When using the \var{-Or} switch, local variables or parameters
|
||||
which are used very often will be moved to registers for faster
|
||||
access.
|
||||
|
||||
\emph{ Remark: } Register variable allocation is currently
|
||||
broken and should not be used.
|
||||
an experimental feature, and should be used with caution.
|
||||
|
||||
\subsection{ Intel x86 specific }
|
||||
|
||||
Here follows a listing of the opimizing techniques used in the compiler:
|
||||
\begin{enumerate}
|
||||
\item When optimizing for a specific Processor (\var{-O3, -O4, -O5 -O6},
|
||||
\item When optimizing for a specific Processor (\var{-Op1, -Op2, -Op3},
|
||||
the following is done:
|
||||
\begin{itemize}
|
||||
\item In \var{case} statements, a check is done whether a jump table
|
||||
@ -2787,18 +3027,18 @@ or a sequence of conditional jumps should be used for optimal performance.
|
||||
\var{movzbl (\%ebp), \%eax} on PentiumPro and PII systems will be changed
|
||||
into \var{xorl \%eax,\%eax; movb (\%ebp),\%al } for lesser systems.
|
||||
\end{itemize}
|
||||
Cyrix \var{6x86} processor owners should optimize with \var{-O4} instead of
|
||||
\var{-O5}, because \var{-O5} leads to larger code, and thus to smaller
|
||||
Cyrix \var{6x86} processor owners should optimize with \var{-Op3} instead of
|
||||
\var{-Op2}, because \var{-Op2} leads to larger code, and thus to smaller
|
||||
speed, according to the Cyrix developers FAQ.
|
||||
\item When optimizing for speed (\var{-OG}) or size (\var{-Og}), a choice is
|
||||
\item When optimizing for speed (\var{-OG}, the default) or size (\var{-Og}), a choice is
|
||||
made between using shorter instructions (for size) such as \var{enter \$4},
|
||||
or longer instructions \var{subl \$4,\%esp} for speed. When smaller size is
|
||||
requested, things aren't aligned on 4-byte boundaries. When speed is
|
||||
requested, things are aligned on 4-byte boundaries as much as possible.
|
||||
\item Simple optimization (\var{-Oa}) makes sure the peephole optimizer is
|
||||
used, as well as the reloading optimizer.
|
||||
\item Uncertain optimizations (\var{-Oz}): With this switch, the reloading
|
||||
optimizer (enabled with \var{-Oa}) can be forced into making uncertain
|
||||
\item Uncertain optimizations (\var{-Ou}): With this switch, the reloading
|
||||
optimizer can be forced into making uncertain
|
||||
optimizations.
|
||||
|
||||
You can enable uncertain optimizations only in certain cases,
|
||||
@ -2903,6 +3143,86 @@ runtime library call will be generated
|
||||
runtime library call will be generated
|
||||
\end{itemize}
|
||||
|
||||
\section{Optimization switches}
|
||||
This is where the various optimizing switches and their actions are
|
||||
described, grouped per switch.
|
||||
|
||||
\begin{description}
|
||||
\item [-On:\ ] with n = 1..3: these switches activate the optimizer.
|
||||
A higher level automatically includes all lower levels.
|
||||
\begin{itemize}
|
||||
\item Level 1 (\var{-O1}) activates the peephole optimizer
|
||||
(common instruction sequences are replaced by faster equivalents).
|
||||
\item Level 2 (\var{-O2}) enables the assembler data flow analyzer,
|
||||
which allows the common subexpression elimination procedure to
|
||||
remove unnecessary reloads of registers with values they already contain.
|
||||
\item Level 3 (\var{-O3}) enables uncertain optimizations. For more info, see -Ou.
|
||||
\end{itemize}
|
||||
\item[-OG:\ ]
|
||||
This causes the code generator (and optimizer, IF activated), to favor
|
||||
faster, but code-wise larger, instruction sequences (such as
|
||||
"\verb|subl $4,%esp|") instead of slower, smaller instructions
|
||||
("\verb|enter $4|"). This is the default setting.
|
||||
|
||||
\item[-Og:\ ] This one is exactly the reverse of -OG, and as such these
|
||||
switches are mutually exclusive: enabling one will disable the other.
|
||||
|
||||
\item[-Or:\ ] this setting (once it's fixed) causes the code generator to
|
||||
check which variables are used most, so it can keep those in a register.
|
||||
|
||||
\item[-Opn:\ ] with n = 1..3: setting the target processor does NOT
|
||||
activate the optimizer. It merely influences the code generator and,
|
||||
if activated, the optimizer:
|
||||
\begin{itemize}
|
||||
\item During the code generation process, this setting is used to
|
||||
decide whether a jump table or a sequence of successive jumps provides
|
||||
the best performance in a case statement.
|
||||
\item The peephole optimizer takes a number of decisions based on this
|
||||
setting, for example it translates certain complex instructions, such
|
||||
as
|
||||
\begin{verbatim}
|
||||
movzbl (mem), %eax|
|
||||
\end{verbatim}
|
||||
to a combination of simpler instructions
|
||||
\begin{verbatim}
|
||||
xorl %eax, %eax
|
||||
movb (mem), %al
|
||||
\end{verbatim}
|
||||
for the Pentium.
|
||||
\end{itemize}
|
||||
\item[-Ou:\ ] This enables uncertain optimizations. You cannot use these
|
||||
always, however. The previous section explains when they can be used, and
|
||||
when they cannot be used.
|
||||
\end{description}
|
||||
|
||||
\section{Tips to get faster code}
|
||||
Here some general tips for getting better code are presented. They are
|
||||
mainly concerned with coding style.
|
||||
|
||||
\begin{itemize}
|
||||
\item Find a better algorithm. No matter how muck you and the compiler
|
||||
tweak the code, a quicksort will (almost) always outperform a bubble
|
||||
sort, for example.
|
||||
|
||||
\item Use variables of the native size of the processor you're writing
|
||||
for. For the 80x86 and compatibles, this is 32 bit, so you're best of
|
||||
using longint and cardinal variables.
|
||||
|
||||
\item Turn on the optimizer.
|
||||
|
||||
\item If you are allocating and disposing a lot of small memory blocks,
|
||||
check out the heapblocks variable. (\refref)
|
||||
|
||||
\item Profile your code (see the -pg switch) to find out where the
|
||||
bottlenecks are. If you want, you can rewrite those parts in assembler.
|
||||
You can take the code generated by the compiler as a starting point. When
|
||||
given the \var{-a} command-line switch, the compiler will not erase the
|
||||
assembler file at the end of the assembly process, so you can study the
|
||||
assembler file.
|
||||
|
||||
{\em Note:} code blocks which contain an assembler block, are not processed
|
||||
at all by the optimizer at this time.
|
||||
\end{itemize}
|
||||
|
||||
\section{ Floating point }
|
||||
|
||||
|
501
docs/ref.tex
501
docs/ref.tex
@ -27,6 +27,9 @@
|
||||
\usepackage{html}
|
||||
\latex{\usepackage{fpc}}
|
||||
\html{\input{fpc-html.tex}}
|
||||
\usepackage{fancyheadings}
|
||||
\pagestyle{fancy}
|
||||
\renewcommand{\chaptermark}[1]{\markboth{#1}{}}
|
||||
\makeindex
|
||||
%
|
||||
% start of document.
|
||||
@ -123,14 +126,16 @@ The true Turbo Pascal compatible types are listed in
|
||||
\begin{FPCltable}{lccr}{Supported Real types}{Reals}
|
||||
Type & Range & Significant digits & Size\footnote{In Turbo Pascal.} \\ \hline
|
||||
Single & 1.5E-45 .. 3.4E38 & 7-8 & 4 \\
|
||||
Real & 5.0E-324 .. 1.7E308 & 15-16 & 8 \\
|
||||
Double & 5.0E-324 .. 1.7E308 & 15-16 & 8 \\
|
||||
Extended & 1.9E-4951 .. 1.1E4932 & 19-20 & 10\\
|
||||
%Comp\footnote{\var{Comp} only holds integer values.} & -2E64+1 .. 2E63-1 & 19-20 & 8 \\
|
||||
Comp\footnote{\var{Comp} only holds integer values.} & -2E64+1 .. 2E63-1 & 19-20 & 8 \\
|
||||
\end{FPCltable}
|
||||
|
||||
Until version 0.9.1 of the compiler, all the real types are mapped to type
|
||||
\var{Double}, meaning that they all have size 8. The \seef{SizeOf} function
|
||||
is your friend here.
|
||||
is your friend here. The \var{Real} type of turbo pascal is automatically
|
||||
mappe to Double.
|
||||
|
||||
\subsection{Character types}
|
||||
\subsubsection{Char}
|
||||
@ -355,7 +360,22 @@ begin
|
||||
end.
|
||||
\end{verbatim}
|
||||
\end{CodEx}
|
||||
\fpc doesn't support pointer arithmetic as C does, however.
|
||||
\fpc supports pointer arithmetic as C does. This means that, if \var{P} is a
|
||||
typed pointer, the instructions
|
||||
\begin{verbatim}
|
||||
Inc(P);
|
||||
Dec(P);
|
||||
\end{verbatim}
|
||||
Will increase, respecively descrease the address the pointer points to
|
||||
with the size of the type \var{P} is a pointer to. For example
|
||||
\begin{verbatim}
|
||||
Var P : ^Longint;
|
||||
|
||||
...
|
||||
|
||||
Inc (p);
|
||||
\end{verbatim}
|
||||
will increase \var{P} with 4.
|
||||
|
||||
\subsection{Procedural types}
|
||||
\fpc has support for procedural types, although it differs from the Turbo
|
||||
@ -384,7 +404,29 @@ Func:=@Pi;
|
||||
\end{verbatim}
|
||||
From this example, the difference with Turbo Pascal is clear: In Turbo
|
||||
Pascal it isn't necessary to use the address operator (\var{@})
|
||||
when assigning a procedural type variable, whereas in \fpc it is required.
|
||||
when assigning a procedural type variable, whereas in \fpc it is required
|
||||
(unless you use the \var{-So} switch)
|
||||
|
||||
Remark that the modifiers concerning the calling conventions (\var{cdecl},
|
||||
\var{pascal}, \var{stdcall} and \var{popstack} stick to the declaration;
|
||||
i.e. the following code would give an error:
|
||||
\begin{verbatim}
|
||||
Type TOneArgCcall = Procedure (Var X : integer);cdecl;
|
||||
|
||||
var proc : TOneArgCcall;
|
||||
|
||||
Procedure printit (Var X : Integer);
|
||||
|
||||
begin
|
||||
writeln (x);
|
||||
end;
|
||||
|
||||
begin
|
||||
P:=@printit;
|
||||
end.
|
||||
\end{verbatim}
|
||||
Because the \var{TOneArgCcall} type is a procedure that uses the cdecl
|
||||
calling convention.
|
||||
|
||||
\subsection{Records}
|
||||
|
||||
@ -508,9 +550,10 @@ Intersection & * \\ \hline
|
||||
You can compare two sets with the \var{<>} and \var{=} operators, but not
|
||||
(yet) with the \var{<} and \var{>} operators.
|
||||
|
||||
From compiler version 0.9.5, the compiler stores small sets (less than 32
|
||||
As of compiler version 0.9.5, the compiler stores small sets (less than 32
|
||||
elements) in a longint, if the type range allows it. This allows for faster
|
||||
processing and decreases program size.
|
||||
processing and decreases program size. Otherwise, sets are stored in 32
|
||||
bytes.
|
||||
|
||||
\subsection{Enumeration types}
|
||||
|
||||
@ -533,10 +576,39 @@ Type
|
||||
\end{verbatim}
|
||||
It is necessary to keep \var{forty} and \var{Thirty} in the correct order.
|
||||
|
||||
{\em Remark :} You cannot use the \var{Pred} and \var{Succ} functions on
|
||||
{\em Remarks :}
|
||||
\begin{enumerate}
|
||||
\item You cannot use the \var{Pred} and \var{Succ} functions on
|
||||
this kind of enumeration types. If you try to do that, you'll get a compiler
|
||||
error.
|
||||
\item Enumeration types are by default stored in 4 bytes. You can change
|
||||
this behaviour with the \var{\{\$PACKENUM \}} compiler directive, which
|
||||
tells the compiler the minimal number of bytes to be used for enumeration
|
||||
types.
|
||||
For instance
|
||||
\begin{verbatim}
|
||||
|
||||
Type
|
||||
LargeEnum = ( BigOne, BigTwo, BigThree );
|
||||
{$PACKENUM 1}
|
||||
SmallEnum = ( one, two, three );
|
||||
|
||||
Var S : SmallEnum;
|
||||
L : LargeEnum;
|
||||
|
||||
begin
|
||||
Writeln ('Small enum : ',Sizeof(S));
|
||||
Writeln ('Large enum : ',SizeOf(L));
|
||||
end.
|
||||
\end{verbatim}
|
||||
will, when run, print the following:
|
||||
\begin{verbatim}
|
||||
Small enum : 1
|
||||
Large enum : 4
|
||||
\end{verbatim}
|
||||
\end{enumerate}
|
||||
More information can be found in the \progref, in the compiler directives
|
||||
section.
|
||||
\section{Constants}
|
||||
|
||||
Just as in Turbo Pascal, \fpc supports both normal and typed constants.
|
||||
@ -613,20 +685,15 @@ Const
|
||||
The order of the fields in a constant record needs to be the same as in the type declaration,
|
||||
otherwise you'll get a compile-time error.
|
||||
|
||||
|
||||
\section{Objects}
|
||||
\fpc supports object oriented programming. In fact, part of the compiler is
|
||||
written using objects. Here we present some technical questions regarding
|
||||
object oriented programming in \fpc.
|
||||
|
||||
\fpc supports 2 programming models for object-oriented programming.
|
||||
You can choose to program object oriented using the Turbo Pascal approach,
|
||||
or you can prefer the Delphi approach.
|
||||
|
||||
\subsection{The Turbo Pascal approach}
|
||||
In the Turbo Pascal approach, Objects should be treated as a special kind of
|
||||
record. The record contains all the fields that are declared in the objects
|
||||
definition, and pointers to the methods that are associated to the objects'
|
||||
type.
|
||||
Objects should be treated as a special kind of record. The record contains
|
||||
all the fields that are declared in the objects definition, and pointers
|
||||
to the methods that are associated to the objects' type.
|
||||
|
||||
An object is declared just as you would declare a record; except that you
|
||||
can now declare procedures and fuctions as of they were part of the record.
|
||||
@ -667,7 +734,25 @@ TObj = Object [(ParentObjectType)]
|
||||
end;
|
||||
\end{verbatim}
|
||||
You can repeat as many \var{private} and \var{public} blocks as you want.
|
||||
\var{Method}s are normal function or procedure declarations.
|
||||
\var{Method}s are normal function or procedure declarations. You cannot put
|
||||
fields after methods in the same block, i.e. the following will generate an
|
||||
error when compiling:
|
||||
\begin{verbatim}
|
||||
Type MyObj = Object
|
||||
Procedure Doit;
|
||||
Field : Longint;
|
||||
end;
|
||||
\end{verbatim}
|
||||
But the following will be accepted:
|
||||
\begin{verbatim}
|
||||
Type MyObj = Object
|
||||
Public
|
||||
Procedure Doit;
|
||||
Private
|
||||
Field : Longint;
|
||||
end;
|
||||
\end{verbatim}
|
||||
because the field is in a different section.
|
||||
|
||||
As can be seen in the prototype object declaration, \fpc supports
|
||||
constructors and destructors. You are responsible for calling the
|
||||
@ -731,11 +816,17 @@ Var PP : Pobj;
|
||||
\end{verbatim}
|
||||
Similarly, the \var{\{\$PACKRECORDS \}} directive acts on objects as well.
|
||||
|
||||
\subsection{The Delphi approach}
|
||||
\section{Classes}
|
||||
In the Delphi approach to Object Oriented Programming, everything revolves
|
||||
around the concept of 'Classes'.
|
||||
A class can be seen as a pointer to an object, or a pointer to a record.
|
||||
around the concept of 'Classes'. A class can be seen as a pointer to an
|
||||
object, or a pointer to a record.
|
||||
|
||||
In order to use objects, it is necessary to put the \file{objpas} unit in the
|
||||
uses clause of your unit or program. This unit contains the basic
|
||||
definitions of \var{TObject} and \var{TClass}, as well as some auxiliary
|
||||
methods for using classes.
|
||||
|
||||
\subsection{Class definitions}
|
||||
The prototype declaration of a class is as follows :
|
||||
\begin{verbatim}
|
||||
TObj = Class [(ParentClassType)]
|
||||
@ -752,15 +843,38 @@ TObj = Class [(ParentClassType)]
|
||||
PrFieldn : PrTypen;
|
||||
PrMethod1;
|
||||
...
|
||||
PrMethodn;]
|
||||
PrMethodn;
|
||||
]
|
||||
[protected
|
||||
PuField1 : PuType1;
|
||||
..
|
||||
Pufield1 : PuTypen;
|
||||
PuMethod1;
|
||||
...
|
||||
PuMethodn;
|
||||
Property1;
|
||||
...
|
||||
Propertyn;
|
||||
[public
|
||||
PuField1 : PuType1;
|
||||
..
|
||||
Pufield1 : PuTypen;
|
||||
PuMethod1;
|
||||
...
|
||||
PuMethodn;]
|
||||
end;
|
||||
PuMethodn;
|
||||
Property1;
|
||||
...
|
||||
Propertyn;]
|
||||
[published
|
||||
PuField1 : PuType1;
|
||||
..
|
||||
Pufield1 : PuTypen;
|
||||
PuMethod1;
|
||||
...
|
||||
PuMethodn;
|
||||
Property1;
|
||||
...
|
||||
Propertyn;]
|
||||
\end{verbatim}
|
||||
You can repeat as many \var{private} and \var{public} blocks as you want.
|
||||
\var{Method}s are normal function or procedure declarations.
|
||||
@ -769,7 +883,23 @@ As you can see, the declaration of a class is almost identical to the
|
||||
declaration of an object. The real difference between objects and classes
|
||||
is in the way they are created;
|
||||
|
||||
Classes must be created using their constructor. Remember that A class is a
|
||||
The visibility of the different sections is as follows:
|
||||
\begin{description}
|
||||
\item [Private\ ] All fields and methods that are in a \var{private} block, can
|
||||
only be accessed in the module (i.e. unit) that contains the class definition.
|
||||
They can be accessed from inside the classes' methods or from outside them
|
||||
(e.g. from other classes' methods)
|
||||
\item [Protected\ ] Is the same as \var{Private}, except that the members of
|
||||
a \var{Protected section} are also accessible to descendent types, even if
|
||||
they are implemented in other modules.
|
||||
\item [Public\ ] sections are always accessible.
|
||||
\item [Published\ ] Is the same as a \var{Public} section, but the compiler
|
||||
generates also type information that is needed for automatic streaming of
|
||||
these classes. Fields defined in a \var{published} section must be of class type.
|
||||
Array peroperties cannot be in a \var{published} section.
|
||||
\end{description}
|
||||
|
||||
Classes must be created using their constructor. Remember that a class is a
|
||||
pointer to an object, so when you declare a variable of some class, the
|
||||
compiler just allocates a pointer, not the entire object. The constructor of
|
||||
a class returns a pointer to an initialized instance of the object.
|
||||
@ -781,7 +911,6 @@ So, to initialize an instance of some class, you do the following :
|
||||
|
||||
{\em Remark :}
|
||||
\begin{itemize}
|
||||
\item \fpc doesn't support the concept of properties yet.
|
||||
\item The \var{\{\$Packrecords \}} directive also affects classes.
|
||||
i.e. the alignment in memory of the different fields depends on the
|
||||
value of the \var{\{\$Packrecords \}} directive.
|
||||
@ -790,6 +919,139 @@ This has the same effect as on an object, or record, namely that the
|
||||
elements are aligned on 1-byte boundaries. i.e. as close as possible.
|
||||
\end{itemize}
|
||||
|
||||
\subsection{Properties}
|
||||
|
||||
Classes can contain properties as part of their fields list. A property
|
||||
acts like a normal field, i.e. you can get or set it's value, but allows to redirect the access of the field through
|
||||
functions and procedures. Moreover, properties can be read-only.
|
||||
|
||||
the prototype declaration of a property is
|
||||
\begin{verbatim}
|
||||
property Name : Type [Read ReadSpecifier [write WriteSpecifier]];
|
||||
\end{verbatim}
|
||||
A \var{ReadSpecifier} is either the name of a field that contains the
|
||||
property, or the name of a method function that has the same return type as
|
||||
the property type. In the case of a simple type, this
|
||||
function must not accept an argument.
|
||||
|
||||
A \var{WriteSpecifier} is optional: If there is no write specifier, the
|
||||
property is read-only. A write specifier is either the name of a field, or
|
||||
the name of a method procedure that accepts as a sole argument a variable of
|
||||
the same type as the property. You cannot specify only a write specifier.
|
||||
|
||||
The section (\var{private}, \var{published} in which the specified function or
|
||||
procedure resides is irrelevant. Usually, however, this will be a protected
|
||||
or private method.
|
||||
|
||||
Example:
|
||||
Given the following declaration:
|
||||
\begin{verbatim}
|
||||
Type
|
||||
MyClass = Class
|
||||
Private
|
||||
Field1 : Longint;
|
||||
Field2 : Longint;
|
||||
Field3 : Longint;
|
||||
Procedure Sety (value : Longint);
|
||||
Function Gety : Longint;
|
||||
Function Getz : Longint;
|
||||
Public
|
||||
Property X : Longint Read Field1 write Field2;
|
||||
Property Y : Longint Read GetY Write Sety;
|
||||
Property Z : Longint Read GetZ;
|
||||
end;
|
||||
|
||||
Var MyClass : TMyClass;
|
||||
\end{verbatim}
|
||||
The following are valid statements:
|
||||
\begin{verbatim}
|
||||
Writeln ('X : ',MyClass.X);
|
||||
Writeln ('Y : ',MyClass.Y);
|
||||
Writeln ('Z : ',MyClass.Z);
|
||||
MyClass.X:=0;
|
||||
MyClass.Y:=0;
|
||||
\end{verbatim}
|
||||
But the following would generate an error:
|
||||
\begin{verbatim}
|
||||
MyClass.Z:=0;
|
||||
\end{verbatim}
|
||||
because Z is a read-only property.
|
||||
|
||||
What happens in the above statements is that when a value needs to be read,
|
||||
the compiler inserts a call to the various \var{getNNN} methods of the
|
||||
object, and the result of this call is used. When an assignment is made,
|
||||
the compiler passes the value that must be assigned as a paramater to
|
||||
the various \var{setNNN} methods.
|
||||
|
||||
Because of this mechanism, properties cannot be passed as var arguments to a
|
||||
function or procedure, since there is no known address of the property (at
|
||||
least, not always).
|
||||
|
||||
You can also have array properties. These are properties that accept an
|
||||
index, just as an array. Only now the index doesn't have to be an ordinal
|
||||
type, but can be any type. An array Property is defined as follows:
|
||||
\begin{verbatim}
|
||||
property Name[Index : IndexType]: Type [Read ReadSpecifier [write WriteSpecifier]];
|
||||
\end{verbatim}
|
||||
A \var{ReadSpecifier} is the name method function that has the same return
|
||||
type as the property type. The function must accept as a sole arguent a
|
||||
variable of the same type as the index type. You cannot specify fields as
|
||||
arrar types.
|
||||
|
||||
A \var{WriteSpecifier} is optional: If there is no write specifier, the
|
||||
property is read-only. A write specifier is the name of a method procedure
|
||||
that accepts two arguments: The first argument has the same type as the
|
||||
index, and the second argument is a variable of the same type as the
|
||||
property type. You cannot specify only a write specifier.
|
||||
|
||||
As an example, see the following declaration:
|
||||
\begin{verbatim}
|
||||
Type TIntList = Class
|
||||
Private
|
||||
Function GetInt (I : Longint);
|
||||
Function GetAsString (A : String) : String;
|
||||
Procedure SetInt (I : Longint; Value : longint;);
|
||||
Procedure SetAsString (A : String; Value : String);
|
||||
Public
|
||||
Property Items [i : Longint] : Longint Read GetInt Write SetInt;
|
||||
Property StrItems [S : String] : String Read GetAsString Write SetAsstring;
|
||||
end;
|
||||
|
||||
Var AIntList : TIntList;
|
||||
\end{verbatim}
|
||||
Then the following statements would be valid:
|
||||
\begin{verbatim}
|
||||
AIntList.Items[26]:=1;
|
||||
AIntList.StrItems['twenty-five']:='zero';
|
||||
|
||||
Writeln ('Item 26 : ',AIntList.Items[26]);
|
||||
Writeln ('Item 25 : ',AIntList.StrItems['twenty-five']);
|
||||
\end{verbatim}
|
||||
While the following statements would generate errors:
|
||||
\begin{verbatim}
|
||||
AIntList.Items['twenty-five']:=1;
|
||||
AIntList.StrItems[26]:='zero';
|
||||
\end{verbatim}
|
||||
Because the index types are wrong.
|
||||
|
||||
Array properties can be declared as \var{default} properties. This means that
|
||||
it is not necessary to specifiy the property name when assigning or readin
|
||||
it. If, in the previous example, the definition of the items property would
|
||||
have been
|
||||
\begin{verbatim}
|
||||
Property Items [i : Longint] : Longint Read GetInt Write SetInt; Default;
|
||||
\end{verbatim}
|
||||
Then the assignment
|
||||
\begin{verbatim}
|
||||
AIntList.Items[26]:=1;
|
||||
\end{verbatim}
|
||||
Would be equivalent to the following abbreviation.
|
||||
\begin{verbatim}
|
||||
AIntList[26]:=1;
|
||||
\end{verbatim}
|
||||
You can have only one default property per class, and descendent classes
|
||||
cannot redeclare the default property.
|
||||
|
||||
\section{Statements controlling program flow.}
|
||||
|
||||
\subsection{Assignments}
|
||||
@ -847,30 +1109,6 @@ end;
|
||||
The compiler will generate a \var{Duplicate case label} error when compiling
|
||||
this, because the 3 also appears (implicitly) in the range \var{1..5}
|
||||
|
||||
{\em Remark:} In versions earlier than 0.9.7, there was an incompatibility here
|
||||
with Turbo Pascal. Where in Turbo Pascal you could do the following:
|
||||
\begin{verbatim}
|
||||
case Pivot of
|
||||
...
|
||||
Else
|
||||
begin
|
||||
Statement1
|
||||
Statement2
|
||||
end;
|
||||
\end{verbatim}
|
||||
You needed to do the following in \fpc :
|
||||
\begin{verbatim}
|
||||
case Pivot of
|
||||
...
|
||||
Else
|
||||
begin
|
||||
Statement1
|
||||
Statement2
|
||||
end;
|
||||
end;
|
||||
\end{verbatim}
|
||||
So there's an extra \var{end} keyword at the end. But from version 0.9.7
|
||||
this has been fixed.
|
||||
\subsection{The \var{For..to/downto..do} statement}
|
||||
\fpc supports the \var{For} loop construction. The prototypes are:
|
||||
\begin{verbatim}
|
||||
@ -882,7 +1120,12 @@ For Counter:=Upperbound downto Lowerbound Do Statement;
|
||||
\end{verbatim}
|
||||
\var{Statement} can be a compound statement. In the first case, if
|
||||
\var{Lowerbound} is larger than \var{Upperbound} then \var{Statement} will
|
||||
never be executed.
|
||||
never be executed. \var{Counter} must be an ordinal type, no other types can
|
||||
be used as counters in a loop.
|
||||
|
||||
{\em Remark:} Contrary to ANSI pascal specifications, \fpc first initializes
|
||||
the counter variable, and only then calculates the upper bound.
|
||||
|
||||
\subsection{The \var{Goto} statement}
|
||||
\fpc supports the \var{goto} jump statement. Its prototype is
|
||||
\begin{verbatim}
|
||||
@ -987,6 +1230,159 @@ that are surrounded by the keywords \var{Begin} and \var{End}. The
|
||||
Last statement doesn't need to be followed by a semicolon, although it is
|
||||
allowed.
|
||||
|
||||
\subsection{Exceptions}
|
||||
|
||||
As of version 0.99.7, \fpc supports exceptions. Exceptions provide a
|
||||
convenient way to program error and error-recovery mechanisms, and are
|
||||
closely related to classes.
|
||||
|
||||
Exception support is based on 3 constructs:
|
||||
\begin{description}
|
||||
\item [Raise\ ] statements. To raise an exeption. This is usually done to signal an
|
||||
error condition.
|
||||
\item [Try ... Except\ ] blocks. These block serve to catch exceptions
|
||||
raised within the scope of the block, and to provide exception-recovery
|
||||
code.
|
||||
\item [Try ... Finally\ ] blocks. These block serve to force code to be
|
||||
executed irrespective of an exception occurrence or not. They generally
|
||||
serve to clean up memory or close files in case an exception occurs.
|
||||
code.
|
||||
\end{description}
|
||||
|
||||
The \var{raise} statement is as follows:
|
||||
\begin{verbatim}
|
||||
Raise [ExceptionInstance [at Address]];
|
||||
\end{verbatim}
|
||||
This statement will raise an exception. If specified, \var{ExceptionInstance}
|
||||
must be an initialized instance of a class, which is the raise type. If
|
||||
specified, \var{Address} must be an expression that returns an address.
|
||||
|
||||
If \var{ExceptionInstance} is omitted, then the Current exception is
|
||||
re-raised. This construct can only be used in an exception handling
|
||||
block.
|
||||
|
||||
As an example: The following division checks whether the denominator is
|
||||
zero, and if so, raises an exception of type \var{EDivException}
|
||||
\begin{verbatim}
|
||||
Type EDivException = Class(Exception);
|
||||
|
||||
Function DoDiv (X,Y : Longint) : Integer;
|
||||
|
||||
begin
|
||||
If Y=0 then
|
||||
Raise EDivException.Create ('Division by Zero would occur');
|
||||
Result:=X Div Y;
|
||||
end;
|
||||
\end{verbatim}
|
||||
The class \var{Exception} is defined in the \file{Sysutils} unit of the rtl.
|
||||
|
||||
An exception handling block is of the following form :
|
||||
\begin{verbatim}
|
||||
Try
|
||||
...Statement List...
|
||||
Except
|
||||
[On [E:] ExceptionClass do CompoundStatement;]
|
||||
[ Default exception handler]
|
||||
end;
|
||||
\end{verbatim}
|
||||
If an exception occurs during the execution of the \var{statement list}, the
|
||||
program flow fill be transferred to the except block. There, the type of the
|
||||
exception is checked, and if there is a \var{On ExcType} statement where
|
||||
\var{ExcType} matches the exception object type, or is a parent type of
|
||||
the exception object type, then the statements follwing the corresponding
|
||||
\var{Do} will be executed. The first matching type is used. After the
|
||||
\var{Do} block was executed, the program continues after the \var{End}
|
||||
statement.
|
||||
|
||||
The identifier \var{E} is optional, and declares an exception object. It
|
||||
can be used to manipulate the exception object in the exception handling
|
||||
code. The scope of this declaration is the statement block foillowing the
|
||||
\var{Do} keyword.
|
||||
|
||||
If none of the \var{On} handlers matches the exception object type, then the
|
||||
\var{Default exception handler} is executed. If no such default handler is
|
||||
found, then the exception is automatically re-raised. This process allows
|
||||
to nest \var{try...except} blocks.
|
||||
|
||||
As an example, given the previous declaration of the \var{DoDiv} function,
|
||||
consider the following
|
||||
\begin{verbatim}
|
||||
Try
|
||||
Z:=DoDiv (X,Y);
|
||||
Except
|
||||
On EDivException do Z:=0;
|
||||
end;
|
||||
\end{verbatim}
|
||||
If \var{Y} happens to be zero, then the DoDiv function code will raise an
|
||||
exception. When this happens, program flow is transferred to the except
|
||||
statement, where the Exception handler will set the value of \var{Z} to
|
||||
zero. If no exception is raised, then program flow continues past the last
|
||||
\var{end} statement.
|
||||
|
||||
To allow error recovery, the \var{Try ... Finally} block is supported.
|
||||
A \var{Try...Finally} block ensures that the statements following the
|
||||
\var{Finally} keyword are guaranteed to be executed, even if an exception
|
||||
occurs.
|
||||
|
||||
A \var{Try..Finally} block has the following form:
|
||||
|
||||
\begin{verbatim}
|
||||
Try
|
||||
...Statement List...
|
||||
Finally
|
||||
[ Finally Statements ]
|
||||
end;
|
||||
\end{verbatim}
|
||||
If no exception occurs inside the \var{Statement List}, then the program
|
||||
runs as if the \var{Try}, \var{Finally} and \var{End} keywords were not
|
||||
present.
|
||||
|
||||
If, however, an exception occurs, the program flow is immediatly
|
||||
transferred to the first statement of the \var{Finally statements}.
|
||||
All statements of the \var{Finally Statements} will be executed, and then
|
||||
the exception will be automatically re-raised. Any statements between the
|
||||
place where the exception was raised and the first statement of the
|
||||
\var{Finally Statements} are skipped.
|
||||
|
||||
As an example consider the following routine:
|
||||
|
||||
\begin{verbatim}
|
||||
Procedure Doit (Name : string);
|
||||
|
||||
Var F : Text;
|
||||
|
||||
begin
|
||||
Try
|
||||
Assign (F,Name);
|
||||
Rewrite (name);
|
||||
|
||||
... File handling ...
|
||||
|
||||
Finally
|
||||
Close(F);
|
||||
end;
|
||||
\end{verbatim}
|
||||
If during the execution of the file handling an excption occurs, then
|
||||
program flow will continue at the \var{close(F)} statement, skipping any
|
||||
file operations that might follow between the place where the exception
|
||||
was raised, and the \var{Close} statement.
|
||||
|
||||
If no exception occurred, all file operations will be executed, and the file
|
||||
will be closed at the end.
|
||||
|
||||
It is possible to nest \var{Try...Except} blocks with \var{Try...Finally}
|
||||
blocks. Program flow will be done according to a \var{lifo} (last in, first
|
||||
out) principle: The code of the last encountered \var{Try...Except} or
|
||||
\var{Try...Finally} block will be executed first. If the exception is not
|
||||
caught, or it was a finally statement, program flow will we transferred to
|
||||
the last but-one block, {\em ad infinitum}.
|
||||
|
||||
If an exception occurs, and there is no exception handler present, then a
|
||||
runerror 217 will be generated. If you use the \file{sysutils} unit, a default
|
||||
handler is installed which ioll show the exception object message, and the
|
||||
address where the exception occurred, after which the program will exit with
|
||||
a \var{Halt} instruction.
|
||||
|
||||
\section{Using functions and procedures}
|
||||
\fpc supports the use of functions and procedures, but with some extras:
|
||||
Function overloading is supported, as well as \var{Const} parameters and
|
||||
@ -1199,6 +1595,9 @@ an external object file. It allows you to use the function in
|
||||
your code, and at linking time, you must link the object file containing the
|
||||
implementation of the function or procedure.
|
||||
|
||||
It replaces, in effect, the function or procedure code block. As such, it
|
||||
can be present only in an implementation block of a unit, or in a program.
|
||||
|
||||
As an example:
|
||||
\begin{CodEx}
|
||||
\begin{verbatim}
|
||||
@ -1354,7 +1753,7 @@ listed in \seet{Modifs}.
|
||||
Modifier & Why not supported ? \\ \hline
|
||||
Near & \fpc is a 32-bit compiler.\\
|
||||
Far & \fpc is a 32-bit compiler. \\
|
||||
External & Replaced by \var{C} modifier. \\ \hline
|
||||
%External & Replaced by \var{C} modifier. \\ \hline
|
||||
\end{FPCltable}
|
||||
|
||||
%
|
||||
|
@ -1,4 +1,4 @@
|
||||
program example79
|
||||
program example79;
|
||||
|
||||
{ Program to demonstrate the setjmp, longjmp functions }
|
||||
|
||||
|
@ -29,8 +29,10 @@
|
||||
\usepackage{html}
|
||||
\latex{\usepackage{fpc}}
|
||||
\html{\input{fpc-html.tex}}
|
||||
\usepackage{fancyheadings}
|
||||
\pagestyle{fancy}
|
||||
\renewcommand{\chaptermark}[1]{\markboth{#1}{}}
|
||||
\makeindex
|
||||
|
||||
%
|
||||
% start of document.
|
||||
%
|
||||
|
987
docs/user.tex
987
docs/user.tex
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user