1 /******************************************************************************
2  *
3  *
4  *
5  * Copyright (C) 2002-2006 by Darren Bowles.
6  *
7  * Permission to use, copy, modify, and distribute this software and its
8  * documentation under the terms of the GNU General Public License is hereby
9  * granted. No representations are made about the suitability of this software
10  * for any purpose. It is provided "as is" without express or implied warranty.
11  * See the GNU General Public License for more details.
12  *
13  * Documents produced by Pas2Dox are derivative works derived from the
14  * input used in their production; they are not affected by this license.
15  *
16  */
17 
18 %{
19 #include <string>
20 #include <list>
21 #include <algorithm>
22 #include <ctype.h>
23 #ifdef _WIN32
24 # include <io.h>
25 #endif
26 
27 using namespace std;
28 
29 const char* version = "0.50rc1";
30 const char* date = __DATE__;
31 
32 FILE* OUTPUT = NULL;
33 
34 //*****************************************************************************
35 /// Type of function
36 enum func_type { NORMAL,       ///< Normal
37                  CONSTRUCTOR,  ///< Constructor function
38                  DESTRUCTOR,   ///< Destructor function
39                };
40 
41 //*****************************************************************************
42 /// Type Conversion
43 struct type_conv
44 {
45     char m_pascal_type[15];
46     char m_c_type[15];
47 };
48 
49 type_conv type_conversion[] = {
50   {"boolean", "bool"},
51   {"shortint", "signed char"},
52   {"byte","char*"},
53   {"smallint","short"},
54   {"word","unsigned short"},
55   {"integer", "int"},
56   {"longint","long"},
57   {"single","float"},
58   {"double","double"},
59   {"self", "this"},
60 };
61 
62 //*****************************************************************************
63 /// Operator Conversion
64 struct op_conv
65 {
66   char m_pascal_op[4];
67   char m_c_op[3];
68 };
69 
70 /**
71 *  \note duplicated operators for bitwise and logical operations.
72 *
73 *  biwise operators have a higher precedence, than logical, so
74 *
75 *  if x > 0 and x < 10 then...  will use bitwise operators
76 *  if (x > 0) and (x < 10) then...  will use logical operators
77 */
78 op_conv operator_conversion[] = {
79   {".","::"},       ///< Scope Resolution
80   {"not","~"},      ///< Bitwise negation
81   {"@","&"},        ///< Address
82   {"^","*"},        ///< De-Reference
83   {"/","/"},        ///< Floating point division
84   {"div","/"},      ///< Integer Division
85   {"mod","^"},      ///< Modulus
86   {"shl","<<"},     ///< Left bitwise shift
87   {"shr",">>"},     ///< Right bitwise shift
88   {"=", "=="},      ///< Equal to
89   {"<>","!="},      ///< Not Equal to
90   {"and","&"},      ///< Bitwise AND
91   {"or","|"},       ///< Bitwise OR
92   {"xor","^"},      ///< Bitwise XOR
93   {"not","!"},      ///< Logical NOT
94   {"and","&&"},     ///< logical AND
95   {"or","||"},      ///< Logical OR
96   {":=","="},       ///< Simple Assignment
97 };
98 
99 //*****************************************************************************
100 /// Convert from Pascal type to C++ type
Convert_Type(string & pText)101 void Convert_Type(string& pText)  ///< Type to be converted
102 {
103   type_conv* p;
104 
105   string str = pText;
106   std::transform (str.begin(),str.end(), str.begin(), ::tolower);
107 
108   int count = sizeof(type_conversion) / sizeof(type_conv);
109 
110   for (int i = 0; i < count; i++)
111   {
112     p = &type_conversion[i];
113 
114     // have we found the pascal type in our table?
115     if (str == p->m_pascal_type)
116     {
117       // convert to c++ type
118       pText = p->m_c_type;
119     }
120   }
121 }
122 
123 //*****************************************************************************
124 /// Remove spaces
RemoveSpaces(string & pText)125 void RemoveSpaces(string& pText)  ///< String to work on
126 {
127   int pos = string::npos;
128 
129   while(true)
130   {
131     pos = pText.find(" ", 0);
132 
133     if (pos == string::npos)
134       break;
135 
136     pText.replace(pos, 1, "");
137   }
138 }
139 
140 //*****************************************************************************
141 /// Class Information
142 class class_info
143 {
144   public:
145     class_info();
146     class_info(string name, string parent, string parent2, string var, string type);
147 
148     string sName;        /// Class Name
149     string sParent;      /// Parent Class
150     string sParent2;     /// Second Parent Class
151 
152     string sVar;         /// Class Variable
153     string sType;        /// Class Type
154 };
155 
class_info()156 class_info::class_info()
157 {
158   sName = "";
159   sParent = "";
160   sParent2 = "";
161   sVar = "";
162   sType = "";
163 }
164 
class_info(string name,string parent,string parent2,string var,string type)165 class_info::class_info(string name,    ///< Class Name
166                        string parent,  ///< Parent Class
167             		       string parent2, ///< Second Parent Class
168                        string var,     ///< Class Variable
169 		                   string type)    ///< Class Type
170 {
171   sName = name;
172   sParent = parent;
173   sParent2 = parent2;
174   sVar = var;
175   sType = type;
176 }
177 
178 //*****************************************************************************
179 /// Parameter Information
180 class param_info
181 {
182   public:
183   // Copy constructor
param_info(const param_info & obj)184   param_info(const param_info& obj)  { *this = obj; }
185 
186   // Assignment operator
187   param_info& operator=(const param_info& obj);
188 
189   param_info();
190   param_info(string type, string name, string comment, string def, bool c, bool v, bool o, bool array);
191 
192   string sType;        /// Parameter Name
193   string sName;        /// Parameter Type
194   string sDefault;     /// Default Value
195   string sComment;     /// Associated Comment
196   bool bConst;         /// Const Parameter
197   bool bVar;           /// Var Parameter
198   bool bOut;           /// Out Parameter
199   bool bArray;         /// Array Parameter
200 };
201 
202 param_info& param_info::operator=(const param_info& obj)
203 {
204   sType = obj.sType;
205   sName = obj.sName;
206   sDefault = obj.sDefault;
207   sComment = obj.sComment;
208 
209   bConst = obj.bConst;
210   bVar = obj.bVar;
211   bOut = obj.bOut;
212   bArray = obj.bArray;
213 
214   return *this;
215 }
216 
param_info()217 param_info::param_info()
218 {
219   sType = "";
220   sName = "";
221   sComment = "";
222   bConst = false;
223   bVar = false;
224   bOut = false;
225   bArray = false;
226 }
227 
param_info(string type,string name,string comment,string def,bool c,bool v,bool o,bool array)228 param_info::param_info(string type, string name, string comment, string def, bool c, bool v, bool o, bool array)
229 {
230   sType = type;
231   sName = name;
232   sComment = comment;
233   sDefault = def;
234   bConst = c;
235   bVar = v;
236   bOut = o;
237   bArray = array;
238 }
239 
240 //*****************************************************************************
241 /// Function Information
242 class func_info
243 {
244   public:
245     func_info();
246     func_info(string aclass, string name, string ret, func_type ft);
247 
248     string sClass;               ///< Associated Class
249     string sName;                ///< Function Name
250     string sRet;	               ///< Return Type
251 
252     func_type eFuncType;         ///< Function type
253 };
254 
func_info()255 func_info::func_info()
256 {
257   sClass = "";
258   sName = "";
259   sRet = "";
260 
261   eFuncType = NORMAL;
262 }
263 
func_info(string aclass,string name,string ret,func_type ft)264 func_info::func_info(string aclass, string name, string ret, func_type ft)
265 {
266   sClass = aclass;
267   sName = name;
268   sRet = ret;
269 
270   eFuncType = ft;
271 }
272 
273 //*****************************************************************************
274 /// Property Information
275 class prop_info
276 {
277   public:
278     prop_info();
279     prop_info(string name, string type);
280 
281     string sName;                /// Property Name
282     string sType;                /// Property Type
283 
284     string sRead;                /// Read Value
285     string sWrite;               /// Write Value
286     string sDefault;             /// Default Value
287 
288     bool bRead;                  /// Assign read property
289 };
290 
prop_info()291 prop_info::prop_info()
292 {
293   sName = "";
294   sType = "";
295 }
296 
prop_info(string name,string type)297 prop_info::prop_info(string name, string type)
298 {
299   sName = name;
300   sType = type;
301 }
302 
303 //*****************************************************************************
304 /// Array / Set Information
305 class array_info
306 {
307   public:
308     array_info();
309     array_info(string name, string type, int size, string def);
310 
311     string sName;           ///< Array Name
312     string sType;           ///< Array Type
313     int nSize;              ///< Array Size
314     string sDefault;        ///< Default Values
315 };
316 
array_info()317 array_info::array_info()
318 {
319   sName = "";
320   sType = "";
321   nSize = 0;
322   sDefault = "";
323 }
324 
array_info(string name,string type,int size,string def)325 array_info::array_info(string name, string type, int size, string def)
326 {
327   sName = name;
328   sType = type;
329   nSize = size;
330   sDefault = def;
331 }
332 
333 //*****************************************************************************
334 func_info* pFunc = NULL;
335 class_info* pClass = NULL;
336 prop_info* pProperty = NULL;
337 array_info* pArray = NULL;
338 
339 list<param_info> lstParams;        /// List Of Parameters
340 list<string> g_lstComments;        /// List Of Comments
341 list<param_info> g_lstParams;      /// List Of Parameters
342 list<int> g_lstSize;               /// List of Integers for multi dimensional arrays
343 string g_defaultvalue;
344 string g_processtype;
345 list<string> g_lParamType;         /// Parameter Type
346 
347 unsigned int g_nBegins = 0;
348 
349 // Sections
350 bool g_bClassBody = false;	       /// In Class Body
351 bool g_bFuncBody = false;          /// In Function Body
352 bool g_bType = false;              /// In Type Section
353 bool g_bImplementation = false;    /// In Implementation Section
354 bool g_bIgnoreTypeSection = false; /// Ignoring type section
355 bool g_bConstSec = false;          /// In a Const Section
356 bool g_bParams = false;            /// Parameter List
357 bool g_bEnum = false;              /// Enumeration
358 bool g_bCase = false;              /// Case Statement
359 bool g_bInterface = false;         /// Interface
360 bool g_bStructure = false;         /// Structure
361 bool g_bVars = false;              /// Vars
362 bool g_bSet = false;               /// Sets
363 bool g_bIgnore = false;            /// Ignore Section
364 
365 bool g_bFom = false;               /// Property Field Or Method
366 bool g_bConst = false;             /// Parameter is const
367 bool g_bVar = false;               /// Var Parameter
368 bool g_bOut = false;               /// Out Parameter
369 bool g_bArray = false;             /// Array parameter
370 
371 string g_strTypedef = "";          /// array or set
372 string g_strTypedefType = "";          /// array or set type
373 string g_strTypedefName = "";          /// array or set name
374 int g_nSize = 0;                   /// Array size
375 
376 bool g_bComments = false;	         /// In a Comment Section
377 
378 bool g_bDebugMode = false;         /// In Debug Mode
379 bool g_bKeepBody = false;          /// Keep function body
380 bool g_bJavaDoc = false;           /// JavaDoc Commenting
381 bool g_bAtEnd = false;             /// At end of function parameters
382 bool g_bInterfaceOnly = false;     /// Process only 'Interface' section
383 bool g_bConvertBody = false;       /// Convert function body to c++
384 bool g_bGenerateSa = true;         /// Generate \sa clauses
385 
386 int g_nCommentCaller = 0;          /// Inteligent returning from comments
387 int g_nDirectiveCaller = 0;        /// Inteligent returning from preprocessor directives
388 int g_nGeneralCaller = 0;          /// Intelligent return
389 bool g_bCallback = false;          /// In function typedef
390 
391 #define OutputLog(s) { if(g_bDebugMode) fprintf(OUTPUT, "%s\n", s); }
392 #define OutputLog2(s, t) { if(g_bDebugMode) fprintf(OUTPUT, "%s '%s'\n", s, t); }
393 #define OutputLogNum(s, num) { if(g_bDebugMode) fprintf(OUTPUT, "%s %d\n", s, num); }
394 
395 //*****************************************************************************
396 /// Convert Operator
Convert_Op(string & pText,bool logical)397 void Convert_Op(string& pText,   ///< Operator to be converted
398                 bool logical)    ///< Are we a logical operator?
399 {
400   op_conv* p;
401 
402   // Return if we're not operating in function body conversion mode
403   if (!g_bConvertBody)
404     return;
405 
406   string str = pText;
407   std::transform (str.begin(),str.end(), str.begin(), ::tolower);
408 
409   int count = sizeof(operator_conversion) / sizeof(op_conv);
410 
411   for (int i = 0; i < count; i++)
412   {
413     p = &operator_conversion[i];
414 
415     // have we found a matching operator in our conversion table?
416     if (str == p->m_pascal_op)
417     {
418       //OutputLog2("// original type = ", pText.c_str());
419       //OutputLog2("// new type = ", p->m_c_op);
420       // convert to a c++ operator
421       pText = p->m_c_op;
422 
423       if (!logical)
424         break;
425     }
426   }
427 }
428 
429 //*****************************************************************************
430 /// Display enumerations
DisplayEnum(void)431 void DisplayEnum(void)
432 {
433   list<param_info>::iterator i;
434 
435   OutputLog("// DisplayEnum");
436 
437   for (i = lstParams.begin(); i != lstParams.end(); ++i)
438   {
439     string comm;
440 
441 	fprintf(OUTPUT, "%s%s ",
442       i->sName.c_str(),
443       distance (i, lstParams.end()) == 1 ? "" : ",");
444 
445 	while (!g_lstComments.empty())
446 	{
447 	  comm = g_lstComments.front();
448 
449       OutputLog2("//Got = ", comm.c_str());
450 	  if (comm == "*/")
451 	  {
452 	    fprintf(OUTPUT, "%s\n", comm.c_str());
453 		g_lstComments.pop_front();
454 	    break;
455 	  }
456 
457 	  fprintf(OUTPUT, "%s", comm.c_str());
458 
459 	  g_lstComments.pop_front();
460 	}
461 
462 	fprintf(OUTPUT, "\n");
463 
464   }
465 }
466 
467 //*****************************************************************************
468 /// Remove Parameters From List
RemoveParams()469 void RemoveParams()
470 {
471   OutputLog("// clearing parameters");
472 
473   g_lstParams.clear();
474   lstParams.clear();
475 }
476 
477 //*****************************************************************************
478 /// Process Parameter Types
ProcessParameterType(const char * pText)479 void ProcessParameterType(const char* pText)
480 {
481   list<param_info>::iterator i;
482 
483   // Loop through the parameters from the last type position
484   for (i = lstParams.begin(); i != lstParams.end(); i++)
485   {
486     // and assign this type to those new parameters
487     i->sType = pText;
488      param_info p(pText, i->sName, i->sComment, g_defaultvalue, i->bConst, i->bVar, i->bOut, i->bArray);
489     g_lstParams.push_back(p);
490   }
491 
492   g_defaultvalue = "";
493   g_processtype = "";
494 
495   OutputLog("// Parameters cleared");
496   lstParams.clear();
497 }
498 
499 //*****************************************************************************
500 /// Process Comments
ProcessComment(void)501 void ProcessComment(void)
502 {
503   // If we're not processing parameters at the moment
504   // Then just output the text
505   if (g_bParams == false)
506   {
507     OutputLog("// PC1");
508     fprintf(OUTPUT, "%s", yytext);
509   }
510   else
511   {
512     OutputLog2("// pushing onto comment stack ", yytext);
513 
514     g_lstComments.push_back(yytext);
515   }
516 }
517 
518 //*****************************************************************************
519 /// Process end;
ProcessEnd(void)520 void ProcessEnd(void)
521 {
522   OutputLog("// processing end\n");
523 
524   if (g_bCase)
525   {
526     fprintf(OUTPUT, "end;\n");
527     g_bCase = false;
528   }
529   else
530   {
531     fprintf(OUTPUT, "};\n");
532   }
533 
534   // Tidy up if we're ending a class
535   if (pClass)
536   {
537 //    delete pClass;
538     pClass = NULL;
539     g_bClassBody = false;
540   }
541 }
542 
543 //*****************************************************************************
544 /// Output Inherited Class Details
OutputInheritedClass(int ntype)545 void OutputInheritedClass(int ntype)
546 {
547   OutputLogNum("// Inherited Class, type = ", ntype);
548   if (g_bInterface)
549   {
550   	// Treat interface like a class
551     fprintf(OUTPUT, "class ");
552     g_bInterface = false;
553   }
554   else
555   {
556     fprintf(OUTPUT, "class ");
557   }
558 
559   if (pClass->sParent != "")
560   {
561     fprintf(OUTPUT, "%s : public %s", pClass->sName.c_str(), pClass->sParent.c_str());
562   }
563   else
564   {
565     fprintf(OUTPUT, "%s", pClass->sName.c_str());
566   }
567 
568   if (pClass->sParent2 != "")
569   {
570     fprintf(OUTPUT, ",%s", pClass->sParent2.c_str());
571   }
572 
573   if (ntype == 0)
574   {
575     fprintf(OUTPUT, "\n{\n");
576 
577     // All members default to public
578    	fprintf(OUTPUT, "public:\n");
579 
580     g_bClassBody = true;
581   }
582   else
583   {
584     fprintf(OUTPUT, ";\n");
585   }
586 }
587 
588 //*****************************************************************************
589 /// Process Enumerations
ProcessEnums(void)590 void ProcessEnums(void)
591 {
592   fprintf(OUTPUT, "enum %s\n{\n", pClass->sName.c_str());
593   g_bParams = true;
594 
595   if (pClass)
596   {
597     delete pClass;
598     pClass = NULL;
599   }
600 
601   g_bEnum = true;
602 }
603 
604 //*****************************************************************************
605 /// Process Array
ProcessArrays(void)606 void ProcessArrays(void)
607 {
608   fprintf(OUTPUT, "%s %s[%d] = { \n", pArray->sType.c_str(), pArray->sName.c_str(),
609     g_nSize);
610 
611   g_bParams = true;
612 
613   if (pArray)
614   {
615     delete pArray;
616     pClass = NULL;
617   }
618 
619   g_bEnum = true;
620 }
621 
622 //*****************************************************************************
ProcessFunction(func_type ft)623 void ProcessFunction(func_type ft)
624 {
625   // Process function or procedure
626 
627   if (pFunc)
628     delete pFunc;
629 
630   pFunc = new func_info;
631   pFunc->sRet = "";
632 
633   pFunc->eFuncType = ft;
634 }
635 
636 //*****************************************************************************
637 // Display function params
DisplayParams(void)638 void DisplayParams(void)
639 {
640   list<param_info>::iterator i;
641 
642   // Loop through parameter list
643   for (i = g_lstParams.begin(); i != g_lstParams.end(); i++)
644   {
645     string comm;
646 
647     if(!g_lstComments.empty())
648     {
649       comm = g_lstComments.front();
650       OutputLog2("// Got comment : ", comm.c_str());
651     }
652 
653     fprintf(OUTPUT, "%s%s%s %s%s%s%s%s %s%s\n",
654         i->bConst ? "const " : "",
655         i->bOut   ? "/* out */ " : "",
656         i->sType.c_str(),
657         i->bVar   ? "&" : "",
658         i->bArray ? "*" : "",
659         i->sName.c_str(),
660         i->sDefault != "" ? " = " : "",
661         i->sDefault.c_str(),
662         distance (i, g_lstParams.end()) == 1 ? "" : ",",
663         comm.c_str()
664         );
665 
666     if (!g_lstComments.empty())
667     {
668       g_lstComments.pop_front();
669     }
670   }
671 
672   RemoveParams();
673 }
674 
675 //*****************************************************************************
676 // Display Variables
DisplayVariables(void)677 void DisplayVariables(void)
678 {
679   list<param_info>::iterator i;
680 
681   // Loop through parameter list
682   for (i = g_lstParams.begin(); i != g_lstParams.end(); i++)
683   {
684     string comm;
685 
686 /*
687     if(!g_lstComments.empty())
688     {
689       comm = g_lstComments.front();
690     }
691 	*/
692 
693     if (g_bConvertBody)
694     {
695       Convert_Type(i->sType);
696     }
697 
698 /*
699     fprintf(OUTPUT, "%s %s %s;%s\n",
700         g_bConstSec ? "const" : "",
701         i->sType.c_str(),
702         i->sName.c_str(),
703         comm.c_str()
704         );
705 		*/
706 
707 OutputLog2("val = ", i->sDefault.c_str());
708     if (i->sDefault != "")
709 	{
710 
711       fprintf(OUTPUT, "%s %s %s = %s; ",
712         g_bConstSec ? "const" : "",
713         i->sType.c_str(),
714         i->sName.c_str(),
715 		i->sDefault.c_str()
716         );
717 
718 	}
719 	else
720 	{
721       fprintf(OUTPUT, "%s %s %s; ",
722           g_bConstSec ? "const" : "",
723           i->sType.c_str(),
724           i->sName.c_str()
725           );
726 	}
727 
728   	while (!g_lstComments.empty())
729 	{
730 	  comm = g_lstComments.front();
731 
732 	  if (comm == "*/")
733 	  {
734 	    fprintf(OUTPUT, "%s\n", comm.c_str());
735 		g_lstComments.pop_front();
736 	    break;
737 	  }
738 
739 	  fprintf(OUTPUT, "%s", comm.c_str());
740 
741 	  g_lstComments.pop_front();
742 	}
743 
744 	fprintf(OUTPUT, "\n");
745   }
746 
747   RemoveParams();
748 }
749 
750 //*****************************************************************************
751 /// Change between Delphi and C++ strings
ChangeStrings(void)752 void ChangeStrings(void)
753 {
754   for (int i = 0; i < yyleng; ++i)
755   {
756     if (yytext[i] == '\'')
757     {
758       // check for double ''
759       if (yytext[i+1] == '\'')
760       {
761         yytext[i] = '\\';
762         ++i;  // safe because of trailing '\0'
763       }
764       else
765       {
766         yytext[i] = '\"';
767       }
768     }
769     else
770     {
771       if (yytext[i] == '\"')
772         yytext[i] = '\'';
773     }
774   }
775 }
776 
777 //*****************************************************************************
778 void PushText(const char* txt);
779 %}
780 
781 ID      [a-z_A-Z][a-z_A-Z0-9]*
782 NUM     [0-9]*
783 S       [ \t\n\r]
784 KEYWORD ("abstract"|"cdecl"|"register"|"dynamic"|"virtual"|"export"|"external"|"far"|"forward"|"override"|"overload"|"pascal"|"reintroduce"|"safecall"|"stdcall")
785 OPER    ("."|"not"|"@"|"^"|"/"|"div"|"mod"|"shl"|"shr"|"="|"<>"|"and"|"xor"|"or"|":=")
786 
787 %x PROGRAM
788 %x function
789 %x func_params
790 %x DefaultVal
791 %x param_type
792 %x func_ret
793 %x comments
794 %x mytype
795 %x myparent
796 %x myparent2
797 %x myparent3
798 %x callback
799 %x directive
800 %x directive_define
801 %x directive_ifdef
802 %x directive_ifndef
803 
804 %x Body
805 %x Func_Body
806 %x InClass
807 %x ClassVar
808 %x ClassPtrVar
809 %x vars
810 %x Uses
811 %x Struct
812 %x Property
813 %x prop_type
814 %x Constants
815 %x   ConstAssign1
816 %x   ConstAssign2
817 %x   ConstAssign3
818 %x Constant2
819 %x Constant3
820 %x Enum
821 %x Array
822 %x Initialisation
823 %x ProcessVariable
824 %x   ProcessVariableType
825 %x   ProcessVariableType2
826 %x   ProcessVariableType3
827 %x ProcessArray
828 %x   ProcessArraySize
829 %x   ProcessArrayType
830 %x ProcessSet
831 %x   ProcessSetType1
832 %x   ProcessSetType2
833 %x ProcessEnum
834 %x   ProcessEnum1
835 
836 %x IfThen
837 %x ForLoop
838 
839 %%
840 
841 <*>\x0d
842 <*>^("program"|"unit") {
843   OutputLog("// We've got a program or unit");
844   BEGIN (PROGRAM);
845 }
846 
847 <*>"{$" {
848   OutputLog("// Got a compiler directive");
849 
850   if (YY_START != directive)
851   	g_nDirectiveCaller = YY_START;
852   BEGIN(directive);
853 }
854 
855 <*>{KEYWORD} {
856 
857   OutputLog2("// got keyword ", yytext);
858 
859   if(g_bComments || YY_START == function)
860   {
861     fprintf(OUTPUT, "%s", yytext);
862   }
863 }
864 
865 <directive>"}" {
866   OutputLog("// Finished Directive");
867 
868   BEGIN(g_nDirectiveCaller);
869   g_nDirectiveCaller = 0;
870 }
871 
872 <directive>"define" {
873   OutputLog("// Got a define");
874   BEGIN(directive_define);
875 }
876 
877 <directive>"else" {
878   OutputLog("// Got Else");
879   fprintf(OUTPUT, "#else\n");
880   BEGIN(directive);
881 }
882 
883 <directive>"endif" {
884   OutputLog("// Got EndIf");
885   fprintf(OUTPUT, "#endif\n");
886   BEGIN(directive);
887 }
888 
889 <directive>"IfDef" {
890   OutputLog("// Got IfDef");
891   fprintf(OUTPUT, "#ifdef ");
892   BEGIN(directive_ifdef);
893 }
894 
895 <directive>"IfNDef" {
896   OutputLog("// Got IfNDef");
897   fprintf(OUTPUT, "#ifndef ");
898   BEGIN(directive_ifndef);
899 }
900 
901 <directive>[^}] {
902 }
903 
904 <directive_define>{ID} {
905   fprintf(OUTPUT, "#define %s\n", yytext);
906   BEGIN(directive);
907 }
908 
909 <directive_ifdef>{ID} {
910   fprintf(OUTPUT, "%s\n", yytext);
911   BEGIN(directive);
912 }
913 
914 <directive_ifndef>{ID} {
915   fprintf(OUTPUT, "%s\n", yytext);
916   BEGIN(directive);
917 }
918 
919 <PROGRAM>[ \t\n]{ID}; {
920   // Get the program name
921   BEGIN(Body);
922 }
923 
924 <comments>[^}\n]* {
925   OutputLog("processing comments");
926   ProcessComment();
927 }
928 
929 <*>"//"[^\n]* {
930   ProcessComment();
931 }
932 
933 <Body>{S}{ID}{S}":=" {
934   fprintf(OUTPUT, "%s", yytext);
935 }
936 
937 <Body>interface {
938   OutputLog("// got interface");
939 }
940 
941 <Body>uses {
942   OutputLog("// processing a uses section");
943 
944   g_bType = false;
945   BEGIN(Uses);
946 } // Uses Section
947 
948 <InClass,Struct,Constants,Body,Func_Body>{S}+end{S}+[^;]*";" {
949   OutputLog("// Processing end with comments");
950   string str = yytext;
951 
952   int i = str.find("end", 0);
953   int s = str.find(";");
954   if (i != string::npos)
955     str.replace(i, 4, "end;" );
956 
957   if (s != string::npos)
958     str.replace(s, 1, " ");
959 
960   PushText(str.c_str());
961 }
962 
963 <InClass,Struct,Constants,Body>(^end;|{S}end;|{S}end{S};) {
964   OutputLog("// Got end in InClass,Struct or Constants");
965   OutputLog2("//", yytext);
966 
967   if (!g_bComments)
968   {
969     OutputLog("// Not a comment");
970     if (g_bFuncBody)
971     {
972       OutputLog("// In function body");
973       if (g_nBegins > 0)
974         g_nBegins--;
975 
976       ProcessEnd();
977       g_bStructure = false;
978 
979       if (g_nBegins > 0)
980         BEGIN(Func_Body);
981       else
982         BEGIN(mytype);
983     }
984     else
985     {
986       OutputLog("// investigate this... we haven't decremented counter");
987       ProcessEnd();
988       g_bStructure = false;
989       BEGIN(mytype);
990     }
991   }
992 }
993 
994 <Body,Constants>^{S}*type {
995   if (g_bImplementation)
996   {
997     OutputLog("// Ignore type Section");
998 
999     fprintf(OUTPUT, "#ifdef INCLUDE_TYPE_SECTION\n");
1000     g_bIgnoreTypeSection = true;
1001 
1002     g_bType = true;
1003     g_bConstSec = false;
1004     BEGIN(mytype);
1005 /*
1006 // removed this to investigate other ways of handling type section
1007     g_bVars = true;
1008     fprintf(OUTPUT, "\n/*\r\n//type\n");
1009     g_bComments = true;
1010     g_bIgnore = true;
1011     BEGIN(vars);
1012 */
1013   }
1014   else
1015   {
1016     OutputLog("// Not Ignoring type Section");
1017 
1018     g_bType = true;
1019     g_bConstSec = false;
1020     BEGIN(mytype);
1021   }
1022 }
1023 
1024 <Body,Constants>^(const|resourcestring) {
1025   if (g_bImplementation)
1026   {
1027     OutputLog("// Ignore const Section");
1028 
1029     g_bVars = true;
1030     fprintf(OUTPUT, "/*\n//const\n");
1031     g_bComments = true;
1032     g_bIgnore = true;
1033     BEGIN(vars);
1034   }
1035   else
1036   {
1037     OutputLog("// Not Ignoring const Section");
1038 
1039     g_bType = false;
1040     g_bClassBody = false;
1041     g_bConstSec = true;
1042     BEGIN(Constants);
1043   }
1044 }
1045 
1046 <Body>^var|{S}*var {
1047   if (g_bImplementation)
1048   {
1049     OutputLog("// Ignore var Section");
1050 
1051     g_bVars = true;
1052     fprintf(OUTPUT, "/*\nvar\n");
1053     g_bComments = true;
1054     BEGIN(vars);
1055   }
1056   else
1057   {
1058     OutputLog("// in a type varsection");
1059 
1060     g_bType = false;
1061     g_bClassBody = false;
1062     g_bConstSec = true;
1063     BEGIN(Constants);
1064   }
1065 }
1066 
1067 <vars>begin|asm        {
1068   OutputLogNum("// Got Begin (vars) - ", g_nBegins);
1069 
1070   if (g_bIgnore)
1071   {
1072     OutputLog("// Stop ignoring");
1073     g_bIgnore = false;
1074   }
1075 
1076   g_nBegins++;
1077   g_bVars = false;
1078   fprintf(OUTPUT, "*/\n{");
1079 
1080   if (!g_bKeepBody)
1081   {
1082     fprintf(OUTPUT, "\n#ifndef DOXYGEN_SKIP\n");
1083   }
1084 
1085   g_bComments = false;
1086   g_bFuncBody = true;
1087   BEGIN(Func_Body);
1088 }
1089 
1090 <vars>implementation {
1091 
1092   if (g_bInterfaceOnly)
1093   {
1094     OutputLog("// End of \'Interface\' section - finish now");
1095     yyterminate();
1096   }
1097 
1098   fprintf(OUTPUT, "*/\n");
1099   OutputLog("// Processing an implementation section (vars)");
1100 
1101   g_bType = false;
1102   g_bImplementation = true;
1103   g_bConstSec = false;
1104   BEGIN(Body);
1105 
1106   // Tidy up if we're ending a class
1107   if (pClass)
1108   {
1109     delete pClass;
1110     pClass = NULL;
1111     g_bClassBody = false;
1112   }
1113 }
1114 
1115 <vars>function|procedure|begin {
1116   if (g_bIgnore)
1117   {
1118     OutputLog("// section ignore");
1119     fprintf(OUTPUT, "*/\n");
1120   }
1121 
1122   g_bIgnore = false;
1123   g_bComments = false;
1124   PushText(yytext);
1125 
1126   g_bType = false;
1127   g_bConstSec = false;
1128   g_bImplementation = true;
1129   g_nBegins = 0;
1130 
1131   ProcessFunction(NORMAL);
1132   BEGIN(function);
1133 }
1134 
1135 <vars>"{*}" {
1136 }
1137 
1138 <Func_Body>{S}*"inherited"{S}+ {
1139 
1140   if (g_bConvertBody)
1141   {
1142     fprintf(OUTPUT, "\n::");
1143   }
1144   else
1145   {
1146     fprintf(OUTPUT, "%s", yytext);
1147   }
1148 }
1149 
1150 <Func_Body,IfThen>"<>" {
1151   if (g_bConvertBody)
1152   {
1153     fprintf(OUTPUT, "!=");
1154   }
1155   else
1156   {
1157     fprintf(OUTPUT, "%s", yytext);
1158   }
1159 }
1160 
1161 <Func_Body,IfThen,Body>")"{S}*{OPER}{S}*"(" {
1162   string op = yytext;
1163   Convert_Op(op, true);
1164 
1165   fprintf(OUTPUT, "%s", op.c_str());
1166 }
1167 
1168 
1169 <Func_Body,IfThen,Body>{OPER} {
1170   string op = yytext;
1171   Convert_Op(op, false);
1172 
1173   fprintf(OUTPUT, "%s", op.c_str());
1174 }
1175 
1176 <Func_Body>^if|{S}+if{S}+ {
1177   if (g_bConvertBody)
1178   {
1179     OutputLog("// Processing if ");
1180     PushText(yytext);
1181     BEGIN(IfThen);
1182   }
1183   else
1184   {
1185     fprintf(OUTPUT, "%s", yytext);
1186   }
1187 }
1188 
1189 <Func_Body>"for ".*"do" {
1190   if (g_bConvertBody)
1191   {
1192     OutputLog("// Processing for  ");
1193     PushText(yytext);
1194     BEGIN(ForLoop);
1195   }
1196   else
1197   {
1198     fprintf(OUTPUT, "%s", yytext);
1199   }
1200 }
1201 
1202 <ForLoop>"for ".*"do" {
1203 
1204   if (g_bConvertBody)
1205   {
1206     string str = yytext;
1207     string lowstr = str;
1208 
1209     std::transform (lowstr.begin(),lowstr.end(), lowstr.begin(), ::tolower);
1210 
1211     int forpos = lowstr.find("for", 0);
1212     int dopos = lowstr.find("do", 0);
1213 
1214     int eqpos;
1215 
1216     eqpos = str.find(":=", 0);
1217     if (eqpos != string::npos)
1218     {
1219       str.replace(eqpos, 2, " =");
1220     }
1221     else
1222     {
1223       eqpos = str.find('=', 0);
1224       if (eqpos != string::npos)
1225       {
1226         str.replace(eqpos, 2, "==");
1227       }
1228     }
1229 
1230     int topos = lowstr.find("to", 0);
1231 
1232     string init = str.substr(forpos + 3, eqpos - (forpos+3));
1233     string initval = str.substr(eqpos+1, topos - (eqpos+1));
1234     string opstr = str.substr(topos+2, dopos - (topos+2));
1235 
1236     fprintf(OUTPUT, "for (%s%s; %s < %s;)", init.c_str(), initval.c_str(), init.c_str(),
1237       opstr.c_str());
1238 
1239   }
1240   else
1241   {
1242     fprintf(OUTPUT, "%s", yytext);
1243   }
1244 
1245   BEGIN(Func_Body);
1246 }
1247 
1248 <Func_Body,IfThen>"self" {
1249   if (g_bConvertBody)
1250   {
1251     fprintf(OUTPUT, "this");
1252   }
1253   else
1254   {
1255     fprintf(OUTPUT, "%s", yytext);
1256   }
1257 }
1258 
1259 <Func_Body,IfThen>"self." {
1260   if (g_bConvertBody)
1261   {
1262     fprintf(OUTPUT, "this->");
1263   }
1264   else
1265   {
1266     fprintf(OUTPUT, "%s", yytext);
1267   }
1268 }
1269 
1270 <Func_Body,IfThen>{ID}"."{ID}|{ID}"("{ID}")""."{ID} {
1271   if (g_bConvertBody)
1272   {
1273     string str = yytext;
1274     int i = str.find('.', 0);
1275     str.replace(i, 1, "->" );
1276 
1277     i = str.find("self->", 0);
1278     if (i != string::npos)
1279       str.replace(i, 4, "this" );
1280 
1281     fprintf(OUTPUT, "%s", str.c_str());
1282   }
1283   else
1284   {
1285     fprintf(OUTPUT, "%s", yytext);
1286   }
1287 }
1288 
1289 <Func_Body,IfThen>{ID}";" {
1290   if (g_bConvertBody)
1291   {
1292     string str = yytext;
1293     // todo : should think about keeping a list of variables and either
1294     // adding () for function calling, or leave alone for variables.
1295 //    int i =  str.find(';', 0);
1296 //    str.replace(i, 3, "();" );
1297     fprintf(OUTPUT, "%s", str.c_str());
1298   }
1299   else
1300   {
1301     fprintf(OUTPUT, "%s", yytext);
1302   }
1303 }
1304 
1305 <Func_Body,IfThen>"Owner." {
1306   if (g_bConvertBody)
1307   {
1308     fprintf(OUTPUT, "::");
1309   }
1310   else
1311   {
1312     fprintf(OUTPUT, "%s", yytext);
1313   }
1314 }
1315 
1316 <Func_Body>{ID}{S}*":"{S}+ {
1317   if (g_bConvertBody)
1318   {
1319     fprintf(OUTPUT, "case %s ", yytext);
1320   }
1321   else
1322   {
1323     fprintf(OUTPUT, "%s", yytext);
1324   }
1325 }
1326 
1327 <IfThen>if {
1328   fprintf(OUTPUT, "if (");
1329 }
1330 
1331 <IfThen>"then" {
1332   fprintf(OUTPUT, ") ");
1333   BEGIN(Func_Body);
1334 }
1335 
1336 <Func_Body>"'"[^']+"'"|"''" {
1337   fprintf(OUTPUT, "%s",yytext);
1338 }
1339 
1340 <Func_Body>{S}case{S}[^*\n]+ {
1341   OutputLogNum("// Got Case - ", g_nBegins);
1342 
1343   if (!g_bComments)
1344   {
1345     g_nBegins++;
1346     g_bCase = true;
1347   }
1348 
1349   if (g_bConvertBody)
1350   {
1351     string str = yytext;
1352     int i =  str.find("case ", 0);
1353     str.erase(i, 5);
1354     i =  str.find(" of", 0);
1355     str.erase(i,3);
1356 
1357     string str2 = str;
1358     std::transform (str.begin(),str.end(), str2.begin(), ::tolower);
1359 
1360     i = str2.find("self", 0);
1361     if (i != string::npos)
1362     {
1363       str = str.replace(i, 4, "this" );
1364     }
1365 
1366     i =  str2.find(".", 0);
1367     if (i != string::npos)
1368     {
1369       str = str.replace(i, 1, "->" );
1370     }
1371 
1372     fprintf(OUTPUT, "switch (%s) {", str.c_str());
1373   }
1374   else
1375   {
1376     if (!g_bComments)
1377     {
1378       fprintf(OUTPUT, "%s\n",yytext);
1379     }
1380   }
1381 }
1382 
1383 <Func_Body>(^try|{S}try){S} {
1384   OutputLogNum("// Got Try - ", g_nBegins);
1385 
1386   if (!g_bComments)
1387   {
1388     OutputLog("// Not a comment");
1389     g_nBegins++;
1390     fprintf(OUTPUT, "%s", yytext);
1391   }
1392 }
1393 
1394 <Body,Func_Body>(^begin|{S}*begin|^asm|{S}asm){S} {
1395   OutputLogNum("// Got Begin (b/fb) - ", g_nBegins);
1396 
1397   if (!g_bComments)
1398   {
1399     OutputLog("// Not a comment");
1400     g_nBegins++;
1401     if (g_nBegins > 1)
1402     {
1403       if (g_bConvertBody)
1404       {
1405         fprintf(OUTPUT, "{");
1406       }
1407       else
1408       {
1409         fprintf(OUTPUT, "begin");
1410       }
1411     }
1412     else
1413     {
1414       fprintf(OUTPUT, "{");
1415 
1416       if (!g_bKeepBody)
1417       {
1418         fprintf(OUTPUT, "\n#ifndef DOXYGEN_SKIP\n");
1419       }
1420     }
1421   }
1422 
1423   g_bFuncBody = true;
1424   BEGIN(Func_Body);
1425 }
1426 
1427 <Body>"end." {
1428   fprintf(OUTPUT, "// finished\n");
1429 
1430   if(g_bIgnoreTypeSection)
1431   {
1432     fprintf(OUTPUT, "#endif\n");
1433   }
1434 }
1435 
1436 <Func_Body>(end$|{S}end$|end\x0d)      {
1437   OutputLogNum("// Got End - ", g_nBegins);
1438 
1439   if (!g_bComments)
1440   {
1441     OutputLog("// Not a comment");
1442     g_nBegins--;
1443     if (g_nBegins > 0)
1444     {
1445       if (g_bConvertBody)
1446       {
1447         fprintf(OUTPUT, "}");
1448       }
1449       else
1450       {
1451         fprintf(OUTPUT, "end");
1452       }
1453     }
1454     else
1455     {
1456       fprintf(OUTPUT, "}");
1457 
1458       if (!g_bKeepBody)
1459       {
1460         fprintf(OUTPUT, "\n*/\n");
1461         fprintf(OUTPUT, "\n#endif /* DOXYGEN_SKIP */");
1462       }
1463     }
1464   }
1465 
1466   // was just Body
1467   BEGIN(Func_Body);
1468 }
1469 
1470 <Func_Body>(^end;|{S}end;|{S}end{S};|{S}end{S}|end\x3b|end;\x0a) {
1471   OutputLogNum("// Got End1 - ", g_nBegins);
1472 
1473   if (!g_bComments)
1474   {
1475     OutputLog("// Not a comment");
1476     g_nBegins--;
1477     if (g_nBegins == 0)
1478     {
1479       if (!g_bKeepBody)
1480       {
1481         fprintf(OUTPUT, "\n#endif /* DOXYGEN_SKIP */");
1482       }
1483 
1484       fprintf(OUTPUT, "\n};");
1485       g_bFuncBody = false;
1486       BEGIN(Body);
1487     }
1488     else
1489     {
1490       if (g_bConvertBody)
1491       {
1492         fprintf(OUTPUT, "}");
1493       }
1494       else
1495       {
1496         fprintf(OUTPUT, "end");
1497       }
1498 
1499       BEGIN(Func_Body);
1500     }
1501   }
1502 }
1503 
1504 <Body>^finalization {
1505   fprintf(OUTPUT, "// %s\n", yytext);
1506 }
1507 
1508 <Body>^initialization {
1509   fprintf(OUTPUT, "// %s\n", yytext);
1510   fprintf(OUTPUT, "\n#ifndef DOXYGEN_SKIP\n");
1511   BEGIN(Initialisation);
1512 }
1513 
1514 <Initialisation>"end." {
1515   fprintf(OUTPUT, "// finished\n");
1516   fprintf(OUTPUT, "#endif\n");
1517   BEGIN(Body);
1518 }
1519 
1520 <*>^implementation {
1521 
1522   if (g_bInterfaceOnly)
1523   {
1524     OutputLog("// End of \'Interface\' section - finish now");
1525     yyterminate();
1526   }
1527 
1528   OutputLog("// Processing an implementation section");
1529 
1530   g_bType = false;
1531   g_bConstSec = false;
1532   g_bImplementation = true;
1533   g_nBegins = 0;
1534   BEGIN(Body);
1535 
1536   // Tidy up if we're ending a class
1537   if (pClass)
1538   {
1539     delete pClass;
1540     pClass = NULL;
1541     g_bClassBody = false;
1542   }
1543 }
1544 
1545 <Constants>^var {
1546   OutputLog("// in a type varsection");
1547 
1548   g_bType = false;
1549   g_bClassBody = false;
1550   g_bConstSec = true;
1551   BEGIN(Constants);
1552 }
1553 
1554 <Constants,mytype,Func_Body,InClass,Struct,myparent>{ID}{S}*":"{S}*"("([^)]*)")"{S}*";" {
1555   PushText(yytext);
1556   g_nGeneralCaller = YY_START;
1557   BEGIN(ProcessEnum);
1558 }
1559 
1560 <ProcessEnum>{ID} {
1561   g_strTypedefName = yytext;
1562   BEGIN(ProcessEnum1);
1563 }
1564 
1565 <ProcessEnum1>":" {} // eat
1566 
1567 <ProcessEnum1>{S}*"("([^)]*)")"{S}* {
1568 
1569   ChangeStrings();
1570 
1571   string str = yytext;
1572   int pos = str.find("(", 0);
1573   str = str.replace(pos, 1, "{");
1574   pos = str.find(")", 0);
1575   str = str.replace(pos, 1, "}");
1576 
1577   g_strTypedefType = str;
1578 }
1579 
1580 <ProcessEnum1>";" {
1581   fprintf(OUTPUT, "enum %s %s;\n", g_strTypedefName.c_str(), g_strTypedefType.c_str());
1582   BEGIN(g_nGeneralCaller);
1583 }
1584 
1585 <Constants,mytype,Func_Body,InClass,Struct,myparent>{ID}{S}*(":"|"="){S}*"array"{S}*"["([^\]])*"]"{S}*"of"{S}*{ID}{S}*("="{S}*"("([^)]*)")"{S}*)*";" {
1586   OutputLog2("// Processing array = ", yytext);
1587 
1588   PushText(yytext);
1589   g_nGeneralCaller = YY_START;
1590   BEGIN(ProcessArray);
1591 }
1592 
1593 <Constants,mytype,Func_Body,InClass,Struct,myparent>{ID}{S}*("="|":"){S}*("array"|"set"){S}*"of"{S}*{ID}{S}*";" {
1594   OutputLog2("// Processing array = ", yytext);
1595 
1596   PushText(yytext);
1597   g_nGeneralCaller = YY_START;
1598   BEGIN(ProcessSet);
1599 }
1600 
1601 <ProcessSet>{ID} {
1602   g_strTypedefName = yytext;
1603   BEGIN(ProcessSetType1);
1604 }
1605 
1606 <ProcessSetType1>("="|":") {}
1607 
1608 <ProcessSetType1>"set"{S}*"of" {
1609   g_strTypedef = "set";
1610   BEGIN(ProcessSetType2);
1611 }
1612 
1613 <ProcessSetType1>"array"{S}*"of" {
1614   g_strTypedef = "array";
1615   BEGIN(ProcessSetType2);
1616 }
1617 
1618 <ProcessSetType2>"("|")"
1619 
1620 <ProcessSetType2>{ID} {
1621   g_strTypedefType = yytext;
1622 }
1623 
1624 <ProcessSetType2>";" {
1625   if (g_bConvertBody)
1626   {
1627     Convert_Type(g_strTypedefType);
1628   }
1629 
1630   fprintf(OUTPUT, "typedef %s<%s> %s;", g_strTypedef.c_str(), g_strTypedefType.c_str(),g_strTypedefName.c_str());
1631   BEGIN(g_nGeneralCaller);
1632 }
1633 
1634 <ProcessArray>{ID} {
1635   pArray = new array_info(yytext, "", 0, "");
1636   BEGIN(ProcessArraySize);
1637 }
1638 
1639 <ProcessArraySize>(":"|"="){S}*"array"{S}*"[" {} // eat up
1640 <ProcessArraySize>"]" {} // eat up
1641 
1642 <ProcessArraySize>"byte" {
1643   OutputLog("// got byte, so size = 255");
1644   g_nSize = 255;
1645 
1646   g_lstSize.push_back(g_nSize);
1647 }
1648 
1649 <ProcessArraySize>"-"*{NUM} {
1650   g_nSize = atoi(yytext);
1651 
1652   OutputLogNum("// got size = ", g_nSize);
1653   g_lstSize.push_back(g_nSize);
1654 }
1655 
1656 <ProcessArraySize>{ID} {
1657   OutputLog2("// Need to decide what to do here...", yytext);
1658   g_nSize = 999;
1659   g_lstSize.push_back(g_nSize);
1660 }
1661 
1662 <ProcessArraySize>"," {
1663    OutputLog("// got a multidimensional array");
1664 }
1665 
1666 <ProcessArraySize>".." {
1667   /*g_lstSize.pop_back();*/
1668 }
1669 
1670 <ProcessArraySize>"]"{S}*"of" { BEGIN(ProcessArrayType); }
1671 
1672 <ProcessArrayType>{ID} {
1673   OutputLog2("// of type", yytext);
1674 
1675   pArray->sType = yytext;
1676 
1677   if (g_bConvertBody)
1678   {
1679     Convert_Type(pArray->sType);
1680   }
1681 }
1682 
1683 <ProcessArrayType>"="{S}*"("([^)]*)")"{S}* {
1684 
1685   ChangeStrings();
1686 
1687   string str = yytext;
1688   int pos = str.find("(", 0);
1689   str = str.replace(pos, 1, "{");
1690   pos = str.find(")", 0);
1691   str = str.replace(pos, 1, "}");
1692 
1693   pArray->sDefault = str;
1694 }
1695 
1696 <ProcessArrayType>";" {
1697 
1698   OutputLog("// Processing array type");
1699   fprintf(OUTPUT, "%s %s", pArray->sType.c_str(), pArray->sName.c_str());
1700 
1701   list<int>::iterator i;
1702 
1703   string comm;
1704   char buf[12];
1705   comm = "/*!< [";
1706   int c = g_lstSize.size();
1707   int pos = 0;
1708   for (i = g_lstSize.begin(); i != g_lstSize.end(); ++i, pos++)
1709   {
1710   #ifdef _WIN32
1711     comm += itoa(*i, buf, 10);
1712   #else
1713      snprintf(buf, sizeof(buf), "%d", *i);
1714      comm += buf;
1715   #endif
1716 
1717 	if (pos+1 < c)
1718 	{
1719 	  comm += "..";
1720 	}
1721 	else
1722 	{
1723 	  comm += "] */";
1724 	}
1725   }
1726 
1727   if (c > 0)
1728   {
1729 	fprintf(OUTPUT, "[%d]", g_lstSize.back());
1730   }
1731 
1732   g_lstSize.clear();
1733 
1734   fprintf(OUTPUT, "%s; %s\n", pArray->sDefault.c_str(), comm.c_str());
1735 
1736   if (pArray)
1737   {
1738     delete pArray;
1739     pArray = NULL;
1740   }
1741 
1742   BEGIN(g_nGeneralCaller);
1743 }
1744 
1745 <Constants>{ID}{S}*(","{S}*{ID}{S}*)+":"{S}*{ID}{S}*";" {
1746   OutputLog("// got a multiple definition");
1747 
1748   PushText(yytext);
1749   g_nGeneralCaller = YY_START;
1750   BEGIN(ProcessVariable);
1751 }
1752 
1753 <Constants>{ID}{S}*":"{S}*{ID}{S}*";" {
1754   OutputLog("// Constants");
1755   PushText(yytext);
1756   g_nGeneralCaller = YY_START;
1757   BEGIN(ProcessVariable);
1758 }
1759 
1760 <Constants>{ID}{S}*":"{S}*{ID}{S}*"="{S}*{NUM}";" {
1761   OutputLog2("// here 1723 ", yytext);
1762   PushText(yytext);
1763   g_nGeneralCaller = YY_START;
1764   BEGIN(ProcessVariable);
1765 }
1766 
1767 <Constants>{ID}{S}*"="{S}*('[^'\n]*'|[^;{\n]*)";" {
1768   OutputLog2("// x = [']y['] = ", yytext);
1769   PushText(yytext);
1770   BEGIN(ConstAssign1);
1771 }
1772 
1773 <ConstAssign1>{ID} {
1774   OutputLog2("// got ID = ", yytext);
1775 
1776   if (pClass)
1777     delete pClass;
1778 
1779   pClass = new class_info;
1780   pClass->sName = yytext;
1781   BEGIN(ConstAssign2);
1782 }
1783 
1784 <ConstAssign2>"=" {
1785   OutputLog("// got equals");
1786   BEGIN(ConstAssign3);
1787 }
1788 
1789 <ConstAssign3>('[^'\n]*'|[^;{\n]*)";" {
1790   OutputLog("// ConstAssign - output");
1791 
1792   ChangeStrings();
1793 
1794   fprintf(OUTPUT, "const %s %s = %s", pClass->sType.c_str(), pClass->sName.c_str(), yytext);
1795 
1796   if (pClass)
1797   {
1798     delete pClass;
1799     pClass = NULL;
1800   }
1801 
1802   BEGIN(Constants);
1803 }
1804 
1805 <mytype>^const|resourcestring {
1806   OutputLog("// in a type const section");
1807 
1808   g_bType = false;
1809   g_bClassBody = false;
1810   g_bConstSec = true;
1811   BEGIN(Constants);
1812 }
1813 
1814 <mytype>^var {
1815   OutputLog("// in a type varsection");
1816 
1817   g_bType = false;
1818   g_bClassBody = false;
1819   g_bConstSec = true;
1820   BEGIN(Constants);
1821 }
1822 
1823 <mytype>{ID}{S}"="{S}"-"*{ID}"("{ID}")"".."{ID}"("{ID}")"";" {
1824   // TODO : Enum - Similar to arraydef
1825   fprintf(OUTPUT, "// %s\n", yytext);
1826 }
1827 
1828 <mytype>{ID}{S}"="{S}"-"*{ID}*".."{ID}";" {
1829   // TODO : Enum - Similar to arraydef
1830   fprintf(OUTPUT, "// %s\n", yytext); }
1831 
1832 <mytype,Constants>function|procedure|constructor|destructor          {
1833   OutputLog2("// type processing :", yytext);
1834 
1835   func_type ft = NORMAL;
1836   if (strcmp(yytext, "destructor") == 0)
1837     ft = DESTRUCTOR;
1838 
1839   if (strcmp(yytext, "constructor") == 0)
1840     ft = CONSTRUCTOR;
1841 
1842   ProcessFunction(ft);
1843   BEGIN(function);
1844 }
1845 
1846 <myparent>"="{S}("procedure"|"function") {
1847 
1848   OutputLog("// function typedef processing");
1849   g_bCallback = true;
1850   ProcessFunction(NORMAL);
1851   BEGIN(callback);
1852 }
1853 
1854 <callback>"(" {
1855   OutputLog("// We've got a parameter list for this function");
1856   g_bParams = true;
1857   BEGIN(func_params);
1858 }
1859 
1860 <callback>":" {
1861   BEGIN(func_ret);
1862 }
1863 
1864 <callback>";"|"of object;" {
1865   OutputLog("// function typedef details");
1866   g_bCallback = false;
1867 
1868   fprintf(OUTPUT, "typedef %s (*%s)(", pFunc->sRet != "" ? pFunc->sRet.c_str() : "void",
1869     pClass->sName.c_str());
1870 
1871   DisplayParams();
1872 
1873   fprintf(OUTPUT, ");\n");
1874 
1875   if (pFunc)
1876   {
1877     delete pFunc;
1878     pFunc = NULL;
1879   }
1880 
1881   if (pClass)
1882   {
1883     delete pClass;
1884     pClass = NULL;
1885   }
1886 
1887   BEGIN(mytype);
1888 }
1889 
1890 <myparent>"="{S}"record" {
1891   OutputLog("// processing a record structure");
1892 
1893   fprintf(OUTPUT, "struct %s\n{\n", pClass->sName.c_str());
1894   BEGIN(InClass);
1895   g_bStructure = true;
1896 }
1897 
1898 <myparent>"="{S}"packed record" {
1899   OutputLog("// got a packed record");
1900 
1901   fprintf(OUTPUT, "struct %s\n{\n", pClass->sName.c_str());
1902   BEGIN(InClass);
1903   g_bStructure = true;
1904 }
1905 
1906 <myparent>"="{S}*"(" {
1907   ProcessEnums();
1908   BEGIN(Enum);
1909 }
1910 
1911 <Enum>({NUM}"."{NUM}|{NUM}) {
1912   OutputLog2("// enum num: ", yytext);
1913 
1914   param_info p ("", yytext,  "", "", false, false, false, false);
1915   lstParams.push_back(p);
1916 }
1917 
1918 <Enum>"'"{ID}"'" {
1919   OutputLog2("// enum 'id': ", yytext);
1920 
1921   param_info p ("", yytext,  "", "", false, false, false, false);
1922   lstParams.push_back(p);
1923 }
1924 
1925 <Enum>{ID} {
1926   OutputLog2("// enum id: ", yytext);
1927 
1928   param_info p ("", yytext,  "", "", false, false, false, false);
1929   lstParams.push_back(p);
1930 }
1931 
1932 <Enum>{ID}{S}*"="{S}*"-"*{NUM} {
1933   OutputLog2("// enum here 1: ", yytext);
1934 
1935   string id = yytext;
1936 
1937   int pos = id.find('=', 0);
1938   string ids = id.substr(0,pos);
1939 
1940   //fprintf(OUTPUT, "int %s", ids.c_str());
1941     param_info p ("", yytext,  "", ids.c_str(), false, false, false, false);
1942   lstParams.push_back(p);
1943 }
1944 
1945 <Enum>","
1946 <Enum>\n
1947 <Enum>{S}
1948 <Enum>")"  {
1949 
1950   DisplayEnum();
1951   RemoveParams();
1952 
1953   fprintf(OUTPUT, "};\n");
1954 
1955   g_bEnum = false;
1956   g_bParams = false;
1957 }
1958 
1959 <Enum>";" {
1960 
1961   if (g_bClassBody)
1962   {
1963     BEGIN(InClass);
1964   }
1965   else if (g_bType)
1966   {
1967     BEGIN(mytype);
1968   }
1969   else
1970   {
1971     BEGIN(Body);
1972   }
1973 
1974   if (g_bParams)
1975   {
1976     if (g_bEnum)
1977     {
1978       BEGIN(Enum);
1979     }
1980     else
1981     {
1982       BEGIN(func_params);
1983     }
1984   }
1985 
1986 }
1987 
1988 <mytype>{ID}{S}*"="{S}*"-"*{NUM}".."{NUM} {
1989   OutputLog2("// here 1: ", yytext);
1990 
1991   string id = yytext;
1992 
1993   int pos = id.find('=', 0);
1994   string ids = id.substr(0,pos);
1995 
1996   fprintf(OUTPUT, "int %s", ids.c_str());
1997 }
1998 
1999 <mytype>type {
2000   OutputLog("// ignore type keyword");
2001 }
2002 
2003 <mytype>(^end;|{S}end;|{S}end{S};) {
2004   OutputLog("// Ignore end...");
2005 }
2006 
2007 <mytype>{ID} {
2008   OutputLog2("// processing types : ", yytext);
2009   // Processing a class
2010 
2011   // Just in case...
2012   if (pClass)
2013     delete pClass;
2014 
2015   pClass = new class_info;
2016   pClass->sName = yytext;
2017   BEGIN(myparent);
2018 }
2019 
2020 <myparent>("="|":"){S}*"class of" {
2021   OutputLog("// pointer to class");
2022   BEGIN(ClassPtrVar);
2023 }
2024 
2025 <myparent>("="|":"){S}*"^" {
2026   OutputLog("// pointer to class");
2027   BEGIN(ClassPtrVar);
2028 }
2029 
2030 <myparent>"="{S}"interface"{S}*"(" {
2031   g_bInterface = true;
2032   BEGIN(myparent2);
2033 }
2034 
2035 <myparent>"="{S}*"class"{S}*";" {
2036   OutputLog("// got x = class;");
2037   fprintf(OUTPUT, "class %s;\n", pClass->sName.c_str());
2038 
2039   BEGIN(mytype);
2040 }
2041 
2042 <myparent>"="{S}"class"{S}*"(" {
2043   BEGIN(myparent2);
2044 } // Processing a class
2045 
2046 <myparent2>","  // Ignore comma
2047 
2048 <myparent2>{ID} {
2049 
2050   if (pClass->sParent != "")
2051   {
2052     OutputLog2("// Assigning parent2 : ", yytext);
2053     pClass->sParent2 = yytext;
2054   }
2055   else
2056   {
2057     OutputLog2("// Assigning parent : ", yytext);
2058 	OutputLog2("// Name parent : ", pClass->sName.c_str());
2059     pClass->sParent = yytext;
2060   }
2061 }
2062 
2063 <myparent2>";" {
2064   OutputLog("// Output class details");
2065   fprintf(OUTPUT, "class %s : public %s,%s\n{\n", pClass->sName.c_str(), pClass->sParent.c_str(),
2066     pClass->sParent2.c_str());
2067 
2068   g_bClassBody = true;
2069   BEGIN(InClass);
2070 }
2071 
2072 <myparent2>")"";" {
2073   OutputInheritedClass(1);
2074   BEGIN(mytype);
2075 }
2076 
2077 <myparent2>")" {
2078 
2079   OutputInheritedClass(0);
2080   BEGIN(InClass);
2081 }
2082 
2083 <myparent>"="{S}"class" {
2084   OutputLog("// got base class");
2085 
2086   OutputInheritedClass(0);
2087   BEGIN(InClass);
2088 }
2089 
2090 <myparent>"="{S} { BEGIN(myparent3); }
2091 <myparent>"="{S}"type" { BEGIN(myparent3); }
2092 <myparent3>{ID} {
2093 
2094   OutputLog("// output class details and tidy up");
2095 
2096   pClass->sParent = yytext;
2097   fprintf(OUTPUT, "typedef %s %s", pClass->sParent.c_str(), pClass->sName.c_str());
2098   BEGIN(mytype);
2099 }
2100 
2101 <InClass,Body>published {
2102 
2103   if (g_bClassBody)
2104   {
2105     fprintf(OUTPUT, "public:"); BEGIN(InClass);
2106   }
2107   else
2108   {
2109     fprintf(OUTPUT, "%s", yytext);
2110   }
2111 }
2112 
2113 <InClass,Body>public|private|protected {
2114 
2115   OutputLog("// got keyword");
2116 
2117   if (g_bClassBody)
2118   {
2119     fprintf(OUTPUT, "%s:", yytext);
2120     BEGIN(InClass);
2121   }
2122   else
2123   {
2124     // some keyword appearing as text
2125     fprintf(OUTPUT, "%s", yytext);
2126   }
2127 }
2128 
2129 <Body,InClass>(^property|{S}property) {
2130 
2131   // Just in case...
2132   if (pProperty)
2133     delete pProperty;
2134 
2135   pProperty = new prop_info;
2136 
2137   pProperty->sName = "";
2138   pProperty->sType = "";
2139   BEGIN(Property);
2140 }
2141 
2142 <InClass>"["[^\]]+"]" {
2143   OutputLog("// Processing GUID");
2144   fprintf(OUTPUT, "%s", yytext);
2145 }
2146 
2147 <Property>"["[^\]]+"]" {
2148   fprintf(OUTPUT, "/*%s*/", yytext);
2149 }
2150 
2151 
2152 <Property>":" { BEGIN(prop_type); }
2153 
2154 <prop_type>read { pProperty->bRead = true; }
2155 <prop_type>write { pProperty->bRead = false; }
2156 
2157 <prop_type>default{S}{NUM} {
2158   OutputLog("// got default");
2159   pProperty->sDefault = yytext;
2160  }
2161 
2162 <prop_type>default{S}{ID} {
2163   OutputLog("// got default");
2164   pProperty->sDefault = yytext;
2165 }
2166 <prop_type>{ID} {
2167   OutputLog2("// prop type :", yytext);
2168 
2169   if (g_bFom)
2170   {
2171     if (pProperty->bRead)
2172     {
2173       pProperty->sRead = yytext;
2174     }
2175     else
2176     {
2177       pProperty->sWrite = yytext;
2178     }
2179   }
2180   else
2181   {
2182     pProperty->sType = yytext;
2183 
2184     g_bFom = true;
2185   }
2186 }
2187 
2188 <Property,prop_type>";" {
2189 
2190   if (g_bGenerateSa)
2191   {
2192     if (pProperty->sRead != "" && pProperty->sWrite != "")
2193     {
2194       fprintf(OUTPUT, "/** \\sa %s For reading   \\sa %s For writing */\n", pProperty->sRead.c_str(), pProperty->sWrite.c_str());
2195     }
2196     else if (pProperty->sRead != "")
2197     {
2198       fprintf(OUTPUT, "/** \\sa %s For reading*/\n", pProperty->sRead.c_str());
2199     }
2200     else if (pProperty->sWrite != "")
2201     {
2202       fprintf(OUTPUT, "/** \\sa %s For writing*/\n", pProperty->sWrite.c_str());
2203     }
2204   }
2205 
2206   fprintf(OUTPUT, "%s %s; \n", pProperty->sType.c_str(), pProperty->sName.c_str() );
2207 
2208   if (pProperty)
2209   {
2210     delete pProperty;
2211     pProperty = NULL;
2212   }
2213 
2214   g_bFom = false;
2215 
2216   if (g_bClassBody)
2217   {
2218     BEGIN(InClass);
2219   }
2220   else
2221   {
2222     BEGIN(Body);
2223   }
2224 }
2225 
2226 <Property>{ID}  {
2227   OutputLog2("// property :", yytext);
2228 
2229   pProperty->sName = yytext;
2230 }
2231 
2232 <Body,InClass>default;
2233 
2234 <*>"{*}"        // Eat up {*}
2235 <*>"{**" {
2236   OutputLog("daz2");
2237   if (!g_bComments)
2238   {
2239     if (!g_bIgnore)
2240     {
2241       if (g_bJavaDoc)
2242         fprintf(OUTPUT, "/**");
2243       else
2244         fprintf(OUTPUT, "/***");
2245     }
2246 
2247     g_bComments = true;
2248   }
2249 
2250   if (YY_START != comments)
2251     g_nCommentCaller = YY_START;
2252 
2253   BEGIN(comments);
2254 }
2255 
2256 <*>"{"|"(*" {
2257   OutputLog("// Processing Block Comments");
2258 
2259   if (g_bVars)
2260   {
2261     fprintf(OUTPUT, yytext);
2262   }
2263   else
2264   {
2265     if (!g_bComments)
2266     {
2267   	  if (!g_bIgnore)
2268 	  {
2269 	    if (!g_bParams)
2270 		{
2271           fprintf(OUTPUT, "/*");
2272 		}
2273 		else
2274 		{
2275 		  g_lstComments.push_back("/*");
2276 	    }
2277 	  }
2278 
2279       g_bComments = true;
2280     }
2281   }
2282 
2283   if (YY_START != comments)
2284     g_nCommentCaller = YY_START;
2285 
2286   BEGIN(comments);
2287 }
2288 
2289 <*>"}"|"*)" {
2290 
2291   if (g_bVars)
2292   {
2293     OutputLog("g_bVars is true");
2294     fprintf(OUTPUT, yytext);
2295   }
2296   else
2297   {
2298     if (g_bIgnore)
2299     {
2300       OutputLog("// Ignore section in progress");
2301     }
2302     else
2303     {
2304 	  if (!g_bParams)
2305 	  {
2306 	    OutputLog("g_bParams is false");
2307         fprintf(OUTPUT, "*/ ");
2308       }
2309 	  else
2310 	  {
2311 	    g_lstComments.push_back("*/");
2312 	  }
2313       g_bComments = false;
2314     }
2315   }
2316 
2317   BEGIN(g_nCommentCaller);
2318   g_nCommentCaller = 0;
2319 }
2320 
2321 <*>function|procedure|constructor|destructor          {
2322 
2323   if (g_nBegins > 0)
2324   {
2325     fprintf(OUTPUT, "%s", yytext);
2326   }
2327   else
2328   {
2329     OutputLog2("// processing a ", yytext);
2330 
2331     if (g_bComments)
2332     {
2333       // print the keyword, then continue commenting
2334       fprintf(OUTPUT, "%s", yytext);
2335       BEGIN(comments);
2336     }
2337     else
2338     {
2339       func_type ft = NORMAL;
2340       if (strcmp(yytext, "destructor") == 0)
2341         ft = DESTRUCTOR;
2342 
2343       if (strcmp(yytext, "constructor") == 0)
2344         ft = CONSTRUCTOR;
2345 
2346       ProcessFunction(ft);
2347       BEGIN(function);
2348     }
2349   }
2350 }
2351 
2352 <function>{ID}"."{ID} {
2353   OutputLog2("// processing function class.name :", yytext);
2354   string s = yytext;
2355 
2356   int pos = s.find('.', 0);
2357   int len = s.length();
2358 
2359   OutputLogNum("// Found . at position", pos);
2360 
2361   pFunc->sClass = s.substr(0, pos);
2362   pFunc->sName = s.substr(pos + 1, len -(pos+1) );
2363 
2364   OutputLog2("// Class = ", pFunc->sClass.c_str());
2365   OutputLog2("// Name  = ", pFunc->sName.c_str());
2366 }
2367 
2368 <function>{ID} {
2369   OutputLog2("// process function name :", yytext);
2370   pFunc->sName = yytext;
2371 }
2372 
2373 <function>"(" {
2374   OutputLog("// We've got a parameter list for this function");
2375   g_bParams = true;
2376   BEGIN(func_params);
2377 }
2378 
2379 <func_ret>{ID}"."{ID} {
2380 
2381   string str = yytext;
2382 
2383   string strUnit;
2384   string strRet;
2385 
2386   int pos = str.find('.', 0);
2387   int len = str.length();
2388 
2389   strUnit = str.substr(0, pos);
2390   strRet = str.substr(pos + 1, len -(pos+1) );
2391 
2392   fprintf(OUTPUT, "/// \\sa %s\n", strUnit.c_str());
2393   pFunc->sRet = strRet;
2394 
2395   if (g_bCallback)
2396   {
2397     BEGIN(callback);
2398   }
2399   else
2400   {
2401     BEGIN(function);
2402   }
2403 }
2404 
2405 <func_ret>{ID} {
2406   OutputLog2("// assign return type :", yytext);
2407 
2408   pFunc->sRet = yytext;
2409 
2410   if (g_bCallback)
2411   {
2412     BEGIN(callback);
2413   }
2414   else
2415   {
2416     BEGIN(function);
2417   }
2418 }
2419 
2420 <func_params>")"":" {
2421 ProcessParameterType(g_processtype.c_str());
2422   OutputLog("// Parameter list has finished - there's a return type to be got");
2423   g_bParams = false;
2424 
2425   BEGIN(func_ret);
2426 }
2427 
2428 
2429 <func_params>")" {
2430 ProcessParameterType(g_processtype.c_str());
2431   OutputLog("// Parameter list has finished");
2432 
2433   g_bAtEnd = true;
2434 }
2435 
2436 <func_params>"var"        { g_bVar = true; }
2437 
2438 <func_params>"out" {
2439   g_bOut = true;
2440 
2441   // display parameter wise, treat in the same way as a var
2442   g_bVar = true;
2443 }
2444 
2445 <func_params>"const"      { g_bConst = true; }
2446 <func_params>"of"
2447 
2448 <func_params>"=" {
2449   OutputLog("// about to assign value");
2450 
2451   BEGIN(DefaultVal);
2452 }
2453 
2454 <DefaultVal>"'"[^']+"'" {
2455   //lstParams.back().sDefault = yytext;
2456   g_defaultvalue = yytext;
2457   ProcessParameterType(g_processtype.c_str());
2458   BEGIN(func_params);
2459 }
2460 
2461 <DefaultVal>"[]" {
2462   g_defaultvalue = yytext;
2463   ProcessParameterType(g_processtype.c_str());
2464   BEGIN(func_params);
2465 }
2466 
2467 <DefaultVal>"''" {
2468   //lstParams.back().sDefault = yytext;
2469   g_defaultvalue = yytext;
2470   ProcessParameterType(g_processtype.c_str());
2471   BEGIN(func_params);
2472 }
2473 
2474 <DefaultVal>{ID} {
2475   OutputLog2("// defaultval id : ", yytext);
2476 
2477   //lstParams.back().sDefault = yytext;
2478   g_defaultvalue = yytext;
2479   ProcessParameterType(g_processtype.c_str());
2480   BEGIN(func_params);
2481 }
2482 
2483 <DefaultVal>{NUM} {
2484   //lstParams.back().sDefault = yytext;
2485   g_defaultvalue = yytext;
2486   ProcessParameterType(g_processtype.c_str());
2487   BEGIN(func_params);
2488 }
2489 
2490 <func_params>{ID} {
2491   OutputLog2("// assign parameter info :", yytext);
2492 
2493   g_defaultvalue = "";
2494   g_processtype = "";
2495 
2496   param_info p("", yytext, "", "", g_bConst, g_bVar, g_bOut, g_bArray);
2497   lstParams.push_back(p);
2498 }
2499 
2500 <function>{S}":"{S}    { BEGIN(func_ret); }	// Get return type
2501 <function>":"    { BEGIN(func_ret); }		// Get return type
2502 
2503 <function>";" {
2504   list<param_info>::iterator i;
2505 
2506   OutputLog("// output function details");
2507 
2508 // ------------------------
2509   // todo : remove this and fix underlying cause
2510   // needed to add, so function details are outputted correctly.
2511   fprintf(OUTPUT, "\n");
2512 // ------------------------
2513 
2514   // Any return type?
2515   if (pFunc->sRet != "")
2516   {
2517     fprintf(OUTPUT, "%s ", pFunc->sRet.c_str() );
2518   }
2519 
2520   // destructor
2521   if (pFunc->eFuncType == DESTRUCTOR)
2522   {
2523     if (g_bClassBody)
2524     {
2525       fprintf(OUTPUT, "~");
2526       if (pClass->sName != "")
2527       {
2528         pFunc->sName = pClass->sName;
2529       }
2530     }
2531     else
2532     {
2533       if (pFunc->sClass != "")
2534       {
2535         pFunc->sName = "~" + pFunc->sClass;
2536       }
2537     }
2538   }
2539 
2540   // constructor
2541   if (pFunc->eFuncType == CONSTRUCTOR)
2542   {
2543     if (g_bClassBody)
2544     {
2545       if (pClass->sName != "")
2546       {
2547         pFunc->sName = pClass->sName;
2548       }
2549     }
2550     else
2551     {
2552       if (pFunc->sClass != "")
2553       {
2554         pFunc->sName = pFunc->sClass;
2555       }
2556     }
2557   }
2558 
2559   // Class
2560   if (pFunc->sClass != "" )
2561   {
2562     fprintf(OUTPUT, "%s::", pFunc->sClass.c_str() );
2563   }
2564 
2565   // Function name
2566   fprintf(OUTPUT, "%s (", pFunc->sName.c_str() );
2567 
2568   DisplayParams();
2569 
2570   fprintf(OUTPUT, ")");
2571 
2572   if (g_bClassBody || !g_bImplementation)
2573   {
2574     fprintf(OUTPUT, ";\n");
2575   }
2576   else
2577   {
2578     fprintf(OUTPUT, "\n");
2579   }
2580 
2581   if (pFunc)
2582   {
2583     delete pFunc;
2584     pFunc = NULL;
2585   }
2586 
2587   if (g_bClassBody)
2588   {
2589     BEGIN(InClass);
2590   }
2591   else
2592   {
2593     BEGIN(Body);
2594   }
2595 }
2596 
2597 <func_params>\n { }
2598 <function>\n { }
2599 <func_params>"," { }
2600 
2601 <func_params>";"|"of object;" {
2602   OutputLog("// func_params 1");
2603 
2604   ProcessParameterType(g_processtype.c_str());
2605 
2606   if(g_bAtEnd)
2607   {
2608     g_bAtEnd = false;
2609     g_bParams = false;
2610     PushText(yytext);
2611     pFunc->sRet = "";
2612 
2613     if (g_bCallback)
2614     {
2615       BEGIN(callback);
2616     }
2617     else
2618     {
2619       BEGIN(function);
2620     }
2621   }
2622 }
2623 
2624 <func_params>":" {
2625 
2626   if (g_bAtEnd)
2627   {
2628     OutputLog("// Parameter list has finished - there's a return type to be got");
2629     g_bParams = false;
2630     g_bAtEnd = false;
2631 
2632     BEGIN(func_ret);
2633   }
2634   else
2635   {
2636     g_bConst = false;
2637     g_bOut = false;
2638     g_bVar = false;
2639     g_bArray = false;
2640     BEGIN(param_type);
2641   }
2642 }
2643 
2644 <param_type>{ID}"."{ID} {
2645 
2646   string str;
2647 
2648   str = yytext;
2649 
2650   int i =  str.find('.', 0);
2651   str = str.replace(i, 3, "::" );
2652   OutputLog2("// param type :", str.c_str());
2653 
2654   ProcessParameterType(str.c_str());
2655 
2656   BEGIN(func_params);
2657 }
2658 
2659 <param_type>"array of" {
2660   OutputLog("// Processing array of ");
2661 
2662   list<param_info>::iterator i;
2663   i = lstParams.begin();
2664   i->bArray = true;
2665 }
2666 
2667 <param_type>{ID} {
2668   OutputLog2("// processing parameter type :", yytext);
2669 
2670   //ProcessParameterType(yytext);
2671   g_processtype = yytext;
2672 
2673   BEGIN(func_params);
2674 }
2675 
2676 <ClassVar>"="{S}*"(" {
2677   ProcessEnums();
2678   BEGIN(Enum);
2679 }
2680 
2681 <ProcessVariable>{ID} {
2682   OutputLog2("// ProcessVariable ", yytext);
2683 
2684   g_bParams = true;
2685 
2686   param_info p ("", yytext,  "", "", false, false, false, false);
2687   lstParams.push_back(p);
2688 
2689   BEGIN(ProcessVariableType);
2690 }
2691 
2692 <ProcessVariableType>"," {
2693   OutputLog("// we've got a multiple variable definition");
2694 
2695   BEGIN(ProcessVariable);
2696 }
2697 
2698 <ProcessVariableType>":" {}	// Eat up the colon
2699 
2700 <ProcessVariableType>{ID} {
2701   OutputLog2("// ProcessVariableType :", yytext);
2702   g_processtype = yytext;
2703   BEGIN(ProcessVariableType2);
2704 }
2705 
2706 <ProcessVariableType2>";" {
2707   OutputLog("// output the variable definition2");
2708 
2709   ProcessParameterType(g_processtype.c_str());
2710   DisplayVariables();
2711   g_bParams = false;
2712 
2713   BEGIN(g_nGeneralCaller);
2714 }
2715 
2716 <ProcessVariableType2>"=" {
2717   BEGIN(ProcessVariableType3);
2718 }
2719 
2720 <ProcessVariableType3>"-"*{NUM} {
2721   g_defaultvalue = yytext;
2722 
2723   OutputLog2("// got size = ", yytext);
2724 
2725   ProcessParameterType(g_processtype.c_str());
2726 
2727   BEGIN(ProcessVariableType);
2728 }
2729 
2730 <ProcessVariableType>";" {
2731   OutputLog("// output the variable definition");
2732 
2733   DisplayVariables();
2734   g_bParams = false;
2735 
2736   BEGIN(g_nGeneralCaller);
2737 }
2738 
2739 <InClass,Struct,mytype>{ID}{S}*(","{S}*"//"[^}\n]*)+ {
2740   OutputLog("// multiple def with comments");
2741   PushText(yytext);
2742   g_nGeneralCaller = YY_START;
2743   BEGIN(ProcessVariable);
2744 }
2745 
2746 <InClass,Struct,Constants,mytype>{ID}{S}*":"{S}*"-"*{NUM}{S}*".."{S}*"-"*{NUM}{S}*";" {
2747   OutputLog2("// got a subrange var = ", yytext);
2748 
2749   string str = yytext;
2750   int pos = str.find(':', 0);
2751   int len = str.length();
2752 
2753   string name = str.substr(0,pos);
2754   string rest = str.substr(pos + 1, len -(pos+1) );
2755 
2756   fprintf(OUTPUT, "long %s;  ", name.c_str());
2757   fprintf(OUTPUT, "/**< Subrange %s */\n", rest.c_str());
2758 }
2759 
2760 <InClass,Struct,mytype>{ID}{S}*(","{S}*{ID}{S}*)+":"{S}*{ID}{S}*";" {
2761   OutputLog("// got a multiple definition");
2762 
2763   PushText(yytext);
2764   g_nGeneralCaller = YY_START;
2765   BEGIN(ProcessVariable);
2766 }
2767 
2768 <InClass,Struct>{ID}{S}*":"{S}*{ID}{S}*";" {
2769   OutputLog("InClass,Struct");
2770   PushText(yytext);
2771   g_nGeneralCaller = YY_START;
2772   BEGIN(ProcessVariable);
2773 }
2774 
2775 <InClass,Struct>{ID} {
2776   OutputLog2("// process a class variable", yytext);
2777 
2778   pClass->sVar = yytext;
2779 
2780 //  PushText(yytext);
2781 
2782 //  g_nGeneralCaller = YY_START;
2783 //  BEGIN(ProcessVariable);
2784 
2785 //  g_bParams = true;
2786 
2787 //  param_info p ("", yytext,  "", "", false, false, false, false);
2788 //  lstParams.push_back(p);
2789 
2790   BEGIN(ClassVar);
2791 
2792 }
2793 
2794 <ClassVar>"," {
2795   OutputLog("// we've got a multiple variable definition");
2796 
2797   if(g_bClassBody)
2798   {
2799     BEGIN(InClass);
2800   }
2801   else
2802   {
2803     BEGIN(Struct);
2804   }
2805 }
2806 
2807 <ClassVar>":" {}	// Eat up the colon
2808 
2809 <ClassVar>{ID} {
2810   OutputLog2("// classvar ID :", yytext);
2811   ProcessParameterType(yytext);
2812 }
2813 
2814 <ClassVar>";" {
2815   OutputLog("// output the variable definition");
2816 
2817   DisplayVariables();
2818   g_bParams = false;
2819 
2820   if(g_bClassBody)
2821   {
2822     BEGIN(InClass);
2823   }
2824   else
2825   {
2826     BEGIN(Struct);
2827   }
2828 }
2829 
2830 <ClassPtrVar>{ID} {
2831   OutputLog2("// classvar id :", yytext);
2832   pClass->sType = yytext;
2833 }
2834 
2835 <ClassPtrVar>";" {
2836   OutputLog("// output the typedef");
2837   fprintf(OUTPUT, "typedef %s* %s;\n", pClass->sType.c_str(), pClass->sName.c_str());
2838 
2839   BEGIN(mytype);
2840 }
2841 
2842 <Uses>;         { BEGIN(Body); }
2843 <Uses>{ID} {}
2844 <Uses>, {}
2845 
2846 %%
2847 
2848 //*****************************************************************************
2849 /// Push text back for processing
2850 void PushText(const char* txt)   ///< Text to be put back
2851 {
2852   int i;
2853 
2854   char* yycopy = strdup(txt);
2855   for (i = yyleng -1 ; i >= 0; --i)
2856     unput(yycopy[i]);
2857 
2858   free(yycopy);
2859 }
2860 
2861 //*****************************************************************************
2862 /// Output program version information
2863 void version_info(void)
2864 {
2865   fprintf(stdout, "Pas2Dox version %s %s\n", version, date);
2866   fprintf(stdout, "Copyright Darren Bowles 2002,2003\n\n");
2867   fprintf(stdout, "Pas2dox is a Pascal/Delphi/Kylix input filter for Doxygen\n\n");
2868   fprintf(stdout, "pas2dox [-h] [-d] [-k] [-i] [-o] <input_file>\n");
2869   fprintf(stdout, " -h - Help Information\n");
2870   fprintf(stdout, " -d - Run In Debug Mode\n");
2871   fprintf(stdout, " -k - Don't Comment Out Function Body\n");
2872   fprintf(stdout, " -i - Process only \'Interface\' section\n");
2873   fprintf(stdout, " -j - JavaDoc processing\n");
2874   fprintf(stdout, " -o - Output to filename.cpp instead of console\n");
2875   fprintf(stdout, " -b - Experimental convert function body to c++\n");
2876   fprintf(stdout, " -s - Suppress generation of \\sa clauses on properties");
2877 }
2878 
2879 int main (int argc, char** argv)
2880 {
2881   bool bOutput   = false;
2882   bool bEnd      = false;
2883   bool bShowHelp = true;
2884 
2885   for (int i = 1; i < argc && !bEnd; ++i)
2886   {
2887     if (strlen(argv[i]) == 2 && argv[i][0] == '-')
2888     {
2889       // commandline option
2890       switch (argv[i][1])
2891       {
2892       case 'd':
2893         g_bDebugMode = true;
2894         break;
2895 
2896       case 'k':
2897         g_bKeepBody = true;
2898         break;
2899 
2900       case 'j':
2901         g_bJavaDoc = true;
2902         break;
2903 
2904       case 'o':
2905         bOutput = true;
2906         break;
2907 
2908       case 'i':
2909         g_bInterfaceOnly = true;
2910         break;
2911 
2912       case 'b':
2913         g_bConvertBody = true;
2914         break;
2915 
2916       case 's':
2917         g_bGenerateSa = false;
2918         break;
2919 
2920       case 'h':
2921       default:
2922 	    bEnd = true;
2923       }
2924     }
2925     else
2926     {
2927       if (i == argc - 1)
2928       {
2929         // input filename
2930         yyin = fopen(argv[i], "r");
2931 
2932         if (yyin == NULL)
2933         {
2934           fprintf(stdout, "Error : Filename %s Not Found.\n", argv[i]);
2935           return 1;
2936         }
2937 
2938         bShowHelp = false;
2939 
2940         if (bOutput)
2941         {
2942           string filename = argv[i];
2943           filename += ".cpp";
2944 
2945           OUTPUT = fopen(filename.c_str(), "w");
2946         }
2947         else
2948           OUTPUT = stdout;
2949       }
2950     }
2951   }
2952 
2953   if (bShowHelp || !OUTPUT)
2954   {
2955     version_info();
2956     return 0;
2957   }
2958 
2959   if (g_bDebugMode)
2960   {
2961     fprintf(OUTPUT, "// Running In Debug Mode...\n\n");
2962   }
2963 
2964 
2965   yyout = OUTPUT;
2966   yylex();
2967 
2968   return 0;
2969 }
2970 
2971 extern "C"
2972 {
2973   int yywrap() { return 1; }
2974   void codeYYdummy() { yyrealloc(0,0); }
2975 }
2976