aboutsummaryrefslogtreecommitdiff
path: root/src/wrapper/alpm.nim
blob: 00b5b86a2e24fbe6c99eb6b399005bff8a6f30e6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import
  strutils,
  "../utils"

type
  AlpmHandle* = object
  AlpmDatabase* = object
  AlpmPackage* = object

  AlpmList*[T] = object
    data*: T
    prev*: ptr AlpmList[T]
    next*: ptr AlpmList[T]

  AlpmDepMod* {.pure, size: sizeof(cint).} = enum
    no = 1,
    eq = 2,
    ge = 3,
    le = 4,
    gt = 5,
    lt = 6

  AlpmReason* {.pure, size: sizeof(cint).} = enum
    explicit = 0,
    depend = 1

  AlpmDependency* = object
    name*: cstring
    version*: cstring
    desc*: cstring
    nameHash: culong
    depMod*: AlpmDepMod

  AlpmGroup* = object
    name*: cstring
    packages*: ptr AlpmList[ptr AlpmPackage]

{.passL: "-lalpm".}

proc newAlpmHandle*(root: cstring, dbpath: cstring, err: var cint): ptr AlpmHandle
  {.cdecl, importc: "alpm_initialize".}

proc release*(handle: ptr AlpmHandle): cint
  {.cdecl, importc: "alpm_release".}

proc setArch*(handle: ptr AlpmHandle, arch: cstring): cint
  {.cdecl, importc: "alpm_option_set_arch".}

proc vercmp*(a: cstring, b: cstring): cint
  {.cdecl, importc: "alpm_pkg_vercmp".}

proc errno*(handle: ptr AlpmHandle): cint
  {.cdecl, importc: "alpm_errno".}

proc errorAlpm*(errno: cint): cstring
  {.cdecl, importc: "alpm_strerror".}

proc register*(handle: ptr AlpmHandle, treeName: cstring, level: cint): ptr AlpmDatabase
  {.cdecl, importc: "alpm_register_syncdb".}

proc local*(handle: ptr AlpmHandle): ptr AlpmDatabase
  {.cdecl, importc: "alpm_get_localdb".}

proc packages*(db: ptr AlpmDatabase): ptr AlpmList[ptr AlpmPackage]
  {.cdecl, importc: "alpm_db_get_pkgcache".}

proc groups*(db: ptr AlpmDatabase): ptr AlpmList[ptr AlpmGroup]
  {.cdecl, importc: "alpm_db_get_groupcache".}

proc name*(db: ptr AlpmDatabase): cstring
  {.cdecl, importc: "alpm_db_get_name".}

proc `[]`*(db: ptr AlpmDatabase, name: cstring): ptr AlpmPackage
  {.cdecl, importc: "alpm_db_get_pkg".}

proc base*(pkg: ptr AlpmPackage): cstring
  {.cdecl, importc: "alpm_pkg_get_base".}

proc name*(pkg: ptr AlpmPackage): cstring
  {.cdecl, importc: "alpm_pkg_get_name".}

proc version*(pkg: ptr AlpmPackage): cstring
  {.cdecl, importc: "alpm_pkg_get_version".}

proc arch*(pkg: ptr AlpmPackage): cstring
  {.cdecl, importc: "alpm_pkg_get_arch".}

proc groups*(pkg: ptr AlpmPackage): ptr AlpmList[cstring]
  {.cdecl, importc: "alpm_pkg_get_groups".}

proc reason*(pkg: ptr AlpmPackage): AlpmReason
  {.cdecl, importc: "alpm_pkg_get_reason".}

proc depends*(pkg: ptr AlpmPackage): ptr AlpmList[ptr AlpmDependency]
  {.cdecl, importc: "alpm_pkg_get_depends".}

proc optional*(pkg: ptr AlpmPackage): ptr AlpmList[ptr AlpmDependency]
  {.cdecl, importc: "alpm_pkg_get_optdepends".}

proc provides*(pkg: ptr AlpmPackage): ptr AlpmList[ptr AlpmDependency]
  {.cdecl, importc: "alpm_pkg_get_provides".}

proc cfree*(data: pointer)
  {.cdecl, importc: "free", header: "<stdlib.h>".}

proc freeList*[T](list: ptr AlpmList[T])
  {.cdecl, importc: "alpm_list_free".}

proc freeListInner*[T](list: ptr AlpmList[T], fn: proc (data: pointer): void {.cdecl.})
  {.cdecl, importc: "alpm_list_free_inner".}

proc freeListFull*[T](list: ptr AlpmList[T]) =
  list.freeListInner(cfree)
  list.freeList()

template withAlpm*(root: string, db: string, dbs: seq[string], arch: string,
  handle: untyped, alpmDbs: untyped, errors: untyped, body: untyped): untyped =
  block:
    var errno: cint = 0
    let handle = newAlpmHandle(root, db, errno)

    if handle == nil:
      raise commandError(trp("failed to initialize alpm library\n(%s: %s)\n").strip
        .replace("%s", "$#") % [$errno.errorAlpm, db])

    var alpmDbs = newSeq[ptr AlpmDatabase]()
    var errors = newSeq[string]()
    for dbName in dbs:
      let alpmDb = handle.register(dbName, 1 shl 30)
      if alpmDb != nil:
        alpmDbs &= alpmDb
      else:
        errors &= trp("could not register '%s' database (%s)\n").strip
          .replace("%s", "$#") % [dbName, $handle.errno.errorAlpm]

    try:
      discard handle.setArch(arch)
      body
    finally:
      discard handle.release()

iterator items*[T](list: ptr AlpmList[T]): T =
  var listi = list
  while listi != nil:
    yield listi.data
    listi = listi.next