Skip to content

Commit a224f77

Browse files
committed
feat: add msiArithPostprocess function to msi
* add msiArithTest.template
1 parent 3855356 commit a224f77

5 files changed

Lines changed: 100 additions & 3 deletions

File tree

modules/database/src/ioc/dbtemplate/Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# Copyright (c) 2002 The Regents of the University of California, as
55
# Operator of Los Alamos National Laboratory.
66
# EPICS BASE is distributed subject to a Software License Agreement found
7-
# in file LICENSE that is included with this distribution.
7+
# in file LICENSE that is included with this distribution.
88
#*************************************************************************
99

1010
# This is a Makefile fragment, see src/ioc/Makefile.
@@ -13,15 +13,15 @@ SRC_DIRS += $(IOCDIR)/dbtemplate
1313

1414
PROD_HOST += msi
1515

16-
msi_SRCS = msi.cpp
16+
msi_SRCS = msi.cpp msiArith.cpp
1717
msi_SYS_LIBS_WIN32 = shlwapi
1818
DOCS += msi.md
1919

2020
INC += dbLoadTemplate.h
2121
INC += dbtoolsIocRegister.h
22+
INC += msiArith.h
2223

2324
dbCore_SRCS += dbLoadTemplate.c
2425
dbCore_SRCS += dbtoolsIocRegister.c
2526

2627
CLEANS += dbLoadTemplate_lex.c dbLoadTemplate.c
27-

modules/database/src/ioc/dbtemplate/msi.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#include <string>
1414
#include <list>
1515

16+
#include "msiArith.h"
17+
1618
#include <stdlib.h>
1719
#include <stddef.h>
1820
#include <stdio.h>
@@ -361,6 +363,7 @@ static void makeSubstitutions(inputData * const inputPvt,
361363
if (expand && !opt_D) {
362364
STEP("Expanding to output stream");
363365
n = macExpandString(macPvt, input, buffer, MAX_BUFFER_SIZE - 1);
366+
msiArithPostprocess(buffer); //add expression evaluation
364367
fputs(buffer, stdout);
365368
if (opt_V == 1 && n < 0) {
366369
fprintf(stderr, "msi: Error - undefined macros present\n");
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#include <cstdlib>
2+
#include <cstdio>
3+
#include <cstring>
4+
5+
// Detect digit
6+
static inline bool isDigit(char c) { return c >= '0' && c <= '9'; }
7+
8+
// Detect digit or "-digit"
9+
static inline bool isInteger(const char* p)
10+
{
11+
return isDigit(*p) || (*p == '-' && p[1] && isDigit(p[1]));
12+
}
13+
14+
void msiArithPostprocess(char* buffer)
15+
{
16+
if (!buffer) return;
17+
18+
size_t r = 0, w = 0;
19+
20+
while (buffer[r]) {
21+
22+
if (isInteger(buffer + r)) {
23+
24+
char* end1 = nullptr;
25+
long long base = std::strtoll(buffer + r, &end1, 0);
26+
size_t j = (size_t)(end1 - buffer);
27+
28+
if (buffer[j] == '~' &&
29+
buffer[j + 1] == '(' &&
30+
(buffer[j + 2] == '+' || buffer[j + 2] == '-'))
31+
{
32+
char sign = buffer[j + 2];
33+
34+
char* end2 = nullptr;
35+
long long off = std::strtoll(buffer + j + 3, &end2, 0);
36+
37+
if (end2 != (buffer + j + 3) && *end2 == ')') {
38+
long long res = (sign == '+') ? (base + off) : (base - off);
39+
40+
char tmp[64];
41+
int m = std::snprintf(tmp, sizeof(tmp), "%lld", res);
42+
if (m > 0) {
43+
std::memcpy(buffer + w, tmp, (size_t)m);
44+
w += (size_t)m;
45+
}
46+
47+
r = (size_t)((end2 - buffer) + 1); // skip ')'
48+
continue;
49+
}
50+
}
51+
52+
// no match -> copy original number text
53+
while (r < j) buffer[w++] = buffer[r++];
54+
continue;
55+
}
56+
57+
buffer[w++] = buffer[r++];
58+
}
59+
60+
buffer[w] = '\0';
61+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#ifndef MSI_ARITH_H
2+
#define MSI_ARITH_H
3+
4+
#include <string>
5+
6+
// In-place: <number>~(+<number>) or <number>~(-<number>), no spaces.
7+
void msiArithPostprocess(char* buffer);
8+
9+
#endif
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Minimal test for post-arithmetic: <number>~(+N) / <number>~(-N)
2+
# Run example:
3+
# msi -M"P=ArithTest,TESTNUM=99" msiArithTest.template
4+
5+
record(stringin, "$(P):orig") {
6+
field(VAL, "$(TESTNUM)")
7+
field(DESC, "orig: $(TESTNUM)")
8+
}
9+
10+
record(stringin, "$(P):plus1") {
11+
field(VAL, "$(TESTNUM)~(+1)")
12+
field(DESC, "plus1: $(TESTNUM)~(+1)")
13+
}
14+
15+
record(stringin, "$(P):minus1") {
16+
field(VAL, "$(TESTNUM)~(-1)")
17+
field(DESC, "minus1: $(TESTNUM)~(-1)")
18+
}
19+
20+
# Should NOT change
21+
record(stringin, "$(P):spaces_should_stay") {
22+
field(VAL, "$(TESTNUM) ~ (+1)")
23+
field(DESC, "spaces: $(TESTNUM) ~ (+1)")
24+
}

0 commit comments

Comments
 (0)