aboutsummaryrefslogtreecommitdiff
path: root/src/nimgen/file.nim
blob: 708ae4a818e5b03356acd4b353a5c5de6fccb0c0 (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
import os, ospaths, pegs, regex, strutils, tables

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]

  if not dirExists(parentDir(result)):
    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 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:
      f = openRetry(file, fmWrite)
      write(f, content)
      f.close()
  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]