mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-15 04:29:31 +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