aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/args.nim2
-rw-r--r--src/aur.nim2
-rw-r--r--src/common.nim2
-rw-r--r--src/feature/syncinfo.nim2
-rw-r--r--src/feature/syncinstall.nim2
-rw-r--r--src/format.nim6
-rw-r--r--src/listcomp.nim69
-rw-r--r--src/main.nim2
-rw-r--r--src/package.nim2
-rw-r--r--src/pacman.nim2
-rw-r--r--src/utils.nim29
-rw-r--r--src/wrapper/curl.nim1
12 files changed, 95 insertions, 26 deletions
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]