From 1a730d71b5e07cc5e00897b0d75a6f2455e2e7a0 Mon Sep 17 00:00:00 2001
From: Anders Lindh Olsson <anders.lindholsson@ess.eu>
Date: Thu, 3 Nov 2022 13:31:29 +0100
Subject: [PATCH] Remove `runScript`

Also remove `expr.h` and `expr.c`, as well as associated test files (which weren't being used).
---
 CHANGELOG.md                  |   1 +
 require-ess/src/expr.c        | 457 ----------------------------------
 require-ess/src/expr.h        |  25 --
 require-ess/src/require.h     |   1 -
 require-ess/src/runScript.dbd |   3 -
 require-ess/test/testscript   |  95 -------
 require-ess/test/teststrings  |  92 -------
 require.Makefile              |   3 -
 8 files changed, 1 insertion(+), 676 deletions(-)
 delete mode 100644 require-ess/src/expr.c
 delete mode 100644 require-ess/src/expr.h
 delete mode 100644 require-ess/src/runScript.dbd
 delete mode 100644 require-ess/test/testscript
 delete mode 100644 require-ess/test/teststrings

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6d62cab4..941ca982 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 * e3-sequencer tests added, as well as removing pre-processing of .stt files.
 * Remove Win32 and CYGWIN32 support
 * Remove `/tools` directory, including `test_installed_modules.sh` utility
+* Remove `runScript`
 
 ## [4.0.0]
 
diff --git a/require-ess/src/expr.c b/require-ess/src/expr.c
deleted file mode 100644
index 150548b7..00000000
--- a/require-ess/src/expr.c
+++ /dev/null
@@ -1,457 +0,0 @@
-/* Copyright (C) 2020 Dirk Zimoch */
-/* Copyright (C) 2020-2022 European Spallation Source, ERIC */
-
-#include "expr.h"
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-int exprDebug;
-
-static int parseSubExpr(const char **pp, long *v, int pr, int op);
-static long parseString(const char **pp, const char **pstart);
-#define parseExpr(pp, v) parseSubExpr(pp, v, 0, 0)
-#define skipSpace(p) \
-  while (isspace((unsigned char)*p)) p++
-
-static int parseValue(const char **pp, long *v) {
-  long val;
-  const char *p = *pp;
-  char o;
-
-  /* A value is optionally prefixed with an unary operator + - ! ~.
-   * It is either a number (decimal, octal or hex)
-   * or an expression in ().
-   * Allowed chars after a number: operators, closing parenthesis, whitespace,
-   * quotes, end of string
-   */
-
-  /* first look for value */
-  skipSpace(p);
-  o = *p;
-  if (memchr("+-~!", o, 4)) {
-    /* unary operators */
-    p++;
-    if (!parseValue(&p, &val)) return 0; /* no valid value */
-    if (exprDebug) printf("parseValue: %c %ld\n", o, val);
-    if (o == '-')
-      val = -val;
-    else if (o == '~')
-      val = ~val;
-    else if (o == '!')
-      val = !val;
-  } else if (o == '(') {
-    /* sub-expression */
-    p++;
-    if (parseExpr(&p, &val) < 0) return 0; /* no valid expression */
-    skipSpace(p);
-    if (*p++ != ')') return 0; /* missing ) */
-  } else if (o == '#') {
-    /* string length operator */
-    p++;
-    if (exprDebug) printf("parseValue: string length of %s\n", p);
-    if (*p == '"' || *p == '\'')
-      val = parseString(&p, NULL);
-    else
-      return 0;
-  } else {
-    /* number */
-    char *e;
-    val = strtol(p, &e, 0);
-    if (e == p) return 0; /* no number */
-
-    if (isalpha((unsigned char)*e) || *e == '.') {
-      /* part of plain word or floating point number */
-      return 0;
-    }
-    p = e;
-  }
-  *pp = p;
-  *v = val;
-  return 1;
-}
-
-static long ipow(long base, long exp) {
-  long val;
-  if (exp == 2) return base * base;
-  if (exp == 3) return base * base * base;
-  if (exp == 1) return base;
-  if (exp == 0) return 1;
-  if (exp < 0) return 0;
-  val = ipow(base, exp >> 1);
-  val *= val;
-  if (exp & 1) val *= base;
-  return val;
-}
-
-static char parseSep(const char **pp, const char *seps) {
-  const char *p = *pp;
-
-  skipSpace(p);
-  if (!*p || !strchr(seps, *p)) return 0;
-  *pp = p + 1;
-  return *p;
-}
-
-struct {
-  char str[4];
-  int pr;
-} ops[] = {{":=", 0},  {"**", 14}, {"*", 13},  {"/", 13},   {"%", 13},
-           {"+", 12},  {"-", 12},  {"<<", 11}, {">>>", 11}, {">>", 11},
-           {"<?", 10}, {">?", 10}, {"<=>", 9}, {"<=", 8},   {">=", 8},
-           {"<", 8},   {">", 8},   {"==", 7},  {"!=", 7},   {"&&", 3},
-           {"||", 2},  {"&", 6},   {"^", 5},   {"|", 4},    {"?:", 1},
-           {"?", 1}};
-
-enum op {
-  op_none,
-  op_pow,
-  op_mul,
-  op_div,
-  op_mod,
-  op_plus,
-  op_minus,
-  op_lshift,
-  op_urshift,
-  op_rshift,
-  op_min,
-  op_max,
-  op_cmp,
-  op_lteq,
-  op_gteq,
-  op_lt,
-  op_gt,
-  op_eq,
-  op_neq,
-  op_logicand,
-  op_logicor,
-  op_bitand,
-  op_bitxor,
-  op_bitor,
-  op_alt,
-  op_if
-};
-
-static int startsWith(const char *p, const char *s) {
-  int i = 0;
-  while (*s) {
-    i++;
-    if (*p++ != *s++) return 0;
-  }
-  return i;
-}
-
-static int parseOp(const char **pp) {
-  const char *p = *pp;
-
-  skipSpace(p);
-  if (ispunct((unsigned char)*p)) {
-    for (int o = 1; o < (int)(sizeof(ops) / sizeof(ops[0])); o++) {
-      int l;
-      if ((l = startsWith(p, ops[o].str))) {
-        /* operator found */
-        *pp = p + l;
-        return o;
-      }
-    }
-  }
-  return 0;
-}
-
-static int parseSubExpr(const char **pp, long *v, int pr, int o) {
-  const char *p = *pp;
-  long val = o ? *v : 0;
-  long val2;
-  int o2;
-
-  if (exprDebug)
-    printf("parseExpr(%d): start %ld %s \"%s\"\n", pr, val, ops[o].str, p);
-  do {
-    if (!parseValue(&p, &val2)) {
-      if (exprDebug)
-        printf("parseExpr(%d): no value after %ld %s\n", pr, val, ops[o].str);
-      return -1;
-    }
-  nextop:
-    if ((o2 = parseOp(&p))) {
-      if (exprDebug)
-        printf("parseExpr(%d): %ld %s %ld %s \"%s\"\n", pr, val, ops[o].str,
-               val2, ops[o2].str, p);
-      if (o && ops[o2].pr > ops[o].pr) {
-        if ((o2 = parseSubExpr(&p, &val2, ops[o].pr, o2)) < 0) {
-          if (exprDebug)
-            printf("parseExpr(%d): parse failed after %ld %s %ld\n", pr, val,
-                   ops[o].str, val2);
-          return -1;
-        }
-      }
-    }
-    if (exprDebug)
-      printf("parseExpr(%d): calc %ld %s %ld\n", pr, val, ops[o].str, val2);
-    switch (o) {
-      case op_none:
-        val = val2;
-        break;
-      case op_pow:
-        val = ipow(val, val2);
-        break;
-      case op_mul:
-        val *= val2;
-        break;
-      case op_div:
-        val /= val2;
-        break;
-      case op_mod:
-        val %= val2;
-        break;
-      case op_plus:
-        val += val2;
-        break;
-      case op_minus:
-        val -= val2;
-        break;
-      case op_lshift:
-        val <<= val2;
-        break;
-      case op_urshift:
-        val = (unsigned long)val >> val2;
-        break;
-      case op_rshift:
-        val >>= val2;
-        break;
-      case op_min:
-        if (val2 < val) val = val2;
-        break;
-      case op_max:
-        if (val2 > val) val = val2;
-        break;
-      case op_cmp:
-        val = val < val2 ? -1 : val == val2 ? 0 : 1;
-        break;
-      case op_lteq:
-        val = val <= val2;
-        break;
-      case op_gteq:
-        val = val >= val2;
-        break;
-      case op_lt:
-        val = val < val2;
-        break;
-      case op_gt:
-        val = val > val2;
-        break;
-      case op_eq:
-        val = val == val2;
-        break;
-      case op_neq:
-        val = val != val2;
-        break;
-      case op_logicand:
-        val = val && val2;
-        break;
-      case op_logicor:
-        val = val || val2;
-        break;
-      case op_bitand:
-        val &= val2;
-        break;
-      case op_bitxor:
-        val ^= val2;
-        break;
-      case op_bitor:
-        val |= val2;
-        break;
-      case op_alt:
-        if (!val) val = val2;
-        break;
-    }
-    if (exprDebug) printf("parseExpr(%d): result %ld\n", pr, val);
-    if (o2 == op_if) {
-      long val3 = 0;
-      val2 = 1;
-      if (exprDebug) printf("parseExpr(%d) if %ld\n", pr, val);
-      if ((o2 = parseExpr(&p, &val2)) >= 0) {
-        if (exprDebug) printf("parseExpr(%d) then %ld\n", pr, val2);
-        if (parseSep(&p, ":")) {
-          parseExpr(&p, &val3);
-          if (exprDebug) printf("parseExpr(%d) else %ld\n", pr, val3);
-        }
-      }
-      if (exprDebug)
-        printf("parseExpr(%d) if %ld then %ld else %ld\n", pr, val, val2, val3);
-      val = val ? val2 : val3;
-      if (exprDebug)
-        printf("parseExpr(%d): result %ld, o2=%d, rest \"%s\" \n", pr, val, o2,
-               p);
-      if (o2 == -1) goto nextop;
-    }
-    o = o2;
-  } while (ops[o].pr && pr <= ops[o].pr);
-  if (exprDebug)
-    printf("parseExpr(%d): value = %ld return %d %s\n", pr, val, o, ops[o].str);
-  *pp = p;
-  *v = val;
-  return o;
-}
-
-static const char *getFormat(const char **pp) {
-  static char format[20];
-  const char *p = *pp;
-  if (exprDebug) printf("getFormat %s\n", p);
-  if ((format[0] = *p++) == '%') {
-    unsigned int i = 1;
-    while (i < sizeof(format) && memchr(" #-+0", *p, 5)) format[i++] = *p++;
-    while (i < sizeof(format) && *p >= '0' && *p <= '9') format[i++] = *p++;
-    if (i < sizeof(format)) format[i++] = 'l';
-    if (i < sizeof(format) && memchr("diouxXc", *p, 7)) {
-      format[i++] = *p++;
-      format[i] = 0;  // FIXME (alo): not our memory!
-      *pp = p;
-      if (exprDebug) printf("format = '%s'\n", format);
-      return format;
-    }
-  }
-  if (exprDebug) printf("no format\n");
-  return NULL;
-}
-
-static int parseSlice(const char **pp, long *pstart, long *plength) {
-  const char *p = *pp;
-  long slice_start = 0;
-  long slice_length = 0;
-  long string_length = *plength;
-  char o;
-
-  if (*p++ != '[') return 0;
-  parseExpr(&p, &slice_start);
-  if (slice_start < 0) slice_start += string_length;
-  if ((o = parseSep(&p, ":,"))) /* [start,length] or [start:end] */ {
-    parseExpr(&p, &slice_length);
-    if (o == ':') {
-      if (slice_length < 0) slice_length += string_length;
-      slice_length -= slice_start;
-    }
-  } else {
-    slice_length = 1;
-  }
-  if (slice_start < 0) {
-    slice_length += slice_start;
-    slice_start = 0;
-  }
-  if (slice_start > string_length) slice_length = 0;
-  if (slice_length > string_length - slice_start)
-    slice_length = string_length - slice_start;
-  if (slice_length < 0) slice_length = 0;
-  skipSpace(p);
-  if (*p++ != ']') return 0;
-  *pstart += slice_start;
-  *plength = slice_length;
-  *pp = p;
-  return 1;
-}
-
-static long parseString(const char **pp, const char **pstart) {
-  const char *p = *pp;
-  const char *string_start = p;
-  long slice_start = 0;
-  long length = 0;
-  char q;
-
-  q = *p++;
-  while (*p) /* string length with escapes */ {
-    if (*p == '\\')
-      if (*++p == 0) break;
-    if (*p++ == q) break;
-    length++;
-  }
-  while (parseSlice(&p, &slice_start, &length)) {
-  }
-  if (exprDebug)
-    printf("parseString %.*s[%ld,%ld]\n", (int)(p - string_start), string_start,
-           slice_start, length);
-  if (length && pstart) {
-    while (slice_start-- > 0) {
-      if (*string_start++ == '\\') string_start++;
-    }
-    *pstart = ++string_start;
-  }
-  *pp = p;
-  return length;
-}
-
-static void writeString(char **pw, const char *r, long length, char q) {
-  char *w = *pw;
-  *w++ = q;
-  while (length-- > 0) {
-    if (*r == '\\') *w++ = *r++;
-    *w++ = *r++;
-  }
-  *w++ = q;
-  *w++ = 0;
-  *pw = w;
-}
-
-size_t replaceExpressions(const char *r, char *buffer, size_t buffersize) {
-  long val, string_length;
-  char *w = buffer;
-  char *s;
-  const char *string_start = r;
-  char q;
-
-  *w = 0;
-  while (*r) {
-    s = w;
-    if (*r == '"' || *r == '\'') {
-      /* quoted strings */
-      q = *r;
-      string_length = parseString(&r, &string_start);
-      writeString(&w, string_start, string_length, q);
-      if (exprDebug) printf("quoted string %s\n", s);
-    } else if (*r == '%') {
-      /* formatted expression */
-      const char *r2 = r;
-      const char *f;
-      if (exprDebug) printf("formatted expression after '%s'\n", s);
-      if ((f = getFormat(&r2)) && parseExpr(&r2, &val) >= 0) {
-        r = r2;
-        if (w > buffer && w[-1] == '(' && *r2++ == ')') {
-          w--;
-          r = r2;
-        }
-        w += sprintf(w, f, val);
-        if (exprDebug) printf("formatted expression %s\n", s);
-      }
-    } else if (parseExpr(&r, &val) >= 0) {
-      /* unformatted expression */
-      if (r[-1] == '?' && (q = parseSep(&r, "\"'"))) {
-        /* handle expression ? "string1" : "string2" */
-        w = s;
-        r--;
-        string_length = parseString(&r, &string_start);
-        if (val) writeString(&w, string_start, string_length, q);
-        if (parseSep(&r, ":")) {
-          string_length = parseString(&r, &string_start);
-          if (!val) writeString(&w, string_start, string_length, q);
-        }
-      } else {
-        w += sprintf(w, "%ld", val);
-      }
-      if (exprDebug) printf("expression %s\n", s);
-    } else {
-      /* unquoted string (i.e plain word) */
-      do {
-        if ((*w++ = *r++) == '\\')
-          if (*r) *w++ = *r++;
-      } while (*r && !strchr("%(\"', \t\n", *r));
-      *w = 0;
-      if (exprDebug) printf("plain word '%s'\n", s);
-    }
-    /* copy space */
-    while (isspace((unsigned char)*r) || *r == ',') *w++ = *r++;
-    /* terminate */
-    *w = 0;
-  }
-  return w - buffer;
-}
diff --git a/require-ess/src/expr.h b/require-ess/src/expr.h
deleted file mode 100644
index ecea8117..00000000
--- a/require-ess/src/expr.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Copyright (C) 2020 Dirk Zimoch */
-/* Copyright (C) 2020-2022 European Spallation Source, ERIC */
-
-#pragma once
-
-#include <stddef.h>
-
-#ifdef __cplusplus
-extern {
-#endif  // __cplusplus
-
-  extern int exprDebug;
-
-  size_t replaceExpressions(const char *source, char *buffer,
-                            size_t buffersize);
-  /* Resolve integer expressions that are either free standing
-   * or in parentheses () embedded in an unquoted word.
-   * Do not resolve expressions in single or double quoted strings.
-   * An expression optionally starts with a integer format such as %x.
-   * It consists of integer numbers, operators and parentheses ().
-   */
-
-#ifdef __cplusplus
-}
-#endif  // __cplusplus
diff --git a/require-ess/src/require.h b/require-ess/src/require.h
index e961d02d..f9ba5060 100644
--- a/require-ess/src/require.h
+++ b/require-ess/src/require.h
@@ -20,7 +20,6 @@ size_t foreachLoadedLib(size_t (*func)(const char *name, const char *version,
 const char *getLibVersion(const char *libname);
 const char *getLibLocation(const char *libname);
 int libversionShow(const char *outfile);
-int runScript(const char *filename, const char *args);
 int putenvprintf(const char *format, ...)
     __attribute__((__format__(__printf__, 1, 2)));
 void pathAdd(const char *varname, const char *dirname);
diff --git a/require-ess/src/runScript.dbd b/require-ess/src/runScript.dbd
deleted file mode 100644
index ab7b21dc..00000000
--- a/require-ess/src/runScript.dbd
+++ /dev/null
@@ -1,3 +0,0 @@
-registrar(runScriptRegister)
-variable(runScriptDebug,int)
-variable(exprDebug,int)
diff --git a/require-ess/test/testscript b/require-ess/test/testscript
deleted file mode 100644
index b4b2d4ca..00000000
--- a/require-ess/test/testscript
+++ /dev/null
@@ -1,95 +0,0 @@
-#var exprDebug 1
-
-x=3, !3, !!3, -3, --3, ~3, ~~3, 3?, 3??
-# $(x) should be: 3, 0, 1, -3, 3, -4, 3, 1, 1
-
-x=x, !x, !!x, -x, --x, ~x, ~~x, x?, x??
-# $(x) should be: x, !x, !!x, -x, --x, ~x, ~~x, x?, x??
-
-x=10+3, 10-3, 10*3, 10/3, 10%3, 10**3
-# $(x) should be: 13, 7, 30, 3, 1, 1000
-
-x=7**-2 7**-1 7**0 7**1 7**2 7**3 7**4 7**5 7**6
-# $(x) should be: 0 0 1 7 49 343 2401 16807 117649
-
-x=%x -10<<2, %x -10>>2, %x -10>>>2
-# $(x) should be: ffffffffffffffd8, fffffffffffffffd, 3ffffffffffffffd
-
-x=%x 0xaa & 0x0f, %x 0xaa | 0x0f, %x 0xaa ^ 0x0f
-# $(x) should be: a, af, a5
-
-x=10<20 10<=20 10==20 10>=20 10>20 10<=>20 10<?20 10>?20 10?<20 10?>20
-# $(x) should be: 1 1 0 0 0 -1 10 20 1 0
-
-x=20<20 20<=20 20==20 20>=20 20>20 20<=>20 20<?20 20>?20 20?<20 20?>20
-# $(x) should be: 0 1 1 1 0 0 20 20 1 0
-
-x=20<10 20<=10 20==10 20>=10 20>10 20<=>10 20<?10 20>?10 20?<10 20?>10
-# $(x) should be: 0 0 0 1 1 1 10 20 1 0
-
-x= (0|0)(0|1)(1|0)(1|1) (0&0)(0&1)(1&0)(1&1) (0^0)(0^1)(1^0)(1^1)
-# $(x) should be: 0111 0001 0110
-
-x=1*2*3+4*5*6-7-8
-# $(x) should be: 111
-
-x=1*2*3+4*5*6-7*8
-# $(x) should be: 70
-
-x=-3**2+1, -(3**2)+1, (-3)**2+1, -3**-2+1, (1+2), (1+2, 1+2)
-# $(x) should be: 10, -8, 10, 1, 3, (1+2, 3)
-
-x=%#X 0x5555&0xfff0|0xaf<<8^0xa00a0>>4
-# $(x) should be: 0X5F5A
-
-x=7+4*2|32
-# $(x) should be: 47
-
-x=3<5 ? 7+4*2|32 : 9 & 10
-# $(x) should be: 47
-
-x=3>5 ? 7+4*2|32 : 9 & 10
-# $(x) should be: 8
-
-x=7 ?: -1
-# $(x) should be: 7
-
-x=0 ?: -1
-# $(x) should be: -1
-
-x=7 ? -1
-# $(x) should be: -1
-
-x=0 ? -1
-# $(x) should be: 0
-
-x=1+0?7?1:2:3?4:5
-# $(x) should be: 1
-
-x=1+0?0?1:2:3?4:5
-# $(x) should be: 2
-
-x=1-1?0?1:2:3?4:5
-# $(x) should be: 4
-
-x=1-1?0?1:2:3-3?4:5
-# $(x) should be: 5
-
-x=0?; 1?; 2?; -4?; 3?+1
-# $(x) should be: 0; 1; 1; 1; 4
-
-x=a030b a(030)b a( 030 )b "a"030"b" a(%x 030)b
-# $(x) should be: a030b a24b a24b a24b a18b
-
-x=030b (030)b ( 030 )b 030"b" %x 030'b'
-# $(x) should be: 030b 24b 24b 24b 18b
-
-x=-0bla -0.1
-# $(x) should be: -0bla -0.1
-
-x=-2**2 0-2**2 0+-2**2 0--2**2
-# $(x) should be: 4 -4 4 -4
-
-x=
-y=$(x)
-# <$(x)><$(y)> should be: <><>
diff --git a/require-ess/test/teststrings b/require-ess/test/teststrings
deleted file mode 100644
index 5c2990ab..00000000
--- a/require-ess/test/teststrings
+++ /dev/null
@@ -1,92 +0,0 @@
-x=string0
-y=$(x)
-# $(x) $(y)
-
-x="string1"
-y=$(x)
-# $(x) $(y)
-
-x="'string2'"
-y=$(x)
-# $(x) $(y)
-
-x='"string3"'
-y=$(x)
-# $(x) $(y)
-
-x=\"string4\"
-y=$(x)
-# $(x) $(y)
-
-x=\'string5\'
-y=$(x)
-# $(x) $(y)
-
-x="Hello World"[2:8]
-# $(x) should be: llo Wo
-
-x=Hello World[2:8]
-# "$(x)" should be: "Hello World[2:8]"
-
-x="Hello World"[2,3]
-# $(x) should be: llo
-
-x="Hello World"[1]
-# $(x) should be: e
-
-x="Hello World"[-1]
-# $(x) should be: d
-
-x="Hello World"[-2:]
-# $(x) should be: ld
-
-x="Hello World"[-2,6]
-# $(x) should be: ld
-
-x="Hello World"[1:1000]
-# $(x) should be: ello World
-
-x="Hello World"[1:-1000]
-# "$(x)" should be: ""
-
-x="Hello World"[:]
-# "$(x)" should be: "Hello World"
-
-x="Hello World"[1?6:0:]
-# "$(x)" should be: "World"
-
-x="Hello World"[1000]
-# "$(x)" should be: ""
-
-x="Hello World"[-1000]
-# "$(x)" should be: ""
-
-x="Hello World"[-1000,1005]
-# "$(x)" should be: "World"
-
-x="Hello World"[-1000:5]
-# "$(x)" should be: "World"
-
-x="Hello World"[7:4]
-# "$(x)" should be: ""
-
-x="Hello World"[1?3+4:0:7-8]
-# "$(x)" should be: "orl"
-
-x="Hello World"[7,-1]
-# "$(x)" should be: ""
-
-x='\"\\x'[2]
-# $(x) should be: x
-
-x=#"Hello World"
-# $(x) should be: 11
-
-x=#"Hello World"[2:8]
-# $(x) should be: 6
-
-x=#Hello World
-# $(x) should be: #Hello World
-
-x=1 ? "true" : "false"
-# $(x) should be: true
diff --git a/require.Makefile b/require.Makefile
index f1fe3ec0..e9b528f1 100644
--- a/require.Makefile
+++ b/require.Makefile
@@ -38,9 +38,6 @@ APPDB := $(APP)/Db
 SOURCES += $(APPSRC)/require.c
 SOURCES += $(APPSRC)/version.c
 DBDS    += $(APPSRC)/require.dbd
-SOURCES += $(APPSRC)/runScript.c
-DBDS    += $(APPSRC)/runScript.dbd
-SOURCES += $(APPSRC)/expr.c
 
 SOURCES += $(APPSRC)/dbLoadTemplate.y
 DBDS    += $(APPSRC)/dbLoadTemplate.dbd
-- 
GitLab