source: trunk/vbfilter.awk @ 42

Revision 42, 24.9 KB checked in by sevo, 7 months ago (diff)
- fixed Type keyword recognition
Line 
1#----------------------------------------------------------------------------
2# vbfilter.awk - doxygen VB .NET filter script - v2.4.1
3#
4# Creation:     26.05.2010  Vsevolod Kukol
5# Last Update:  09.10.2011  Vsevolod Kukol
6#
7# Copyright (c) 2010-2011 Vsevolod Kukol, sevo(at)sevo(dot)org
8#
9# Inspired by the Visual Basic convertion script written by
10# Mathias Henze. Rewritten from scratch with VB.NET support by
11# Vsevolod Kukol.
12#
13# requirements: doxygen, gawk
14#
15# usage:
16#    1. create a wrapper shell script:
17#        #!/bin/sh
18#        gawk -f /path/to/vbfilter.awk "$1"
19#        EOF
20#    2. define wrapper script as INPUT_FILTER in your Doxyfile:
21#        INPUT_FILTER = /path/to/vbfilter.sh
22#    3. take a look on the configuration options in the Configuration
23#       section of this file (inside BEGIN function)
24#
25# This program is free software; you can redistribute it and/or modify
26# it under the terms of the GNU General Public License as published by
27# the Free Software Foundation; either version 2 of the License, or
28# (at your option) any later version.
29#----------------------------------------------------------------------------
30
31
32BEGIN{
33#############################################################################
34# Configuration
35#############################################################################
36        # unix line breaks
37        # set to 1 if using doxygen on unix with
38        # windows formatted sources
39        UnixLineBreaks=1;
40       
41        # leading shift inside classes/namespaces/etc.
42        # default is "\t" (tab)
43        ShiftRight="\t";
44        #ShiftRight="    ";
45       
46        # add namespace definition at the beginning using project directory name
47        # should be enabled, if no explicit namespaces are used in the sources
48        # but doxygen should recognize package names.
49        # in C# unlike in VB .NET a namespace must always be defined
50        leadingNamespace=1;
51       
52        # per default the parser converts all keywords to their C# equivalents:
53        # Function -> function
54        # Sub -> void
55        # ....
56        # Set csharpStyledOutput=0 to keep the VB style in the resulting
57        # documentation.
58        csharpStyledOutput=1;
59       
60#############################################################################
61# helper variables, don't change
62#############################################################################
63        printedFilename=0;
64        fileHeader=0;
65        fullLine=1;
66        classNestCounter=0;
67        className[1]="";
68        insideVB6Class=0;
69        insideVB6ClassName="";
70        insideVB6Header=0;
71        insideNamespace=0;
72        insideComment=0;
73        insideImports=0;
74        instideVB6Property=0;
75        isInherited=0;
76        lastLine="";
77        appShift="";
78       
79}
80
81#############################################################################
82# shifter functions
83#############################################################################
84function AddShift() {
85        appShift=appShift ShiftRight;
86}
87
88function ReduceShift() {
89        appShift=substr(appShift,0,length(appShift)-length(ShiftRight));
90}
91
92#############################################################################
93# apply dos2unix
94#############################################################################
95UnixLineBreaks==1{
96        sub(/\r$/,"")
97}
98
99#############################################################################
100# merge multiline statements into one line
101#############################################################################
102fullLine==0{
103        fullLine=1;
104        $0= lastLine$0;
105        lastLine="";
106}
107/_$/{
108        fullLine=0;
109        sub(/_$/,"");
110        lastLine=$0;
111        next;
112
113}
114#############################################################################
115# remove leading whitespaces and tabs
116#############################################################################
117/^[ \t]/{
118        sub(/^[ \t]*/, "")
119}
120
121#############################################################################
122# remove Option and Region statements
123#############################################################################
124(/^#Region[[:blank:]]+/ ||
125/.*Option[[:blank:]]+/) && insideComment!=1 {
126        next;
127}
128
129
130#############################################################################
131# VB6 file headers including class definitions
132#############################################################################
133
134# if file begins with a class definition, swith to VB6 mode
135/.*[[:blank:]]+CLASS/ ||
136/.*[[:blank:]]+VB\.Form[[:blank:]]+/ ||
137/.*[[:blank:]]+VB\.UserControl[[:blank:]]+/ {
138        insideVB6Class=1;
139        next;
140}
141
142# ignore first line in VB6 forms
143/.*VERSION[[:blank:]]+[0-9]+/ {
144        next;
145}
146
147# get VB6 class name
148/^Attribute[[:blank:]]+VB_Name.*/ {
149        insideVB6ClassName=gensub(".*VB_Name[[:blank:]]+[=][[:blank:]]+\"(.*)\"","\\1","g",$0);
150        insideVB6Header=1
151}
152
153# detect when class attributes begin, to recognize the end of VB6 header
154/^Attribute[[:blank:]]+.*/ {
155        insideVB6Header=1
156        next;
157}
158
159# detect the end of VB6 header
160(!(/^Attribute[[:blank:]]+.*/)) && insideVB6Class==1 && insideVB6Header<=1{
161        if (insideVB6Header==0) {
162                next;
163        } else {
164                insideVB6Header=2
165        }
166}
167
168
169#############################################################################
170# parse file header comment
171#############################################################################
172
173/^[[:blank:]]*'/ && fileHeader!=2 {
174
175        # check if header already processed
176        if (fileHeader==0) {
177                fileHeader=1;
178                printedFilename=1
179                # print @file line at the beginning
180                file=gensub(/\\/, "/", "G", FILENAME)
181                print "/**\n * @file "basename[split(file, basename , "/")];
182                # if inside VB6 class module, then the file header describes the
183                # class itself and should be printed after
184                if (insideVB6Class==1) {
185                        print " * \\brief Single VB6 class module, defining " insideVB6ClassName;
186                        print " */";
187                        if (leadingNamespace==1) {      # leading namespace enabled?
188                                # get project name from the file path
189                                print "namespace "basename[split(file, basename , "/")-1]" {";
190                                AddShift()
191                        }
192                        print appShift " /**";
193                }
194        }
195        sub("^[ \t]*'+"," * ");         # replace leading "'"
196        print appShift $0;
197        next;
198}
199
200# if .*' didn't match but header was processed, then
201# the header ends here
202fileHeader!=2 {
203        if (fileHeader!=0) {
204                print appShift " */";
205        }
206        fileHeader=2;
207}
208
209#############################################################################
210# print simply @file, if no file header found
211#############################################################################
212printedFilename==0 {
213        printedFilename=1;
214        file=gensub(/\\/, "/", "G", FILENAME)
215                if (insideVB6Class!=1) {
216                        print "/// @file \n";
217                } else {
218                        print "/**\n * @file \n";
219                        print " * \\brief Single VB6 class module, defining " insideVB6ClassName;
220                        print " */";
221                        if (leadingNamespace==1) {      # leading namespace enabled?
222                                # get project name from the file path
223                                print "namespace "basename[split(file, basename , "/")-1]" {";
224                                AddShift()
225                        }
226                }
227}
228
229
230#############################################################################
231# skip empty lines
232#############################################################################
233/^$/ { next; }
234
235#############################################################################
236# convert Imports to C# style
237#
238# remark: doxygen seems not to recognize
239#         c# using directives so converting Imports is maybe useless?
240#############################################################################
241/.*Imports[[:blank:]]+/ {
242        sub("Imports","using");
243        print $0";";
244        insideImports=1;
245        next;
246}
247
248#############################################################################
249# print leading namespace after the using section (if present)
250# or after the file header.
251# namespace name is extracted from file path. the last directory name in
252# the path, usually the project folder, is used.
253#
254# can be disabled by leadingNamespace=0;
255#############################################################################
256(!/^Imports[[:blank:]]+/) && leadingNamespace<=1 && fileHeader==2{
257        if (leadingNamespace==1) {      # leading namespace enabled?
258                # if inside VB6 file, then namespace was already printed
259                if (insideVB6Class!=1) {
260                        file=gensub(/\\/, "/", "G", FILENAME)
261                        # get project name from the file path
262                        print "namespace "gensub(/ /,"_","G",basename[split(file, basename , "/")-1])" {";
263                        AddShift()
264                }
265                leadingNamespace=2;     # is checked by the END function to print corresponding "}"
266        } else {
267                # reduce leading shift
268                leadingNamespace=3;
269        }
270        insideImports=0;
271        if (insideVB6Class==1) {
272                isInherited=1;
273                print appShift "class " insideVB6ClassName;
274        }
275}
276
277
278
279#############################################################################
280# handle comments
281#############################################################################
282
283## beginning of comment
284(/^[[:blank:]]*'''[[:blank:]]*/ || /^[[:blank:]]*'[[:blank:]]*[\\<][^ ].+/) && insideComment!=1 {
285        if (insideEnum==1){     
286                # if enum is being processed, add comment to enumComment
287                # instead of printing it
288                if (enumComment!="") {
289                        enumComment = enumComment "\n" appShift "/**";
290                } else {
291                        enumComment = appShift "/**";
292                }
293               
294        } else {
295       
296                # if inheritance is being processed, then add comment to lastLine
297                # instead of printing it and process the end of
298                # class/interface declaration
299               
300                if (isInherited==1){
301                        endOfInheritance();
302                }
303                print appShift "/**"
304        }
305        insideComment=1;
306}
307
308## strip leading '''
309/^[[:blank:]]*'/ {
310        if(insideComment==1){
311                commentString=gensub("^[ \t]*[']+"," * ",1,$0);
312                # if enum is being processed, add comment to enumComment
313                # instead of printing it
314                if (insideEnum==1){
315                        enumComment = enumComment "\n" appShift commentString;
316                } else {
317                        print appShift commentString;
318                }
319                next;
320        }
321}
322
323## end of comment
324(!(/^[[:blank:]]*'/)) && insideComment==1 {
325        # if enum is being processed, add comment to enumComment
326        # instead of printing it
327        if (insideEnum==1){     
328                enumComment = enumComment "\n" appShift " */";
329        } else {
330                print appShift " */";
331        }
332        insideComment=0;
333}
334
335#############################################################################
336# inline comments in c# style /** ... */
337#############################################################################
338# strip all commented lines, if not part of a comment block
339/^'+/ && insideComment!=1 {
340        next;
341}
342/.+'+/ && insideComment!=1 {
343        sub("[[:blank:]]*'"," /**< \\brief ");
344        $0 = $0" */"
345}
346
347#############################################################################
348# strip compiler options
349#############################################################################
350/.*<.*>.*/ {
351        gsub("<.*>[ ]+","");
352}
353
354#############################################################################
355# simple rewrites
356# vb -> c# style
357#
358# keywords used by doxygen must be rewritten. All other rewrites
359# are optional and depend on the csharpStyledOutput setting.
360#############################################################################
361/^.*Private[[:blank:]]+/ {
362        sub("Private[[:blank:]]+","private ");
363}
364/^.*Public[[:blank:]]+/ {
365        sub("Public[[:blank:]]+","public ");
366}
367# friend is the same as internal in c#, but Doxygen doesn't support internal,
368# so make it private to get it recognized by Doxygen) and Friend appear
369# in Documentation
370/^.*Friend[[:blank:]]+/ {
371        if (csharpStyledOutput==1)
372                sub("Friend[[:blank:]]+","private Friend ");
373        else {
374                print appShift"/// \\remark declared as Friend in the VB original source"
375                sub("Friend[[:blank:]]+","private ");
376        }
377}
378
379/^.*Protected[[:blank:]]+/ {
380        sub("Protected[[:blank:]]+","protected ");
381}
382
383/^.*Shared[[:blank:]]+/ {
384        if (csharpStyledOutput==1)
385                sub("Shared", "static");
386        else
387                sub("Shared", "static Shared");
388}
389# Replace "Partial" by "partial" and swap order of "partial" and "public" or "private"
390/^.*Partial[[:blank:]]+/ {
391        sub("Partial","partial");
392        if($1 == "partial" && $2 ~ /public|private/) {
393                $1 = $2;
394                $2 = "partial";
395        }       
396}
397
398# Const -> const
399/\<Const\>/ {
400        gsub(/\<Const\>/,"const");
401}
402
403# No WithEvents in C# - let's treat it like variables
404/^.*WithEvents[[:blank:]]+/ && (csharpStyledOutput==1) {
405        sub("WithEvents","");
406}
407
408# Overrides -> override
409/[[:blank:]]Overrides[[:blank:]]/ && (csharpStyledOutput==1) {
410        sub("Overrides","override");
411}
412
413# Overridable -> virtual
414/[[:blank:]]Overridable[[:blank:]]/ && (csharpStyledOutput==1) {
415        sub("Overridable","virtual");
416}
417
418# Optional has to be removed for c# style
419/[[:blank:]]Optional[[:blank:]]/ && (csharpStyledOutput==1) {
420        gsub("Optional"," ");
421}
422
423/\<String\>/ && (csharpStyledOutput==1) {
424        gsub(/\<String\>/,"string");
425}
426
427/\<Boolean\>/ && (csharpStyledOutput==1) {
428        gsub(/\<Boolean\>/,"bool");
429}
430
431/\<Char\>/ && (csharpStyledOutput==1) {
432        gsub(/\<Char\>/,"char");
433}
434
435/\<Byte\>/ && (csharpStyledOutput==1) {
436        gsub(/\<Byte\>/,"byte");
437}
438
439/\<Short\>/ && (csharpStyledOutput==1) {
440        gsub(/\<Short\>/,"short");
441}
442
443/\<Integer\>/ && (csharpStyledOutput==1) {
444        gsub(/\<Integer\>/,"int");
445}
446
447/\<Long\>/ && (csharpStyledOutput==1) {
448        gsub(/\<Long\>/,"long");
449}
450
451/\<Single\>/ && (csharpStyledOutput==1) {
452        gsub(/\<Single\>/,"float");
453}
454
455/\<Double\>/ && (csharpStyledOutput==1) {
456        gsub(/\<Double\>/,"double");
457}
458
459/\<Decimal\>/ && (csharpStyledOutput==1) {
460        gsub(/\<Decimal\>/,"decimal");
461}
462
463/\<Date\>/ && (csharpStyledOutput==1) {
464        gsub(/\<Date\>/,"DateTime");
465}
466
467/\<Object\>/ && (csharpStyledOutput==1) {
468        gsub(/\<Object\>/,"object");
469}
470
471/\<Delegate\>/ && (csharpStyledOutput==1) {
472        gsub(/\<Delegate\>/,"delegate");
473}
474
475/\<AddressOf\>/ && (csharpStyledOutput==1) {
476        gsub(/\<AddressOf\>/,"\\&");
477}
478
479#############################################################################
480# Enums
481#############################################################################
482/^Enum[[:blank:]]+/ || /[[:blank:]]+Enum[[:blank:]]+/ {
483        sub("Enum","enum");
484        sub("+*[[:blank:]]As.*",""); # enums shouldn't have type definitions
485        print appShift $0"\n"appShift"{";
486        insideEnum=1;
487        lastEnumLine="";
488        AddShift()
489        next;
490}
491
492/^[ \t]*End[[:blank:]]+Enum/ && insideEnum==1{
493        print appShift lastEnumLine;
494        ReduceShift()
495        print appShift "}"
496        insideEnum=0;
497        lastEnumLine="";
498        enumComment="";
499        next;
500}
501
502insideEnum==1 {
503        if ( lastEnumLine == "" ) {
504                lastEnumLine = $0;
505                if (enumComment!="") print enumComment;
506                enumComment="";
507        } else {
508                commentPart=substr(lastEnumLine,match(lastEnumLine,"[/][*][*]<"));
509                definitionPart=substr(lastEnumLine,0,match(lastEnumLine,"[/][*][*]<")-2);
510                if (definitionPart=="") print appShift commentPart ",";
511                else {
512                        print appShift definitionPart ", " commentPart
513                }
514                lastEnumLine = $0;
515                # print leading comment of next element, if present
516                if (enumComment!="") print enumComment;
517                enumComment="";
518        }
519        next;
520}
521
522#############################################################################
523# Declares
524#############################################################################
525
526/.*Declare[[:blank:]]+/ {
527        libName=gensub(".+Lib[[:blank:]]+\"([^ ]*)\"[[:blank:]].*","\\1","g");
528        if (match($0,"Alias")>0) aliasName=gensub(".+Alias[[:blank:]]+\"([^ ]*)\"[[:blank:]].*"," (Alias: \\1)","g");
529        print appShift "/** Is imported from extern library: " libName aliasName " */";
530        if (csharpStyledOutput==1)
531                sub(/Declare[[:blank:]]+/,"extern ");
532        libName="";
533        aliasName="";
534}
535
536# remove lib and alias from declares
537/.*Lib[[:blank:]]+/ {
538        sub("Lib[[:blank:]]+[^[:blank:]]+","");
539        sub("Alias[[:blank:]]+[^[:blank:]]+","");
540}
541
542
543
544#############################################################################
545# types (handle As and Of)
546#############################################################################
547
548/.*[(]Of[ ][^ ]+[)].*/ {
549        $0=gensub("[(]Of[ ]([^ )]+)[)]", "<\\1>","g",$0);
550}
551
552## converts a single type definition to c#
553##  "Var As Type" -> "Type Var"
554##  "Var As New Type" -> "Type Var = new Type()"
555function convertSimpleType(Param)
556{
557        l=split(Param, aParam, " ")
558        newParam="";
559        for (j = 1; j <= l; j++) {
560                if (aParam[j] == "As") {                       
561                        typeIndex = 1;
562                        if (aParam[j+1] == "New") {
563                                typeIndex = 2;
564                                aParam[j+1] = "";
565                        }
566                        aParam[j]=aParam[j-1];
567                        aParam[j-1]=aParam[j+typeIndex];
568                        aParam[j+typeIndex]="";
569                }
570        }
571        for (j = 1; j <= l; j++) {
572                if (aParam[j]!="") {
573                        if (j == 1) {
574                                newParam=aParam[j];
575                        } else {
576                                newParam=newParam " " aParam[j];
577                        }
578                }
579        }
580        l="";
581        delete aParam;
582        return newParam;
583}
584
585function rindex(string, find) {
586        ns=length(string);
587        nf=length(find);
588        for (r = ns + 1 - nf; r>=1; r--)
589                if (substr(string, r, nf) == find)
590                        return r;
591        return 0;
592}
593
594function findEndArgs(string) {
595        ns=length(string);
596        nf=length(")");
597        for (r = ns + 1 - nf; r>=1; r--) {
598                if ((substr(string, r, nf) == ")") && (substr(string, r - 1, nf) != "(")) {
599                        return r;
600                }
601        }
602        return 0;
603}
604
605#(/.*Function[[:blank:]]+/ ||
606#/.*Sub[[:blank:]]+/ ||
607#/.*Property[[:blank:]]+/ ||
608#/.*Event[[:blank:]]+/ ||
609#/.*Operator[[:blank:]]+/) &&
610/.*As[[:blank:]]+/ {
611        gsub("ByVal","");
612        # keep ByRef to make pointers differ from others
613        # gsub("ByRef","");
614        if (csharpStyledOutput==1)
615                gsub("ByRef","ref");
616       
617        # simple member definition without brackets
618        if (index($0,"(") == 0) {
619                $0=convertSimpleType($0);
620        }
621        else if (match($0, ".*Sub[[:blank:]].+") ||
622            match($0, ".*Function[[:blank:]].+") ||
623            match($0, ".*Property[[:blank:]].+") ||
624            match($0, ".*Event[[:blank:]].+") ||
625            match($0, ".*Operator[[:blank:]].+")) {
626                # parametrized member
627                preParams=substr($0,0,index($0,"(")-1)
628                lpreParams=split(preParams, apreParams , " ")
629               
630                Params=substr($0,index($0,"(")+1,findEndArgs($0)-index($0,"(")-1)
631               
632                lParams=split(Params, aParams, ",")
633                Params="";
634                # loop over params and convert them
635                if (lParams > 0) {
636                        for (i = 1; i <= lParams; i++) {
637                       
638                               
639                                if(match(aParams[i],/.+[(][)].*/)) {
640                                        lParam=split(aParams[i], aParam , " ")
641                                        for (j = 1; j <= lParam; j++) {
642                                                if (aParam[j] == "As") {
643                                                        aParam[j-1]=gensub("[(][)]","","g",aParam[j-1]);
644                                                        aParam[j+1]=gensub("[(][)]","","g",aParam[j+1]);
645                                                        aParam[j+1]=aParam[j+1]"[]";
646                                                }
647                                        }
648                                        for (j = 1; j <= lParam; j++) {
649                                                if (j == 1) {
650                                                        aParams[i]=aParam[j];
651                                                } else {
652                                                        aParams[i]=aParams[i] " " aParam[j];
653                                                }
654                                        }
655                                }
656                       
657                                if (i == 1) {
658                                        Params=convertSimpleType(aParams[i]);
659                                } else {
660                                        Params=Params ", " convertSimpleType(aParams[i]);
661                                }
662                        }
663                        postParams=substr($0,findEndArgs($0)+1)
664                } else {
665                        postParams=substr($0,rindex($0, ")")+1)
666                }
667                #postParams=substr($0,findEndArgs($0)+1)
668                # handle type def of functions and properties
669                lpostParams=split(postParams, apostParams , " ")
670                if (lpostParams > 0) {
671                        if (apostParams[1] == "As") {
672                                ## functions with array as result
673                                if (match(apostParams[2], ".*[(].*[)].*")) {
674                                        apostParams[2]=gensub("[(].*[)]","[]","g",apostParams[2]);
675                                }
676                                ##
677                                apreParams[lpreParams+1]=apreParams[lpreParams];
678                                apreParams[lpreParams]=apostParams[2];
679                                lpreParams++;
680                                apostParams[1]="";
681                                apostParams[2]="";
682                        }                       
683                }
684               
685                # put everything back together
686                $0="";
687                for (i = 1; i <= lpreParams; i++) {
688                        if (apreParams[i]!="")  $0=$0 apreParams[i]" ";
689                }
690
691                $0=$0 "("Params") ";
692                for (i = 1; i <= lpostParams; i++) {
693                        if (apostParams[i]!="") $0=$0 apostParams[i]" ";
694                }
695               
696                # cleanup mem
697                lParams="";
698                delete aParams;
699                lpostParams="";
700                delete apostParams;
701                lpreParams="";
702                delete apreParams;
703        }
704        else {
705                # convert arrays
706                $0=convertSimpleType($0);
707               
708                lLine=split($0, aLine , " ")
709                for (j = 1; j <= lLine; j++) {
710                        if (match(aLine[j], ".*[(].*[)].*")) {
711                                aLine[j]=gensub("[(].*[)]","","g",aLine[j]);
712                                aLine[j-1]=aLine[j-1]"[]";
713                        }
714                }
715                $0 = "";
716                for (j = 1; j <= lLine; j++) {
717                        $0 = $0 aLine[j] " ";
718                }
719        }
720}
721
722#############################################################################
723# Rewrite Subs handling events if csharpStyledOutput=1
724#############################################################################
725
726/.*[[:blank:]]Handles[[:blank:]]+/ && (csharpStyledOutput==1) {
727        name=gensub(/(.*)[[:blank:]]+Handles[[:blank:]]+(\w+)/,"\\2","g",$0);
728        print appShift "/// \\remark Handles the " name " event.";
729        $0=  gensub(/(.*)[[:blank:]]+Handles[[:blank:]]+(.*)/,"\\1","g",$0);
730}
731               
732#############################################################################
733# namespaces
734#############################################################################
735/^Namespace[[:blank:]]+/ || /[[:blank:]]+Namespace[[:blank:]]+/ {
736        sub("Namespace","namespace");
737        insideNamespace=1;
738        print appShift $0" {";
739        AddShift();
740        next;
741}
742
743/^.*End[[:blank:]]+Namespace/ && insideNamespace==1{
744        ReduceShift();
745        print appShift "}";
746        insideNamespace=0;
747        next;
748}
749
750#############################################################################
751# interfaces, classes, structures
752#############################################################################
753/^Interface[[:blank:]]+/ ||
754/.*[[:blank:]]Interface[[:blank:]]+/ ||
755/^Class[[:blank:]]+/ ||
756/.*[[:blank:]]Class[[:blank:]]+/ ||
757/^Structure[[:blank:]]+/ ||
758/.*[[:blank:]]Structure[[:blank:]]+/ ||
759/^Type[[:blank:]]+/ ||
760/(friend|protected|private|public).*[[:blank:]]+Type[[:blank:]]+/ {
761        sub("Interface","interface");
762        sub("Class","class");
763        sub("Structure","struct");
764        sub("Type","struct");
765        if(isInherited) {
766                endOfInheritance();
767        }
768        classNestCounter++;
769       
770        # save class name for constructor handling
771        className[classNestCounter]=gensub(".+class[[:blank:]]+([^ ]*).*","\\1","g");
772        isInherited=1;
773        print appShift $0;
774        next;
775}
776
777# handle constructors
778/.*Sub[[:blank:]]+New.*/ && className[classNestCount]!="" {
779        sub("New", "New " className[classNestCount]);
780}
781
782function endOfInheritance()
783{
784                isInherited=0;
785                if (lastLine!="") print appShift lastLine;
786                print appShift "{";
787                AddShift();
788                lastLine="";
789                return 0;
790}
791
792# handle inheritance
793isInherited==1{
794        if(($0 ~ /^[[:blank:]]*Inherits[[:blank:]]+/) || ($0 ~ /^[[:blank:]]*Implements[[:blank:]]+/)) {
795               
796                if ( lastLine == "" )
797                {
798                        sub("Inherits",":");
799                        sub("Implements",":");
800                        lastLine=$0;
801                }
802                else
803                {
804                        sub(".*Inherits",",");
805                        sub(".*Implements",",");
806                        lastLine=lastLine $0;
807                }
808        }
809        else {
810                endOfInheritance();
811        }
812}
813
814(/.*End[[:blank:]]+Interface/ ||
815 /.*End[[:blank:]]+Class.*/ ||
816 /.*End[[:blank:]]+Structure/ ||
817 /.*End[[:blank:]]+Type/) &&
818 (classNestCounter >= 1){
819        ReduceShift();
820        print appShift "}";
821        delete className[classNestCounter+1];
822        next;
823}
824
825
826#############################################################################
827# Replace Implements with a comment linking to the interface member,
828#   since Doxygen does not recognize members with names that differ
829#   from their corresponding interface members
830#############################################################################
831/.+[[:blank:]]+Implements[[:blank:]]+/ {
832        if ($0 ~ /.*Property[[:blank:]]+.*/) {
833                $0=gensub("(Implements)[[:blank:]]+(.+)$","/** Implements <see cref=\"\\2\"/> */","g",$0);
834        } else {
835                $0=gensub("(Implements)[[:blank:]]+(.+)$","/**< Implements <see cref=\"\\2\"/> */","g",$0);
836        }
837}
838
839#############################################################################
840# Properties
841#############################################################################
842
843/^Property[[:blank:]]+/ ||
844/.*[[:blank:]]+Property[[:blank:]]+/ {
845        sub("[(][)]","");
846
847        if (csharpStyledOutput==1)
848        {
849                # remove Property keyword
850                gsub("^Property[[:blank:]]","")
851                gsub("[[:blank:]]Property[[:blank:]]"," ")
852        }
853       
854        if (match($0,"[(].+[)]")) {
855                $0=gensub("[(]","[","g");
856                $0=gensub("[)]","]","g");
857        } else {
858                $0=gensub("[(][)]","","g");
859        }
860       
861        # add c# styled get/set methods
862        if ((match($0,"ReadOnly")) || (match($0,"Get"))) {
863                if (csharpStyledOutput==1)
864                        sub("ReadOnly[[:blank:]]","");
865                if (instideVB6Property == 1)
866                {
867                        instideVB6Property = 0;
868                        $0=gensub("[[:blank:]]Get|[[:blank:]]Set|[[:blank:]]Let","","g");
869                        print appShift $0 "\n" appShift "{ get; set; }";
870                }
871                else
872                {
873                        $0=gensub(" Get| Set| Let","","g");
874                        print appShift $0 "\n" appShift "{ get; }";
875                }
876        } else {
877                if ((match($0, "Let") || match($0, "Set"))) {
878                        instideVB6Property = 1;
879                        next;
880                }
881                        $0=gensub(" Get| Set| Let","","g");
882                print appShift $0 "\n" appShift "{ get; set; }";
883                next;
884        }
885        instideVB6Property = 0;
886        next;
887}
888
889
890/.*Operator[[:blank:]]+/ {
891        $0=gensub("Operator[[:blank:]]+([^ ]+)[[:blank:]]+","\\1 operator ","g",$0);
892}
893
894#############################################################################
895# process everything else
896#############################################################################
897/.*private[[:blank:]]+/ ||
898/.*public[[:blank:]]+/ ||
899/.*protected[[:blank:]]+/ ||
900/.*friend[[:blank:]]+/ ||
901/.*internal[[:blank:]]+/ ||
902/^Sub[[:blank:]]+/ ||
903/.*[[:blank:]]+Sub[[:blank:]]+/ ||
904/^Function[[:blank:]]+/ ||
905/.*[[:blank:]]+Function[[:blank:]]+/ ||
906/.*declare[[:blank:]]+/ ||
907/^Event[[:blank:]]+/ ||
908/.*[[:blank:]]+Event[[:blank:]]+/ ||
909/.*const[[:blank:]]+/ ||
910/.*[[:blank:]]+const[[:blank:]]+/ {
911               
912        # remove square brackets from reserved names
913        # but do not match array brackets
914        #  "Integer[]" is not replaced
915        #  "[Stop]" is replaced by "Stop"       
916        $0=gensub("([^[])([\\]])","\\1","g");
917        $0=gensub("([[])([^\\]])","\\2","g");
918
919        if (csharpStyledOutput==1)
920        {
921                # subs are functions returning void
922                gsub("[[:blank:]]Sub[[:blank:]]+"," void ");
923                gsub("^Sub[[:blank:]]+","void ");
924                gsub("[[:blank:]]Event[[:blank:]]+"," event ");
925                gsub("^Event[[:blank:]]+","event ");
926        }
927       
928        # add semicolon before inline comment
929        if( $0 != "" ){
930                commentPart=substr($0,index($0,"/"));
931                definitionPart=substr($0,0,index($0,"/")-1);
932                if ( definitionPart != "" && commentPart != "") {
933                        $0 = appShift definitionPart"; "commentPart
934                } else {
935                        $0 = appShift $0";";
936                }
937                # with Declares we can have a superfluous "Function" here.
938                sub("Function","");             
939                print $0
940        }
941}
942
943END{
944        # close file header if file contains no code
945        if (fileHeader!=2 && fileHeader!=0) {
946                print " */";
947        }
948        if (insideVB6Class==1) print ShiftRight "}";
949        if (leadingNamespace==2) print "}";
950}
Note: See TracBrowser for help on using the repository browser.