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 |