2 * This file is part of duit.
4 * duit is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; either version 2.1 of the License, or
7 * (at your option) any later version.
9 * duit is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with duit; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 module utils
.DuitClass
;
24 //debug = stringToDuit;
25 //debug = tokenToDuit;
26 //debug = endFunction;
30 //debug = functionType;
31 //debug = declaration;
41 //debug = signalFunction;
47 //version = noGtkBody;
50 * Creates a Duit class
53 public class DuitClass
56 private import std
.ctype
;
57 private import std
.path
;
58 private import std
.stdio
;
60 private import utils
.HtmlStrip
;
61 private import utils
.WrapperIF
;
62 private import utils
.convparms
;
63 private import utils
.funct
;
65 private WrapperIF wrapper
;
67 private char[][] inLines
;
70 private int status
= 0;
71 private int countBlock
= 0;
76 char[] iFaceChar
= "";
78 private char[] parentName
; /// gtk parent struct
79 private char[] duitParentName
; /// duit parent name
80 private char[] duitParentNamePrefix
; /// duit parent name package
82 private char[][] externalDeclarations
; /// the external definition to pass to the wrapper
84 private char[][] collectedAliases
; /// public, module level type aliases
85 private char[][] collectedEnums
; /// public, module level definitions of enums
86 private char[][] stockEnums
; /// special enums for the SotckID
87 private char[][] gTypes
; /// special enums for G_TYPE_*
88 private char[][] stockChars
; /// the char[] value for the stockIDs
89 private char[][] collectedStructs
; /// public, module level definitions of structs
90 private char[][] collectedTypes
; /// public, module level definitions of other types
91 private char[][] collectedFuncts
; /// public, module level definitions of functions
92 private char[][] collectedUnions
; /// public, module level definitions of unions
93 private char[][] collectedConstants
;/// public, module level constants
96 private char[] duitText
;
98 private char[][] properties
;
99 private char[][] styleProperties
;
100 private char[][] signals
;
101 private char[][] description
;
104 int[char[]] functionSignatures
;
105 int[char[]] gtkStructs
;
108 private bit needSignalImports
;
110 private char[] tabs
; /// used for simple indentation
112 public this (WrapperIF wrapper
)
114 this.wrapper
= wrapper
;
117 public char[][] getExternalDeclarations()
119 return externalDeclarations
;
122 public char[][] getAliases()
124 return collectedAliases
;
127 public char[][] getConstants()
129 return collectedConstants
;
132 public char[][] getEnums()
134 return collectedEnums
;
136 public char[][] getStockEnums()
140 public char[][] getStockChars()
145 public char[][] getGTypes()
150 public char[][] getStructs()
152 return collectedStructs
;
155 public char[][] getTypes()
157 return collectedTypes
;
160 public char[][] getFuncts()
162 return collectedFuncts
;
165 public char[][] getUnions()
167 return collectedUnions
;
170 public int getError()
175 private int[char[]] getCleanSigns()
177 int[char[]] cleanSignature
;
178 return cleanSignature
;
181 public void openDuitClass(char[] inAPI
, ConvParms
* convParms
)
184 isInterface
= convParms
.interf
.length
> 0;
185 if ( isInterface
) iFaceChar
= ";";
187 HtmlStrip stripper
= new HtmlStrip();
188 inLines
= std
.string
.splitlines(stripper
.strip(inAPI
));
189 //writefln("new API\n%s",inAPI);
191 functionSignatures
= getCleanSigns();
192 gtkStructs
= getCleanSigns();
194 this.convParms
= convParms
;
196 collectedAliases
.length
= 0;
197 collectedEnums
.length
= 0;
198 stockEnums
.length
= 0;
199 stockChars
.length
= 0;
201 collectedStructs
.length
= 0;
202 collectedUnions
.length
= 0;
203 collectedTypes
.length
= 0;
204 collectedFuncts
.length
= 0;
205 collectedConstants
.length
= 0;
207 needSignalImports
= true;
209 externalDeclarations
~= "";
210 externalDeclarations
~= "// " ~ convParms
.outPack
~ '.' ~ convParms
.clss
;
211 externalDeclarations
~= "";
213 duitText
= wrapper
.getLicense();
215 convParms
.appendAsComment(duitText
);
217 duitText
~= "module "~convParms
.outPack
~".";
218 if ( convParms
.clss
.length
> 0 )
220 duitText
~= convParms
.outFile
;
222 else if ( convParms
.outFile
.length
> 0 )
224 duitText
~= convParms
.outFile
;
228 // moved to class level
229 duitText
~= "private import "~convParms
.outPack
~ "."~convParms
.outPack
~"types;\n\n";
230 duitText
~= "private import lib."~convParms
.outPack
~ ";\n\n";
232 // moved back to class level
233 foreach( char[] imprt
; convParms
.imprts
)
235 duitText
~= "private import "~imprt
~";\n";
238 properties
.length
= 0;
239 styleProperties
.length
= 0;
242 readDuitClass(convParms
);
245 // moved to GdkWrapper.d
246 append(text, collectedAliases, tabs);
247 append(text, collectedEnums, tabs);
248 append(text, collectedStructs, tabs);
249 append(text, collectedTypes, tabs);
250 append(text, collectedFuncts, tabs);
251 append(text, collectedUnions, tabs);
254 if ( wrapper
.includeComments() )
256 append(duitText
, description
, tabs
);
259 // reset the parent name
263 char[][] classHead
= openClass(convParms
);
264 append(duitText
, classHead
, tabs
);
269 private void readDuitClass(ConvParms
* convParms
)
271 description
= getDescription();
272 properties
~= getProperties();
273 styleProperties
~= getStyleProperties();
274 signals
~= getSignals();
276 members
~= getMembers(convParms
);
280 public void mergeDuitClass(char[] inAPI
, ConvParms
* convParms
)
283 HtmlStrip stripper
= new HtmlStrip();
284 inLines
= std
.string
.splitlines(stripper
.strip(inAPI
));
285 //writefln("new API\n%s",inAPI);
287 this.convParms
= convParms
;
289 readDuitClass(convParms
);
291 if ( wrapper
.includeComments() )
293 append(duitText
, description
, tabs
);
298 public char[] closeDuitClass(char[] inAPI
, ConvParms
* convParms
)
300 mergeDuitClass(inAPI
, convParms
);
302 append(duitText
, properties
, tabs
);
303 append(duitText
, styleProperties
, tabs
);
304 append(duitText
, signals
, tabs
);
306 append(duitText
, members
, tabs
);
308 duitText
~= closeClass(convParms
);
314 * Gets the name to the output file
319 public char[] getOutFile(char[] outputRoot
, char[] srcOut
)
321 char[] outF
= std
.path
.join(outputRoot
, srcOut
);
322 outF
= std
.path
.join(outF
, convParms
.outPack
);
323 outF
= std
.path
.join(outF
, (convParms
.clss
.length
>0 ? convParms
.outFile
: convParms
.outFile
));
328 * Appends to the main text with the correct indentation
330 * text = The main text
331 * lines = The lines to append
332 * tabs = The indentation to use
334 public static void append(inout char[] text
, char[][] lines
, inout char[] tabs
)
336 foreach(char[] line
; lines
)
338 char[] ln
= std
.string
.strip(line
);
339 if ( endsWith(ln
, '}')
340 ||
endsWith(ln
, "};")
341 ||
startsWith(ln
, "}")
342 ||
startsWith(ln
, "* }")
343 ||
startsWith(ln
, "// }")
346 if ( tabs
.length
> 0 ) tabs
.length
= tabs
.length
-1;
348 if ( startsWith(ln
, '*') )
350 text
~= tabs
~" "~ ln
~ "\n";
354 text
~= tabs
~ ln
~ "\n";
356 if ( endsWith(ln
,'{') )//&& !startsWith(line, " *") )
364 * Checks if we are a template and if the parent name
369 private char[] getClassHeader(ConvParms
* convParms
, char[] parentName
)
372 if ( convParms
.interf
.length
> 0 )
374 h
= "public interface "~convParms
.interf
;
376 else if ( convParms
.templ
.length
== 0 )
378 h
= "public class "~convParms
.clss
;
382 h
= "public template "~convParms
.clss
~"(";
384 foreach ( int count
, char[] tp
; convParms
.templ
)
394 if ( parentName
.length
> 0 )
396 h
~= " : " ~ parentName
;
402 * Create the class header.
403 * If the class name is empty this is not a class so no header is created
405 * clss = The class Name
408 private char[][] openClass(ConvParms
* convParms
)
411 if ( convParms
.clss
.length
> 0 )
414 if ( duitParentName
.length
> 0
415 && duitParentNamePrefix
.length
> 0
418 text
~= "private import "~duitParentNamePrefix
~"."~duitParentName
~";\n";
420 text
~= getClassHeader(convParms
, duitParentName
)
421 ~ getImplements(convParms
, duitParentName
);
422 // char[] implements = getImplements(convParms, duitParentName);
423 // if ( implements.length > 0 )
425 // text ~= implements;
430 // moved from module level
431 //text ~= "private import "~convParms.outPack ~ "."~convParms.outPack~"types;\n\n";
432 //text ~= "private import lib."~convParms.outPack ~ ";\n\n";
434 // moved to module level - AND BACK AGAIN
435 //foreach( char[] imprt ; convParms.imprts )
437 // text ~= "private import "~imprt~";";
440 char[] flipG(char[] inStr
)
442 char[] flipped
= inStr
.dup
;
444 if ( flipped
[0] == 'G' )
446 flipped
= flipped
[1..flipped
.length
] ~ 'G';
452 if ( convParms
.strct
.length
> 0 )
454 char[] gtkStruct
= convParms
.realStrct
.length
> 0
455 ? convParms
.realStrct
457 char[] var
= toVar(gtkStruct
.dup
);
461 text
~= "/** the main Gtk struct */";
462 text
~= "protected "~gtkStruct
~"* "~var
~";";
466 if ( convParms
.clss
.length
> 0 )
470 if ( convParms
.templ
.length
> 0 )
472 text
~= "public "~gtkStruct
~"* get"~convParms
.clss
~"Struct()"~iFaceChar
;
476 text
~= "return cast("~gtkStruct
~"*)getStruct();";
483 text
~= "public "~gtkStruct
~"* get"~convParms
.clss
~"Struct()"~iFaceChar
;
487 text
~= "return " ~ var
~ ';';
492 text
~= "/** the main Gtk struct as a void* */";
493 text
~= "protected void* getStruct()"~iFaceChar
;
497 text
~= "return cast(void*)" ~ var
~ ';';
501 if ( "GObject" != convParms
.strct
)
503 // GObject has a specific constructor for the struct
507 text
~= " * Sets our main struct and passes it to the parent class";
509 text
~= "public this ("~gtkStruct
~"* "~var
~")"~iFaceChar
;
511 if ( parentName
.length
> 0 )
513 text
~= "super("~castToParent(var
)~");";
515 text
~= "this."~var
~" = "~var
~";";
523 addStaticClassCode(convParms
, text
);
530 * Adds the class code from the conversion parameters.
531 * If current output is a interface the body functions
532 * will be removed (at least we'll try to remove it)
536 private void addStaticClassCode(ConvParms
* convParms
, inout char[][] text
)
540 if ( isInterface
) code
= convParms
.interfaceCode
;
541 else code
= convParms
.classCode
;
543 if ( code
.length
> 0 )
546 foreach ( char[] line
; std
.string
.splitlines(code
))
548 text
~= std
.string
.strip(line
);
553 private char[] castToParent(char[] var
)
555 return "cast("~parentName
~"*)"~var
;
559 * Converts a type to a var.
560 * lower case the first letter
565 public static char[] toVar(char[] type
)
567 if ( type
.length
> 0 )
569 type
[0] = std
.ctype
.tolower(type
[0]);
571 if ( type
.endsWith("_t") )
573 type
= type
[0..type
.length
-2];
579 * Close the class by adding the final brace
580 * If the class name is empty this is not a class so no closing is necessary
582 * clss = The class name
585 private char[] closeClass(ConvParms
* convParms
)
587 if ( tabs
.length
> 0 )
589 tabs
.length
= tabs
.length
-1;
591 return convParms
.clss
.length
>0 ?
"}\n" : "\n";
595 * Read the parent class under "Object Hierarchy" section
596 * or get from the extend on the convParms
601 private char[] getParent()
603 debug(getParent
) writefln("getParent for %s ", convParms
.outFile
);
605 if ( parentName
is null )
607 if ( convParms
.extend
.length
> 0 )
609 parentName
= convParms
.extend
.dup
;
610 duitParentName
= convertClassName(convParms
.extend
, duitParentNamePrefix
);
614 int i
= moveToBlockStart("Object Hierarchy", inLines
);
616 while ( i
< inLines
.length
&& !startsWith(std
.string
.strip(inLines
[i
]), "+----") )
618 debug(getParent
)writefln("\t skip line %s", inLines
[i
]);
623 writefln("getParent 1 ");
624 for ( int j
=i
-3 ;j
<inLines
.length
&& j
<i
+5 ; j
++)
626 writefln("\t getParent line = %s", inLines
[j
]);
628 if ( i
<inLines
.length
) writefln("\t getParent first line = %s", inLines
[i
]);
634 if ( i
< inLines
.length
)
636 next
= std
.string
.strip(inLines
[i
-1]); // many times "GObject"
637 if ( next
!= "GInterface" )
642 char[] gtkStruct
= convParms
.strct
;
643 if ( convParms
.realStrct
.length
> 0 )
645 gtkStruct
= convParms
.realStrct
;
647 while ( i
< inLines
.length
648 && startsWith(std
.string
.strip(inLines
[i
]), "+----")
649 && current
!= gtkStruct
653 next
= inLines
[i
][6..inLines
[i
].length
];
654 if ( "GInitiallyUnowned" != next
)
657 debug(getParent
) writefln("\t current = %s", current
);
661 if ( gtkStruct
== current
&& parent
.length
>0 )
663 parentName
= parent
.dup
;
664 duitParentName
= convertClassName(parentName
, duitParentNamePrefix
);
671 private char[] convertClassName(char[] gName
, inout char[] prefix
)
674 if ( startsWith(gName
, "Gtk") ) prefix
= "Gtk";
675 else if ( startsWith(gName
, "Gdk") ) prefix
= "Gdk";
676 else if ( startsWith(gName
, "Atk") ) prefix
= "Atk";
677 else if ( startsWith(gName
, "G") ) prefix
= "G";
679 conv
= gName
[prefix
.length
..gName
.length
];
680 if ( conv
== "Object" )
684 debug(getParent
)writefln("convertClassName %s >>> %s", gName
, conv
);
685 prefix
= std
.string
.tolower(prefix
);
694 * Under "Implemented Interfaces" section
699 private char[] getImplements(ConvParms
* convParms
, char[] parentName
)
702 foreach ( int count
, char[] impl
; convParms
.impl
)
704 if ( count
> 0 || parentName
.length
> 0)
708 else if ( count
== 0 || parentName
.length
== 0)
710 impls
~= "/+implements+/ ";
717 private char[][] getProperties()
724 private char[][] getStyleProperties()
736 private char[][] getSignals()
739 debug(getSignal
) writefln("\tgetSignals");
741 int i
= moveToBlockStart("Signal Details", inLines
);
743 debug(getSignal
)if(i
<inLines
.length
)writefln("\t %s", inLines
[i
]);
745 while ( i
<inLines
.length
&& startsWith(inLines
[i
], "The \"") )
747 text
~= getSignal(i
, inLines
);
748 while ( i
<inLines
.length
&& !startsWith(inLines
[i
], "The \"") )
750 debug(getSignal
) writefln("\tgoto next\t%s", inLines
[i
]);
758 private char[][] getSignal(inout int i
, char[][] lines
)
760 debug(getSignal
) writefln("\tgetSignal %s", lines
[i
]);
762 int endPos
= std
.string
.rfind(lines
[i
], '"');
765 char[] signalName
= lines
[i
][5..endPos
];
768 char[] funct
= getSignalFunctionDeclaration(i
, lines
);
770 if ( wrapper
.includeComments
)
773 while ( i
<lines
.length
&& lines
[i
] != "<hr>" )
775 debug(getSignal
) writefln("\t\t%s", lines
[i
]);
776 comments
~= " * "~lines
[i
];
783 fun
.init(funct
, convParms
);
785 char[] duitSignal
= signalNameToDuit(signalName
);
786 char[] delegateDeclaration
= fun
.getDelegateDeclaration(convParms
, 1);
788 addSignalImports(text
);
789 text
~= delegateDeclaration
~ "[] on" ~ duitSignal
~"Listeners;" ;
790 addAddListener(text
, signalName
, duitSignal
, delegateDeclaration
);
791 addExternCallback(text
, fun
, duitSignal
, delegateDeclaration
);
797 void addExternCallback(inout char[][] text
, Funct fun
, char[] duitSignal
, char[] dlg
)
801 text
~= "extern(C) static void callBack"~duitSignal
~"("
802 ~fun
.getCallbackParameters(0, convParms
, wrapper
.getAliases())
805 text
~= " bit consumed = false;";
807 text
~= " foreach ( "~dlg
~" dlg ; "~getClassVar(convParms
)~".on"~duitSignal
~"Listeners )";
809 char[] dlgCall
= "dlg("~fun
.getCallbackVars(convParms
, wrapper
.getAliases())~");";
810 //if ( dlgCall == "dlg(widget, container);" )
813 // dlgCall = "dlg(new Widget(widget), container);";
818 text
~= " return consumed;";
824 void addAddListener(inout char[][] text
, char[] signalName
, char[] duitSignalName
, char[] dlg
)
826 text
~= "void addOn"~duitSignalName
~"("~dlg
~" dlg)"~iFaceChar
;
830 text
~= "if ( !(\""~signalName
~"\" in connectedSignals) )";
833 // TODO move this to the config files or read it from the Gtk docs (how?)
834 switch ( signalName
)
836 case "button-press-event": text
~= "addEvents(EventMask.BUTTON_PRESS_MASK);"; break;
837 case "button-release-event": text
~= "addEvents(EventMask.BUTTON_RELEASE_MASK);"; break;
838 case "motion-notify-event": text
~= "addEvents(EventMask.POINTER_MOTION_MASK);"; break;
843 text
~= " Signals.connectData(";
844 text
~= " getStruct(), ";
845 text
~= " \""~signalName
~"\", ";
846 text
~= " cast(GCallback)&callBack"~duitSignalName
~", ";
849 //text ~= " ConnectFlags.AFTER);";
850 text
~= " cast(ConnectFlags)0);";
852 text
~= " connectedSignals[\""~signalName
~"\"] = 1;";
854 text
~= "on"~duitSignalName
~"Listeners ~= dlg;";
860 public static char[] getClassVar(ConvParms
* convParms
)
864 if ( convParms
.clss
.length
> 0 )
866 cv
= convParms
.clss
.dup
;
867 cv
[0] = std
.ctype
.tolower(cv
[0]);
873 private char[] signalNameToDuit(char[] signalName
)
878 foreach ( int count
, char c
; signalName
)
882 signalDuit
~= std
.ctype
.toupper(c
);
886 if ( c
!='-' && c
!='_' )
888 if ( pc
=='-' || pc
=='_' )
890 signalDuit
~= std
.ctype
.toupper(c
);
901 //writefln("signalDuit = %s", signalDuit);
903 if ( "MapEvent" != signalDuit
904 && "UnmapEvent" != signalDuit
905 && endsWith(signalDuit
, "Event") )
907 signalDuit
= signalDuit
[0..signalDuit
.length
-5];
915 * "private import gobject.Signals;"
916 * "private import gdk.gdktypes;"
920 void addSignalImports(inout char[][] text
)
922 if ( needSignalImports
)
925 text
~= "// imports for the signal processing";
926 text
~= "private import gobject.Signals;";
927 text
~= "private import gdk.gdktypes;";
930 text
~= "int[char[]] connectedSignals;";
934 needSignalImports
= false;
939 private char[] getSignalFunctionDeclaration(inout int line
, char[][] lines
)
941 debug(signalFunction
)writefln("getSignalFunctionDeclaration");
943 while ( line
<lines
.length
944 && std
.string
.find(lines
[line
], ":")<0
947 funct
~= lines
[line
]~ " ";
948 debug(endFunction
)writefln("funct line = >>>%s<<< endWith(\");\") = ",
950 endsWith(lines
[line
], ");")
954 if ( line
<lines
.length
&& std
.string
.find(lines
[line
], ":")>0 )
956 funct
~= lines
[line
++];
963 private char[][] getMembers(ConvParms
* convParms
)
970 while ( currLine
< inLines
.length
)
972 text
~= getMember(convParms
.prefixes
);
978 private char[][] getMember(char[][] prefixes
)
980 char[][] lines
= convParms
.text
.dup
;
981 convParms
.text
.length
= 0;
982 lines
~= getUntil("<hr>");
986 // writefln("lines[1] = %s", lines[1]);
987 //}else debug(enums){
988 // writefln("lines[1] = %s", lines[1]);
994 writefln("getMember:");
995 foreach (char[] line
; lines
)
997 writefln("\t%s", line
);
1000 if ( lines
.length
< 2 )
1007 if ( endsWith(lines
[0],"()") )
1009 member
~= getFunction(lines
, prefixes
);
1011 else if ( startsWith(lines
[1], "typedef enum") )
1013 if ( !convParms
.strictPrefix
1017 collectEnums(lines
, convParms
);
1020 else if ( startsWith(lines
[1], "typedef struct")
1021 ||
startsWith(lines
[1], "struct")
1024 if ( !convParms
.strictPrefix
1028 collectStructs(lines
, convParms
);
1031 else if ( startsWith(lines
[0], "union") )
1033 if ( !convParms
.strictPrefix
1037 collectUnions(lines
, convParms
);
1040 else if ( startsWith(lines
[1], "typedef") )
1042 if ( !convParms
.strictPrefix
1046 collectAliases(lines
, convParms
);
1049 else if ( startsWith(lines
[0], "GTK_STOCK_") )
1053 collectStockItems(lines
, convParms
);
1056 else if ( startsWith(lines
[0], "G_TYPE_")
1057 && convParms
.outFile
== "Type"
1062 collectGTypes(lines
, convParms
);
1070 private void collectGTypes(char[][] lines
, ConvParms
* convParms
)
1072 debug(gTypes
)writefln("gype lines\n\t%s\n\t%s\n\t%s",lines
[0],lines
[1],lines
[2]);
1074 if ( lines
.length
> 0
1075 && std
.string
.find(lines
[defLine
],"G_TYPE_MAKE_FUNDAMENTAL")>=0
1076 && endsWith(lines
[defLine
],")")
1077 && std
.string
.find(lines
[defLine
],"<<") < 0
1080 int pos
= std
.string
.find(lines
[defLine
], "(");
1083 int posf
= std
.string
.find(lines
[defLine
], ")");
1086 gTypes
~= lines
[0][7..lines
[0].length
]
1087 ~ " = "~lines
[defLine
][pos
+1..posf
]~"<<2"
1094 // we expect all stock constants to be defined in one file
1098 private void collectStockItems(char[][] lines
, ConvParms
* convParms
)
1100 debug(stockItems
)writefln("stock items lines\n\t%s\n\t%s\n\t%s",lines
[0],lines
[1],lines
[2]);
1102 if ( lines
.length
> 0 && startsWith(lines
[defLine
],"#define GTK_") )
1104 char[] line
= lines
[defLine
];
1108 int pos
= std
.string
.find(line
[12..line
.length
],' ')+12;
1109 debug(stockItems
)writefln("pos=%s", pos
);
1112 stockID
= line
[12..pos
];
1113 if ( startsWith(stockID
, "STOCK_") )
1115 stockID
= stockID
[6..stockID
.length
];
1117 debug(stockItems
)writefln("\t\tstockID = %s", stockID
);
1118 if ( stockID
.length
>0 )
1120 stockValue
= std
.string
.strip(line
[pos
+1..line
.length
]);
1121 debug(stockItems
)writefln("\t\tstockValue = %s", stockValue
);
1122 if ( stockValue
.length
>2
1123 && stockValue
[0] == '"'
1124 && endsWith(stockValue
, '"')
1129 stockEnums
~= "/**";
1130 while ( ln
< lines
.length
&& lines
[ln
][0] > ' ' )
1132 stockEnums
~= " * "~lines
[ln
++].dup
;
1134 stockEnums
~= " */";
1135 stockEnums
~= stockID
~",";
1136 stockChars
~= "\""~stockValue
[1..stockValue
.length
-1]~"\",";
1137 //collectedConstants ~=
1138 // "const StockID "~stockID
1139 // ~" = cast(StockID)\""~stockValue[1..stockValue.length-1]~"\";";
1148 private void collectAliases(char[][] lines
, ConvParms
* convParms
)
1151 char[][] tokens
= std
.string
.split(until(pos
, lines
[1], ';'));
1153 char[] alis
= "public alias " ~ tokens
[1] ~ ' ' ~ tokens
[2] ~ ';';
1155 collectedAliases
~= "";
1156 collectedAliases
~= "/**";
1158 while ( ln
< lines
.length
&& lines
[ln
][0] > ' ' )
1160 collectedAliases
~= " * "~lines
[ln
++].dup
;
1162 collectedAliases
~= " */";
1163 collectedAliases
~= stringToDuit(alis
, convParms
, wrapper
.getAliases());
1167 private char[] getEnumPrefix(char[] enumName
, char[] enumEntry
)
1169 debug(enumPrefix
)writefln("%s.%s", enumName
, enumEntry
);
1171 char[] upper
= std
.string
.toupper(enumName
.dup
);
1177 bool v
= (n
>=upper
.length
) ||
(e
>=enumEntry
.length
);
1178 debug(enumPrefix
) if (v
) writefln("\t ended by endfStrings");
1184 bool v
= enumEntry
[e
] == '_';
1190 bool v
= upper
[n
] == enumEntry
[e
];
1191 debug(enumPrefix
) if (!v
) writefln("\t ended by sameChar");
1197 bool v
= upper
.length
-n
== 4
1198 && ( upper
[n
..n
+4]=="TYPE"
1199 || upper
[n
..n
+4]=="FLAG"
1200 || upper
[n
..n
+4]=="MODE"
1202 debug(enumPrefix
) if (v
) writefln("\t ended by isSuffix");
1206 while ( !endOfStrings()
1209 ( sameChar() && !isSuffix() )
1213 if ( upper
[n
] == enumEntry
[e
] )
1225 if ( e
< enumEntry
.length
)
1227 while ( e
>0 && enumEntry
[e
]!= '_' )
1234 if ( e
<enumEntry
.length
&& enumEntry
[e
] == '_' )
1239 prefix
= enumEntry
[0..e
];
1240 debug(enumPrefix
) writefln("\t%s", prefix
);
1244 private void collectEnums(char[][] lines
, ConvParms
* convParms
)
1246 char[] enumName
= lines
[0][5..lines
[0].length
];
1247 char[] duitEnumName
;
1249 bool isGdkPrefix(char[] name
)
1252 startsWith(enumName
, "Gdk")
1257 if ( startsWith(enumName
, "Gtk")
1258 ||
isGdkPrefix(enumName
)
1261 duitEnumName
= enumName
[3..enumName
.length
];
1262 if ( duitEnumName
== "Function" ) duitEnumName
= "Funct";
1264 else if ( startsWith(enumName
, "G") )
1266 duitEnumName
= enumName
[1..enumName
.length
];
1268 //char[] enumName = removeUnderscore(lines[0][5..lines[0].length]);
1269 debug(enums
)writefln("enum %s", enumName
);
1271 // skipp until the start of the enumerations
1273 while ( pos
<lines
.length
1274 && !endsWith(std
.string
.strip(lines
[pos
]),'{')
1275 && !startsWith(std
.string
.strip(lines
[pos
]),'{')
1276 && !startsWith(lines
[pos
], "typedef enum {")
1279 debug(enums
)writefln("\tskipp line: %s", lines
[pos
]);
1283 bit invalidDEnum
= false;
1284 if ( pos
<lines
.length
&& lines
[pos
][0] != '}' )
1286 char[] enumPrefix
= getEnumPrefix(enumName
, std
.string
.strip(lines
[pos
].dup
));
1287 int prefixLength
= enumPrefix
.length
;
1288 while ( pos
<lines
.length
&& lines
[pos
][0] != '}' )
1290 debug(enums
)writefln("\tenum line %s", lines
[pos
]);
1292 char[] value
= std
.string
.strip(lines
[pos
++].dup
);
1293 debug(enums
)writefln("\traw %s", value
);
1294 value
= enumToDuit(enumName
, value
, convParms
, wrapper
);
1295 debug(enums
)writefln("\tprocessed %s", value
);
1297 //if ( std.string.find(value, ":") >= 0 )
1299 // invalidDEnum = true;
1300 // debug(structs)writefln("- INVALID >>>%s<<<", value);
1303 if ( startsWith(value
, '#') )
1306 debug(enums
)writefln("= IGNORED >>>%s<<<", value
);
1312 char[] replace(char[] s
, char[] from
, char[] to
)
1315 if ( from
.length
== 0 )
1325 while (istart
< s
.length
)
1327 i
= std
.string
.find(s
[istart
.. s
.length
], from
);
1330 p
~= s
[istart
.. s
.length
];
1333 p
~= s
[istart
.. istart
+ i
];
1335 istart
+= i
+ from
.length
;
1342 debug(enumPrefix
)writefln("\t\t%s", value
);
1343 char[] v
= replace(value
, enumPrefix
, "");
1348 case "2BI": v
= "TOO_"~v
[1..v
.length
]; break;
1349 case "2BU": v
= "DOUBLE_"~v
[1..v
.length
]; break;
1350 case "3BU": v
= "TRIPPLE_"~v
[1..v
.length
]; break;
1359 //debug(enumPrefix)writefln("-> %s", value[prefixLength..value.length]);
1360 // if ( startsWith(value, enumPrefix) )
1362 // values ~= value[prefixLength..value.length];
1367 // debug(enumPrefix)writefln();
1369 debug(enums
)writefln("+ ADDED >>>%s<<<", v
);
1374 if ( pos
< lines
.length
)
1376 collectedEnums
~= "/**";
1377 while ( pos
< lines
.length
&& lines
[pos
][0] > ' ' )
1379 collectedEnums
~= " * "~lines
[pos
++].dup
;
1381 collectedEnums
~= " */";
1385 collectedEnums
~= "// TODO ";
1386 collectedEnums
~= "// public enum "~enumName
;
1390 collectedEnums
~= "public enum "~enumName
;
1392 collectedEnums
~= "{";
1393 foreach ( char[] value
; values
)
1395 debug(enums
)writefln("\t\t%s", value
);
1396 collectedEnums
~= stringToDuit(value
, convParms
, wrapper
.getAliases());
1398 collectedEnums
~= "}";
1399 if ( duitEnumName
.length
> 0
1400 && !startsWith(duitEnumName
, "Gdk")
1403 collectedEnums
~= "alias "~enumName
~" "~duitEnumName
~ ";";
1404 collectedEnums
~= "";
1410 private void collectUnions(char[][] lines
, ConvParms
* convParms
)
1412 char[] unionName
= lines
[0][6..lines
[0].length
];
1413 if ( unionName
== "cairo_path_data_t" )
1415 collectedUnions
~= "";
1416 collectedUnions
~= "// skipped union "~unionName
;
1417 collectedUnions
~= "";
1420 debug(unions
)writefln("union %s", unionName
);
1423 while ( pos
<lines
.length
&& lines
[pos
][0] != '}' )
1425 debug(unions
)writefln("\tunion line %s", lines
[pos
]);
1426 char[] value
= std
.string
.strip(lines
[pos
++].dup
);
1427 debug(unions
)writefln("\traw %s", value
);
1428 value
= stringToDuit(value
, convParms
, wrapper
.getAliases());
1429 debug(unions
)writefln("\tprocessed %s", value
);
1433 if ( pos
< lines
.length
)
1435 collectedUnions
~= "/**";
1436 while ( pos
< lines
.length
&& lines
[pos
][0] > ' ' )
1438 collectedUnions
~= " * "~lines
[pos
++].dup
;
1440 collectedUnions
~= " */";
1442 collectedUnions
~= "public struct "~unionName
;
1443 collectedUnions
~= "{";
1444 collectedUnions
~= "union";
1445 collectedUnions
~= "{";
1446 foreach ( char[] value
; values
)
1448 debug(unions
)writefln("\t\t%s", value
);
1449 collectedUnions
~= value
;
1451 collectedUnions
~= "}";
1452 collectedUnions
~= "}";
1455 private void collectStructs(char[][] lines
, ConvParms
* convParms
)
1457 char[] structName
= lines
[0].dup
;
1458 if ( startsWith(structName
, "struct ") )
1460 structName
= structName
[7..structName
.length
];
1462 debug(structs
)writefln("found typdef struct = %s", structName
);
1463 bit includeStruct
= true;
1465 while ( includeStruct
&& nStructs
< convParms
.noStructs
.length
)
1467 includeStruct
= ! (structName
== convParms
.noStructs
[nStructs
++]);
1469 if ( includeStruct
)
1471 char[][] structDef
; /// all elements of the struct
1472 bit invalidDStruct
= false;
1474 if ( lines
[1][lines
[1].length
-1] == '{' )
1477 while ( pos
< lines
.length
&& lines
[pos
][0] != '}' )
1479 //invalidDStruct = true;
1480 structDef
~= lines
[pos
].dup
;
1481 //if ( std.string.find(lines[pos], ":") >= 0 )
1483 // invalidDStruct = true;
1484 // debug(structs)writefln("- INVALID >>>%s<<<", lines[pos]);
1487 if ( std
.string
.find(lines
[pos
], "[") >= 0 )
1489 invalidDStruct
= true;
1490 debug(structs
)writefln("- INVALID ([)>>>%s<<<", lines
[pos
]);
1492 else if ( std
.string
.find(lines
[pos
], "{") >= 0 )
1494 invalidDStruct
= true;
1495 debug(structs
)writefln("- INVALID ({)>>>%s<<<", lines
[pos
]);
1497 else if ( startsWith(std
.string
.strip(lines
[pos
]), '#') )
1500 debug(structs
)writefln("= IGNORED >>>%s<<<", lines
[pos
]);
1502 else if ( !primitiveType(lines
[pos
]) )
1504 switch ( structName
)
1517 if ( std
.string
.find(structName
, "Event")>=0 )
1519 // try build a D struct
1523 invalidDStruct
= true;
1524 debug(structs
)writefln("- INVALID (not primitive) >>>%s<<<", lines
[pos
]);
1531 debug(structs
)writefln("+ ADDED >>>%s<<<", lines
[pos
]);
1537 if ( pos
< lines
.length
)
1539 collectedStructs
~= "";
1540 char[] line
= lines
[pos
];
1542 char[] gtkStruct
= convParms
.realStrct
.length
> 0
1543 ? convParms
.realStrct
1546 if ( pos
< lines
.length
&& lines
[pos
][0] > ' ' )
1548 collectedStructs
~= "/**";
1549 if ( structName
== gtkStruct
)
1551 collectedStructs
~= " * Main Gtk struct.";
1553 while ( pos
< lines
.length
&& lines
[pos
][0] > ' ' )
1555 collectedStructs
~= " * "~lines
[pos
++].dup
;
1557 collectedStructs
~= " */";
1559 else if ( structName
== gtkStruct
)
1561 collectedStructs
~= "/**";
1562 collectedStructs
~= " * Main Gtk struct.";
1563 collectedStructs
~= " */";
1566 if ( (!invalidDStruct
1567 ||
"GValue"==structName
1568 ||
"GError"==structName
1570 && structDef
.length
>0 )
1572 collectedStructs
~= "public struct "~structName
~"\n{";
1574 bool bitField
= false; // if we are in a bit field
1576 foreach ( char[] def
; structDef
)
1578 char[] elem
= stringToDuit(def
, convParms
, wrapper
.getAliases());
1579 if ( std
.string
.find(def
, ":") >= 0 )
1584 // just assume uint for now
1585 // TODO get the type
1586 collectedStructs
~= "\tuint bitfield;";
1587 collectedStructs
~= "//" ~ elem
;
1593 collectedStructs
~= elem
;
1596 collectedStructs
~= "\n}";
1597 // char[] duitStructName;
1598 // if ( startsWith(structName, "Gtk")
1599 // || startsWith(structName, "Gdk")
1602 // duitStructName = structName[3..structName.length];
1604 // else if ( startsWith(structName, "G") )
1606 // duitStructName = structName[1..structName.length];
1608 // if ( duitStructName.length > 0
1609 // && "Color"!=duitStructName
1610 // && "Rectangle"!=duitStructName
1611 // && "Bitmap"!=duitStructName
1614 // collectedStructs ~= "\nalias "~structName~" "~duitStructName~";\n";
1617 else //if ( structDef.length > 0 )
1619 switch ( structName
)
1621 // TODO "public struct GdkEventClient;" comfuses DMD!!!???
1622 case "GdkEventClient":
1623 collectedStructs
~= "public struct "~structName
~"{}";
1627 collectedStructs
~= "public struct "~structName
~"{}";
1630 foreach ( char[] def
; structDef
)
1632 collectedStructs
~= "// "~stringToDuit(def
, convParms
, wrapper
.getAliases());
1633 collectedStructs
~= "// "~convParms
.inFile
;
1636 collectedStructs
~= "";
1640 bit
primitiveType(char[] line
)
1644 char[] type
= untilBlank(p
, line
);
1645 return (type
in wrapper
.getAliases()) !is null;
1648 public static void skipBlank(inout int p
, char[] text
)
1650 while( p
<text
.length
&& text
[p
]<=' ' )
1656 public static void skip(inout int p
, char[] text
, char s
)
1658 while( p
<text
.length
&& text
[p
]==s
)
1664 public static char[] untilBlank(inout int p
, char[] text
)
1667 while ( p
<text
.length
&& text
[p
]>' ')
1671 return text
[start
..p
];
1674 public static char[] untilBlank(inout int p
, char[] text
, char[] s
)
1677 while ( p
<text
.length
&& text
[p
]>' ' && std
.string
.find(s
,text
[p
])<0 )
1681 return text
[start
..p
];
1684 public static char[] until(inout int p
, char[] text
, char s
)
1687 while ( p
<text
.length
&& text
[p
]!=s
)
1691 return text
[start
..p
];
1694 public static char[] until(inout int p
, char[] text
, char[] s
)
1697 while ( p
<text
.length
&& std
.string
.find(s
,text
[p
])<0 )
1701 return text
[start
..p
];
1704 private char[] getFunctionDeclaration(inout int line
, char[][] lines
)
1707 while ( line
<lines
.length
1708 && (!endsWith(lines
[line
], ");")
1709 && !startsWith(funct
, "#define"))
1712 funct
~= lines
[line
]~ " ";
1713 debug(endFunction
)writefln("funct line = >>>%s<<< endWith(\");\") = ",
1715 endsWith(lines
[line
], ");")
1719 if ( line
<lines
.length
&& endsWith(lines
[line
], ");") )
1721 funct
~= lines
[line
++];
1727 private char[][] getFunction(char[][] lines
, char[][] prefixes
)
1733 char[] funct
= getFunctionDeclaration(line
, lines
);
1736 fun
.init(funct
, convParms
);
1740 * Checks restrictions on the functions to include
1746 bit
includeFunction(ConvParms
* convParms
)
1751 while ( inc && nPrefix
<convParms
.noPrefixes
.length
)
1753 debug(noPrefixes
)writefln("\ttest noPrefix %s ?= %s", fun
.name
, convParms
.noPrefixes
[nPrefix
]);
1754 inc = !startsWith(fun
.name
, convParms
.noPrefixes
[nPrefix
++]);
1760 if ( convParms
.containsPrefix(fun
.name
) )
1762 debug(noPrefixes
)writefln("included by name");
1765 else if ( convParms
.strictPrefix
&& convParms
.prefixes
.length
>0 )
1767 debug(noPrefixes
) writefln("dropped by strictPrefix");
1773 debug(noPrefixes
)if ( !inc) writefln("dropped by noPrefixes");
1776 //debug(noPrefixes)writefln("%s : %s (%s)", (inc?"included":"dropped"),fun.name, convParms.prefix);
1780 if ( includeFunction(convParms
) )
1782 if ( funct
[0] == '#' )
1784 if ( !convParms
.strictPrefix
)
1786 collectedTypes
~= "";
1787 debug(defines
)writefln("it's define: %s",funct
);
1789 if ( wrapper
.includeComments() )
1791 collectedTypes
~= "/*";
1792 while ( line
<lines
.length
)
1794 collectedTypes
~= " * "~lines
[line
++];
1796 collectedTypes
~= " */";
1798 collectedTypes
~= "// TODO";
1800 collectedTypes
~= "// "~funct
;
1806 debug(functName
) writefln("funct name = %s", fun
.name
);
1807 if ( fun
.name
.length
==0 || fun
.name
[0] == '(' )
1811 if ( !convParms
.strictPrefix
)
1813 collectedFuncts
~= "";
1815 if ( wrapper
.includeComments() )
1817 collectedFuncts
~= "/*";
1818 while ( line
<lines
.length
)
1820 collectedFuncts
~= " * "~lines
[line
++];
1822 collectedFuncts
~= " */";
1823 collectedFuncts
~= "// "~funct
;
1826 collectedFuncts
~= getFunction(funct
, convParms
);
1830 else // the regular function
1832 bit tooSoon
= false; // reject for 2.10
1836 if ( wrapper
.includeComments() )
1839 while ( line
<lines
.length
)
1843 // tooSoon = lines[line]=="Since 2.10";
1845 member
~= " * "~lines
[line
++];
1854 member
~= "// next release";
1860 externalDeclarations
~= fun
.getExternal(convParms
, wrapper
.getAliases());
1863 if ( !convParms
.omitCode(fun
.name
) )
1865 char[] rawDeclaration
= fun
.declaration(convParms
,wrapper
.getAliases());
1866 char[] duitDeclaration
= stringToDuit(rawDeclaration
,convParms
,wrapper
.getAliases());
1867 debug(declaration
) writefln("Declaration\n\t%s\n\t%s",rawDeclaration
, duitDeclaration
);
1869 member
~= duitDeclaration
~iFaceChar
;
1873 member
~= "// "~funct
;
1874 version( noGtkBody
)
1876 // switch ( fun.typeWrap )
1878 // case "void": break;
1879 // case "int", "uint", "bit", "long", "ulong"
1880 // member ~= "return 0;";
1883 // case "int", "uint", "bit", "long", "ulong"
1884 // member ~= "return 0;";
1887 // case "char[]": member ~= "return "";"; break;
1888 // default: member ~= "return null;"; break;
1893 member
~= fun
.bod(convParms
, wrapper
.getAliases());
1897 checkIfDupFunction(fun
);
1898 checkIfGtkStructs(fun
);
1908 private void checkIfDupFunction(Funct fun
)
1910 char[] signature
= fun
.convName
~'('~fun
.getWrapParametersType()~')';
1911 if ( signature
in functionSignatures
)
1913 writefln("######################## duplicated function %s", signature
);
1917 functionSignatures
[signature
] = 1;
1923 * Prints out the potential Gtk struct to be wrapped
1924 * so that the wrap parameter can be set on the APILookupXXX.txt
1925 * TODO assume all structs are to be wrapped an explicitly declare the ones not to be wrapped
1929 private void checkIfGtkStructs(Funct fun
)
1932 void check(char[] type
)
1934 if ( startsWith(type
, 'G')
1935 && endsWith(type
, '*')
1938 if ( type
in gtkStructs
)
1945 gtkStructs
[type
] = 1;
1946 //writefln("######################## Gtk struct found %s\t\t%s",
1948 // fun.convName~"("~fun.getWrapParametersType()~")"
1951 char[] strct
= type
.dup
;
1954 if ( startsWith(strct
, "Gtk") )
1957 dName
= strct
[3..strct
.length
-1];
1958 //dName[0] = std.ctype.tolower(dName[0]);
1960 else if ( startsWith(strct
, "Gdk") )
1963 dName
= strct
[3..strct
.length
-1];
1964 //dName[0] = std.ctype.tolower(dName[0]);
1965 if ( dName
== "Pixbuf") pack
= "gdkpixbuf";
1967 else if ( startsWith(strct
, "G") )
1969 dName
= strct
[1..strct
.length
-1];
1976 pack
= "gobject"; dName
= "ObjectG";
1978 else if ( pack
== "gdk" )
1982 else if ( pack
== "gtk" )
1984 dName
= "ObjectGtk";
1986 else if ( pack
== "atk" )
1988 dName
= "ObjectAtk";
1991 case "Closure": pack
= "gobject"; break;
1992 case "Type": pack
= "gobject"; break;
1993 case "Value": pack
= "gobject"; break;
1994 case "List": pack
= "glib"; dName
= "ListG"; break;
1995 case "SList": pack
= "glib"; dName
= "ListSG"; break;
1996 case "String": pack
= "glib"; dName
= "StringG"; break;
1997 case "IOChannel": pack
= "glib"; break;
1998 case "Quark": pack
= "glib"; break;
1999 case "ParmSpec": pack
= "gobject"; break;
2000 case "TypeModule": pack
= "gobject"; break;
2001 case "Flags": pack
= "gobject"; break;
2002 case "Enums": pack
= "gobject"; break;
2008 debug(structs
)writefln("import: %s.%s", pack
, dName
);
2009 debug(structs
)writefln("structWrap: %s %s", strct
, dName
);
2015 && !endsWith(fun
.convName
, "Struct")
2018 check(fun
.typeWrap
);
2020 foreach ( int count
, char[] parm
; fun
.parmsWrap
)
2022 if ( count
> 0 || parm
!= convParms
.strct
~'*' )
2031 * line = The API line of the function
2032 * convParms = the Conversion parameters
2035 private char[] getFunction(char[] line
, ConvParms
* convParms
)
2037 debug(functionType
) writefln("\ngetFunction line = %s", line
);
2038 // void (*GChildWatchFunc) (GPid pid, gint status, gpointer data);
2039 // public typedef extern(C) void function(int, int, void*) GChildWatchFunc;
2040 char[] f
= "public typedef extern(C) ";
2042 char[] type
= until(pos
, line
, "(");
2043 until(pos
, line
, "*");
2044 skip(pos
, line
, '*');
2045 char[] name
= until(pos
, line
, ")");
2047 //adjustTypeName(type, name);
2049 f
~= stringToDuit(type
, convParms
, wrapper
.getAliases());
2052 until(pos
, line
, "(");
2053 skip(pos
, line
, '(');
2054 skipBlank(pos
, line
);
2056 char[] sourceParms
= std
.string
.strip(until(pos
, line
, ")"));
2059 if ( sourceParms
!= "void" )
2063 debug(functionType
) writefln("sourceParms = %s", sourceParms
);
2064 while ( sPos
< sourceParms
.length
)
2066 skipBlank(sPos
, sourceParms
);
2067 debug(functionType
)writefln("parms sPos=%s [%s]",sPos
, sourceParms
[sPos
..sourceParms
.length
]);
2072 char[] pType
= untilBlank(sPos
, sourceParms
);
2073 fixType(pType
, sPos
, sourceParms
);
2075 char[] pName
= until(sPos
, sourceParms
, ",)");
2077 debug(parmType
)writefln("\tParameter type before = %s", pType
);
2078 debug(parmName
)writefln("\tParameter name before = %s", pName
);
2079 adjustTypeName(pType
, pName
);
2080 debug(parmType
)writefln("\tParameter type after = %s", pType
);
2081 debug(parmName
)writefln("\tParameter name after = %s", pName
);
2083 parms
~= tokenToDuit(pType
, convParms
, wrapper
.getAliases());
2088 f
~= parms
~ ") " ~ name
~ ";";
2094 * Wraps a set of lines in the block documentation comment
2095 * Returns: The comment formated for D block documentation comment
2097 private char[][] getDescription()
2101 desc
~= tabs
~ "/**";
2102 char[][] block
= getBlock ("Description", "Details");
2103 foreach ( char[] line
; block
)
2105 desc
~= " * " ~ line
;
2107 desc
~= tabs
~ " */";
2114 * Finds a block of lines delimited by the marker lines from the start of the text
2116 * startLine = The Start marker line
2117 * endLine = The end marker line
2118 * Returns: The block os lines
2120 private char[][] getBlock(char[] startLine
, char[] endLine
)
2124 debug(getBlock
) writefln("getBlock for ]%s,%s[", startLine
, endLine
);
2126 // TODO use slicing instead of this array
2129 while ( currLine
<inLines
.length
&& inLines
[currLine
]!=startLine
)
2131 debug(getBlock
) writefln("-\t\t[%s]%s",currLine
,inLines
[currLine
]);
2135 return getUntil(endLine
);
2138 private int moveToBlockStart(char[] startLine
, char[][] inLines
)
2141 while ( startPos
< inLines
.length
&& inLines
[startPos
]!= startLine
)
2149 * Gets all the non empty lines until a marker line
2151 * endLine = the marker line
2154 private char[][] getUntil(char[] endLine
)
2160 while ( currLine
< inLines
.length
&& !end
)
2162 if ( inLines
[currLine
] == endLine
)
2165 debug(getUntil
) writefln("getBlock end at line %s",currLine
,"\n");
2169 if ( std
.string
.strip(inLines
[currLine
]).length
> 0 )
2171 block
~= inLines
[currLine
];
2173 debug(getUntil
) writefln("+[%s]%s",currLine
,inLines
[currLine
]);
2181 * Converts a GTK strin to a Duit string.
2182 * This removes the "_" and capitalises the next letter and converts the basic types
2187 public static char[] stringToDuit(char[] gString
, ConvParms
* convParms
, char[][char[]] aliases
, bit caseConvert
=true)
2192 char[] seps
= " \n\r\t\f\v()[]*,;";
2198 while ( pos
< gString
.length
)
2202 if ( std
.string
.find(seps
,c
) >= 0 )
2205 converted
~= tokenToDuit(gString
[start
..end
], convParms
, aliases
, caseConvert
);
2210 // converted.length = converted.length-1;
2212 //converted ~= "[] ";
2218 if ( converted
.length
>0 && converted
[converted
.length
-1] != ' ' )
2234 converted
~= tokenToDuit(gString
[start
..pos
], convParms
, aliases
, caseConvert
);
2240 public static char[] idsToDuit(char[] gToken
, ConvParms
* convParms
, char[][char[]] aliases
, bit caseConvert
=true)
2242 char[] converted
= tokenToDuit(gToken
, convParms
, aliases
, caseConvert
);
2243 switch ( converted
)
2245 case "alias" : converted
= "alia"; break;
2246 case "class" : converted
= "clss"; break;
2255 * Convert for normal Duit conversion and after verifies if is necessary to use a enumType for references enum values
2264 public static char[] enumToDuit(char[] enumType
, char[] gToken
, ConvParms
* convParms
, WrapperIF wrapper
, bit caseConvert
=true)
2266 debug(enumToDuit
)writefln("enumLine (%s) BEFORE %s", enumType
, gToken
);
2267 char[] converted
= stringToDuit(gToken
, convParms
, wrapper
.getAliases());
2269 int pos
= std
.string
.find(converted
, '=');
2270 debug(enumToDuit
)writefln("\t pos = %s", pos
);
2273 char[] refValue
= std
.string
.strip(converted
.dup
[pos
+1..converted
.length
]);
2274 debug(enumToDuit
)writefln("\t refValue = %s", refValue
);
2275 bit needComa
= false;
2276 if ( endsWith(refValue
, ',') )
2278 refValue
= std
.string
.strip(refValue
[0..refValue
.length
-1]);
2281 debug(enumToDuit
)writefln("\t refValue = %s", refValue
);
2285 foreach(char[] key
; wrapper
.getEnumTypes().keys
)
2287 writefln("\t\t [%s] = %s", key
, wrapper
.getEnumTypes()[key
]);
2291 if ( refValue
in wrapper
.getEnumTypes() )
2293 converted
= converted
[0..pos
+1]
2295 ~ wrapper
.getEnumTypes()[refValue
]
2298 ~ (needComa ?
"," : "" )
2302 debug(enumToDuit
)writefln("enumLine (%s) AFTER %s", enumType
, converted
);
2308 * Converts a GTK token to a Dui token
2309 * This removes the "_" and capitalises the next letter and converts the basic types.
2310 * Doesn't do it if it's cairo name
2315 public static char[] tokenToDuit(char[] gToken
, ConvParms
* convParms
, char[][char[]] aliases
, bit caseConvert
=true)
2319 //debug(tokenToDuit) writefln("gToken=>>>%s<<< (prefix=%s)", gToken, convParms.prefix);
2321 if ( (aliases
!is null) && (gToken
in aliases
) )
2323 converted
= aliases
[gToken
];
2325 else if ( endsWith(gToken
, "_t") && startsWith(gToken
,"cairo_") )
2327 converted
= gToken
.dup
;
2329 else if ( caseConvert
)
2331 removePrefix(gToken
, convParms
);
2332 converted
= removeUnderscore(gToken
);
2333 // do it again after the gToken is converted
2334 if ( (aliases
!is null) && (gToken
in aliases
) )
2336 converted
= aliases
[gToken
];
2341 converted
= gToken
.dup
;
2344 debug(tokenToDuit
) writefln("converted=>>>%s<<<\n", converted
);
2350 public static char[] removePrefix(inout char[] gToken
, char[] prefix
)
2352 if ( startsWith(gToken
, prefix
) )
2354 gToken
= gToken
[prefix
.length
..gToken
.length
];
2359 public static char[] removePrefix(inout char[] gToken
, ConvParms
* convParms
)
2361 //debug(tokenToDuit) writefln("gToken.length > prefix.length %s",gToken.length > convParms.prefix.length);
2362 char[] prefix
= convParms
.getPrefix(gToken
);
2363 if ( prefix
.length
> 0 )
2365 gToken
= gToken
[prefix
.length
..gToken
.length
];
2367 debug(tokenToDuit
) writefln("gToken after prefix = %s",gToken
);
2373 public static char[] removeUnderscore(char[] gToken
)
2381 while ( pos
< gToken
.length
)
2386 c
= std
.ctype
.toupper(c
);
2388 else if ( c
== '_' && std
.ctype
.islower(pc
) )
2399 && gToken
.length
-1 > pos
2400 && gToken
[pos
+1] == '_'
2416 * Moves '*' and 'const' and trailing '[]' from the name to the type token
2421 public static void adjustTypeName(inout char[] type
, inout char[] name
)
2423 debug(type
)writefln("type before %s", type
);
2424 debug(name
)writefln("name before %s", name
);
2425 name
= std
.string
.strip(name
);
2426 while ( name
.length
> 0
2427 && (DuitClass
.startsWith(name
,"const") || name
[0] == '*' )
2430 if ( name
[0] == '*' )
2433 name
= std
.string
.strip(name
[1..name
.length
]);
2437 name
= std
.string
.strip(name
[5..name
.length
]);
2439 name
= std
.string
.strip(name
);
2441 while ( DuitClass
.endsWith(name
, "[]") )
2444 name
= std
.string
.strip(name
[0..name
.length
-2]);
2446 debug(type
)writefln("type after %s", type
);
2447 debug(name
)writefln("name after %s", name
);
2451 * Consumes "const" and "unsigned" adding "u" to the type when "unsigned" is found
2452 * (? uchar will become just char)
2458 public static void fixType(inout char[] type
, inout int p
, inout char[] text
)
2460 if ( type
== "const" )
2462 DuitClass
.skipBlank(p
, text
);
2463 type
= untilBlank(p
, text
);
2465 if ( type
== "unsigned" )
2467 DuitClass
.skipBlank(p
, text
);
2468 type
= "u" ~ untilBlank(p
, text
);
2470 // if ( type == "uchar" )
2479 public static bit
startsWith(char[] str, char[] prefix
)
2481 return str.length
>= prefix
.length
2482 && str[0..prefix
.length
] == prefix
;
2485 public static bit
startsWith(char[] str, char prefix
)
2487 return str.length
> 0
2488 && str[0] == prefix
;
2491 public static bit
endsWith(char[] str, char[] suffix
)
2493 return str.length
>= suffix
.length
2494 && str[str.length
-suffix
.length
..str.length
] == suffix
;
2497 public static bit
endsWith(char[] str, char suffix
)
2499 return str.length
>= 1
2500 && str[str.length
-1] == suffix
;