|
1 | 1 | import os |
2 | 2 | import sys |
3 | 3 | from ctypes import * |
| 4 | +from tempfile import NamedTemporaryFile |
4 | 5 |
|
5 | 6 | from epicsdbbuilder.recordset import recordset |
6 | 7 |
|
@@ -245,33 +246,43 @@ def dbLoadDatabase(database, path = None, substitutions = None): |
245 | 246 | '''Loads a database file and applies any given substitutions.''' |
246 | 247 | imports.dbLoadDatabase(database, path, substitutions) |
247 | 248 |
|
248 | | -def _add_records_from_file(dir, file, macros): |
249 | | - # This is very naive, for instance macros are added to but never removed, |
250 | | - # but it works well enough for devIocStats |
251 | | - with open(os.path.join(dir, file)) as f: |
| 249 | + |
| 250 | +def _add_records_from_file(dirname, file, substitutions): |
| 251 | + # This is very naive, it loads all includes before their parents which |
| 252 | + # possibly can put them out of order, but it works well enough for |
| 253 | + # devIocStats |
| 254 | + with open(os.path.join(dirname, file)) as f: |
| 255 | + lines, include_subs = [], "" |
252 | 256 | for line in f.readlines(): |
253 | 257 | line = line.rstrip() |
254 | 258 | if line.startswith('substitute'): |
255 | | - # substitute "QUEUE=scanOnce, QUEUE_CAPS=SCANONCE |
256 | | - for sub in line.split('"')[1].split(','): |
257 | | - k, v = sub.split('=') |
258 | | - macros[k.strip()] = v.strip() |
| 259 | + # substitute "QUEUE=scanOnce, QUEUE_CAPS=SCANONCE" |
| 260 | + # keep hold of the substitutions |
| 261 | + include_subs = line.split('"')[1] |
259 | 262 | elif line.startswith('include'): |
260 | 263 | # include "iocQueue.db" |
261 | | - _add_records_from_file(dir, line.split('"')[1], macros) |
| 264 | + subs = substitutions |
| 265 | + if substitutions and include_subs: |
| 266 | + subs = substitutions + ", " + include_subs |
| 267 | + else: |
| 268 | + subs = substitutions + include_subs |
| 269 | + _add_records_from_file(dirname, line.split('"')[1], subs) |
262 | 270 | else: |
263 | 271 | # A record line |
264 | | - for k, v in macros.items(): |
265 | | - line = line.replace('$(%s)' % k, v) |
266 | | - recordset.AddBodyLine(line) |
| 272 | + lines.append(line) |
| 273 | + # Write a tempfile and load it |
| 274 | + with NamedTemporaryFile(suffix='.db', delete=False) as f: |
| 275 | + f.write(os.linesep.join(lines).encode()) |
| 276 | + dbLoadDatabase(f.name, substitutions=substitutions) |
| 277 | + os.unlink(f.name) |
267 | 278 |
|
268 | 279 |
|
269 | 280 | def devIocStats(ioc_name): |
270 | 281 | '''This will load a template for the devIocStats library with the specified |
271 | 282 | IOC name. This should be called before `iocInit`''' |
272 | | - macros = dict(IOCNAME=ioc_name, TODFORMAT='%m/%d/%Y %H:%M:%S') |
| 283 | + substitutions = 'IOCNAME=' + ioc_name + ', TODFORMAT=%m/%d/%Y %H:%M:%S' |
273 | 284 | iocstats_dir = os.path.join(os.path.dirname(__file__), 'iocStatsDb') |
274 | | - _add_records_from_file(iocstats_dir, 'ioc.template', macros) |
| 285 | + _add_records_from_file(iocstats_dir, 'ioc.template', substitutions) |
275 | 286 |
|
276 | 287 |
|
277 | 288 | def interactive_ioc(context = {}, call_exit = True): |
|
0 commit comments