aboutsummaryrefslogtreecommitdiff
path: root/src/nimgen/file.nim
blob: 81e1d86125dc85d874ebf2250c42487a4432541e (plain)
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
import os, pegs, regex, strutils, tables

when (NimMajor, NimMinor, NimPatch) < (0, 19, 9):
  import ospaths

import globals, external

# ###
# File loction

proc getNimout*(file: string, rename=true): string =
  result = file.splitFile().name.multiReplace([("-", "_"), (".", "_")]) & ".nim"
  if gOutput != "":
    result = gOutput & "/" & result

  if not rename:
    return

  if gRenames.hasKey(file):
    result = gRenames[file]

  createDir(parentDir(result))

proc exclude*(file: string): bool =
  for excl in gExcludes:
    if excl in file:
      return true
  return false

proc search*(file: string): string =
  if exclude(file):
    return ""

  result = file
  if file.splitFile().ext == ".nim":
    result = getNimout(file)
  elif not fileExists(result) and not dirExists(result):
    var found = false
    for inc in gIncludes:
      result = inc & "/" & file
      if fileExists(result) or dirExists(result):
        found = true
        break
    if not found:
      echo "File doesn't exist: " & file
      quit(1)

  # Only keep relative directory
  return result.sanitizePath.replace(gProjectDir & "/", "")

proc rename*(file: string, renfile: string) =
  if file.splitFile().ext == ".nim":
    return

  var
    nimout = getNimout(file, false)
    newname = renfile.replace("$nimout", extractFilename(nimout))

  if newname =~ peg"(!\$.)*{'$replace'\s*'('\s*{(!\)\S)+}')'}":
    var final = nimout.extractFilename()
    for entry in matches[1].split(","):
      let spl = entry.split("=")
      if spl.len() != 2:
        echo "Bad replace syntax: " & renfile
        quit(1)

      let
        srch = spl[0].strip()
        repl = spl[1].strip()

      final = final.replace(srch, repl)
    newname = newname.replace(matches[0], final)

  gRenames[file] = gOutput & "/" & newname

# ###
# Actions

proc openRetry*(file: string, mode: FileMode = fmRead): File =
  while true:
    try:
      result = open(file, mode)
      break
    except IOError:
      sleep(100)

template writeFileFlush*(file, content: string): untyped =
  let f = openRetry(file, fmWrite)
  f.write(content)
  f.flushFile()
  f.close()

template withFile*(file: string, body: untyped): untyped =
  if fileExists(file):
    var f = openRetry(file)

    var contentOrig = f.readAll()
    f.close()
    var content {.inject.} = contentOrig

    body

    if content != contentOrig:
      writeFileFlush(file, content)
  else:
    echo "Missing file " & file

proc doCopy*(flist: string) =
  for pair in flist.split(","):
    let spl = pair.split("=")
    if spl.len() != 2:
      echo "Bad copy syntax: " & flist
      quit(1)

    let
      lfile = spl[0].strip()
      rfile = spl[1].strip()

    copyFile(lfile, rfile)
    echo "Copied $# to $#" % [lfile, rfile]