Merge branch 'master' of https://github.com/Araq/Nimrod into vm2
Conflicts: web/news.txt
This commit is contained in:
commit
b76729df1c
35 changed files with 1047 additions and 269 deletions
397
.gitignore
vendored
397
.gitignore
vendored
|
|
@ -63,7 +63,10 @@ examples/cross_calculator/android/tags
|
||||||
/examples/allany
|
/examples/allany
|
||||||
/examples/cairoex
|
/examples/cairoex
|
||||||
/examples/cgiex
|
/examples/cgiex
|
||||||
|
/examples/cgi/cgi_stacktrace
|
||||||
|
/examples/cgi/example
|
||||||
/examples/curlex
|
/examples/curlex
|
||||||
|
/examples/debugging
|
||||||
/examples/docstrings
|
/examples/docstrings
|
||||||
/examples/filterex
|
/examples/filterex
|
||||||
/examples/fizzbuzz
|
/examples/fizzbuzz
|
||||||
|
|
@ -89,6 +92,12 @@ examples/cross_calculator/android/tags
|
||||||
/examples/pythonex
|
/examples/pythonex
|
||||||
/examples/sdlex
|
/examples/sdlex
|
||||||
/examples/statcsv
|
/examples/statcsv
|
||||||
|
/examples/talk/dsl
|
||||||
|
/examples/talk/formatoptimizer
|
||||||
|
/examples/talk/hoisting
|
||||||
|
/examples/talk/lazyeval
|
||||||
|
/examples/talk/quasiquote
|
||||||
|
/examples/talk/tags
|
||||||
/examples/tclex
|
/examples/tclex
|
||||||
/examples/transff
|
/examples/transff
|
||||||
/examples/tunit
|
/examples/tunit
|
||||||
|
|
@ -96,10 +105,13 @@ examples/cross_calculator/android/tags
|
||||||
/examples/x11ex
|
/examples/x11ex
|
||||||
/lib/libnimrtl.dylib
|
/lib/libnimrtl.dylib
|
||||||
/lib/libserver.dylib
|
/lib/libserver.dylib
|
||||||
|
/lib/packages/docutils/highlite
|
||||||
/lib/pure/actors
|
/lib/pure/actors
|
||||||
/lib/pure/algorithm
|
/lib/pure/algorithm
|
||||||
/lib/pure/asyncio
|
/lib/pure/asyncio
|
||||||
/lib/pure/base64
|
/lib/pure/base64
|
||||||
|
/lib/pure/basic2d
|
||||||
|
/lib/pure/basic3d
|
||||||
/lib/pure/browsers
|
/lib/pure/browsers
|
||||||
/lib/pure/cgi
|
/lib/pure/cgi
|
||||||
/lib/pure/collections/sequtils
|
/lib/pure/collections/sequtils
|
||||||
|
|
@ -111,6 +123,7 @@ examples/cross_calculator/android/tags
|
||||||
/lib/pure/encodings
|
/lib/pure/encodings
|
||||||
/lib/pure/endians
|
/lib/pure/endians
|
||||||
/lib/pure/events
|
/lib/pure/events
|
||||||
|
/lib/pure/fsmonitor
|
||||||
/lib/pure/ftpclient
|
/lib/pure/ftpclient
|
||||||
/lib/pure/gentabs
|
/lib/pure/gentabs
|
||||||
/lib/pure/hashes
|
/lib/pure/hashes
|
||||||
|
|
@ -127,19 +140,23 @@ examples/cross_calculator/android/tags
|
||||||
/lib/pure/math
|
/lib/pure/math
|
||||||
/lib/pure/md5
|
/lib/pure/md5
|
||||||
/lib/pure/memfiles
|
/lib/pure/memfiles
|
||||||
|
/lib/pure/mersenne
|
||||||
/lib/pure/mimetypes
|
/lib/pure/mimetypes
|
||||||
/lib/pure/nimprof
|
/lib/pure/nimprof
|
||||||
|
/lib/pure/numeric
|
||||||
/lib/pure/oids
|
/lib/pure/oids
|
||||||
/lib/pure/os
|
/lib/pure/os
|
||||||
/lib/pure/osproc
|
/lib/pure/osproc
|
||||||
/lib/pure/parsecfg
|
/lib/pure/parsecfg
|
||||||
/lib/pure/parsecsv
|
/lib/pure/parsecsv
|
||||||
/lib/pure/parseopt
|
/lib/pure/parseopt
|
||||||
|
/lib/pure/parseopt2
|
||||||
/lib/pure/parsesql
|
/lib/pure/parsesql
|
||||||
/lib/pure/parseurl
|
/lib/pure/parseurl
|
||||||
/lib/pure/parseutils
|
/lib/pure/parseutils
|
||||||
/lib/pure/parsexml
|
/lib/pure/parsexml
|
||||||
/lib/pure/pegs
|
/lib/pure/pegs
|
||||||
|
/lib/pure/poly
|
||||||
/lib/pure/redis
|
/lib/pure/redis
|
||||||
/lib/pure/romans
|
/lib/pure/romans
|
||||||
/lib/pure/ropes
|
/lib/pure/ropes
|
||||||
|
|
@ -167,9 +184,9 @@ examples/cross_calculator/android/tags
|
||||||
/run.json
|
/run.json
|
||||||
/testresults.html
|
/testresults.html
|
||||||
/testresults.json
|
/testresults.json
|
||||||
/tests/caas/SymbolProcRun.*/
|
|
||||||
/tests/caas/absurd_nesting
|
/tests/caas/absurd_nesting
|
||||||
/tests/caas/completion_dot_syntax_main
|
/tests/caas/completion_dot_syntax_main
|
||||||
|
/tests/caasdriver
|
||||||
/tests/caas/forward_declarations
|
/tests/caas/forward_declarations
|
||||||
/tests/caas/idetools_api
|
/tests/caas/idetools_api
|
||||||
/tests/caas/imported
|
/tests/caas/imported
|
||||||
|
|
@ -178,6 +195,380 @@ examples/cross_calculator/android/tags
|
||||||
/tests/caas/issue_477_dynamic_dispatch
|
/tests/caas/issue_477_dynamic_dispatch
|
||||||
/tests/caas/its_full_of_procs
|
/tests/caas/its_full_of_procs
|
||||||
/tests/caas/main
|
/tests/caas/main
|
||||||
/tests/caasdriver
|
/tests/caas/SymbolProcRun.*/
|
||||||
/tools/nimgrep
|
/tests/ccg/tmissingbracket
|
||||||
|
/tests/compile/talias
|
||||||
|
/tests/compile/tambsym2
|
||||||
|
/tests/compile/tarrindx
|
||||||
|
/tests/compile/tassign
|
||||||
|
/tests/compile/tbindoverload
|
||||||
|
/tests/compile/tcan_alias_generic
|
||||||
|
/tests/compile/tcan_alias_specialised_generic
|
||||||
|
/tests/compile/tcan_inherit_generic
|
||||||
|
/tests/compile/tcan_specialise_generic
|
||||||
|
/tests/compile/tccgen1
|
||||||
|
/tests/compile/tclosure4
|
||||||
|
/tests/compile/tclosurebug2
|
||||||
|
/tests/compile/tcmdline
|
||||||
|
/tests/compile/tcodegenbug1
|
||||||
|
/tests/compile/tcolonisproc
|
||||||
|
/tests/compile/tcolors
|
||||||
|
/tests/compile/tcommontype
|
||||||
|
/tests/compile/tcompiles
|
||||||
|
/tests/compile/tcomputedgoto
|
||||||
|
/tests/compile/tconsteval
|
||||||
|
/tests/compile/tconstraints
|
||||||
|
/tests/compile/tconvcolors
|
||||||
|
/tests/compile/tcputime
|
||||||
|
/tests/compile/tdefaultprocparam
|
||||||
|
/tests/compile/tdictdestruct
|
||||||
|
/tests/compile/tdiscardable
|
||||||
|
/tests/compile/tdllvar
|
||||||
|
/tests/compile/tdumpast
|
||||||
|
/tests/compile/tdumpast2
|
||||||
|
/tests/compile/techo
|
||||||
|
/tests/compile/teffects1
|
||||||
|
/tests/compile/temptyecho
|
||||||
|
/tests/compile/tendian
|
||||||
|
/tests/compile/tenum
|
||||||
|
/tests/compile/tenum2
|
||||||
|
/tests/compile/tenum3
|
||||||
|
/tests/compile/teval1
|
||||||
|
/tests/compile/texport
|
||||||
|
/tests/compile/tfib
|
||||||
|
/tests/compile/tforwardgeneric
|
||||||
|
/tests/compile/tforwty
|
||||||
|
/tests/compile/tforwty2
|
||||||
|
/tests/compile/tgeneric
|
||||||
|
/tests/compile/tgeneric2
|
||||||
|
/tests/compile/tgeneric3
|
||||||
|
/tests/compile/tgeneric4
|
||||||
|
/tests/compile/tgenericmatcher
|
||||||
|
/tests/compile/tgenericmatcher2
|
||||||
|
/tests/compile/tgenericprocvar
|
||||||
|
/tests/compile/tgenericprop
|
||||||
|
/tests/compile/tgenericrefs
|
||||||
|
/tests/compile/tgenerictmpl
|
||||||
|
/tests/compile/tgenericvariant
|
||||||
|
/tests/compile/tgensymgeneric
|
||||||
|
/tests/compile/tgetstartmilsecs
|
||||||
|
/tests/compile/tglobalforvar
|
||||||
|
/tests/compile/thallo
|
||||||
|
/tests/compile/theaproots
|
||||||
|
/tests/compile/thexrange
|
||||||
|
/tests/compile/thygienictempl
|
||||||
|
/tests/compile/tident
|
||||||
|
/tests/compile/timplicititems
|
||||||
|
/tests/compile/timplictderef
|
||||||
|
/tests/compile/tinheritref
|
||||||
|
/tests/compile/tio
|
||||||
|
/tests/compile/tircbot
|
||||||
|
/tests/compile/titer
|
||||||
|
/tests/compile/titer2
|
||||||
|
/tests/compile/titer_no_tuple_unpack
|
||||||
|
/tests/compile/titerovl
|
||||||
|
/tests/compile/tlastmod
|
||||||
|
/tests/compile/tlinearscanend
|
||||||
|
/tests/compile/tloops
|
||||||
|
/tests/compile/tmacro1
|
||||||
|
/tests/compile/tmacro2
|
||||||
|
/tests/compile/tmacroaspragma
|
||||||
|
/tests/compile/tmacrostmt
|
||||||
|
/tests/compile/tmandelbrot
|
||||||
|
/tests/compile/tmarshal
|
||||||
|
/tests/compile/tmath
|
||||||
|
/tests/compile/tmatrix1
|
||||||
|
/tests/compile/tmatrix2
|
||||||
|
/tests/compile/tmongo
|
||||||
|
/tests/compile/tnamedparamanonproc
|
||||||
|
/tests/compile/tnamedparams
|
||||||
|
/tests/compile/tnestedproc
|
||||||
|
/tests/compile/tnew
|
||||||
|
/tests/compile/tnewsets
|
||||||
|
/tests/compile/tnewuns
|
||||||
|
/tests/compile/tnoargopenarray
|
||||||
|
/tests/compile/tnoforward
|
||||||
|
/tests/compile/tobjconstr2
|
||||||
|
/tests/compile/tobjcov
|
||||||
|
/tests/compile/tobject2
|
||||||
|
/tests/compile/tobject3
|
||||||
|
/tests/compile/tobjects
|
||||||
|
/tests/compile/toop
|
||||||
|
/tests/compile/toptions
|
||||||
|
/tests/compile/tos
|
||||||
|
/tests/compile/toverprc
|
||||||
|
/tests/compile/tparedef
|
||||||
|
/tests/compile/tparscfg
|
||||||
|
/tests/compile/tparsefloat
|
||||||
|
/tests/compile/tparsopt
|
||||||
|
/tests/compile/tposix
|
||||||
|
/tests/compile/tprep
|
||||||
|
/tests/compile/tprocvars
|
||||||
|
/tests/compile/tpush
|
||||||
|
/tests/compile/tquicksort
|
||||||
|
/tests/compile/tquit
|
||||||
|
/tests/compile/tradix
|
||||||
|
/tests/compile/treadln
|
||||||
|
/tests/compile/treadx
|
||||||
|
/tests/compile/trecmod
|
||||||
|
/tests/compile/trecmod2
|
||||||
|
/tests/compile/trectuple
|
||||||
|
/tests/compile/trectuples
|
||||||
|
/tests/compile/tredef
|
||||||
|
/tests/compile/trepr
|
||||||
|
/tests/compile/tsecondarrayproperty
|
||||||
|
/tests/compile/tseq2
|
||||||
|
/tests/compile/tseqcon2
|
||||||
|
/tests/compile/tshadow_magic_type
|
||||||
|
/tests/compile/tsizeof
|
||||||
|
/tests/compile/tslurp
|
||||||
|
/tests/compile/tsockets
|
||||||
|
/tests/compile/tsortcall
|
||||||
|
/tests/compile/tspecialised_is_equivalent
|
||||||
|
/tests/compile/tstrace
|
||||||
|
/tests/compile/tstrdesc
|
||||||
|
/tests/compile/tstrdist
|
||||||
|
/tests/compile/tstreams
|
||||||
|
/tests/compile/tstrset
|
||||||
|
/tests/compile/tstrtabs
|
||||||
|
/tests/compile/ttableconstr
|
||||||
|
/tests/compile/ttempl
|
||||||
|
/tests/compile/ttempl3
|
||||||
|
/tests/compile/ttempl4
|
||||||
|
/tests/compile/ttempl5
|
||||||
|
/tests/compile/ttemplreturntype
|
||||||
|
/tests/compile/tthread_generic
|
||||||
|
/tests/compile/ttime
|
||||||
|
/tests/compile/ttuple1
|
||||||
|
/tests/compile/ttypeclasses
|
||||||
|
/tests/compile/ttypeconverter1
|
||||||
|
/tests/compile/tuserpragma
|
||||||
|
/tests/compile/tvoid
|
||||||
|
/tests/compile/twalker
|
||||||
|
/tests/compile/typalias
|
||||||
|
/tests/dll/client
|
||||||
|
/tests/gc/closureleak
|
||||||
|
/tests/gc/cycleleak
|
||||||
|
/tests/gc/gcbench
|
||||||
|
/tests/gc/gcleak
|
||||||
|
/tests/gc/gcleak2
|
||||||
|
/tests/gc/gcleak3
|
||||||
|
/tests/gc/gctest
|
||||||
|
/tests/gc/weakrefs
|
||||||
|
/tests/manyloc/argument_parser/ex_wget
|
||||||
|
/tests/manyloc/nake/nakefile
|
||||||
|
/tests/manyloc/packages/noconflicts
|
||||||
|
/tests/manyloc/standalone/barebone
|
||||||
|
/tests/patterns/targlist
|
||||||
|
/tests/patterns/tcse
|
||||||
|
/tests/patterns/thoist
|
||||||
|
/tests/patterns/tmatrix
|
||||||
|
/tests/patterns/tnoalias
|
||||||
|
/tests/patterns/tnoendlessrec
|
||||||
|
/tests/patterns/tor
|
||||||
|
/tests/patterns/tpartial
|
||||||
|
/tests/patterns/tstar
|
||||||
|
/tests/patterns/tstmtlist
|
||||||
|
/tests/reject/t99bott
|
||||||
|
/tests/reject/tcheckedfield1
|
||||||
|
/tests/reject/tdeprecated
|
||||||
|
/tests/reject/tdisallowif
|
||||||
|
/tests/reject/tuninit1
|
||||||
|
/tests/rodfiles/aconv
|
||||||
|
/tests/rodfiles/bconv
|
||||||
|
/tests/rodfiles/bmethods
|
||||||
|
/tests/rodfiles/bmethods2
|
||||||
|
/tests/rodfiles/deada
|
||||||
|
/tests/rodfiles/deada2
|
||||||
|
/tests/rodfiles/hallo
|
||||||
|
/tests/rodfiles/hallo2
|
||||||
|
/tests/rodfiles/tgeneric1
|
||||||
|
/tests/rodfiles/tgeneric2
|
||||||
|
/tests/run/tack
|
||||||
|
/tests/run/tactiontable
|
||||||
|
/tests/run/tambsym2
|
||||||
|
/tests/run/tambsys
|
||||||
|
/tests/run/tanontuples
|
||||||
|
/tests/run/tarray
|
||||||
|
/tests/run/tarray2
|
||||||
|
/tests/run/tarray3
|
||||||
|
/tests/run/tarraycons
|
||||||
|
/tests/run/tassert
|
||||||
|
/tests/run/tastoverload1
|
||||||
|
/tests/run/tasynciossl
|
||||||
|
/tests/run/tasyncudp
|
||||||
|
/tests/run/tbind1
|
||||||
|
/tests/run/tbind3
|
||||||
|
/tests/run/tbintre2
|
||||||
|
/tests/run/tbintree
|
||||||
|
/tests/run/tborrow
|
||||||
|
/tests/run/tbug499771
|
||||||
|
/tests/run/tbug511622
|
||||||
|
/tests/run/tcase_setconstr
|
||||||
|
/tests/run/tcasestm
|
||||||
|
/tests/run/tcgbug
|
||||||
|
/tests/run/tclosure2
|
||||||
|
/tests/run/tclosure3
|
||||||
|
/tests/run/tcnstseq
|
||||||
|
/tests/run/tcnstseq2
|
||||||
|
/tests/run/tcnstseq3
|
||||||
|
/tests/run/tconcat
|
||||||
|
/tests/run/tconstr2
|
||||||
|
/tests/run/tcontinue
|
||||||
|
/tests/run/tcontinuexc
|
||||||
|
/tests/run/tcopy
|
||||||
|
/tests/run/tcountup
|
||||||
|
/tests/run/tcritbits
|
||||||
|
/tests/run/tcurrncy
|
||||||
|
/tests/run/tdestructor
|
||||||
|
/tests/run/tdrdobbs_examples
|
||||||
|
/tests/run/temit
|
||||||
|
/tests/run/tenumhole
|
||||||
|
/tests/run/tenumitems
|
||||||
|
/tests/run/teventemitter
|
||||||
|
/tests/run/tevents
|
||||||
|
/tests/run/texceptions
|
||||||
|
/tests/run/texcpt1
|
||||||
|
/tests/run/texcsub
|
||||||
|
/tests/run/texplicitgeneric1
|
||||||
|
/tests/run/tfieldindex
|
||||||
|
/tests/run/tfielditerator
|
||||||
|
/tests/run/tfielditerator2
|
||||||
|
/tests/run/tfilter
|
||||||
|
/tests/run/tfinally
|
||||||
|
/tests/run/tfinally2
|
||||||
|
/tests/run/tfinally3
|
||||||
|
/tests/run/tfinalobj
|
||||||
|
/tests/run/tfloat1
|
||||||
|
/tests/run/tfloat2
|
||||||
|
/tests/run/tfloat3
|
||||||
|
/tests/run/tformat
|
||||||
|
/tests/run/tfriends
|
||||||
|
/tests/run/tgenericassign
|
||||||
|
/tests/run/tgenericassigntuples
|
||||||
|
/tests/run/tgenericconverter
|
||||||
|
/tests/run/tgenericprocvar
|
||||||
|
/tests/run/tgenerics1
|
||||||
|
/tests/run/tgensym
|
||||||
|
/tests/run/tglobal
|
||||||
|
/tests/run/thashes
|
||||||
|
/tests/run/thexlit
|
||||||
|
/tests/run/thintoff
|
||||||
|
/tests/run/tidgen
|
||||||
|
/tests/run/tindent1
|
||||||
|
/tests/run/tinit
|
||||||
|
/tests/run/tinterf
|
||||||
|
/tests/run/tints
|
||||||
|
/tests/run/tisopr
|
||||||
|
/tests/run/titer3
|
||||||
|
/tests/run/titer5
|
||||||
|
/tests/run/titer6
|
||||||
|
/tests/run/titer7
|
||||||
|
/tests/run/titer8
|
||||||
|
/tests/run/titer9
|
||||||
|
/tests/run/titerslice
|
||||||
|
/tests/run/titervaropenarray
|
||||||
|
/tests/run/tkoeniglookup
|
||||||
|
/tests/run/tlet
|
||||||
|
/tests/run/tlists
|
||||||
|
/tests/run/tlocals
|
||||||
|
/tests/run/tlowhigh
|
||||||
|
/tests/run/tmacro2
|
||||||
|
/tests/run/tmacro3
|
||||||
|
/tests/run/tmacro4
|
||||||
|
/tests/run/tmacros1
|
||||||
|
/tests/run/tmath
|
||||||
|
/tests/run/tmatrix
|
||||||
|
/tests/run/tmemoization
|
||||||
|
/tests/run/tmethods1
|
||||||
|
/tests/run/tmixin
|
||||||
|
/tests/run/tmoditer
|
||||||
|
/tests/run/tmultim1
|
||||||
|
/tests/run/tmultim2
|
||||||
|
/tests/run/tmultim3
|
||||||
|
/tests/run/tmultim4
|
||||||
|
/tests/run/tmultim6
|
||||||
|
/tests/run/tnamedenumfields
|
||||||
|
/tests/run/tnestif
|
||||||
|
/tests/run/tnestprc
|
||||||
|
/tests/run/tnewderef
|
||||||
|
/tests/run/tnodeadlocks
|
||||||
|
/tests/run/tobjasgn
|
||||||
|
/tests/run/tobjconstr
|
||||||
|
/tests/run/tobject
|
||||||
|
/tests/run/tofopr
|
||||||
|
/tests/run/tonraise
|
||||||
|
/tests/run/toop1
|
||||||
|
/tests/run/topenarrayrepr
|
||||||
|
/tests/run/topenlen
|
||||||
|
/tests/run/toprprec
|
||||||
|
/tests/run/toverflw
|
||||||
|
/tests/run/toverflw2
|
||||||
|
/tests/run/toverl2
|
||||||
|
/tests/run/toverl3
|
||||||
|
/tests/run/toverwr
|
||||||
|
/tests/run/tovfint
|
||||||
|
/tests/run/tpatterns
|
||||||
|
/tests/run/tpegs
|
||||||
|
/tests/run/tpos
|
||||||
|
/tests/run/tprecedence
|
||||||
|
/tests/run/tprintf
|
||||||
|
/tests/run/tprocvar
|
||||||
|
/tests/run/tquotewords
|
||||||
|
/tests/run/tregex
|
||||||
|
/tests/run/treguse
|
||||||
|
/tests/run/trepr
|
||||||
|
/tests/run/treraise
|
||||||
|
/tests/run/tromans
|
||||||
|
/tests/run/tseqcon
|
||||||
|
/tests/run/tseqtuple
|
||||||
|
/tests/run/tsequtils
|
||||||
|
/tests/run/tsets
|
||||||
|
/tests/run/tsets2
|
||||||
|
/tests/run/tsidee2
|
||||||
|
/tests/run/tsidee3
|
||||||
|
/tests/run/tsimmeth
|
||||||
|
/tests/run/tsimplesort
|
||||||
|
/tests/run/tslices
|
||||||
|
/tests/run/tsortdev
|
||||||
|
/tests/run/tsplit
|
||||||
|
/tests/run/tstempl
|
||||||
|
/tests/run/tstmtexprs
|
||||||
|
/tests/run/tstrange
|
||||||
|
/tests/run/tstringinterp
|
||||||
|
/tests/run/tstrlits
|
||||||
|
/tests/run/tstrutil
|
||||||
|
/tests/run/tsubrange
|
||||||
|
/tests/run/tsubrange2
|
||||||
|
/tests/run/ttables
|
||||||
|
/tests/run/ttables2
|
||||||
|
/tests/run/ttoseq
|
||||||
|
/tests/run/ttypedesc1
|
||||||
|
/tests/run/tunhandledexc
|
||||||
|
/tests/run/tunidecode
|
||||||
|
/tests/run/tunittests
|
||||||
|
/tests/run/tuserassert
|
||||||
|
/tests/run/tvarargs_vs_generic
|
||||||
|
/tests/run/tvardecl
|
||||||
|
/tests/run/tvariantasgn
|
||||||
|
/tests/run/tvariantstack
|
||||||
|
/tests/run/tvarious1
|
||||||
|
/tests/run/tvarnums
|
||||||
|
/tests/run/tvarres1
|
||||||
|
/tests/run/tvarres2
|
||||||
|
/tests/run/tvartup
|
||||||
|
/tests/run/tvtable
|
||||||
|
/tests/run/twrongexc
|
||||||
|
/tests/run/txmlgen
|
||||||
|
/tests/run/txmltree
|
||||||
|
/tests/run/tzeroarray
|
||||||
|
/tests/system/helpers/readall_echo
|
||||||
|
/tests/system/io
|
||||||
/tests/system/params
|
/tests/system/params
|
||||||
|
/tests/tester
|
||||||
|
/tests/threads/tactors
|
||||||
|
/tests/threads/tactors2
|
||||||
|
/tests/threads/tthreadanalysis2
|
||||||
|
/tests/threads/tthreadanalysis3
|
||||||
|
/tests/threads/tthreadheapviolation1
|
||||||
|
/tools/nimgrep
|
||||||
|
|
|
||||||
|
|
@ -290,6 +290,7 @@ proc genCall(p: BProc, e: PNode, d: var TLoc) =
|
||||||
genNamedParamCall(p, e, d)
|
genNamedParamCall(p, e, d)
|
||||||
else:
|
else:
|
||||||
genPrefixCall(p, nil, e, d)
|
genPrefixCall(p, nil, e, d)
|
||||||
|
postStmtActions(p)
|
||||||
when false:
|
when false:
|
||||||
if d.s == onStack and containsGarbageCollectedRef(d.t): keepAlive(p, d)
|
if d.s == onStack and containsGarbageCollectedRef(d.t): keepAlive(p, d)
|
||||||
|
|
||||||
|
|
@ -303,6 +304,7 @@ proc genAsgnCall(p: BProc, le, ri: PNode, d: var TLoc) =
|
||||||
genNamedParamCall(p, ri, d)
|
genNamedParamCall(p, ri, d)
|
||||||
else:
|
else:
|
||||||
genPrefixCall(p, le, ri, d)
|
genPrefixCall(p, le, ri, d)
|
||||||
|
postStmtActions(p)
|
||||||
when false:
|
when false:
|
||||||
if d.s == onStack and containsGarbageCollectedRef(d.t): keepAlive(p, d)
|
if d.s == onStack and containsGarbageCollectedRef(d.t): keepAlive(p, d)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -921,7 +921,12 @@ proc genPragma(p: BProc, n: PNode) =
|
||||||
of wEmit: genEmit(p, it)
|
of wEmit: genEmit(p, it)
|
||||||
of wBreakpoint: genBreakPoint(p, it)
|
of wBreakpoint: genBreakPoint(p, it)
|
||||||
of wWatchpoint: genWatchpoint(p, it)
|
of wWatchpoint: genWatchpoint(p, it)
|
||||||
else: nil
|
of wInjectStmt:
|
||||||
|
var p = newProc(nil, p.module)
|
||||||
|
p.options = p.options - {optLineTrace, optStackTrace}
|
||||||
|
genStmts(p, it.sons[1])
|
||||||
|
p.module.injectStmt = p.s(cpsStmts)
|
||||||
|
else: discard
|
||||||
|
|
||||||
proc FieldDiscriminantCheckNeeded(p: BProc, asgn: PNode): bool =
|
proc FieldDiscriminantCheckNeeded(p: BProc, asgn: PNode): bool =
|
||||||
if optFieldCheck in p.options:
|
if optFieldCheck in p.options:
|
||||||
|
|
|
||||||
|
|
@ -289,6 +289,9 @@ proc genLineDir(p: BProc, t: PNode) =
|
||||||
linefmt(p, cpsStmts, "nimln($1, $2);$n",
|
linefmt(p, cpsStmts, "nimln($1, $2);$n",
|
||||||
line.toRope, t.info.quotedFilename)
|
line.toRope, t.info.quotedFilename)
|
||||||
|
|
||||||
|
proc postStmtActions(p: BProc) {.inline.} =
|
||||||
|
app(p.s(cpsStmts), p.module.injectStmt)
|
||||||
|
|
||||||
proc accessThreadLocalVar(p: BProc, s: PSym)
|
proc accessThreadLocalVar(p: BProc, s: PSym)
|
||||||
proc emulatedThreadVars(): bool {.inline.}
|
proc emulatedThreadVars(): bool {.inline.}
|
||||||
|
|
||||||
|
|
@ -1119,6 +1122,9 @@ proc newPostInitProc(m: BModule): BProc =
|
||||||
# little hack so that unique temporaries are generated:
|
# little hack so that unique temporaries are generated:
|
||||||
result.labels = 200_000
|
result.labels = 200_000
|
||||||
|
|
||||||
|
proc initProcOptions(m: BModule): TOptions =
|
||||||
|
if sfSystemModule in m.module.flags: gOptions-{optStackTrace} else: gOptions
|
||||||
|
|
||||||
proc rawNewModule(module: PSym, filename: string): BModule =
|
proc rawNewModule(module: PSym, filename: string): BModule =
|
||||||
new(result)
|
new(result)
|
||||||
InitLinkedList(result.headerFiles)
|
InitLinkedList(result.headerFiles)
|
||||||
|
|
@ -1131,7 +1137,7 @@ proc rawNewModule(module: PSym, filename: string): BModule =
|
||||||
result.module = module
|
result.module = module
|
||||||
result.typeInfoMarker = initIntSet()
|
result.typeInfoMarker = initIntSet()
|
||||||
result.initProc = newProc(nil, result)
|
result.initProc = newProc(nil, result)
|
||||||
result.initProc.options = gOptions
|
result.initProc.options = initProcOptions(result)
|
||||||
result.preInitProc = newPreInitProc(result)
|
result.preInitProc = newPreInitProc(result)
|
||||||
result.postInitProc = newPostInitProc(result)
|
result.postInitProc = newPostInitProc(result)
|
||||||
initNodeTable(result.dataCache)
|
initNodeTable(result.dataCache)
|
||||||
|
|
@ -1139,7 +1145,12 @@ proc rawNewModule(module: PSym, filename: string): BModule =
|
||||||
result.forwardedProcs = @[]
|
result.forwardedProcs = @[]
|
||||||
result.typeNodesName = getTempName()
|
result.typeNodesName = getTempName()
|
||||||
result.nimTypesName = getTempName()
|
result.nimTypesName = getTempName()
|
||||||
result.PreventStackTrace = sfSystemModule in module.flags
|
# no line tracing for the init sections of the system module so that we
|
||||||
|
# don't generate a TFrame which can confuse the stack botton initialization:
|
||||||
|
if sfSystemModule in module.flags:
|
||||||
|
result.PreventStackTrace = true
|
||||||
|
excl(result.preInitProc.options, optStackTrace)
|
||||||
|
excl(result.postInitProc.options, optStackTrace)
|
||||||
|
|
||||||
proc nullify[T](arr: var T) =
|
proc nullify[T](arr: var T) =
|
||||||
for i in low(arr)..high(arr):
|
for i in low(arr)..high(arr):
|
||||||
|
|
@ -1152,7 +1163,7 @@ proc resetModule*(m: var BModule) =
|
||||||
m.declaredProtos = initIntSet()
|
m.declaredProtos = initIntSet()
|
||||||
initIdTable(m.forwTypeCache)
|
initIdTable(m.forwTypeCache)
|
||||||
m.initProc = newProc(nil, m)
|
m.initProc = newProc(nil, m)
|
||||||
m.initProc.options = gOptions
|
m.initProc.options = initProcOptions(m)
|
||||||
m.preInitProc = newPreInitProc(m)
|
m.preInitProc = newPreInitProc(m)
|
||||||
m.postInitProc = newPostInitProc(m)
|
m.postInitProc = newPostInitProc(m)
|
||||||
initNodeTable(m.dataCache)
|
initNodeTable(m.dataCache)
|
||||||
|
|
@ -1242,7 +1253,7 @@ proc myProcess(b: PPassContext, n: PNode): PNode =
|
||||||
result = n
|
result = n
|
||||||
if b == nil or passes.skipCodegen(n): return
|
if b == nil or passes.skipCodegen(n): return
|
||||||
var m = BModule(b)
|
var m = BModule(b)
|
||||||
m.initProc.options = gOptions
|
m.initProc.options = initProcOptions(m)
|
||||||
genStmts(m.initProc, n)
|
genStmts(m.initProc, n)
|
||||||
|
|
||||||
proc finishModule(m: BModule) =
|
proc finishModule(m: BModule) =
|
||||||
|
|
@ -1329,7 +1340,7 @@ proc myClose(b: PPassContext, n: PNode): PNode =
|
||||||
if b == nil or passes.skipCodegen(n): return
|
if b == nil or passes.skipCodegen(n): return
|
||||||
var m = BModule(b)
|
var m = BModule(b)
|
||||||
if n != nil:
|
if n != nil:
|
||||||
m.initProc.options = gOptions
|
m.initProc.options = initProcOptions(m)
|
||||||
genStmts(m.initProc, n)
|
genStmts(m.initProc, n)
|
||||||
# cached modules need to registered too:
|
# cached modules need to registered too:
|
||||||
registerModuleToMain(m.module)
|
registerModuleToMain(m.module)
|
||||||
|
|
|
||||||
|
|
@ -111,6 +111,7 @@ type
|
||||||
labels*: natural # for generating unique module-scope names
|
labels*: natural # for generating unique module-scope names
|
||||||
extensionLoaders*: array['0'..'9', PRope] # special procs for the
|
extensionLoaders*: array['0'..'9', PRope] # special procs for the
|
||||||
# OpenGL wrapper
|
# OpenGL wrapper
|
||||||
|
injectStmt*: PRope
|
||||||
|
|
||||||
var
|
var
|
||||||
mainModProcs*, mainModInit*, mainDatInit*: PRope # parts of the main module
|
mainModProcs*, mainModInit*, mainDatInit*: PRope # parts of the main module
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,10 @@
|
||||||
# semantic checking is done for the code. Cross-references are generated
|
# semantic checking is done for the code. Cross-references are generated
|
||||||
# by knowing how the anchors are going to be named.
|
# by knowing how the anchors are going to be named.
|
||||||
|
|
||||||
import
|
import
|
||||||
ast, strutils, strtabs, options, msgs, os, ropes, idents,
|
ast, strutils, strtabs, options, msgs, os, ropes, idents,
|
||||||
wordrecg, syntaxes, renderer, lexer, rstast, rst, rstgen, times, highlite,
|
wordrecg, syntaxes, renderer, lexer, rstast, rst, rstgen, times, highlite,
|
||||||
importer, sempass2
|
importer, sempass2, json
|
||||||
|
|
||||||
type
|
type
|
||||||
TSections = array[TSymKind, PRope]
|
TSections = array[TSymKind, PRope]
|
||||||
|
|
@ -25,7 +25,7 @@ type
|
||||||
indexValFilename: string
|
indexValFilename: string
|
||||||
|
|
||||||
PDoc* = ref TDocumentor
|
PDoc* = ref TDocumentor
|
||||||
|
|
||||||
proc compilerMsgHandler(filename: string, line, col: int,
|
proc compilerMsgHandler(filename: string, line, col: int,
|
||||||
msgKind: rst.TMsgKind, arg: string) {.procvar.} =
|
msgKind: rst.TMsgKind, arg: string) {.procvar.} =
|
||||||
# translate msg kind:
|
# translate msg kind:
|
||||||
|
|
@ -41,69 +41,69 @@ proc compilerMsgHandler(filename: string, line, col: int,
|
||||||
of mwUnknownSubstitution: k = warnUnknownSubstitutionX
|
of mwUnknownSubstitution: k = warnUnknownSubstitutionX
|
||||||
of mwUnsupportedLanguage: k = warnLanguageXNotSupported
|
of mwUnsupportedLanguage: k = warnLanguageXNotSupported
|
||||||
GlobalError(newLineInfo(filename, line, col), k, arg)
|
GlobalError(newLineInfo(filename, line, col), k, arg)
|
||||||
|
|
||||||
proc parseRst(text, filename: string,
|
proc parseRst(text, filename: string,
|
||||||
line, column: int, hasToc: var bool,
|
line, column: int, hasToc: var bool,
|
||||||
rstOptions: TRstParseOptions): PRstNode =
|
rstOptions: TRstParseOptions): PRstNode =
|
||||||
result = rstParse(text, filename, line, column, hasToc, rstOptions,
|
result = rstParse(text, filename, line, column, hasToc, rstOptions,
|
||||||
options.FindFile, compilerMsgHandler)
|
options.FindFile, compilerMsgHandler)
|
||||||
|
|
||||||
proc newDocumentor*(filename: string, config: PStringTable): PDoc =
|
proc newDocumentor*(filename: string, config: PStringTable): PDoc =
|
||||||
new(result)
|
new(result)
|
||||||
initRstGenerator(result[], (if gCmd != cmdRst2Tex: outHtml else: outLatex),
|
initRstGenerator(result[], (if gCmd != cmdRst2Tex: outHtml else: outLatex),
|
||||||
options.gConfigVars, filename, {roSupportRawDirective},
|
options.gConfigVars, filename, {roSupportRawDirective},
|
||||||
options.FindFile, compilerMsgHandler)
|
options.FindFile, compilerMsgHandler)
|
||||||
result.id = 100
|
result.id = 100
|
||||||
|
|
||||||
proc dispA(dest: var PRope, xml, tex: string, args: openarray[PRope]) =
|
proc dispA(dest: var PRope, xml, tex: string, args: openarray[PRope]) =
|
||||||
if gCmd != cmdRst2Tex: appf(dest, xml, args)
|
if gCmd != cmdRst2Tex: appf(dest, xml, args)
|
||||||
else: appf(dest, tex, args)
|
else: appf(dest, tex, args)
|
||||||
|
|
||||||
proc getVarIdx(varnames: openarray[string], id: string): int =
|
proc getVarIdx(varnames: openarray[string], id: string): int =
|
||||||
for i in countup(0, high(varnames)):
|
for i in countup(0, high(varnames)):
|
||||||
if cmpIgnoreStyle(varnames[i], id) == 0:
|
if cmpIgnoreStyle(varnames[i], id) == 0:
|
||||||
return i
|
return i
|
||||||
result = -1
|
result = -1
|
||||||
|
|
||||||
proc ropeFormatNamedVars(frmt: TFormatStr, varnames: openarray[string],
|
proc ropeFormatNamedVars(frmt: TFormatStr, varnames: openarray[string],
|
||||||
varvalues: openarray[PRope]): PRope =
|
varvalues: openarray[PRope]): PRope =
|
||||||
var i = 0
|
var i = 0
|
||||||
var L = len(frmt)
|
var L = len(frmt)
|
||||||
result = nil
|
result = nil
|
||||||
var num = 0
|
var num = 0
|
||||||
while i < L:
|
while i < L:
|
||||||
if frmt[i] == '$':
|
if frmt[i] == '$':
|
||||||
inc(i) # skip '$'
|
inc(i) # skip '$'
|
||||||
case frmt[i]
|
case frmt[i]
|
||||||
of '#':
|
of '#':
|
||||||
app(result, varvalues[num])
|
app(result, varvalues[num])
|
||||||
inc(num)
|
inc(num)
|
||||||
inc(i)
|
inc(i)
|
||||||
of '$':
|
of '$':
|
||||||
app(result, "$")
|
app(result, "$")
|
||||||
inc(i)
|
inc(i)
|
||||||
of '0'..'9':
|
of '0'..'9':
|
||||||
var j = 0
|
var j = 0
|
||||||
while true:
|
while true:
|
||||||
j = (j * 10) + Ord(frmt[i]) - ord('0')
|
j = (j * 10) + Ord(frmt[i]) - ord('0')
|
||||||
inc(i)
|
inc(i)
|
||||||
if (i > L + 0 - 1) or not (frmt[i] in {'0'..'9'}): break
|
if (i > L + 0 - 1) or not (frmt[i] in {'0'..'9'}): break
|
||||||
if j > high(varvalues) + 1: internalError("ropeFormatNamedVars")
|
if j > high(varvalues) + 1: internalError("ropeFormatNamedVars")
|
||||||
num = j
|
num = j
|
||||||
app(result, varvalues[j - 1])
|
app(result, varvalues[j - 1])
|
||||||
of 'A'..'Z', 'a'..'z', '\x80'..'\xFF':
|
of 'A'..'Z', 'a'..'z', '\x80'..'\xFF':
|
||||||
var id = ""
|
var id = ""
|
||||||
while true:
|
while true:
|
||||||
add(id, frmt[i])
|
add(id, frmt[i])
|
||||||
inc(i)
|
inc(i)
|
||||||
if not (frmt[i] in {'A'..'Z', '_', 'a'..'z', '\x80'..'\xFF'}): break
|
if not (frmt[i] in {'A'..'Z', '_', 'a'..'z', '\x80'..'\xFF'}): break
|
||||||
var idx = getVarIdx(varnames, id)
|
var idx = getVarIdx(varnames, id)
|
||||||
if idx >= 0: app(result, varvalues[idx])
|
if idx >= 0: app(result, varvalues[idx])
|
||||||
else: rawMessage(errUnkownSubstitionVar, id)
|
else: rawMessage(errUnkownSubstitionVar, id)
|
||||||
of '{':
|
of '{':
|
||||||
var id = ""
|
var id = ""
|
||||||
inc(i)
|
inc(i)
|
||||||
while frmt[i] != '}':
|
while frmt[i] != '}':
|
||||||
if frmt[i] == '\0': rawMessage(errTokenExpected, "}")
|
if frmt[i] == '\0': rawMessage(errTokenExpected, "}")
|
||||||
add(id, frmt[i])
|
add(id, frmt[i])
|
||||||
inc(i)
|
inc(i)
|
||||||
|
|
@ -124,17 +124,17 @@ proc genComment(d: PDoc, n: PNode): string =
|
||||||
var dummyHasToc: bool
|
var dummyHasToc: bool
|
||||||
if n.comment != nil and startsWith(n.comment, "##"):
|
if n.comment != nil and startsWith(n.comment, "##"):
|
||||||
renderRstToOut(d[], parseRst(n.comment, toFilename(n.info),
|
renderRstToOut(d[], parseRst(n.comment, toFilename(n.info),
|
||||||
toLineNumber(n.info), toColumn(n.info),
|
toLineNumber(n.info), toColumn(n.info),
|
||||||
dummyHasToc, d.options + {roSkipPounds}), result)
|
dummyHasToc, d.options + {roSkipPounds}), result)
|
||||||
|
|
||||||
proc genRecComment(d: PDoc, n: PNode): PRope =
|
proc genRecComment(d: PDoc, n: PNode): PRope =
|
||||||
if n == nil: return nil
|
if n == nil: return nil
|
||||||
result = genComment(d, n).toRope
|
result = genComment(d, n).toRope
|
||||||
if result == nil:
|
if result == nil:
|
||||||
if n.kind notin {nkEmpty..nkNilLit}:
|
if n.kind notin {nkEmpty..nkNilLit}:
|
||||||
for i in countup(0, len(n)-1):
|
for i in countup(0, len(n)-1):
|
||||||
result = genRecComment(d, n.sons[i])
|
result = genRecComment(d, n.sons[i])
|
||||||
if result != nil: return
|
if result != nil: return
|
||||||
else:
|
else:
|
||||||
n.comment = nil
|
n.comment = nil
|
||||||
|
|
||||||
|
|
@ -158,10 +158,10 @@ proc extractDocComment*(s: PSym, d: PDoc = nil): string =
|
||||||
else:
|
else:
|
||||||
result = n.comment.substr(2).replace("\n##", "\n").strip
|
result = n.comment.substr(2).replace("\n##", "\n").strip
|
||||||
|
|
||||||
proc isVisible(n: PNode): bool =
|
proc isVisible(n: PNode): bool =
|
||||||
result = false
|
result = false
|
||||||
if n.kind == nkPostfix:
|
if n.kind == nkPostfix:
|
||||||
if n.len == 2 and n.sons[0].kind == nkIdent:
|
if n.len == 2 and n.sons[0].kind == nkIdent:
|
||||||
var v = n.sons[0].ident
|
var v = n.sons[0].ident
|
||||||
result = v.id == ord(wStar) or v.id == ord(wMinus)
|
result = v.id == ord(wStar) or v.id == ord(wMinus)
|
||||||
elif n.kind == nkSym:
|
elif n.kind == nkSym:
|
||||||
|
|
@ -171,36 +171,36 @@ proc isVisible(n: PNode): bool =
|
||||||
result = {sfExported, sfFromGeneric, sfForward}*n.sym.flags == {sfExported}
|
result = {sfExported, sfFromGeneric, sfForward}*n.sym.flags == {sfExported}
|
||||||
elif n.kind == nkPragmaExpr:
|
elif n.kind == nkPragmaExpr:
|
||||||
result = isVisible(n.sons[0])
|
result = isVisible(n.sons[0])
|
||||||
|
|
||||||
proc getName(d: PDoc, n: PNode, splitAfter = -1): string =
|
proc getName(d: PDoc, n: PNode, splitAfter = -1): string =
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkPostfix: result = getName(d, n.sons[1], splitAfter)
|
of nkPostfix: result = getName(d, n.sons[1], splitAfter)
|
||||||
of nkPragmaExpr: result = getName(d, n.sons[0], splitAfter)
|
of nkPragmaExpr: result = getName(d, n.sons[0], splitAfter)
|
||||||
of nkSym: result = esc(d.target, n.sym.renderDefinitionName, splitAfter)
|
of nkSym: result = esc(d.target, n.sym.renderDefinitionName, splitAfter)
|
||||||
of nkIdent: result = esc(d.target, n.ident.s, splitAfter)
|
of nkIdent: result = esc(d.target, n.ident.s, splitAfter)
|
||||||
of nkAccQuoted:
|
of nkAccQuoted:
|
||||||
result = esc(d.target, "`")
|
result = esc(d.target, "`")
|
||||||
for i in 0.. <n.len: result.add(getName(d, n[i], splitAfter))
|
for i in 0.. <n.len: result.add(getName(d, n[i], splitAfter))
|
||||||
result.add esc(d.target, "`")
|
result.add esc(d.target, "`")
|
||||||
else:
|
else:
|
||||||
internalError(n.info, "getName()")
|
internalError(n.info, "getName()")
|
||||||
result = ""
|
result = ""
|
||||||
|
|
||||||
proc getRstName(n: PNode): PRstNode =
|
proc getRstName(n: PNode): PRstNode =
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkPostfix: result = getRstName(n.sons[1])
|
of nkPostfix: result = getRstName(n.sons[1])
|
||||||
of nkPragmaExpr: result = getRstName(n.sons[0])
|
of nkPragmaExpr: result = getRstName(n.sons[0])
|
||||||
of nkSym: result = newRstNode(rnLeaf, n.sym.renderDefinitionName)
|
of nkSym: result = newRstNode(rnLeaf, n.sym.renderDefinitionName)
|
||||||
of nkIdent: result = newRstNode(rnLeaf, n.ident.s)
|
of nkIdent: result = newRstNode(rnLeaf, n.ident.s)
|
||||||
of nkAccQuoted:
|
of nkAccQuoted:
|
||||||
result = getRstName(n.sons[0])
|
result = getRstName(n.sons[0])
|
||||||
for i in 1 .. <n.len: result.text.add(getRstName(n[i]).text)
|
for i in 1 .. <n.len: result.text.add(getRstName(n[i]).text)
|
||||||
else:
|
else:
|
||||||
internalError(n.info, "getRstName()")
|
internalError(n.info, "getRstName()")
|
||||||
result = nil
|
result = nil
|
||||||
|
|
||||||
proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind) =
|
proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind) =
|
||||||
if not isVisible(nameNode): return
|
if not isVisible(nameNode): return
|
||||||
var name = toRope(getName(d, nameNode))
|
var name = toRope(getName(d, nameNode))
|
||||||
var result: PRope = nil
|
var result: PRope = nil
|
||||||
var literal = ""
|
var literal = ""
|
||||||
|
|
@ -208,73 +208,89 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind) =
|
||||||
var comm = genRecComment(d, n) # call this here for the side-effect!
|
var comm = genRecComment(d, n) # call this here for the side-effect!
|
||||||
var r: TSrcGen
|
var r: TSrcGen
|
||||||
initTokRender(r, n, {renderNoBody, renderNoComments, renderDocComments})
|
initTokRender(r, n, {renderNoBody, renderNoComments, renderDocComments})
|
||||||
while true:
|
while true:
|
||||||
getNextTok(r, kind, literal)
|
getNextTok(r, kind, literal)
|
||||||
case kind
|
case kind
|
||||||
of tkEof:
|
of tkEof:
|
||||||
break
|
break
|
||||||
of tkComment:
|
of tkComment:
|
||||||
dispA(result, "<span class=\"Comment\">$1</span>", "\\spanComment{$1}",
|
dispA(result, "<span class=\"Comment\">$1</span>", "\\spanComment{$1}",
|
||||||
[toRope(esc(d.target, literal))])
|
[toRope(esc(d.target, literal))])
|
||||||
of tokKeywordLow..tokKeywordHigh:
|
of tokKeywordLow..tokKeywordHigh:
|
||||||
dispA(result, "<span class=\"Keyword\">$1</span>", "\\spanKeyword{$1}",
|
dispA(result, "<span class=\"Keyword\">$1</span>", "\\spanKeyword{$1}",
|
||||||
[toRope(literal)])
|
[toRope(literal)])
|
||||||
of tkOpr:
|
of tkOpr:
|
||||||
dispA(result, "<span class=\"Operator\">$1</span>", "\\spanOperator{$1}",
|
dispA(result, "<span class=\"Operator\">$1</span>", "\\spanOperator{$1}",
|
||||||
[toRope(esc(d.target, literal))])
|
[toRope(esc(d.target, literal))])
|
||||||
of tkStrLit..tkTripleStrLit:
|
of tkStrLit..tkTripleStrLit:
|
||||||
dispA(result, "<span class=\"StringLit\">$1</span>",
|
dispA(result, "<span class=\"StringLit\">$1</span>",
|
||||||
"\\spanStringLit{$1}", [toRope(esc(d.target, literal))])
|
"\\spanStringLit{$1}", [toRope(esc(d.target, literal))])
|
||||||
of tkCharLit:
|
of tkCharLit:
|
||||||
dispA(result, "<span class=\"CharLit\">$1</span>", "\\spanCharLit{$1}",
|
dispA(result, "<span class=\"CharLit\">$1</span>", "\\spanCharLit{$1}",
|
||||||
[toRope(esc(d.target, literal))])
|
[toRope(esc(d.target, literal))])
|
||||||
of tkIntLit..tkUInt64Lit:
|
of tkIntLit..tkUInt64Lit:
|
||||||
dispA(result, "<span class=\"DecNumber\">$1</span>",
|
dispA(result, "<span class=\"DecNumber\">$1</span>",
|
||||||
"\\spanDecNumber{$1}", [toRope(esc(d.target, literal))])
|
"\\spanDecNumber{$1}", [toRope(esc(d.target, literal))])
|
||||||
of tkFloatLit..tkFloat128Lit:
|
of tkFloatLit..tkFloat128Lit:
|
||||||
dispA(result, "<span class=\"FloatNumber\">$1</span>",
|
dispA(result, "<span class=\"FloatNumber\">$1</span>",
|
||||||
"\\spanFloatNumber{$1}", [toRope(esc(d.target, literal))])
|
"\\spanFloatNumber{$1}", [toRope(esc(d.target, literal))])
|
||||||
of tkSymbol:
|
of tkSymbol:
|
||||||
dispA(result, "<span class=\"Identifier\">$1</span>",
|
dispA(result, "<span class=\"Identifier\">$1</span>",
|
||||||
"\\spanIdentifier{$1}", [toRope(esc(d.target, literal))])
|
"\\spanIdentifier{$1}", [toRope(esc(d.target, literal))])
|
||||||
of tkSpaces, tkInvalid:
|
of tkSpaces, tkInvalid:
|
||||||
app(result, literal)
|
app(result, literal)
|
||||||
of tkParLe, tkParRi, tkBracketLe, tkBracketRi, tkCurlyLe, tkCurlyRi,
|
of tkParLe, tkParRi, tkBracketLe, tkBracketRi, tkCurlyLe, tkCurlyRi,
|
||||||
tkBracketDotLe, tkBracketDotRi, tkCurlyDotLe, tkCurlyDotRi, tkParDotLe,
|
tkBracketDotLe, tkBracketDotRi, tkCurlyDotLe, tkCurlyDotRi, tkParDotLe,
|
||||||
tkParDotRi, tkComma, tkSemiColon, tkColon, tkEquals, tkDot, tkDotDot,
|
tkParDotRi, tkComma, tkSemiColon, tkColon, tkEquals, tkDot, tkDotDot,
|
||||||
tkAccent, tkColonColon,
|
tkAccent, tkColonColon,
|
||||||
tkGStrLit, tkGTripleStrLit, tkInfixOpr, tkPrefixOpr, tkPostfixOpr:
|
tkGStrLit, tkGTripleStrLit, tkInfixOpr, tkPrefixOpr, tkPostfixOpr:
|
||||||
dispA(result, "<span class=\"Other\">$1</span>", "\\spanOther{$1}",
|
dispA(result, "<span class=\"Other\">$1</span>", "\\spanOther{$1}",
|
||||||
[toRope(esc(d.target, literal))])
|
[toRope(esc(d.target, literal))])
|
||||||
inc(d.id)
|
inc(d.id)
|
||||||
app(d.section[k], ropeFormatNamedVars(getConfigVar("doc.item"),
|
app(d.section[k], ropeFormatNamedVars(getConfigVar("doc.item"),
|
||||||
["name", "header", "desc", "itemID"],
|
["name", "header", "desc", "itemID"],
|
||||||
[name, result, comm, toRope(d.id)]))
|
[name, result, comm, toRope(d.id)]))
|
||||||
app(d.toc[k], ropeFormatNamedVars(getConfigVar("doc.item.toc"),
|
app(d.toc[k], ropeFormatNamedVars(getConfigVar("doc.item.toc"),
|
||||||
["name", "header", "desc", "itemID"], [
|
["name", "header", "desc", "itemID"], [
|
||||||
toRope(getName(d, nameNode, d.splitAfter)), result, comm, toRope(d.id)]))
|
toRope(getName(d, nameNode, d.splitAfter)), result, comm, toRope(d.id)]))
|
||||||
setIndexTerm(d[], $d.id, getName(d, nameNode))
|
setIndexTerm(d[], $d.id, getName(d, nameNode))
|
||||||
|
|
||||||
proc checkForFalse(n: PNode): bool =
|
proc genJSONItem(d: PDoc, n, nameNode: PNode, k: TSymKind): PJsonNode =
|
||||||
|
if not isVisible(nameNode): return
|
||||||
|
var
|
||||||
|
name = getName(d, nameNode)
|
||||||
|
comm = genRecComment(d, n).ropeToStr()
|
||||||
|
r: TSrcGen
|
||||||
|
|
||||||
|
initTokRender(r, n, {renderNoBody, renderNoComments, renderDocComments})
|
||||||
|
|
||||||
|
result = %{ "name": %name, "type": %($k) }
|
||||||
|
|
||||||
|
if comm != nil and comm != "":
|
||||||
|
result["description"] = %comm
|
||||||
|
if r.buf != nil:
|
||||||
|
result["code"] = %r.buf
|
||||||
|
|
||||||
|
proc checkForFalse(n: PNode): bool =
|
||||||
result = n.kind == nkIdent and IdentEq(n.ident, "false")
|
result = n.kind == nkIdent and IdentEq(n.ident, "false")
|
||||||
|
|
||||||
proc traceDeps(d: PDoc, n: PNode) =
|
proc traceDeps(d: PDoc, n: PNode) =
|
||||||
const k = skModule
|
const k = skModule
|
||||||
if d.section[k] != nil: app(d.section[k], ", ")
|
if d.section[k] != nil: app(d.section[k], ", ")
|
||||||
dispA(d.section[k],
|
dispA(d.section[k],
|
||||||
"<a class=\"reference external\" href=\"$1.html\">$1</a>",
|
"<a class=\"reference external\" href=\"$1.html\">$1</a>",
|
||||||
"$1", [toRope(getModuleName(n))])
|
"$1", [toRope(getModuleName(n))])
|
||||||
|
|
||||||
proc generateDoc*(d: PDoc, n: PNode) =
|
proc generateDoc*(d: PDoc, n: PNode) =
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkCommentStmt: app(d.modDesc, genComment(d, n))
|
of nkCommentStmt: app(d.modDesc, genComment(d, n))
|
||||||
of nkProcDef:
|
of nkProcDef:
|
||||||
when useEffectSystem: documentRaises(n)
|
when useEffectSystem: documentRaises(n)
|
||||||
genItem(d, n, n.sons[namePos], skProc)
|
genItem(d, n, n.sons[namePos], skProc)
|
||||||
of nkMethodDef:
|
of nkMethodDef:
|
||||||
when useEffectSystem: documentRaises(n)
|
when useEffectSystem: documentRaises(n)
|
||||||
genItem(d, n, n.sons[namePos], skMethod)
|
genItem(d, n, n.sons[namePos], skMethod)
|
||||||
of nkIteratorDef:
|
of nkIteratorDef:
|
||||||
when useEffectSystem: documentRaises(n)
|
when useEffectSystem: documentRaises(n)
|
||||||
genItem(d, n, n.sons[namePos], skIterator)
|
genItem(d, n, n.sons[namePos], skIterator)
|
||||||
of nkMacroDef: genItem(d, n, n.sons[namePos], skMacro)
|
of nkMacroDef: genItem(d, n, n.sons[namePos], skMacro)
|
||||||
|
|
@ -284,27 +300,69 @@ proc generateDoc*(d: PDoc, n: PNode) =
|
||||||
genItem(d, n, n.sons[namePos], skConverter)
|
genItem(d, n, n.sons[namePos], skConverter)
|
||||||
of nkTypeSection, nkVarSection, nkLetSection, nkConstSection:
|
of nkTypeSection, nkVarSection, nkLetSection, nkConstSection:
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
if n.sons[i].kind != nkCommentStmt:
|
if n.sons[i].kind != nkCommentStmt:
|
||||||
# order is always 'type var let const':
|
# order is always 'type var let const':
|
||||||
genItem(d, n.sons[i], n.sons[i].sons[0],
|
genItem(d, n.sons[i], n.sons[i].sons[0],
|
||||||
succ(skType, ord(n.kind)-ord(nkTypeSection)))
|
succ(skType, ord(n.kind)-ord(nkTypeSection)))
|
||||||
of nkStmtList:
|
of nkStmtList:
|
||||||
for i in countup(0, sonsLen(n) - 1): generateDoc(d, n.sons[i])
|
for i in countup(0, sonsLen(n) - 1): generateDoc(d, n.sons[i])
|
||||||
of nkWhenStmt:
|
of nkWhenStmt:
|
||||||
# generate documentation for the first branch only:
|
# generate documentation for the first branch only:
|
||||||
if not checkForFalse(n.sons[0].sons[0]):
|
if not checkForFalse(n.sons[0].sons[0]):
|
||||||
generateDoc(d, lastSon(n.sons[0]))
|
generateDoc(d, lastSon(n.sons[0]))
|
||||||
of nkImportStmt:
|
of nkImportStmt:
|
||||||
for i in 0 .. sonsLen(n)-1: traceDeps(d, n.sons[i])
|
for i in 0 .. sonsLen(n)-1: traceDeps(d, n.sons[i])
|
||||||
of nkFromStmt, nkImportExceptStmt: traceDeps(d, n.sons[0])
|
of nkFromStmt, nkImportExceptStmt: traceDeps(d, n.sons[0])
|
||||||
else: nil
|
else: nil
|
||||||
|
|
||||||
proc genSection(d: PDoc, kind: TSymKind) =
|
proc generateJson(d: PDoc, n: PNode, jArray: PJsonNode = nil): PJsonNode =
|
||||||
|
case n.kind
|
||||||
|
of nkCommentStmt:
|
||||||
|
if n.comment != nil and startsWith(n.comment, "##"):
|
||||||
|
let stripped = n.comment.substr(2).strip
|
||||||
|
result = %{ "comment": %stripped }
|
||||||
|
of nkProcDef:
|
||||||
|
when useEffectSystem: documentRaises(n)
|
||||||
|
result = genJSONItem(d, n, n.sons[namePos], skProc)
|
||||||
|
of nkMethodDef:
|
||||||
|
when useEffectSystem: documentRaises(n)
|
||||||
|
result = genJSONItem(d, n, n.sons[namePos], skMethod)
|
||||||
|
of nkIteratorDef:
|
||||||
|
when useEffectSystem: documentRaises(n)
|
||||||
|
result = genJSONItem(d, n, n.sons[namePos], skIterator)
|
||||||
|
of nkMacroDef:
|
||||||
|
result = genJSONItem(d, n, n.sons[namePos], skMacro)
|
||||||
|
of nkTemplateDef:
|
||||||
|
result = genJSONItem(d, n, n.sons[namePos], skTemplate)
|
||||||
|
of nkConverterDef:
|
||||||
|
when useEffectSystem: documentRaises(n)
|
||||||
|
result = genJSONItem(d, n, n.sons[namePos], skConverter)
|
||||||
|
of nkTypeSection, nkVarSection, nkLetSection, nkConstSection:
|
||||||
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
|
if n.sons[i].kind != nkCommentStmt:
|
||||||
|
# order is always 'type var let const':
|
||||||
|
result = genJSONItem(d, n.sons[i], n.sons[i].sons[0],
|
||||||
|
succ(skType, ord(n.kind)-ord(nkTypeSection)))
|
||||||
|
of nkStmtList:
|
||||||
|
var elem = jArray
|
||||||
|
if elem == nil: elem = newJArray()
|
||||||
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
|
var r = generateJson(d, n.sons[i], elem)
|
||||||
|
if r != nil:
|
||||||
|
elem.add(r)
|
||||||
|
if result == nil: result = elem
|
||||||
|
of nkWhenStmt:
|
||||||
|
# generate documentation for the first branch only:
|
||||||
|
if not checkForFalse(n.sons[0].sons[0]) and jArray != nil:
|
||||||
|
discard generateJson(d, lastSon(n.sons[0]), jArray)
|
||||||
|
else: nil
|
||||||
|
|
||||||
|
proc genSection(d: PDoc, kind: TSymKind) =
|
||||||
const sectionNames: array[skModule..skTemplate, string] = [
|
const sectionNames: array[skModule..skTemplate, string] = [
|
||||||
"Imports", "Types", "Vars", "Lets", "Consts", "Vars", "Procs", "Methods",
|
"Imports", "Types", "Vars", "Lets", "Consts", "Vars", "Procs", "Methods",
|
||||||
"Iterators", "Converters", "Macros", "Templates"
|
"Iterators", "Converters", "Macros", "Templates"
|
||||||
]
|
]
|
||||||
if d.section[kind] == nil: return
|
if d.section[kind] == nil: return
|
||||||
var title = sectionNames[kind].toRope
|
var title = sectionNames[kind].toRope
|
||||||
d.section[kind] = ropeFormatNamedVars(getConfigVar("doc.section"), [
|
d.section[kind] = ropeFormatNamedVars(getConfigVar("doc.section"), [
|
||||||
"sectionid", "sectionTitle", "sectionTitleID", "content"], [
|
"sectionid", "sectionTitle", "sectionTitleID", "content"], [
|
||||||
|
|
@ -313,7 +371,7 @@ proc genSection(d: PDoc, kind: TSymKind) =
|
||||||
"sectionid", "sectionTitle", "sectionTitleID", "content"], [
|
"sectionid", "sectionTitle", "sectionTitleID", "content"], [
|
||||||
ord(kind).toRope, title, toRope(ord(kind) + 50), d.toc[kind]])
|
ord(kind).toRope, title, toRope(ord(kind) + 50), d.toc[kind]])
|
||||||
|
|
||||||
proc genOutFile(d: PDoc): PRope =
|
proc genOutFile(d: PDoc): PRope =
|
||||||
var
|
var
|
||||||
code, content: PRope
|
code, content: PRope
|
||||||
title = ""
|
title = ""
|
||||||
|
|
@ -321,7 +379,7 @@ proc genOutFile(d: PDoc): PRope =
|
||||||
var tmp = ""
|
var tmp = ""
|
||||||
renderTocEntries(d[], j, 1, tmp)
|
renderTocEntries(d[], j, 1, tmp)
|
||||||
var toc = tmp.toRope
|
var toc = tmp.toRope
|
||||||
for i in countup(low(TSymKind), high(TSymKind)):
|
for i in countup(low(TSymKind), high(TSymKind)):
|
||||||
genSection(d, i)
|
genSection(d, i)
|
||||||
app(toc, d.toc[i])
|
app(toc, d.toc[i])
|
||||||
if toc != nil:
|
if toc != nil:
|
||||||
|
|
@ -329,30 +387,30 @@ proc genOutFile(d: PDoc): PRope =
|
||||||
for i in countup(low(TSymKind), high(TSymKind)): app(code, d.section[i])
|
for i in countup(low(TSymKind), high(TSymKind)): app(code, d.section[i])
|
||||||
if d.meta[metaTitle].len != 0: title = d.meta[metaTitle]
|
if d.meta[metaTitle].len != 0: title = d.meta[metaTitle]
|
||||||
else: title = "Module " & extractFilename(changeFileExt(d.filename, ""))
|
else: title = "Module " & extractFilename(changeFileExt(d.filename, ""))
|
||||||
|
|
||||||
let bodyname = if d.hasToc: "doc.body_toc" else: "doc.body_no_toc"
|
let bodyname = if d.hasToc: "doc.body_toc" else: "doc.body_no_toc"
|
||||||
content = ropeFormatNamedVars(getConfigVar(bodyname), ["title",
|
content = ropeFormatNamedVars(getConfigVar(bodyname), ["title",
|
||||||
"tableofcontents", "moduledesc", "date", "time", "content"],
|
"tableofcontents", "moduledesc", "date", "time", "content"],
|
||||||
[title.toRope, toc, d.modDesc, toRope(getDateStr()),
|
[title.toRope, toc, d.modDesc, toRope(getDateStr()),
|
||||||
toRope(getClockStr()), code])
|
toRope(getClockStr()), code])
|
||||||
if optCompileOnly notin gGlobalOptions:
|
if optCompileOnly notin gGlobalOptions:
|
||||||
# XXX what is this hack doing here? 'optCompileOnly' means raw output!?
|
# XXX what is this hack doing here? 'optCompileOnly' means raw output!?
|
||||||
code = ropeFormatNamedVars(getConfigVar("doc.file"), ["title",
|
code = ropeFormatNamedVars(getConfigVar("doc.file"), ["title",
|
||||||
"tableofcontents", "moduledesc", "date", "time",
|
"tableofcontents", "moduledesc", "date", "time",
|
||||||
"content", "author", "version"],
|
"content", "author", "version"],
|
||||||
[title.toRope, toc, d.modDesc, toRope(getDateStr()),
|
[title.toRope, toc, d.modDesc, toRope(getDateStr()),
|
||||||
toRope(getClockStr()), content, d.meta[metaAuthor].toRope,
|
toRope(getClockStr()), content, d.meta[metaAuthor].toRope,
|
||||||
d.meta[metaVersion].toRope])
|
d.meta[metaVersion].toRope])
|
||||||
else:
|
else:
|
||||||
code = content
|
code = content
|
||||||
result = code
|
result = code
|
||||||
|
|
||||||
proc generateIndex*(d: PDoc) =
|
proc generateIndex*(d: PDoc) =
|
||||||
if optGenIndex in gGlobalOptions:
|
if optGenIndex in gGlobalOptions:
|
||||||
writeIndexFile(d[], splitFile(options.outFile).dir /
|
writeIndexFile(d[], splitFile(options.outFile).dir /
|
||||||
splitFile(d.filename).name & indexExt)
|
splitFile(d.filename).name & indexExt)
|
||||||
|
|
||||||
proc writeOutput*(d: PDoc, filename, outExt: string, useWarning = false) =
|
proc writeOutput*(d: PDoc, filename, outExt: string, useWarning = false) =
|
||||||
var content = genOutFile(d)
|
var content = genOutFile(d)
|
||||||
if optStdout in gGlobalOptions:
|
if optStdout in gGlobalOptions:
|
||||||
writeRope(stdout, content)
|
writeRope(stdout, content)
|
||||||
|
|
@ -361,7 +419,7 @@ proc writeOutput*(d: PDoc, filename, outExt: string, useWarning = false) =
|
||||||
|
|
||||||
proc CommandDoc*() =
|
proc CommandDoc*() =
|
||||||
var ast = parseFile(gProjectMainIdx)
|
var ast = parseFile(gProjectMainIdx)
|
||||||
if ast == nil: return
|
if ast == nil: return
|
||||||
var d = newDocumentor(gProjectFull, options.gConfigVars)
|
var d = newDocumentor(gProjectFull, options.gConfigVars)
|
||||||
d.hasToc = true
|
d.hasToc = true
|
||||||
generateDoc(d, ast)
|
generateDoc(d, ast)
|
||||||
|
|
@ -388,12 +446,26 @@ proc CommandRst2TeX*() =
|
||||||
splitter = "\\-"
|
splitter = "\\-"
|
||||||
CommandRstAux(gProjectFull, TexExt)
|
CommandRstAux(gProjectFull, TexExt)
|
||||||
|
|
||||||
|
proc CommandJSON*() =
|
||||||
|
var ast = parseFile(gProjectMainIdx)
|
||||||
|
if ast == nil: return
|
||||||
|
var d = newDocumentor(gProjectFull, options.gConfigVars)
|
||||||
|
d.hasToc = true
|
||||||
|
var json = generateJson(d, ast)
|
||||||
|
var content = newRope(pretty(json))
|
||||||
|
|
||||||
|
if optStdout in gGlobalOptions:
|
||||||
|
writeRope(stdout, content)
|
||||||
|
else:
|
||||||
|
echo getOutFile(gProjectFull, JsonExt)
|
||||||
|
writeRope(content, getOutFile(gProjectFull, JsonExt), useWarning = false)
|
||||||
|
|
||||||
proc CommandBuildIndex*() =
|
proc CommandBuildIndex*() =
|
||||||
var content = mergeIndexes(gProjectFull).toRope
|
var content = mergeIndexes(gProjectFull).toRope
|
||||||
|
|
||||||
let code = ropeFormatNamedVars(getConfigVar("doc.file"), ["title",
|
let code = ropeFormatNamedVars(getConfigVar("doc.file"), ["title",
|
||||||
"tableofcontents", "moduledesc", "date", "time",
|
"tableofcontents", "moduledesc", "date", "time",
|
||||||
"content", "author", "version"],
|
"content", "author", "version"],
|
||||||
["Index".toRope, nil, nil, toRope(getDateStr()),
|
["Index".toRope, nil, nil, toRope(getDateStr()),
|
||||||
toRope(getClockStr()), content, nil, nil])
|
toRope(getClockStr()), content, nil, nil])
|
||||||
writeRope(code, getOutFile("theindex", HtmlExt))
|
writeRope(code, getOutFile("theindex", HtmlExt))
|
||||||
|
|
|
||||||
|
|
@ -463,9 +463,9 @@ proc getCompileOptions: string =
|
||||||
proc getLinkOptions: string =
|
proc getLinkOptions: string =
|
||||||
result = linkOptions
|
result = linkOptions
|
||||||
for linkedLib in items(cLinkedLibs):
|
for linkedLib in items(cLinkedLibs):
|
||||||
result.add(cc[ccompiler].linkLibCmd % linkedLib.quoteIfContainsWhite)
|
result.add(cc[ccompiler].linkLibCmd % linkedLib.quoteShell)
|
||||||
for libDir in items(cLibs):
|
for libDir in items(cLibs):
|
||||||
result.add([cc[ccompiler].linkDirCmd, libDir.quoteIfContainsWhite])
|
result.add([cc[ccompiler].linkDirCmd, libDir.quoteShell])
|
||||||
|
|
||||||
proc needsExeExt(): bool {.inline.} =
|
proc needsExeExt(): bool {.inline.} =
|
||||||
result = (optGenScript in gGlobalOptions and targetOS == osWindows) or
|
result = (optGenScript in gGlobalOptions and targetOS == osWindows) or
|
||||||
|
|
@ -485,10 +485,10 @@ proc getCompileCFileCmd*(cfilename: string, isExternal = false): string =
|
||||||
var includeCmd, compilePattern: string
|
var includeCmd, compilePattern: string
|
||||||
if not noAbsolutePaths():
|
if not noAbsolutePaths():
|
||||||
# compute include paths:
|
# compute include paths:
|
||||||
includeCmd = cc[c].includeCmd & quoteIfContainsWhite(libpath)
|
includeCmd = cc[c].includeCmd & quoteShell(libpath)
|
||||||
|
|
||||||
for includeDir in items(cIncludes):
|
for includeDir in items(cIncludes):
|
||||||
includeCmd.add([cc[c].includeCmd, includeDir.quoteIfContainsWhite])
|
includeCmd.add([cc[c].includeCmd, includeDir.quoteShell])
|
||||||
|
|
||||||
compilePattern = JoinPath(ccompilerpath, exe)
|
compilePattern = JoinPath(ccompilerpath, exe)
|
||||||
else:
|
else:
|
||||||
|
|
@ -501,17 +501,17 @@ proc getCompileCFileCmd*(cfilename: string, isExternal = false): string =
|
||||||
toObjFile(cfile)
|
toObjFile(cfile)
|
||||||
else:
|
else:
|
||||||
completeCFilePath(toObjFile(cfile))
|
completeCFilePath(toObjFile(cfile))
|
||||||
cfile = quoteIfContainsWhite(AddFileExt(cfile, cExt))
|
cfile = quoteShell(AddFileExt(cfile, cExt))
|
||||||
objfile = quoteIfContainsWhite(objfile)
|
objfile = quoteShell(objfile)
|
||||||
result = quoteIfContainsWhite(compilePattern % [
|
result = quoteShell(compilePattern % [
|
||||||
"file", cfile, "objfile", objfile, "options", options,
|
"file", cfile, "objfile", objfile, "options", options,
|
||||||
"include", includeCmd, "nimrod", getPrefixDir(), "lib", libpath])
|
"include", includeCmd, "nimrod", getPrefixDir(), "lib", libpath])
|
||||||
add(result, ' ')
|
add(result, ' ')
|
||||||
addf(result, cc[c].compileTmpl, [
|
addf(result, cc[c].compileTmpl, [
|
||||||
"file", cfile, "objfile", objfile,
|
"file", cfile, "objfile", objfile,
|
||||||
"options", options, "include", includeCmd,
|
"options", options, "include", includeCmd,
|
||||||
"nimrod", quoteIfContainsWhite(getPrefixDir()),
|
"nimrod", quoteShell(getPrefixDir()),
|
||||||
"lib", quoteIfContainsWhite(libpath)])
|
"lib", quoteShell(libpath)])
|
||||||
|
|
||||||
proc footprint(filename: string): TCrc32 =
|
proc footprint(filename: string): TCrc32 =
|
||||||
result = crcFromFile(filename) ><
|
result = crcFromFile(filename) ><
|
||||||
|
|
@ -590,7 +590,7 @@ proc CallCCompiler*(projectfile: string) =
|
||||||
while it != nil:
|
while it != nil:
|
||||||
let objFile = if noAbsolutePaths(): it.data.extractFilename else: it.data
|
let objFile = if noAbsolutePaths(): it.data.extractFilename else: it.data
|
||||||
add(objfiles, ' ')
|
add(objfiles, ' ')
|
||||||
add(objfiles, quoteIfContainsWhite(
|
add(objfiles, quoteShell(
|
||||||
addFileExt(objFile, cc[ccompiler].objExt)))
|
addFileExt(objFile, cc[ccompiler].objExt)))
|
||||||
it = PStrEntry(it.next)
|
it = PStrEntry(it.next)
|
||||||
|
|
||||||
|
|
@ -602,8 +602,8 @@ proc CallCCompiler*(projectfile: string) =
|
||||||
var linkerExe = getConfigVar(c, ".linkerexe")
|
var linkerExe = getConfigVar(c, ".linkerexe")
|
||||||
if len(linkerExe) == 0: linkerExe = cc[c].linkerExe
|
if len(linkerExe) == 0: linkerExe = cc[c].linkerExe
|
||||||
if needsExeExt(): linkerExe = addFileExt(linkerExe, "exe")
|
if needsExeExt(): linkerExe = addFileExt(linkerExe, "exe")
|
||||||
if noAbsolutePaths(): linkCmd = quoteIfContainsWhite(linkerExe)
|
if noAbsolutePaths(): linkCmd = quoteShell(linkerExe)
|
||||||
else: linkCmd = quoteIfContainsWhite(JoinPath(ccompilerpath, linkerExe))
|
else: linkCmd = quoteShell(JoinPath(ccompilerpath, linkerExe))
|
||||||
if optGenGuiApp in gGlobalOptions: buildGui = cc[c].buildGui
|
if optGenGuiApp in gGlobalOptions: buildGui = cc[c].buildGui
|
||||||
else: buildGui = ""
|
else: buildGui = ""
|
||||||
var exefile: string
|
var exefile: string
|
||||||
|
|
@ -616,18 +616,19 @@ proc CallCCompiler*(projectfile: string) =
|
||||||
if options.outFile.len > 0:
|
if options.outFile.len > 0:
|
||||||
exefile = options.outFile
|
exefile = options.outFile
|
||||||
if not noAbsolutePaths():
|
if not noAbsolutePaths():
|
||||||
exefile = joinPath(splitFile(projectFile).dir, exefile)
|
if not exeFile.isAbsolute():
|
||||||
exefile = quoteIfContainsWhite(exefile)
|
exefile = joinPath(splitFile(projectFile).dir, exefile)
|
||||||
|
exefile = quoteShell(exefile)
|
||||||
let linkOptions = getLinkOptions()
|
let linkOptions = getLinkOptions()
|
||||||
linkCmd = quoteIfContainsWhite(linkCmd % ["builddll", builddll,
|
linkCmd = quoteShell(linkCmd % ["builddll", builddll,
|
||||||
"buildgui", buildgui, "options", linkOptions, "objfiles", objfiles,
|
"buildgui", buildgui, "options", linkOptions, "objfiles", objfiles,
|
||||||
"exefile", exefile, "nimrod", getPrefixDir(), "lib", libpath])
|
"exefile", exefile, "nimrod", getPrefixDir(), "lib", libpath])
|
||||||
linkCmd.add ' '
|
linkCmd.add ' '
|
||||||
addf(linkCmd, cc[c].linkTmpl, ["builddll", builddll,
|
addf(linkCmd, cc[c].linkTmpl, ["builddll", builddll,
|
||||||
"buildgui", buildgui, "options", linkOptions,
|
"buildgui", buildgui, "options", linkOptions,
|
||||||
"objfiles", objfiles, "exefile", exefile,
|
"objfiles", objfiles, "exefile", exefile,
|
||||||
"nimrod", quoteIfContainsWhite(getPrefixDir()),
|
"nimrod", quoteShell(getPrefixDir()),
|
||||||
"lib", quoteIfContainsWhite(libpath)])
|
"lib", quoteShell(libpath)])
|
||||||
if optCompileOnly notin gGlobalOptions: execExternalProgram(linkCmd)
|
if optCompileOnly notin gGlobalOptions: execExternalProgram(linkCmd)
|
||||||
else:
|
else:
|
||||||
linkCmd = ""
|
linkCmd = ""
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@
|
||||||
|
|
||||||
# implements the command dispatcher and several commands
|
# implements the command dispatcher and several commands
|
||||||
|
|
||||||
import
|
import
|
||||||
llstream, strutils, ast, astalgo, lexer, syntaxes, renderer, options, msgs,
|
llstream, strutils, ast, astalgo, lexer, syntaxes, renderer, options, msgs,
|
||||||
os, condsyms, rodread, rodwrite, times,
|
os, condsyms, rodread, rodwrite, times,
|
||||||
wordrecg, sem, semdata, idents, passes, docgen, extccomp,
|
wordrecg, sem, semdata, idents, passes, docgen, extccomp,
|
||||||
cgen, jsgen, json, nversion,
|
cgen, jsgen, json, nversion,
|
||||||
|
|
@ -98,7 +98,7 @@ proc CommandCompileToC =
|
||||||
# rodread.rodcompilerProcs
|
# rodread.rodcompilerProcs
|
||||||
# rodread.gTypeTable
|
# rodread.gTypeTable
|
||||||
# rodread.gMods
|
# rodread.gMods
|
||||||
|
|
||||||
# !! ropes.cache
|
# !! ropes.cache
|
||||||
# semthreads.computed?
|
# semthreads.computed?
|
||||||
#
|
#
|
||||||
|
|
@ -166,7 +166,7 @@ proc commandEval(exp: string) =
|
||||||
proc CommandPrettyOld =
|
proc CommandPrettyOld =
|
||||||
var projectFile = addFileExt(mainCommandArg(), NimExt)
|
var projectFile = addFileExt(mainCommandArg(), NimExt)
|
||||||
var module = parseFile(projectFile.fileInfoIdx)
|
var module = parseFile(projectFile.fileInfoIdx)
|
||||||
if module != nil:
|
if module != nil:
|
||||||
renderModule(module, getOutFile(mainCommandArg(), "pretty." & NimExt))
|
renderModule(module, getOutFile(mainCommandArg(), "pretty." & NimExt))
|
||||||
|
|
||||||
proc CommandPretty =
|
proc CommandPretty =
|
||||||
|
|
@ -175,24 +175,24 @@ proc CommandPretty =
|
||||||
registerPass(prettyPass)
|
registerPass(prettyPass)
|
||||||
compileProject()
|
compileProject()
|
||||||
pretty.overwriteFiles()
|
pretty.overwriteFiles()
|
||||||
|
|
||||||
proc CommandScan =
|
proc CommandScan =
|
||||||
var f = addFileExt(mainCommandArg(), nimExt)
|
var f = addFileExt(mainCommandArg(), nimExt)
|
||||||
var stream = LLStreamOpen(f, fmRead)
|
var stream = LLStreamOpen(f, fmRead)
|
||||||
if stream != nil:
|
if stream != nil:
|
||||||
var
|
var
|
||||||
L: TLexer
|
L: TLexer
|
||||||
tok: TToken
|
tok: TToken
|
||||||
initToken(tok)
|
initToken(tok)
|
||||||
openLexer(L, f, stream)
|
openLexer(L, f, stream)
|
||||||
while true:
|
while true:
|
||||||
rawGetTok(L, tok)
|
rawGetTok(L, tok)
|
||||||
PrintTok(tok)
|
PrintTok(tok)
|
||||||
if tok.tokType == tkEof: break
|
if tok.tokType == tkEof: break
|
||||||
CloseLexer(L)
|
CloseLexer(L)
|
||||||
else:
|
else:
|
||||||
rawMessage(errCannotOpenFile, f)
|
rawMessage(errCannotOpenFile, f)
|
||||||
|
|
||||||
proc CommandSuggest =
|
proc CommandSuggest =
|
||||||
if isServing:
|
if isServing:
|
||||||
# XXX: hacky work-around ahead
|
# XXX: hacky work-around ahead
|
||||||
|
|
@ -246,7 +246,7 @@ proc resetMemory =
|
||||||
for i in low(buckets)..high(buckets):
|
for i in low(buckets)..high(buckets):
|
||||||
buckets[i] = nil
|
buckets[i] = nil
|
||||||
idAnon = nil
|
idAnon = nil
|
||||||
|
|
||||||
# XXX: clean these global vars
|
# XXX: clean these global vars
|
||||||
# ccgstmts.gBreakpoints
|
# ccgstmts.gBreakpoints
|
||||||
# ccgthreadvars.nimtv
|
# ccgthreadvars.nimtv
|
||||||
|
|
@ -262,7 +262,7 @@ proc resetMemory =
|
||||||
# rodread.rodcompilerProcs
|
# rodread.rodcompilerProcs
|
||||||
# rodread.gTypeTable
|
# rodread.gTypeTable
|
||||||
# rodread.gMods
|
# rodread.gMods
|
||||||
|
|
||||||
# !! ropes.cache
|
# !! ropes.cache
|
||||||
# semthreads.computed?
|
# semthreads.computed?
|
||||||
#
|
#
|
||||||
|
|
@ -289,7 +289,7 @@ const
|
||||||
proc MainCommand* =
|
proc MainCommand* =
|
||||||
when SimiluateCaasMemReset:
|
when SimiluateCaasMemReset:
|
||||||
gGlobalOptions.incl(optCaasEnabled)
|
gGlobalOptions.incl(optCaasEnabled)
|
||||||
|
|
||||||
# In "nimrod serve" scenario, each command must reset the registered passes
|
# In "nimrod serve" scenario, each command must reset the registered passes
|
||||||
clearPasses()
|
clearPasses()
|
||||||
gLastCmdTime = epochTime()
|
gLastCmdTime = epochTime()
|
||||||
|
|
@ -301,7 +301,7 @@ proc MainCommand* =
|
||||||
passes.gIncludeFile = includeModule
|
passes.gIncludeFile = includeModule
|
||||||
passes.gImportModule = importModule
|
passes.gImportModule = importModule
|
||||||
case command.normalize
|
case command.normalize
|
||||||
of "c", "cc", "compile", "compiletoc":
|
of "c", "cc", "compile", "compiletoc":
|
||||||
# compile means compileToC currently
|
# compile means compileToC currently
|
||||||
gCmd = cmdCompileToC
|
gCmd = cmdCompileToC
|
||||||
wantMainModule()
|
wantMainModule()
|
||||||
|
|
@ -325,13 +325,13 @@ proc MainCommand* =
|
||||||
when hasTinyCBackend:
|
when hasTinyCBackend:
|
||||||
extccomp.setCC("tcc")
|
extccomp.setCC("tcc")
|
||||||
CommandCompileToC()
|
CommandCompileToC()
|
||||||
else:
|
else:
|
||||||
rawMessage(errInvalidCommandX, command)
|
rawMessage(errInvalidCommandX, command)
|
||||||
of "js", "compiletojs":
|
of "js", "compiletojs":
|
||||||
gCmd = cmdCompileToJS
|
gCmd = cmdCompileToJS
|
||||||
wantMainModule()
|
wantMainModule()
|
||||||
CommandCompileToJS()
|
CommandCompileToJS()
|
||||||
of "compiletollvm":
|
of "compiletollvm":
|
||||||
gCmd = cmdCompileToLLVM
|
gCmd = cmdCompileToLLVM
|
||||||
wantMainModule()
|
wantMainModule()
|
||||||
when has_LLVM_Backend:
|
when has_LLVM_Backend:
|
||||||
|
|
@ -353,21 +353,27 @@ proc MainCommand* =
|
||||||
wantMainModule()
|
wantMainModule()
|
||||||
DefineSymbol("nimdoc")
|
DefineSymbol("nimdoc")
|
||||||
CommandDoc2()
|
CommandDoc2()
|
||||||
of "rst2html":
|
of "rst2html":
|
||||||
gCmd = cmdRst2html
|
gCmd = cmdRst2html
|
||||||
LoadConfigs(DocConfig)
|
LoadConfigs(DocConfig)
|
||||||
wantMainModule()
|
wantMainModule()
|
||||||
CommandRst2Html()
|
CommandRst2Html()
|
||||||
of "rst2tex":
|
of "rst2tex":
|
||||||
gCmd = cmdRst2tex
|
gCmd = cmdRst2tex
|
||||||
LoadConfigs(DocTexConfig)
|
LoadConfigs(DocTexConfig)
|
||||||
wantMainModule()
|
wantMainModule()
|
||||||
CommandRst2TeX()
|
CommandRst2TeX()
|
||||||
|
of "jsondoc":
|
||||||
|
gCmd = cmdDoc
|
||||||
|
LoadConfigs(DocConfig)
|
||||||
|
wantMainModule()
|
||||||
|
DefineSymbol("nimdoc")
|
||||||
|
CommandJSON()
|
||||||
of "buildindex":
|
of "buildindex":
|
||||||
gCmd = cmdDoc
|
gCmd = cmdDoc
|
||||||
LoadConfigs(DocConfig)
|
LoadConfigs(DocConfig)
|
||||||
CommandBuildIndex()
|
CommandBuildIndex()
|
||||||
of "gendepend":
|
of "gendepend":
|
||||||
gCmd = cmdGenDepend
|
gCmd = cmdGenDepend
|
||||||
wantMainModule()
|
wantMainModule()
|
||||||
CommandGenDepend()
|
CommandGenDepend()
|
||||||
|
|
@ -400,16 +406,16 @@ proc MainCommand* =
|
||||||
gCmd = cmdCheck
|
gCmd = cmdCheck
|
||||||
wantMainModule()
|
wantMainModule()
|
||||||
CommandCheck()
|
CommandCheck()
|
||||||
of "parse":
|
of "parse":
|
||||||
gCmd = cmdParse
|
gCmd = cmdParse
|
||||||
wantMainModule()
|
wantMainModule()
|
||||||
discard parseFile(gProjectMainIdx)
|
discard parseFile(gProjectMainIdx)
|
||||||
of "scan":
|
of "scan":
|
||||||
gCmd = cmdScan
|
gCmd = cmdScan
|
||||||
wantMainModule()
|
wantMainModule()
|
||||||
CommandScan()
|
CommandScan()
|
||||||
MsgWriteln("Beware: Indentation tokens depend on the parser\'s state!")
|
MsgWriteln("Beware: Indentation tokens depend on the parser\'s state!")
|
||||||
of "i":
|
of "i":
|
||||||
gCmd = cmdInteractive
|
gCmd = cmdInteractive
|
||||||
CommandInteractive()
|
CommandInteractive()
|
||||||
of "e":
|
of "e":
|
||||||
|
|
@ -427,11 +433,11 @@ proc MainCommand* =
|
||||||
of "serve":
|
of "serve":
|
||||||
isServing = true
|
isServing = true
|
||||||
gGlobalOptions.incl(optCaasEnabled)
|
gGlobalOptions.incl(optCaasEnabled)
|
||||||
msgs.gErrorMax = high(int) # do not stop after first error
|
msgs.gErrorMax = high(int) # do not stop after first error
|
||||||
serve(MainCommand)
|
serve(MainCommand)
|
||||||
else:
|
else:
|
||||||
rawMessage(errInvalidCommandX, command)
|
rawMessage(errInvalidCommandX, command)
|
||||||
|
|
||||||
if (msgs.gErrorCounter == 0 and
|
if (msgs.gErrorCounter == 0 and
|
||||||
gCmd notin {cmdInterpret, cmdRun, cmdDump} and
|
gCmd notin {cmdInterpret, cmdRun, cmdDump} and
|
||||||
gVerbosity > 0):
|
gVerbosity > 0):
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,9 @@ when defined(gcc) and defined(windows):
|
||||||
else:
|
else:
|
||||||
{.link: "icons/nimrod_icon.o".}
|
{.link: "icons/nimrod_icon.o".}
|
||||||
|
|
||||||
import
|
import
|
||||||
commands, lexer, condsyms, options, msgs, nversion, nimconf, ropes,
|
commands, lexer, condsyms, options, msgs, nversion, nimconf, ropes,
|
||||||
extccomp, strutils, os, platform, main, parseopt, service
|
extccomp, strutils, os, osproc, platform, main, parseopt, service
|
||||||
|
|
||||||
when hasTinyCBackend:
|
when hasTinyCBackend:
|
||||||
import tccgen
|
import tccgen
|
||||||
|
|
@ -23,7 +23,7 @@ when hasTinyCBackend:
|
||||||
when defined(profiler) or defined(memProfiler):
|
when defined(profiler) or defined(memProfiler):
|
||||||
{.hint: "Profiling support is turned on!".}
|
{.hint: "Profiling support is turned on!".}
|
||||||
import nimprof
|
import nimprof
|
||||||
|
|
||||||
proc prependCurDir(f: string): string =
|
proc prependCurDir(f: string): string =
|
||||||
when defined(unix):
|
when defined(unix):
|
||||||
if os.isAbsolute(f): result = f
|
if os.isAbsolute(f): result = f
|
||||||
|
|
@ -61,12 +61,18 @@ proc HandleCmdLine() =
|
||||||
tccgen.run()
|
tccgen.run()
|
||||||
if optRun in gGlobalOptions:
|
if optRun in gGlobalOptions:
|
||||||
if gCmd == cmdCompileToJS:
|
if gCmd == cmdCompileToJS:
|
||||||
var ex = quoteIfContainsWhite(
|
var ex = quoteShell(
|
||||||
completeCFilePath(changeFileExt(gProjectFull, "js").prependCurDir))
|
completeCFilePath(changeFileExt(gProjectFull, "js").prependCurDir))
|
||||||
execExternalProgram("node " & ex & ' ' & service.arguments)
|
execExternalProgram("node " & ex & ' ' & service.arguments)
|
||||||
else:
|
else:
|
||||||
var ex = quoteIfContainsWhite(
|
var binPath: string
|
||||||
changeFileExt(gProjectFull, exeExt).prependCurDir)
|
if options.outFile.len > 0:
|
||||||
|
# If the user specified an outFile path, use that directly.
|
||||||
|
binPath = options.outFile.prependCurDir
|
||||||
|
else:
|
||||||
|
# Figure out ourselves a valid binary name.
|
||||||
|
binPath = changeFileExt(gProjectFull, exeExt).prependCurDir
|
||||||
|
var ex = quoteShell(binPath)
|
||||||
execExternalProgram(ex & ' ' & service.arguments)
|
execExternalProgram(ex & ' ' & service.arguments)
|
||||||
|
|
||||||
when defined(GC_setMaxPause):
|
when defined(GC_setMaxPause):
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,7 @@ const
|
||||||
NimExt* = "nim"
|
NimExt* = "nim"
|
||||||
RodExt* = "rod"
|
RodExt* = "rod"
|
||||||
HtmlExt* = "html"
|
HtmlExt* = "html"
|
||||||
|
JsonExt* = "json"
|
||||||
TexExt* = "tex"
|
TexExt* = "tex"
|
||||||
IniExt* = "ini"
|
IniExt* = "ini"
|
||||||
DefaultConfig* = "nimrod.cfg"
|
DefaultConfig* = "nimrod.cfg"
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,8 @@ const
|
||||||
wFatal, wDefine, wUndef, wCompile, wLink, wLinkSys, wPure, wPush, wPop,
|
wFatal, wDefine, wUndef, wCompile, wLink, wLinkSys, wPure, wPush, wPop,
|
||||||
wBreakpoint, wWatchpoint, wPassL, wPassC, wDeadCodeElim, wDeprecated,
|
wBreakpoint, wWatchpoint, wPassL, wPassC, wDeadCodeElim, wDeprecated,
|
||||||
wFloatChecks, wInfChecks, wNanChecks, wPragma, wEmit, wUnroll,
|
wFloatChecks, wInfChecks, wNanChecks, wPragma, wEmit, wUnroll,
|
||||||
wLinearScanEnd, wPatterns, wEffects, wNoForward, wComputedGoto}
|
wLinearScanEnd, wPatterns, wEffects, wNoForward, wComputedGoto,
|
||||||
|
wInjectStmt}
|
||||||
lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
|
lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
|
||||||
wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader,
|
wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader,
|
||||||
wDeprecated, wExtern, wThread, wImportcpp, wImportobjc, wNoStackFrame,
|
wDeprecated, wExtern, wThread, wImportcpp, wImportobjc, wNoStackFrame,
|
||||||
|
|
@ -722,6 +723,11 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
|
||||||
of wOperator:
|
of wOperator:
|
||||||
if sym == nil: invalidPragma(it)
|
if sym == nil: invalidPragma(it)
|
||||||
else: sym.position = expectIntLit(c, it)
|
else: sym.position = expectIntLit(c, it)
|
||||||
|
of wInjectStmt:
|
||||||
|
if it.kind != nkExprColonExpr:
|
||||||
|
localError(it.info, errExprExpected)
|
||||||
|
else:
|
||||||
|
it.sons[1] = c.semExpr(c, it.sons[1])
|
||||||
else: invalidPragma(it)
|
else: invalidPragma(it)
|
||||||
else: invalidPragma(it)
|
else: invalidPragma(it)
|
||||||
else: processNote(c, it)
|
else: processNote(c, it)
|
||||||
|
|
|
||||||
|
|
@ -380,7 +380,8 @@ proc analyseThreadProc*(prc: PSym) =
|
||||||
var formals = skipTypes(prc.typ, abstractInst).n
|
var formals = skipTypes(prc.typ, abstractInst).n
|
||||||
for i in 1 .. formals.len-1:
|
for i in 1 .. formals.len-1:
|
||||||
var formal = formals.sons[i].sym
|
var formal = formals.sons[i].sym
|
||||||
c.mapping[formal.id] = toTheirs # thread receives foreign data!
|
# the input is copied and belongs to the thread:
|
||||||
|
c.mapping[formal.id] = toMine
|
||||||
discard analyse(c, prc.getBody)
|
discard analyse(c, prc.getBody)
|
||||||
|
|
||||||
proc needsGlobalAnalysis*: bool =
|
proc needsGlobalAnalysis*: bool =
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ type
|
||||||
wPassc, wPassl, wBorrow, wDiscardable,
|
wPassc, wPassl, wBorrow, wDiscardable,
|
||||||
wFieldChecks,
|
wFieldChecks,
|
||||||
wWatchPoint, wSubsChar,
|
wWatchPoint, wSubsChar,
|
||||||
wAcyclic, wShallow, wUnroll, wLinearScanEnd, wComputedGoto,
|
wAcyclic, wShallow, wUnroll, wLinearScanEnd, wComputedGoto, wInjectStmt,
|
||||||
wWrite, wGensym, wInject, wDirty, wInheritable, wThreadVar, wEmit,
|
wWrite, wGensym, wInject, wDirty, wInheritable, wThreadVar, wEmit,
|
||||||
wNoStackFrame,
|
wNoStackFrame,
|
||||||
wImplicitStatic, wGlobal, wCodegenDecl,
|
wImplicitStatic, wGlobal, wCodegenDecl,
|
||||||
|
|
@ -142,7 +142,8 @@ const
|
||||||
"compiletime", "noinit",
|
"compiletime", "noinit",
|
||||||
"passc", "passl", "borrow", "discardable", "fieldchecks",
|
"passc", "passl", "borrow", "discardable", "fieldchecks",
|
||||||
"watchpoint",
|
"watchpoint",
|
||||||
"subschar", "acyclic", "shallow", "unroll", "linearscanend", "computedgoto",
|
"subschar", "acyclic", "shallow", "unroll", "linearscanend",
|
||||||
|
"computedgoto", "injectstmt",
|
||||||
"write", "gensym", "inject", "dirty", "inheritable", "threadvar", "emit",
|
"write", "gensym", "inject", "dirty", "inheritable", "threadvar", "emit",
|
||||||
"nostackframe", "implicitstatic", "global", "codegendecl",
|
"nostackframe", "implicitstatic", "global", "codegendecl",
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,11 @@
|
||||||
.. contents::
|
.. contents::
|
||||||
|
|
||||||
|
|
||||||
|
.. raw:: html
|
||||||
|
<blockquote><p>
|
||||||
|
"yes, I'm the creator" -- Araq, 2013-07-26 19:28:32.
|
||||||
|
</p></blockquote>
|
||||||
|
|
||||||
Nimrod differs from many other compilers in that it is really fast,
|
Nimrod differs from many other compilers in that it is really fast,
|
||||||
and being so fast makes it suited to provide external queries for
|
and being so fast makes it suited to provide external queries for
|
||||||
text editors about the source code being written. Through the
|
text editors about the source code being written. Through the
|
||||||
|
|
@ -522,21 +527,6 @@ At the moment idetools support is still in development so the test
|
||||||
suite is not integrated with the main test suite and you have to
|
suite is not integrated with the main test suite and you have to
|
||||||
run it manually. First you have to compile the tester::
|
run it manually. First you have to compile the tester::
|
||||||
|
|
||||||
$ cd my/nimrod/checkout
|
|
||||||
$ nimrod c tests/tester.nim
|
|
||||||
|
|
||||||
Running the tester without parameters will display some options.
|
|
||||||
To run the caas test suite (and other special tests) you need to
|
|
||||||
use the `special` command. You need to run this command from the
|
|
||||||
root of the checkout or it won't be able to open the required files::
|
|
||||||
|
|
||||||
$ ./tests/tester special
|
|
||||||
|
|
||||||
However this is a roundabout way of running the test suite. You can
|
|
||||||
also compile and run ``tests/caasdriver.nim`` manually. In fact,
|
|
||||||
running it manually will allow you to specify special parameters
|
|
||||||
too. Example::
|
|
||||||
|
|
||||||
$ cd my/nimrod/checkout/tests
|
$ cd my/nimrod/checkout/tests
|
||||||
$ nimrod c caasdriver.nim
|
$ nimrod c caasdriver.nim
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4708,7 +4708,11 @@ fatal pragma
|
||||||
------------
|
------------
|
||||||
The `fatal`:idx: pragma is used to make the compiler output an error message
|
The `fatal`:idx: pragma is used to make the compiler output an error message
|
||||||
with the given content. In contrast to the ``error`` pragma, compilation
|
with the given content. In contrast to the ``error`` pragma, compilation
|
||||||
is guaranteed to be aborted by this pragma.
|
is guaranteed to be aborted by this pragma. Example:
|
||||||
|
|
||||||
|
.. code-block:: nimrod
|
||||||
|
when not defined(objc):
|
||||||
|
{.fatal: "Compile this program with the objc command!".}
|
||||||
|
|
||||||
warning pragma
|
warning pragma
|
||||||
--------------
|
--------------
|
||||||
|
|
@ -5053,6 +5057,18 @@ Note that this pragma is somewhat of a misnomer: Other backends will provide
|
||||||
the same feature under the same name.
|
the same feature under the same name.
|
||||||
|
|
||||||
|
|
||||||
|
Extern pragma
|
||||||
|
-------------
|
||||||
|
Like ``exportc`` or ``importc`` the `extern`:idx: pragma affects name
|
||||||
|
mangling. The string literal passed to ``extern`` can be a format string:
|
||||||
|
|
||||||
|
.. code-block:: Nimrod
|
||||||
|
proc p(s: string) {.extern: "prefix$1".} =
|
||||||
|
echo s
|
||||||
|
|
||||||
|
In the example the external name of ``p`` is set to ``prefixp``.
|
||||||
|
|
||||||
|
|
||||||
Bycopy pragma
|
Bycopy pragma
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -468,6 +468,19 @@ proc is declared in the generated code:
|
||||||
|
|
||||||
proc myinterrupt() {.codegenDecl: "__interrupt $# $#$#".} =
|
proc myinterrupt() {.codegenDecl: "__interrupt $# $#$#".} =
|
||||||
echo "realistic interrupt handler"
|
echo "realistic interrupt handler"
|
||||||
|
|
||||||
|
|
||||||
|
InjectStmt pragma
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
The `injectStmt`:idx: pragma can be used to inject a statement before every
|
||||||
|
other statement in the current module. It is only supposed to be used for
|
||||||
|
debugging:
|
||||||
|
|
||||||
|
.. code-block:: nimrod
|
||||||
|
{.injectStmt: gcInvariants().}
|
||||||
|
|
||||||
|
# ... complex code here that produces crashes ...
|
||||||
|
|
||||||
|
|
||||||
LineDir option
|
LineDir option
|
||||||
|
|
|
||||||
11
examples/cgi/cgi_server.py
Normal file
11
examples/cgi/cgi_server.py
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
import BaseHTTPServer
|
||||||
|
import CGIHTTPServer
|
||||||
|
|
||||||
|
server = BaseHTTPServer.HTTPServer
|
||||||
|
handler = CGIHTTPServer.CGIHTTPRequestHandler
|
||||||
|
server_address = ('localhost', 8008)
|
||||||
|
handler.cgi_directories = ['/']
|
||||||
|
|
||||||
|
httpd = server(server_address, handler)
|
||||||
|
httpd.serve_forever()
|
||||||
5
examples/cgi/cgi_stacktrace.nim
Normal file
5
examples/cgi/cgi_stacktrace.nim
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
import cgi
|
||||||
|
cgi.setStackTraceStdout()
|
||||||
|
|
||||||
|
var a: string = nil
|
||||||
|
a.add "foobar"
|
||||||
7
examples/cgi/example.nim
Normal file
7
examples/cgi/example.nim
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
import cgi
|
||||||
|
|
||||||
|
write(stdout, "Content-type: text/html\n\n")
|
||||||
|
write(stdout, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\">\n")
|
||||||
|
write(stdout, "<html><head><title>Test</title></head><body>\n")
|
||||||
|
write(stdout, "Hello!")
|
||||||
|
writeln(stdout, "</body></html>")
|
||||||
|
|
@ -274,6 +274,8 @@ proc quote*(bl: stmt, op = "``"): PNimrodNode {.magic: "QuoteAst".}
|
||||||
##
|
##
|
||||||
## Example:
|
## Example:
|
||||||
##
|
##
|
||||||
|
## .. code-block:: nimrod
|
||||||
|
##
|
||||||
## macro check(ex: expr): stmt =
|
## macro check(ex: expr): stmt =
|
||||||
## # this is a simplified version of the check macro from the
|
## # this is a simplified version of the check macro from the
|
||||||
## # unittest module.
|
## # unittest module.
|
||||||
|
|
@ -296,6 +298,8 @@ template emit*(e: expr[string]): stmt =
|
||||||
## that should be inserted verbatim in the program
|
## that should be inserted verbatim in the program
|
||||||
## Example:
|
## Example:
|
||||||
##
|
##
|
||||||
|
## .. code-block:: nimrod
|
||||||
|
##
|
||||||
## emit("echo " & '"' & "hello world".toUpper & '"')
|
## emit("echo " & '"' & "hello world".toUpper & '"')
|
||||||
##
|
##
|
||||||
eval: result = e.parseStmt
|
eval: result = e.parseStmt
|
||||||
|
|
@ -480,6 +484,34 @@ proc newDotExpr*(a, b: PNimrodNode): PNimrodNode {.compileTime.} =
|
||||||
|
|
||||||
proc newIdentDefs*(name, kind: PNimrodNode;
|
proc newIdentDefs*(name, kind: PNimrodNode;
|
||||||
default = newEmptyNode()): PNimrodNode {.compileTime.} =
|
default = newEmptyNode()): PNimrodNode {.compileTime.} =
|
||||||
|
## Creates a new ``nnkIdentDefs`` node of a specific kind and value.
|
||||||
|
##
|
||||||
|
## ``nnkIdentDefs`` need to have at least three children, but they can have
|
||||||
|
## more: first comes a list of identifiers followed by a type and value
|
||||||
|
## nodes. This helper proc creates a three node subtree, the first subnode
|
||||||
|
## being a single identifier name. Both the ``kind`` node and ``default``
|
||||||
|
## (value) nodes may be empty depending on where the ``nnkIdentDefs``
|
||||||
|
## appears: tuple or object definitions will have an empty ``default`` node,
|
||||||
|
## ``let`` or ``var`` blocks may have an empty ``kind`` node if the
|
||||||
|
## identifier is being assigned a value. Example:
|
||||||
|
##
|
||||||
|
## .. code-block:: nimrod
|
||||||
|
##
|
||||||
|
## var varSection = newNimNode(nnkVarSection).add(
|
||||||
|
## newIdentDefs(ident("a"), ident("string")),
|
||||||
|
## newIdentDefs(ident("b"), newEmptyNode(), newLit(3)))
|
||||||
|
## # --> var
|
||||||
|
## # a: string
|
||||||
|
## # b = 3
|
||||||
|
##
|
||||||
|
## If you need to create multiple identifiers you need to use the lower level
|
||||||
|
## ``newNimNode``:
|
||||||
|
##
|
||||||
|
## .. code-block:: nimrod
|
||||||
|
##
|
||||||
|
## result = newNimNode(nnkIdentDefs).add(
|
||||||
|
## ident("a"), ident("b"), ident("c"), ident("string"),
|
||||||
|
## newStrLitNode("Hello"))
|
||||||
newNimNode(nnkIdentDefs).add(name, kind, default)
|
newNimNode(nnkIdentDefs).add(name, kind, default)
|
||||||
|
|
||||||
proc newNilLit*(): PNimrodNode {.compileTime.} =
|
proc newNilLit*(): PNimrodNode {.compileTime.} =
|
||||||
|
|
@ -503,11 +535,11 @@ from strutils import cmpIgnoreStyle, format
|
||||||
proc expectKind*(n: PNimrodNode; k: set[TNimrodNodeKind]) {.compileTime.} =
|
proc expectKind*(n: PNimrodNode; k: set[TNimrodNodeKind]) {.compileTime.} =
|
||||||
assert n.kind in k, "Expected one of $1, got $2".format(k, n.kind)
|
assert n.kind in k, "Expected one of $1, got $2".format(k, n.kind)
|
||||||
|
|
||||||
proc newProc*(name = newEmptyNode(); params: openarray[PNimrodNode] = [];
|
proc newProc*(name = newEmptyNode(); params: openarray[PNimrodNode] = [newEmptyNode()];
|
||||||
body: PNimrodNode = newStmtList(), procType = nnkProcDef): PNimrodNode {.compileTime.} =
|
body: PNimrodNode = newStmtList(), procType = nnkProcDef): PNimrodNode {.compileTime.} =
|
||||||
## shortcut for creating a new proc
|
## shortcut for creating a new proc
|
||||||
##
|
##
|
||||||
## The ``params`` array should start with the return type of the proc,
|
## The ``params`` array must start with the return type of the proc,
|
||||||
## followed by a list of IdentDefs which specify the params.
|
## followed by a list of IdentDefs which specify the params.
|
||||||
assert procType in RoutineNodes
|
assert procType in RoutineNodes
|
||||||
result = newNimNode(procType).add(
|
result = newNimNode(procType).add(
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,18 @@
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
#
|
#
|
||||||
|
|
||||||
## This module implements a generator of HTML/Latex from `reStructuredText`:idx:.
|
## This module implements a generator of HTML/Latex from
|
||||||
|
## `reStructuredText`:idx: (see http://docutils.sourceforge.net/rst.html for
|
||||||
|
## information on this markup syntax). You can generate HTML output through the
|
||||||
|
## convenience proc ``rstToHtml``, which provided an input string with rst
|
||||||
|
## markup returns a string with the generated HTML. The final output is meant
|
||||||
|
## to be embedded inside a full document you provide yourself, so it won't
|
||||||
|
## contain the usual ``<header>`` or ``<body>`` parts.
|
||||||
|
##
|
||||||
|
## You can also create a ``TRstGenerator`` structure and populate it with the
|
||||||
|
## other lower level methods to finally build complete documents. This requires
|
||||||
|
## many options and tweaking, but you are not limited to snippets and can
|
||||||
|
## generate `LaTeX documents <https://en.wikipedia.org/wiki/LaTeX>`_ too.
|
||||||
|
|
||||||
import strutils, os, hashes, strtabs, rstast, rst, highlite
|
import strutils, os, hashes, strtabs, rstast, rst, highlite
|
||||||
|
|
||||||
|
|
@ -40,13 +51,51 @@ type
|
||||||
filename*: string
|
filename*: string
|
||||||
meta*: array[TMetaEnum, string]
|
meta*: array[TMetaEnum, string]
|
||||||
|
|
||||||
PDoc = var TRstGenerator
|
PDoc = var TRstGenerator ## Alias to type less.
|
||||||
|
|
||||||
proc initRstGenerator*(g: var TRstGenerator, target: TOutputTarget,
|
proc initRstGenerator*(g: var TRstGenerator, target: TOutputTarget,
|
||||||
config: PStringTable, filename: string,
|
config: PStringTable, filename: string,
|
||||||
options: TRstParseOptions,
|
options: TRstParseOptions,
|
||||||
findFile: TFindFileHandler,
|
findFile: TFindFileHandler,
|
||||||
msgHandler: TMsgHandler) =
|
msgHandler: TMsgHandler) =
|
||||||
|
## Initializes a ``TRstGenerator``.
|
||||||
|
##
|
||||||
|
## You need to call this before using a ``TRstGenerator`` with any other
|
||||||
|
## procs in this module. Pass a non ``nil`` ``PStringTable`` value as
|
||||||
|
## ``config`` with parameters used by the HTML output generator. If you
|
||||||
|
## don't know what to use, pass the results of the ``defaultConfig()`` proc.
|
||||||
|
## The ``filename`` is symbolic and used only for error reporting, you can
|
||||||
|
## pass any non ``nil`` string here.
|
||||||
|
##
|
||||||
|
## The ``TRstParseOptions``, ``TFindFileHandler`` and ``TMsgHandler`` types
|
||||||
|
## are defined in the the `packages/docutils/rst module <rst.html>`_.
|
||||||
|
## ``options`` selects the behaviour of the rst parser.
|
||||||
|
##
|
||||||
|
## ``findFile`` is a proc used by the rst ``include`` directive among others.
|
||||||
|
## The purpose of this proc is to mangle or filter paths. It receives paths
|
||||||
|
## specified in the rst document and has to return a valid path to existing
|
||||||
|
## files or the empty string otherwise. If you pass ``nil``, a default proc
|
||||||
|
## will be used which given a path returns the input path only if the file
|
||||||
|
## exists. One use for this proc is to transform relative paths found in the
|
||||||
|
## document to absolute path, useful if the rst file and the resources it
|
||||||
|
## references are not in the same directory as the current working directory.
|
||||||
|
##
|
||||||
|
## The ``msgHandler`` is a proc used for user error reporting. It will be
|
||||||
|
## called with the filename, line, col, and type of any error found during
|
||||||
|
## parsing. If you pass ``nil``, a default message handler will be used which
|
||||||
|
## writes the messages to the standard output.
|
||||||
|
##
|
||||||
|
## Example:
|
||||||
|
##
|
||||||
|
## .. code-block:: nimrod
|
||||||
|
##
|
||||||
|
## import packages/docutils/rstgen
|
||||||
|
##
|
||||||
|
## var gen: TRstGenerator
|
||||||
|
##
|
||||||
|
## gen.initRstGenerator(outHtml, defaultConfig(),
|
||||||
|
## "filename", {}, nil, nil)
|
||||||
|
|
||||||
g.config = config
|
g.config = config
|
||||||
g.target = target
|
g.target = target
|
||||||
g.tocPart = @[]
|
g.tocPart = @[]
|
||||||
|
|
@ -147,7 +196,19 @@ proc dispA(target: TOutputTarget, dest: var string,
|
||||||
if target != outLatex: addf(dest, xml, args)
|
if target != outLatex: addf(dest, xml, args)
|
||||||
else: addf(dest, tex, args)
|
else: addf(dest, tex, args)
|
||||||
|
|
||||||
proc renderRstToOut*(d: PDoc, n: PRstNode, result: var string)
|
proc renderRstToOut*(d: var TRstGenerator, n: PRstNode, result: var string)
|
||||||
|
## Writes into ``result`` the rst ast ``n`` using the ``d`` configuration.
|
||||||
|
##
|
||||||
|
## Before using this proc you need to initialise a ``TRstGenerator`` with
|
||||||
|
## ``initRstGenerator`` and parse a rst file with ``rstParse`` from the
|
||||||
|
## `packages/docutils/rst module <rst.html>`_. Example:
|
||||||
|
##
|
||||||
|
## .. code-block:: nimrod
|
||||||
|
##
|
||||||
|
## # ...configure gen and rst vars...
|
||||||
|
## var generatedHTML = ""
|
||||||
|
## renderRstToOut(gen, rst, generatedHTML)
|
||||||
|
## echo generatedHTML
|
||||||
|
|
||||||
proc renderAux(d: PDoc, n: PRstNode, result: var string) =
|
proc renderAux(d: PDoc, n: PRstNode, result: var string) =
|
||||||
for i in countup(0, len(n)-1): renderRstToOut(d, n.sons[i], result)
|
for i in countup(0, len(n)-1): renderRstToOut(d, n.sons[i], result)
|
||||||
|
|
@ -162,7 +223,7 @@ proc renderAux(d: PDoc, n: PRstNode, frmtA, frmtB: string, result: var string) =
|
||||||
|
|
||||||
# ---------------- index handling --------------------------------------------
|
# ---------------- index handling --------------------------------------------
|
||||||
|
|
||||||
proc setIndexTerm*(d: PDoc, id, term: string) =
|
proc setIndexTerm*(d: var TRstGenerator, id, term: string) =
|
||||||
d.theIndex.add(term)
|
d.theIndex.add(term)
|
||||||
d.theIndex.add('\t')
|
d.theIndex.add('\t')
|
||||||
let htmlFile = changeFileExt(extractFilename(d.filename), HtmlExt)
|
let htmlFile = changeFileExt(extractFilename(d.filename), HtmlExt)
|
||||||
|
|
@ -295,7 +356,7 @@ proc renderTocEntry(d: PDoc, e: TTocEntry, result: var string) =
|
||||||
"<li><a class=\"reference\" id=\"$1_toc\" href=\"#$1\">$2</a></li>\n",
|
"<li><a class=\"reference\" id=\"$1_toc\" href=\"#$1\">$2</a></li>\n",
|
||||||
"\\item\\label{$1_toc} $2\\ref{$1}\n", [e.refname, e.header])
|
"\\item\\label{$1_toc} $2\\ref{$1}\n", [e.refname, e.header])
|
||||||
|
|
||||||
proc renderTocEntries*(d: PDoc, j: var int, lvl: int, result: var string) =
|
proc renderTocEntries*(d: var TRstGenerator, j: var int, lvl: int, result: var string) =
|
||||||
var tmp = ""
|
var tmp = ""
|
||||||
while j <= high(d.tocPart):
|
while j <= high(d.tocPart):
|
||||||
var a = abs(d.tocPart[j].n.level)
|
var a = abs(d.tocPart[j].n.level)
|
||||||
|
|
@ -678,8 +739,26 @@ $content
|
||||||
|
|
||||||
proc rstToHtml*(s: string, options: TRstParseOptions,
|
proc rstToHtml*(s: string, options: TRstParseOptions,
|
||||||
config: PStringTable): string =
|
config: PStringTable): string =
|
||||||
## exported for *nimforum*.
|
## Converts an input rst string into embeddable HTML.
|
||||||
|
##
|
||||||
|
## This convenience proc parses any input string using rst markup (it doesn't
|
||||||
|
## have to be a full document!) and returns an embeddable piece of HTML. The
|
||||||
|
## proc is meant to be used in *online* environments without access to a
|
||||||
|
## meaningful filesystem, and therefore rst ``include`` like directives won't
|
||||||
|
## work. For an explanation of the ``config`` parameter see the
|
||||||
|
## ``initRstGenerator`` proc. Example:
|
||||||
|
##
|
||||||
|
## .. code-block:: nimrod
|
||||||
|
## import packages/docutils/rstgen, strtabs
|
||||||
|
##
|
||||||
|
## echo rstToHtml("*Hello* **world**!", {},
|
||||||
|
## newStringTable(modeStyleInsensitive))
|
||||||
|
## # --> <em>Hello</em> <strong>world</strong>!
|
||||||
|
##
|
||||||
|
## If you need to allow the rst ``include`` directive or tweak the generated
|
||||||
|
## output you have to create your own ``TRstGenerator`` with
|
||||||
|
## ``initRstGenerator`` and related procs.
|
||||||
|
|
||||||
proc myFindFile(filename: string): string =
|
proc myFindFile(filename: string): string =
|
||||||
# we don't find any files in online mode:
|
# we don't find any files in online mode:
|
||||||
result = ""
|
result = ""
|
||||||
|
|
@ -692,4 +771,8 @@ proc rstToHtml*(s: string, options: TRstParseOptions,
|
||||||
var rst = rstParse(s, filen, 0, 1, dummyHasToc, options)
|
var rst = rstParse(s, filen, 0, 1, dummyHasToc, options)
|
||||||
result = ""
|
result = ""
|
||||||
renderRstToOut(d, rst, result)
|
renderRstToOut(d, rst, result)
|
||||||
|
|
||||||
|
|
||||||
|
when isMainModule:
|
||||||
|
echo rstToHtml("*Hello* **world**!", {},
|
||||||
|
newStringTable(modeStyleInsensitive))
|
||||||
|
|
|
||||||
|
|
@ -33,10 +33,10 @@ proc openDefaultBrowser*(url: string) =
|
||||||
else:
|
else:
|
||||||
discard ShellExecuteA(0'i32, "open", url, nil, nil, SW_SHOWNORMAL)
|
discard ShellExecuteA(0'i32, "open", url, nil, nil, SW_SHOWNORMAL)
|
||||||
elif defined(macosx):
|
elif defined(macosx):
|
||||||
discard execShellCmd("open " & quoteIfContainsWhite(url))
|
discard execShellCmd("open " & quoteShell(url))
|
||||||
else:
|
else:
|
||||||
const attempts = ["gnome-open ", "kde-open ", "xdg-open "]
|
const attempts = ["gnome-open ", "kde-open ", "xdg-open "]
|
||||||
var u = quoteIfContainsWhite(url)
|
var u = quoteShell(url)
|
||||||
for a in items(attempts):
|
for a in items(attempts):
|
||||||
if execShellCmd(a & u) == 0: return
|
if execShellCmd(a & u) == 0: return
|
||||||
for b in getEnv("BROWSER").string.split(PathSep):
|
for b in getEnv("BROWSER").string.split(PathSep):
|
||||||
|
|
|
||||||
|
|
@ -342,16 +342,35 @@ proc writeContentType*() =
|
||||||
##
|
##
|
||||||
## .. code-block:: Nimrod
|
## .. code-block:: Nimrod
|
||||||
## write(stdout, "Content-type: text/html\n\n")
|
## write(stdout, "Content-type: text/html\n\n")
|
||||||
##
|
|
||||||
## It also modifies the debug stack traces so that they contain
|
|
||||||
## ``<br />`` and are easily readable in a browser.
|
|
||||||
write(stdout, "Content-type: text/html\n\n")
|
write(stdout, "Content-type: text/html\n\n")
|
||||||
system.stackTraceNewLine = "<br />\n"
|
|
||||||
|
|
||||||
proc setStackTraceNewLine*() =
|
proc resetForStacktrace() =
|
||||||
## Modifies the debug stack traces so that they contain
|
stdout.write """<!--: spam
|
||||||
## ``<br />`` and are easily readable in a browser.
|
Content-Type: text/html
|
||||||
system.stackTraceNewLine = "<br />\n"
|
|
||||||
|
<body bgcolor=#f0f0f8><font color=#f0f0f8 size=-5> -->
|
||||||
|
<body bgcolor=#f0f0f8><font color=#f0f0f8 size=-5> --> -->
|
||||||
|
</font> </font> </font> </script> </object> </blockquote> </pre>
|
||||||
|
</table> </table> </table> </table> </table> </font> </font> </font>
|
||||||
|
"""
|
||||||
|
|
||||||
|
proc writeErrorMessage*(data: string) =
|
||||||
|
## Tries to reset browser state and writes `data` to stdout in
|
||||||
|
## <plaintext> tag.
|
||||||
|
resetForStacktrace()
|
||||||
|
# We use <plaintext> here, instead of escaping, so stacktrace can
|
||||||
|
# be understood by human looking at source.
|
||||||
|
stdout.write("<plaintext>\n")
|
||||||
|
stdout.write(data)
|
||||||
|
|
||||||
|
proc setStackTraceStdout*() =
|
||||||
|
## Makes Nimrod output stacktraces to stdout, instead of server log.
|
||||||
|
errorMessageWriter = writeErrorMessage
|
||||||
|
|
||||||
|
proc setStackTraceNewLine*() {.deprecated.} =
|
||||||
|
## Makes Nimrod output stacktraces to stdout, instead of server log.
|
||||||
|
## Depracated alias for setStackTraceStdout.
|
||||||
|
setStackTraceStdout()
|
||||||
|
|
||||||
proc setCookie*(name, value: string) =
|
proc setCookie*(name, value: string) =
|
||||||
## Sets a cookie.
|
## Sets a cookie.
|
||||||
|
|
@ -374,4 +393,3 @@ when isMainModule:
|
||||||
const test1 = "abc\L+def xyz"
|
const test1 = "abc\L+def xyz"
|
||||||
assert UrlEncode(test1) == "abc%0A%2Bdef+xyz"
|
assert UrlEncode(test1) == "abc%0A%2Bdef+xyz"
|
||||||
assert UrlDecode(UrlEncode(test1)) == test1
|
assert UrlDecode(UrlEncode(test1)) == test1
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -956,17 +956,37 @@ proc moveFile*(source, dest: string) {.rtl, extern: "nos$1",
|
||||||
if crename(source, dest) != 0'i32:
|
if crename(source, dest) != 0'i32:
|
||||||
raise newException(EOS, $strerror(errno))
|
raise newException(EOS, $strerror(errno))
|
||||||
|
|
||||||
when not defined(ENOENT):
|
when not defined(ENOENT) and not defined(Windows):
|
||||||
var ENOENT {.importc, header: "<errno.h>".}: cint
|
var ENOENT {.importc, header: "<errno.h>".}: cint
|
||||||
|
|
||||||
|
when defined(Windows):
|
||||||
|
when useWinUnicode:
|
||||||
|
template DeleteFile(file: expr): expr {.immediate.} = DeleteFileW(file)
|
||||||
|
template SetFileAttributes(file, attrs: expr): expr {.immediate.} =
|
||||||
|
SetFileAttributesW(file, attrs)
|
||||||
|
else:
|
||||||
|
template DeleteFile(file: expr): expr {.immediate.} = DeleteFileA(file)
|
||||||
|
template SetFileAttributes(file, attrs: expr): expr {.immediate.} =
|
||||||
|
SetFileAttributesA(file, attrs)
|
||||||
|
|
||||||
proc removeFile*(file: string) {.rtl, extern: "nos$1", tags: [FWriteDir].} =
|
proc removeFile*(file: string) {.rtl, extern: "nos$1", tags: [FWriteDir].} =
|
||||||
## Removes the `file`. If this fails, `EOS` is raised. This does not fail
|
## Removes the `file`. If this fails, `EOS` is raised. This does not fail
|
||||||
## if the file never existed in the first place.
|
## if the file never existed in the first place.
|
||||||
## On Windows, ignores the read-only attribute.
|
## On Windows, ignores the read-only attribute.
|
||||||
when defined(Windows):
|
when defined(Windows):
|
||||||
setFilePermissions(file, {fpUserWrite})
|
when useWinUnicode:
|
||||||
if cremove(file) != 0'i32 and errno != ENOENT:
|
let f = newWideCString(file)
|
||||||
raise newException(EOS, $strerror(errno))
|
else:
|
||||||
|
let f = file
|
||||||
|
if DeleteFile(f) == 0:
|
||||||
|
if GetLastError() == ERROR_ACCESS_DENIED:
|
||||||
|
if SetFileAttributes(f, FILE_ATTRIBUTE_NORMAL) == 0:
|
||||||
|
OSError(OSLastError())
|
||||||
|
if DeleteFile(f) == 0:
|
||||||
|
OSError(OSLastError())
|
||||||
|
else:
|
||||||
|
if cremove(file) != 0'i32 and errno != ENOENT:
|
||||||
|
raise newException(EOS, $strerror(errno))
|
||||||
|
|
||||||
proc execShellCmd*(command: string): int {.rtl, extern: "nos$1",
|
proc execShellCmd*(command: string): int {.rtl, extern: "nos$1",
|
||||||
tags: [FExecIO].} =
|
tags: [FExecIO].} =
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,58 @@ type
|
||||||
poStdErrToStdOut, ## merge stdout and stderr to the stdout stream
|
poStdErrToStdOut, ## merge stdout and stderr to the stdout stream
|
||||||
poParentStreams ## use the parent's streams
|
poParentStreams ## use the parent's streams
|
||||||
|
|
||||||
|
proc quoteShellWindows*(s: string): string {.noSideEffect, rtl, extern: "nosp$1".} =
|
||||||
|
## Quote s, so it can be safely passed to Windows API.
|
||||||
|
## Based on Python's subprocess.list2cmdline
|
||||||
|
## See http://msdn.microsoft.com/en-us/library/17w5ykft.aspx
|
||||||
|
let needQuote = {' ', '\t'} in s or s.len == 0
|
||||||
|
|
||||||
|
result = ""
|
||||||
|
var backslashBuff = ""
|
||||||
|
if needQuote:
|
||||||
|
result.add("\"")
|
||||||
|
|
||||||
|
for c in s:
|
||||||
|
if c == '\\':
|
||||||
|
backslashBuff.add(c)
|
||||||
|
elif c == '\"':
|
||||||
|
result.add(backslashBuff)
|
||||||
|
result.add(backslashBuff)
|
||||||
|
backslashBuff.setLen(0)
|
||||||
|
result.add("\\\"")
|
||||||
|
else:
|
||||||
|
if backslashBuff.len != 0:
|
||||||
|
result.add(backslashBuff)
|
||||||
|
backslashBuff.setLen(0)
|
||||||
|
result.add(c)
|
||||||
|
|
||||||
|
if needQuote:
|
||||||
|
result.add("\"")
|
||||||
|
|
||||||
|
proc quoteShellPosix*(s: string): string {.noSideEffect, rtl, extern: "nosp$1".} =
|
||||||
|
## Quote s, so it can be safely passed to POSIX shell.
|
||||||
|
## Based on Python's pipes.quote
|
||||||
|
const safeUnixChars = {'%', '+', '-', '.', '/', '_', ':', '=', '@',
|
||||||
|
'0'..'9', 'A'..'Z', 'a'..'z'}
|
||||||
|
if s.len == 0:
|
||||||
|
return "''"
|
||||||
|
|
||||||
|
let safe = s.allCharsInSet(safeUnixChars)
|
||||||
|
|
||||||
|
if safe:
|
||||||
|
return s
|
||||||
|
else:
|
||||||
|
return "'" & s.replace("'", "'\"'\"'") & "'"
|
||||||
|
|
||||||
|
proc quoteShell*(s: string): string {.noSideEffect, rtl, extern: "nosp$1".} =
|
||||||
|
## Quote s, so it can be safely passed to shell.
|
||||||
|
when defined(Windows):
|
||||||
|
return quoteShellWindows(s)
|
||||||
|
elif defined(posix):
|
||||||
|
return quoteShellPosix(s)
|
||||||
|
else:
|
||||||
|
{.error:"quoteShell is not supported on your system".}
|
||||||
|
|
||||||
proc execProcess*(command: string,
|
proc execProcess*(command: string,
|
||||||
options: set[TProcessOption] = {poStdErrToStdOut,
|
options: set[TProcessOption] = {poStdErrToStdOut,
|
||||||
poUseShell}): TaintedString {.
|
poUseShell}): TaintedString {.
|
||||||
|
|
@ -307,10 +359,10 @@ when defined(Windows) and not defined(useNimRtl):
|
||||||
result.writeDataImpl = hsWriteData
|
result.writeDataImpl = hsWriteData
|
||||||
|
|
||||||
proc buildCommandLine(a: string, args: openarray[string]): cstring =
|
proc buildCommandLine(a: string, args: openarray[string]): cstring =
|
||||||
var res = quoteIfContainsWhite(a)
|
var res = quoteShell(a)
|
||||||
for i in 0..high(args):
|
for i in 0..high(args):
|
||||||
res.add(' ')
|
res.add(' ')
|
||||||
res.add(quoteIfContainsWhite(args[i]))
|
res.add(quoteShell(args[i]))
|
||||||
result = cast[cstring](alloc0(res.len+1))
|
result = cast[cstring](alloc0(res.len+1))
|
||||||
copyMem(result, cstring(res), res.len)
|
copyMem(result, cstring(res), res.len)
|
||||||
|
|
||||||
|
|
@ -510,10 +562,10 @@ elif not defined(useNimRtl):
|
||||||
writeIdx = 1
|
writeIdx = 1
|
||||||
|
|
||||||
proc addCmdArgs(command: string, args: openarray[string]): string =
|
proc addCmdArgs(command: string, args: openarray[string]): string =
|
||||||
result = quoteIfContainsWhite(command)
|
result = quoteShell(command)
|
||||||
for i in 0 .. high(args):
|
for i in 0 .. high(args):
|
||||||
add(result, " ")
|
add(result, " ")
|
||||||
add(result, quoteIfContainsWhite(args[i]))
|
add(result, quoteShell(args[i]))
|
||||||
|
|
||||||
proc toCStringArray(b, a: openarray[string]): cstringArray =
|
proc toCStringArray(b, a: openarray[string]): cstringArray =
|
||||||
result = cast[cstringArray](alloc0((a.len + b.len + 1) * sizeof(cstring)))
|
result = cast[cstringArray](alloc0((a.len + b.len + 1) * sizeof(cstring)))
|
||||||
|
|
@ -792,5 +844,14 @@ proc execCmdEx*(command: string, options: set[TProcessOption] = {
|
||||||
close(p)
|
close(p)
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
var x = execProcess("gcc -v")
|
assert quoteShellWindows("aaa") == "aaa"
|
||||||
echo "ECHO ", x
|
assert quoteShellWindows("aaa\"") == "aaa\\\""
|
||||||
|
assert quoteShellWindows("") == "\"\""
|
||||||
|
|
||||||
|
assert quoteShellPosix("aaa") == "aaa"
|
||||||
|
assert quoteShellPosix("aaa a") == "'aaa a'"
|
||||||
|
assert quoteShellPosix("") == "''"
|
||||||
|
assert quoteShellPosix("a'a") == "'a'\"'\"'a'"
|
||||||
|
|
||||||
|
when defined(posix):
|
||||||
|
assert quoteShell("") == "''"
|
||||||
|
|
|
||||||
|
|
@ -709,9 +709,11 @@ proc rfind*(s, sub: string, start: int = -1): int {.noSideEffect.} =
|
||||||
if result != -1: return
|
if result != -1: return
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
proc quoteIfContainsWhite*(s: string): string =
|
proc quoteIfContainsWhite*(s: string): string {.deprecated.} =
|
||||||
## returns ``'"' & s & '"'`` if `s` contains a space and does not
|
## returns ``'"' & s & '"'`` if `s` contains a space and does not
|
||||||
## start with a quote, else returns `s`
|
## start with a quote, else returns `s`
|
||||||
|
## DEPRECATED as it was confused for shell quoting function.
|
||||||
|
## For this application use osproc.quoteShell.
|
||||||
if find(s, {' ', '\t'}) >= 0 and s[0] != '"':
|
if find(s, {' ', '\t'}) >= 0 and s[0] != '"':
|
||||||
result = '"' & s & '"'
|
result = '"' & s & '"'
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -923,6 +923,10 @@ proc quit*(errorcode: int = QuitSuccess) {.
|
||||||
## The proc ``quit(QuitSuccess)`` is called implicitly when your nimrod
|
## The proc ``quit(QuitSuccess)`` is called implicitly when your nimrod
|
||||||
## program finishes without incident. A raised unhandled exception is
|
## program finishes without incident. A raised unhandled exception is
|
||||||
## equivalent to calling ``quit(QuitFailure)``.
|
## equivalent to calling ``quit(QuitFailure)``.
|
||||||
|
##
|
||||||
|
## Note that this is a *runtime* call and using ``quit`` inside a macro won't
|
||||||
|
## have any compile time effect. If you need to stop the compiler inside a
|
||||||
|
## macro, use the ``error`` or ``fatal`` pragmas.
|
||||||
|
|
||||||
template sysAssert(cond: bool, msg: string) =
|
template sysAssert(cond: bool, msg: string) =
|
||||||
when defined(useSysAssert):
|
when defined(useSysAssert):
|
||||||
|
|
@ -1947,15 +1951,13 @@ when not defined(JS): #and not defined(NimrodVM):
|
||||||
## The standard output stream.
|
## The standard output stream.
|
||||||
stderr* {.importc: "stderr", header: "<stdio.h>".}: TFile
|
stderr* {.importc: "stderr", header: "<stdio.h>".}: TFile
|
||||||
## The standard error stream.
|
## The standard error stream.
|
||||||
##
|
|
||||||
## Note: In my opinion, this should not be used -- the concept of a
|
when defined(useStdoutAsStdmsg):
|
||||||
## separate error stream is a design flaw of UNIX. A separate *message
|
template stdmsg*: TFile = stdout
|
||||||
## stream* is a good idea, but since it is named ``stderr`` there are few
|
else:
|
||||||
## programs out there that distinguish properly between ``stdout`` and
|
template stdmsg*: TFile = stderr
|
||||||
## ``stderr``. So, that's what you get if you don't name your variables
|
## Template which expands to either stdout or stderr depending on
|
||||||
## appropriately. It also annoys people if redirection
|
## `useStdoutAsStdmsg` compile-time switch.
|
||||||
## via ``>output.txt`` does not work because the program writes
|
|
||||||
## to ``stderr``.
|
|
||||||
|
|
||||||
proc Open*(f: var TFile, filename: string,
|
proc Open*(f: var TFile, filename: string,
|
||||||
mode: TFileMode = fmRead, bufSize: int = -1): Bool {.tags: [].}
|
mode: TFileMode = fmRead, bufSize: int = -1): Bool {.tags: [].}
|
||||||
|
|
|
||||||
|
|
@ -760,7 +760,7 @@ proc getOccupiedMem(a: TMemRegion): int {.inline.} =
|
||||||
# ---------------------- thread memory region -------------------------------
|
# ---------------------- thread memory region -------------------------------
|
||||||
|
|
||||||
template InstantiateForRegion(allocator: expr) =
|
template InstantiateForRegion(allocator: expr) =
|
||||||
when false:
|
when defined(fulldebug):
|
||||||
proc interiorAllocatedPtr*(p: pointer): pointer =
|
proc interiorAllocatedPtr*(p: pointer): pointer =
|
||||||
result = interiorAllocatedPtr(allocator, p)
|
result = interiorAllocatedPtr(allocator, p)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,14 +11,13 @@
|
||||||
# use the heap (and nor exceptions) do not include the GC or memory allocator.
|
# use the heap (and nor exceptions) do not include the GC or memory allocator.
|
||||||
|
|
||||||
var
|
var
|
||||||
stackTraceNewLine*: string ## undocumented feature; it is replaced by ``<br>``
|
errorMessageWriter*: (proc(msg: string): void {.tags: [FWriteIO].})
|
||||||
## for CGI applications
|
## Function that will be called
|
||||||
|
## instead of stdmsg.write when printing stacktrace.
|
||||||
template stackTraceNL: expr =
|
## Unstable API.
|
||||||
(if IsNil(stackTraceNewLine): "\n" else: stackTraceNewLine)
|
|
||||||
|
|
||||||
when not defined(windows) or not defined(guiapp):
|
when not defined(windows) or not defined(guiapp):
|
||||||
proc writeToStdErr(msg: CString) = write(stdout, msg)
|
proc writeToStdErr(msg: CString) = write(stdmsg, msg)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
proc MessageBoxA(hWnd: cint, lpText, lpCaption: cstring, uType: int): int32 {.
|
proc MessageBoxA(hWnd: cint, lpText, lpCaption: cstring, uType: int): int32 {.
|
||||||
|
|
@ -27,6 +26,12 @@ else:
|
||||||
proc writeToStdErr(msg: CString) =
|
proc writeToStdErr(msg: CString) =
|
||||||
discard MessageBoxA(0, msg, nil, 0)
|
discard MessageBoxA(0, msg, nil, 0)
|
||||||
|
|
||||||
|
proc showErrorMessage(data: cstring) =
|
||||||
|
if errorMessageWriter != nil:
|
||||||
|
errorMessageWriter($data)
|
||||||
|
else:
|
||||||
|
writeToStdErr(data)
|
||||||
|
|
||||||
proc chckIndx(i, a, b: int): int {.inline, compilerproc.}
|
proc chckIndx(i, a, b: int): int {.inline, compilerproc.}
|
||||||
proc chckRange(i, a, b: int): int {.inline, compilerproc.}
|
proc chckRange(i, a, b: int): int {.inline, compilerproc.}
|
||||||
proc chckRangeF(x, a, b: float): float {.inline, compilerproc.}
|
proc chckRangeF(x, a, b: float): float {.inline, compilerproc.}
|
||||||
|
|
@ -111,7 +116,7 @@ when defined(nativeStacktrace) and nativeStackTraceSupported:
|
||||||
add(s, tempDlInfo.dli_sname)
|
add(s, tempDlInfo.dli_sname)
|
||||||
else:
|
else:
|
||||||
add(s, '?')
|
add(s, '?')
|
||||||
add(s, stackTraceNL)
|
add(s, "\n")
|
||||||
else:
|
else:
|
||||||
if dlresult != 0 and tempDlInfo.dli_sname != nil and
|
if dlresult != 0 and tempDlInfo.dli_sname != nil and
|
||||||
c_strcmp(tempDlInfo.dli_sname, "signalHandler") == 0'i32:
|
c_strcmp(tempDlInfo.dli_sname, "signalHandler") == 0'i32:
|
||||||
|
|
@ -172,21 +177,18 @@ proc auxWriteStackTrace(f: PFrame, s: var string) =
|
||||||
add(s, ')')
|
add(s, ')')
|
||||||
for k in 1..max(1, 25-(s.len-oldLen)): add(s, ' ')
|
for k in 1..max(1, 25-(s.len-oldLen)): add(s, ' ')
|
||||||
add(s, tempFrames[j].procname)
|
add(s, tempFrames[j].procname)
|
||||||
add(s, stackTraceNL)
|
add(s, "\n")
|
||||||
|
|
||||||
when hasSomeStackTrace:
|
when hasSomeStackTrace:
|
||||||
proc rawWriteStackTrace(s: var string) =
|
proc rawWriteStackTrace(s: var string) =
|
||||||
when nimrodStackTrace:
|
when nimrodStackTrace:
|
||||||
if framePtr == nil:
|
if framePtr == nil:
|
||||||
add(s, "No stack traceback available")
|
add(s, "No stack traceback available\n")
|
||||||
add(s, stackTraceNL)
|
|
||||||
else:
|
else:
|
||||||
add(s, "Traceback (most recent call last)")
|
add(s, "Traceback (most recent call last)\n")
|
||||||
add(s, stackTraceNL)
|
|
||||||
auxWriteStackTrace(framePtr, s)
|
auxWriteStackTrace(framePtr, s)
|
||||||
elif defined(nativeStackTrace) and nativeStackTraceSupported:
|
elif defined(nativeStackTrace) and nativeStackTraceSupported:
|
||||||
add(s, "Traceback from system (most recent call last)")
|
add(s, "Traceback from system (most recent call last)\n")
|
||||||
add(s, stackTraceNL)
|
|
||||||
auxWriteStackTraceWithBacktrace(s)
|
auxWriteStackTraceWithBacktrace(s)
|
||||||
else:
|
else:
|
||||||
add(s, "No stack traceback available\n")
|
add(s, "No stack traceback available\n")
|
||||||
|
|
@ -207,7 +209,7 @@ proc raiseExceptionAux(e: ref E_Base) =
|
||||||
pushCurrentException(e)
|
pushCurrentException(e)
|
||||||
c_longjmp(excHandler.context, 1)
|
c_longjmp(excHandler.context, 1)
|
||||||
elif e[] of EOutOfMemory:
|
elif e[] of EOutOfMemory:
|
||||||
writeToStdErr(e.name)
|
showErrorMessage(e.name)
|
||||||
quitOrDebug()
|
quitOrDebug()
|
||||||
else:
|
else:
|
||||||
when hasSomeStackTrace:
|
when hasSomeStackTrace:
|
||||||
|
|
@ -219,7 +221,7 @@ proc raiseExceptionAux(e: ref E_Base) =
|
||||||
add(buf, " [")
|
add(buf, " [")
|
||||||
add(buf, $e.name)
|
add(buf, $e.name)
|
||||||
add(buf, "]\n")
|
add(buf, "]\n")
|
||||||
writeToStdErr(buf)
|
showErrorMessage(buf)
|
||||||
else:
|
else:
|
||||||
# ugly, but avoids heap allocations :-)
|
# ugly, but avoids heap allocations :-)
|
||||||
template xadd(buf, s, slen: expr) =
|
template xadd(buf, s, slen: expr) =
|
||||||
|
|
@ -235,7 +237,7 @@ proc raiseExceptionAux(e: ref E_Base) =
|
||||||
add(buf, " [")
|
add(buf, " [")
|
||||||
xadd(buf, e.name, c_strlen(e.name))
|
xadd(buf, e.name, c_strlen(e.name))
|
||||||
add(buf, "]\n")
|
add(buf, "]\n")
|
||||||
writeToStdErr(buf)
|
showErrorMessage(buf)
|
||||||
quitOrDebug()
|
quitOrDebug()
|
||||||
|
|
||||||
proc raiseException(e: ref E_Base, ename: CString) {.compilerRtl.} =
|
proc raiseException(e: ref E_Base, ename: CString) {.compilerRtl.} =
|
||||||
|
|
@ -255,9 +257,9 @@ proc WriteStackTrace() =
|
||||||
when hasSomeStackTrace:
|
when hasSomeStackTrace:
|
||||||
var s = ""
|
var s = ""
|
||||||
rawWriteStackTrace(s)
|
rawWriteStackTrace(s)
|
||||||
writeToStdErr(s)
|
showErrorMessage(s)
|
||||||
else:
|
else:
|
||||||
writeToStdErr("No stack traceback available\n")
|
showErrorMessage("No stack traceback available\n")
|
||||||
|
|
||||||
proc getStackTrace(): string =
|
proc getStackTrace(): string =
|
||||||
when hasSomeStackTrace:
|
when hasSomeStackTrace:
|
||||||
|
|
@ -298,13 +300,13 @@ when not defined(noSignalHandler):
|
||||||
var buf = newStringOfCap(2000)
|
var buf = newStringOfCap(2000)
|
||||||
rawWriteStackTrace(buf)
|
rawWriteStackTrace(buf)
|
||||||
processSignal(sig, buf.add) # nice hu? currying a la nimrod :-)
|
processSignal(sig, buf.add) # nice hu? currying a la nimrod :-)
|
||||||
writeToStdErr(buf)
|
showErrorMessage(buf)
|
||||||
GC_enable()
|
GC_enable()
|
||||||
else:
|
else:
|
||||||
var msg: cstring
|
var msg: cstring
|
||||||
template asgn(y: expr) = msg = y
|
template asgn(y: expr) = msg = y
|
||||||
processSignal(sig, asgn)
|
processSignal(sig, asgn)
|
||||||
writeToStdErr(msg)
|
showErrorMessage(msg)
|
||||||
when defined(endb): dbgAborting = True
|
when defined(endb): dbgAborting = True
|
||||||
quit(1) # always quit when SIGABRT
|
quit(1) # always quit when SIGABRT
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -345,8 +345,9 @@ proc forAllChildrenAux(dest: Pointer, mt: PNimType, op: TWalkOp) =
|
||||||
|
|
||||||
proc forAllChildren(cell: PCell, op: TWalkOp) =
|
proc forAllChildren(cell: PCell, op: TWalkOp) =
|
||||||
gcAssert(cell != nil, "forAllChildren: 1")
|
gcAssert(cell != nil, "forAllChildren: 1")
|
||||||
gcAssert(cell.typ != nil, "forAllChildren: 2")
|
gcAssert(isAllocatedPtr(gch.region, cell), "forAllChildren: 2")
|
||||||
gcAssert cell.typ.kind in {tyRef, tySequence, tyString}, "forAllChildren: 3"
|
gcAssert(cell.typ != nil, "forAllChildren: 3")
|
||||||
|
gcAssert cell.typ.kind in {tyRef, tySequence, tyString}, "forAllChildren: 4"
|
||||||
let marker = cell.typ.marker
|
let marker = cell.typ.marker
|
||||||
if marker != nil:
|
if marker != nil:
|
||||||
marker(cellToUsr(cell), op.int)
|
marker(cellToUsr(cell), op.int)
|
||||||
|
|
@ -361,7 +362,7 @@ proc forAllChildren(cell: PCell, op: TWalkOp) =
|
||||||
for i in 0..s.len-1:
|
for i in 0..s.len-1:
|
||||||
forAllChildrenAux(cast[pointer](d +% i *% cell.typ.base.size +%
|
forAllChildrenAux(cast[pointer](d +% i *% cell.typ.base.size +%
|
||||||
GenericSeqSize), cell.typ.base, op)
|
GenericSeqSize), cell.typ.base, op)
|
||||||
else: nil
|
else: discard
|
||||||
|
|
||||||
proc addNewObjToZCT(res: PCell, gch: var TGcHeap) {.inline.} =
|
proc addNewObjToZCT(res: PCell, gch: var TGcHeap) {.inline.} =
|
||||||
# we check the last 8 entries (cache line) for a slot that could be reused.
|
# we check the last 8 entries (cache line) for a slot that could be reused.
|
||||||
|
|
@ -408,8 +409,10 @@ proc addNewObjToZCT(res: PCell, gch: var TGcHeap) {.inline.} =
|
||||||
add(gch.zct, res)
|
add(gch.zct, res)
|
||||||
|
|
||||||
{.push stackTrace: off, profiler:off.}
|
{.push stackTrace: off, profiler:off.}
|
||||||
proc gcInvariant*(msg: string) =
|
proc gcInvariant*() =
|
||||||
sysAssert(allocInv(gch.region), msg)
|
sysAssert(allocInv(gch.region), "injected")
|
||||||
|
when defined(markForDebug):
|
||||||
|
markForDebug(gch)
|
||||||
{.pop.}
|
{.pop.}
|
||||||
|
|
||||||
proc rawNewObj(typ: PNimType, size: int, gch: var TGcHeap): pointer =
|
proc rawNewObj(typ: PNimType, size: int, gch: var TGcHeap): pointer =
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,8 @@ const
|
||||||
logGC = false
|
logGC = false
|
||||||
traceGC = false # extensive debugging
|
traceGC = false # extensive debugging
|
||||||
alwaysCycleGC = false
|
alwaysCycleGC = false
|
||||||
alwaysGC = false # collect after every memory allocation (for debugging)
|
alwaysGC = defined(fulldebug) # collect after every memory
|
||||||
|
# allocation (for debugging)
|
||||||
leakDetector = false
|
leakDetector = false
|
||||||
overwriteFree = false
|
overwriteFree = false
|
||||||
trackAllocationSource = leakDetector
|
trackAllocationSource = leakDetector
|
||||||
|
|
|
||||||
|
|
@ -416,17 +416,17 @@ var
|
||||||
SOMAXCONN* {.importc, header: "Winsock2.h".}: cint
|
SOMAXCONN* {.importc, header: "Winsock2.h".}: cint
|
||||||
INVALID_SOCKET* {.importc, header: "Winsock2.h".}: TSocketHandle
|
INVALID_SOCKET* {.importc, header: "Winsock2.h".}: TSocketHandle
|
||||||
SOL_SOCKET* {.importc, header: "Winsock2.h".}: cint
|
SOL_SOCKET* {.importc, header: "Winsock2.h".}: cint
|
||||||
SO_DEBUG* {.importc, header: "Winsock2.h".}: cint ## turn on debugging info recording
|
SO_DEBUG* {.importc, header: "Winsock2.h".}: cint ## turn on debugging info recording
|
||||||
SO_ACCEPTCONN* {.importc, header: "Winsock2.h".}: cint # socket has had listen()
|
SO_ACCEPTCONN* {.importc, header: "Winsock2.h".}: cint # socket has had listen()
|
||||||
SO_REUSEADDR* {.importc, header: "Winsock2.h".}: cint # allow local address reuse
|
SO_REUSEADDR* {.importc, header: "Winsock2.h".}: cint # allow local address reuse
|
||||||
SO_KEEPALIVE* {.importc, header: "Winsock2.h".}: cint # keep connections alive
|
SO_KEEPALIVE* {.importc, header: "Winsock2.h".}: cint # keep connections alive
|
||||||
SO_DONTROUTE* {.importc, header: "Winsock2.h".}: cint # just use interface addresses
|
SO_DONTROUTE* {.importc, header: "Winsock2.h".}: cint # just use interface addresses
|
||||||
SO_BROADCAST* {.importc, header: "Winsock2.h".}: cint # permit sending of broadcast msgs
|
SO_BROADCAST* {.importc, header: "Winsock2.h".}: cint # permit sending of broadcast msgs
|
||||||
SO_USELOOPBACK* {.importc, header: "Winsock2.h".}: cint # bypass hardware when possible
|
SO_USELOOPBACK* {.importc, header: "Winsock2.h".}: cint # bypass hardware when possible
|
||||||
SO_LINGER* {.importc, header: "Winsock2.h".}: cint # linger on close if data present
|
SO_LINGER* {.importc, header: "Winsock2.h".}: cint # linger on close if data present
|
||||||
SO_OOBINLINE* {.importc, header: "Winsock2.h".}: cint # leave received OOB data in line
|
SO_OOBINLINE* {.importc, header: "Winsock2.h".}: cint # leave received OOB data in line
|
||||||
|
|
||||||
SO_DONTLINGER* {.importc, header: "Winsock2.h".}: cint
|
SO_DONTLINGER* {.importc, header: "Winsock2.h".}: cint
|
||||||
SO_EXCLUSIVEADDRUSE* {.importc, header: "Winsock2.h".}: cint # disallow local address reuse
|
SO_EXCLUSIVEADDRUSE* {.importc, header: "Winsock2.h".}: cint # disallow local address reuse
|
||||||
|
|
||||||
proc `==`*(x, y: TSocketHandle): bool {.borrow.}
|
proc `==`*(x, y: TSocketHandle): bool {.borrow.}
|
||||||
|
|
@ -553,18 +553,26 @@ const
|
||||||
|
|
||||||
FILE_FLAG_BACKUP_SEMANTICS* = 33554432'i32
|
FILE_FLAG_BACKUP_SEMANTICS* = 33554432'i32
|
||||||
|
|
||||||
|
# Error Constants
|
||||||
|
const
|
||||||
|
ERROR_ACCESS_DENIED* = 5
|
||||||
|
|
||||||
when useWinUnicode:
|
when useWinUnicode:
|
||||||
proc CreateFileW*(lpFileName: widecstring, dwDesiredAccess, dwShareMode: DWORD,
|
proc CreateFileW*(lpFileName: widecstring, dwDesiredAccess, dwShareMode: DWORD,
|
||||||
lpSecurityAttributes: pointer,
|
lpSecurityAttributes: pointer,
|
||||||
dwCreationDisposition, dwFlagsAndAttributes: DWORD,
|
dwCreationDisposition, dwFlagsAndAttributes: DWORD,
|
||||||
hTemplateFile: THANDLE): THANDLE {.
|
hTemplateFile: THANDLE): THANDLE {.
|
||||||
stdcall, dynlib: "kernel32", importc: "CreateFileW".}
|
stdcall, dynlib: "kernel32", importc: "CreateFileW".}
|
||||||
|
proc DeleteFileW*(pathName: widecstring): int32 {.
|
||||||
|
importc: "DeleteFileW", dynlib: "kernel32", stdcall.}
|
||||||
else:
|
else:
|
||||||
proc CreateFileA*(lpFileName: cstring, dwDesiredAccess, dwShareMode: DWORD,
|
proc CreateFileA*(lpFileName: cstring, dwDesiredAccess, dwShareMode: DWORD,
|
||||||
lpSecurityAttributes: pointer,
|
lpSecurityAttributes: pointer,
|
||||||
dwCreationDisposition, dwFlagsAndAttributes: DWORD,
|
dwCreationDisposition, dwFlagsAndAttributes: DWORD,
|
||||||
hTemplateFile: THANDLE): THANDLE {.
|
hTemplateFile: THANDLE): THANDLE {.
|
||||||
stdcall, dynlib: "kernel32", importc: "CreateFileA".}
|
stdcall, dynlib: "kernel32", importc: "CreateFileA".}
|
||||||
|
proc DeleteFileA*(pathName: cstring): int32 {.
|
||||||
|
importc: "DeleteFileA", dynlib: "kernel32", stdcall.}
|
||||||
|
|
||||||
proc SetEndOfFile*(hFile: THANDLE): WINBOOL {.stdcall, dynlib: "kernel32",
|
proc SetEndOfFile*(hFile: THANDLE): WINBOOL {.stdcall, dynlib: "kernel32",
|
||||||
importc: "SetEndOfFile".}
|
importc: "SetEndOfFile".}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ when haveZipLib:
|
||||||
import zipfiles
|
import zipfiles
|
||||||
|
|
||||||
import
|
import
|
||||||
os, strutils, parseopt, parsecfg, strtabs, streams, debcreation
|
os, osproc, strutils, parseopt, parsecfg, strtabs, streams, debcreation
|
||||||
|
|
||||||
const
|
const
|
||||||
maxOS = 20 # max number of OSes
|
maxOS = 20 # max number of OSes
|
||||||
|
|
@ -486,7 +486,7 @@ proc setupDist(c: var TConfigData) =
|
||||||
if c.innoSetup.path.len == 0:
|
if c.innoSetup.path.len == 0:
|
||||||
c.innoSetup.path = "iscc.exe"
|
c.innoSetup.path = "iscc.exe"
|
||||||
var outcmd = if c.outdir.len == 0: "build" else: c.outdir
|
var outcmd = if c.outdir.len == 0: "build" else: c.outdir
|
||||||
var cmd = "$# $# /O$# $#" % [quoteIfContainsWhite(c.innoSetup.path),
|
var cmd = "$# $# /O$# $#" % [quoteShell(c.innoSetup.path),
|
||||||
c.innoSetup.flags, outcmd, n]
|
c.innoSetup.flags, outcmd, n]
|
||||||
echo(cmd)
|
echo(cmd)
|
||||||
if execShellCmd(cmd) == 0:
|
if execShellCmd(cmd) == 0:
|
||||||
|
|
@ -587,4 +587,3 @@ if actionZip in c.actions:
|
||||||
quit("libzip is not installed")
|
quit("libzip is not installed")
|
||||||
if actionDeb in c.actions:
|
if actionDeb in c.actions:
|
||||||
debDist(c)
|
debDist(c)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,8 @@ Changes affecting backwards compatibility
|
||||||
require an error code to be passed to them. This error code can be retrieved
|
require an error code to be passed to them. This error code can be retrieved
|
||||||
using the new ``OSLastError`` proc.
|
using the new ``OSLastError`` proc.
|
||||||
- ``os.parentDir`` now returns "" if there is no parent dir.
|
- ``os.parentDir`` now returns "" if there is no parent dir.
|
||||||
|
- In CGI scripts stacktraces are shown user only if cgi.setStackTraceStdout
|
||||||
|
is used.
|
||||||
|
|
||||||
Compiler Additions
|
Compiler Additions
|
||||||
------------------
|
------------------
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue