Re: Resolving environment variables in a string

2020-04-09 Thread squattingmonk
Thanks, Araq! That's exactly what I needed.


Re: Resolving environment variables in a string

2020-04-08 Thread squattingmonk
I'm also noticing that this will throw an exception if any of the variables in 
the string are not found among the environment variables.


Resolving environment variables in a string

2020-04-08 Thread squattingmonk
Hi, all! I need to resolve environment variables in a string. I'm not seeing a 
proc for this in the standard library, so I whipped this up:


import os, strtabs

proc envTable: StringTableRef =
  result = newStringTable(modeCaseSensitive)
  for key, value in envPairs():
result[key] = value

let
  envs = envTable()
  path = paramStr(1)

echo path % envs


Run

Is there a better or more idomatic way to do this?


Re: Split on whitespace except for between quotes

2019-09-07 Thread squattingmonk
Thanks! I came up with the following:


import parseutils, strutils

proc splitArgs(args: string): seq[string] =
  var
parsed, tmp: string
i, quotes: int
  
  while i < args.len:
i += args.parseUntil(parsed, Whitespace, i) + 1
tmp.add(parsed)
if parsed.startsWith('"'):
  quotes.inc
if parsed.endsWith('"'):
  quotes.dec
elif quotes > 0:
  tmp.add(" ")

if quotes == 0:
  tmp.removePrefix('"')
  tmp.removeSuffix('"')
  result.add(tmp)
  tmp = ""
  
  if tmp.len > 0:
result.add(tmp[1 .. ^2])

let text = "spam eggs \"spam and eggs\""
doAssert text.splitArgs == @["spam", "eggs", "spam and eggs"]


Run

I chose not to cover single quotes because I don't want to have to handle words 
like "don't". Advice on how I could improve on this?


Re: Split on whitespace except for between quotes

2019-09-07 Thread squattingmonk
This text wouldn't be passed into the command line (it's read from a file), but 
it will be passed to it. Your suggestion turned me on to `parseCmdLine()` from 
the os module. It does exactly what I need. Thank you!


Split on whitespace except for between quotes

2019-09-07 Thread squattingmonk
I want to split a string on whitespace, but keep strings that are between 
quotes:


input: spam eggs "spam and eggs"
output: @["spam", "eggs", "spam and eggs"]

I want to support both single and double quotes, and I'm having trouble 
wrapping my brain around how to do this. I've been thinking maybe splitting 
with a regular expression is the way to go, but I wondered if there is a 
simpler way (perhaps already in the standard library that I've missed).


Re: Getting OrderedTable key/value pair by insertion order

2019-06-25 Thread squattingmonk
> So indeed iterating over the keys and stopping after first one makes sense, I 
> think there is no function to retrieve the first added element. And I think I 
> can remember someone asking how to get the n-th. added element, conclusion 
> was to use a loop similar as you do.

Thanks, Stefan. I'd though I was just being silly and missing something 
obvious. Good to know this is a reasonable solution.

> use 
> 
> 
> iterator pairs[A, B](t: OrderedTable[A, B]): (A, B)
> 
> 
> Run
> 
> and break-out after first (does "... in insertion order." kind of implies 
> FIFO?) element.

Hi, lucian. That's what I did in the code sample I provided, but I used the 
`keys` iterator instead of `pairs`.


Re: Getting OrderedTable key/value pair by insertion order

2019-06-25 Thread squattingmonk
I'm not trying to get sorted items, just the first item added (hence why I used 
an OrderedTable).


Getting OrderedTable key/value pair by insertion order

2019-06-24 Thread squattingmonk
Hi, all! I'm trying to get the first item out of an OrderedTable that was 
indexed with strings. I'm not sure which is the best way to do it.

My program is reading a set of configuration files and loading the information 
into a type `Target`, which is then added to an ordered table using the name of 
the target as its index. If the user executes a command that takes a target, I 
want to get the target using the supplied name as the index (just normalized). 
So far, so good. However, if the user does not specify a target, I want to 
select the first one that was added to the table.

Here's my types: 


type
  Config* = object
# ...
targets*: OrderedTable[string, Target]
  
  Target = object
name*, file*, description*: string
sources*: seq[string]


Run

This is the only way I can think of to get the first index: 


if opts.target.len == 0:
  for target in cfg.targets.keys:
opts.target = target
break
 

Run

Is there a better way of getting the first index? Or maybe a better way to 
structure my data that avoids this?

Thanks!