Skip to content
Snippets Groups Projects
Commit e6a070a0 authored by Simon Rose's avatar Simon Rose
Browse files

Add afterInit back to require

parent a8fe7a69
No related branches found
No related tags found
No related merge requests found
/* Copyright (C) 2020 Dirk Zimoch */ /* Copyright (C) 2020 Dirk Zimoch */
/* Copyright (C) 2020-2022 European Spallation Source, ERIC */ /* Copyright (C) 2020-2023 European Spallation Source, ERIC */
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <ctype.h>
#include <dbAccess.h> #include <dbAccess.h>
#include <epicsVersion.h> #include <epicsExport.h>
#include <epicsStdio.h>
#include <errno.h> #include <errno.h>
#include <initHooks.h> #include <initHooks.h>
#include <macLib.h> #include <iocsh.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#define EPICSVER \
EPICS_VERSION * 10000 + EPICS_REVISION * 100 + EPICS_MODIFICATION
#include <iocsh.h>
#include <osiFileName.h>
DBCORE_API int epicsStdCall iocshCmd(const char *cmd);
#include <epicsExport.h>
#define IS_ABS_PATH(filename) \
(filename[0] == OSI_PATH_SEPARATOR[0]) /* may be different for other OS ? */
#include "expr.h"
#include "require.h"
#define SAVEENV(var) \
do { \
old_##var = getenv(#var); \
if (old_##var) old_##var = strdup(old_##var); \
} while (0)
#define RESTOREENV(var) \
do { \
if (old_##var) { \
putenvprintf("%s=%s", #var, old_##var); \
free(old_##var); \
} \
} while (0)
int runScriptDebug = 0;
int runScript(const char *filename, const char *args) {
MAC_HANDLE *mac = NULL;
FILE *file = NULL;
char *line_raw = NULL;
char *aux_pointer = NULL;
char *line_exp = NULL;
long line_raw_size = 256;
long line_exp_size = line_raw_size;
long len;
char **pairs;
int status = 0;
char *old_MODULE = NULL;
char *old_MODULE_DIR = NULL;
if (!filename) {
fprintf(stderr, "Usage: runScript filename [macro=value,...]\n");
return -1;
}
if (macCreateHandle(&mac, (const char *[]){"", "environ", NULL, NULL}) != 0)
goto error;
macSuppressWarning(mac, 1);
if ((line_exp = malloc(line_exp_size)) == NULL) goto error;
if ((line_raw = malloc(line_raw_size)) == NULL) goto error;
/* add args to macro definitions */
if (args) {
if (runScriptDebug) printf("runScript: macParseDefns \"%s\"\n", args);
macParseDefns(mac, (char *)args, &pairs);
macInstallMacros(mac, pairs);
free(pairs);
}
if (IS_ABS_PATH(filename)) {
file = fopen(filename, "r");
} else {
const char *dirname;
const char *end;
char *fullname;
const char *path = getenv("SCRIPT_PATH");
int dirlen;
for (dirname = path; dirname != NULL; dirname = end) {
end = strchr(dirname, OSI_PATH_LIST_SEPARATOR[0]);
if (end && end[1] == OSI_PATH_SEPARATOR[0] &&
end[2] == OSI_PATH_SEPARATOR[0]) /* "http://..." and friends */
end = strchr(end + 2, OSI_PATH_LIST_SEPARATOR[0]);
if (end)
dirlen = (int)(end++ - dirname);
else
dirlen = (int)strlen(dirname);
if (dirlen == 0) continue; /* ignore empty path elements */
if (dirname[dirlen - 1] == OSI_PATH_SEPARATOR[0]) dirlen--;
asprintf(&fullname, "%.*s" OSI_PATH_SEPARATOR "%s", dirlen, dirname,
filename);
if (runScriptDebug) printf("runScript: trying %s\n", fullname);
file = fopen(fullname, "r");
if (!file && (errno & 0xffff) != ENOENT) perror(fullname);
free(fullname);
if (file) break;
}
}
if (file == NULL) {
perror(filename);
return errno;
}
/* save some environments variables */
SAVEENV(MODULE);
SAVEENV(MODULE_DIR);
/* execute script line by line after expanding macros with arguments or
* environment */
while (fgets(line_raw, line_raw_size, file)) {
char *p, *x;
/* check if we have a line longer than the buffer size */
while (line_raw[(len = (long)strlen(line_raw)) - 1] != '\n' &&
!feof(file)) {
if (runScriptDebug) printf("runScript partial line: \"%s\"\n", line_raw);
if ((aux_pointer = realloc(line_raw, line_raw_size *= 2)) == NULL)
goto error;
line_raw = aux_pointer;
if (fgets(line_raw + len, line_raw_size - len, file) == NULL) break;
}
while (len > 0 && isspace((unsigned char)line_raw[len - 1]))
line_raw[--len] = 0; /* get rid of '\n' and friends */
if (runScriptDebug)
printf("runScript raw line (%ld chars): '%s'\n", len, line_raw);
/* expand and check the buffer size (different epics versions write
* different may number of bytes)*/
while ((len = labs(
macExpandString(mac, line_raw, line_exp, line_exp_size - 1))) >=
line_exp_size - 2) {
if (runScriptDebug)
printf("runScript: grow expand buffer: len=%ld size=%ld\n", len,
line_exp_size);
free(line_exp);
if ((line_exp = malloc(line_exp_size *= 2)) == NULL) goto error;
}
if (runScriptDebug)
printf("runScript expanded line (%ld chars): '%s'\n", len, line_exp);
printf("%s\n", line_exp);
p = line_exp;
while (isspace((unsigned char)*p)) p++;
if (*p == 0 || *p == '#') continue;
/* find local variable assignments */
if ((x = strpbrk(p, "=(, \t\n\r")) != NULL && *x == '=') {
*x++ = 0;
replaceExpressions(x, line_raw, line_raw_size);
if (runScriptDebug) printf("runScript: assign %s=%s\n", p, line_raw);
macPutValue(mac, p, line_raw);
continue;
}
if (runScriptDebug) printf("runScript: iocshCmd: '%s'\n", line_exp);
status = iocshCmd(line_exp);
if (status != 0) break;
}
goto end;
error:
if (errno) {
status = errno;
perror("runScript");
}
end:
free(line_raw);
free(line_exp);
if (mac) macDeleteHandle(mac);
if (file) fclose(file);
/* restore environment */
RESTOREENV(MODULE);
RESTOREENV(MODULE_DIR);
return status;
}
struct cmditem { struct cmditem {
struct cmditem *next; struct cmditem *next;
int type; int type;
...@@ -191,7 +17,7 @@ struct cmditem { ...@@ -191,7 +17,7 @@ struct cmditem {
char *a[12]; char *a[12];
char cmd[256]; char cmd[256];
} x; } x;
} * cmdlist, **cmdlast = &cmdlist; } *cmdlist, **cmdlast = &cmdlist;
void afterInitHook(initHookState state) { void afterInitHook(initHookState state) {
struct cmditem *item; struct cmditem *item;
...@@ -219,9 +45,8 @@ void afterInitHook(initHookState state) { ...@@ -219,9 +45,8 @@ void afterInitHook(initHookState state) {
} }
} }
static int first_time = 1;
static struct cmditem *newItem(char *cmd, int type) { static struct cmditem *newItem(char *cmd, int type) {
static int first_time = 1;
struct cmditem *item; struct cmditem *item;
if (!cmd) { if (!cmd) {
fprintf(stderr, "usage: afterInit command, args...\n"); fprintf(stderr, "usage: afterInit command, args...\n");
...@@ -268,20 +93,6 @@ int afterInit(char *cmd, char *a1, char *a2, char *a3, char *a4, char *a5, ...@@ -268,20 +93,6 @@ int afterInit(char *cmd, char *a1, char *a2, char *a3, char *a4, char *a5,
return 0; return 0;
} }
epicsExportAddress(int, runScriptDebug);
epicsExportAddress(int, exprDebug);
static const iocshFuncDef runScriptDef = {
"runScript", 2,
(const iocshArg *[]){
&(iocshArg){"filename", iocshArgString},
&(iocshArg){"substitutions", iocshArgString},
}};
static void runScriptFunc(const iocshArgBuf *args) {
runScript(args[0].sval, args[1].sval);
}
static const iocshFuncDef afterInitDef = { static const iocshFuncDef afterInitDef = {
"afterInit", 1, "afterInit", 1,
(const iocshArg *[]){ (const iocshArg *[]){
...@@ -302,12 +113,11 @@ static void afterInitFunc(const iocshArgBuf *args) { ...@@ -302,12 +113,11 @@ static void afterInitFunc(const iocshArgBuf *args) {
} }
} }
static void runScriptRegister(void) { static void afterInitRegister(void) {
static int firstTime = 1; static int firstTime = 1;
if (firstTime) { if (firstTime) {
firstTime = 0; firstTime = 0;
iocshRegister(&runScriptDef, runScriptFunc);
iocshRegister(&afterInitDef, afterInitFunc); iocshRegister(&afterInitDef, afterInitFunc);
} }
} }
epicsExportRegistrar(runScriptRegister); epicsExportRegistrar(afterInitRegister);
registrar(afterInitRegister)
...@@ -37,7 +37,9 @@ APPDB := $(APP)/Db ...@@ -37,7 +37,9 @@ APPDB := $(APP)/Db
SOURCES += $(APPSRC)/require.c SOURCES += $(APPSRC)/require.c
SOURCES += $(APPSRC)/version.c SOURCES += $(APPSRC)/version.c
SOURCES += $(APPSRC)/afterInit.c
DBDS += $(APPSRC)/require.dbd DBDS += $(APPSRC)/require.dbd
DBDS += $(APPSRC)/afterInit.dbd
SOURCES += $(APPSRC)/dbLoadTemplate.y SOURCES += $(APPSRC)/dbLoadTemplate.y
DBDS += $(APPSRC)/dbLoadTemplate.dbd DBDS += $(APPSRC)/dbLoadTemplate.dbd
......
...@@ -45,3 +45,11 @@ def test_cellpath_does_not_depend_on_order(wrapper: Wrapper): ...@@ -45,3 +45,11 @@ def test_cellpath_does_not_depend_on_order(wrapper: Wrapper):
rc, *_ = run_ioc_get_output("-r", wrapper.name, "-l", cell_path) rc, *_ = run_ioc_get_output("-r", wrapper.name, "-l", cell_path)
assert rc == 0 assert rc == 0
def test_after_init():
rc, outs, _ = run_ioc_get_output("-c", "afterInit echo hello")
assert rc == 0
lines = outs.split("\n")
assert "hello" in lines[lines.index("iocInit") :]
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment