crc check for external files to compile; bugfix: os.parseCmdLine

This commit is contained in:
Andreas Rumpf 2010-04-05 19:47:18 +02:00
commit e90665bff2
7 changed files with 145 additions and 54 deletions

View file

@ -926,28 +926,90 @@ proc createDir*(dir: string) =
rawCreateDir(dir)
proc parseCmdLine*(c: string): seq[string] =
## Splits a command line into several components; components are separated by
## whitespace unless the whitespace occurs within ``"`` or ``'`` quotes.
## Splits a command line into several components;
## This proc is only occassionally useful, better use the `parseopt` module.
##
## On Windows, it uses the following parsing rules
## (see http://msdn.microsoft.com/en-us/library/17w5ykft.aspx):
##
## * Arguments are delimited by white space, which is either a space or a tab.
## * The caret character (^) is not recognized as an escape character or
## delimiter. The character is handled completely by the command-line parser
## in the operating system before being passed to the argv array in the
## program.
## * A string surrounded by double quotation marks ("string") is interpreted
## as a single argument, regardless of white space contained within. A
## quoted string can be embedded in an argument.
## * A double quotation mark preceded by a backslash (\") is interpreted as a
## literal double quotation mark character (").
## * Backslashes are interpreted literally, unless they immediately precede
## a double quotation mark.
## * If an even number of backslashes is followed by a double quotation mark,
## one backslash is placed in the argv array for every pair of backslashes,
## and the double quotation mark is interpreted as a string delimiter.
## * If an odd number of backslashes is followed by a double quotation mark,
## one backslash is placed in the argv array for every pair of backslashes,
## and the double quotation mark is "escaped" by the remaining backslash,
## causing a literal double quotation mark (") to be placed in argv.
##
## On Posix systems, it uses the following parsing rules:
## components are separated by
## whitespace unless the whitespace occurs within ``"`` or ``'`` quotes.
result = @[]
var i = 0
var a = ""
while true:
setLen(a, 0)
while c[i] >= '\1' and c[i] <= ' ': inc(i) # skip whitespace
case c[i]
of '\'', '\"':
var delim = c[i]
inc(i) # skip ' or "
while c[i] != '\0' and c[i] != delim:
add a, c[i]
inc(i)
if c[i] != '\0': inc(i)
of '\0': break
while c[i] == ' ' or c[i] == '\t': inc(i)
when defined(windows):
# parse a single argument according to the above rules:
var inQuote = false
while true:
case c[i]
of '\0': break
of '\\':
var j = i
while c[j] == '\\': inc(j)
if c[j] == '"':
for k in 0..(j-i) div 2: a.add('\\')
if (j-i) mod 2 == 0:
i = j
else:
a.add('"')
i = j+1
else:
a.add(c[i])
inc(i)
of '"':
inc(i)
if not inQuote: inQuote = true
elif c[i] == '"':
a.add(c[i])
inc(i)
else:
inQuote = false
break
of ' ', '\t':
if not inQuote: break
a.add(c[i])
inc(i)
else:
a.add(c[i])
inc(i)
else:
while c[i] > ' ':
add(a, c[i])
inc(i)
case c[i]
of '\'', '\"':
var delim = c[i]
inc(i) # skip ' or "
while c[i] != '\0' and c[i] != delim:
add a, c[i]
inc(i)
if c[i] != '\0': inc(i)
of '\0': break
else:
while c[i] > ' ':
add(a, c[i])
inc(i)
add(result, a)
type

View file

@ -233,9 +233,9 @@ type
## that is too small to be represented as
## a normal number
EFloatInexact* {.compilerproc.} =
object of EFloatingPoint ## Inexact. Operation produces a result that cannot
## be represented with infinite precision --
## for example, 2.0 / 3.0, log(1.1)
object of EFloatingPoint ## Inexact. Operation produces a result
## that cannot be represented with infinite
## precision -- for example, 2.0 / 3.0, log(1.1)
## NOTE: Nimrod currently does not detect these!
TResult* = enum Failure, Success
@ -962,7 +962,7 @@ proc `$` *(x: Cstring): string {.magic: "CStrToStr", noSideEffect.}
proc `$` *(x: string): string {.magic: "StrToStr", noSideEffect.}
## The stingify operator for a string argument. Returns `x`
## as it is. This operator is useful for generic code, so
## that ``$expr`` also works if ``expr`` is already a string.
## that ``$expr`` also works if ``expr`` already is a string.
proc `$` *[T](x: ordinal[T]): string {.magic: "EnumToStr", noSideEffect.}
## The stingify operator for an enumeration argument. This works for