• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

WinBGI/H27-Jun-2008-2,2751,960

Xbgi/H17-Oct-2008-5,3363,350

examples/H03-May-2022-5,5514,262

vms/H23-Jun-2008-1,130995

Readme.htmH A D22-Apr-200546.9 KiB1,2521,010

analyse.cxxH A D18-Aug-19992.4 KiB12093

array.hH A D17-Oct-200822.2 KiB890762

bring.cxxH A D24-Feb-20043.5 KiB152120

bring.hH A D15-Oct-20063.4 KiB140107

dprintf.cxxH A D13-May-1999383 2017

dprintf.hH A D13-May-199938 21

graph.hH A D13-May-199911.4 KiB446393

graph.pasH A D02-Apr-19987.5 KiB291228

io.cH A D22-May-200225.8 KiB1,1401,008

io.hH A D09-Dec-200419.2 KiB868659

lex.cxxH A D27-Jun-2008145.2 KiB3,7413,026

lex.lH A D16-Jun-200817.1 KiB636545

main.cxxH A D03-May-202210.1 KiB370343

main.hH A D24-Oct-20021.9 KiB9779

make.batH A D15-Feb-199836 11

makefileH A D04-Mar-20082.2 KiB14866

makefile.bccH A D04-Mar-19982.5 KiB12879

makefile.bsdH A D03-May-20222.4 KiB15266

makefile.emxH A D07-Nov-19982 KiB12864

makefile.mvcH A D04-Mar-20082.5 KiB12979

nmtbl.cxxH A D13-May-1999928 5239

nmtbl.hH A D13-May-1999569 2819

parser.cxxH A D27-Jun-2008112.5 KiB3,2032,513

parser.hH A D27-Jun-20085.1 KiB240194

parser.yH A D03-May-202227.5 KiB911656

paslib.cH A D21-Jul-19991.9 KiB11085

paslib.hH A D27-Sep-19993.8 KiB160107

ptoc.cfgH A D01-Jun-20001.2 KiB3934

ptoc.dspH A D18-Aug-19992.5 KiB9880

ptoc.dswH A D18-Aug-1999502 3019

ptoc.hH A D24-Oct-2000898 4831

ptoc.pasH A D20-Oct-20002.3 KiB10862

set.cH A D03-Mar-19982.4 KiB10988

set.hH A D13-May-19994.1 KiB148120

token.cxxH A D16-Jun-20088.7 KiB381321

token.dppH A D13-May-19994.9 KiB139125

token.hH A D18-Aug-19994.2 KiB173128

tpexpr.cxxH A D03-May-202211.3 KiB455367

tpexpr.hH A D26-Mar-20017 KiB306232

tptoc.pasH A D24-Jun-20083.4 KiB15691

trnod.cxxH A D03-May-2022136.6 KiB5,3754,870

trnod.hH A D26-Mar-200135.4 KiB1,421942

util.cxxH A D30-Jul-19992.5 KiB130105

util.hH A D23-Jul-1999538 159

Readme.htm

1<HTML>
2<HEAD>
3<TITLE>Pascal to C/C++ converter</TITLE>
4<UL>
5<LI><A HREF = "#about">About PtoC</A>
6<LI><A HREF = "#installation">PtoC installation</A>
7<LI><A HREF = "#paslib">Pascal runtime library emulation</A>
8  <OL>
9  <LI><A HREF = "#paslib.arrays">Arrays</A>
10  <LI><A HREF = "#paslib.sets">Sets</A>
11  <LI><A HREF = "#paslib.math">Mathematical functions</A>
12  <LI><A HREF = "#paslib.io">Input/Output</A>
13  </OL>
14<LI><A HREF = "#winbgi">BGI emulation</A>
15<LI><A HREF = "#structure">Structure of converter</A>
16<LI><A HREF = "#cganal">Nested functions and call graph analysis</A>
17<LI><A HREF = "#name conflicts">Resolving name conflicts</A>
18<LI><A HREF = "#C parameters">Passing parameters in C</A>
19<LI><A HREF = "#C++ parameters">Passing parameters in C++</A>
20<LI><A HREF = "#C functions">Calling of C functions</A>
21<LI><A HREF = "#assignment">Array assignments</A>
22<LI><A HREF = "#string">Conversion of Turbo Pascal strings</A>
23<LI><A HREF = "#porting">Some porting problems</A>
24  <OL>
25  <LI><A HREF = "#integer">Representation of integer types</A>
26  <LI><A HREF = "#set">Implementation of Pascal sets</A>
27  <LI><A HREF = "#enum">Enumeration types</A>
28  </OL>
29<LI><A HREF = "#style">Style of converted sources</A>
30<LI><A HREF = "#modules">Includes in ANSII Pascal</A>
31<LI><A HREF = "#options">PtoC options</A>
32<LI><A HREF = "#bugs">Known bugs</A>
33<LI><A HREF = "#distribution">PtoC distribution</A>
34</UL>
35
36<BODY>
37<HR>
38<H2><A NAME = "about">About PtoC</A></H2>
39
40This is yet another Pascal to C/C++ converter. The primary idea of this
41converter is to produce readable and supportable code which
42preserves style of original code as far as possible.<P>
43
44Converter recognizes Pascal dialects which are compatible with
45Turbo Pascal 4.0/5.0 and ISO Pascal standard - IEC 7185:1990(E)
46(including conformant arrays). At this moment it was tested
47with Turbo Pascal, Oregon Pascal, Sun Pascal and HP Pascal.<P>
48
49Converter can produce both C++ and C output. Using of C++ language allows
50to encapsulate some Pascal types and constructions into C++ classes.
51So mapping between Pascal and C++ becomes more direct
52then between Pascal and C. I use C++ templates to implement Pascal arrays
53and files. Special template classes are used for conformant arrays.
54C++ like streams are used to implement Pascal IO routines.
55The same runtime library is used both for C and C++.<P>
56
57Now PtoC recognizes Turbo Pascal's extensions, such as units,
58strings, some special types and operations. Turbo Pascal extensions are
59supported only for C++ language.<P>
60
61At this moment PtoC successfully converts more than 400,000 lines
62of Oregon Pascal to C (from RSX to OpenVMS). To test C++ translation and
63conversion of Turbo Pascal extensions I convert BGIDEMO.PAS and LISTER.PAS
64files from Turbo Pascal distribution and also convert some
65numeric programs written on Turbo Pascal by my friends.
66To check quality of conversion please look in file
67<A HREF = "examples/bgidemo.cxx">bgidemo.cxx</A> which was produces from
68original Borland <HREF = "examples/bgidemo.cxx">bgidemo.pas</A> without
69any manual changes. Moreover it is possible to compile it, link with
70WinBGI library and run it under Windows or X-Windows.<P>
71
72
73<H2><A NAME = "installation">PtoC installation</A></H2>
74
75To build PtoC just try <CODE>make</CODE>. Converter consists of two
76executable files: <CODE>ptoc</CODE> - converter itself and
77<CODE>cganal</CODE> - analyzer of call graph, runtime library
78<CODE>libptoc.a</CODE>, configuration file for converter <CODE>ptoc.cfg</CODE>,
79Pascal header for converter <CODE>ptoc.pas</CODE>
80(<CODE>tptoc.pas</CODE> for Turbo Pascal) and include file for all converted
81sources <CODE>ptoc.h</CODE>. To run converter you should only specify path to
82directory with <CODE>ptoc</CODE> and <CODE>cganal</CODE>. To compile and link
83converted files you should specify for compiler and linker path to header
84file <CODE>ptoc.h</CODE> and library <CODE>libptoc.a</CODE>.<P>
85
86I compile PtoC at Unix with GCC or CXX (Digital C++ compiler).
87I hope that many other C++ compilers also can do it.
88In MS-Windows I use Microsoft Visual C++ 5.0. You should
89either explicitly specify name of makefile: <CODE>nmake -f makefile.mvc</CODE>
90or use <CODE>make.bat</CODE> which do exactly the same.
91Also makefile for Borland C++ <CODE>makefile.bcc</CODE> is prepared.
92To invoke Borland linker issue command <CODE>make.exe -f makefile.bcc</CODE>
93(<CODE>.exe</CODE> extension is significant, otherwise <CODE>make.bat</CODE>
94will be executed)<P>
95
96I have used converter in following way:
97
98<PRE>
99rm */*.[ch] call.grp
100for name in */*.pas
101do
102$(PTOC_DIR)ptoc -I include -h -in $name -c -analyze -intset -init -unsigned
103done
104$(PTOC_DIR)cganal
105</PRE>
106
107In directory <CODE>examples</CODE> there are several Pascal files and
108makefile which converts and compiles this files.
109Examples will be build also by issuing <CODE>make</CODE> command.
110You can look in this makefile at the examples of using PTOC
111and compiling converted code.
112To compile sources produced from Turbo Pascal files,
113do not forget to specify <CODE>-DTURBO_PASCAL</CODE> option.<P>
114
115Directory WinBGI contains source and header file for
116BGI emulator for MS-Windows as well as makefile for Microsoft Visual C++
117(makefile.mvc) and Borland C++ (makefile.bcc) to build this library.
118Directory Xbgi contains sources of BGI emulator for X-Windows.<P>
119
120Directory "vms" contains VMS specific versions of Pascal
121runtime library emulation module "io.c".<P>
122
123If you want to make some changes in scanner or parser you need
124GNU bison and flex. For MS-Windows you can download this tools
125for example from
126<A HREF="ftp.keme.co.uk/pub/winsite-mirror/win95/programr/flexbison.zip">
127flexbison.zip</A>.
128File produced by GNU flex contains reference to <CODE>unistd.h</CODE>.
129At Windows you can either remove this reference or create file
130with this name.<P>
131
132
133
134<H2><A NAME = "paslib">Pascal runtime library emulation</A></H2>
135
136<H3><A NAME = "paslib.arrays">Arrays</A></H3>
137
138All Pascal arrays in C are stored as zero based (first element has
139offset 0). Low value of Pascal array bounds is subtracted from index
140expression. When array is passed to conformant array parameter or
141to input/output functions Pascal array bounds are passed before array
142pointer. Low bound is always passed as it was mentioned in Pascal
143array definition (symbolic constant or integer literal).
144High bound is calculated depending on value of low bound (if it is
145explicit constant) and whether variable is formal parameter.
146if variable is not formal parameter and low bound is either 0 or 1
147macro <CODE>items(x)</CODE> is used to calculate high array bound:
148
149<PRE>
150    #define items(x) (sizeof(x)/sizeof(*(x)))
151
152      procedure foo(a : array [l1..h1,l2..h2:integer] of char); external;
153      var a : array [1..10,-10..10] of char;
154      begin foo(a); end;
155
156    ==>
157
158      foo(const int l1, const int h2, const int l2, const int h2,
159          char* arr);
160      char a[10][21];
161      { foo(1, items(a), -10, items(*a), *a); }
162</PRE>
163
164
165If left operand is not formal parameter and hence 'sizeof' operation
166can be used to obtain array size two macros are used to copy and
167compare array:
168
169<PRE>
170      #define arrcmp(a,b) memcmp(a, b, sizeof(a))
171      #define arrcpy(a,b) memcpy(a, b, sizeof(a))
172</PRE>
173
174If left operand is formal parameter sizeof operator is applied to it's
175type:
176
177
178<PRE>
179      foo(str5 s) {
180         memcpy(s, "12345", sizeof(str5));
181      }
182</PRE>
183
184When string is passed as actual parameter for conformant array macro
185<CODE>array(s)</CODE> is used to calculate bounds of string:
186
187<PRE>
188      #define array(s)  1, sizeof(s)-1, (s)
189</PRE>
190
191PtoC provides special type <CODE>zero_terminated_string</CODE>
192for passing zero terminated strings to C functions.
193Consider for example the following definition of function:
194
195<PRE>
196      function putenv(s : zero_terminated_string); external;
197</PRE>
198
199This function can be called in the following way:
200
201<PRE>
202    procedure foo(a : array [1..10] of char);
203    begin
204      putenv('VERSION=1');
205      putenv(a);
206    end;
207
208==>
209
210    void foo(array<1,10,char> a)
211    {
212      putenv("VERSION=1");
213      putenv(lpsz(a));
214    }
215</PRE>
216
217Function <CODE>lpsz(a)</CODE> converts array to zero terminated string.
218This function use static circular buffers for coping array elements
219to it and appending '\0' symbols at the end.<P>
220
221
222In C++ arrays are implemented by following template C++ classes:<P>
223
224<DL>
225<DT><CODE>array&lt;low_bound, high_bound, type&gt;</CODE><DD>
226One dimensional array with fixed bounds.
227
228<DT><CODE>conf_array&lt;type&gt;</CODE><DD>
229Conformant array.
230for more details.
231
232<DT><CODE>matrix&lt;low_1, high_1, low_2, high_2, type&gt;</CODE><DD>
233Two dimensional array with fixed bounds.
234
235<DT><CODE>conf_matrix&lt;type&gt;</CODE><DD>
236Conformant two dimensional array.
237</DL>
238
239See <A HREF = "#C++ parameters">Passing parameters in C++</A> for
240more details about passing of array parameters.<P>
241
242Methods of classes <CODE>array, conf_array, matrix, conf_matrix</CODE>
243performs bounds checking by means of <CODE>assert()</CODE> statement.
244If, for example, array index is out of bounds, assertion will fail and
245program will be abnormally terminated. To avoid asserts overhead
246you should define <CODE>NDEBUG</CODE> macro (pass <CODE>-DNDEBUG</CODE>
247options to the C++ compiler).<P>
248
249
250<H3><A NAME = "paslib.sets">Sets</A></H3>
251
252By default converter use single set type for all Pascal sets.
253This set type can handle sets with card up to 256 elements
254(consequently size of set is 256/8 = 32 bytes). Following functions
255implement Pascal operations with sets:
256
257<PRE>
258      boolean subset(set a, set b); /* if a is subset of b */
259      boolean inset(SetElemType elem, set s);
260      boolean equivalent(set a, set b);
261      set     join(set a, set b);
262      set     difference(set a, set b);
263      set     intersect(set a, set b);
264</PRE>
265
266There is a special constructor for set constants:  setof().
267This function takes varying number of arguments each of them
268is either set element or range of elements, defined by macro range(a,b).
269List of elements should be  terminated with <CODE>eos</CODE>
270(end of set) constant:
271
272<PRE>
273      s := [' ', '!', '?', '_', '0'..'9', 'a'..'z'];
274
275    ==>
276
277      s = setof(' ', '!', '?', '_', range('0','9'), range('a','z'), eos);
278</PRE>
279
280
281In C++ work with Pascal sets is encapsulated in <CODE>set_template</CODE>
282class. Instantiation of this class with constant <CODE>MAX_SET_CARD</CODE>
283as parameter is used as standard Pascal <CODE>set</CODE>.
284Sets of enumerations are created by <CODE>set_of_enum(e)</CODE> macro:
285
286<PRE>
287typedef set_template&lt;MAX_SET_CARD&gt; set;
288
289#define set_of_enum(e) set_template&lt;last_##e&gt;
290</PRE>
291
292
293<H3><A NAME = "paslib.math">Mathematical functions</A></H3>
294
295This is one to one correspondence between Pascal and C mathematical
296functions:<P>
297
298<TABLE BORDER WIDTH=60%>
299<TR BGCOLOR="#A0A0A0"><TH>Pascal</TH>     <TH>C</TH></TR>
300<TR><TD>sin</TD>        <TD>sin</TD></TR>
301<TR><TD>cos</TD>        <TD>cos</TD></TR>
302<TR><TD>tan</TD>        <TD>tan</TD></TR>
303<TR><TD>arctan</TD>     <TD>atan</TD></TR>
304<TR><TD>ln</TD>         <TD>log</TD></TR>
305<TR><TD>sqrt</TD>       <TD>sqrt</TD></TR>
306</TABLE><P>
307
308Functions <CODE>trunc(), pred(), succ(), bitsize(), odd(), chr(), ord()</CODE>
309are implemented by macros in the following way:
310
311<PRE>
312      #define trunc(x)  ((integer)(x))
313      #define pred(type,x) ((type)((x) - 1))
314      #define succ(type,x) ((type)((x) + 1))
315      #define bitsize(x) (sizeof(x)*8)
316      #define odd(x) ((x) & 1)
317      #define chr(n) ((char)(n))
318      #define ord(c) ((int)(unsigned char)(c))
319</PRE>
320
321Round function is implemented as
322
323<PRE>
324                        trunc(x+0.5)   x &gt;= 0
325            round(x) =
326                        trunc(x-0.5)   x &lt; 0
327</PRE>
328
329Pascal function <CODE>size(x)</CODE> is replaced with C operator
330<CODE>sizeof(x)</CODE>.
331
332
333<H3><A NAME = "paslib.io">Input/Output</A></H3>
334
335We use standard C io library to emulate Pascal input/output.
336Pascal file type is emulated by C macro file(r) which defines structure
337containing file descriptor and current record. There are following
338fields in file descriptor: pointer to C FILE structure, file name,
339last IO-operation error status, open mode, file status (and FAB pointer
340for OpenVMS system). Special macros are used for all Pascal
341file accessing procedures which scatter file structure fields
342and call corresponding functions. Bellow there is a table
343specifying mapping between Pascal functions, macros and C functions:<P>
344
345<TABLE BORDER WIDTH="63%">
346<CAPTION>Mapping between Pascal and C I/O functions</CAPTION>
347<TR BGCOLOR="#A0A0A0"><TH>Pascal</TH>     <TH>C macro</TH>     <TH>C function</TH></TR>
348<TR><TD>rewrite</TD>    <TD>rewrite</TD>     <TD>pio_rewrite_file</TD></TR>
349<TR><TD>reset</TD>      <TD>reset</TD>  <TD>pio_reset_file</TD></TR>
350<TR><TD>get</TD>        <TD>get</TD>    <TD>pio_get_record</TD></TR>
351<TR><TD>put</TD>        <TD>put</TD>    <TD>pio_put_record</TD></TR>
352<TR><TD>eof</TD>        <TD>eof</TD>    <TD>pio_check_end_of_file</TD></TR>
353<TR><TD>read</TD>       <TD>sread</TD>  <TD>pio_read_record  (1)</TD></TR>
354<TR><TD>write</TD>      <TD>swrite</TD> <TD>pio_write_record (1)</TD></TR>
355<TR><TD>close</TD>      <TD>close</TD>  <TD>pio_close</TD></TR>
356<TR><TD>seek</TD>       <TD>seek</TD>   <TD>pio_seek_file</TD></TR>
357<TR><TD>rename</TD>     <TD>rename</TD> <TD>pio_rename_file</TD></TR>
358<TR><TD>break</TD>      <TD>flush</TD>  <TD>pio_flush_file   (2)</TD></TR>
359<TR><TD>delete</TD>     <TD>delete_file</TD> <TD>pio_delete_file  (2)</TD></TR>
360<TR><TD>iostatus</TD>   <TD>iostatus</TD>  <TD>pio_iostatus     (2)</TD></TR>
361<TR><TD>ioerror</TD>    <TD>ioerror</TD>   <TD>pio_ioerror      (2) </TD></TR>
362<TR><TD>noioerror</TD>  <TD>noioerror</TD> <TD>pio_ignore_error (2)</TD></TR>
363<TR><TD>-</TD>          <TD>scopy</TD>  <TD>pio_copy_record  (3)</TD></TR>
364<TR><TD>-</TD>          <TD>access</TD> <TD>pio_access_recprd(3)</TD></TR>
365<TR><TD>-</TD>          <TD>store</TD>  <TD>pio_store_record (3)</TD></TR>
366</TABLE>
367
368<OL>
369<LI> read and write with first file parameter
370<LI> Oregon Pascal extensions
371<LI> This macros are used for translation of some Pascal constructions.
372</OL>
373
374Let the following variable are defined:
375
376<PRE>
377      type rec = record ... end;
378      var f, g : file of rec;
379          r : rec;
380</PRE>
381
382Then translation translation for the following construction will be:
383
384<PRE>
385      r := f^;
386      f^ := r;
387      f^ := g^;
388
389    ==>
390
391      r = *access(f);
392      store(f, r);
393      scopy(f, g);
394</PRE>
395
396
397We use lazy evaluation strategy for implementing Pascal file access.
398Current record is red from disc only when it is accessed.
399To handle current state of current record two flags are used:
400<CODE>fs_record_defined</CODE> and <CODE>fs_next_pos</CODE>. First flag is used
401to mark record which is either red from disk or was assigned
402a value. Flag <CODE>fs_next_pos</CODE> is set when pointer in file
403is moved to position after current record. There is the
404following invariant: flag <CODE>fs_next_pos</CODE> is set only when
405flag <CODE>fs_record_defined</CODE> is set. A table below shows state
406of this flags after execution of some functions: <P>
407
408
409<TABLE BORDER>
410<CAPTION>Flags settings</CAPTION>
411<TR BGCOLOR="#A0A0A0"><TH>function</TH>      <TH>fs_next_pos</TH> <TH>fs_record_defined</TH></TR>
412<TR><TD>pio_rewrite_file</TD>  <TD>0</TD>       <TD>0</TD></TR>
413<TR><TD>pio_reset_file</TD>    <TD>0</TD>       <TD>0</TD></TR>
414<TR><TD>pio_get_record</TD>    <TD>0</TD>       <TD>0</TD></TR>
415<TR><TD>pio_put_record</TD>    <TD>0</TD>       <TD>0</TD></TR>
416<TR><TD>pio_read_record</TD>   <TD>0</TD>       <TD>0</TD></TR>
417<TR><TD>pio_write_record</TD>  <TD>0</TD>       <TD>0</TD></TR>
418<TR><TD>pio_seek_file</TD>     <TD>0</TD>       <TD>0</TD></TR>
419<TR><TD>pio_copy_record</TD>   <TD>0</TD>       <TD>0</TD></TR>
420<TR><TD>pio_access_record</TD> <TD>1</TD>       <TD>1</TD></TR>
421<TR><TD>pio_store_record</TD>  <TD>0</TD>       <TD>1</TD></TR>
422</TABLE><P>
423
424Pascal write and read procedures working with text files are
425replaced with <CODE>twrite</CODE> and <CODE>tread</CODE> C functions when
426first parameter is file and <CODE>cwrite</CODE> and <CODE>cread</CODE> when
427console input/output is used.
428This functions receive printf-like format string and varying
429number of arguments. Format string can include arbitrary text
430and format specifiers:<P>
431
432
433<TABLE BORDER>
434<CAPTION>Format specifiers for read and write operations</CAPTION>
435<TR BGCOLOR="#A0A0A0"><TH>type</TH>       <TH>read</TH>   <TH>write</TH></TR>
436
437<TR><TD>integer</TD>    <TD>%i</TD>     <TD>%i<P>
438                                            %&lt;width&gt;i</TD></TR>
439
440<TR><TD>real</TD>       <TD>%f</TD>     <TD>%f<P>
441                                            %&lt;width&gt;f<P>
442                                            %&lt;width&gt;.&lt;precision&gt;f</TD></TR>
443
444<TR><TD>char[]<P>(array of char)</TD> <TD>%s</TD>  <TD>%s<P>
445                                                       %&lt;width&gt;s</TD></TR>
446
447<TR><TD>char*<P>const ok := 'ok'<P> (zero terminated string)</TD>
448<TD>-</TD>
449<TD>%z<P>%&lt;width&gt;z</TD></TR>
450
451<TR><TD>short<P>unsigned short<P>[-32768..32767]<P>[0..65535]</TD>
452<TD>%W</TD> <TD>-</TD></TR>
453
454<TR><TD>char<P>unsigned char<P>[-128..127]<P>[0..255]</TD>
455<TD>%B</TD> <TD>-</TD></TR>
456</TABLE><P>
457
458
459where <B>&lt;<I>width</I>&gt;</B> and <B>&lt;<I>precision</I>&gt;</B>
460is either literal specified in
461format string either symbol <CODE>'*'</CODE>. In former case value of this
462qualifiers is specified <EMP>AFTER</EMP> (unlike C) corresponding parameter:
463
464<PRE>
465      write(x:5:2);        ==>        cwrite("%5.2f",x);
466      write(x:w:p);        ==>        cwrite("%*.*f",x,w,p);
467</PRE>
468
469For symbols not preceding with <CODE>%</CODE> action performed
470by read and write are:<P>
471
472<TABLE BORDER>
473<TR><TH>read</TH> <TH>write</TH></TR>
474<TR><TD>
475if character is <CODE>'\n'</CODE> then skip all input
476character until newline character is reached;<P>
477
478otherwise character is compared with next
479input character and if not equal read operation fails</TD>
480
481<TD>just output character</TD></TR>
482</TABLE><P>
483
484To output <CODE>%</CODE> character this symbol should be included in the
485format string twice.<P>
486
487Procedures <CODE>writeln()</CODE> and <CODE>readln()</CODE> are implemented
488by the same functions but symbol <CODE>'\n'</CODE> is appended to the
489formating string.<P>
490
491Array arguments are passed to read and write function with low
492and high bound specified before array pointer:
493
494<PRE>
495      procedure foo(str : packed array [1..100] of char);
496      begin
497        writeln('str = ',str);
498      end;
499
500    ==>
501
502      void foo(char str[100]) {
503        writec("str = %s\n", 1, 100, str);
504      }
505</PRE>
506
507In C++ template class <CODE>file&lt;type&gt;</CODE> is used as wrapper
508for these C <CODE>pio_</CODE> functions. PtoC uses <CODE>streamio</CODE>
509like interface for converting Pascal IO operation in C++:
510
511<PRE>
512      type
513        rec = record
514	  code : integer;
515	  name : array [1..10] of char;
516        end;
517      const
518        pi = 3.14;
519      var
520        f : file of rec;
521	r : rec;
522      begin
523        writeln('Hello world');
524	writeln('pi = ', pi:10:5);
525	write(f, r);
526	read(f, r);
527	r := f^;
528	f^ := r;
529	readln;
530      end.
531
532  ==>
533
534      struct rec {
535          integer code;
536          array<1,10,char> name;
537      };
538      const real pi = 3.14;
539      file<rec> f;
540      rec r;
541
542      main()
543      {
544        output << "Hello world" << NL;
545	output << "pi = " << format(pi, 10, 5) << NL;
546        f << r;
547        f >> r;
548        r = *f;
549        store(f, r);
550	input >> NL;
551	return EXOT_SUCCESS;
552     }
553</PRE><P>
554
555The following table summirize rules of translation Pascal IO constructions
556to C++:
557
558<TABLE BORDER>
559<TR BGCOLOR="#A0A0A0"><TH>Pascal construction</TH>   <TH>C++ construction</TH></TR>
560
561<TR><TD ALIGN="LEFT">
562    write(expr1, expr2, ..., exprN)<P>
563    writeln(expr1, ..., exprN)<P>
564    write(f, expr1, ..., exprN)<P>
565    writeln(f, expr1, ..., exprN)</TD>
566<TD ALIGN="LEFT">
567    output << expr1 << expr2 << ... << exprN;<P>
568    output << expr1 << ... << exprN << NL;<P>
569    f << expr1 << ... << exprN;<P>
570    f << expr1 << ... << exprN << NL;</TD>
571</TR>
572<TR><TD ALIGN="LEFT">
573    read(lvalue1, lvalue2, ..., lvalueN)<P>
574    readln(lvalue1, ..., lvalueN)<P>
575    read(f, lvalue1, ..., lvalueN)<P>
576    readln(f, lvalue1, ..., lvalueN)</TD>
577<TD ALIGN="LEFT">
578    input >> lvalue1 >> lvalue2 >> ... >> lvalueN;<P>
579    input >> lvalue1 >> ... >> lvalueN >> NL;<P>
580    f >> lvalue1 >> ... >> lvalueN;<P>
581    f >> lvalue1 >> ... >> lvalueN >> NL;<P>
582</TR>
583<TR><TD ALIGN="LEFT">
584    write(string_expr:width)<P>
585    write(integer_expr:width)<P>
586    write(real_expr:width:precision)</TD>
587<TD ALIGN="LEFT">
588    output << format(string_expr, width);<P>
589    output << format(integer_expr, width);<P>
590    output << format(real_expr, width, precision);</TD>
591</TR>
592<TR>
593<TD ALIGN="LEFT">file_variable^</TD>
594<TD ALIGN="LEFT">*file_variable</TD>
595</TR>
596<TR>
597<TD ALIGN="LEFT">file_variable^ := expr</TD>
598<TD ALIGN="LEFT">store(file_variable, expr);</TD>
599</TR>
600</TABLE>
601
602<H2><A NAME = "winbgi">BGI emulation</A></H2>
603
604PtoC now provides emulation libraries of Borland Graphics Interface (BGI)
605for X-Windows and Windows-95/NT are included in this distribution
606(BGI emulators can be also used without converter for C programs using BGI).
607I found source code of BGI emulator for X-Windows in Internet,
608so I only have to do some changes and fix few bugs.
609Unfortunately this emulation library is not fully completed and
610tested, also not all BGI functionality is supported.
611And BGI emulator for MS-Windows I created myself (in Internet I found
612only commercial products). I called this library WinBGI.<P>
613
614WinBGI strictly emulates most of BGI functions
615(except using of non-standard drivers). Also may be mapping of fonts
616is not correct. But as far as sources are also available, you can
617easily customize them for your application. Unfortunately direct work
618with palette colors (setpalette, setbkcolor, write and putimage modes other
619than COPYPUT) is supported only for 256-colors Windows mode.
620Also I have used this library for only few programs (bgidemo is
621certainly the most complex one) so I can't guaranty that all
622functions always work properly. I am also sorry for the lack of
623parameter checking in WinBGI functions. So summarizing all above:<P>
624
625WinBGI advantages:
626<OL>
627<LI> Allows you to run your old Turbo-C DOS applications in 32-bit mode
628     in normal windows. So you can easily overcome all 64Kb limitations
629     and getting 32-bit application by simple recompilation !
630
631<LI> Graphics is much faster with WinBGI (because native Win32 API
632     is used with minimal emulation overhead) in comparison with
633     original application running in DOS session under Windows
634     (especially at my PPro-200 with NT).
635     Also it seems to me that some things (like switching of graphical
636     pages) are not working properly in DOS mode under Windows-NT.
637
638<LI> You can use WinBGI for creating non-event driven graphical applications.
639     For example if you want to write a program which only draws
640     graphic of functions, it is not so easy to do with windows.
641     You have to handle REDRAW messages, create timers to output next
642     graphics iteration... It seems to me that BGI is much more
643     comfortable for this purposes: you just draw lines or points and do
644     not worry about window system at all...
645</OL><P>
646
647WinBGI shortcomings:
648<OL>
649<LI> Handling of Windows events is done in BGI functions
650     <CODE>kbhit(). getch() and delay()</CODE>.
651     So to make your application work properly You should
652     periodically call one of this functions. For example,
653     the following program will not work with WinBGI:
654
655<PRE>
656        initgraph(&hd, &hm, NULL);
657        while (1) putpixel(random(640), random(480), random(16));
658        closegraph();
659
660</PRE>
661Correct version of this program is:
662<PRE>
663        initgraph(&hd, &hm, NULL);
664        while (!kbhit()) putpixel(random(640), random(480), random(16));
665        closegraph();
666</PRE>
667<LI> To handle REDRAW message WinBGI has to perform drawing twice:
668     at the screen and in the pixmap which can be used while redrawing.
669     I find that speed of drawing is still very fast but if you want to
670     make it even faster you can assign 0 to global variable
671     <CODE>bgiemu_handle_redraw</CODE>. In this case drawing is performed
672     only at the screen but correct redrawing is not possible.
673     If your application makes some kind of animation (constantly updates
674     pictures at the screen) then may be storing image in the pixmap is not
675     necessary, because your application will draw new picture instead of old
676     one.
677
678<LI> Work with palette is possible only in 256-colors Windows mode.
679     I don't know how to solve this problem with Win32
680     (I am not going to use DirectX).
681
682<LI> It is still not so good tested and not all BGI functionality
683     is precisely simulated. I am hope that current version of WinBGI
684     can satisfy requirements of most simple Turbo-C graphics applications.
685</OL><P>
686
687By default WinBGI emulates VGA device with VGAHI (640x480) mode.
688Default mode parameter can be changed using <CODE>bgiemu_default_mode</CODE>
689variable. Special new mode VGAMAX is supported by WinBGI, causing
690creation of maximized window. To use this mode you should either
691change value of <CODE>bgiemu_default_mode</CODE> variable to
692<CODE>VGAMAX</CODE> and specify <CODE>DETECT</CODE> device type,
693or specify <CODE>VGA</CODE> device type and <CODE>VGAMAX</CODE> mode.<P>
694
695I am using Microsoft Visual C++ 5.0 to compile this application.
696To build library and BGIDEMO example you should only issue command
697<CODE>nmake -f makefile.mvc</CODE>.
698As a result you will have library <CODE>winbgi.lib</CODE>,
699header file <CODE>graphics.h</CODE>.<P>
700
701
702<H2><A NAME = "structure">Structure of converter</A></H2>
703
704Below there is a short description of converter itself:
705
706<UL>
707<LI> Scanner <A HREF = "lex.l">"lex.l"</A> is written using LEX.
708     It produces list of all tokens including comments and white spaces.
709
710<LI> Parser <A HREF = "parser.y">parser.y</A> is written using YACC.
711     Parser takes from list of tokens created by scanner all tokens except
712     separators and creates object tree (classes are described in
713     <A HREF = "trnod.h">trnod.h</A> which nodes contain references to tokens.
714     All names are inserted in global name table
715     <A HREF = "nmtbl.h">nmtbl.h</A>.
716
717<LI> Attributes are assigned to tree nodes by executing virtual method
718     <CODE>attrib()</CODE> <A HREF = "trnod.cxx">trnod.cxx</A>.
719     At this step symbol table <A HREF = "bring.h">bring.h</A> is created.
720     Classes for type expressions are implemented in
721     <A HREF = "tpexpr.cxx">tpexpr.cxx</A>.
722
723<LI> Virtual method <CODE>translate()</CODE> is recursively called for all
724     nodes in tree <A HREF = "trnod.cxx">trnod.cxx</A>. This methods perform
725     conversion of input tokens (modify value, swap tokens, add new tokens)
726     and as a result prepare output list of tokens.
727
728<LI> All tokens from output list of tokens are printed to target file
729     with intelligent preserving position and layout of tokens
730     <A HREF = "token.cxx">token.cxx</A>.
731</UL><P>
732
733
734<H2><A NAME = "cganal">Nested functions and call graph analysis</A></H2>
735
736Converter can perform global call graph analyze in order to recognize
737non-recursive functions and making static variables of such functions which
738are accessed by nested functions. If you specify <CODE>-analyze</CODE> option,
739converter appends to file "call.grp" information about callers and callees.
740After conversion of all files special utility <CODE>cganal</CODE> can be used
741to produced transitive closure of call graph and output list
742of recursive procedures in file "recur.prc". When you run converter
743once again (with <CODE>-analyze</CODE> option) information from this file is
744used to mark recursive procedures.
745This approach greatly increase readability of program as no extra
746arguments need to be passed to nested functions.<P>
747
748
749<H2><A NAME = "name conflicts">Resolving name conflicts</A></H2>
750
751Resolving of names conflicts is controlled by file
752<A HREF = "ptoc.cfg">ptoc.cfg</A> which is loaded by converter at startup.
753This file specifies reserved symbols (C and C++ keywords),
754names of functions from C standard library, names of macros defined by
755converter, and mapping of names for some functions from pascal runtime.<P>
756
757
758<H2><A NAME = "C parameters">Passing parameters in C</A></H2>
759
760When converter produces C code, it doesn't copy arrays which are
761passed by value. Instead of this converter declare such arrays as
762<CODE>const</CODE>, so any attempt to modify contents of such array cause
763C compiler warning or error. It seems to me, that there are usually few places
764in program where procedure modifies array which is passed by value.
765As a rule absence of VAR qualifier means that procedure only access
766but not modify contents of the array. So we decide that efficient generation
767of  this most common is more important then some amount of manual job
768which is necessary to correct places where array has to be copied.
769You should only rename formal parameter, create local variable with original
770name and copy value to it:
771
772<PRE>
773        foo(str20 const name) {
774            ...
775        }
776
777=>
778
779        foo(str20 name_) {
780            str20 name;
781
782            memcpy(name, name_, sizeof(name));
783            ...
784        }
785</PRE>
786
787<H2><A NAME = "C++ parameters">Passing parameters in C++</A></H2>
788
789As far as Pascal arrays are represented in C++ by special class,
790there is no problem with array parameter passing as in C.
791But as far as arrays passed by value are very rarely modified
792in called procedure, PtoC optimizes passing of arrays by value.
793If array parameter, passed by value, is not changed in procedure
794and is not passed by reference to another procedure, then PtoC
795doesn't create copy of the array. This optimization can be
796suppressed by <CODE>-copy</CODE> option. When this option is specified,
797PtoC strictly emulates Pascal call semantic for arrays passed by value
798(always create copy of the array). I don't know reasons of using this
799options.<P>
800
801PtoC implements conformant array by template class
802<CODE>conf_array</CODE>. PtoC uses special macro
803<CODE>copy_conformant_array()</CODE> to create copy of conformant array
804passed by value when this array is modified within procedure or
805option <CODE>-copy</CODE> is specified. This macro uses
806<CODE>alloca()</CODE> function from C library, which allocates space from
807the system stack.<P>
808
809PtoC uses macro <CODE>as(type, string-constant)</CODE> for passing
810string constant to the parameter of <CODE>array of char</CODE> type.
811As far as PtoC wants to make it possible to initialize arrays
812by means of C aggregate construction <CODE>{...}</CODE>, it is impossible
813for array class to have constructor. That is why macro <CODE>as()</CODE>,
814which calls method <CODE>array::make(char const* str)</CODE>, is used for
815passing string constant as parameter. If size of string constant is less
816than size of target parameter, then string is padded with spaces.
817If size of string constant is greater than size of target parameter, then
818string is truncated to the size of parameter.<P>
819
820
821<H2><A NAME = "C functions">Calling of C functions</A></H2>
822
823Sometimes C functions need to be called from Pascal code.
824Sun Pascal has special "<CODE>EXTERNAL C</CODE>" qualifier for C procedures
825called from Pascal. PtoC recognize this qualifier and treat it as
826C (not C++) function declaration. There are some specific items
827of conversion of declarations and calls of such functions:
828
829<UL>
830<LI><B>Zero terminated strings.</B>
831Many C functions accept zero terminated strings
832parameters. As far as character arrays in Pascal are not zero terminated,
833some conversion of string should be done. PtoC provides function
834<CODE>lpsz()</CODE>, which copies characters from Pascal array to internal
835static cyclic buffer and appends them with <CODE>'\0'</CODE> symbol.
836Passing of string literal requires no
837conversion. Turbo Pascal <CODE>string</CODE> type can be implicitly converted
838to zero terminated string without calling <CODE>lpsz()</CODE> method.
839
840<LI><B>Variables passed by reference.</B>
841When conversion to C++ is used, formal parameters declared with <CODE>VAR</CODE>
842keyword are translated to C++ reference variables. So no explicit operation
843to take address of actual parameter is required. But as far as there are no
844references in C, references should be replaced with pointers and
845explicit operation <CODE>"&"</CODE> is needed for actual parameters.
846
847<LI><B>Array passing</B>.
848Arrays in C are treated as pointers. When C++ is used as target language and
849function is declared with <CODE>"EXTERNAL C"</CODE> qualifier, formal
850parameter of such function belonging to array type are translated to
851pointer of the array element type. Actual parameters are passed by means
852of <CODE>body()</CODE> method, which returns pointer to the array elements.
853</UL>
854
855The following examples illustrate these items:
856
857<PRE>
858type smallstr = array [1..64] of char;
859
860procedure foo(var x : integer; a : smallstr; b : zero_terminated_string);
861external c;
862
863var
864   i : integer;
865   s : smallstr;
866begin
867   foo(i, s, s);
868   foo(i, 'abc', 'xyz');
869end.
870
871----------------------------------------------
872
873typedef array&lt;1,64,char&gt; smallstr;
874
875extern "C" void foo(integer* x, char*  a, char*  b);
876
877int main()
878{
879   integer i;
880   smallstr s;
881
882   foo(&i, s.body(), lpsz(s));
883   foo(&i, "abc", "xyz");
884   return EXIT_SUCCESS;
885}
886</PRE>
887
888
889<H2><A NAME = "assignment">Array assignments</A></H2>
890
891Some C++ compilers don't allow classes with any assignment operators
892to be members of unions (for correct implementation it is only
893necessary that such classes should not redefine DEFAULT assignment operator).
894As far as arrays can be members of variant components in Pascal,
895converter can generate code without using of assignment operator for
896string and character constants. If your specify <CODE>-assign</CODE> option,
897converter will use <CODE>assign(str)</CODE> method of array instead of
898<CODE>operator =</CODE> for assignment of string and character constants to
899array. But PtoC still use default <CODE>operator=</CODE> generated by compiler
900for assignment of one array to another. To compile code produced
901with <CODE>-assign</CODE> option, pass <CODE>-DNO_ARRAY_ASSIGN_OPERATOR</CODE>
902option to C++ compiler.<P>
903
904PtoC translates assignment of string constant to variable of
905fixed array type by means of <CODE>as(type, string-constant)</CODE> macro,
906which performs conversion of string constant to the type of destination
907variable. If size of string constant is less
908than the size of the destination variable, then string is padded with spaces.
909If size of string constant is greater than size of the destination variable,
910then the string is truncated to the size of destination variable,<P>
911
912
913<H2><A NAME = "string">Conversion of Turbo Pascal strings</A></H2>
914
915For conversion of Turbo Pascal classes <CODE>string</CODE> and
916<CODE>varying_string</CODE> were designed to represent correspondent
917Pascal types. This classes
918have constructors and assignment operators and so they can not
919be initialized using C aggregates notation {} and can not be used
920as components of unions (GCC allows to initialize classes with constructors
921with {}). To avoid this problem either manually replace such places
922with C arrays or use option <CODE>-cstring</CODE> of compiler.
923When this option is set converter replaces type of string
924component of records or arrays with C pointer to zero terminated string
925<CODE>const char*</CODE>. This approach works well only when this types are
926used to declare constants.<P>
927
928
929<H2><A NAME = "porting">Some porting problems</A></H2>
930
931<H3><A NAME = "integer">Representation of integer type</A></H3>
932
933When your are porting application from 16-bit architecture platform
934you may want to preserve integer size (2 bytes). In this case
935you can face with two problems: one is that pointers will not
936more fit into such integers. Converter can't help your in this
937case. You should change types of some variables and records fields.
938And second problem is less obvious. In language C <CODE>short</CODE> and
939<CODE>char</CODE> operands are converted to <CODE>int</CODE> type before
940operation takes place.
941So if you you compare for equality variables of signed and unsigned type
942declared in Pascal as
943
944<PRE>
945      type
946        word : -32768..32767
947        uword : 0..65535
948      var
949        v1 : word;
950        v2 : uword;
951</PRE>
952
953containing the same value (for example 40000) then result will be
954false (unlike original application) !
955This is because variable with signed type will be
956converted to integer with sign extension while variable with unsigned
957type - without sign extension. To help to deal with this problem
958converter provides option <CODE>-unsigned</CODE>, which force converter to
959insert explicit type conversion in such operations. Lets look at the
960translation the following Pascal construction with and without
961<CODE>-unsigned</CODE> option:<P>
962
963<TABLE BORDER>
964<TR BGCOLOR="#A0A0A0"><TH>Pascal</TH>
965<TH>C without <CODE>-unsigned</CODE></TH>
966<TH>C with <CODE>-unsigned</CODE></TH></TR>
967<TR><TD>if v1 = v2 then ...</TD>
968    <TD>if (v1 == v2) ...</TD>
969    <TD>if ((uword)v1 == v2) ...</TD>
970</TABLE><P>
971
972It is not recommended to use 2-byte C types for representing
973INTEGER and WORD Turbo Pascal types, because structures and functions
974of BGI emulation library deal with original C <CODE>int</CODE> type.
975Also I see no much sense in using short types for converted
976Turbo Pascal applications because in this case you can not receive benefits
977of 32-bit architecture, it is better to run original application.<P>
978
979
980<H3><A NAME = "set">Implementation of Pascal sets</A></H3>
981
982Sometimes it is necessary to preserve original size of data structure.
983For example if structure is mapped to another structure by means of union
984(record with variants in Pascal) or is extracted from file. There are
985two options in converter which can help you in this case. First
986option is <CODE>-intset</CODE>, which order converter to generate short sets
987(2 or 4 bytes) for sets of enumeration types, Operations with
988short sets are implemented by macros using bit arithmetic.
989(so they are significantly faster than operations with universal sets).
990Disadvantage of using short sets is that adding elements to enumeration
991may cause problems in future.<P>
992
993<H3><A NAME = "enum">Enumeration types</A></H3>
994
995And another option is <CODE>-smallenum</CODE>.
996The problem is that <CODE>enum</CODE> type in C is treated by many compilers
997as integers and there are no ways to make compiler use less bytes for their
998representation. When you specify option <CODE>-smallenum</CODE> converter
999replaces original enumeration type definition with
1000<CODE>unsigned char</CODE> or <CODE>unsigned short</CODE>
1001definitions according to number of elements in enumeration. So construction
1002
1003<PRE>
1004        colors = (red, green, blue);
1005</PRE>
1006
1007will be translated to
1008
1009<PRE>
1010        typedef unsigned char colors;
1011        enum {red, green, blue};
1012</PRE>
1013
1014Size of <CODE>colors</CODE> type will be 1.
1015And without <CODE>-smallenum</CODE> size of <CODE>colors</CODE>
1016type depends on compiler and usually will be equal to the
1017size of integer (4):
1018
1019<PRE>
1020        enum colors {red, green, blue};
1021</PRE>
1022
1023
1024
1025<H2><A NAME = "style">Style of converted sources</A></H2>
1026
1027As was mentioned above converter tries to preserve original
1028indentation of converted sources. But if Pascal sources are not properly
1029aligned you can reformat produced C code using some indentation
1030utility, for example GNU indent, which is freely distributed
1031(GNU indent has one interesting bug: it fails to work with
1032files with empty comments <CODE>/**/</CODE> which are produced from popular
1033Pascal <CODE>{}</CODE> comments. To avoid this problem just replace such
1034comments with <CODE>/* */</CODE> or something else).<P>
1035
1036
1037
1038<H2><A NAME = "modules">Includes in ANSII Pascal</A></H2>
1039
1040PtoC supports %include operator (used in Oregon Pascal).
1041This operator works like C #include directive, performing text substitution.
1042This operator can be used in one of the following forms:
1043
1044<PRE>
1045%include file             { "file.pas" will be included }
1046%include '../../file.inc' { "../../file.inc" will be included }
1047%include file.con ;       { "file.con" will be included }
1048</PRE>
1049
1050The statements above will be converted to
1051
1052<PRE>
1053#include "file.h"
1054#include "../../file_inc.h"
1055#include "file_con.h"
1056</PRE>
1057
1058If several files include the file with variables declarations,
1059then this variables will be multiple defined. This problem
1060can be solved either by passing option to linker to merge symbols
1061with the name (most linkers have such option), either by using
1062<CODE>-extern</CODE> option. Specifying <CODE>-extern</CODE> option tells
1063the converter to prepend each variable declaration in included file by
1064<CODE>EXTERN</CODE> qualifier. <CODE>EXTERN</CODE> is defined as
1065<CODE>extern</CODE> in ptoc.h and is redefined to <CODE>""</CODE>
1066(empty string) if:<P>
1067
1068<OL>
1069<LI> included file name without extension is the same as name of
1070     converted file without extension
1071<LI> included file name extension is ".var"
1072</OL>
1073
1074
1075<H2><A NAME = "options">PtoC options</A></H2>
1076
1077<DL>
1078<DT>-I [.]<DD>
1079Include path (colon separated directory list). PtoC will search for included
1080Pascal files in all specified directories.
1081
1082<DT>-in<DD>
1083Input Pascal file. Exactly one input file should be specified for PtoC.
1084Keyword <CODE>-in</CODE> can be skipped if name of the file doesn't start
1085with minus sign.
1086
1087<DT>-out<DD>
1088Name of output C/C++ file. If output file name is not specified, PtoC
1089will creates file with the same name as source Pascal file with extension
1090replaced with ".cxx" (or with one specified by <CODE>-suf</CODE> option).
1091
1092<DT>-suf [.cxx]<DD>
1093Output C/C++ file name suffix.
1094
1095
1096<DT>-c<DD>
1097Translate into ANSI C. By default converter produce C++ output.
1098
1099<DT>-assign<DD>
1100Do not use assignment operators for array. Use method
1101<CODE>array::assign()</CODE> instead.
1102See <A HREF = "#assignment">Array assignments</A>
1103
1104<DT>-analyze<DD>
1105Analyze call graph to find non-recursive functions.
1106Makes <CODE>static</CODE> all variables from non-recursive functions,
1107which are accessed from nested functions.
1108See <A HREF = "#cganal">Nested functions and call graph analysis</A>
1109
1110<DT>-intset<DD>
1111Use integer types for short sets of enumerations.
1112See <A HREF = "#set">Implementation of Pascal sets</A>
1113
1114<DT>-init<DD>
1115Call pio_initialize() function from main(). Invocation of this function
1116performs initialization of Pascal runtime library structures.
1117This functions must be called in VMS and for Turbo Pascal if ParamStr
1118or ExitProc variables are used.
1119
1120<DT>-smallenum<DD>
1121Use for enumerated types as small bytes as possible.
1122See <A HREF = "#enum">Enumeration types</A>
1123
1124<DT>-unsigned<DD>
1125Generate correct code for sign/unsigned comparisons when application
1126is ported from 16-bit architecture to 32/64 bit platform with
1127preserving size of integer type (2 bytes).
1128See <A HREF = "#integer">Representation of integer types</A>
1129
1130<DT>-h<DD>
1131Output only not existed header files.
1132By default PtoC performs conversion and output of all included files.
1133This option tells PtoC not to output existed files.
1134
1135<DT>-turbo<DD>
1136Recognize Turbo Pascal extensions.
1137
1138<DT>-cstring<DD>
1139Use <CODE>char*</CODE> type for string fields in records and arrays.
1140
1141<DT>-nological<DD>
1142Use <CODE>|</CODE> and <CODE>&</CODE> instead of <CODE>||</CODE> and
1143<CODE>&&</CODE> for boolean operations.
1144
1145<DT>-extern<DD>
1146Declare all variables from included files with <CODE>EXTERN</CODE> qualifier.
1147
1148<DT>-preserve<DD>
1149Preserve case of identifiers.
1150By default PtoC translates all names to lowercase. If you prefer
1151to preserve original style of using uppercase and lowercase
1152letters, then use this option.
1153
1154<DT>-nested<DD>
1155Nested comments. Do not mix <CODE>(* *)</CODE> and <CODE>{ }</CODE> comments.
1156By default PtoC consider <CODE>(* ... }</CODE> as valid comment.
1157Setting this option makes it possible to enclose one type of comments
1158insize another one: <CODE>(* outside comment { inside comment } *)</CODE>.
1159This rule is the same as in Turbo Pascal, so
1160this option is implicitly set by <CODE>-turbo</CODE> option.
1161
1162<DT>-copy<DD>
1163This option is meaningful only for C++ conversion. When this option is set,
1164PtoC strictly emulates Pascal call semantic for arrays passed by value
1165(always create array copy). By default PtoC optimizes passing of array
1166parameter by value. Array parameter is copied only if it is changed
1167within procedure or it is passed by reference to another procedure.
1168See <A HREF = "#C++ parameters">Passing parameters in C++</A>
1169
1170<DT>-pascall []<DD>
1171Specify modifier (pascal, WINAPI...) for converted functions.
1172
1173<DT>-comment_tags<DD>
1174Place in comments tags of Pascal variant records. By default
1175PtoC just skip this tags and doesn't output them to C file.
1176in comments tags of Pascal variant records. By default
1177PtoC just skip this tags and doesn't output them to C file.
1178
1179<DT>-namespace<DD>
1180Place Turbo Pascal units in separate namespaces:
1181<PRE>
1182unit foo;
1183interface
1184var
1185    a : integer;
1186implementation
1187end.
1188---------------------------------------------
1189namespace foo {
1190    integer a;
1191}
1192unsing namespace foo;
1193</PRE>
1194</DL><P>
1195
1196
1197<H2><A NAME = "bugs">Known bugs</A></H2>
1198
1199<UL>
1200<LI> Arrays with dimension greater than 2 should be written in form
1201<PRE>
1202        array [l1..h1] of array [l2..h2] of array [l3..h3] of something
1203     instead of
1204        array [l1..h1,l2..h2,l3..h3] of something
1205</PRE>
1206
1207<LI> Converter translates ranges in case statement in the following manner:
1208
1209<PRE>
1210     case x of                          switch (x) {
1211       'a'..'z':           =>             case RANGE_26('a','z'):
1212       0..9:                              case RANGE_10(0,9):
1213       -100..100:                         case -100 ... 100;
1214       low..high:                         case low ... high;
1215     end;                               }
1216</PRE>
1217
1218   Unfortunately '...' C extension is supported only by GCC.
1219
1220<LI> <CODE>CHAR</CODE> type in Turbo Pascal is unsigned and in most
1221     implementations of C/C++ by default is signed. To avoid the problem
1222     with comparison of chars with code greater than 127 use option of
1223     C++ compiler forcing <CODE>char</CODE> type to be unsigned.
1224
1225<LI> The following Turbo Pascal contructions are not recognized by PtoC:
1226     segment prefixes (<CODE>$0000:$1000</CODE>), explicit address specification
1227     for variable (<CODE>ABSOLUTE</CODE> statement), inline assembler,
1228     <CODE>INTERRUPT</CODE> quilifier in function or procedure definition.
1229     Only the following Turbo Pascal compiler directives are recognized by PtoC:
1230     <CODE>$I, $IFDEF, $ELSE, $ENDIF, $IFNDEF, $DEFINE, $IFOPT</CODE>. Other are
1231     treated as normal comments.
1232</OL>
1233
1234<H2><A NAME = "distribution">PtoC distribution</A></H2>
1235
1236PtoC is shareware and is distributed in the hope to be useful.
1237Your are free to use this converter, modify the sources
1238and do with this converter everything else you want.
1239Also feel free to ask me any questions about the converter
1240and BGI emulator for Windows. Shareware status doesn't mean
1241lack of support. I will do my best to fix all reported bugs
1242and will help you to tune PtoC to fit your requirements.
1243Also e-mail support is guaranteed.
1244
1245<HR>
1246<P ALIGN="CENTER"><A HREF="http://www.garret.ru/~knizhnik">
1247<B>Look for new version at my homepage</B></A><B> | </B>
1248<A HREF="mailto:knizhnik@garret.ru">
1249<B>E-mail me about bugs and problems</B></A></P>
1250</BODY>
1251</HTML>
1252