Compare commits

..

83 commits

Author SHA1 Message Date
Joey Yakimowich-Payne
638c9b4a5a Fix bug with length 2019-09-07 09:12:32 -06:00
Joey Yakimowich-Payne
942ae8e803 Merge remote-tracking branch 'upstream/master' 2019-09-07 08:51:49 -06:00
Ganesh Viswanathan
2be81614a9 Fix #42 - curl should follow redirects, powershell wget backport 2019-07-16 22:17:32 -05:00
Ganesh Viswanathan
39f5f320a6 Remove libsvm 2019-07-16 22:06:06 -05:00
Ganesh Viswanathan
fabd615379 C2nim is now backwards compatible 2019-07-16 14:06:02 -05:00
Ganesh Viswanathan
b54feea3fc Remove nimnuklear 2019-07-16 13:04:05 -05:00
Ganesh Viswanathan
4ab5ff93b8 Fix c2nim dependency 2019-07-15 22:49:04 -05:00
Ganesh Viswanathan
97141f523f Bump to latest 2019-07-09 23:58:01 -05:00
Joey Yakimowich-Payne
d6f8d140cc Add function to remove function bodies 2019-03-22 09:53:23 -06:00
Joey Yakimowich-Payne
69b9ee9083 Re-enable remove static 2019-03-22 09:15:49 -06:00
Ganesh Viswanathan
293476c0a9 Remove nimarchive since it is currently broken 2019-03-06 00:34:11 -06:00
Ganesh Viswanathan
cf132951bd Update appveyor to 0.19.2 2018-12-31 12:33:09 -06:00
Ganesh Viswanathan
31b63a6ea6 Update nimfuzz to nimfuzzy 2018-12-10 12:00:53 -06:00
genotrance
5199b86b74
Merge pull request #39 from data-man/ospaths
Don't use ospaths on Nim-devel
2018-12-10 09:49:25 -06:00
Ganesh Viswanathan
46cce39e64 Use choosenim for Travis 2018-12-10 09:48:46 -06:00
data-man
2f1a62a030 Don't use ospaths on Nim-devel 2018-12-09 05:54:36 +05:00
Ganesh Viswanathan
24c62dbc18 Enable nimfastText on OSX 2018-12-07 17:58:46 -06:00
Ganesh Viswanathan
86df7b19f1 Fix README 2018-11-08 21:39:20 -06:00
Ganesh Viswanathan
d6241b1da4 Pygmentize only 2018-11-04 16:19:54 -06:00
Ganesh Viswanathan
02459f3d82 Remove nimfastText from gcc < 5.x 2018-11-04 15:06:37 -06:00
Ganesh Viswanathan
b78f6d38fd Fix nimgen dir regression 2018-11-04 14:34:50 -06:00
Ganesh Viswanathan
44fc30a9cb Add nimdoc.cfg 2018-11-04 14:27:27 -06:00
Ganesh Viswanathan
ae6d4aff28 Last nightlies release 2018-11-03 23:38:04 -05:00
Ganesh Viswanathan
47ca2cffd6 Brew no autoupdate 2018-11-03 23:20:28 -05:00
Ganesh Viswanathan
c60a8cd415 Remove nimzbar from OSX 2018-11-03 21:14:13 -05:00
Ganesh Viswanathan
5be86fcd99 Brew install 2018-11-02 23:24:45 -05:00
Ganesh Viswanathan
a8b836656e libssh2 for OSX 2018-11-02 23:04:58 -05:00
Ganesh Viswanathan
81fa6d15ba Github download 2018-11-02 22:26:46 -05:00
Ganesh Viswanathan
d6c827bb28 Github download 2018-11-02 22:18:05 -05:00
Ganesh Viswanathan
03c38a2448 Github download 2018-11-02 22:04:09 -05:00
Ganesh Viswanathan
d080be55a5 Github download 2018-11-02 21:56:14 -05:00
Ganesh Viswanathan
d27d28f0d9 Fix travis again 2018-11-02 17:15:35 -05:00
Ganesh Viswanathan
c7c419e6fa Backrev c2nim 2018-11-02 17:12:37 -05:00
Ganesh Viswanathan
5549505f61 Cleanup 2018-11-02 15:09:28 -05:00
Ganesh Viswanathan
34efd6619f Docgen only on Windows 2018-11-02 14:14:15 -05:00
Ganesh Viswanathan
715b502274 Fix path 2018-11-02 11:25:48 -05:00
Ganesh Viswanathan
c40919b87c Fix deps 2018-11-02 10:58:38 -05:00
Ganesh Viswanathan
713703caae Travis fixes 2018-11-02 10:55:05 -05:00
Ganesh Viswanathan
ee7a55f2ec Add Travis for devel/OSX 2018-11-02 10:38:38 -05:00
Ganesh Viswanathan
f1a8d17891 Fix version print 2018-11-01 15:37:56 -05:00
Ganesh Viswanathan
8188c75118 Enable 0.19.0 2018-11-01 14:31:09 -05:00
Ganesh Viswanathan
ad49917733 Appveyor bugfix 2018-10-30 23:25:43 -05:00
Ganesh Viswanathan
ebd362d934 Appveyor bugfix 2018-10-30 23:04:28 -05:00
Ganesh Viswanathan
e8faaf8d0c Appveyor bugfix 2018-10-30 22:54:08 -05:00
Ganesh Viswanathan
9ec27678ea Appveyor bugfix 2018-10-30 22:43:55 -05:00
Ganesh Viswanathan
1f3ae34dc0 Fix gGitOutput set 2018-10-30 22:16:29 -05:00
Ganesh Viswanathan
1c057f2520 OS specific sections, execAction, nowildcard, multi git repos, branch/tag/commit 2018-10-30 21:55:17 -05:00
Ganesh Viswanathan
caba6fcc50 Fix regex crash 2018-10-08 17:54:43 -05:00
Ganesh Viswanathan
da865618be Multi-version CI 2018-10-08 17:28:58 -05:00
Ganesh Viswanathan
b5030a8bd5 Multi-version CI 2018-10-08 17:27:07 -05:00
Ganesh Viswanathan
c4d45b318b Multi-version CI 2018-10-08 17:17:33 -05:00
Ganesh Viswanathan
35765f046b Multi-version CI 2018-10-08 12:28:12 -05:00
Ganesh Viswanathan
db26f9580d Multi-version CI 2018-10-08 12:21:49 -05:00
Ganesh Viswanathan
83465b25de Multi-version CI 2018-10-08 12:15:01 -05:00
Ganesh Viswanathan
efc04c38cc Multi-version CI 2018-10-08 12:08:38 -05:00
Ganesh Viswanathan
e04b40d6a8 Remove nimfastText 2018-10-05 10:47:36 -05:00
Ganesh Viswanathan
4df59320fd Comp fixes 2018-10-04 21:17:02 -05:00
Ganesh Viswanathan
6b16a83572 Edit comps 2018-10-04 17:10:43 -05:00
Ganesh Viswanathan
0a32e7fa2c Add nimmonocrypt, remove nimfastText 2018-10-02 12:24:28 -05:00
Ganesh Viswanathan
2f27ad0d05 Save artifacts 2018-09-27 19:27:22 -05:00
Ganesh Viswanathan
6c8bf5e842 Save artifacts 2018-09-27 19:06:16 -05:00
Ganesh Viswanathan
598214c1d2 Save project artifacts 2018-09-27 18:35:11 -05:00
Ganesh Viswanathan
8eaa765601 Add nimnuklear and nimfastText 2018-09-26 16:44:28 -05:00
Ganesh Viswanathan
23bb86803d Add duktape-nim 2018-09-05 14:33:35 -05:00
Ganesh Viswanathan
7082f89781 Add duktape-nim 2018-09-05 14:32:19 -05:00
Ganesh Viswanathan
a2a2c41704 Add nimtess2 to test suite 2018-09-05 13:18:45 -05:00
Ganesh Viswanathan
864506afbc Remove ropes dependency 2018-08-19 19:25:04 -05:00
Ganesh Viswanathan
02de68b36d Fix nil rope 2018-08-19 17:05:19 -05:00
Ganesh Viswanathan
1711052eae Add move capability, handle compile duplicate names 2018-08-19 12:31:21 -05:00
Ganesh Viswanathan
7e21b2799e Improve compile 2018-08-15 15:19:59 -05:00
Ganesh Viswanathan
1e26d3e6eb More flexibility in compile flag 2018-08-15 14:41:41 -05:00
Ganesh Viswanathan
1a29b9f0f8 Add badges 2018-08-14 11:21:51 -05:00
Ganesh Viswanathan
1fb8674d07 Add badges 2018-08-14 11:19:32 -05:00
Ganesh Viswanathan
bb2c9474fa Add badges 2018-08-14 11:18:31 -05:00
Ganesh Viswanathan
667d6caf84 CLI support - #20 2018-08-08 11:06:21 -05:00
Ganesh Viswanathan
0406d83384 Merge branch 'master' of https://github.com/genotrance/nimgen into features-1 2018-08-06 11:37:02 -05:00
genotrance
db0363505e
Merge pull request #34 from jyapayne/fix_unittest_continue
Fix unit test for Windows and quit with failure code
2018-08-06 11:36:11 -05:00
Ganesh Viswanathan
32debc5534 Regex search/replace support - #2 2018-08-05 01:10:47 -05:00
Ganesh Viswanathan
1dbff5cbd1 Inline fixes 2018-08-03 23:27:26 -05:00
Joey Yakimowich-Payne
c6148571c1 Fix windows echo 2018-08-03 15:08:03 +09:00
Joey Yakimowich-Payne
87e08bfb66 Fix unit test for Windows and quit with failure code 2018-08-03 13:02:56 +09:00
Ganesh Viswanathan
2c3cc71540 Fix permission denied and file flushing issues 2018-08-02 20:49:50 -05:00
genotrance
dc9943a22c
Merge pull request #31 from jyapayne/fix_another_issue
Fix windows not processing headers
2018-07-18 09:28:10 -05:00
17 changed files with 2094 additions and 364 deletions

27
.travis.yml Normal file
View file

@ -0,0 +1,27 @@
os:
- linux
- osx
language: c
env:
- BRANCH=devel
addons:
apt:
packages:
- libssh2-1-dev
before_install:
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then HOMEBREW_NO_AUTO_UPDATE=1 brew install libssh2; fi
install:
- export CHOOSENIM_CHOOSE_VERSION=$BRANCH
- |
curl https://nim-lang.org/choosenim/init.sh -sSf > init.sh
sh init.sh -y
- export PATH=$HOME/.nimble/bin:$PATH
script:
- nimble install -y
- nimble test

View file

@ -1,3 +1,7 @@
[![Chat on Gitter](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/nimgen/Lobby)
[![Build status](https://ci.appveyor.com/api/projects/status/05t5ja88lmv1rt3r/branch/master?svg=true)](https://ci.appveyor.com/project/genotrance/nimgen/branch/master)
[![Build Status](https://travis-ci.org/genotrance/nimgen.svg?branch=master)](https://travis-ci.org/genotrance/nimgen)
Nimgen is a helper for [c2nim](https://github.com/nim-lang/c2nim/) to simplify and automate the wrapping of C libraries.
Nimgen can be used to automate the process of manipulating C files so that c2nim can be run on them without issues. This includes adding/removing code snippets, removal of complex preprocessor definitions that c2nim doesn't yet comprehend and recursively running on #include files.
@ -39,7 +43,7 @@ To see examples of nimgen in action check out the following wrappers:-
* [nim-clblast](https://github.com/numforge/nim-clblast) - OpenCL BLAS wrapper
* static
* Compile C code into binary
* Compile C/C++ code into binary
* [nim7z](https://github.com/genotrance/nim7z) - 7z decoder wrapper: [docs](http://nimgen.genotrance.com/nim7z)
* git sparse checkout
* [nimarchive](https://github.com/genotrance/nimarchive) - libarchive wrapper: [docs](http://nimgen.genotrance.com/nimarchive)
@ -48,18 +52,26 @@ To see examples of nimgen in action check out the following wrappers:-
* git checkout
* [nimclipboard](https://github.com/genotrance/nimclipboard) - libclipboard wrapper: [docs](http://nimgen.genotrance.com/nimclipboard)
* git checkout
* [nimfuzz](https://github.com/genotrance/nimfuzz) - fts_fuzzy_match wrapper: [docs](http://nimgen.genotrance.com/nimfuzz)
* [nimfastText](https://github.com/genotrance/nimfastText) - fastText wrapper: [docs](http://nimgen.genotrance.com/nimfastText)
* git sparse checkout
* [nimfuzzy](https://github.com/genotrance/nimfuzzy) - fts_fuzzy_match wrapper: [docs](http://nimgen.genotrance.com/nimfuzzy)
* download header file
* [nimkerberos](https://github.com/genotrance/nimkerberos) - WinKerberos wrapper: [docs](http://nimgen.genotrance.com/nimkerberos)
* git sparse checkout
* [nimmonocypher](https://github.com/genotrance/nimmonocypher) - monocypher wrapper: [docs](http://nimgen.genotrance.com/nimmonocypher)
* git sparse checkout
* [nimnuklear](https://github.com/genotrance/nimnuklear) - nuklear wrapper: [docs](https://nimgen.genotrance.com/nimnuklear)
* git sparse checkout
* [nimpcre](https://github.com/genotrance/nimpcre) - PCRE wrapper: [docs](http://nimgen.genotrance.com/nimpcre)
* git checkout
* [nimrax](https://github.com/genotrance/nimrax) - Radix tree wrapper: [docs](http://nimgen.genotrance.com/nimrax)
* git checkout
* [nimssl](https://github.com/genotrance/nimssl) - OpenSSL wrapper: [docs](http://nimgen.genotrance.com/nimssl)
* git sparse checkout
* [libsvm](https://github.com/genotrance/libsvm) - libsvm wrapper: [docs](http://nimgen.genotrance.com/libsvm)
* git sparse checkout
* [nimtess2](https://github.com/genotrance/nimtess2) - libtess2 wrapper: [docs](http://nimgen.genotrance.com/nimtess2)
* git checkout
* [duktape-nim](https://github.com/manguluka/duktape-nim) - Duktape wrapper
* static
* Compile in as static binary
* [nimssh2](https://github.com/genotrance/nimssh2) - libssh2 wrapper: [docs](http://nimgen.genotrance.com/nimssh2)
@ -80,6 +92,8 @@ In all sections below, environment variables are supported via Nim's string inte
"${output}/library/include"
"${MY_INCLUDE_PATH}/include"
Append -win, -lin and -mac/osx for OS specific sections and tasks. E.g. n.global-win, n.post-lin, download-win, execute-lin-mac.unique1. -unix can be used as a shortcut for -lin-mac.
_[n.global]_
```output``` = name of the Nimble project once installed, also location to place generated .nim files
@ -106,17 +120,21 @@ List of all directories or files to exclude from all parsing. If an entry here m
_[n.prepare]_
The following keys can be used to prepare dependencies such as downloading ZIP files, cloning Git repositories, etc. Multiple entries are possible by appending any .string to the key. E.g. download.file1. -win, -lin and -mac/osx can be used for OS specific tasks. E.g. download-win, execute-lin,mac.unique1
The following keys can be used to prepare dependencies such as downloading ZIP files, cloning Git repositories, etc. Multiple entries are possible by appending any .string to the key. E.g. download.file1.
```download``` = url to download to the output directory. ZIP files are automatically extracted. Files are not redownloaded if already present but re-extracted
```extract``` = ZIP file to extract in case they are local and don't need to be downloaded. Path is relative to output directory.
```git``` = url of Git repository to clone. Full repo is pulled so gitremote + gitsparse is preferable. Resets to HEAD if already present
```gitcheckout``` = branch, commit or tag of repository to checkout in following Git command, resets after each use. Use "-b name" for branches
```gitoutput``` = directory for all following Git commands relative to `n.global:output` [default: `n.global:output` directory]
```git``` = url of Git repository to clone. Full repo is pulled so gitremote + gitsparse is preferable. Resets if already present
```gitremote``` = url of Git repository to partially checkout. Use with gitsparse to pull only files and dirs of interest
```gitsparse``` = list of files and/or dirs to include in partial checkout, one per line. Resets to HEAD if already present
```gitsparse``` = list of files and/or dirs to include in partial checkout, one per line. Resets if already present
```execute``` = command to run during preparation
@ -126,7 +144,9 @@ _[n.post]_
This section is the same as the prepare section, but for performing actions after the project has been processed.
```reset``` = whether or not to perform a git reset on all files after processing [default: false]
```gitoutput``` = output directory for Git reset [default: `n.global:output` directory]
```reset``` = perform a Git reset on all files after processing [default: false]
```execute``` = command to run after processing
@ -142,7 +162,7 @@ This section allows selection of multiple sourcefiles without requiring a detail
_[sourcefile]_
The following keys apply to library source code and help with generating the .nim files. -win, -lin and -osx can be used for OS specific tasks. E.g. dynlib-win, pragma-win
The following keys apply to library source code and help with generating the .nim files. -win, -lin and -osx can be used for OS specific tasks. E.g. dynlib-win, pragma-win.
```recurse``` = find #include files and process them [default: false]
@ -160,11 +180,13 @@ The following keys apply to library source code and help with generating the .ni
```noprocess``` = do not process this source file with c2nim [default: false] - this is useful if a file only needs to be manipulated
```nowildcard``` = ignore any wildcard definitions for this sourcefile
```reset``` = reset the file back to original state after all processing [default: false]
Multiple entries for the all following keys are possible by appending any .string to the key. E.g. dynlib.win, compile.dir
```compile``` = file or dir of files of source code to {.compile.} into generated .nim
```compile``` = file or dir of files of source code to {.compile.} into generated .nim. If directory, picks *.c if C mode and *.cxx, *.cpp, *.cc, *.c++ and *.C for cpp mode. Dir can also include wildcards. e.g. compile = """dir/A*.cxx"""
```pragma``` = pragmas to define in generated .nim file. E.g. pragma = "passL: \"-lssl\"" => {.passL: "-lssl".}
@ -174,15 +196,19 @@ The following keys apply to library source code (before processing) and generate
```create``` = create a file at exact location with contents specified. File needs to be in the _[n.exclude]_ list in order to be created.
```pipe``` = execute a command on a file and store the output of the command as the new file contents. E.g. pipe = "cat $file | grep 'static inline'"
```search``` = search string providing context for following prepend/append/replace directives
```pipe``` = execute a command on a file and store the output of the command as the new file contents. Ex: pipe = "cat $file | grep 'static inline'"
```regex``` = regex search string providing context for the following replace directive. Specify using """ to avoid regex parsing issues
```prepend``` = string value to prepend into file at beginning or before search
```append``` = string value to append into file at the end or after search
```replace``` = string value to replace search string in file
```replace``` = string value to replace search string in file. Regex captures can be referred to using $1, $2, etc.
```move``` = search string providing context for location to move the results of a preceding search or regex match
```comment``` = number of lines to comment from search location
@ -196,6 +222,41 @@ The following key only applies before processing and allows renaming the generat
`$replace(srch1=repl1, srch2=reply2)` = rename specific portions in `$nimout`
__Command Line__
A subset of capabilities are available through the command line to enable quick tests using nimgen. Command line flags only apply to source files specified on the command line and do not influence any ```cfg``` files which are expected to be self-sufficient.
```
Usage:
nimgen [options] file.cfg|file.h ...
Params:
-C<compile> add compile entry *
-E<exclude> add n.exclude entry *
-F<flags> set c2nim flags *
-I<include> add n.include dir *
-O<outdir> set output directory
-P<ppflags> set preprocessor flags *
Options:
-c set ctags = true
-d set defines = true
-i set inline = true
-n set noprocess = true
-p set preprocess = true
-r set recurse = true
Editing:
-a<append> append string *
-e<prepend> prepend string *
-l<replace> replace string *
-o#lines comment X lines *
-s<search> search string *
-x<regex> regex search string *
* supports multiple instances
```
__Feedback__
Nimgen is a work in progress and any feedback or suggestions are welcome. It is hosted on [GitHub](https://github.com/genotrance/nimgen) with an MIT license so issues, forks and PRs are most appreciated. Also join us at https://gitter.im/nimgen/Lobby to chat about nimgen and the future of Nim wrappers.

View file

@ -7,6 +7,11 @@ image:
matrix:
fast_finish: true
environment:
matrix:
- NIM_VERSION: 0.20.0
- NIM_VERSION: 0.19.6
for:
-
matrix:
@ -14,93 +19,80 @@ for:
- image: Visual Studio 2017
environment:
MINGW_DIR: mingw32
MINGW_URL: https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/8.1.0/threads-posix/dwarf/i686-8.1.0-release-posix-dwarf-rt_v6-rev0.7z/download
ARCH: 32
MINGW_URL: https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/8.1.0/threads-posix/dwarf
MINGW_ARCHIVE: i686-8.1.0-release-posix-dwarf-rt_v6-rev0.7z
NIM_URL: https://nim-lang.org/download/nim-0.18.0_x32.zip
NIM_ARCHIVE: nim-0.18.0_x32.zip
NIM_VERSION: nim-0.18.0
LIBSSH2_ARCHIVE: mingw-w64-i686-libssh2-1.8.0-1-any.pkg.tar.xz
LIBSSH2_ARCHIVE2: mingw-w64-i686-libssh2-1.8.0-1-any.pkg.tar
LIBSSH2_URL: https://sourceforge.net/projects/msys2/files/REPOS/MINGW/i686/mingw-w64-i686-libssh2-1.8.0-1-any.pkg.tar.xz/download
LIBCRYPTO_ARCHIVE: mingw-w64-i686-openssl-1.0.2.o-1-any.pkg.tar.xz
LIBCRYPTO_ARCHIVE2: mingw-w64-i686-openssl-1.0.2.o-1-any.pkg.tar
LIBCRYPTO_URL: https://sourceforge.net/projects/msys2/files/REPOS/MINGW/i686/mingw-w64-i686-openssl-1.0.2.o-1-any.pkg.tar.xz/download
DLLS_URL: http://nim-lang.org/download/dlls.zip
DLLS_ARCHIVE: dlls.zip
BASE_DIR: c:\projects
SFNET_URL: https://sourceforge.net/projects/msys2/files/REPOS/MINGW/i686
LIBSSH2_ARCHIVE: mingw-w64-i686-libssh2-1.8.0-1-any.pkg
LIBCRYPTO_ARCHIVE: mingw-w64-i686-openssl-1.0.2.o-1-any.pkg
install:
- CD %BASE_DIR%
- IF not exist "%MINGW_ARCHIVE%" appveyor DownloadFile "%MINGW_URL%" -FileName "%MINGW_ARCHIVE%"
- 7z x -y "%MINGW_ARCHIVE%"> nul
- IF not exist "%LIBSSH2_ARCHIVE%" appveyor DownloadFile "%LIBSSH2_URL%" -FileName "%LIBSSH2_ARCHIVE%"
- 7z x -y "%LIBSSH2_ARCHIVE%"> nul
- 7z x -y "%LIBSSH2_ARCHIVE2%"> nul
- IF not exist "%LIBCRYPTO_ARCHIVE%" appveyor DownloadFile "%LIBCRYPTO_URL%" -FileName "%LIBCRYPTO_ARCHIVE%"
- 7z x -y "%LIBCRYPTO_ARCHIVE%"> nul
- 7z x -y "%LIBCRYPTO_ARCHIVE2%"> nul
- IF not exist "%NIM_ARCHIVE%" appveyor DownloadFile "%NIM_URL%" -FileName "%NIM_ARCHIVE%"
- 7z x -y "%NIM_ARCHIVE%"> nul
- SET PATH=%BASE_DIR%\%MINGW_DIR%\bin;%BASE_DIR%\%NIM_VERSION%\bin;%USERPROFILE%\.nimble\bin;%PATH%
- CD %BASE_DIR%\nimgen
# - git clone --depth 1 https://github.com/nim-lang/nim
# - cd nim
# - git clone --depth 1 https://github.com/nim-lang/csources
# - cd csources
# - IF "%PLATFORM%" == "x64" ( build64.bat ) else ( build.bat )
# - cd ..
# - IF not exist "%DLLS_ARCHIVE%" appveyor DownloadFile "%DLLS_URL%" -FileName "%DLLS_ARCHIVE%"
# - 7z x -y "%DLLS_ARCHIVE%" -o"%CD%\bin"> nul
# - bin\nim c -d:release koch
# - koch boot -d:release
# - koch nimble -d:release
# - SET PATH=%CD%\bin;%PATH%
# - cd ..
- CD c:\
- IF not exist "binaries" (
echo %NIM_VERSION% &&
MKDIR binaries &&
CD binaries &&
appveyor DownloadFile "%MINGW_URL%/%MINGW_ARCHIVE%/download" -FileName "%MINGW_ARCHIVE%" &&
7z x -y "%MINGW_ARCHIVE%"> nul &&
del "%MINGW_ARCHIVE%" &&
appveyor DownloadFile "%SFNET_URL%/%LIBSSH2_ARCHIVE%.tar.xz/download" -FileName "%LIBSSH2_ARCHIVE%.tar.xz" &&
7z x -y "%LIBSSH2_ARCHIVE%.tar.xz"> nul &&
del "%LIBSSH2_ARCHIVE%.tar.xz" &&
7z x -y "%LIBSSH2_ARCHIVE%.tar"> nul &&
del "%LIBSSH2_ARCHIVE%.tar" &&
appveyor DownloadFile "%SFNET_URL%/%LIBCRYPTO_ARCHIVE%.tar.xz/download" -FileName "%LIBCRYPTO_ARCHIVE%.tar.xz" &&
7z x -y "%LIBCRYPTO_ARCHIVE%.tar.xz"> nul &&
del "%LIBCRYPTO_ARCHIVE%.tar.xz" &&
7z x -y "%LIBCRYPTO_ARCHIVE%.tar"> nul &&
del "%LIBCRYPTO_ARCHIVE%.tar" &&
appveyor DownloadFile "https://nim-lang.org/download/nim-%NIM_VERSION%_x%ARCH%.zip" -FileName "nim-%NIM_VERSION%_x%ARCH%.zip" &&
7z x -y "nim-%NIM_VERSION%_x%ARCH%.zip"> nul &&
del "nim-%NIM_VERSION%_x%ARCH%.zip")
- SET PATH=c:\binaries\mingw%ARCH%\bin;c:\binaries\nim-%NIM_VERSION%\bin;%USERPROFILE%\.nimble\bin;%PATH%
- CD c:\projects\nimgen
on_finish:
- 7z a -r buildlogs-win.zip %USERPROFILE%\.nimble\pkgs
- appveyor PushArtifact buildlogs-win.zip
- 7z a -r nimgen-docs.zip %BASE_DIR%\nimgen\web
- 7z a -r buildlogs-win-pkgs.zip %USERPROFILE%\.nimble\pkgs
- appveyor PushArtifact buildlogs-win-pkgs.zip
- 7z a -r buildlogs-win-projects.zip c:\projects\*
- appveyor PushArtifact buildlogs-win-projects.zip
- 7z a -r nimgen-docs.zip c:\projects\nimgen\web
- appveyor PushArtifact nimgen-docs.zip
cache:
- c:\projects\i686-8.1.0-release-posix-dwarf-rt_v6-rev0.7z
- c:\projects\mingw-w64-i686-libssh2-1.8.0-1-any.pkg.tar.xz
- c:\projects\mingw-w64-i686-openssl-1.0.2.o-1-any.pkg.tar.xz
- c:\projects\nim-0.18.0_x32.zip
- c:\binaries
-
matrix:
only:
- image: Ubuntu
environment:
NIM_URL: https://nim-lang.org/download/nim-0.18.0.tar.xz
NIM_ARCHIVE: nim-0.18.0.tar.xz
NIM_VERSION: nim-0.18.0
BASE_DIR: /home/appveyor/projects
install:
- sudo apt -qq update
- sudo apt -qq install --yes python-pygments libssh2-1-dev libgcrypt20-dev libgpg-error-dev
- cd $BASE_DIR
- if [ ! -e $NIM_ARCHIVE ]; then curl -s -o $NIM_ARCHIVE $NIM_URL; fi
- tar xJf $NIM_ARCHIVE
- cd $NIM_VERSION
- sh build.sh
- bin/nim c -d:release koch
- ./koch boot -d:release
- ./koch nimble -d:release
- export PATH=$BASE_DIR/$NIM_VERSION/bin:~/.nimble/bin:$PATH
- cd $BASE_DIR/nimgen
- sudo apt -qq install --yes libssh2-1-dev libgcrypt20-dev libgpg-error-dev
- if [ ! -e /home/appveyor/binaries ]; then
echo $NIM_VERSION &&
mkdir /home/appveyor/binaries &&
cd /home/appveyor/binaries &&
curl -s -o nim-$NIM_VERSION.tar.xz https://nim-lang.org/download/nim-$NIM_VERSION.tar.xz &&
tar xJf nim-$NIM_VERSION.tar.xz &&
cd nim-$NIM_VERSION &&
sh build.sh &&
bin/nim c -d:release koch &&
./koch boot -d:release &&
./koch nimble -d:release;
fi
- export PATH=/home/appveyor/binaries/nim-$NIM_VERSION/bin:~/.nimble/bin:$PATH
- cd /home/appveyor/projects/nimgen
on_finish:
- zip -r -q buildlogs-lin.zip ~/.nimble/pkgs
- appveyor PushArtifact buildlogs-lin.zip
- zip -r -q buildlogs-lin-pkgs.zip ~/.nimble/pkgs
- appveyor PushArtifact buildlogs-lin-pkgs.zip
- zip -r -q buildlogs-lin-projects.zip /home/appveyor/projects
- appveyor PushArtifact buildlogs-lin-projects.zip
cache:
- /home/appveyor/projects/nim-0.18.0.tar.xz
- /home/appveyor/binaries
build_script:
- nimble install -y

View file

@ -1,17 +1,17 @@
# Package
version = "0.3.0"
version = "0.5.1"
author = "genotrance"
description = "c2nim helper to simplify and automate the wrapping of C libraries"
license = "MIT"
bin = @["nimgen"]
srcDir = "src"
skipDirs = @["nimgen", "tests"]
skipDirs = @["nimgen", "tests", "web"]
# Dependencies
requires "nim >= 0.17.0", "c2nim >= 0.9.13", "regex >= 0.7.1"
requires "nim >= 0.19.0", "c2nim >= 0.9.14", "regex >= 0.10.0"
task test, "Test nimgen":
exec "nim c -r tests/rununittests.nim"

View file

@ -2,6 +2,4 @@ import os
import nimgen/runcfg
for i in commandLineParams():
if i != "-f":
runCfg(i)
runCli()

View file

@ -1,40 +1,47 @@
import os, ospaths, regex, strutils
import os, regex, strutils
when (NimMajor, NimMinor, NimPatch) < (0, 19, 9):
import ospaths
import external, file, fileops, gencore, globals
template relativePath(path: untyped): untyped =
path.multiReplace([(gOutput, ""), ("\\", "/"), ("//", "/")])
proc relativePath(path: string): string =
if gOutput.len() == 0:
result = path
else:
# multiReplace() bug - #9557
result = path.replace(gOutput, "")
return result.multiReplace([("\\", "/"), ("//", "/")])
proc c2nim*(fl, outfile: string, c2nimConfig: c2nimConfigObj) =
var file = search(fl)
if file.len() == 0:
return
echo " Generating " & outfile
# Remove static inline function bodies
removeStatic(file)
fixFuncProtos(file)
echo "Generating " & outfile
var cfile = file
if c2nimConfig.preprocess:
cfile = "temp-$#.c" % [outfile.extractFilename()]
writeFile(cfile, runPreprocess(file, c2nimConfig.ppflags, c2nimConfig.flags, c2nimConfig.inline))
writeFileFlush(cfile, runPreprocess(file, c2nimConfig.ppflags, c2nimConfig.flags, c2nimConfig.inline))
elif c2nimConfig.ctags:
cfile = "temp-$#.c" % [outfile.extractFilename()]
writeFile(cfile, runCtags(file))
writeFileFlush(cfile, runCtags(file))
if c2nimConfig.removeBodies:
removeBodies(cfile)
if c2nimConfig.defines and (c2nimConfig.preprocess or c2nimConfig.ctags):
prepend(cfile, getDefines(file, c2nimConfig.inline))
removeStatic(cfile)
var
extflags = ""
passC = ""
outlib = ""
outpragma = ""
passC = "import ospaths, strutils\n"
passC = "import strutils\n"
passC &= """const sourcePath = currentSourcePath().split({'\\', '/'})[0..^2].join("/")""" & "\n"
@ -98,18 +105,18 @@ proc c2nim*(fl, outfile: string, c2nimConfig: c2nimConfigObj) =
removeFile(cfile)
except:
discard
else:
if c2nimConfig.removeBodies:
reAddBodies(cfile)
reAddStatic(cfile)
# Nim doesn't like {.cdecl.} for type proc()
freplace(outfile, re"(?m)(.*? = proc.*?)\{.cdecl.\}", "$#")
freplace(outfile, re"(?m)(.*? = proc.*?)\{.cdecl.\}", "$1")
freplace(outfile, " {.cdecl.})", ")")
# Include {.compile.} directives
for cpl in c2nimConfig.compile:
let fcpl = search(cpl)
if getFileInfo(fcpl).kind == pcFile:
prepend(outfile, compile(file=fcpl))
else:
prepend(outfile, compile(dir=fcpl))
prepend(outfile, compile(cpl, c2nimConfig.flags))
# Add any pragmas
if outpragma != "":
@ -122,6 +129,3 @@ proc c2nim*(fl, outfile: string, c2nimConfig: c2nimConfigObj) =
# Add dynamic library
if outlib != "":
prepend(outfile, outlib)
# Add back static functions for compilation
reAddStatic(file)

View file

@ -1,4 +1,4 @@
import os, osproc, regex, ropes, streams, strutils
import os, osproc, regex, streams, strutils
import globals
@ -6,26 +6,25 @@ proc sanitizePath*(path: string): string =
path.multiReplace([("\\", "/"), ("//", "/")])
proc execProc*(cmd: string): string =
result = ""
var
p = startProcess(cmd, options = {poStdErrToStdOut, poUsePath, poEvalCommand})
var ret: int
outp = outputStream(p)
line = newStringOfCap(120).TaintedString
while true:
if outp.readLine(line):
result.add(line)
result.add("\n")
elif not running(p): break
var x = p.peekExitCode()
if x != 0:
echo "Command failed: " & $x
(result, ret) = execCmdEx(cmd)
if ret != 0:
echo "Command failed: " & $ret
echo cmd
echo result
quit(1)
proc execAction*(cmd: string): string =
var ccmd = ""
when defined(Windows):
ccmd = "cmd /c " & cmd.replace("/", "\\")
when defined(Linux) or defined(MacOSX):
ccmd = "bash -c '" & cmd & "'"
echo "Running '" & ccmd[0..<min(64, len(ccmd))] & "'"
return execProc(ccmd)
proc extractZip*(zipfile: string) =
var cmd = "unzip -o $#"
if defined(Windows):
@ -44,9 +43,10 @@ proc downloadUrl*(url: string) =
file = url.extractFilename()
ext = file.splitFile().ext.toLowerAscii()
var cmd = "curl $# -o $#"
if defined(Windows):
cmd = "powershell wget $# -OutFile $#"
var cmd = if defined(Windows):
"powershell [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; wget $# -OutFile $#"
else:
"curl -L $# -o $#"
if not (ext == ".zip" and fileExists(gOutput/file)):
echo "Downloading " & file
@ -55,53 +55,67 @@ proc downloadUrl*(url: string) =
if ext == ".zip":
extractZip(file)
proc gitReset*() =
echo "Resetting Git repo"
setCurrentDir(gOutput)
template setGitDir() =
setCurrentDir(gGitOutput)
defer: setCurrentDir(gProjectDir)
discard execProc("git reset --hard HEAD")
proc gitReset*() =
echo "Resetting " & gGitOutput
setGitDir()
let cmd = "git reset --hard"
while execCmdEx(cmd)[0].contains("Permission denied"):
sleep(1000)
echo " Retrying ..."
proc gitCheckout*(file: string) =
echo " Resetting " & file
echo "Resetting " & file
setCurrentDir(gOutput)
defer: setCurrentDir(gProjectDir)
setGitDir()
discard execProc("git checkout $#" % file.replace(gOutput & "/", ""))
let cmd = "git checkout $#" % file.replace(gGitOutput & "/", "")
while execCmdEx(cmd)[0].contains("Permission denied"):
sleep(500)
echo " Retrying ..."
proc gitPull() =
if gGitCheckout.len() != 0:
echo "Checking out " & gGitCheckout
discard execProc("git pull --tags origin master")
discard execProc("git checkout " & gGitCheckout)
gGitCheckout = ""
else:
echo "Pulling repository"
discard execProc("git pull --depth=1 origin master")
proc gitRemotePull*(url: string, pull=true) =
if dirExists(gOutput/".git"):
if dirExists(gGitOutput/".git"):
if pull:
gitReset()
return
setCurrentDir(gOutput)
defer: setCurrentDir(gProjectDir)
setGitDir()
echo "Setting up Git repo"
echo "Setting up Git repo: " & url
discard execProc("git init .")
discard execProc("git remote add origin " & url)
if pull:
echo "Checking out artifacts"
discard execProc("git pull --depth=1 origin master")
gitPull()
proc gitSparseCheckout*(plist: string) =
let sparsefile = ".git/info/sparse-checkout"
if fileExists(gOutput/sparsefile):
if fileExists(gGitOutput/sparsefile):
gitReset()
return
setCurrentDir(gOutput)
defer: setCurrentDir(gProjectDir)
setGitDir()
discard execProc("git config core.sparsecheckout true")
writeFile(sparsefile, plist)
echo "Checking out artifacts"
discard execProc("git pull --depth=1 origin master")
gitPull()
proc runPreprocess*(file, ppflags, flags: string, inline: bool): string =
var
@ -116,7 +130,7 @@ proc runPreprocess*(file, ppflags, flags: string, inline: bool): string =
# Include content only from file
var
rdata: Rope
rdata: seq[string] = @[]
start = false
sfile = file.sanitizePath
@ -136,9 +150,9 @@ proc runPreprocess*(file, ppflags, flags: string, inline: bool): string =
line.multiReplace([("_Noreturn", ""), ("(())", ""), ("WINAPI", ""),
("__attribute__", ""), ("extern \"C\"", "")])
.replace(re"\(\([_a-z]+?\)\)", "")
.replace(re"\(\(__format__[\s]*\(__[gnu_]*printf__, [\d]+, [\d]+\)\)\);", ";") & "\n"
.replace(re"\(\(__format__[\s]*\(__[gnu_]*printf__, [\d]+, [\d]+\)\)\);", ";")
)
return $rdata
return rdata.join("\n")
proc runCtags*(file: string): string =
var

View file

@ -1,4 +1,7 @@
import os, ospaths, pegs, regex, strutils, tables
import os, pegs, regex, strutils, tables
when (NimMajor, NimMinor, NimPatch) < (0, 19, 9):
import ospaths
import globals, external
@ -16,8 +19,7 @@ proc getNimout*(file: string, rename=true): string =
if gRenames.hasKey(file):
result = gRenames[file]
if not dirExists(parentDir(result)):
createDir(parentDir(result))
createDir(parentDir(result))
proc exclude*(file: string): bool =
for excl in gExcludes:
@ -82,6 +84,12 @@ proc openRetry*(file: string, mode: FileMode = fmRead): File =
except IOError:
sleep(100)
template writeFileFlush*(file, content: string): untyped =
let f = openRetry(file, fmWrite)
f.write(content)
f.flushFile()
f.close()
template withFile*(file: string, body: untyped): untyped =
if fileExists(file):
var f = openRetry(file)
@ -93,9 +101,7 @@ template withFile*(file: string, body: untyped): untyped =
body
if content != contentOrig:
f = openRetry(file, fmWrite)
write(f, content)
f.close()
writeFileFlush(file, content)
else:
echo "Missing file " & file

View file

@ -31,20 +31,25 @@ proc append*(file: string, data: string, search="") =
if idx != -1:
content = content[0..<idy] & data & content[idy..<content.len()]
proc freplace*(file: string, pattern: string, repl="") =
proc freplace*(file: string, pattern: string|Regex, repl="") =
withFile(file):
if pattern in content:
content = content.replace(pattern, repl)
content = content.replace(pattern, repl)
proc freplace*(file: string, pattern: Regex, repl="") =
proc move*(file: string, pattern: string|Regex, move: string) =
var tomove: seq[string] = @[]
withFile(file):
var m: RegexMatch
if content.find(pattern, m):
if "$#" in repl:
content = content.replace(pattern,
proc (m: RegexMatch, s: string): string = repl % s[m.group(0)[0]])
else:
content = content.replace(pattern, repl)
when pattern is string:
tomove.add(pattern)
when pattern is Regex:
var ms = content.findAll(pattern)
for i, m in ms:
tomove.add(content[m.group(0)[0]])
content = content.replace(pattern, "")
for i in tomove:
append(file, i, move)
proc comment*(file: string, pattern: string, numlines: string) =
let
@ -86,6 +91,36 @@ proc removeStatic*(filename: string) =
result.add(body.replace(re"(?m)^(.*\n?)", "//$1"))
)
proc removeBodies*(filename: string) =
## Replace function bodies with a semicolon and commented
## out body
withFile(filename):
content = content.replace(
re"(?m)(.*?\))(\s*\{(\s*?.*?$)*?[\n\r]\})",
proc (m: RegexMatch, s: string): string =
let funcDecl = s[m.group(0)[0]]
let body = s[m.group(1)[0]].strip()
result = ""
result.add("$#;" % [funcDecl])
result.add(body.replace(re"(?m)^(.*\n?)", "//$1"))
)
proc reAddBodies*(filename: string) =
## Uncomment out the body and remove the semicolon. Undoes
## removeBodies
withFile(filename):
content = content.replace(
re"(?m)(.*?\))(\s*\{(\s*?.*?$)*?[\n\r]\})",
proc (m: RegexMatch, s: string): string =
let funcDecl = s[m.group(0)[0]]
let body = s[m.group(1)[0]].strip()
result = ""
result.add("$# " % [funcDecl])
result.add(body.replace(re"(?m)^\/\/(.*\n?)", "$1"))
)
proc reAddStatic*(filename: string) =
## Uncomment out the body and remove the semicolon. Undoes
## removeStatic

View file

@ -4,38 +4,53 @@ import file, globals
proc addEnv*(str: string): string =
var newStr = str
for pair in envPairs():
try:
newStr = newStr % [pair.key, pair.value.string]
except ValueError:
# Ignore if there are no values to replace. We
# want to continue anyway
discard
try:
if "$output" in newStr or "${output}" in newStr:
newStr = newStr % ["output", gOutput]
except ValueError:
# Ignore if there are no values to replace. We
# want to continue anyway
discard
# if there are still format args, print a warning
if newStr.contains("$") and not newStr.contains("$replace("):
echo "WARNING: \"", newStr, "\" still contains an uninterpolated value!"
for pair in envPairs():
if pair.key.len() == 0:
continue
if ("$" & pair.key) in newStr or ("${" & pair.key & "}") in newStr:
newStr = newStr % [pair.key, pair.value.string]
return newStr
proc compile*(dir="", file=""): string =
proc fcompile(file: string): string =
return "{.compile: \"$#\".}" % file.replace("\\", "/")
proc compile*(cpl, flags: string): string =
var data = ""
if dir != "" and dirExists(dir):
for f in walkFiles(dir / "*.c"):
proc fcompile(file: string): string =
let fn = file.splitFile().name
var
ufn = fn
uniq = 1
while ufn in gCompile:
ufn = fn & $uniq
uniq += 1
gCompile.add(ufn)
if fn == ufn:
return "{.compile: \"$#\".}" % file.replace("\\", "/")
else:
return "{.compile: (\"../$#\", \"$#.o\").}" % [file.replace("\\", "/"), ufn]
proc dcompile(dir: string) =
for f in walkFiles(dir):
data &= fcompile(f) & "\n"
if file != "" and fileExists(file):
data &= fcompile(file) & "\n"
if cpl.contains("*") or cpl.contains("?"):
dcompile(cpl)
else:
let fcpl = search(cpl)
if getFileInfo(fcpl).kind == pcFile:
data &= fcompile(fcpl) & "\n"
elif getFileInfo(fcpl).kind == pcDir:
if flags.contains("cpp"):
for i in @["*.C", "*.cpp", "*.c++", "*.cc", "*.cxx"]:
dcompile(fcpl / i)
else:
dcompile(fcpl / "*.c")
return data
@ -87,7 +102,6 @@ proc getDefines*(file: string, inline=false): string =
for incl in incls:
let sincl = search(incl)
if sincl != "":
echo "Inlining " & sincl
result &= getDefines(sincl)
withFile(file):
for def in content.findAll(re"(?m)^(\s*#\s*define\s+[\w\d_]+\s+[\d\-.xf]+)(?:\r|//|/*).*?$"):

View file

@ -7,25 +7,32 @@ const
defaultCppCompiler* = "g++"
var
gDoneRecursive*: seq[string] = @[]
gDoneInline*: seq[string] = @[]
gProjectDir* = ""
# Config
gConfig*: Config
gFilter* = ""
gQuotes* = true
gCppCompiler* = getEnv(cppCompilerEnv, defaultCCompiler)
gCCompiler* = getEnv(cCompilerEnv, defaultCppCompiler)
gOutput* = ""
gIncludes*: seq[string] = @[]
gExcludes*: seq[string] = @[]
gIncludes*: seq[string] = @[]
gRenames* = initTable[string, string]()
gWildcards* = newConfig()
# n.global
gOutput* = "."
gQuotes* = true
gFilter* = ""
gCppCompiler* = getEnv(cppCompilerEnv, defaultCCompiler)
gCCompiler* = getEnv(cCompilerEnv, defaultCppCompiler)
# State tracking
gGitCheckout* = ""
gGitOutput* = ""
gProjectDir* = ""
gCompile*: seq[string] = @[]
gDoneInline*: seq[string] = @[]
gDoneRecursive*: seq[string] = @[]
type
c2nimConfigObj* = object
flags*, ppflags*: string
recurse*, inline*, preprocess*, ctags*, defines*: bool
recurse*, inline*, preprocess*, removeBodies*, ctags*, defines*: bool
dynlib*, compile*, pragma*: seq[string]
const gDoc* = """

View file

@ -6,18 +6,19 @@ proc `[]`*(table: OrderedTableRef[string, string], key: string): string =
## Gets table values with env vars inserted
tables.`[]`(table, key).addEnv
proc getKey(ukey: string): tuple[key: string, val: bool] =
var kv = ukey.replace(re"\..*", "").split("-", 1)
proc getKey(ukey: string, section = false): tuple[key: string, val: bool] =
var kv = if not section: ukey.replace(re"\..*", "").split("-", 1) else: ukey.split("-", 1)
if kv.len() == 1:
kv.add("")
if kv[1] == "":
return (kv[0], true)
for ostyp in kv[1].split(","):
for ostyp in kv[1].split("-"):
if (ostyp == "win" and defined(Windows)) or
(ostyp == "lin" and defined(Linux)) or
((ostyp == "osx" or ostyp == "mac") and defined(MacOSX)):
((ostyp == "osx" or ostyp == "mac") and defined(MacOSX)) or
(ostyp == "unix" and (defined(Linux) or defined(MacOSX))):
return (kv[0], true)
return (kv[0], false)
@ -26,6 +27,7 @@ proc runFile*(file: string, cfgin: OrderedTableRef = newOrderedTable[string, str
var
cfg = cfgin
sfile = search(file)
nowildcard = false
if sfile in gDoneRecursive:
return
@ -34,16 +36,24 @@ proc runFile*(file: string, cfgin: OrderedTableRef = newOrderedTable[string, str
echo "Processing " & sfile
gDoneRecursive.add(sfile)
for pattern in gWildcards.keys():
var m: RegexMatch
let pat = pattern.replace(".", "\\.").replace("*", ".*").replace("?", ".?")
if file.find(toPattern(pat), m):
echo " Appending keys for wildcard " & pattern
for key in gWildcards[pattern].keys():
cfg[key & "." & pattern] = gWildcards[pattern][key]
for act in cfg.keys():
let (action, val) = getKey(act)
if val == true and action == "nowildcard" and cfg[act] == "true":
nowildcard = true
break
if not nowildcard:
for pattern in gWildcards.keys():
var m: RegexMatch
let pat = pattern.replace(".", "\\.").replace("*", ".*").replace("?", ".?")
if file.find(toPattern(pat), m):
echo " Appending keys for wildcard " & pattern
for key in gWildcards[pattern].keys():
cfg[key & "." & pattern] = gWildcards[pattern][key]
var
srch = ""
rgx = ""
c2nimConfig = c2nimConfigObj(
flags: "--stdcall", ppflags: "",
@ -57,14 +67,14 @@ proc runFile*(file: string, cfgin: OrderedTableRef = newOrderedTable[string, str
if action == "create":
echo "Creating " & file
createDir(file.splitPath().head)
writeFile(file, cfg[act])
writeFileFlush(file, cfg[act])
if file in gExcludes:
gExcludes.delete(gExcludes.find(file))
sfile = search(file)
sfile = file
gDoneRecursive.add(sfile)
elif action in @["prepend", "append", "replace", "comment",
"rename", "compile", "dynlib", "pragma",
"pipe"] and sfile != "":
elif action in @["prepend", "append", "replace", "move", "comment",
"rename", "compile", "dynlib", "pragma", "pipe"] and
sfile != "":
if action == "prepend":
if srch != "":
prepend(sfile, cfg[act], cfg[srch])
@ -78,6 +88,13 @@ proc runFile*(file: string, cfgin: OrderedTableRef = newOrderedTable[string, str
elif action == "replace":
if srch != "":
freplace(sfile, cfg[srch], cfg[act])
elif rgx != "":
freplace(sfile, toPattern(cfg[rgx]), cfg[act])
elif action == "move":
if srch != "":
move(sfile, cfg[srch], cfg[act])
elif rgx != "":
move(sfile, toPattern(cfg[rgx]), cfg[act])
elif action == "comment":
if srch != "":
comment(sfile, cfg[srch], cfg[act])
@ -92,8 +109,11 @@ proc runFile*(file: string, cfgin: OrderedTableRef = newOrderedTable[string, str
elif action == "pipe":
pipe(sfile, cfg[act])
srch = ""
rgx = ""
elif action == "search":
srch = act
elif action == "regex":
rgx = act
if file.splitFile().ext != ".nim":
var
@ -110,6 +130,8 @@ proc runFile*(file: string, cfgin: OrderedTableRef = newOrderedTable[string, str
c2nimConfig.inline = true
elif action == "preprocess":
c2nimConfig.preprocess = true
elif action == "removeBodies":
c2nimConfig.removeBodies = true
elif action == "ctags":
c2nimConfig.ctags = true
elif action == "defines":
@ -127,35 +149,62 @@ proc runFile*(file: string, cfgin: OrderedTableRef = newOrderedTable[string, str
echo "Cannot use recurse and inline simultaneously"
quit(1)
if not noprocess:
let outfile = getNimout(sfile)
c2nim(file, outfile, c2nimConfig)
removeStatic(sfile)
fixFuncProtos(sfile)
if c2nimConfig.recurse:
var
cfg = newOrderedTable[string, string]()
incls = getIncls(sfile)
incout = ""
let outfile = getNimout(sfile)
var incout = ""
if c2nimConfig.recurse or c2nimConfig.inline:
var
cfg = newOrderedTable[string, string]()
incls = getIncls(sfile)
for name, value in c2nimConfig.fieldPairs:
when value is string:
cfg[name] = value
when value is bool:
cfg[name] = $value
for name, value in c2nimConfig.fieldPairs:
when value is string:
cfg[name] = value
when value is bool:
cfg[name] = $value
for i in c2nimConfig.dynlib:
cfg["dynlib." & i] = i
for i in c2nimConfig.dynlib:
cfg["dynlib." & i] = i
for inc in incls:
runFile(inc, cfg)
if c2nimConfig.inline:
cfg["noprocess"] = "true"
for inc in incls:
runFile(inc, cfg)
if c2nimConfig.recurse:
incout &= "import $#\n" % inc.search().getNimout()[0 .. ^5]
if incout.len() != 0:
prepend(outfile, incout)
if not noprocess:
c2nim(file, outfile, c2nimConfig)
if c2nimConfig.recurse and incout.len() != 0:
prepend(outfile, incout)
if reset:
gitCheckout(sfile)
proc setOutputDir(dir: string) =
gOutput = dir.sanitizePath
if dirExists(gOutput):
if "-f" in commandLineParams():
try:
removeDir(gOutput)
except OSError:
echo "Directory in use: " & gOutput
quit(1)
else:
for f in walkFiles(gOutput/"*.nim"):
try:
removeFile(f)
except OSError:
echo "Unable to delete: " & f
quit(1)
createDir(gOutput)
gGitOutput = gOutput
proc runCfg*(cfg: string) =
if not fileExists(cfg):
echo "Config doesn't exist: " & cfg
@ -164,104 +213,199 @@ proc runCfg*(cfg: string) =
gProjectDir = parentDir(cfg.expandFilename()).sanitizePath
gConfig = loadConfig(cfg)
gCppCompiler = getEnv(cppCompilerEnv, defaultCppCompiler).quoteShell
gCCompiler = getEnv(cCompilerEnv, defaultCCompiler).quoteShell
gGitOutput = gOutput
if gConfig.hasKey("n.global"):
if gConfig["n.global"].hasKey("output"):
gOutput = gConfig["n.global"]["output"].sanitizePath
if dirExists(gOutput):
if "-f" in commandLineParams():
try:
removeDir(gOutput)
except OSError:
echo "Directory in use: " & gOutput
quit(1)
else:
for f in walkFiles(gOutput/"*.nim"):
try:
removeFile(f)
except OSError:
echo "Unable to delete: " & f
quit(1)
createDir(gOutput)
if gConfig["n.global"].hasKey("cpp_compiler"):
gCppCompiler = gConfig["n.global"]["cpp_compiler"]
else:
# Reset on a per project basis
gCppCompiler = getEnv(cppCompilerEnv, defaultCppCompiler)
if gConfig["n.global"].hasKey("c_compiler"):
gCCompiler = gConfig["n.global"]["c_compiler"]
else:
# Reset on a per project basis
gCCompiler = getEnv(cCompilerEnv, defaultCCompiler)
gCppCompiler = gCppCompiler.quoteShell
gCCompiler = gCCompiler.quoteShell
if gConfig["n.global"].hasKey("filter"):
gFilter = gConfig["n.global"]["filter"]
if gConfig["n.global"].hasKey("quotes"):
if gConfig["n.global"]["quotes"] == "false":
gQuotes = false
if gConfig.hasKey("n.include"):
for inc in gConfig["n.include"].keys():
gIncludes.add(inc.addEnv().sanitizePath)
if gConfig.hasKey("n.exclude"):
for excl in gConfig["n.exclude"].keys():
gExcludes.add(excl.addEnv().sanitizePath)
if gConfig.hasKey("n.prepare"):
for prep in gConfig["n.prepare"].keys():
let (key, val) = getKey(prep)
if val == true:
let prepVal = gConfig["n.prepare"][prep]
if key == "download":
downloadUrl(prepVal)
elif key == "extract":
extractZip(prepVal)
elif key == "git":
gitRemotePull(prepVal)
elif key == "gitremote":
gitRemotePull(prepVal, false)
elif key == "gitsparse":
gitSparseCheckout(prepVal)
elif key == "execute":
discard execProc(prepVal)
elif key == "copy":
doCopy(prepVal)
if gConfig.hasKey("n.wildcard"):
var wildcard = ""
for wild in gConfig["n.wildcard"].keys():
let (key, val) = getKey(wild)
if val == true:
if key == "wildcard":
wildcard = gConfig["n.wildcard"][wild]
else:
gWildcards.setSectionKey(wildcard, wild,
gConfig["n.wildcard"][wild])
for file in gConfig.keys():
if file in @["n.global", "n.include", "n.exclude",
"n.prepare", "n.wildcard", "n.post"]:
for section in gConfig.keys():
let (sname, sval) = getKey(section, true)
if not sval:
continue
if file == "n.sourcefile":
for pattern in gConfig["n.sourcefile"].keys():
for file in walkFiles(pattern.addEnv):
runFile(file)
else:
runFile(file, gConfig[file])
case sname:
of "n.global":
for glob in gConfig[section].keys():
let (key, val) = getKey(glob)
if val == true:
let globVal = gConfig[section][glob]
case key:
of "output":
setOutputDir(globVal)
of "cpp_compiler":
gCppCompiler = globVal.quoteShell
of "c_compiler":
gCCompiler = globVal.quoteShell
of "filter":
gFilter = globVal
of "quotes":
if globVal == "false":
gQuotes = false
if gConfig.hasKey("n.post"):
for post in gConfig["n.post"].keys():
let (key, val) = getKey(post)
if val == true:
let postVal = gConfig["n.post"][post]
if key == "reset":
gitReset()
elif key == "execute":
discard execProc(postVal)
of "n.include":
for inc in gConfig[section].keys():
gIncludes.add(inc.addEnv().sanitizePath)
of "n.exclude":
for excl in gConfig[section].keys():
gExcludes.add(excl.addEnv().sanitizePath)
of "n.prepare":
for prep in gConfig[section].keys():
let (key, val) = getKey(prep)
if val == true:
let prepVal = gConfig[section][prep]
case key:
of "download":
downloadUrl(prepVal)
of "extract":
extractZip(prepVal)
of "gitcheckout":
gGitCheckout = prepVal
of "gitoutput":
gGitOutput = gOutput/prepVal
createDir(gGitOutput)
of "git":
gitRemotePull(prepVal)
of "gitremote":
gitRemotePull(prepVal, false)
of "gitsparse":
gitSparseCheckout(prepVal)
of "execute":
discard execAction(prepVal)
of "copy":
doCopy(prepVal)
of "n.wildcard":
var wildcard = ""
for wild in gConfig[section].keys():
let (key, val) = getKey(wild)
if val == true:
if key == "wildcard":
wildcard = gConfig[section][wild]
else:
gWildcards.setSectionKey(wildcard, wild,
gConfig[section][wild])
of "n.sourcefile":
for pattern in gConfig[section].keys():
for file in walkFiles(pattern.addEnv):
runFile(file)
of "n.post":
for post in gConfig[section].keys():
let (key, val) = getKey(post)
if val == true:
let postVal = gConfig[section][post]
case key:
of "gitoutput":
gGitOutput = gOutput/postVal
of "reset":
gitReset()
of "execute":
discard execAction(postVal)
else:
runFile(section, gConfig[section])
let gHelp = """
Nimgen is a helper for c2nim to simplify and automate the wrapping of C libraries
Usage:
nimgen [options] file.cfg|file.h ...
Params:
-C<compile> add compile entry *
-E<exclude> add n.exclude entry *
-F<flags> set c2nim flags *
-I<include> add n.include dir *
-O<outdir> set output directory
-P<ppflags> set preprocessor flags *
Options:
-c set ctags = true
-d set defines = true
-i set inline = true
-n set noprocess = true
-p set preprocess = true
-r set recurse = true
Editing:
-a<append> append string *
-e<prepend> prepend string *
-l<replace> replace string *
-o#lines comment X lines *
-s<search> search string *
-x<regex> regex search string *
* supports multiple instances
"""
proc runCli*() =
var
cfg = newOrderedTable[string, string]()
files: seq[string]
uniq = 1
gProjectDir = getCurrentDir().sanitizePath
for param in commandLineParams():
let flag = if param.len() <= 2: param else: param[0..<2]
if fileExists(param):
if param.splitFile().ext.toLowerAscii() == ".cfg":
runCfg(param)
else:
files.add(param)
elif flag == "-C":
cfg["compile." & $uniq] = param[2..^1]
elif flag == "-E":
gExcludes.add(param[2..^1].addEnv().sanitizePath)
elif flag == "-F":
if cfg.hasKey("flags"):
cfg["flags"] = cfg["flags"] & " " & param[2..^1]
else:
cfg["flags"] = param[2..^1]
elif flag == "-I":
gIncludes.add(param[2..^1].addEnv().sanitizePath)
elif flag == "-O":
setOutputDir(param[2..^1])
elif flag == "-P":
if cfg.hasKey("ppflags"):
cfg["ppflags"] = cfg["ppflags"] & " " & param[2..^1]
else:
cfg["ppflags"] = param[2..^1]
elif flag == "-c":
cfg["ctags"] = "true"
elif flag == "-d":
cfg["defines"] = "true"
elif flag == "-i":
cfg["inline"] = "true"
elif flag == "-n":
cfg["noprocess"] = "true"
elif flag == "-p":
cfg["preprocess"] = "true"
elif flag == "-r":
cfg["recurse"] = "true"
elif flag == "-a":
cfg["append." & $uniq] = param[2..^1]
elif flag == "-e":
cfg["prepend." & $uniq] = param[2..^1]
elif flag == "-l":
cfg["replace." & $uniq] = param[2..^1]
elif flag == "-o":
cfg["comment." & $uniq] = param[2..^1]
elif flag == "-s":
cfg["search." & $uniq] = param[2..^1]
elif flag == "-x":
cfg["regex." & $uniq] = param[2..^1]
elif param == "-h" or param == "-?" or param == "--help":
echo gHelp
quit(0)
uniq += 1
for file in files:
runFile(file, cfg)

View file

@ -1,52 +1,78 @@
import distros, ospaths, strutils
var
full = true
comps = @["libsvm", "nim7z", "nimarchive", "nimbass", "nimbigwig", "nimclipboard",
"nimfuzz", "nimpcre", "nimrax", "nimssl", "nimssh2"]
pygonly = false
comps = @["nim7z", #"nimarchive",
"nimbass", "nimbigwig",
"nimclipboard", "nimfuzzy", "nimmonocypher",
#"nimnuklear",
"nimpcre", "nimrax", "nimssl", "nimssh2",
"nimtess2"
]
let
gccver = staticExec("gcc --version").split("\n")[0].split(" ")[^1]
nimver = staticExec("nim -v").split("\n")[0].split(" ")[3]
if nimver >= "0.19.0" and (gccver >= "5.0.0" or detectOs(MacOSX)):
comps.add("nimfastText")
if detectOs(Windows):
comps.add("nimkerberos")
if not detectOs(MacOSX):
comps.add("nimzbar")
echo "Nim version: " & nimver
echo "GCC version: " & gccver
echo "Testing comps:"
for comp in comps:
echo " " & comp
if paramCount() > 2:
for i in 3 .. paramCount():
if paramStr(i) == "--full":
full = true
if paramStr(i) == "--pygonly":
pygonly = true
elif paramStr(i).len() > 10 and "--comps=" in paramStr(i)[0 ..< 8]:
comps = paramStr(i)[8 .. ^1].split(",")
for comp in comps:
if not dirExists(".."/comp):
withDir(".."):
exec "git clone --depth=1 https://github.com/genotrance/" & comp
if not pygonly:
if not dirExists(".."/comp):
withDir(".."):
exec "git clone --depth=1 https://github.com/genotrance/" & comp
exec "nimble uninstall -y " & comp, "", ""
withDir(".."/comp):
exec "git pull"
exec "nimble uninstall -y " & comp, "", ""
withDir(".."/comp):
exec "git pull"
if full:
rmDir(comp)
exec "nimble install -y"
exec "nimble test"
exec "nimble install -y"
exec "nimble test"
exec "nimble install -y"
exec "nimble test"
if dirExists("web"/comp):
rmDir("web"/comp)
when defined(windows):
if not pygonly:
if dirExists("web"/comp):
rmDir("web"/comp)
mkDir("web"/comp)
for file in listFiles(".."/comp/comp) & listFiles(".."/comp):
if file.splitFile().ext == ".nim":
cpFile(file, "web"/comp/extractFilename(file))
mkDir("web"/comp)
for file in listFiles(".."/comp/comp) & listFiles(".."/comp):
if file.splitFile().ext == ".nim":
cpFile(file, "web"/comp/extractFilename(file))
cpFile("web"/"nimdoc.cfg", "web"/comp/"nimdoc.cfg")
withDir("web"/comp):
for file in listFiles("."):
if file.splitFile().ext == ".nim":
exec "nim doc --git.url:. --index:on -o:" & file.changeFileExt("html") & " " & file
exec "pygmentize -f html -O full,linenos=1,anchorlinenos=True,lineanchors=L,style=vs -o " & file & ".html " & file
cpFile("web"/"nimdoc.cfg", "web"/comp/"nimdoc.cfg")
withDir("web"/comp):
for file in listFiles("."):
if file.splitFile().ext == ".nim":
if not pygonly:
exec "nim doc --git.url:. --index:on -o:" & file.changeFileExt("html") & " " & file
exec "pygmentize -f html -O full,linenos=1,anchorlinenos=True,lineanchors=L,style=vs -o " & file & ".html " & file
exec "nim buildIndex -o:index.html ."
rmFile("web"/comp/"nimdoc.cfg")
if not pygonly:
exec "nim buildIndex -o:index.html ."
rmFile("web"/comp/"nimdoc.cfg")

View file

@ -1,8 +1,10 @@
import os, osproc, strutils
proc main() =
var failures = 0
for file in walkFiles(currentSourcePath().splitPath().head / "unittests/*.nim"):
let (path, fname, ext) = file.splitFile()
if fname.startswith("test"):
discard execCmd "nim c -r " & file
failures += execCmd "nim c -r " & file
quit(failures)
main()

View file

@ -97,8 +97,6 @@ suite "test file ops":
dataDir.createDir()
setup:
if testfilename.existsFile():
removeFile(testfilename)
writeFile(testfilename, testFileContent)
################### Prepend #######################
@ -120,7 +118,7 @@ suite "test file ops":
test "pipe command into file":
when defined(windows):
pipe(testfilename, "(ECHO foo)>>$file")
pipe(testfilename, "ECHO foo")
testfilename.checkFile("foo")
else:
pipe(testfilename, "cat $file | grep 'this is text'")

1
web/CNAME Normal file
View file

@ -0,0 +1 @@
nimgen.genotrance.com

1401
web/nimdoc.cfg Normal file

File diff suppressed because it is too large Load diff