diff options
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | src/args.nim | 2 | ||||
-rw-r--r-- | src/aur.nim | 2 | ||||
-rw-r--r-- | src/common.nim | 2 | ||||
-rw-r--r-- | src/feature/syncinfo.nim | 2 | ||||
-rw-r--r-- | src/feature/syncinstall.nim | 2 | ||||
-rw-r--r-- | src/format.nim | 6 | ||||
-rw-r--r-- | src/listcomp.nim | 69 | ||||
-rw-r--r-- | src/main.nim | 2 | ||||
-rw-r--r-- | src/package.nim | 2 | ||||
-rw-r--r-- | src/pacman.nim | 2 | ||||
-rw-r--r-- | src/utils.nim | 29 | ||||
-rw-r--r-- | src/wrapper/curl.nim | 1 |
13 files changed, 96 insertions, 26 deletions
@@ -55,6 +55,7 @@ NIM_OPTIMIZE = size NIM_CACHE_DIR = nimcache NIM_OPTIONS = \ + --useVersion:'1.0' \ --putenv:'PROG_VERSION'="${RVERSION}" \ --putenv:'PROG_COPYRIGHT'="${COPYRIGHT}" \ --putenv:'PROG_PKGLIBDIR'="${PKGLIBDIR}" \ diff --git a/src/args.nim b/src/args.nim index 490bd2b..acf9604 100644 --- a/src/args.nim +++ b/src/args.nim @@ -1,6 +1,6 @@ import options, os, posix, sequtils, sets, strutils, sugar, - utils + utils, "listcomp" type ArgumentType* {.pure.} = enum diff --git a/src/aur.nim b/src/aur.nim index 542a21c..49e350c 100644 --- a/src/aur.nim +++ b/src/aur.nim @@ -1,7 +1,7 @@ import json, lists, options, re, sequtils, sets, strutils, sugar, tables, package, utils, - "wrapper/curl" + "wrapper/curl", "listcomp" type AurComment* = tuple[ diff --git a/src/common.nim b/src/common.nim index 0f2804b..af1f21e 100644 --- a/src/common.nim +++ b/src/common.nim @@ -1,7 +1,7 @@ import options, os, osproc, posix, sequtils, sets, strutils, sugar, tables, args, config, format, lists, package, pacman, utils, - "wrapper/alpm" + "wrapper/alpm", "listcomp" type CacheKind* {.pure.} = enum diff --git a/src/feature/syncinfo.nim b/src/feature/syncinfo.nim index 6b2278d..77e94bf 100644 --- a/src/feature/syncinfo.nim +++ b/src/feature/syncinfo.nim @@ -2,7 +2,7 @@ import options, posix, sequtils, strutils, sugar, tables, "../args", "../aur", "../common", "../config", "../format", "../package", "../pacman", "../utils", - "../wrapper/alpm" + "../wrapper/alpm", "../listcomp" const pacmanInfoStrings = [ diff --git a/src/feature/syncinstall.nim b/src/feature/syncinstall.nim index b6347f9..abb25b5 100644 --- a/src/feature/syncinstall.nim +++ b/src/feature/syncinstall.nim @@ -2,7 +2,7 @@ import algorithm, options, os, posix, sequtils, sets, strutils, sugar, tables, "../args", "../aur", "../config", "../common", "../format", "../lists", "../package", "../pacman", "../utils", - "../wrapper/alpm" + "../wrapper/alpm", "../listcomp" type Installed = tuple[ diff --git a/src/format.nim b/src/format.nim index 3ed7b58..f85733a 100644 --- a/src/format.nim +++ b/src/format.nim @@ -1,6 +1,6 @@ import macros, options, posix, sequtils, strutils, sugar, times, unicode, - utils + utils, "listcomp" type PackageLineFormat* = tuple[ @@ -83,7 +83,9 @@ proc splitLines(text: string, lineSize: int, lines: seq[string] = @[]): seq[stri if not addBreaks: lines & text else: - let offset = text.runeOffset(lineSize) + var offset : int = -1 + if text.len() != 0: + offset = text.runeOffset(lineSize) if offset < 0: lines & text else: diff --git a/src/listcomp.nim b/src/listcomp.nim new file mode 100644 index 0000000..c9f8dc0 --- /dev/null +++ b/src/listcomp.nim @@ -0,0 +1,69 @@ +import macros + +type ListComprehension = object +var lc* : ListComprehension + +template `|`*(lc: ListComprehension, comp: untyped): untyped = lc + +macro `[]`*(lc: ListComprehension, comp, typ: untyped): untyped = + ## List comprehension, returns a sequence. `comp` is the actual list + ## comprehension, for example ``x | (x <- 1..10, x mod 2 == 0)``. `typ` is + ## the type that will be stored inside the result seq. + ## + ## .. code-block:: nim + ## + ## echo lc[x | (x <- 1..10, x mod 2 == 0), int] + ## + ## const n = 20 + ## echo lc[(x,y,z) | (x <- 1..n, y <- x..n, z <- y..n, x*x + y*y == z*z), + ## tuple[a,b,c: int]] + + expectLen(comp, 3) + expectKind(comp, nnkInfix) + assert($comp[0] == "|") + + result = newCall( + newDotExpr( + newIdentNode("result"), + newIdentNode("add")), + comp[1]) + + for i in countdown(comp[2].len-1, 0): + let x = comp[2][i] + expectMinLen(x, 1) + if x[0].kind == nnkIdent and x[0].strVal == "<-": + expectLen(x, 3) + result = newNimNode(nnkForStmt).add(x[1], x[2], result) + else: + result = newIfStmt((x, result)) + + result = newNimNode(nnkCall).add( + newNimNode(nnkPar).add( + newNimNode(nnkLambda).add( + newEmptyNode(), + newEmptyNode(), + newEmptyNode(), + newNimNode(nnkFormalParams).add( + newNimNode(nnkBracketExpr).add( + newIdentNode("seq"), + typ)), + newEmptyNode(), + newEmptyNode(), + newStmtList( + newAssignment( + newIdentNode("result"), + newNimNode(nnkPrefix).add( + newIdentNode("@"), + newNimNode(nnkBracket))), + result)))) + + +when isMainModule: + var a = lc[x | (x <- 1..10, x mod 2 == 0), int] + assert a == @[2, 4, 6, 8, 10] + + const n = 20 + var b = lc[(x,y,z) | (x <- 1..n, y <- x..n, z <- y..n, x*x + y*y == z*z), + tuple[a,b,c: int]] + assert b == @[(a: 3, b: 4, c: 5), (a: 5, b: 12, c: 13), (a: 6, b: 8, c: 10), +(a: 8, b: 15, c: 17), (a: 9, b: 12, c: 15), (a: 12, b: 16, c: 20)] diff --git a/src/main.nim b/src/main.nim index 458ba72..87bb8d2 100644 --- a/src/main.nim +++ b/src/main.nim @@ -1,6 +1,6 @@ import options, os, posix, re, sequtils, strutils, sugar, - args, config, format, pacman, utils + args, config, format, pacman, utils, "listcomp" import "feature/localquery", diff --git a/src/package.nim b/src/package.nim index 3014cba..181b5bf 100644 --- a/src/package.nim +++ b/src/package.nim @@ -1,6 +1,6 @@ import options, os, re, sequtils, sets, strutils, sugar, tables, utils, - "wrapper/alpm" + "wrapper/alpm", "listcomp" type ConstraintOperation* {.pure.} = enum diff --git a/src/pacman.nim b/src/pacman.nim index f9fc978..8b72538 100644 --- a/src/pacman.nim +++ b/src/pacman.nim @@ -1,6 +1,6 @@ import macros, options, posix, sequtils, sets, strutils, sugar, tables, - args, config, utils + args, config, utils, "listcomp" type OpGroup* {.pure.} = enum diff --git a/src/utils.nim b/src/utils.nim index e46a8e0..da9618b 100644 --- a/src/utils.nim +++ b/src/utils.nim @@ -211,26 +211,23 @@ proc forkWaitRedirect*(call: () -> int): tuple[output: seq[string], code: int] = proc getgrouplist*(user: cstring, group: Gid, groups: ptr cint, ngroups: var cint): cint {.importc, header: "<grp.h>".} + proc setgroups*(size: csize_t, groups: ptr cint): cint {.importc, header: "<grp.h>".} proc getUser(uid: int): User = - while true: - var pw = getpwent() - if pw == nil: - endpwent() - raise newException(CatchableError, "") - if pw.pw_uid.int == uid: - var groups: array[100, cint] - var ngroups: cint = 100 - if getgrouplist(pw.pw_name, pw.pw_gid, addr(groups[0]), ngroups) < 0: - raise newException(CatchableError, "") - else: - let groupsSeq = groups[0 .. ngroups - 1].map(x => x.int) - let res = ($pw.pw_name, pw.pw_uid.int, pw.pw_gid.int, groupsSeq, - $pw.pw_dir, $pw.pw_shell) - endpwent() - return res + var pw = getpwuid(Uid(uid)) + if pw == nil: + raise newException(CatchableError, "") + var groups: array[100, cint] + var ngroups: cint = 100 + if getgrouplist(pw.pw_name, pw.pw_gid, addr(groups[0]), ngroups) < 0: + raise newException(CatchableError, "") + else: + let groupsSeq = groups[0 .. ngroups - 1].map(x => x.int) + let res = ($pw.pw_name, pw.pw_uid.int, pw.pw_gid.int, groupsSeq, + $pw.pw_dir, $pw.pw_shell) + return res let currentUser* = getUser(getuid().int) diff --git a/src/wrapper/curl.nim b/src/wrapper/curl.nim index 9abb341..149f0a3 100644 --- a/src/wrapper/curl.nim +++ b/src/wrapper/curl.nim @@ -60,6 +60,7 @@ proc escape*(instance: ref CurlInstance, s: string): string = proc curlWriteMemory(mem: array[csize_t.high, char], size: csize_t, nmemb: csize_t, userdata: ref CurlInstance): csize_t {.cdecl.} = + let total = size * nmemb if total > 0: userData.data &= mem[0 .. total - 1] |