mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-20 07:39:25 +02:00
* moved
This commit is contained in:
parent
3629bc6001
commit
3a56cae749
159
utils/Makefile
Normal file
159
utils/Makefile
Normal file
@ -0,0 +1,159 @@
|
||||
#
|
||||
# $Id$
|
||||
# Copyright (c) 1999 by the Free Pascal Development Team
|
||||
#
|
||||
# Makefile for Free Pascal Utils
|
||||
#
|
||||
# See the file COPYING.FPC, included in this distribution,
|
||||
# for details about the copyright.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
|
||||
|
||||
#####################################################################
|
||||
# Defaults
|
||||
#####################################################################
|
||||
|
||||
# Default place of the makefile.fpc
|
||||
DEFAULTFPCDIR=..
|
||||
|
||||
|
||||
#####################################################################
|
||||
# Real targets
|
||||
#####################################################################
|
||||
|
||||
EXEOBJECTS=ppudump ppumove ppdep ptop
|
||||
UNITOBJECTS=
|
||||
|
||||
|
||||
#####################################################################
|
||||
# Common targets
|
||||
#####################################################################
|
||||
|
||||
.PHONY: all clean install info \
|
||||
staticlib sharedlib libsclean \
|
||||
staticinstall sharedinstall libinstall \
|
||||
extra_clean \
|
||||
h2pas_all h2pas_clean h2pas_install \
|
||||
|
||||
all: testfpcmake fpc_all h2pas_all
|
||||
|
||||
clean: testfpcmake fpc_clean extra_clean h2pas_clean
|
||||
|
||||
install: testfpcmake fpc_install h2pas_install
|
||||
|
||||
info: testfpcmake fpc_info
|
||||
|
||||
staticlib: testfpcmake fpc_staticlib
|
||||
|
||||
sharedlib: testfpcmake fpc_sharedlib
|
||||
|
||||
libsclean: testfpcmake fpc_libsclean
|
||||
|
||||
staticinstall: testfpcmake fpc_staticinstall
|
||||
|
||||
sharedinstall: testfpcmake fpc_sharedinstall
|
||||
|
||||
libinstall: testfpcmake fpc_libinstall
|
||||
|
||||
|
||||
#####################################################################
|
||||
# Include default makefile
|
||||
#####################################################################
|
||||
|
||||
# test if FPCMAKE is still valid
|
||||
ifdef FPCMAKE
|
||||
ifeq ($(strip $(wildcard $(FPCMAKE))),)
|
||||
FPCDIR=
|
||||
FPCMAKE=
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef FPCDIR
|
||||
ifdef DEFAULTFPCDIR
|
||||
FPCDIR=$(DEFAULTFPCDIR)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef FPCMAKE
|
||||
ifdef FPCDIR
|
||||
FPCMAKE=$(FPCDIR)/makefile.fpc
|
||||
else
|
||||
FPCMAKE=makefile.fpc
|
||||
endif
|
||||
endif
|
||||
|
||||
override FPCMAKE:=$(strip $(wildcard $(FPCMAKE)))
|
||||
ifeq ($(FPCMAKE),)
|
||||
testfpcmake:
|
||||
@echo makefile.fpc not found!
|
||||
@echo Check the FPCMAKE and FPCDIR environment variables.
|
||||
@exit
|
||||
else
|
||||
include $(FPCMAKE)
|
||||
testfpcmake:
|
||||
endif
|
||||
|
||||
|
||||
|
||||
#####################################################################
|
||||
# Dependencies
|
||||
#####################################################################
|
||||
|
||||
#
|
||||
# PPU Tools
|
||||
#
|
||||
ppu$(PPUEXT): ppu.pas
|
||||
|
||||
ppudump$(EXEEXT): ppudump.pp ppu$(PPUEXT)
|
||||
|
||||
ppumove$(EXEEXT): ppumove.pp ppu$(PPUEXT)
|
||||
|
||||
#
|
||||
# Pascal beautifier
|
||||
#
|
||||
ptop$(EXEEXT): ptop.pp ptopu$(PPUEXT)
|
||||
|
||||
ptopu$(PPUEXT): ptopu.pp
|
||||
|
||||
#
|
||||
# Clean also the .ppu's
|
||||
#
|
||||
extra_clean:
|
||||
$(DEL) ppu$(PPUEXT) ptopu$(PPUEXT)
|
||||
|
||||
#
|
||||
# H2Pas
|
||||
#
|
||||
h2pas_all:
|
||||
$(MAKE) -C h2pas all
|
||||
|
||||
h2pas_clean:
|
||||
$(MAKE) -C h2pas clean
|
||||
|
||||
h2pas_install:
|
||||
$(MAKE) -C h2pas install
|
||||
|
||||
#
|
||||
# $Log$
|
||||
# Revision 1.1 1999-05-12 16:11:39 peter
|
||||
# * moved
|
||||
#
|
||||
# Revision 1.14 1999/05/03 18:03:13 peter
|
||||
# * renamed mkdep -> ppdep
|
||||
# * removed obsolete units
|
||||
# * add .cod files
|
||||
#
|
||||
# Revision 1.13 1999/04/02 00:01:49 peter
|
||||
# + ptop to exeobjects
|
||||
#
|
||||
# Revision 1.12 1999/04/01 22:52:00 peter
|
||||
# * update for makefile.fpc
|
||||
#
|
||||
# Revision 1.1 1999/03/16 00:50:29 peter
|
||||
# + init
|
||||
#
|
||||
#
|
25
utils/README
Normal file
25
utils/README
Normal file
@ -0,0 +1,25 @@
|
||||
This dirctory contains some utilities that come with the Free Pascal
|
||||
Compiler. They can be compiled by typing 'make all' in this directory,
|
||||
or 'make utils_all' in the top directory.
|
||||
|
||||
Currently, the following things are provided:
|
||||
|
||||
ppudump : This program prints the contents of a unit (.ppu or .ppl) file
|
||||
to screen. It should handle units of all versions of the compiler.
|
||||
|
||||
ppumove : Similar to tpumove from Borland, Inc. this program can be used
|
||||
to combine several (or one) units in a shared or static library.
|
||||
usage is straightforward. running the program without arguments
|
||||
gives possible arguments.
|
||||
|
||||
ppdep : Creates a makefile which includes all interdependant units.
|
||||
|
||||
ptop : Pascal source beautifier
|
||||
|
||||
h2pas/ : Contains the h2pas program, which converts C header files to pascal
|
||||
unit files.
|
||||
|
||||
Typing a 'make install' will put everything into place.
|
||||
|
||||
Happy Coding !
|
||||
The Free Pascal Development Team.
|
159
utils/h2pas/Makefile
Normal file
159
utils/h2pas/Makefile
Normal file
@ -0,0 +1,159 @@
|
||||
#
|
||||
# $Id$
|
||||
# Copyright (c) 1999 by the Free Pascal Development Team
|
||||
#
|
||||
# Makefile for Free Pascal Utils
|
||||
#
|
||||
# See the file COPYING.FPC, included in this distribution,
|
||||
# for details about the copyright.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
|
||||
|
||||
#####################################################################
|
||||
# Defaults
|
||||
#####################################################################
|
||||
|
||||
# Default place of the makefile.fpc
|
||||
DEFAULTFPCDIR=../..
|
||||
|
||||
# We need -Sg
|
||||
NEEDOPT=-Sg
|
||||
|
||||
|
||||
#####################################################################
|
||||
# Real targets
|
||||
#####################################################################
|
||||
|
||||
# the files in this dir use .pas
|
||||
PASEXT=.pas
|
||||
|
||||
EXEOBJECTS=h2pas
|
||||
UNITOBJECTS=
|
||||
|
||||
|
||||
#####################################################################
|
||||
# Common targets
|
||||
#####################################################################
|
||||
|
||||
.PHONY: all clean install info \
|
||||
staticlib sharedlib libsclean \
|
||||
staticinstall sharedinstall libinstall \
|
||||
|
||||
all: testfpcmake fpc_all
|
||||
|
||||
clean: testfpcmake fpc_cleanall
|
||||
|
||||
install: testfpcmake fpc_install
|
||||
|
||||
info: testfpcmake fpc_info
|
||||
|
||||
staticlib: testfpcmake fpc_staticlib
|
||||
|
||||
sharedlib: testfpcmake fpc_sharedlib
|
||||
|
||||
libsclean: testfpcmake fpc_libsclean
|
||||
|
||||
staticinstall: testfpcmake fpc_staticinstall
|
||||
|
||||
sharedinstall: testfpcmake fpc_sharedinstall
|
||||
|
||||
libinstall: testfpcmake fpc_libinstall
|
||||
|
||||
|
||||
#####################################################################
|
||||
# Include default makefile
|
||||
#####################################################################
|
||||
|
||||
# test if FPCMAKE is still valid
|
||||
ifdef FPCMAKE
|
||||
ifeq ($(strip $(wildcard $(FPCMAKE))),)
|
||||
FPCDIR=
|
||||
FPCMAKE=
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef FPCDIR
|
||||
ifdef DEFAULTFPCDIR
|
||||
FPCDIR=$(DEFAULTFPCDIR)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef FPCMAKE
|
||||
ifdef FPCDIR
|
||||
FPCMAKE=$(FPCDIR)/makefile.fpc
|
||||
else
|
||||
FPCMAKE=makefile.fpc
|
||||
endif
|
||||
endif
|
||||
|
||||
override FPCMAKE:=$(strip $(wildcard $(FPCMAKE)))
|
||||
ifeq ($(FPCMAKE),)
|
||||
testfpcmake:
|
||||
@echo makefile.fpc not found!
|
||||
@echo Check the FPCMAKE and FPCDIR environment variables.
|
||||
@exit
|
||||
else
|
||||
include $(FPCMAKE)
|
||||
testfpcmake:
|
||||
endif
|
||||
|
||||
|
||||
|
||||
#####################################################################
|
||||
# Dependencies
|
||||
#####################################################################
|
||||
|
||||
# do we have pyacc?
|
||||
ifndef PYACC
|
||||
PYACC=$(strip $(wildcard $(addsuffix /pyacc$(EXEEXT),$(SEARCHPATH))))
|
||||
ifeq ($(PYACC),)
|
||||
PYACC=
|
||||
else
|
||||
export PYACC:=$(firstword $(PYACC))
|
||||
endif
|
||||
endif
|
||||
|
||||
# do we have plex?
|
||||
ifndef PLEX
|
||||
PLEX=$(strip $(wildcard $(addsuffix /plex$(EXEEXT),$(SEARCHPATH))))
|
||||
ifeq ($(PLEX),)
|
||||
PLEX=
|
||||
else
|
||||
export PLEX:=$(firstword $(PLEX))
|
||||
endif
|
||||
endif
|
||||
|
||||
h2pas$(EXEEXT): h2pas$(PASEXT)
|
||||
|
||||
#
|
||||
# Lex and Yacc (only if pyacc is found)
|
||||
#
|
||||
ifdef PYACC
|
||||
h2pas$(PASEXT): h2pas.y
|
||||
$(PYACC) h2pas.y
|
||||
|
||||
yacclex: yacc lex
|
||||
|
||||
yacc:
|
||||
$(PYACC) h2pas.y
|
||||
|
||||
lex :
|
||||
$(PLEX) scan.l
|
||||
endif
|
||||
|
||||
#
|
||||
# $Log$
|
||||
# Revision 1.1 1999-05-12 16:11:39 peter
|
||||
# * moved
|
||||
#
|
||||
# Revision 1.12 1999/04/01 22:52:01 peter
|
||||
# * update for makefile.fpc
|
||||
#
|
||||
# Revision 1.1 1999/03/16 00:50:29 peter
|
||||
# + init
|
||||
#
|
||||
#
|
52
utils/h2pas/README
Normal file
52
utils/h2pas/README
Normal file
@ -0,0 +1,52 @@
|
||||
This is the h2pas program, a utility to convert C header files to pascal
|
||||
units. It is part of the Free Pascal distribution.
|
||||
|
||||
COMPILING
|
||||
|
||||
To compile the program, a simple
|
||||
'make'
|
||||
should be sufficient; you need GNU make for this. When using TP, a simple
|
||||
tpc h2pas.pas
|
||||
should also be possible.
|
||||
|
||||
USAGE
|
||||
|
||||
h2pas [-p] [-t] [-o outputfilename] [-l libname] [-u unitname] filename
|
||||
|
||||
-t : Prepend 'T' to all type names in typedef definitions. This may help
|
||||
when the C header use uppercase types and lowercase variables of the
|
||||
same name.
|
||||
|
||||
-p : Use 'P' instead of ^ as a pointer symbol;
|
||||
This will convert
|
||||
^char to pchar
|
||||
^longint to plongint
|
||||
etc. It will also define a PSOMETYPE pointer for each SOMETYPE struct type
|
||||
definition in the header file.
|
||||
Thus
|
||||
typedef struct somestruct {
|
||||
...
|
||||
}
|
||||
Will be converted to
|
||||
somestruct = record
|
||||
...
|
||||
end;
|
||||
PSomestruct = ^Somestruct;
|
||||
If the -t options is used, the -p option takes care of that too.
|
||||
|
||||
-l : In the implementation part, the external functions will be
|
||||
written with 'external libname;' behind it.
|
||||
If you omit this option, all functions will be declared as
|
||||
cdecl; external;
|
||||
|
||||
-o : specify the outputname. By default, the inputname is used, with
|
||||
extension '.pp'.
|
||||
|
||||
-u : Specify the unit name. By default, the outputname is used, without
|
||||
extension.
|
||||
|
||||
-v : Replaces pointer types in parameter list by call by reference
|
||||
parameters:
|
||||
void p(int *i) => procedure p(var i : longint);
|
||||
|
||||
Enjoy !
|
72
utils/h2pas/converu.pas
Normal file
72
utils/h2pas/converu.pas
Normal file
@ -0,0 +1,72 @@
|
||||
unit converu;
|
||||
|
||||
interface
|
||||
|
||||
const TYPEDEF = 257;
|
||||
const DEFINE = 258;
|
||||
const COLON = 259;
|
||||
const SEMICOLON = 260;
|
||||
const COMMA = 261;
|
||||
const LKLAMMER = 262;
|
||||
const RKLAMMER = 263;
|
||||
const LECKKLAMMER = 264;
|
||||
const RECKKLAMMER = 265;
|
||||
const LGKLAMMER = 266;
|
||||
const RGKLAMMER = 267;
|
||||
const STRUCT = 268;
|
||||
const UNION = 269;
|
||||
const ENUM = 270;
|
||||
const ID = 271;
|
||||
const NUMBER = 272;
|
||||
const CSTRING = 273;
|
||||
const SHORT = 274;
|
||||
const UNSIGNED = 275;
|
||||
const LONG = 276;
|
||||
const INT = 277;
|
||||
const REAL = 278;
|
||||
const _CHAR = 279;
|
||||
const VOID = 280;
|
||||
const _CONST = 281;
|
||||
const _FAR = 282;
|
||||
const _HUGE = 283;
|
||||
const _NEAR = 284;
|
||||
const _ASSIGN = 285;
|
||||
const NEW_LINE = 286;
|
||||
const SPACE_DEFINE = 287;
|
||||
const EXTERN = 288;
|
||||
const STDCALL = 289;
|
||||
const CDECL = 290;
|
||||
const CALLBACK = 291;
|
||||
const PASCAL = 292;
|
||||
const WINAPI = 293;
|
||||
const APIENTRY = 294;
|
||||
const WINGDIAPI = 295;
|
||||
const SYS_TRAP = 296;
|
||||
const _PACKED = 297;
|
||||
const ELLIPSIS = 298;
|
||||
const R_AND = 299;
|
||||
const EQUAL = 300;
|
||||
const UNEQUAL = 301;
|
||||
const GT = 302;
|
||||
const LT = 303;
|
||||
const GTE = 304;
|
||||
const LTE = 305;
|
||||
const QUESTIONMARK = 306;
|
||||
const _OR = 307;
|
||||
const _AND = 308;
|
||||
const _PLUS = 309;
|
||||
const MINUS = 310;
|
||||
const _SHR = 311;
|
||||
const _SHL = 312;
|
||||
const STAR = 313;
|
||||
const _SLASH = 314;
|
||||
const _NOT = 315;
|
||||
const PSTAR = 316;
|
||||
const P_AND = 317;
|
||||
const POINT = 318;
|
||||
const DEREF = 319;
|
||||
const STICK = 320;
|
||||
|
||||
|
||||
implementation
|
||||
end.
|
6544
utils/h2pas/h2pas.pas
Normal file
6544
utils/h2pas/h2pas.pas
Normal file
File diff suppressed because it is too large
Load Diff
2155
utils/h2pas/h2pas.y
Normal file
2155
utils/h2pas/h2pas.y
Normal file
File diff suppressed because it is too large
Load Diff
407
utils/h2pas/lexlib.pas
Normal file
407
utils/h2pas/lexlib.pas
Normal file
@ -0,0 +1,407 @@
|
||||
|
||||
unit LexLib;
|
||||
|
||||
(* Standard Lex library unit for TP Lex Version 3.0.
|
||||
2-11-91 AG *)
|
||||
|
||||
interface
|
||||
|
||||
(* The Lex library unit supplies a collection of variables and routines
|
||||
needed by the lexical analyzer routine yylex and application programs
|
||||
using Lex-generated lexical analyzers. It also provides access to the
|
||||
input/output streams used by the lexical analyzer and the text of the
|
||||
matched string, and provides some utility functions which may be used
|
||||
in actions.
|
||||
|
||||
This `standard' version of the LexLib unit is used to implement lexical
|
||||
analyzers which read from and write to MS-DOS files (using standard input
|
||||
and output, by default). It is suitable for many standard applications
|
||||
for lexical analyzers, such as text conversion tools or compilers.
|
||||
|
||||
However, you may create your own version of the LexLib unit, tailored to
|
||||
your target applications. In particular, you may wish to provide another
|
||||
set of I/O functions, e.g., if you want to read from or write to memory
|
||||
instead to files, or want to use different file types. *)
|
||||
|
||||
(* Variables:
|
||||
|
||||
The variable yytext contains the current match, yyleng its length.
|
||||
The variable yyline contains the current input line, and yylineno and
|
||||
yycolno denote the current input position (line, column). These values
|
||||
are often used in giving error diagnostics (however, they will only be
|
||||
meaningful if there is no rescanning across line ends).
|
||||
|
||||
The variables yyinput and yyoutput are the text files which are used
|
||||
by the lexical analyzer. By default, they are assigned to standard
|
||||
input and output, but you may change these assignments to fit your
|
||||
target application (use the Turbo Pascal standard routines assign,
|
||||
reset, and rewrite for this purpose). *)
|
||||
|
||||
var
|
||||
|
||||
yyinput, yyoutput : Text; (* input and output file *)
|
||||
yyline : String; (* current input line *)
|
||||
yylineno, yycolno : Integer; (* current input position *)
|
||||
yytext : String; (* matched text (should be considered r/o) *)
|
||||
yyleng : Byte (* length of matched text *)
|
||||
absolute yytext;
|
||||
|
||||
(* I/O routines:
|
||||
|
||||
The following routines get_char, unget_char and put_char are used to
|
||||
implement access to the input and output files. Since \n (newline) for
|
||||
Lex means line end, the I/O routines have to translate MS-DOS line ends
|
||||
(carriage-return/line-feed) into newline characters and vice versa. Input
|
||||
is buffered to allow rescanning text (via unput_char).
|
||||
|
||||
The input buffer holds the text of the line to be scanned. When the input
|
||||
buffer empties, a new line is obtained from the input stream. Characters
|
||||
can be returned to the input buffer by calls to unget_char. At end-of-
|
||||
file a null character is returned.
|
||||
|
||||
The input routines also keep track of the input position and set the
|
||||
yyline, yylineno, yycolno variables accordingly.
|
||||
|
||||
Since the rest of the Lex library only depends on these three routines
|
||||
(there are no direct references to the yyinput and yyoutput files or
|
||||
to the input buffer), you can easily replace get_char, unget_char and
|
||||
put_char by another suitable set of routines, e.g. if you want to read
|
||||
from/write to memory, etc. *)
|
||||
|
||||
function get_char : Char;
|
||||
(* obtain one character from the input file (null character at end-of-
|
||||
file) *)
|
||||
|
||||
procedure unget_char ( c : Char );
|
||||
(* return one character to the input file to be reread in subsequent calls
|
||||
to get_char *)
|
||||
|
||||
procedure put_char ( c : Char );
|
||||
(* write one character to the output file *)
|
||||
|
||||
(* Utility routines: *)
|
||||
|
||||
procedure echo;
|
||||
(* echoes the current match to the output stream *)
|
||||
|
||||
procedure yymore;
|
||||
(* append the next match to the current one *)
|
||||
|
||||
procedure yyless ( n : Integer );
|
||||
(* truncate yytext to size n and return the remaining characters to the
|
||||
input stream *)
|
||||
|
||||
procedure reject;
|
||||
(* reject the current match and execute the next one *)
|
||||
|
||||
(* reject does not actually cause the input to be rescanned; instead,
|
||||
internal state information is used to find the next match. Hence
|
||||
you should not try to modify the input stream or the yytext variable
|
||||
when rejecting a match. *)
|
||||
|
||||
procedure return ( n : Integer );
|
||||
procedure returnc ( c : Char );
|
||||
(* sets the return value of yylex *)
|
||||
|
||||
procedure start ( state : Integer );
|
||||
(* puts the lexical analyzer in the given start state; state=0 denotes
|
||||
the default start state, other values are user-defined *)
|
||||
|
||||
(* yywrap:
|
||||
|
||||
The yywrap function is called by yylex at end-of-file (unless you have
|
||||
specified a rule matching end-of-file). You may redefine this routine
|
||||
in your Lex program to do application-dependent processing at end of
|
||||
file. In particular, yywrap may arrange for more input and return false
|
||||
in which case the yylex routine resumes lexical analysis. *)
|
||||
|
||||
function yywrap : Boolean;
|
||||
(* The default yywrap routine supplied here closes input and output files
|
||||
and returns true (causing yylex to terminate). *)
|
||||
|
||||
(* The following are the internal data structures and routines used by the
|
||||
lexical analyzer routine yylex; they should not be used directly. *)
|
||||
|
||||
var
|
||||
|
||||
yystate : Integer; (* current state of lexical analyzer *)
|
||||
yyactchar : Char; (* current character *)
|
||||
yylastchar : Char; (* last matched character (#0 if none) *)
|
||||
yyrule : Integer; (* matched rule *)
|
||||
yyreject : Boolean; (* current match rejected? *)
|
||||
yydone : Boolean; (* yylex return value set? *)
|
||||
yyretval : Integer; (* yylex return value *)
|
||||
|
||||
procedure yynew;
|
||||
(* starts next match; initializes state information of the lexical
|
||||
analyzer *)
|
||||
|
||||
procedure yyscan;
|
||||
(* gets next character from the input stream and updates yytext and
|
||||
yyactchar accordingly *)
|
||||
|
||||
procedure yymark ( n : Integer );
|
||||
(* marks position for rule no. n *)
|
||||
|
||||
procedure yymatch ( n : Integer );
|
||||
(* declares a match for rule number n *)
|
||||
|
||||
function yyfind ( var n : Integer ) : Boolean;
|
||||
(* finds the last match and the corresponding marked position and adjusts
|
||||
the matched string accordingly; returns:
|
||||
- true if a rule has been matched, false otherwise
|
||||
- n: the number of the matched rule *)
|
||||
|
||||
function yydefault : Boolean;
|
||||
(* executes the default action (copy character); returns true unless
|
||||
at end-of-file *)
|
||||
|
||||
procedure yyclear;
|
||||
(* reinitializes state information after lexical analysis has been
|
||||
finished *)
|
||||
|
||||
implementation
|
||||
|
||||
procedure fatal ( msg : String );
|
||||
(* writes a fatal error message and halts program *)
|
||||
begin
|
||||
writeln('LexLib: ', msg);
|
||||
halt(1);
|
||||
end(*fatal*);
|
||||
|
||||
(* I/O routines: *)
|
||||
|
||||
const nl = #10; (* newline character *)
|
||||
|
||||
const max_chars = 2048;
|
||||
|
||||
var
|
||||
|
||||
bufptr : Integer;
|
||||
buf : array [1..max_chars] of Char;
|
||||
|
||||
function get_char : Char;
|
||||
var i : Integer;
|
||||
begin
|
||||
if (bufptr=0) and not eof(yyinput) then
|
||||
begin
|
||||
readln(yyinput, yyline);
|
||||
inc(yylineno); yycolno := 1;
|
||||
buf[1] := nl;
|
||||
for i := 1 to length(yyline) do
|
||||
buf[i+1] := yyline[length(yyline)-i+1];
|
||||
inc(bufptr, length(yyline)+1);
|
||||
end;
|
||||
if bufptr>0 then
|
||||
begin
|
||||
get_char := buf[bufptr];
|
||||
dec(bufptr);
|
||||
inc(yycolno);
|
||||
end
|
||||
else
|
||||
get_char := #0;
|
||||
end(*get_char*);
|
||||
|
||||
procedure unget_char ( c : Char );
|
||||
begin
|
||||
if bufptr=max_chars then fatal('input buffer overflow');
|
||||
inc(bufptr);
|
||||
dec(yycolno);
|
||||
buf[bufptr] := c;
|
||||
end(*unget_char*);
|
||||
|
||||
procedure put_char ( c : Char );
|
||||
begin
|
||||
if c=#0 then
|
||||
{ ignore }
|
||||
else if c=nl then
|
||||
writeln(yyoutput)
|
||||
else
|
||||
write(yyoutput, c)
|
||||
end(*put_char*);
|
||||
|
||||
(* Variables:
|
||||
|
||||
Some state information is maintained to keep track with calls to yymore,
|
||||
yyless, reject, start and yymatch/yymark, and to initialize state
|
||||
information used by the lexical analyzer.
|
||||
- yystext: contains the initial contents of the yytext variable; this
|
||||
will be the empty string, unless yymore is called which sets yystext
|
||||
to the current yytext
|
||||
- yysstate: start state of lexical analyzer (set to 0 during
|
||||
initialization, and modified in calls to the start routine)
|
||||
- yylstate: line state information (1 if at beginning of line, 0
|
||||
otherwise)
|
||||
- yystack: stack containing matched rules; yymatches contains the number of
|
||||
matches
|
||||
- yypos: for each rule the last marked position (yymark); zeroed when rule
|
||||
has already been considered
|
||||
- yysleng: copy of the original yyleng used to restore state information
|
||||
when reject is used *)
|
||||
|
||||
const
|
||||
|
||||
max_matches = 1024;
|
||||
max_rules = 256;
|
||||
|
||||
var
|
||||
|
||||
yystext : String;
|
||||
yysstate, yylstate : Integer;
|
||||
yymatches : Integer;
|
||||
yystack : array [1..max_matches] of Integer;
|
||||
yypos : array [1..max_rules] of Integer;
|
||||
yysleng : Byte;
|
||||
|
||||
(* Utilities: *)
|
||||
|
||||
procedure echo;
|
||||
var i : Integer;
|
||||
begin
|
||||
for i := 1 to yyleng do
|
||||
put_char(yytext[i])
|
||||
end(*echo*);
|
||||
|
||||
procedure yymore;
|
||||
begin
|
||||
yystext := yytext;
|
||||
end(*yymore*);
|
||||
|
||||
procedure yyless ( n : Integer );
|
||||
var i : Integer;
|
||||
begin
|
||||
for i := yyleng downto n+1 do
|
||||
unget_char(yytext[i]);
|
||||
yyleng := n;
|
||||
end(*yyless*);
|
||||
|
||||
procedure reject;
|
||||
var i : Integer;
|
||||
begin
|
||||
yyreject := true;
|
||||
for i := yyleng+1 to yysleng do
|
||||
yytext := yytext+get_char;
|
||||
dec(yymatches);
|
||||
end(*reject*);
|
||||
|
||||
procedure return ( n : Integer );
|
||||
begin
|
||||
yyretval := n;
|
||||
yydone := true;
|
||||
end(*return*);
|
||||
|
||||
procedure returnc ( c : Char );
|
||||
begin
|
||||
yyretval := ord(c);
|
||||
yydone := true;
|
||||
end(*returnc*);
|
||||
|
||||
procedure start ( state : Integer );
|
||||
begin
|
||||
yysstate := state;
|
||||
end(*start*);
|
||||
|
||||
(* yywrap: *)
|
||||
|
||||
function yywrap : Boolean;
|
||||
begin
|
||||
close(yyinput); close(yyoutput);
|
||||
yywrap := true;
|
||||
end(*yywrap*);
|
||||
|
||||
(* Internal routines: *)
|
||||
|
||||
procedure yynew;
|
||||
begin
|
||||
if yylastchar<>#0 then
|
||||
if yylastchar=nl then
|
||||
yylstate := 1
|
||||
else
|
||||
yylstate := 0;
|
||||
yystate := yysstate+yylstate;
|
||||
yytext := yystext;
|
||||
yystext := '';
|
||||
yymatches := 0;
|
||||
yydone := false;
|
||||
end(*yynew*);
|
||||
|
||||
procedure yyscan;
|
||||
begin
|
||||
if yyleng=255 then fatal('yytext overflow');
|
||||
yyactchar := get_char;
|
||||
inc(yyleng);
|
||||
yytext[yyleng] := yyactchar;
|
||||
end(*yyscan*);
|
||||
|
||||
procedure yymark ( n : Integer );
|
||||
begin
|
||||
if n>max_rules then fatal('too many rules');
|
||||
yypos[n] := yyleng;
|
||||
end(*yymark*);
|
||||
|
||||
procedure yymatch ( n : Integer );
|
||||
begin
|
||||
inc(yymatches);
|
||||
if yymatches>max_matches then fatal('match stack overflow');
|
||||
yystack[yymatches] := n;
|
||||
end(*yymatch*);
|
||||
|
||||
function yyfind ( var n : Integer ) : Boolean;
|
||||
begin
|
||||
yyreject := false;
|
||||
while (yymatches>0) and (yypos[yystack[yymatches]]=0) do
|
||||
dec(yymatches);
|
||||
if yymatches>0 then
|
||||
begin
|
||||
yysleng := yyleng;
|
||||
n := yystack[yymatches];
|
||||
yyless(yypos[n]);
|
||||
yypos[n] := 0;
|
||||
if yyleng>0 then
|
||||
yylastchar := yytext[yyleng]
|
||||
else
|
||||
yylastchar := #0;
|
||||
yyfind := true;
|
||||
end
|
||||
else
|
||||
begin
|
||||
yyless(0);
|
||||
yylastchar := #0;
|
||||
yyfind := false;
|
||||
end
|
||||
end(*yyfind*);
|
||||
|
||||
function yydefault : Boolean;
|
||||
begin
|
||||
yyreject := false;
|
||||
yyactchar := get_char;
|
||||
if yyactchar<>#0 then
|
||||
begin
|
||||
put_char(yyactchar);
|
||||
yydefault := true;
|
||||
end
|
||||
else
|
||||
begin
|
||||
yylstate := 1;
|
||||
yydefault := false;
|
||||
end;
|
||||
yylastchar := yyactchar;
|
||||
end(*yydefault*);
|
||||
|
||||
procedure yyclear;
|
||||
begin
|
||||
bufptr := 0;
|
||||
yysstate := 0;
|
||||
yylstate := 1;
|
||||
yylastchar := #0;
|
||||
yytext := '';
|
||||
yystext := '';
|
||||
end(*yyclear*);
|
||||
|
||||
begin
|
||||
assign(yyinput, '');
|
||||
assign(yyoutput, '');
|
||||
reset(yyinput); rewrite(yyoutput);
|
||||
yylineno := 0;
|
||||
yyclear;
|
||||
end(*LexLib*).
|
210
utils/h2pas/options.pas
Normal file
210
utils/h2pas/options.pas
Normal file
@ -0,0 +1,210 @@
|
||||
{
|
||||
$Id$
|
||||
Copyright (c) 1993-98 by Florian Klaempfl
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
****************************************************************************}
|
||||
|
||||
|
||||
unit options;
|
||||
|
||||
interface
|
||||
|
||||
var
|
||||
inputfilename, outputfilename : string; { Filenames }
|
||||
LibFileName, unitname : string; { external library name }
|
||||
UseLib, { Append external to implementation ? }
|
||||
UseName, { Append 'libname name 'funcname ' }
|
||||
UsePPOinters, { Use P instead of ^ for pointers }
|
||||
EnumToConst, { Write enumeration types as constants }
|
||||
Win32headers, { allows dec_specifier }
|
||||
stripcomment, { strip comments from inputfile }
|
||||
PrependTypes : Boolean; { Print T in front of type names ? }
|
||||
usevarparas : boolean; { generate var parameters, when a pointer }
|
||||
{ is passed }
|
||||
includefile : boolean; { creates an include file instead of a unit }
|
||||
palmpilot : boolean; { handling of PalmOS SYS_CALLs }
|
||||
|
||||
Procedure ProcessOptions;
|
||||
|
||||
Implementation
|
||||
|
||||
Procedure Usage;
|
||||
|
||||
begin
|
||||
writeln ('Usage : ',paramstr(0),' [options] filename');
|
||||
writeln (' Where [options] is one or more of:');
|
||||
writeln (' -o outputfilename Specify the outputfilename');
|
||||
writeln (' -l libname Specify the library name for external.');
|
||||
writeln (' -u unitname Specify the name of the unit.');
|
||||
writeln (' -t Prepend typedef type names with T');
|
||||
writeln (' -p Use "P" instead of "^" for pointers.');
|
||||
writeln (' -d Use external;');
|
||||
writeln (' -D use external libname name ''func_name'';');
|
||||
writeln (' -e change enum type to list of constants.');
|
||||
writeln (' -s strip comments from inputfile.');
|
||||
writeln (' -v replace pointer parameters by call by');
|
||||
writeln (' reference parameters');
|
||||
writeln (' -w special for win32 headers');
|
||||
writeln (' -i create include files (no unit header)');
|
||||
writeln (' -x handle SYS_TRAP of PalmOS header files');
|
||||
halt (0);
|
||||
end;
|
||||
|
||||
Function ForceExtension(Const HStr,ext:String):String;
|
||||
{
|
||||
Return a filename which certainly has the extension ext
|
||||
(no dot in ext !!)
|
||||
}
|
||||
var
|
||||
j : longint;
|
||||
begin
|
||||
j:=length(Hstr);
|
||||
while (j>0) and (Hstr[j]<>'.') do
|
||||
dec(j);
|
||||
if j=0 then
|
||||
j:=255;
|
||||
ForceExtension:=Copy(Hstr,1,j-1)+'.'+Ext;
|
||||
end;
|
||||
|
||||
Procedure ProcessOptions;
|
||||
|
||||
Var cp : string;
|
||||
I : longint;
|
||||
|
||||
Function GetNextParam (const Opt,Name : String) : string;
|
||||
|
||||
begin
|
||||
if i=paramcount then
|
||||
begin
|
||||
writeln ('Error : -',Opt,' : ',name,' expected');
|
||||
halt(1);
|
||||
end
|
||||
else
|
||||
begin
|
||||
GetNextParam:=paramstr(i+1);
|
||||
inc(i);
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
if paramcount=0 then
|
||||
Usage;
|
||||
inputfilename:='';
|
||||
outputfilename:='';
|
||||
LibFileName:='';
|
||||
UnitName:='';
|
||||
UseLib:=False;
|
||||
UseName:=FAlse;
|
||||
StripComment:=False;
|
||||
UsePPointers:=False;
|
||||
EnumToCOnst:=False;
|
||||
usevarparas:=false;
|
||||
palmpilot:=false;
|
||||
includefile:=false;
|
||||
i:=1;
|
||||
while i<=paramcount do
|
||||
begin
|
||||
cp:=paramstr(i);
|
||||
if cp[1]='-' then
|
||||
case cp[2] of
|
||||
'o' : outputfilename:=GetNextParam('o','outputfilename');
|
||||
't' : PrependTypes := True;
|
||||
'p' : UsePPointers := True;
|
||||
'e' : EnumToConst := True;
|
||||
'd' : UseLib := True;
|
||||
'D' : begin
|
||||
UseLib := True;
|
||||
usename := True;
|
||||
end;
|
||||
's' : stripcomment:=true;
|
||||
'l' : LibFileName:=GetNextParam ('l','libname');
|
||||
'u' : UnitName:=GetNextParam ('u','unitname');
|
||||
'v' : usevarparas:=true;
|
||||
'i' : includefile:=true;
|
||||
'w' : begin
|
||||
Win32headers:=true;
|
||||
UseLib:=true;
|
||||
usename:=true;
|
||||
usevarparas:=true;
|
||||
LibFileName:='kernel32';
|
||||
end;
|
||||
'x' : palmpilot:=true;
|
||||
else
|
||||
Writeln ('Illegal option : ',cp);
|
||||
end
|
||||
else
|
||||
begin { filename }
|
||||
if inputfilename<>'' then
|
||||
begin
|
||||
writeln ('Error : only one filename supported. Found also :',cp);
|
||||
halt(1);
|
||||
end;
|
||||
inputfilename:=cp;
|
||||
if outputfilename='' then
|
||||
outputfilename:=ForceExtension (inputfilename,'pp');
|
||||
end;
|
||||
inc(i);
|
||||
end;
|
||||
If inputfilename='' then Usage;
|
||||
if UnitName='' then
|
||||
begin
|
||||
i:=pos('.',outputfilename)-1;
|
||||
if i<=0 then
|
||||
UnitName:=outputfilename
|
||||
else
|
||||
UnitName:=Copy(OutputFileName,1,i);
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.1 1999-05-12 16:11:39 peter
|
||||
* moved
|
||||
|
||||
Revision 1.10 1999/04/08 20:47:02 florian
|
||||
* misplaced line in the help screen fixed
|
||||
|
||||
Revision 1.9 1998/09/04 17:26:33 pierre
|
||||
* better packed field handling
|
||||
|
||||
Revision 1.8 1998/08/05 15:50:10 florian
|
||||
* small problems with // comments fixed (invalid line counting)
|
||||
+ SYS_TRAP support for PalmOS
|
||||
+ switch -x for PalmOS
|
||||
+ switch -i to generate include files instead of units
|
||||
|
||||
Revision 1.7 1998/07/24 20:55:44 michael
|
||||
* Fixed some minor bugs in Pierres stuff
|
||||
|
||||
Revision 1.6 1998/07/23 23:26:04 michael
|
||||
+ added -D option instead of -d, restored old -d
|
||||
|
||||
Revision 1.5 1998/06/08 08:13:47 pierre
|
||||
+ merged version of h2pas
|
||||
+ added -w for special win32 header directives
|
||||
|
||||
Revision 1.4 1998/04/27 12:06:40 michael
|
||||
+ Added GPL statement
|
||||
|
||||
Revision 1.3 1998/04/24 18:23:46 florian
|
||||
+ parameter -v added (replaces pointer parameters by call by reference
|
||||
parameters)
|
||||
void p(int *i) => procedure p(var i : longint);
|
||||
|
||||
}
|
707
utils/h2pas/scan.l
Normal file
707
utils/h2pas/scan.l
Normal file
@ -0,0 +1,707 @@
|
||||
%{
|
||||
{
|
||||
$Id$
|
||||
Copyright (c) 1993-98 by Florian Klaempfl
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
****************************************************************************}
|
||||
|
||||
|
||||
unit scan;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
strings,
|
||||
lexlib,yacclib;
|
||||
|
||||
type
|
||||
Char=system.char;
|
||||
ttyp = (
|
||||
t_id,
|
||||
{ p contains the string }
|
||||
t_arraydef,
|
||||
{ }
|
||||
t_pointerdef,
|
||||
{ p1 contains the definition
|
||||
if in type overrider
|
||||
or nothing for args
|
||||
}
|
||||
t_addrdef,
|
||||
|
||||
t_void,
|
||||
{ no field }
|
||||
t_dec,
|
||||
{ }
|
||||
t_declist,
|
||||
{ p1 is t_dec
|
||||
next if exists }
|
||||
t_memberdec,
|
||||
{ p1 is type specifier
|
||||
p2 is declarator_list }
|
||||
t_structdef,
|
||||
{ }
|
||||
t_memberdeclist,
|
||||
{ p1 is memberdec
|
||||
next is next if it exist }
|
||||
t_procdef,
|
||||
{ }
|
||||
t_uniondef,
|
||||
{ }
|
||||
t_enumdef,
|
||||
{ }
|
||||
t_enumlist,
|
||||
{ }
|
||||
t_preop,
|
||||
{ p contains the operator string
|
||||
p1 contains the right expr }
|
||||
t_bop,
|
||||
{ p contains the operator string
|
||||
p1 contains the left expr
|
||||
p2 contains the right expr }
|
||||
t_arg,
|
||||
{
|
||||
p1 contain the typedef
|
||||
p2 the declarator (t_dec)
|
||||
}
|
||||
t_arglist,
|
||||
{ }
|
||||
t_funexprlist,
|
||||
{ }
|
||||
t_exprlist,
|
||||
{ p1 contains the expr
|
||||
next contains the next if it exists }
|
||||
t_ifexpr,
|
||||
{ p1 contains the condition expr
|
||||
p2 contains the if branch
|
||||
p3 contains the else branch }
|
||||
t_funcname,
|
||||
{ p1 contains the function dname
|
||||
p2 contains the funexprlist
|
||||
p3 possibly contains the return type }
|
||||
t_typespec,
|
||||
{ p1 is the type itself
|
||||
p2 the typecast expr }
|
||||
t_size_specifier,
|
||||
{ p1 expr for size }
|
||||
t_default_value
|
||||
{ p1 expr for value }
|
||||
);
|
||||
|
||||
{tdtyp = (dt_id,dt_one,dt_two,dt_three,dt_no,dt_uop,dt_bop);
|
||||
obsolete removed }
|
||||
|
||||
presobject = ^tresobject;
|
||||
|
||||
tresobject = object
|
||||
typ : ttyp;
|
||||
p : pchar;
|
||||
next : presobject;
|
||||
p1,p2,p3 : presobject;
|
||||
{ dtyp : tdtyp; }
|
||||
constructor init_no(t : ttyp);
|
||||
constructor init_one(t : ttyp;_p1 : presobject);
|
||||
constructor init_two(t : ttyp;_p1,_p2 : presobject);
|
||||
constructor init_three(t : ttyp;_p1,_p2,_p3 : presobject);
|
||||
constructor init_id(const s : string);
|
||||
constructor init_bop(const s : string;_p1,_p2 : presobject);
|
||||
constructor init_preop(const s : string;_p1 : presobject);
|
||||
function str : string;
|
||||
function strlength : byte;
|
||||
function get_copy : presobject;
|
||||
{ can this ve considered as a constant ? }
|
||||
function is_const : boolean;
|
||||
destructor done;
|
||||
end;
|
||||
|
||||
tblocktype = (bt_type,bt_const,bt_var,bt_func,bt_no);
|
||||
|
||||
|
||||
var
|
||||
infile : string;
|
||||
textinfile,outfile : text;
|
||||
c : char;
|
||||
aktspace : string;
|
||||
block_type : tblocktype;
|
||||
|
||||
const
|
||||
in_define : boolean = false;
|
||||
{ 1 after define; 2 after the ID to print the first
|
||||
separating space }
|
||||
in_space_define : byte = 0;
|
||||
arglevel : longint = 0;
|
||||
prev_line : string = '';
|
||||
last_source_line : string = 'Line number 0';
|
||||
|
||||
function yylex : integer;
|
||||
function act_token : string;
|
||||
procedure internalerror(i : integer);
|
||||
|
||||
procedure next_line;
|
||||
|
||||
function strpnew(const s : string) : pchar;
|
||||
|
||||
implementation
|
||||
uses options,converu;
|
||||
|
||||
procedure internalerror(i : integer);
|
||||
begin
|
||||
writeln('Internal error ',i,' in line ',line_no);
|
||||
halt(1);
|
||||
end;
|
||||
|
||||
{ keep the last source line }
|
||||
procedure next_line;
|
||||
|
||||
begin
|
||||
inc(line_no);
|
||||
prev_line:=last_source_line;
|
||||
readln(textinfile,last_source_line);
|
||||
end;
|
||||
|
||||
procedure commenteof;
|
||||
begin
|
||||
writeln('unexpected EOF inside comment at line ',line_no);
|
||||
end;
|
||||
|
||||
var p : pchar;
|
||||
function strpnew(const s : string) : pchar;
|
||||
begin
|
||||
getmem(p,length(s)+1);
|
||||
strpcopy(p,s);
|
||||
strpnew:=p;
|
||||
end;
|
||||
|
||||
const
|
||||
newline = #10;
|
||||
|
||||
constructor tresobject.init_preop(const s : string;_p1 : presobject);
|
||||
begin
|
||||
typ:=t_preop;
|
||||
p:=strpnew(s);
|
||||
p1:=_p1;
|
||||
p2:=nil;
|
||||
p3:=nil;
|
||||
next:=nil;
|
||||
end;
|
||||
|
||||
constructor tresobject.init_bop(const s : string;_p1,_p2 : presobject);
|
||||
begin
|
||||
typ:=t_bop;
|
||||
p:=strpnew(s);
|
||||
p1:=_p1;
|
||||
p2:=_p2;
|
||||
p3:=nil;
|
||||
next:=nil;
|
||||
end;
|
||||
|
||||
constructor tresobject.init_id(const s : string);
|
||||
begin
|
||||
typ:=t_id;
|
||||
p:=strpnew(s);
|
||||
p1:=nil;
|
||||
p2:=nil;
|
||||
p3:=nil;
|
||||
next:=nil;
|
||||
end;
|
||||
|
||||
constructor tresobject.init_two(t : ttyp;_p1,_p2 : presobject);
|
||||
begin
|
||||
typ:=t;
|
||||
p1:=_p1;
|
||||
p2:=_p2;
|
||||
p3:=nil;
|
||||
p:=nil;
|
||||
next:=nil;
|
||||
end;
|
||||
|
||||
constructor tresobject.init_three(t : ttyp;_p1,_p2,_p3 : presobject);
|
||||
begin
|
||||
typ:=t;
|
||||
p1:=_p1;
|
||||
p2:=_p2;
|
||||
p3:=_p3;
|
||||
p:=nil;
|
||||
next:=nil;
|
||||
end;
|
||||
|
||||
constructor tresobject.init_one(t : ttyp;_p1 : presobject);
|
||||
begin
|
||||
typ:=t;
|
||||
p1:=_p1;
|
||||
p2:=nil;
|
||||
p3:=nil;
|
||||
next:=nil;
|
||||
p:=nil;
|
||||
end;
|
||||
|
||||
constructor tresobject.init_no(t : ttyp);
|
||||
begin
|
||||
typ:=t;
|
||||
p:=nil;
|
||||
p1:=nil;
|
||||
p2:=nil;
|
||||
p3:=nil;
|
||||
next:=nil;
|
||||
end;
|
||||
|
||||
function tresobject.str : string;
|
||||
|
||||
begin
|
||||
str:=strpas(p);
|
||||
end;
|
||||
|
||||
function tresobject.strlength : byte;
|
||||
|
||||
begin
|
||||
if assigned(p) then
|
||||
strlength:=strlen(p)
|
||||
else
|
||||
strlength:=0;
|
||||
end;
|
||||
|
||||
{ can this ve considered as a constant ? }
|
||||
function tresobject.is_const : boolean;
|
||||
|
||||
begin
|
||||
case typ of
|
||||
t_id,t_void :
|
||||
is_const:=true;
|
||||
t_preop :
|
||||
is_const:= ((str='-') or (str=' not ')) and p1^.is_const;
|
||||
t_bop :
|
||||
is_const:= p2^.is_const and p1^.is_const;
|
||||
else
|
||||
is_const:=false;
|
||||
end;
|
||||
end;
|
||||
|
||||
function tresobject.get_copy : presobject;
|
||||
var
|
||||
newres : presobject;
|
||||
begin
|
||||
newres:=new(presobject,init_no(typ));
|
||||
if assigned(p) then
|
||||
newres^.p:=strnew(p);
|
||||
if assigned(p1) then
|
||||
newres^.p1:=p1^.get_copy;
|
||||
if assigned(p2) then
|
||||
newres^.p2:=p2^.get_copy;
|
||||
if assigned(p3) then
|
||||
newres^.p3:=p3^.get_copy;
|
||||
if assigned(next) then
|
||||
newres^.next:=next^.get_copy;
|
||||
get_copy:=newres;
|
||||
end;
|
||||
|
||||
destructor tresobject.done;
|
||||
begin
|
||||
(* writeln('disposing ',byte(typ)); *)
|
||||
if assigned(p)then strdispose(p);
|
||||
if assigned(p1) then
|
||||
dispose(p1,done);
|
||||
if assigned(p2) then
|
||||
dispose(p2,done);
|
||||
if assigned(p3) then
|
||||
dispose(p3,done);
|
||||
if assigned(next) then
|
||||
dispose(next,done);
|
||||
end;
|
||||
%}
|
||||
|
||||
D [0-9]
|
||||
%%
|
||||
|
||||
"/*" begin
|
||||
if not stripcomment then
|
||||
write(outfile,aktspace,'{');
|
||||
repeat
|
||||
c:=get_char;
|
||||
case c of
|
||||
'*' : begin
|
||||
c:=get_char;
|
||||
if c='/' then
|
||||
begin
|
||||
if not stripcomment then
|
||||
writeln(outfile,' }');
|
||||
flush(outfile);
|
||||
exit;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if not stripcomment then
|
||||
write(outfile,' ');
|
||||
unget_char(c)
|
||||
end;
|
||||
end;
|
||||
newline : begin
|
||||
next_line;
|
||||
if not stripcomment then
|
||||
begin
|
||||
writeln(outfile);
|
||||
write(outfile,aktspace);
|
||||
end;
|
||||
end;
|
||||
#0 : commenteof;
|
||||
else if not stripcomment then
|
||||
write(outfile,c);
|
||||
end;
|
||||
until false;
|
||||
flush(outfile);
|
||||
end;
|
||||
|
||||
"//" begin
|
||||
If not stripcomment then
|
||||
write(outfile,aktspace,'{');
|
||||
repeat
|
||||
c:=get_char;
|
||||
case c of
|
||||
newline : begin
|
||||
unget_char(c);
|
||||
if not stripcomment then
|
||||
writeln(outfile,' }');
|
||||
flush(outfile);
|
||||
exit;
|
||||
end;
|
||||
#0 : commenteof;
|
||||
else if not stripcomment then
|
||||
write(outfile,c);
|
||||
flush(outfile);
|
||||
end;
|
||||
until false;
|
||||
flush(outfile);
|
||||
end;
|
||||
\"[^\"]*\" return(CSTRING);
|
||||
\'[^\']*\' return(CSTRING);
|
||||
"L"\"[^\"]*\" if win32headers then
|
||||
return(CSTRING)
|
||||
else
|
||||
return(256);
|
||||
"L"\'[^\']*\' if win32headers then
|
||||
return(CSTRING)
|
||||
else
|
||||
return(256);
|
||||
{D}*[U]?[L]? begin
|
||||
if yytext[length(yytext)]='L' then
|
||||
dec(byte(yytext[0]));
|
||||
if yytext[length(yytext)]='U' then
|
||||
dec(byte(yytext[0]));
|
||||
return(NUMBER);
|
||||
end;
|
||||
"0x"[0-9A-Fa-f]*[U]?[L]? begin
|
||||
(* handle pre- and postfixes *)
|
||||
if copy(yytext,1,2)='0x' then
|
||||
begin
|
||||
delete(yytext,1,2);
|
||||
yytext:='$'+yytext;
|
||||
end;
|
||||
if yytext[length(yytext)]='L' then
|
||||
dec(byte(yytext[0]));
|
||||
if yytext[length(yytext)]='U' then
|
||||
dec(byte(yytext[0]));
|
||||
return(NUMBER);
|
||||
end;
|
||||
|
||||
{D}+(\.{D}+)?([Ee][+-]?{D}+)?
|
||||
begin
|
||||
return(NUMBER);
|
||||
end;
|
||||
|
||||
"->" if in_define then
|
||||
return(DEREF)
|
||||
else
|
||||
return(256);
|
||||
"-" return(MINUS);
|
||||
"==" return(EQUAL);
|
||||
"!=" return(UNEQUAL);
|
||||
">=" return(GTE);
|
||||
"<=" return(LTE);
|
||||
">>" return(_SHR);
|
||||
"##" return(STICK);
|
||||
"<<" return(_SHL);
|
||||
">" return(GT);
|
||||
"<" return(LT);
|
||||
"|" return(_OR);
|
||||
"&" return(_AND);
|
||||
"!" return(_NOT);
|
||||
"/" return(_SLASH);
|
||||
"+" return(_PLUS);
|
||||
"?" return(QUESTIONMARK);
|
||||
":" return(COLON);
|
||||
"," return(COMMA);
|
||||
"[" return(LECKKLAMMER);
|
||||
"]" return(RECKKLAMMER);
|
||||
"(" begin
|
||||
inc(arglevel);
|
||||
return(LKLAMMER);
|
||||
end;
|
||||
")" begin
|
||||
dec(arglevel);
|
||||
return(RKLAMMER);
|
||||
end;
|
||||
"*" return(STAR);
|
||||
"..." return(ELLIPSIS);
|
||||
"." if in_define then
|
||||
return(POINT)
|
||||
else
|
||||
return(256);
|
||||
"=" return(_ASSIGN);
|
||||
"extern" return(EXTERN);
|
||||
"STDCALL" if Win32headers then
|
||||
return(STDCALL)
|
||||
else
|
||||
return(ID);
|
||||
"CDECL" if not Win32headers then
|
||||
return(ID)
|
||||
else
|
||||
return(CDECL);
|
||||
"PASCAL" if not Win32headers then
|
||||
return(ID)
|
||||
else
|
||||
return(PASCAL);
|
||||
"PACKED" if not Win32headers then
|
||||
return(ID)
|
||||
else
|
||||
return(_PACKED);
|
||||
"WINAPI" if not Win32headers then
|
||||
return(ID)
|
||||
else
|
||||
return(WINAPI);
|
||||
"SYS_TRAP" if not palmpilot then
|
||||
return(ID)
|
||||
else
|
||||
return(SYS_TRAP);
|
||||
"WINGDIAPI" if not Win32headers then
|
||||
return(ID)
|
||||
else
|
||||
return(WINGDIAPI);
|
||||
"CALLBACK" if not Win32headers then
|
||||
return(ID)
|
||||
else
|
||||
return(CALLBACK);
|
||||
"EXPENTRY" if not Win32headers then
|
||||
return(ID)
|
||||
else
|
||||
return(CALLBACK);
|
||||
|
||||
"void" return(VOID);
|
||||
"VOID" return(VOID);
|
||||
"#ifdef __cplusplus"[ \t]*\n"extern \"C\" {"\n"#endif"
|
||||
writeln(outfile,'{ C++ extern C conditionnal removed }');
|
||||
"#ifdef __cplusplus"[ \t]*\n"}"\n"#endif"
|
||||
writeln(outfile,'{ C++ end of extern C conditionnal removed }');
|
||||
|
||||
"#else" begin
|
||||
writeln(outfile,'{$else}');
|
||||
block_type:=bt_no;
|
||||
flush(outfile);
|
||||
end;
|
||||
"#endif" begin
|
||||
writeln(outfile,'{$endif}');
|
||||
block_type:=bt_no;
|
||||
flush(outfile);
|
||||
end;
|
||||
"#elif" begin
|
||||
write(outfile,'(*** was #elif ****)');
|
||||
write(outfile,'{$else');
|
||||
c:=get_char;
|
||||
while c<>newline do
|
||||
begin write(outfile,c);c:=get_char;end;
|
||||
writeln(outfile,'}');
|
||||
block_type:=bt_no;
|
||||
flush(outfile);
|
||||
next_line;
|
||||
end;
|
||||
"#undef" begin
|
||||
write(outfile,'{$undef');
|
||||
c:=get_char;
|
||||
while c<>newline do
|
||||
begin write(outfile,c);c:=get_char;end;
|
||||
writeln(outfile,'}');
|
||||
flush(outfile);
|
||||
next_line;
|
||||
end;
|
||||
"#error" begin
|
||||
write(outfile,'{$error');
|
||||
c:=get_char;
|
||||
while c<>newline do
|
||||
begin
|
||||
write(outfile,c);
|
||||
c:=get_char;
|
||||
end;
|
||||
writeln(outfile,'}');
|
||||
flush(outfile);
|
||||
next_line;
|
||||
end;
|
||||
|
||||
"#include" begin
|
||||
write(outfile,'{$include');
|
||||
c:=get_char;
|
||||
while c<>newline do
|
||||
begin write(outfile,c);c:=get_char;end;
|
||||
writeln(outfile,'}');
|
||||
flush(outfile);
|
||||
block_type:=bt_no;
|
||||
next_line;
|
||||
end;
|
||||
"#if" begin
|
||||
write(outfile,'{$if');
|
||||
c:=get_char;
|
||||
while c<>newline do
|
||||
begin write(outfile,c);c:=get_char;end;
|
||||
writeln(outfile,'}');
|
||||
flush(outfile);
|
||||
block_type:=bt_no;
|
||||
next_line;
|
||||
end;
|
||||
"#pragma" begin
|
||||
write(outfile,'(** unsupported pragma');
|
||||
write(outfile,'#pragma');
|
||||
c:=get_char;
|
||||
while c<>newline do
|
||||
begin write(outfile,c);c:=get_char;end;
|
||||
writeln(outfile,'*)');
|
||||
flush(outfile);
|
||||
block_type:=bt_no;
|
||||
next_line;
|
||||
end;
|
||||
"#define" begin
|
||||
in_define:=true;
|
||||
in_space_define:=1;
|
||||
return(DEFINE);
|
||||
end;
|
||||
"char" return(_CHAR);
|
||||
"union" return(UNION);
|
||||
"enum" return(ENUM);
|
||||
"struct" return(STRUCT);
|
||||
"{" return(LGKLAMMER);
|
||||
"}" return(RGKLAMMER);
|
||||
"typedef" return(TYPEDEF);
|
||||
"int" return(INT);
|
||||
"short" return(SHORT);
|
||||
"long" return(LONG);
|
||||
"unsigned" return(UNSIGNED);
|
||||
"float" return(REAL);
|
||||
"const" return(_CONST);
|
||||
"CONST" return(_CONST);
|
||||
"FAR" return(_FAR);
|
||||
"far" return(_FAR);
|
||||
"NEAR" return(_NEAR);
|
||||
"near" return(_NEAR);
|
||||
"HUGE" return(_HUGE);
|
||||
"huge" return(_HUGE);
|
||||
[A-Za-z_][A-Za-z0-9_]* begin
|
||||
if in_space_define=1 then
|
||||
in_space_define:=2;
|
||||
return(ID);
|
||||
end;
|
||||
";" return(SEMICOLON);
|
||||
[ \f\t] if arglevel=0 then
|
||||
if in_space_define=2 then
|
||||
begin
|
||||
in_space_define:=0;
|
||||
return(SPACE_DEFINE);
|
||||
end;
|
||||
\\\n begin
|
||||
next_line;
|
||||
if arglevel=0 then
|
||||
if in_space_define=2 then
|
||||
begin
|
||||
in_space_define:=0;
|
||||
return(SPACE_DEFINE);
|
||||
end;
|
||||
end;
|
||||
\n begin
|
||||
next_line;
|
||||
if in_define then
|
||||
begin
|
||||
in_define:=false;
|
||||
in_space_define:=0;
|
||||
return(NEW_LINE);
|
||||
end;
|
||||
end;
|
||||
. begin
|
||||
writeln('Illegal character in line ',line_no);
|
||||
writeln(last_source_line);
|
||||
return(256 { error });
|
||||
end;
|
||||
%%
|
||||
|
||||
function act_token : string;
|
||||
begin
|
||||
act_token:=yytext;
|
||||
end;
|
||||
|
||||
Function ForceExtension(Const HStr,ext:String):String;
|
||||
{
|
||||
Return a filename which certainly has the extension ext
|
||||
(no dot in ext !!)
|
||||
}
|
||||
var
|
||||
j : longint;
|
||||
begin
|
||||
j:=length(Hstr);
|
||||
while (j>0) and (Hstr[j]<>'.') do
|
||||
dec(j);
|
||||
if j=0 then
|
||||
j:=255;
|
||||
ForceExtension:=Copy(Hstr,1,j-1)+'.'+Ext;
|
||||
end;
|
||||
|
||||
begin
|
||||
ProcessOptions;
|
||||
line_no := 1;
|
||||
assign(yyinput, inputfilename);
|
||||
reset(yyinput);
|
||||
assign(textinfile, inputfilename);
|
||||
reset(textinfile);
|
||||
readln(textinfile,last_source_line);
|
||||
assign(outfile, outputfilename);
|
||||
rewrite(outfile);
|
||||
if not(includefile) then
|
||||
begin
|
||||
writeln(outfile,'unit ',unitname,';');
|
||||
writeln(outfile);
|
||||
writeln(outfile,'{ Automatically converted by H2PAS.EXE from '+inputfilename);
|
||||
writeln(outfile,' Utility made by Florian Klaempfl 25th-28th september 96');
|
||||
writeln(outfile,' Improvements made by Mark A. Malakanov 22nd-25th may 97 ');
|
||||
writeln(outfile,' Further improvements by Michael Van Canneyt, April 1998 ');
|
||||
writeln(outfile,' define handling and error recovery by Pierre Muller, June 1998 }');
|
||||
writeln(outfile);
|
||||
writeln(outfile);
|
||||
writeln(outfile,' interface');
|
||||
writeln(outfile);
|
||||
writeln(outfile,' { C default packing is dword }');
|
||||
writeln(outfile);
|
||||
writeln(outfile,'{$PACKRECORDS 4}');
|
||||
end;
|
||||
if UsePPointers then
|
||||
begin
|
||||
{ Define some pointers to basic pascal types }
|
||||
writeln(outfile);
|
||||
Writeln(outfile,' { Pointers to basic pascal types, inserted by h2pas conversion program.}');
|
||||
Writeln(outfile,' Type');
|
||||
Writeln(outfile,' PLongint = ^Longint;');
|
||||
Writeln(outfile,' PByte = ^Byte;');
|
||||
Writeln(outfile,' PWord = ^Word;');
|
||||
Writeln(outfile,' PInteger = ^Integer;');
|
||||
Writeln(outfile,' PCardinal = ^Cardinal;');
|
||||
Writeln(outfile,' PReal = ^Real;');
|
||||
Writeln(outfile,' PDouble = ^Double;');
|
||||
Writeln(outfile);
|
||||
end;
|
||||
end.
|
||||
|
4705
utils/h2pas/scan.pas
Normal file
4705
utils/h2pas/scan.pas
Normal file
File diff suppressed because it is too large
Load Diff
38
utils/h2pas/testit.h
Normal file
38
utils/h2pas/testit.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
Test header file to test conversion program.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
int x;
|
||||
int y;
|
||||
} a;
|
||||
|
||||
typedef union fpk {
|
||||
int X;
|
||||
int y;
|
||||
int z;
|
||||
} b;
|
||||
|
||||
typedef _test test;
|
||||
|
||||
struct _test
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
void proc(int *,int);
|
||||
void proc(int *p,int i);
|
||||
|
||||
typedef enum { First, second, third } C;
|
||||
|
||||
typedef enum { DFirst = 1, DSecond = 2, DThird = 3 } D;
|
||||
|
||||
typedef enum { EFirst = 100, ESecond, EThird } D;
|
||||
|
||||
void someproc(char *Firstarg,...);
|
||||
|
||||
mytype* somefunc (char *firstarg);
|
||||
|
||||
#define test 0x012345UL
|
||||
|
120
utils/h2pas/yacclib.pas
Normal file
120
utils/h2pas/yacclib.pas
Normal file
@ -0,0 +1,120 @@
|
||||
{
|
||||
Yacc Library Unit for TP Yacc
|
||||
|
||||
|
||||
Copyright (c) 1990-92 Albert Graef <ag@muwiinfa.geschichte.uni-mainz.de>
|
||||
Copyright (C) 1996 Berend de Boer <berend@pobox.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
$Revision$
|
||||
$Modtime: 96-08-01 14:04 $
|
||||
|
||||
$History: YACCLIB.PAS $
|
||||
*
|
||||
* ***************** Version 2 *****************
|
||||
* User: Berend Date: 96-10-10 Time: 21:16
|
||||
* Updated in $/Lex and Yacc/tply
|
||||
* Updated for protected mode, windows and Delphi 1.X and 2.X.
|
||||
|
||||
}
|
||||
|
||||
|
||||
{$I-}
|
||||
|
||||
unit YaccLib;
|
||||
|
||||
(* Yacc Library Unit for TP Yacc Version 3.0, 6-17-91 AG *)
|
||||
|
||||
interface
|
||||
|
||||
const yymaxdepth = 10000;
|
||||
(* default stack size of parser *)
|
||||
|
||||
type YYSType = Integer;
|
||||
(* default value type, may be redefined in Yacc output file *)
|
||||
|
||||
var
|
||||
|
||||
yychar : Integer; (* current lookahead character *)
|
||||
yynerrs : Integer; (* current number of syntax errors reported by the
|
||||
parser *)
|
||||
yydebug : Boolean; (* set to true to enable debugging output of parser *)
|
||||
|
||||
line_no : longint;
|
||||
|
||||
procedure yyerror ( msg : String );
|
||||
(* error message printing routine used by the parser *)
|
||||
|
||||
procedure yyclearin;
|
||||
(* delete the current lookahead token *)
|
||||
|
||||
procedure yyaccept;
|
||||
(* trigger accept action of the parser; yyparse accepts returning 0, as if
|
||||
it reached end of input *)
|
||||
|
||||
procedure yyabort;
|
||||
(* like yyaccept, but causes parser to return with value 1, as if an
|
||||
unrecoverable syntax error had been encountered *)
|
||||
|
||||
procedure yyerrlab;
|
||||
(* causes error recovery to be started, as if a syntax error had been
|
||||
encountered *)
|
||||
|
||||
procedure yyerrok;
|
||||
(* when in error mode, resets the parser to its normal mode of
|
||||
operation *)
|
||||
|
||||
(* Flags used internally by the parser routine: *)
|
||||
|
||||
var
|
||||
|
||||
yyflag : ( yyfnone, yyfaccept, yyfabort, yyferror );
|
||||
yyerrflag : Integer;
|
||||
|
||||
implementation
|
||||
|
||||
procedure yyerror ( msg : String );
|
||||
begin
|
||||
writeln('at line ',line_no,' error : ',msg);
|
||||
end(*yyerrmsg*);
|
||||
|
||||
procedure yyclearin;
|
||||
begin
|
||||
yychar := -1;
|
||||
end(*yyclearin*);
|
||||
|
||||
procedure yyaccept;
|
||||
begin
|
||||
yyflag := yyfaccept;
|
||||
end(*yyaccept*);
|
||||
|
||||
procedure yyabort;
|
||||
begin
|
||||
yyflag := yyfabort;
|
||||
end(*yyabort*);
|
||||
|
||||
procedure yyerrlab;
|
||||
begin
|
||||
yyflag := yyferror;
|
||||
end(*yyerrlab*);
|
||||
|
||||
procedure yyerrok;
|
||||
begin
|
||||
yyerrflag := 0;
|
||||
end(*yyerrork*);
|
||||
|
||||
end(*YaccLib*).
|
80
utils/h2pas/yylex.cod
Normal file
80
utils/h2pas/yylex.cod
Normal file
@ -0,0 +1,80 @@
|
||||
|
||||
(* lexical analyzer template (TP Lex V3.0), V1.0 3-2-91 AG *)
|
||||
|
||||
(* global definitions: *)
|
||||
%%
|
||||
|
||||
function yylex : Integer;
|
||||
|
||||
procedure yyaction ( yyruleno : Integer );
|
||||
(* local definitions: *)
|
||||
%%
|
||||
begin
|
||||
(* actions: *)
|
||||
case yyruleno of
|
||||
%%
|
||||
end;
|
||||
end(*yyaction*);
|
||||
|
||||
(* DFA table: *)
|
||||
%%
|
||||
|
||||
var yyn : Integer;
|
||||
|
||||
label start, scan, action;
|
||||
|
||||
begin
|
||||
|
||||
start:
|
||||
|
||||
(* initialize: *)
|
||||
|
||||
yynew;
|
||||
|
||||
scan:
|
||||
|
||||
(* mark positions and matches: *)
|
||||
|
||||
for yyn := yykl[yystate] to yykh[yystate] do yymark(yyk[yyn]);
|
||||
for yyn := yymh[yystate] downto yyml[yystate] do yymatch(yym[yyn]);
|
||||
|
||||
if yytl[yystate]>yyth[yystate] then goto action; (* dead state *)
|
||||
|
||||
(* get next character: *)
|
||||
|
||||
yyscan;
|
||||
|
||||
(* determine action: *)
|
||||
|
||||
yyn := yytl[yystate];
|
||||
while (yyn<=yyth[yystate]) and not (yyactchar in yyt[yyn].cc) do inc(yyn);
|
||||
if yyn>yyth[yystate] then goto action;
|
||||
(* no transition on yyactchar in this state *)
|
||||
|
||||
(* switch to new state: *)
|
||||
|
||||
yystate := yyt[yyn].s;
|
||||
|
||||
goto scan;
|
||||
|
||||
action:
|
||||
|
||||
(* execute action: *)
|
||||
|
||||
if yyfind(yyrule) then
|
||||
begin
|
||||
yyaction(yyrule);
|
||||
if yyreject then goto action;
|
||||
end
|
||||
else if not yydefault and yywrap then
|
||||
begin
|
||||
yyclear;
|
||||
return(0);
|
||||
end;
|
||||
|
||||
if not yydone then goto start;
|
||||
|
||||
yylex := yyretval;
|
||||
|
||||
end(*yylex*);
|
||||
|
184
utils/h2pas/yyparse.cod
Normal file
184
utils/h2pas/yyparse.cod
Normal file
@ -0,0 +1,184 @@
|
||||
|
||||
(* Yacc parser template (TP Yacc V3.0), V1.2 6-17-91 AG *)
|
||||
|
||||
(* global definitions: *)
|
||||
%%
|
||||
|
||||
var yylval : YYSType;
|
||||
|
||||
function yylex : Integer; forward;
|
||||
|
||||
function yyparse : Integer;
|
||||
|
||||
var yystate, yysp, yyn : Integer;
|
||||
yys : array [1..yymaxdepth] of Integer;
|
||||
yyv : array [1..yymaxdepth] of YYSType;
|
||||
yyval : YYSType;
|
||||
|
||||
procedure yyaction ( yyruleno : Integer );
|
||||
(* local definitions: *)
|
||||
%%
|
||||
begin
|
||||
(* actions: *)
|
||||
case yyruleno of
|
||||
%%
|
||||
end;
|
||||
end(*yyaction*);
|
||||
|
||||
(* parse table: *)
|
||||
%%
|
||||
|
||||
const _error = 256; (* error token *)
|
||||
|
||||
function yyact(state, sym : Integer; var act : Integer) : Boolean;
|
||||
(* search action table *)
|
||||
var k : Integer;
|
||||
begin
|
||||
k := yyal[state];
|
||||
while (k<=yyah[state]) and (yya[k].sym<>sym) do inc(k);
|
||||
if k>yyah[state] then
|
||||
yyact := false
|
||||
else
|
||||
begin
|
||||
act := yya[k].act;
|
||||
yyact := true;
|
||||
end;
|
||||
end(*yyact*);
|
||||
|
||||
function yygoto(state, sym : Integer; var nstate : Integer) : Boolean;
|
||||
(* search goto table *)
|
||||
var k : Integer;
|
||||
begin
|
||||
k := yygl[state];
|
||||
while (k<=yygh[state]) and (yyg[k].sym<>sym) do inc(k);
|
||||
if k>yygh[state] then
|
||||
yygoto := false
|
||||
else
|
||||
begin
|
||||
nstate := yyg[k].act;
|
||||
yygoto := true;
|
||||
end;
|
||||
end(*yygoto*);
|
||||
|
||||
label parse, next, error, errlab, shift, reduce, accept, abort;
|
||||
|
||||
begin(*yyparse*)
|
||||
|
||||
(* initialize: *)
|
||||
|
||||
yystate := 0; yychar := -1; yynerrs := 0; yyerrflag := 0; yysp := 0;
|
||||
|
||||
{$ifdef yydebug}
|
||||
yydebug := true;
|
||||
{$else}
|
||||
yydebug := false;
|
||||
{$endif}
|
||||
|
||||
parse:
|
||||
|
||||
(* push state and value: *)
|
||||
|
||||
inc(yysp);
|
||||
if yysp>yymaxdepth then
|
||||
begin
|
||||
yyerror('yyparse stack overflow');
|
||||
goto abort;
|
||||
end;
|
||||
yys[yysp] := yystate; yyv[yysp] := yyval;
|
||||
|
||||
next:
|
||||
|
||||
if (yyd[yystate]=0) and (yychar=-1) then
|
||||
(* get next symbol *)
|
||||
begin
|
||||
yychar := yylex; if yychar<0 then yychar := 0;
|
||||
end;
|
||||
|
||||
if yydebug then writeln('state ', yystate, ', char ', yychar);
|
||||
|
||||
(* determine parse action: *)
|
||||
|
||||
yyn := yyd[yystate];
|
||||
if yyn<>0 then goto reduce; (* simple state *)
|
||||
|
||||
(* no default action; search parse table *)
|
||||
|
||||
if not yyact(yystate, yychar, yyn) then goto error
|
||||
else if yyn>0 then goto shift
|
||||
else if yyn<0 then goto reduce
|
||||
else goto accept;
|
||||
|
||||
error:
|
||||
|
||||
(* error; start error recovery: *)
|
||||
|
||||
if yyerrflag=0 then yyerror('syntax error');
|
||||
|
||||
errlab:
|
||||
|
||||
if yyerrflag=0 then inc(yynerrs); (* new error *)
|
||||
|
||||
if yyerrflag<=2 then (* incomplete recovery; try again *)
|
||||
begin
|
||||
yyerrflag := 3;
|
||||
(* uncover a state with shift action on error token *)
|
||||
while (yysp>0) and not ( yyact(yys[yysp], _error, yyn) and
|
||||
(yyn>0) ) do
|
||||
begin
|
||||
if yydebug then
|
||||
if yysp>1 then
|
||||
writeln('error recovery pops state ', yys[yysp], ', uncovers ',
|
||||
yys[yysp-1])
|
||||
else
|
||||
writeln('error recovery fails ... abort');
|
||||
dec(yysp);
|
||||
end;
|
||||
if yysp=0 then goto abort; (* parser has fallen from stack; abort *)
|
||||
yystate := yyn; (* simulate shift on error *)
|
||||
goto parse;
|
||||
end
|
||||
else (* no shift yet; discard symbol *)
|
||||
begin
|
||||
if yydebug then writeln('error recovery discards char ', yychar);
|
||||
if yychar=0 then goto abort; (* end of input; abort *)
|
||||
yychar := -1; goto next; (* clear lookahead char and try again *)
|
||||
end;
|
||||
|
||||
shift:
|
||||
|
||||
(* go to new state, clear lookahead character: *)
|
||||
|
||||
yystate := yyn; yychar := -1; yyval := yylval;
|
||||
if yyerrflag>0 then dec(yyerrflag);
|
||||
|
||||
goto parse;
|
||||
|
||||
reduce:
|
||||
|
||||
(* execute action, pop rule from stack, and go to next state: *)
|
||||
|
||||
if yydebug then writeln('reduce ', -yyn);
|
||||
|
||||
yyflag := yyfnone; yyaction(-yyn);
|
||||
dec(yysp, yyr[-yyn].len);
|
||||
if yygoto(yys[yysp], yyr[-yyn].sym, yyn) then yystate := yyn;
|
||||
|
||||
(* handle action calls to yyaccept, yyabort and yyerror: *)
|
||||
|
||||
case yyflag of
|
||||
yyfaccept : goto accept;
|
||||
yyfabort : goto abort;
|
||||
yyferror : goto errlab;
|
||||
end;
|
||||
|
||||
goto parse;
|
||||
|
||||
accept:
|
||||
|
||||
yyparse := 0; exit;
|
||||
|
||||
abort:
|
||||
|
||||
yyparse := 1; exit;
|
||||
|
||||
end(*yyparse*);
|
629
utils/ppdep.pp
Normal file
629
utils/ppdep.pp
Normal file
@ -0,0 +1,629 @@
|
||||
{
|
||||
$Id$
|
||||
This program is part of the Free Pascal run time library.
|
||||
Copyright (c) 1997 by Peter Vreman
|
||||
member of the Free Pascal development team
|
||||
|
||||
See the file COPYING.FPC, included in this distribution,
|
||||
for details about the copyright.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
**********************************************************************}
|
||||
|
||||
{ Program to create a depend makefile for a program with multiple units }
|
||||
|
||||
program ppdep;
|
||||
uses Dos;
|
||||
|
||||
{.$define debug}
|
||||
|
||||
const
|
||||
{$ifdef linux}
|
||||
exeext='';
|
||||
{$else}
|
||||
exeext='.EXE';
|
||||
{$endif}
|
||||
|
||||
type
|
||||
PUses=^TUses;
|
||||
TUses=record
|
||||
Name : string[32];
|
||||
Next : PUses;
|
||||
end;
|
||||
PUnit=^TUnit;
|
||||
TUnit=record
|
||||
UsesList : PUses;
|
||||
PasFn,
|
||||
Name : string[32];
|
||||
IsUnit : boolean;
|
||||
Next : PUnit;
|
||||
end;
|
||||
PDefine=^TDefine;
|
||||
TDefine = Record
|
||||
Name : String[32];
|
||||
Next : PDefine;
|
||||
end;
|
||||
|
||||
|
||||
var
|
||||
UnitList : PUnit;
|
||||
Define : PDefine;
|
||||
ParaFile : string;
|
||||
Verbose : boolean;
|
||||
AddCall : byte;
|
||||
CallLine,
|
||||
OutFile : String;
|
||||
UnitExt : String;
|
||||
|
||||
{****************************************************************************
|
||||
Handy Routines
|
||||
****************************************************************************}
|
||||
|
||||
function UCase(Const Hstr:string):string;
|
||||
var
|
||||
i : longint;
|
||||
begin
|
||||
for i:=1to Length(Hstr) do
|
||||
UCase[i]:=Upcase(Hstr[i]);
|
||||
UCase[0]:=chr(Length(Hstr));
|
||||
end;
|
||||
|
||||
|
||||
function FixFn(const s:string):string;
|
||||
var
|
||||
i : longint;
|
||||
NoPath : boolean;
|
||||
begin
|
||||
NoPath:=true;
|
||||
for i:=length(s) downto 1 do
|
||||
begin
|
||||
case s[i] of
|
||||
{$ifdef Linux}
|
||||
'/','\' : begin
|
||||
FixFn[i]:='/';
|
||||
NoPath:=false; {Skip lowercasing path: 'X11'<>'x11' }
|
||||
end;
|
||||
'A'..'Z' : if NoPath then
|
||||
FixFn[i]:=char(byte(s[i])+32)
|
||||
else
|
||||
FixFn[i]:=s[i];
|
||||
{$else}
|
||||
'/' : FixFn[i]:='\';
|
||||
'A'..'Z' : FixFn[i]:=char(byte(s[i])+32); { everything lowercase }
|
||||
{$endif}
|
||||
else
|
||||
FixFn[i]:=s[i];
|
||||
end;
|
||||
end;
|
||||
FixFn[0]:=Chr(Length(s));
|
||||
end;
|
||||
|
||||
|
||||
{****************************************************************************
|
||||
Main Program
|
||||
****************************************************************************}
|
||||
|
||||
Function SearchPas(const fn:string):string;
|
||||
var
|
||||
Dir : SearchRec;
|
||||
begin
|
||||
FindFirst(FixFn(fn+'.PP'),$20,Dir);
|
||||
if Doserror=0 then
|
||||
SearchPas:=FixFn(fn+'.PP')
|
||||
else
|
||||
SearchPas:=FixFn(fn+'.PAS')
|
||||
end;
|
||||
|
||||
|
||||
Function UnitDone(const fn:string):boolean;
|
||||
var
|
||||
hp : PUnit;
|
||||
begin
|
||||
hp:=UnitList;
|
||||
while not (hp=nil) do
|
||||
begin
|
||||
if hp^.Name=fn then
|
||||
begin
|
||||
UnitDone:=true;
|
||||
exit;
|
||||
end;
|
||||
hp:=hp^.Next;
|
||||
end;
|
||||
UnitDone:=false;
|
||||
end;
|
||||
|
||||
|
||||
Function CheckDefine(const s:string):boolean;
|
||||
var
|
||||
ss : string[32];
|
||||
P : PDefine;
|
||||
begin
|
||||
ss:=ucase(s);
|
||||
P:=Define;
|
||||
while (p<>Nil) do
|
||||
begin
|
||||
if ss=p^.name then
|
||||
begin
|
||||
CheckDefine:=true;
|
||||
exit;
|
||||
end;
|
||||
P:=P^.Next;
|
||||
end;
|
||||
CheckDefine:=false;
|
||||
end;
|
||||
|
||||
Procedure AddDefine(Const S : String);
|
||||
Var
|
||||
P : PDefine;
|
||||
begin
|
||||
New(P);
|
||||
P^.Name:=Ucase(S);
|
||||
P^.Next:=Define;
|
||||
Define:=P;
|
||||
end;
|
||||
|
||||
|
||||
procedure RemoveSep(var fn:string);
|
||||
var
|
||||
i : longint;
|
||||
begin
|
||||
i:=0;
|
||||
while (i<length(fn)) and (fn[i+1] in [',',' ',#9]) do
|
||||
inc(i);
|
||||
Delete(fn,1,i);
|
||||
end;
|
||||
|
||||
|
||||
function GetName(var fn:string):string;
|
||||
var
|
||||
i : longint;
|
||||
begin
|
||||
i:=0;
|
||||
while (i<length(fn)) and (fn[i+1] in ['A'..'Z','0'..'9','_','-']) do
|
||||
inc(i);
|
||||
GetName:=Copy(fn,1,i);
|
||||
Delete(fn,1,i);
|
||||
end;
|
||||
|
||||
|
||||
procedure ListDepend(const fn:string);
|
||||
|
||||
{$ifndef FPC}
|
||||
procedure readln(var t:text;var s:string);
|
||||
var
|
||||
c : char;
|
||||
i : longint;
|
||||
begin
|
||||
c:=#0;
|
||||
i:=0;
|
||||
while (not eof(t)) and (c<>#10) do
|
||||
begin
|
||||
read(t,c);
|
||||
if c<>#10 then
|
||||
begin
|
||||
inc(i);
|
||||
s[i]:=c;
|
||||
end;
|
||||
end;
|
||||
if (i>0) and (s[i]=#13) then
|
||||
dec(i);
|
||||
s[0]:=chr(i);
|
||||
end;
|
||||
{$endif}
|
||||
|
||||
const
|
||||
MaxLevel=200;
|
||||
var
|
||||
f : text;
|
||||
hs : ^string;
|
||||
curruses,lastuses : PUses;
|
||||
currunit,lastunit : PUnit;
|
||||
i,j : longint;
|
||||
UsesDone,
|
||||
OldComment,
|
||||
Done,Comment,
|
||||
InImplementation : boolean;
|
||||
Skip : array[0..MaxLevel] of boolean;
|
||||
Level : byte;
|
||||
begin
|
||||
if UnitDone(fn) then
|
||||
exit;
|
||||
new(hs);
|
||||
new(currunit);
|
||||
currunit^.next:=nil;
|
||||
currunit^.Name:=fn;
|
||||
currunit^.IsUnit:=true;
|
||||
currunit^.PasFn:=SearchPas(fn);
|
||||
currunit^.useslist:=nil;
|
||||
assign(f,currunit^.PasFn);
|
||||
{$I-}
|
||||
reset(f);
|
||||
{$I+}
|
||||
if ioresult=0 then
|
||||
begin
|
||||
if verbose then
|
||||
Writeln('Processing ',currunit^.PasFn);
|
||||
{Add to Linked List}
|
||||
if unitlist=nil then
|
||||
unitlist:=currunit
|
||||
else
|
||||
begin
|
||||
lastunit:=UnitList;
|
||||
while not (lastunit^.Next=nil) do
|
||||
lastunit:=lastunit^.next;
|
||||
lastunit^.next:=currunit;
|
||||
end;
|
||||
{Parse file}
|
||||
InImplementation:=false;
|
||||
done:=false;
|
||||
usesdone:=true;
|
||||
Comment:=false;
|
||||
OldComment:=false;
|
||||
FillChar(skip,sizeof(Skip),0);
|
||||
hs^:='';
|
||||
Level:=0;
|
||||
while (not done) and (not Eof(f)) do
|
||||
begin
|
||||
repeat
|
||||
if hs^='' then
|
||||
begin
|
||||
ReadLn(f,hs^);
|
||||
hs^:=UCase(hs^);
|
||||
end;
|
||||
RemoveSep(hs^);
|
||||
until (hs^<>'') or Eof(f);
|
||||
if Comment then
|
||||
begin
|
||||
i:=pos('}',hs^);
|
||||
if (i>0) then
|
||||
begin
|
||||
j:=pos('{',hs^);
|
||||
if (j>0) and (j<i) then
|
||||
begin
|
||||
Comment:=true;
|
||||
Delete(hs^,1,j-1);
|
||||
end
|
||||
else
|
||||
begin
|
||||
Comment:=false;
|
||||
Delete(hs^,1,i-1);
|
||||
end;
|
||||
end
|
||||
else
|
||||
hs^:='';
|
||||
end;
|
||||
if (pos('(*',hs^)>0) or OldComment then
|
||||
begin
|
||||
i:=pos('*)',hs^);
|
||||
if (i>0) then
|
||||
begin
|
||||
OldComment:=false;
|
||||
Delete(hs^,1,i+1);
|
||||
end
|
||||
else
|
||||
begin
|
||||
OldComment:=true;
|
||||
hs^:='';
|
||||
end;
|
||||
end;
|
||||
if (hs^<>'') then
|
||||
begin
|
||||
case hs^[1] of
|
||||
'}' : begin
|
||||
Comment:=false;
|
||||
hs^:='';
|
||||
end;
|
||||
'{' : begin
|
||||
if (Copy(hs^,2,6)='$IFDEF') then
|
||||
begin
|
||||
Delete(hs^,1,7);
|
||||
RemoveSep(hs^);
|
||||
inc(Level);
|
||||
if Level>=MaxLevel then
|
||||
begin
|
||||
Writeln('Too many IF(N)DEFs');
|
||||
Halt(1);
|
||||
end;
|
||||
skip[level]:=skip[level-1] or (not CheckDefine(GetName(hs^)));
|
||||
hs^:='';
|
||||
end
|
||||
else
|
||||
if (Copy(hs^,2,7)='$IFNDEF') then
|
||||
begin
|
||||
Delete(hs^,1,7);
|
||||
RemoveSep(hs^);
|
||||
inc(Level);
|
||||
if Level>=MaxLevel then
|
||||
begin
|
||||
Writeln('Too many IF(N)DEFs');
|
||||
Halt(1);
|
||||
end;
|
||||
skip[level]:=skip[level-1] or (CheckDefine(GetName(hs^)));
|
||||
hs^:='';
|
||||
end
|
||||
else
|
||||
if (Copy(hs^,2,6)='$ELSE') then
|
||||
begin
|
||||
skip[level]:=skip[level-1] or (not skip[level]);
|
||||
hs^:='';
|
||||
end
|
||||
else
|
||||
if (Copy(hs^,2,6)='$ENDIF') then
|
||||
begin
|
||||
skip[level]:=false;
|
||||
if Level=0 then
|
||||
begin
|
||||
Writeln('Too many ENDIFs');
|
||||
Halt(1);
|
||||
end;
|
||||
dec(level);
|
||||
hs^:='';
|
||||
end
|
||||
else
|
||||
if (Copy(hs^,2,6)='$IFOPT') then
|
||||
begin
|
||||
inc(Level);
|
||||
if Level>=MaxLevel then
|
||||
begin
|
||||
Writeln('Too many IF(N)DEFs');
|
||||
Halt(1);
|
||||
end;
|
||||
skip[level]:=true;
|
||||
hs^:='';
|
||||
end
|
||||
else
|
||||
begin
|
||||
i:=pos('}',hs^);
|
||||
if i>0 then
|
||||
begin
|
||||
Delete(hs^,1,i);
|
||||
Comment:=false;
|
||||
end
|
||||
else
|
||||
Comment:=true;
|
||||
end;
|
||||
end;
|
||||
';' : begin
|
||||
UsesDone:=true;
|
||||
Done:=(UsesDone and InImplementation);
|
||||
hs^:='';
|
||||
end;
|
||||
else
|
||||
begin
|
||||
if skip[level] then
|
||||
hs^:=''
|
||||
else
|
||||
begin
|
||||
if (not UsesDone) then
|
||||
begin
|
||||
new(curruses);
|
||||
curruses^.Name:=GetName(hs^);
|
||||
curruses^.next:=nil;
|
||||
if currunit^.useslist=nil then
|
||||
currunit^.useslist:=curruses
|
||||
else
|
||||
begin
|
||||
lastuses:=currunit^.useslist;
|
||||
while not (lastuses^.Next=nil) do
|
||||
lastuses:=lastuses^.next;
|
||||
lastuses^.next:=curruses;
|
||||
end;
|
||||
{$ifndef debug}
|
||||
ListDepend(curruses^.Name);
|
||||
{$endif}
|
||||
RemoveSep(hs^);
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (Copy(hs^,1,4)='USES') and ((length(hs^)=4) or (hs^[5] in [' ',#9])) then
|
||||
begin
|
||||
Delete(hs^,1,4);
|
||||
UsesDone:=false;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (hs^='IMPLEMENTATION') then
|
||||
InImplementation:=true
|
||||
else
|
||||
if (Copy(hs^,1,7)='PROGRAM') then
|
||||
begin
|
||||
currunit^.IsUnit:=false;
|
||||
InImplementation:=true; {there can be only 1 uses}
|
||||
end
|
||||
else
|
||||
if InImplementation and ((copy(hs^,1,5)='CONST') or
|
||||
(copy(hs^,1,3)='VAR') or (copy(hs^,1,5)='BEGIN')) then
|
||||
done:=true;
|
||||
hs^:='';
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
Close(f);
|
||||
end
|
||||
else
|
||||
dispose(currunit);
|
||||
dispose(hs);
|
||||
end;
|
||||
|
||||
|
||||
procedure ShowDepend;
|
||||
var
|
||||
currunit : PUnit;
|
||||
curruses : PUses;
|
||||
t : text;
|
||||
P : PDefine;
|
||||
First : boolean;
|
||||
begin
|
||||
if CallLine='' then
|
||||
begin
|
||||
CallLine:='ppc386 ';
|
||||
P:=Define;
|
||||
While P<>Nil do
|
||||
begin
|
||||
CallLine:=CallLine+' -d'+P^.Name;
|
||||
P:=P^.Next;
|
||||
end;
|
||||
end;
|
||||
assign(t,OutFile);
|
||||
rewrite(t);
|
||||
currunit:=UnitList;
|
||||
First:=true;
|
||||
while not (currunit=nil) do
|
||||
begin
|
||||
if currunit^.IsUnit then
|
||||
Write(t,FixFn(currunit^.Name+'.'+unitext)+': '+currunit^.PasFn)
|
||||
else
|
||||
Write(t,FixFn(currunit^.Name+exeext)+': '+currunit^.PasFn);
|
||||
curruses:=currunit^.useslist;
|
||||
while not (curruses=nil) do
|
||||
begin
|
||||
{$ifndef debug}
|
||||
if UnitDone(curruses^.name) then
|
||||
{$endif}
|
||||
begin
|
||||
writeln(t,' \');
|
||||
write(t,#9+FixFn(curruses^.name+'.'+unitext));
|
||||
end;
|
||||
curruses:=curruses^.next;
|
||||
end;
|
||||
writeln(t,'');
|
||||
If (AddCall=2) or (First and (AddCall=1)) then
|
||||
writeln(t,#9,CallLine,' ',currunit^.PasFn);
|
||||
writeln(t,'');
|
||||
currunit:=currunit^.next;
|
||||
First:=false;
|
||||
end;
|
||||
close(t);
|
||||
end;
|
||||
|
||||
|
||||
procedure getpara;
|
||||
var
|
||||
ch : char;
|
||||
para : string[128];
|
||||
i : word;
|
||||
|
||||
procedure helpscreen;
|
||||
begin
|
||||
writeln('ppdep [Options] <File>');
|
||||
Writeln;
|
||||
Writeln('Options can be: -D<define> Define a symbol');
|
||||
Writeln(' -oFile Write output to file');
|
||||
WRiteln(' (default stdout)');
|
||||
Writeln(' -eext Set unit extension to ext');
|
||||
Writeln(' (default ppu)');
|
||||
Writeln(' -V Be more verbose');
|
||||
Writeln(' -? or -H This HelpScreen');
|
||||
Writeln(' -A[call] Add compiler calls to makefile');
|
||||
halt(1);
|
||||
end;
|
||||
|
||||
begin
|
||||
Define:=Nil;
|
||||
Outfile:='';
|
||||
AddCall:=0;
|
||||
Verbose:=False;
|
||||
{$IFDEF LINUX}
|
||||
UnitExt:='ppu';
|
||||
{$ELSE}
|
||||
UnitExt:='PPU';
|
||||
{$endif}
|
||||
for i:=1 to paramcount do
|
||||
begin
|
||||
para:=Paramstr(i);
|
||||
if (para[1]='-') then
|
||||
begin
|
||||
ch:=Upcase(para[2]);
|
||||
delete(para,1,2);
|
||||
case ch of
|
||||
'A' : begin
|
||||
AddCall:=2;
|
||||
CallLine:=Para;
|
||||
end;
|
||||
'F' : begin
|
||||
AddCall:=1;
|
||||
CallLine:=Para;
|
||||
end;
|
||||
'D' : AddDefine(para);
|
||||
'O' : OutFile:=Para;
|
||||
'E' : UnitExt:=Para;
|
||||
'V' : verbose:=true;
|
||||
'?','H' : helpscreen;
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
ParaFile:=Para;
|
||||
if Pos('.',ParaFile)>0 then
|
||||
Delete(Parafile,Pos('.',ParaFile),255);
|
||||
end;
|
||||
end;
|
||||
if (ParaFile='') then
|
||||
HelpScreen;
|
||||
end;
|
||||
|
||||
|
||||
begin
|
||||
GetPara;
|
||||
ListDepend(ParaFile);
|
||||
ShowDepend;
|
||||
end.
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.1 1999-05-12 16:11:39 peter
|
||||
* moved
|
||||
|
||||
Revision 1.1 1999/05/03 18:03:15 peter
|
||||
* renamed mkdep -> ppdep
|
||||
* removed obsolete units
|
||||
* add .cod files
|
||||
|
||||
Revision 1.7 1998/11/18 11:15:14 michael
|
||||
+ Added support for different unit extensions
|
||||
|
||||
Revision 1.6 1998/10/22 23:51:35 peter
|
||||
* better comment support
|
||||
|
||||
Revision 1.5 1998/08/10 09:55:21 peter
|
||||
* fix for uses in rejected part
|
||||
|
||||
Revision 1.4 1998/06/24 14:02:17 peter
|
||||
+ (* *) support
|
||||
|
||||
Revision 1.3 1998/06/23 14:01:18 peter
|
||||
+ -F to add a line to only the first file
|
||||
|
||||
Revision 1.2 1998/03/27 18:39:20 peter
|
||||
* fixed the preprocessor
|
||||
+ -A<call> to add the <call> to all the entries
|
||||
|
||||
Revision 1.1.1.1 1998/03/25 11:18:48 root
|
||||
* Restored version
|
||||
|
||||
Revision 1.5 1998/03/15 15:39:23 peter
|
||||
* fixed $ELSE
|
||||
|
||||
Revision 1.4 1998/03/10 12:53:24 peter
|
||||
* much better preprocessor
|
||||
+ IFOPT skipping
|
||||
|
||||
Revision 1.3 1998/03/02 13:45:34 peter
|
||||
* works better and exefile name is written when a program is parsed
|
||||
|
||||
Revision 1.2 1998/02/24 13:55:07 michael
|
||||
+ Added option to write to file. Default is to stdout
|
||||
+ Added option to write/not write a compiler call
|
||||
+ Nr of defines is now unlimited.
|
||||
* Fixed bug with uppercase filenames under linux.
|
||||
|
||||
Revision 1.1 1998/02/23 23:16:48 peter
|
||||
+ Initial implementation
|
||||
}
|
1013
utils/ppu.pas
Normal file
1013
utils/ppu.pas
Normal file
File diff suppressed because it is too large
Load Diff
1275
utils/ppudump.pp
Normal file
1275
utils/ppudump.pp
Normal file
File diff suppressed because it is too large
Load Diff
570
utils/ppumove.pp
Normal file
570
utils/ppumove.pp
Normal file
@ -0,0 +1,570 @@
|
||||
{
|
||||
$Id$
|
||||
Copyright (c) 1998 by the FPC Development Team
|
||||
|
||||
Add multiple FPC units into a static/shared library
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
****************************************************************************}
|
||||
{$ifdef TP}
|
||||
{$N+,E+}
|
||||
{$endif}
|
||||
Program ppumove;
|
||||
uses
|
||||
{$ifdef linux}
|
||||
linux,
|
||||
{$else linux}
|
||||
dos,
|
||||
{$endif linux}
|
||||
ppu,
|
||||
getopts;
|
||||
|
||||
const
|
||||
Version = 'Version 0.99.7';
|
||||
Title = 'PPU-Mover';
|
||||
Copyright = 'Copyright (c) 1998 by the Free Pascal Development Team';
|
||||
|
||||
ShortOpts = 'o:e:d:qhsvbw';
|
||||
BufSize = 4096;
|
||||
PPUExt = 'ppu';
|
||||
ObjExt = 'o';
|
||||
StaticLibExt ='a';
|
||||
{$ifdef Linux}
|
||||
SharedLibExt ='so';
|
||||
BatchExt ='.sh';
|
||||
{$else}
|
||||
SharedLibExt ='dll';
|
||||
BatchExt ='.bat';
|
||||
{$endif Linux}
|
||||
|
||||
|
||||
Type
|
||||
PLinkOEnt = ^TLinkOEnt;
|
||||
TLinkOEnt = record
|
||||
Name : string;
|
||||
Next : PLinkOEnt;
|
||||
end;
|
||||
|
||||
Var
|
||||
ArBin,LDBin,
|
||||
OutputFile,
|
||||
DestPath,
|
||||
PPLExt,
|
||||
LibExt : string;
|
||||
Batch,
|
||||
Quiet,
|
||||
MakeStatic : boolean;
|
||||
Buffer : Pointer;
|
||||
ObjFiles : PLinkOEnt;
|
||||
BatchFile : Text;
|
||||
|
||||
{*****************************************************************************
|
||||
Helpers
|
||||
*****************************************************************************}
|
||||
|
||||
Procedure Error(const s:string;stop:boolean);
|
||||
{
|
||||
Write an error message to stderr
|
||||
}
|
||||
begin
|
||||
{$ifdef FPC}
|
||||
writeln(stderr,s);
|
||||
flush(stderr);
|
||||
{$else}
|
||||
writeln(s);
|
||||
{$endif}
|
||||
if stop then
|
||||
halt(1);
|
||||
end;
|
||||
|
||||
|
||||
function Shell(const s:string):longint;
|
||||
{
|
||||
Run a shell commnad and return the exitcode
|
||||
}
|
||||
begin
|
||||
if Batch then
|
||||
begin
|
||||
Writeln(BatchFile,s);
|
||||
Shell:=0;
|
||||
exit;
|
||||
end;
|
||||
{$ifdef Linux}
|
||||
Shell:=Linux.shell(s);
|
||||
{$else}
|
||||
exec(getenv('COMSPEC'),'/C '+s);
|
||||
Shell:=DosExitCode;
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
|
||||
Function FileExists (Const F : String) : Boolean;
|
||||
{
|
||||
Returns True if the file exists, False if not.
|
||||
}
|
||||
Var
|
||||
{$ifdef linux}
|
||||
info : Stat;
|
||||
{$else}
|
||||
info : searchrec;
|
||||
{$endif}
|
||||
begin
|
||||
{$ifdef linux}
|
||||
FileExists:=FStat (F,Info);
|
||||
{$else}
|
||||
FindFirst (F,anyfile,Info);
|
||||
FileExists:=DosError=0;
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
|
||||
Function AddExtension(Const HStr,ext:String):String;
|
||||
{
|
||||
Return a filename which will have extension ext added if no
|
||||
extension is found
|
||||
}
|
||||
var
|
||||
j : longint;
|
||||
begin
|
||||
j:=length(Hstr);
|
||||
while (j>0) and (Hstr[j]<>'.') do
|
||||
dec(j);
|
||||
if j=0 then
|
||||
AddExtension:=Hstr+'.'+Ext
|
||||
else
|
||||
AddExtension:=HStr;
|
||||
end;
|
||||
|
||||
|
||||
Function ForceExtension(Const HStr,ext:String):String;
|
||||
{
|
||||
Return a filename which certainly has the extension ext
|
||||
}
|
||||
var
|
||||
j : longint;
|
||||
begin
|
||||
j:=length(Hstr);
|
||||
while (j>0) and (Hstr[j]<>'.') do
|
||||
dec(j);
|
||||
if j=0 then
|
||||
j:=255;
|
||||
ForceExtension:=Copy(Hstr,1,j-1)+'.'+Ext;
|
||||
end;
|
||||
|
||||
|
||||
Procedure AddToLinkFiles(const S : String);
|
||||
{
|
||||
Adds a filename to a list of object files to link to.
|
||||
No duplicates allowed.
|
||||
}
|
||||
Var
|
||||
P : PLinKOEnt;
|
||||
begin
|
||||
P:=ObjFiles;
|
||||
{ Don't add files twice }
|
||||
While (P<>nil) and (p^.name<>s) do
|
||||
p:=p^.next;
|
||||
if p=nil then
|
||||
begin
|
||||
new(p);
|
||||
p^.next:=ObjFiles;
|
||||
p^.name:=s;
|
||||
ObjFiles:=P;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
Function ExtractLib(const libfn:string):string;
|
||||
{
|
||||
Extract a static library libfn and return the files with a
|
||||
wildcard
|
||||
}
|
||||
var
|
||||
n,d,e : string;
|
||||
i : word;
|
||||
begin
|
||||
{ create the temp dir first }
|
||||
fsplit(libfn,d,n,e);
|
||||
{$I-}
|
||||
mkdir(n+'.sl');
|
||||
{$I+}
|
||||
i:=ioresult;
|
||||
{ Extract }
|
||||
if Shell(arbin+' x '+libfn)<>0 then
|
||||
Error('Fatal: Error running '+arbin,true);
|
||||
{ Remove the lib file, it's extracted so it can be created with ease }
|
||||
if PPLExt=PPUExt then
|
||||
Shell('rm '+libfn);
|
||||
{$ifdef linux}
|
||||
ExtractLib:=n+'.sl/*';
|
||||
{$else}
|
||||
ExtractLib:=n+'.sl\*';
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
|
||||
Function DoPPU(const PPUFn,PPLFn:String):Boolean;
|
||||
{
|
||||
Convert one file (in Filename) to library format.
|
||||
Return true if successful, false otherwise.
|
||||
}
|
||||
Var
|
||||
inppu,
|
||||
outppu : pppufile;
|
||||
b,
|
||||
untilb : byte;
|
||||
l : longint;
|
||||
i : word;
|
||||
f : file;
|
||||
isstaticlinked : boolean;
|
||||
begin
|
||||
DoPPU:=false;
|
||||
If Not Quiet then
|
||||
Write ('Processing ',PPUFn,'...');
|
||||
inppu:=new(pppufile,init(PPUFn));
|
||||
if not inppu^.open then
|
||||
begin
|
||||
dispose(inppu,done);
|
||||
Error('Error: Could not open : '+PPUFn,false);
|
||||
Exit;
|
||||
end;
|
||||
{ Check the ppufile }
|
||||
if not inppu^.CheckPPUId then
|
||||
begin
|
||||
dispose(inppu,done);
|
||||
Error('Error: Not a PPU File : '+PPUFn,false);
|
||||
Exit;
|
||||
end;
|
||||
if inppu^.GetPPUVersion<15 then
|
||||
begin
|
||||
dispose(inppu,done);
|
||||
Error('Error: Wrong PPU Version : '+PPUFn,false);
|
||||
Exit;
|
||||
end;
|
||||
{ Already a lib? }
|
||||
if (inppu^.header.flags and uf_in_library)<>0 then
|
||||
begin
|
||||
dispose(inppu,done);
|
||||
Error('Error: PPU is already in a library : '+PPUFn,false);
|
||||
Exit;
|
||||
end;
|
||||
{ Create the new ppu }
|
||||
if PPUFn=PPLFn then
|
||||
outppu:=new(pppufile,init('ppumove.$$$'))
|
||||
else
|
||||
outppu:=new(pppufile,init(PPLFn));
|
||||
outppu^.create;
|
||||
{ Create new header, with the new flags }
|
||||
outppu^.header:=inppu^.header;
|
||||
outppu^.header.flags:=outppu^.header.flags or uf_in_library;
|
||||
if MakeStatic then
|
||||
outppu^.header.flags:=outppu^.header.flags or uf_static_linked
|
||||
else
|
||||
outppu^.header.flags:=outppu^.header.flags or uf_shared_linked;
|
||||
{ Is the until smartlinked ? }
|
||||
IsStaticLinked:=(inppu^.header.flags and uf_static_linked)<>0;
|
||||
{ read until the object files are found }
|
||||
if IsStaticLinked then
|
||||
untilb:=iblinkstaticlibs
|
||||
else
|
||||
untilb:=iblinkofiles;
|
||||
repeat
|
||||
b:=inppu^.readentry;
|
||||
if b in [ibendinterface,ibend] then
|
||||
begin
|
||||
dispose(inppu,done);
|
||||
dispose(outppu,done);
|
||||
Error('Error: No files to be linked found : '+PPUFn,false);
|
||||
Exit;
|
||||
end;
|
||||
if b<>untilb then
|
||||
begin
|
||||
repeat
|
||||
inppu^.getdatabuf(buffer^,bufsize,l);
|
||||
outppu^.putdata(buffer^,l);
|
||||
until l<bufsize;
|
||||
outppu^.writeentry(b);
|
||||
end;
|
||||
until (b=untilb);
|
||||
{ we have now reached the section for the files which need to be added,
|
||||
now add them to the list }
|
||||
case b of
|
||||
iblinkofiles : begin
|
||||
while not inppu^.endofentry do
|
||||
AddToLinkFiles(inppu^.getstring);
|
||||
end;
|
||||
iblinkstaticlibs : begin
|
||||
AddToLinkFiles(ExtractLib(inppu^.getstring));
|
||||
if not inppu^.endofentry then
|
||||
begin
|
||||
repeat
|
||||
inppu^.getdatabuf(buffer^,bufsize,l);
|
||||
outppu^.putdata(buffer^,l);
|
||||
until l<bufsize;
|
||||
outppu^.writeentry(b);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
{ just add a new entry with the new lib }
|
||||
outppu^.putstring(outputfile);
|
||||
if MakeStatic then
|
||||
outppu^.writeentry(iblinkstaticlibs)
|
||||
else
|
||||
outppu^.writeentry(iblinksharedlibs);
|
||||
{ read all entries until the end and write them also to the new ppu }
|
||||
repeat
|
||||
b:=inppu^.readentry;
|
||||
{ don't write ibend, that's written automaticly }
|
||||
if b<>ibend then
|
||||
begin
|
||||
repeat
|
||||
inppu^.getdatabuf(buffer^,bufsize,l);
|
||||
outppu^.putdata(buffer^,l);
|
||||
until l<bufsize;
|
||||
outppu^.writeentry(b);
|
||||
end;
|
||||
until b=ibend;
|
||||
{ write the last stuff and close }
|
||||
outppu^.flush;
|
||||
outppu^.writeheader;
|
||||
dispose(outppu,done);
|
||||
dispose(inppu,done);
|
||||
{ rename }
|
||||
if PPUFn=PPLFn then
|
||||
begin
|
||||
{$I-}
|
||||
assign(f,PPUFn);
|
||||
erase(f);
|
||||
assign(f,'ppumove.$$$');
|
||||
rename(f,PPUFn);
|
||||
{$I+}
|
||||
i:=ioresult;
|
||||
end;
|
||||
{ the end }
|
||||
If Not Quiet then
|
||||
Writeln (' Done.');
|
||||
DoPPU:=True;
|
||||
end;
|
||||
|
||||
|
||||
Function DoFile(const FileName:String):Boolean;
|
||||
{
|
||||
Process a file, mainly here for wildcard support under Dos
|
||||
}
|
||||
{$ifndef linux}
|
||||
var
|
||||
dir : searchrec;
|
||||
{$endif}
|
||||
begin
|
||||
{$ifdef linux}
|
||||
DoFile:=DoPPU(FileName,ForceExtension(FileName,PPLExt));
|
||||
{$else}
|
||||
DoFile:=false;
|
||||
findfirst(filename,$20,dir);
|
||||
while doserror=0 do
|
||||
begin
|
||||
if not DoPPU(Dir.Name,ForceExtension(Dir.Name,PPLExt)) then
|
||||
exit;
|
||||
findnext(dir);
|
||||
end;
|
||||
DoFile:=true;
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
|
||||
Procedure DoLink;
|
||||
{
|
||||
Link the object files together to form a (shared) library, the only
|
||||
problem here is the 255 char limit of Names
|
||||
}
|
||||
Var
|
||||
Names : String;
|
||||
f : file;
|
||||
Err : boolean;
|
||||
P : PLinkOEnt;
|
||||
begin
|
||||
if not Quiet then
|
||||
Write ('Linking ');
|
||||
P:=ObjFiles;
|
||||
names:='';
|
||||
While p<>nil do
|
||||
begin
|
||||
if Names<>'' then
|
||||
Names:=Names+' '+P^.name
|
||||
else
|
||||
Names:=p^.Name;
|
||||
p:=p^.next;
|
||||
end;
|
||||
if Names='' then
|
||||
begin
|
||||
If not Quiet then
|
||||
Writeln('Error: no files found to be linked');
|
||||
exit;
|
||||
end;
|
||||
If not Quiet then
|
||||
WriteLn(names);
|
||||
{ Run ar or ld to create the lib }
|
||||
If MakeStatic then
|
||||
Err:=Shell(arbin+' rs '+outputfile+' '+names)<>0
|
||||
else
|
||||
Err:=Shell(ldbin+' -shared -o '+OutputFile+' '+names)<>0;
|
||||
If Err then
|
||||
Error('Fatal: Library building stage failed.',true);
|
||||
{ Remove the .o files }
|
||||
if PPLExt=PPUExt then
|
||||
begin
|
||||
while pos('*',names)>0 do
|
||||
Delete(names,pos('*',names),1);
|
||||
Shell('rm -rf '+names);
|
||||
end;
|
||||
{ Rename to the destpath }
|
||||
if DestPath<>'' then
|
||||
begin
|
||||
Assign(F, OutputFile);
|
||||
Rename(F,DestPath+'/'+OutputFile);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
Procedure usage;
|
||||
{
|
||||
Print usage and exit.
|
||||
}
|
||||
begin
|
||||
Writeln(paramstr(0),': [-qhwvbs] [-e ext] [-o name] [-d path] file [file ...]');
|
||||
Halt(0);
|
||||
end;
|
||||
|
||||
|
||||
|
||||
Procedure processopts;
|
||||
{
|
||||
Process command line opions, and checks if command line options OK.
|
||||
}
|
||||
var
|
||||
C : char;
|
||||
begin
|
||||
if paramcount=0 then
|
||||
usage;
|
||||
{ Reset }
|
||||
ObjFiles:=Nil;
|
||||
Quiet:=False;
|
||||
Batch:=False;
|
||||
OutputFile:='';
|
||||
PPLExt:='ppu';
|
||||
ArBin:='ar';
|
||||
LdBin:='ld';
|
||||
repeat
|
||||
c:=Getopt (ShortOpts);
|
||||
Case C of
|
||||
EndOfOptions : break;
|
||||
's' : MakeStatic:=True;
|
||||
'o' : OutputFile:=OptArg;
|
||||
'd' : DestPath:=OptArg;
|
||||
'e' : PPLext:=OptArg;
|
||||
'q' : Quiet:=True;
|
||||
'w' : begin
|
||||
ArBin:='arw';
|
||||
LdBin:='ldw';
|
||||
end;
|
||||
'b' : Batch:=true;
|
||||
'?' : Usage;
|
||||
'h' : Usage;
|
||||
end;
|
||||
until false;
|
||||
{ Test filenames on the commandline }
|
||||
if (OptInd>Paramcount) then
|
||||
Error('Error: no input files',true);
|
||||
if (OptInd<ParamCount) and (OutputFile='') then
|
||||
Error('Error: when moving multiple units, specify an output name.',true);
|
||||
{ alloc a buffer }
|
||||
GetMem (Buffer,Bufsize);
|
||||
If Buffer=Nil then
|
||||
Error('Error: could not allocate memory for buffer.',true);
|
||||
{ fix filename }
|
||||
{$ifdef linux}
|
||||
if Copy(OutputFile,1,3)<>'lib' then
|
||||
OutputFile:='lib'+OutputFile;
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
||||
var
|
||||
i : longint;
|
||||
begin
|
||||
ProcessOpts;
|
||||
{ Write Header }
|
||||
if not Quiet then
|
||||
begin
|
||||
Writeln(Title+' '+Version);
|
||||
Writeln(Copyright);
|
||||
Writeln;
|
||||
end;
|
||||
{ Check if shared is allowed }
|
||||
{$ifndef linux}
|
||||
if arbin<>'arw' then
|
||||
begin
|
||||
Writeln('Warning: shared library not supported for Go32, switching to static library');
|
||||
MakeStatic:=true;
|
||||
end;
|
||||
{$endif}
|
||||
{ fix the libext and outputfilename }
|
||||
if Makestatic then
|
||||
LibExt:=StaticLibExt
|
||||
else
|
||||
LibExt:=SharedLibExt;
|
||||
if OutputFile='' then
|
||||
OutPutFile:=Paramstr(OptInd);
|
||||
OutputFile:=ForceExtension(OutputFile,LibExt);
|
||||
{ Open BatchFile }
|
||||
if Batch then
|
||||
begin
|
||||
Assign(BatchFile,'pmove'+BatchExt);
|
||||
Rewrite(BatchFile);
|
||||
end;
|
||||
{ Process Files }
|
||||
i:=OptInd;
|
||||
While (i<=ParamCount) and Dofile(AddExtension(Paramstr(i),PPUExt)) do
|
||||
Inc(i);
|
||||
{ Do Linking stage }
|
||||
DoLink;
|
||||
{ Close BatchFile }
|
||||
if Batch then
|
||||
begin
|
||||
if Not Quiet then
|
||||
Writeln('Writing pmove'+BatchExt);
|
||||
Close(BatchFile);
|
||||
{$ifdef Linux}
|
||||
ChMod('pmove'+BatchExt,493);
|
||||
{$endif}
|
||||
end;
|
||||
{ The End }
|
||||
if Not Quiet then
|
||||
Writeln('Done.');
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.1 1999-05-12 16:11:39 peter
|
||||
* moved
|
||||
|
||||
Revision 1.3 1998/08/17 10:26:30 peter
|
||||
* updated for new shared/static style
|
||||
|
||||
Revision 1.2 1998/06/18 10:47:55 peter
|
||||
* new for v15
|
||||
}
|
161
utils/ptop.pp
Normal file
161
utils/ptop.pp
Normal file
@ -0,0 +1,161 @@
|
||||
|
||||
Program PtoP;
|
||||
{
|
||||
$Id$
|
||||
This file is part of the Free Pascal run time library.
|
||||
Copyright (c) 1999 by Michael Van Canneyt, member of
|
||||
the Free Pascal development team
|
||||
|
||||
Pascal pretty print program
|
||||
|
||||
See the file COPYING.FPC, included in this distribution,
|
||||
for details about the copyright.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
**********************************************************************}
|
||||
|
||||
Uses PtoPu,Objects,getopts;
|
||||
|
||||
Var
|
||||
Infilename,OutFileName,ConfigFile : String;
|
||||
BeVerbose : Boolean;
|
||||
TheIndent,TheBufSize : Integer;
|
||||
|
||||
Function StrToInt(Const S : String) : Integer;
|
||||
|
||||
Var Code : integer;
|
||||
|
||||
begin
|
||||
Val(S,StrToInt,Code);
|
||||
If Code<>0 then StrToInt:=0;
|
||||
end;
|
||||
|
||||
Procedure Usage;
|
||||
|
||||
begin
|
||||
Writeln ('ptop : Usage : ');
|
||||
Writeln ('ptop [-v] [-i indent] [-b bufsize ][-c optsfile] infile outfile');
|
||||
Writeln (' converts infile to outfile.');
|
||||
Writeln (' -c : read options from optsfile');
|
||||
Writeln (' -i : Set number of indent spaces.');
|
||||
Writeln (' -b : Use buffers of size bufsize');
|
||||
Writeln (' -v : be verbose');
|
||||
writeln ('ptop -g ofile');
|
||||
writeln (' generate default options file');
|
||||
Writeln ('ptop -h : This help');
|
||||
halt(0);
|
||||
end;
|
||||
|
||||
Procedure Genopts;
|
||||
|
||||
Var S : PBufStream;
|
||||
|
||||
begin
|
||||
S:=New(PBufStream,Init(ConfigFile,stCreate,255));
|
||||
GeneratecfgFile(S);
|
||||
S^.Close;
|
||||
S^.Done;
|
||||
end;
|
||||
|
||||
Procedure ProcessOpts;
|
||||
|
||||
Var c : char;
|
||||
|
||||
begin
|
||||
{ Set defaults }
|
||||
Infilename:='';
|
||||
OutFileName:='';
|
||||
ConfigFile:='';
|
||||
TheIndent:=2;
|
||||
TheBufSize:=255;
|
||||
BeVerbose:=False;
|
||||
Repeat
|
||||
c:=getopt('i:c:g:b:hv');
|
||||
case c of
|
||||
'i' : begin
|
||||
TheIndent:=StrToInt(OptArg);
|
||||
If TheIndent=0 then TheIndent:=2;
|
||||
end;
|
||||
'b' : begin
|
||||
TheBufSize:=StrToInt(OptArg);
|
||||
If TheBufSize=0 then TheBufSize:=255;
|
||||
end;
|
||||
'c' : ConfigFile:=OptArg;
|
||||
'g' : begin
|
||||
ConfigFIle:=OptArg;
|
||||
GenOpts;
|
||||
halt(0);
|
||||
end;
|
||||
'h' : usage;
|
||||
'v' : BeVerbose:=True;
|
||||
else
|
||||
end;
|
||||
until c=endofoptions;
|
||||
If optind<=paramcount then
|
||||
begin
|
||||
InFileName:=paramstr(OptInd);
|
||||
Inc(optind);
|
||||
If OptInd<=paramcount then
|
||||
OutFilename:=Paramstr(OptInd);
|
||||
end;
|
||||
end; { Of ProcessOpts }
|
||||
|
||||
Var DiagS : PMemoryStream;
|
||||
InS,OutS,cfgS : PBufSTream;
|
||||
PPrinter : TPrettyPrinter;
|
||||
P : Pchar;
|
||||
i : longint;
|
||||
|
||||
begin
|
||||
ProcessOpts;
|
||||
If (Length(InfileName)=0) or (Length(OutFileName)=0) Then
|
||||
Usage;
|
||||
Ins:=New(PBufStream,Init(InFileName,StopenRead,TheBufSize));
|
||||
OutS:=New(PBufStream,Init(OutFileName,StCreate,TheBufSize));
|
||||
If BeVerbose then
|
||||
diagS:=New(PMemoryStream,Init(1000,255))
|
||||
else
|
||||
DiagS:=Nil;
|
||||
If ConfigFile<>'' then
|
||||
CfgS:=New(PBufStream,Init(ConfigFile,StOpenRead,TheBufSize))
|
||||
else
|
||||
CfgS:=Nil;
|
||||
PPrinter.Create;
|
||||
PPrinter.Indent:=TheIndent;
|
||||
PPrinter.Ins:=Ins;
|
||||
PPrinter.outS:=OutS;
|
||||
PPrinter.cfgS:=CfgS;
|
||||
PPrinter.DiagS:=DiagS;
|
||||
PPrinter.PrettyPrint;
|
||||
If Assigned(DiagS) then
|
||||
begin
|
||||
I:=DiagS^.GetSize;
|
||||
DiagS^.Seek(0);
|
||||
getmem (P,I+1);
|
||||
DiagS^.Read(P[0],I);
|
||||
P[I]:=#0;
|
||||
Writeln (stderr,P);
|
||||
Flush(stderr);
|
||||
DiagS^.Done;
|
||||
end;
|
||||
If Assigned(CfgS) then
|
||||
CfgS^.Done;
|
||||
Ins^.Done;
|
||||
OutS^.Done;
|
||||
end.
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.1 1999-05-12 16:11:39 peter
|
||||
* moved
|
||||
|
||||
Revision 1.3 1999/03/25 16:52:29 michael
|
||||
+ Implemented Delphi keywords and delphi comments
|
||||
|
||||
Revision 1.2 1999/03/23 13:47:47 michael
|
||||
Added GPL and log
|
||||
|
||||
}
|
1204
utils/ptopu.pp
Normal file
1204
utils/ptopu.pp
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user