config.bmx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. ' Copyright (c) 2013-2017 Bruce A Henderson
  2. '
  3. ' Based on the public domain Monkey "trans" by Mark Sibly
  4. '
  5. ' This software is provided 'as-is', without any express or implied
  6. ' warranty. In no event will the authors be held liable for any damages
  7. ' arising from the use of this software.
  8. '
  9. ' Permission is granted to anyone to use this software for any purpose,
  10. ' including commercial applications, and to alter it and redistribute it
  11. ' freely, subject to the following restrictions:
  12. '
  13. ' 1. The origin of this software must not be misrepresented; you must not
  14. ' claim that you wrote the original software. If you use this software
  15. ' in a product, an acknowledgment in the product documentation would be
  16. ' appreciated but is not required.
  17. '
  18. ' 2. Altered source versions must be plainly marked as such, and must not be
  19. ' misrepresented as being the original software.
  20. '
  21. ' 3. This notice may not be removed or altered from any source
  22. ' distribution.
  23. '
  24. SuperStrict
  25. Import BRL.LinkedList
  26. Import BRL.Map
  27. Import BRL.FileSystem
  28. Import Pub.zlib
  29. Import "options.bmx"
  30. Import "base.stringhelper.bmx"
  31. Import "base64.bmx"
  32. ' debugging help
  33. Const DEBUG:Int = False
  34. Const ABORT_ON_NULL:Int = True
  35. Const PROFILER:Int = False
  36. Const DEBUGSTOP_ON_ERROR:Int = False
  37. Global ENV_LANG$
  38. Global _errInfo$
  39. Global _errStack:TList = New TList
  40. ' bytes offset to the first field
  41. Global OBJECT_BASE_OFFSET:Int = 8
  42. ' 4 bytes on 32-bit, 8 bytes on 64-bit
  43. Global POINTER_SIZE:Int = 4
  44. Global _symbols$[]=[ "..","[]",":*",":/",":+",":-",":|",":&",":~~",":shr",":shl",":sar",":mod"]
  45. Global _symbols_map$[]=[ "..","[]","*=","/=","+=","-=","|=","&=","^=",">>=", "<<=",">>=","%=" ]
  46. Function PushErr( errInfo$ )
  47. _errStack.AddLast _errInfo
  48. _errInfo=errInfo
  49. End Function
  50. Function PopErr()
  51. _errInfo=String(_errStack.RemoveLast())
  52. End Function
  53. Function Err( err$ )
  54. If DEBUGSTOP_ON_ERROR Then
  55. DebugStop ' useful for debugging!
  56. End If
  57. Throw "Compile Error: "+err + "~n" + _errInfo + "~n"
  58. End Function
  59. Function Warn( err$ )
  60. 'If DEBUGSTOP_ON_ERROR Then
  61. ' DebugStop ' useful for debugging!
  62. 'End If
  63. Print "Compile Warning: "+err + "~n" + _errInfo + "~n"
  64. End Function
  65. Function FormatError:String(path:String, line:Int, char:Int)
  66. Return "[" + path + ";" + line + ";" + char + "]"
  67. End Function
  68. Function InternalErr()
  69. If DEBUGSTOP_ON_ERROR Then
  70. DebugStop ' useful for debugging!
  71. End If
  72. Throw "Internal Error.~n" + _errInfo + "~n"
  73. End Function
  74. Function IsSpace:Int( ch:Int )
  75. Return ch<=Asc(" ") Or ch=$A0 ' NO-BREAK SPACE (U+00A0)
  76. End Function
  77. Function IsDigit:Int( ch:Int )
  78. Return ch>=Asc("0") And ch<=Asc("9")
  79. End Function
  80. Function IsAlpha:Int( ch:Int )
  81. Return (ch>=Asc("A") And ch<=Asc("Z")) Or (ch>=Asc("a") And ch<=Asc("z"))
  82. End Function
  83. Function IsBinDigit:Int( ch:Int )
  84. Return ch=Asc("0") Or ch=Asc("1")
  85. End Function
  86. Function IsHexDigit:Int( ch:Int )
  87. Return IsDigit(ch) Or (ch>=Asc("A") And ch<=Asc("F")) Or (ch>=Asc("a") And ch<=Asc("f"))
  88. End Function
  89. Function Todo()
  90. Err "TODO!"
  91. End Function
  92. Function IsStandardFunc:Int(func:String)
  93. func = func.ToLower()
  94. Global funcs:String = ";isalnum;isalpha;isascii;isblank;iscntrl;isdigit;isgraph;islower;isprint;ispunct;isspace;isupper;isxdigit;" + ..
  95. "strlen;_wgetenv;_wputenv;"
  96. Return funcs.Find(func) > 0
  97. End Function
  98. Function mapSymbol:String(sym:String)
  99. For Local i:Int = 0 Until _symbols.length
  100. If sym = _symbols[i] Then
  101. Return _symbols_map[i]
  102. End If
  103. Next
  104. Return sym
  105. End Function
  106. 'enquote depending on ENV_LANG
  107. '
  108. Function LangEnquote$( str$ )
  109. str=EscapeString(str)
  110. ' str=str.Replace( "~0","\0" ) 'Fix me?
  111. For Local i:Int=0 Until str.Length
  112. If str[i]>=32 And str[i]<128 Continue
  113. Local t$,n:Int=str[i]
  114. While n
  115. Local c:Int=(n&15)+48
  116. If c>=58 c:+97-58
  117. t=Chr( c )+t
  118. n=(n Shr 4) & $0fffffff
  119. Wend
  120. If Not t t="0"
  121. If ENV_LANG = "cpp" Then
  122. 'Case "cpp"
  123. t="~q~q\x"+t+"~q~q"
  124. Else
  125. t="\u"+("0000"+t)[-4..]
  126. End If
  127. str=str[..i]+t+str[i+1..]
  128. i:+t.Length-1
  129. Next
  130. str="~q"+str+"~q"
  131. If ENV_LANG="cpp" str="L"+str
  132. Return str
  133. End Function
  134. Function EscapeString$(str$)
  135. str=str.Replace( "\","\\" )
  136. str=str.Replace( "~q","\~q" )
  137. str=str.Replace( "~n","\n" )
  138. str=str.Replace( "~r","\r" )
  139. str=str.Replace( "~t","\t" )
  140. Return str
  141. End Function
  142. Function BmxEnquote$( str$ )
  143. str=str.Replace( "~~","~~~~" )
  144. str=str.Replace( "~q","~~q" )
  145. str=str.Replace( "~n","~~n" )
  146. str=str.Replace( "~r","~~r" )
  147. str=str.Replace( "~t","~~t" )
  148. str=str.Replace( "~0","~~0" )
  149. str="~q"+str+"~q"
  150. Return str
  151. End Function
  152. Function BmxUnquote$( str$, unicodeConvert:Int = False )
  153. If str.length = 1 Or str[str.length - 1] <> Asc("~q") Then
  154. Err "Expecting expression but encountered malformed string literal"
  155. End If
  156. str=str[1..str.Length-1]
  157. If unicodeConvert Then
  158. Local pos:Int = str.Find("~~")
  159. While pos <> -1
  160. If pos + 1 < str.length Then
  161. If str[pos + 1] >= Asc("1") And str[pos + 1] <= Asc("9") Then
  162. Local p2:Int = str.Find("~~", pos + 1)
  163. If p2 <> -1 Then
  164. Local s:String = Chr(str[pos + 1.. p2].ToInt())
  165. str = str[..pos] + s + str[p2 + 1..]
  166. End If
  167. End If
  168. End If
  169. pos = str.Find("~~", pos + 1)
  170. Wend
  171. End If
  172. str=str.Replace( "~~~~","~~z" ) 'a bit dodgy - uses bad esc sequence ~z
  173. str=str.Replace( "~~q","~q" )
  174. str=str.Replace( "~~n","~n" )
  175. str=str.Replace( "~~r","~r" )
  176. str=str.Replace( "~~t","~t" )
  177. str=str.Replace( "~~0","~0" )
  178. str=str.Replace( "~~z","~~" )
  179. Return str
  180. End Function
  181. Type TStack Extends TList
  182. Method Push(obj:Object)
  183. AddFirst(obj)
  184. End Method
  185. Method Length:Int()
  186. Return count()
  187. End Method
  188. Method Get:Object(index:Int)
  189. Return ValueAtIndex(index)
  190. End Method
  191. Method Pop:Object()
  192. Return RemoveFirst()
  193. End Method
  194. End Type
  195. Type TStringList Extends TList
  196. Method Join:String(s:String)
  197. Local arr:String[] = New String[count()]
  198. Local index:Int
  199. For Local t:String = EachIn Self
  200. arr[index] = t
  201. index :+ 1
  202. Next
  203. Return s.Join(arr)
  204. End Method
  205. End Type
  206. Type TKeyValue
  207. Field key:Object
  208. Field value:Object
  209. Method Create:TKeyValue(key:Object,value:Object)
  210. Self.key = key
  211. Self.value = value
  212. Return Self
  213. End Method
  214. Method Compare:Int(other:Object)
  215. If Not TKeyValue(other) Return 0
  216. Return key.Compare(TKeyValue(other).key)
  217. End Method
  218. End Type
  219. Type TUnorderedMap
  220. Field list:TList = New TList
  221. Field map:TMap = New TMap
  222. Field valuesList:TList = New TList
  223. Method Insert( key:Object,value:Object )
  224. list.AddLAst(New TKeyValue.Create(key, value))
  225. valuesList.AddLast(value)
  226. map.Insert(key, value)
  227. End Method
  228. Method Keys:TList()
  229. Local klist:TList = New TList
  230. For Local kv:TKeyValue = EachIn list
  231. klist.AddLast(kv.key)
  232. Next
  233. Return klist
  234. End Method
  235. Method Values:TList()
  236. 'Local vlist:TList = New TList
  237. 'For Local kv:TKeyValue = EachIn list
  238. ' vlist.AddLast(kv.value)
  239. 'Next
  240. Return valuesList
  241. End Method
  242. Method Contains:Int( key:Object )
  243. Return map.Contains(key)
  244. End Method
  245. Method ValueForKey:Object( key:Object )
  246. Return map.ValueForKey(key)
  247. End Method
  248. End Type
  249. Function MakeKeywords:String()
  250. Local keywords:String
  251. keywords :+ "import brl.classes~n"
  252. keywords :+ "Asc%(v$)=~qbrl_blitz_keywords_asc~q~n"
  253. keywords :+ "Sgn#(v#)=~qbrl_blitz_keywords_sgn~q~n"
  254. keywords :+ "Chr$(v%)=~qbrl_blitz_keywords_chr~q~n"
  255. keywords :+ "Len%(v:Object)=~qbrl_blitz_keywords_len~q~n"
  256. keywords :+ "Min%(v1%,v2%)=~qbrl_blitz_keywords_min~q~n"
  257. keywords :+ "Max%(v1%,v2%)=~qbrl_blitz_keywords_max~q~n"
  258. 'keywords :+ "SizeOf%(v%)=~qbrl_blitz_keywords_sizeof~q~n"
  259. 'keywords :+ "Incbin(v$)=~qbrl_blitz_keywords_incbin~q~n"
  260. keywords :+ "IncbinPtr@*(v$)=~qbbIncbinPtr~q~n"
  261. keywords :+ "IncbinLen%(v$)=~qbbIncbinLen~q~n"
  262. Return keywords
  263. End Function
  264. Function FilePath:String(path:String)
  265. Local baseDir:String = ExtractDir(path)
  266. Local bmxDir:String = baseDir + "/.bmx"
  267. If FileType(bmxDir) <> FILETYPE_DIR Then
  268. Throw "Missing : " + bmxDir
  269. End If
  270. Return bmxDir
  271. End Function
  272. Function BuildHeaderName:String(path:String)
  273. If opt_buildtype = BUILDTYPE_MODULE Then
  274. path = opt_modulename + "_" + StripDir(path)
  275. Else
  276. Local dir:String = ExtractDir(path).ToLower().Replace("/.bmx","")
  277. dir = dir[dir.findLast("/") + 1..]
  278. If dir.EndsWith(".mod") Then
  279. dir = dir.Replace(".mod", "")
  280. End If
  281. Local file:String = StripDir(path).ToLower()
  282. path = dir + "_" + file
  283. End If
  284. Return TStringHelper.Sanitize(path, , True)
  285. End Function
  286. Rem
  287. bbdoc: Get the header file name from a given module ident, optionally with include path.
  288. End Rem
  289. Function ModuleHeaderFromIdent:String(ident:String, includePath:Int = False)
  290. Local ns:String = ident[..ident.find(".")]
  291. Local name:String = ident[ident.find(".") + 1..]
  292. Local file:String = name + ".bmx" + FileMung() + ".h"
  293. If includePath Then
  294. file = ns + ".mod/" + name + ".mod/.bmx/" + file
  295. End If
  296. Return file
  297. End Function
  298. Function HeaderFile:String(path:String, mung:String)
  299. Local fileDir:String = FilePath(path)
  300. Local file:String = StripDir(path)
  301. Return fileDir + "/" + file + mung + ".h"
  302. End Function
  303. Function OutputFilePath:String(path:String, mung:String, suffix:String, bmxDir:Int = False)
  304. Local fileDir:String = FilePath(path)
  305. If bmxDir Then
  306. fileDir :+ "/.bmx"
  307. End If
  308. Local file:String = StripDir(path)
  309. Return fileDir + "/" + file + mung + "." + suffix
  310. End Function
  311. Function FileMung:String(makeApp:Int = False)
  312. Local m:String = "."
  313. If makeApp Then
  314. Select opt_apptype
  315. Case APPTYPE_CONSOLE
  316. m :+ "console."
  317. Case APPTYPE_GUI
  318. m :+ "gui."
  319. End Select
  320. End If
  321. If opt_release Then
  322. m :+ "release"
  323. Else
  324. m :+ "debug"
  325. End If
  326. ' If opt_threaded Then
  327. ' m :+ ".mt"
  328. ' End If
  329. m :+ "." + opt_platform
  330. m :+ "." + opt_arch
  331. Return m
  332. End Function
  333. Function HeaderComment:String()
  334. ' TODO
  335. End Function
  336. Type TTemplateRecord
  337. Field start:Int
  338. Field file:String
  339. Field source:String
  340. Method Create:TTemplateRecord(start:Int, file:String, source:String)
  341. Self.start = start
  342. Self.file = file
  343. Self.source = source
  344. Return Self
  345. End Method
  346. Method ToString:String()
  347. Local s:Byte Ptr = source.ToUTF8String()
  348. Local slen:Int = strlen_(s)
  349. ?Not bmxng
  350. Local dlen:Int = slen + 12
  351. ?bmxng And (win32 Or ptr32)
  352. Local dlen:UInt = slen + 12
  353. ?bmxng And ptr64 And Not win32
  354. Local dlen:ULong = slen + 12
  355. ?
  356. Local data:Byte[dlen]
  357. compress2(data, dlen, s, slen, 9)
  358. MemFree(s)
  359. Local t:String = "{" + start +","+ slen +","+ LangEnquote(file) + ","
  360. t :+ LangEnquote(TBase64.Encode(data, dlen, 0, TBase64.DONT_BREAK_LINES))
  361. Return t + "}"
  362. End Method
  363. Function Load:TTemplateRecord(start:Int, file:String, size:Int, source:String)
  364. ?Not bmxng
  365. Local dlen:Int = size + 1
  366. ?bmxng And (win32 Or ptr32)
  367. Local dlen:UInt = size + 1
  368. ?bmxng And ptr64 And Not win32
  369. Local dlen:ULong = size + 1
  370. ?
  371. Local data:Byte[dlen]
  372. Local s:Byte[] = TBase64.Decode(source)
  373. uncompress(data, dlen, s, s.length)
  374. Return New TTemplateRecord.Create(start, file, String.FromUTF8String(data))
  375. End Function
  376. End Type
  377. Extern
  378. Function strlen_:Int(s:Byte Ptr)="strlen"
  379. End Extern