Code archives/Miscellaneous/itoh

This code has been declared by its author to be Public Domain code.

Download source code

itoh by skidracer
(Posted 20 years ago)
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