From b32d39ad08ec630f288958c4c9e0878ab2e8677f Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Sat, 7 Jul 2018 19:16:16 +0900 Subject: Add preliminary support for removing static funcs --- nimgen.nim | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 2 deletions(-) diff --git a/nimgen.nim b/nimgen.nim index c132fe1..7a053bb 100644 --- a/nimgen.nim +++ b/nimgen.nim @@ -25,7 +25,7 @@ var type c2nimConfigObj = object flags, ppflags: string - recurse, inline, preprocess, ctags, defines: bool + recurse, inline, preprocess, ctags, defines, remove_static: bool dynlib, compile, pragma: seq[string] const DOC = """ @@ -92,7 +92,9 @@ proc execProc(cmd: string): string = proc extractZip(zipfile: string) = var cmd = "unzip -o $#" if defined(Windows): - cmd = "powershell -nologo -noprofile -command \"& { Add-Type -A 'System.IO.Compression.FileSystem'; [IO.Compression.ZipFile]::ExtractToDirectory('$#', '.'); }\"" + cmd = "powershell -nologo -noprofile -command \"& { Add-Type -A " & + "'System.IO.Compression.FileSystem'; " & + "[IO.Compression.ZipFile]::ExtractToDirectory('$#', '.'); }\"" setCurrentDir(gOutput) defer: setCurrentDir(gProjectDir) @@ -322,6 +324,67 @@ proc comment(file: string, pattern: string, numlines: string) = idx += 1 break +proc removeStatic(filename: string) = + + if not fileExists(filename): + echo "Missing file: " & filename + return + + # This function should ideally be a regex. However, I could not + # get it to work as intended with the current re implementation + # in Nim. + # + # withFile(filename): + # content = content.replacef( + # re"(static inline.*?\))([ \r\n]*?\{([ \r\n]*?.*?)*[\n\r]\})", "$1;") + # ) + # + # This currently won't even run, but if the replacef function is modified + # to not have nil checks, it will run on 1/3 of the input file. Maybe there's + # a buffer length issue. + + var + file = open(filename) + stack: seq[string] = @[] + foundBrace = false + foundStatic = false + writeOutput = true + output = newStringofCap(getFileSize(filename)) + + for line in file.lines(): + var modLine = line + + if not foundStatic: + writeOutput = true + if line.startswith("static inline"): + foundStatic = true + let index = modLine.find("{") + if index != -1: + foundBrace = true + modLine.setLen(index) + elif not foundBrace: + writeOutput = true + if modLine.strip().startswith("{"): + foundBrace = true + writeOutput = false + else: + if modLine.startswith("}"): + foundBrace = false + foundStatic = false + output[^1] = ';' + output &= "\n" + + if writeOutput: + output &= modLine + output &= "\n" + writeOutput = false + + file.close() + + var f = open(filename, fmWrite) + write(f, output) + f.close() + proc rename(file: string, renfile: string) = if file.splitFile().ext == ".nim": return @@ -519,6 +582,9 @@ proc c2nim(fl, outfile: string, c2nimConfig: c2nimConfigObj) = if c2nimConfig.defines and (c2nimConfig.preprocess or c2nimConfig.ctags): prepend(cfile, getDefines(file, c2nimConfig.inline)) + if c2nimConfig.remove_static: + removeStatic(cfile) + var extflags = "" passC = "" @@ -697,6 +763,8 @@ proc runFile(file: string, cfgin: OrderedTableRef) = c2nimConfig.ctags = true elif action == "defines": c2nimConfig.defines = true + elif act == "remove_static": + c2nimConfig.remove_static = true elif action == "noprocess": noprocess = true elif action == "flags": -- cgit v1.2.3 From 5321014983a5dff827cecf37392b7ee99985b738 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Sun, 8 Jul 2018 10:03:33 +0900 Subject: Add readme section about remove_static --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 40f7556..360bec5 100644 --- a/README.md +++ b/README.md @@ -138,6 +138,8 @@ The following keys apply to library source code and help with generating the .ni ```defines``` = pulls out simple #defines of ints, floats and hex values for separate conversion [default: false] - works only when preprocess or ctags is used and helps include useful definitions in generated .nim file +```remove_static``` = pulls out the bodies of inline static functions [default: false] + ```flags``` = flags to pass to the c2nim process in "quotes" [default: --stdcall]. --cdecl, --assumedef, --assumendef may be useful ```ppflags``` = flags to pass to the preprocessor [default: ""]. -D for gcc and others may be useful -- cgit v1.2.3 From 0d0506675c6fc91de1fd6ac59faeece0f248ac4a Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Tue, 10 Jul 2018 20:09:51 +0900 Subject: Make static bodies replacement use regex --- nimgen.nim | 64 +++++--------------------------------------------------------- 1 file changed, 5 insertions(+), 59 deletions(-) diff --git a/nimgen.nim b/nimgen.nim index 7a053bb..e520309 100644 --- a/nimgen.nim +++ b/nimgen.nim @@ -325,65 +325,11 @@ proc comment(file: string, pattern: string, numlines: string) = break proc removeStatic(filename: string) = - - if not fileExists(filename): - echo "Missing file: " & filename - return - - # This function should ideally be a regex. However, I could not - # get it to work as intended with the current re implementation - # in Nim. - # - # withFile(filename): - # content = content.replacef( - # re"(static inline.*?\))([ \r\n]*?\{([ \r\n]*?.*?)*[\n\r]\})", "$1;") - # ) - # - # This currently won't even run, but if the replacef function is modified - # to not have nil checks, it will run on 1/3 of the input file. Maybe there's - # a buffer length issue. - - var - file = open(filename) - stack: seq[string] = @[] - foundBrace = false - foundStatic = false - writeOutput = true - output = newStringofCap(getFileSize(filename)) - - for line in file.lines(): - var modLine = line - - if not foundStatic: - writeOutput = true - if line.startswith("static inline"): - foundStatic = true - let index = modLine.find("{") - if index != -1: - foundBrace = true - modLine.setLen(index) - elif not foundBrace: - writeOutput = true - if modLine.strip().startswith("{"): - foundBrace = true - writeOutput = false - else: - if modLine.startswith("}"): - foundBrace = false - foundStatic = false - output[^1] = ';' - output &= "\n" - - if writeOutput: - output &= modLine - output &= "\n" - writeOutput = false - - file.close() - - var f = open(filename, fmWrite) - write(f, output) - f.close() + ## Replace static function bodies with a semicolon + withFile(filename): + content = content.replace( + re"(?m)(static inline.*?\))(\s*\{(\s*?.*?$)*[\n\r]\})", "$1;" + ) proc rename(file: string, renfile: string) = if file.splitFile().ext == ".nim": -- cgit v1.2.3 From 14b119f433f7584f2b9a529f388b4f298f3da874 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Wed, 11 Jul 2018 07:02:36 +0900 Subject: Move remove static and reset after processing --- nimgen.nim | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/nimgen.nim b/nimgen.nim index e520309..32e640b 100644 --- a/nimgen.nim +++ b/nimgen.nim @@ -25,7 +25,7 @@ var type c2nimConfigObj = object flags, ppflags: string - recurse, inline, preprocess, ctags, defines, remove_static: bool + recurse, inline, preprocess, ctags, defines, removeStatic: bool dynlib, compile, pragma: seq[string] const DOC = """ @@ -126,6 +126,16 @@ proc gitReset() = discard execProc("git reset --hard HEAD") +proc gitCheckout(filename: string) = + echo "Resetting file: $#" % [filename] + + setCurrentDir(gOutput) + defer: setCurrentDir(gProjectDir) + + let adjustedFile = filename.replace(gOutput & $DirSep, "") + + discard execProc("git checkout $#" % [adjustedFile]) + proc gitRemotePull(url: string, pull=true) = if dirExists(gOutput/".git"): if pull: @@ -528,7 +538,7 @@ proc c2nim(fl, outfile: string, c2nimConfig: c2nimConfigObj) = if c2nimConfig.defines and (c2nimConfig.preprocess or c2nimConfig.ctags): prepend(cfile, getDefines(file, c2nimConfig.inline)) - if c2nimConfig.remove_static: + if c2nimConfig.removeStatic: removeStatic(cfile) var @@ -659,6 +669,9 @@ proc runFile(file: string, cfgin: OrderedTableRef) = if action == "create": createDir(file.splitPath().head) writeFile(file, cfg[act]) + elif action == "removestatic": + removeStatic(sfile) + c2nimConfig.removeStatic = true elif action in @["prepend", "append", "replace", "comment", "rename", "compile", "dynlib", "pragma", "pipe"] and sfile != "": @@ -709,8 +722,6 @@ proc runFile(file: string, cfgin: OrderedTableRef) = c2nimConfig.ctags = true elif action == "defines": c2nimConfig.defines = true - elif act == "remove_static": - c2nimConfig.remove_static = true elif action == "noprocess": noprocess = true elif action == "flags": @@ -725,6 +736,9 @@ proc runFile(file: string, cfgin: OrderedTableRef) = if not noprocess: c2nim(file, getNimout(sfile), c2nimConfig) + if c2nimConfig.removeStatic: + gitCheckout(sfile) + proc runCfg(cfg: string) = if not fileExists(cfg): echo "Config doesn't exist: " & cfg -- cgit v1.2.3 From f62125a4aaed2a15970bdd186dddb7cb9a4bd862 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Wed, 11 Jul 2018 07:53:05 +0900 Subject: Update readme with removestatic --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 360bec5..7f3f256 100644 --- a/README.md +++ b/README.md @@ -138,7 +138,7 @@ The following keys apply to library source code and help with generating the .ni ```defines``` = pulls out simple #defines of ints, floats and hex values for separate conversion [default: false] - works only when preprocess or ctags is used and helps include useful definitions in generated .nim file -```remove_static``` = pulls out the bodies of inline static functions [default: false] +```removestatic``` = pulls out the bodies of inline static functions [default: false] ```flags``` = flags to pass to the c2nim process in "quotes" [default: --stdcall]. --cdecl, --assumedef, --assumendef may be useful -- cgit v1.2.3 From 685081b6a99c0022e29863e8d70bd873d7fe5876 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Wed, 11 Jul 2018 13:36:45 +0900 Subject: Modify removeStatic to comment out body, then re-comment --- nimgen.nim | 44 ++++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/nimgen.nim b/nimgen.nim index 32e640b..d613386 100644 --- a/nimgen.nim +++ b/nimgen.nim @@ -25,7 +25,7 @@ var type c2nimConfigObj = object flags, ppflags: string - recurse, inline, preprocess, ctags, defines, removeStatic: bool + recurse, inline, preprocess, ctags, defines: bool dynlib, compile, pragma: seq[string] const DOC = """ @@ -126,7 +126,7 @@ proc gitReset() = discard execProc("git reset --hard HEAD") -proc gitCheckout(filename: string) = +proc gitCheckout(filename: string) {.used.} = echo "Resetting file: $#" % [filename] setCurrentDir(gOutput) @@ -335,10 +335,33 @@ proc comment(file: string, pattern: string, numlines: string) = break proc removeStatic(filename: string) = - ## Replace static function bodies with a semicolon + ## Replace static function bodies with a semicolon and commented + ## out body withFile(filename): content = content.replace( - re"(?m)(static inline.*?\))(\s*\{(\s*?.*?$)*[\n\r]\})", "$1;" + re"(?m)(static inline.*?\))(\s*\{(\s*?.*?$)*[\n\r]\})", + proc (match: RegexMatch): string = + let funcDecl = match.captures[0] + let body = match.captures[1].strip() + result = "" + + result.add("$#;" % [funcDecl]) + result.add(body.replace(re"(?m)^", "//")) + ) + +proc reAddStatic(filename: string) = + ## Uncomment out the body and remove the semicolon. Undoes + ## removeStatic + withFile(filename): + content = content.replace( + re"(?m)(static inline.*?\));(\/\/\s*\{(\s*?.*?$)*[\n\r]\/\/\})", + proc (match: RegexMatch): string = + let funcDecl = match.captures[0] + let body = match.captures[1].strip() + result = "" + + result.add("$# " % [funcDecl]) + result.add(body.replace(re"(?m)^\/\/", "")) ) proc rename(file: string, renfile: string) = @@ -538,9 +561,6 @@ proc c2nim(fl, outfile: string, c2nimConfig: c2nimConfigObj) = if c2nimConfig.defines and (c2nimConfig.preprocess or c2nimConfig.ctags): prepend(cfile, getDefines(file, c2nimConfig.inline)) - if c2nimConfig.removeStatic: - removeStatic(cfile) - var extflags = "" passC = "" @@ -669,9 +689,6 @@ proc runFile(file: string, cfgin: OrderedTableRef) = if action == "create": createDir(file.splitPath().head) writeFile(file, cfg[act]) - elif action == "removestatic": - removeStatic(sfile) - c2nimConfig.removeStatic = true elif action in @["prepend", "append", "replace", "comment", "rename", "compile", "dynlib", "pragma", "pipe"] and sfile != "": @@ -733,11 +750,14 @@ proc runFile(file: string, cfgin: OrderedTableRef) = echo "Cannot use recurse and inline simultaneously" quit(1) + # Remove static inline function bodies + removeStatic(sfile) + if not noprocess: c2nim(file, getNimout(sfile), c2nimConfig) - if c2nimConfig.removeStatic: - gitCheckout(sfile) + # Add them back for compilation + reAddStatic(sfile) proc runCfg(cfg: string) = if not fileExists(cfg): -- cgit v1.2.3 From 15ba47946822a80d034c247c3f22b350d4651d74 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Wed, 11 Jul 2018 13:54:37 +0900 Subject: Remove removestatic from readme --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 7f3f256..40f7556 100644 --- a/README.md +++ b/README.md @@ -138,8 +138,6 @@ The following keys apply to library source code and help with generating the .ni ```defines``` = pulls out simple #defines of ints, floats and hex values for separate conversion [default: false] - works only when preprocess or ctags is used and helps include useful definitions in generated .nim file -```removestatic``` = pulls out the bodies of inline static functions [default: false] - ```flags``` = flags to pass to the c2nim process in "quotes" [default: --stdcall]. --cdecl, --assumedef, --assumendef may be useful ```ppflags``` = flags to pass to the preprocessor [default: ""]. -D for gcc and others may be useful -- cgit v1.2.3