Skip to content

Commit

Permalink
Convert case of array sizes defined by C macros
Browse files Browse the repository at this point in the history
  • Loading branch information
planetis-m committed Nov 22, 2024
1 parent 66f1db4 commit be4ed49
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 5 deletions.
15 changes: 10 additions & 5 deletions tools/wrapper/ctypes.nim
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import std/[parseutils, strutils]
import std/[parseutils, strutils], utils

const
NonWordChars = {'\1'..'\xff'} - IdentChars
Expand Down Expand Up @@ -93,7 +93,9 @@ proc convertArrayType(s: sink string, pointerType: PointerType): string =
result = s
if result.endsWith(']'):
let openBracket = result.find('[')
let arraySize = result[openBracket + 1 ..< result.high]
var arraySize = result[openBracket + 1 ..< result.high]
if arraySize.isScreamingSnakeCaseAscii():
arraySize = arraySize.camelCaseAscii()
result = convertPointerType(result[0 ..< openBracket],
if pointerType in {ptPtr, ptArray}: pointerType else: ptPtr) # nestable types
result = "array[" & arraySize & ", " & result & "]"
Expand All @@ -110,15 +112,17 @@ proc stripPrefixFromType(s: sink string; prefix: string): string =
start = prefixPos + prefix.len
if prefixPos > 0 and result[prefixPos - 1] notin NonWordChars:
continue
let captured = skipUntil(result, NonWordChars, start)
var token: string
let captured = parseUntil(result, token, NonWordChars, start)
if captured == 0:
continue
result = result.substr(0, prefixPos-1) & result.substr(start)
result = result.substr(0, prefixPos-1) & token & result.substr(start + captured)
start = prefixPos + captured

proc convertType*(s: string; prefix = ""; pointerType = ptPtr): string =
result = s.replace("const ", "")
result = result.multiReplace(TypeMapping)
# for prefix in prefixes.items:
result = stripPrefixFromType(result, prefix)
result = convertArrayType(result, pointerType)

Expand All @@ -127,12 +131,13 @@ when isMainModule:

assert convertType("rlDrawCall", "rl") == "DrawCall"
assert convertType("BorderlessWindowed", prefix = "rl") == "BorderlessWindowed"
assert convertType("int[RL_MAX_GAMEPADS]", "RL_") == "array[MaxGamepads, int32]"
assert convertType("rlDrawCall *", "rl", pointerType = ptArray) == "ptr UncheckedArray[DrawCall]"
assert convertType("Transform **") == "ptr ptr Transform"
assert convertType("Transform **", pointerType = ptArray) == "ptr UncheckedArray[ptr UncheckedArray[Transform]]"
assert convertType("const char *") == "cstring"
assert convertType("const char**") == "cstringArray"
assert convertType("const char *[MAX_TEXT_COUNT]", pointerType = ptArray) == "array[MAX_TEXT_COUNT, cstring]"
assert convertType("const char *[MAX_TEXT_COUNT]", pointerType = ptArray) == "array[MaxTextCount, cstring]"
assert convertType("Image *", pointerType = ptOpenArray) == "openArray[Image]"
assert convertType("Image *[4]", pointerType = ptVar) == "array[4, ptr Image]"
assert convertType("Image *[4]", pointerType = ptArray) == "array[4, ptr UncheckedArray[Image]]"
Expand Down
15 changes: 15 additions & 0 deletions tools/wrapper/utils.nim
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,21 @@ proc uncapitalizeAscii*(s: string): string =
if s.len == 0: result = ""
else: result = toLowerAscii(s[0]) & substr(s, 1)

proc isScreamingSnakeCaseAscii*(s: string): bool =
result = true
if s.len == 0 or s[0] == '_' or s[s.high] == '_':
return false
var lastWasUnderscore = false
for c in s:
if c == '_':
if lastWasUnderscore:
return false
lastWasUnderscore = true
elif not (c.isUpperAscii or c.isDigit):
return false
else:
lastWasUnderscore = false

proc isKeyword*(s: string): bool {.inline.} =
## Checks if an indentifier is a Nim keyword
binarySearch(nimKeyw, s) >= 0

0 comments on commit be4ed49

Please sign in to comment.