diff options
author | Andreas Rumpf <andreas@andreas-laptop> | 2010-04-05 19:47:18 +0200 |
---|---|---|
committer | Andreas Rumpf <andreas@andreas-laptop> | 2010-04-05 19:47:18 +0200 |
commit | e90665bff2e062598b51ada915c4861db6e94a8d (patch) | |
tree | d05a0cfdc7b0b9f84e9ed362eee21a17edab2373 /lib | |
parent | b2ad7b30dc5866a92e239acfd6032e5fb005a240 (diff) | |
download | Nim-e90665bff2e062598b51ada915c4861db6e94a8d.tar.gz |
crc check for external files to compile; bugfix: os.parseCmdLine
Diffstat (limited to 'lib')
-rwxr-xr-x | lib/pure/os.nim | 92 | ||||
-rwxr-xr-x | lib/system.nim | 8 |
2 files changed, 81 insertions, 19 deletions
diff --git a/lib/pure/os.nim b/lib/pure/os.nim index f807c39f5..129774f6e 100755 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -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 diff --git a/lib/system.nim b/lib/system.nim index 66c5b4dfd..a83812ed0 100755 --- a/lib/system.nim +++ b/lib/system.nim @@ -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 |