config.bmx 12 KB

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