Code archives/Miscellaneous/itoh
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
Only of interest to C/C++ programmers this code will scan the .i files of the specified module build - in this case win32 x86 release (good for Windows usage) and builds an interface for all the types, consts and globals it finds for use by C/C++ code. Method table descriptions not yet implemented sorry. WARNING: this program generates many files in currentdir so make sure you save it in it's own folder before running, the path $blitzmax/include might be a good choice. <edit> sry, MingW not quite compatible, usable code coming soon... | |||||
' itoh.bmx ' converts blitzmax .i interface files to c/c++ .h files ' WARNING: this program generates many files in currentdir Local modpath$=RequestDir("Please select your blitzmax/mod directory as source path",CurrentDir()) MakeHeaders modpath,".release.win32.x86","bb" ' "C:/blitzmax/mod",".release.win32.x86","bb" Function MakeHeaders(modpath$,suffix$,prefix$) Local suffixi$=suffix+".i" Local suffixa$=suffix+".a" For Local d$=EachIn LoadDir(modpath) If d[d.length-4..]<>".mod" Continue For Local m$=EachIn LoadDir(modpath+"/"+d) If m[m.length-4..]<>".mod" Continue Local id$=d[..d.length-4]+"_"+m[..m.length-4] For Local f$=EachIn LoadDir(modpath+"/"+d+"/"+m) Rem uncomment to archive single super mods.a If f[f.length-suffixa.length..]=suffixa Local ar$="ar -vrus mods.a "+modpath+"/"+d+"/"+m+"/"+f DebugLog ar system_ ar Continue EndIf EndRem If f[f.length-suffixi.length..]<>suffixi Continue Local hpath$=d[..d.length-4]+"_"+f[..f.length-suffixi.length]+".h" Local ipath$=modpath+"/"+d+"/"+m+"/"+f CreateHeader hpath,ipath,id,prefix Next Next Next Local b$=modpath+"/brl.mod/blitz.mod/" CopyFile b+"blitz_types.h","blitz_types.h" CopyFile b+"blitz_object.h","blitz_object.h" CopyFile b+"blitz_array.h","blitz_array.h" CopyFile b+"blitz_string.h","blitz_string.h" CopyFile b+"blitz_debug.h","blitz_debug.h" CopyFile b+"blitz_handle.h","blitz_handle.h" End Function Function CreateHeader( hpath$,ipath$,id$,prefix$ ) Local f:TStream Local l$,sname$,ssuper$,p,q Local struct$ Local hdrs$,structs$,defs$,funcs$ If id="brl_blitz" hdrs:+"#include ~qblitz_types.h~q~n" hdrs:+"#include ~qblitz_debug.h~q~n" hdrs:+"#include ~qblitz_object.h~q~n" hdrs:+"#include ~qblitz_string.h~q~n" hdrs:+"#include ~qblitz_array.h~q~n" hdrs:+"#include ~qblitz_handle.h~q~n" EndIf f=ReadStream(ipath) If Not f Return While Not Eof(f) l=f.ReadLine() If l[..10]="ModuleInfo" Continue If l[..7]="import " l=l[7..] If l[..1]="~q" Continue 'ignore misc import directives p=l.findlast(".") If p=-1 DebugStop EndIf l=l.Replace(".","_") ' l=l[p+1..] hdrs:+"#include ~q"+l+".h~q~n" Continue EndIf If l[l.length-1..]="{" p=l.find("^") If p<>-1 sname=l[..p] ssuper=l[p+1..l.length-1] p=ssuper.findlast(".") ssuper=":"+ssuper[p+1..] If ssuper=":Null" ssuper="" ssuper=ssuper.Replace(":Object",":BBObject") struct$="struct "+sname+ssuper+"{~n" ' DebugLog struct EndIf Continue EndIf If struct If l[..2]="}=" Or l[..3]="}A=" Or l[..3]="}E=" struct:+"};~n~n" ' DebugLog struct structs:+struct struct="" Continue EndIf If l[..1]="." l=l[1..l.length-1] struct:+"~t"+bb2c(l)+";~n" EndIf Continue EndIf p=l.findlast("=") If p<>-1 Select l[p-1..p] Case ")" Local bbname$,args$,ftype$ bbname=l[p+1..] l=l[..p] p=l.find("(") args=l[p+1..l.length-1] l=l[..p] funcs:+funcbb2c(l,bbname,args,prefix) ' DebugLog "FUNCTION:l="+l+" bbname="+bbname+" args="+args Case "%" defs:+"#define "+l[..p-1]+" "+l[p+1..]+"~n" Case "$" defs:+"#define "+l[..p-1]+" "+l[p+2..]+"~n" Case "&" ' DebugLog "Ptr= ??? "+l Case "S" ' DebugLog "STDCALL Function= ??? "+l Default DebugStop End Select Continue EndIf Wend CloseFile f id=id.ToUpper()+"_H" Local h$=hdrs+"~n"+defs+"~n"+structs+funcs h="#ifndef "+id+"~n#define "+id+"~n~n"+h+"#endif~n" SaveText h,hpath End Function Function funcbb2c$(l$,bbname$,args$,prefix$) Local h$,a$ bbname=bbname[1..bbname.length-1] h=bb2c(l)+"(" 'strips l and returns c decl h=h.Replace(l+"(",bbname+"(") While True a=getarg(args) If Not a Exit h:+bb2c(a) If args h:+"," Wend h:+");~n" l=prefix+l If l<>bbname h:+"#define "+l+" "+bbname+"~n~n" EndIf ' DebugLog h Return h End Function Function bb2c$(bb$ Var) 'on return strips input string to friendly name Local p,t$,eq$,fn$,ar$,std$ Local o$=bb p=bb.find("=") If p<>-1 eq$=bb[p..] bb=bb[..p] If eq[..2]="=~q" eq=eq[2..eq.length-1] If eq[..2]="bb" eq="&"+eq EndIf eq="="+eq EndIf If eq[..2]="=$" If eq="=$~q~q" eq="=&bbEmptyString" Else DebugLog "&&&&&&&&"+eq eq="" EndIf EndIf Select eq[eq.length-1..] Case "!","#" eq=eq[..eq.length-1] If eq.find(".")=-1 eq=eq+".0" eq=eq+"f" End Select EndIf While bb.length If bb[bb.length-4..]=" Var" t="&"+t bb=bb[..bb.length-4] Continue EndIf If bb[bb.length-2..]=")S" bb=bb[..bb.length-1] std="__stdcall " EndIf Select bb[bb.length-1..] Case ")" p=bb.find("(") fn=bb[p..bb.length] bb=bb[..p] Local args$=fn[1..fn.length-1] If args fn="" While True Local a$=getarg(args) If Not a Exit fn:+bb2c(a) If args fn:+"," Wend fn="("+fn+")" EndIf Continue Case "%" If bb[bb.length-2..]="%%" t="BBInt64"+t bb=bb[..bb.length-2] Continue EndIf t="int"+t Case "#" t="float"+t Case "!" t="double"+t Case "$" t="BBString*"+t Case "z" If bb[bb.length-2..]="$z" t="const char *"+t bb=bb[..bb.length-2] Continue EndIf Case "@" If bb[bb.length-2..]="@@" t="BBSHORT"+t bb=bb[..bb.length-2] Continue EndIf t="BBBYTE"+t Case "*" t="*"+t 'Function LoadDir$[]( dir$,skip_dots=True ) ' Object&[]* _datas; Case "]" p=bb.find("&[") ' If bb[bb.length-3..]="&[]" If p<>-1 ar="BBArray*"+t bb=bb[..p] Continue EndIf DebugStop Default p=bb.find(":") If p<>-1 If t DebugStop o=bb[p+1..] bb=bb[..p] p=o.findlast(".") 'typedef o=o[p+1..] If o="Object" o="BBObject" Else If eq eq="=("+o+"*)"+eq[1..] EndIf EndIf ' If bb="_datas" DebugStop If ar Return ar+" "+bb ' DebugLog"default:"+o+" *"+bb Return o+" *"+bb+eq EndIf If bb="char" bb="c" If ar t=ar 'ignore type of array for now If fn ' DebugLog "FN:"+t+"("+bb+")"+fn+eq Return t+"("+std+bb+")"+fn+eq EndIf If t="Object&[]*" DebugStop Return t$+" "+bb+eq End Select bb=bb[..bb.length-1] Wend End Function Function getarg$(arg$ Var) Local p=arg.find(",") Local q=arg.find("(") If q<>-1 And q<p 'needs to handle nest q=arg.find(")",q) p=arg.find(",",q) EndIf If p=-1 p=arg.length Local a$=arg[..p] arg=arg[p+1..] Return a End Function |
Comments
| ||
Slightly modified, included in comments my changes. This produces working code at times, from what I can see, the only issue is that of referencing stuff that has not yet been declared (structures, specifically, absolutely need to be declared in prototype form before they get really defined -- may write my own parser to handle this, since this is kind of messy at the moment). Aside from what I noted, the code this produces now seems to work for me. |
| ||
Thanks Noel. Just been trying to build interfaces for an application not just modules. Unfortunately the main .bmx build file does not generate a .i so you need to declare a single line .bmx file that imports yourapp.bmx, build the single line version in release mode and then run the following selecting yourapp.bmx (not the stub) as the application source in the second requester. This could be easily automated with a few calls to bmk once some other issues get ironed out. My new initialization code now looks like this: Strict Const BUILD$=".release.win32.x86" Const PREFIX$="bb" Local cd$=CurrentDir() Local modpath$=RequestDir("Please select your blitzmax/mod directory as source path",cd) MakeHeaders modpath,BUILD,PREFIX Local app$=RequestFile("Please select your application.bmx","BlitzMax Source:bmx",False,cd) Local path$=app[..app.length-4] Local dir$=ExtractDir(path) Local ifile$=dir+"/.bmx/"+StripDir(app)+BUILD+".i" CreateHeader( path+".h",ifile,"",prefix$ ) End |
Code Archives Forum