Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • e3/wrappers/e3-require
  • waynelewis/e3-require
  • krisztianloki/e3-require
  • timokorhonen/e3-require
  • juntongliu/e3-require
  • roryclarke/e3-require
  • alfiorizzo/e3-require
  • lucasmagalhaes/e3-require
  • lucas-module-testgroup/e3-require
  • grzegorzkowalski/e3-require
  • anderslindh1/e3-require
11 results
Show changes
Showing
with 359 additions and 174 deletions
TEST_DIR:=$(TOP)/tests
RUN_IOCSH_TEST_COMMAND = run-iocsh --name "${EPICS_BASE}/require/${E3_REQUIRE_VERSION}/bin/iocsh.bash" -r "$(E3_MODULE_NAME),$(E3_MODULE_VERSION)" -l $(TEMP_CELL_PATH)
RUN_IOCSH_TEST_COMMAND = run-iocsh -r "$(E3_MODULE_NAME),$(E3_MODULE_VERSION)"
TEMP_CELL_PATH := $(TOP)/testMods-$(shell date +"%y%m%d%H%M%S")
RMDIR = $(RM) -rf
......@@ -9,3 +9,10 @@ EXPORT_VARS+=TEMP_CELL_PATH
VARS_EXCLUDES+=TEST_DIR
VARS_EXCLUDES+=RMDIR
VARS_EXCLUDES+=TEMP_CELL_PATH
ifneq (,$(findstring test,$(MAKECMDGOALS)))
E3_MODULES_PATH=$(TEMP_CELL_PATH)/$(notdir $(EPICS_BASE))/require-$(E3_REQUIRE_VERSION)
# We have to do the export here since the sub-processes - like run-iocsh - otherwise would not inherit the variable
export EPICS_DRIVER_PATH:=$(E3_MODULES_PATH):$(EPICS_DRIVER_PATH)
PATH:=$(EPICS_BASE)/require/$(E3_REQUIRE_VERSION)/bin:$(PATH)
endif
# Legacy file. Needed since <module>.Makefiles include this.
# Keep always the module up-to-date
define git_update =
git submodule deinit -f $@/
rm -rf $(TOP)/.git/modules/$@
define git_update
rm -rf $(TOP)/$@
git submodule init $@/
git submodule update --init --recursive $@/.
git submodule update --remote --merge $@/
endef
define git_module_init_update =
git submodule update --init --recursive $@/.
git submodule update --remote --merge $@/
endef
define patch_site
patches=$$(ls $(TOP)/patch/Site/$(E3_MODULE_VERSION)/*.p0.patch 2> /dev/null); \
patches=$$(ls $(TOP)/patch/*.p0.patch 2> /dev/null); \
if [ -n "$$patches" ]; then \
for i in $$patches; do \
printf "\nPatching %s with the file : %s\n" "$(E3_MODULE_SRC_PATH)" "$$i"; \
git apply --directory=$(E3_MODULE_SRC_PATH) --ignore-whitespace -p0 $$i; \
done; \
else \
echo ">>> No patches to apply" >&2; \
echo ">>> No patches to apply"; \
fi
endef
define patch_revert_site
patches=$$(ls $(TOP)/patch/Site/$(E3_MODULE_VERSION)/*.p0.patch 2> /dev/null); \
patches=$$(ls $(TOP)/patch/*.p0.patch 2> /dev/null); \
if [ -n "$$patches" ]; then \
for i in $$patches; do\
printf "\nReverting applied patch %s with the file : %s\n" "$(E3_MODULE_SRC_PATH)" "$$i"; \
git apply -R --directory=$(E3_MODULE_SRC_PATH) --ignore-whitespace -p0 $$i;\
done \
else \
echo ">>> No patches to revert" >&2; \
echo ">>> No patches to revert"; \
fi
endef
......@@ -42,7 +36,6 @@ endif
### Exclude the following variables to display
VARS_EXCLUDES+=git_update
VARS_EXCLUDES+=git_module_init_update
VARS_EXCLUDES+=patch_site
VARS_EXCLUDES+=patch_revert_site
VARS_EXCLUDES+=QUIET
......
.PHONY: cellbuild
## Builds the module while also searching in $(E3_CELL_PATH) for dependencies
cellbuild: build
cellbuild: ${COMMON_DIR}/${METAFILE}
.PHONY: cellinstall
## Installs the module in a local directory $(E3_CELL_PATH)
cellinstall: install_module fix_permissions
cellinstall: install fix_permissions
.PHONY: celluninstall
## Remove the module from the local directory $(E3_CELL_PATH)
......
......@@ -2,7 +2,7 @@
consistency_checks: module_name_check loc-check
ifneq (require,$(E3_MODULE_NAME))
consistency_checks: sitemods_check
consistency_checks: sitemods_check build_path_check
endif
# Check that the module name satisfies a few conditions before we go on.
......@@ -19,8 +19,13 @@ ifeq ($(filter RULES_SITEMODS,$(notdir $(MAKEFILE_LIST))),)
endif
# Check that e3 wrappers are using EPICS_MODULE_TAG to manage local source mode
.PHONU: loc-check
.PHONY: loc-check
loc-check:
ifneq (,$(findstring -loc,$(E3_MODULE_SRC_PATH)))
$(error DEPRECATED: Local source mode "-loc" has been deprecated. Please comment out the EPICS_MODULE_TAG to use local source mode.)
endif
.PHONY: build_path_check
build_path_check:
$(if $(filter $(abspath $(E3_MODULES_PATH))/%,$(abspath $(TOP))),$(warning It is ill-advised to build a module from the module install location.)\
$(warning Please note that you may obtain unexpected results.))
# -*- mode: Makefile;-*-
ifneq ($(E3_LOCAL_SOURCE),1)
.PHONY: devvars devenv devinit devbuild devclean devinstall devrebuild devuninstall devdistclean devconf devepics devepics-clean devepics-distclean devpatch devpatchrevert devexistent devdep devvers
.PHONY: devvars devenv devinit devbuild devclean devinstall devrebuild devuninstall devdistclean devconf devepics devepics-clean devepics-distclean devpatch devexistent devdep devvers
devvars: vars
......@@ -30,7 +30,6 @@ devepics: nonexists
devepics-clean: nonexists
devepics-distclean: nonexists
devpatch: nonexists
devpatchrevert: nonexists
devexistent: nonexists
devdep: nonexists
devvers: nonexists
......@@ -66,7 +65,6 @@ devepics: epics
devepics-clean: epics-clean
devepics-distclean: epics-distclean
devpatch: patch
devpatchrevert: patchrevert
devexistent: existent
devdep: dep
devvers: vers
......
......@@ -3,10 +3,13 @@
.DEFAULT_GOAL := help
.PHONY: help default install uninstall build rebuild clean conf all prebuild
.PHONY: help default install uninstall build rebuild clean all prebuild
default: help
# Include some checks before build happens
include $(E3_REQUIRE_CONFIG)/RULES_CHECKS
# # help is defined in
# # https://gist.github.com/rcmachado/af3db315e31383502660
help:
......@@ -28,9 +31,6 @@ help:
## Install module to $(E3_MODULES_INSTALL_LOCATION)
install: install_module hdrs
.PHONY: db
db: err_no_db_rule
......@@ -38,48 +38,57 @@ db: err_no_db_rule
err_no_db_rule:
$(error The 'db' target has been discontinued. If you have custom database expansion rule to use, please contact the e3 team)
.PHONY: install_module
install_module: build db_internal
# Decouple build and install targets by using metadata file generated during
# build as install prerequisite.
# The metadata file target cannot depend on build, since its phony nature will
# trigger the rebuild anyway. Instead, the metadata file is created as a side
# effect of running the build target in separate make process.
${COMMON_DIR}/${METAFILE}:
$(QUIET) $(MAKE) build
## Install module to $(E3_MODULES_INSTALL_LOCATION)
install: ${COMMON_DIR}/${METAFILE}
$(QUIET) $(E3_MODULE_MAKE_CMDS) install
@echo "Installing metadata file $(MODULE_INSTALL_LOCATION)/${METAFILE}"
$(QUIET) install -m444 ${COMMON_DIR}/${METAFILE} ${MODULE_INSTALL_LOCATION}
.PHONY: check_uninstall
check_uninstall:
## Uninstall the current module
uninstall: check_uninstall conf
uninstall: check_uninstall
$(QUIET) $(E3_MODULE_MAKE_CMDS) uninstall
## Build current module
build: conf checkout prebuild
build: consistency_checks checkout prebuild db_internal
$(QUIET) $(E3_MODULE_MAKE_CMDS) build
@echo "Populating metadata file ${COMMON_DIR}/${METAFILE}"
@echo "wrapper_url: '$(${E3_MODULE_NAME}_E3_GIT_URL)'" > ${COMMON_DIR}/${METAFILE}
@echo "wrapper_git_desc: '$(${E3_MODULE_NAME}_E3_GIT_DESC)'" >> ${COMMON_DIR}/${METAFILE}
@echo "module_git_desc: '$(shell git rev-parse HEAD 2> /dev/null)'" >> ${COMMON_DIR}/${METAFILE}
## Run module-specific commands before building
prebuild: conf
prebuild: consistency_checks
$(QUIET) $(E3_MODULE_MAKE_CMDS) prebuild
## Displays information about the build process
debug: conf
debug:
$(QUIET) $(E3_MODULE_MAKE_CMDS) debug
.PHONY: db_internal
db_internal: conf
db_internal: consistency_checks
$(QUIET) $(E3_MODULE_MAKE_CMDS) db_internal
## Clean, build, and install the current module
rebuild: clean build install
## Deletes temporary build files
clean: conf
clean:
$(QUIET) $(E3_MODULE_MAKE_CMDS) clean
## Initializes, patches, builds, and installs
all: init patch rebuild
# Copy $(E3_MODULE_MAKEFILE) into $(E3_MODULE_SRC_PATH)
include $(REQUIRE_CONFIG)/RULES_CHECKS
conf: consistency_checks
$(QUIET) install -p -m 644 $(TOP)/$(E3_MODULE_MAKEFILE) $(E3_MODULE_SRC_PATH)/
.PHONY: init git-submodule-sync $(E3_MODULE_SRC_PATH) checkout
ifeq (,$(strip $(EPICS_MODULE_TAG)))
......
# One should define the any dependency modules and EPICS base path
# in the following directory
.PHONY: epics-clean epics-distclean
epics-clean:
$(MAKE) -C $(E3_MODULE_SRC_PATH) clean
epics-distclean:
$(MAKE) -C $(E3_MODULE_SRC_PATH) distclean
.PHONY: patch patchrevert
.PHONY: patch
.PHONY: check_for_old_patches
check_for_old_patches:
$(if $(wildcard $(TOP)/patch/Site/$(patsubst %+0,%,$(E3_MODULE_VERSION))*.p0.patch),$(warning Warning: old-style patches detected. Please move them to patch/Site/$$E3_MODULE_VERSION/.))
## Apply Patch Files
patch:
define PATCH_TEMPLATE
patch: $1
.PHONY: $1
$1:
@echo "Applying patch $$@"
git apply --directory=$$(E3_MODULE_SRC_PATH) --ignore-whitespace -p0 $$@
endef
## Apply Patch Files
patch: check_for_old_patches
$(QUIET) $(call patch_site)
ifneq ($(strip $(PATCHES)),)
$(foreach patch,$(PATCHES),$(eval $(call PATCH_TEMPLATE,$(patch))))
else
patch:
@echo "No patches to apply"
## Revert Patch Files
patchrevert: check_for_old_patches
$(QUIET) $(call patch_revert_site)
endif
# -*- mode: Makefile;-*-
include $(REQUIRE_CONFIG)/RULES_E3
include $(REQUIRE_CONFIG)/RULES_CELL
include $(REQUIRE_CONFIG)/DEFINES_FT
include $(REQUIRE_CONFIG)/RULES_PATCH
include $(REQUIRE_CONFIG)/RULES_TEST
include $(E3_REQUIRE_CONFIG)/RULES_E3
include $(E3_REQUIRE_CONFIG)/RULES_CELL
include $(E3_REQUIRE_CONFIG)/DEFINES_FT
include $(E3_REQUIRE_CONFIG)/RULES_PATCH
include $(E3_REQUIRE_CONFIG)/RULES_TEST
include $(REQUIRE_CONFIG)/RULES_DKMS
include $(REQUIRE_CONFIG)/RULES_VARS
include $(E3_REQUIRE_CONFIG)/RULES_DKMS
include $(E3_REQUIRE_CONFIG)/RULES_VARS
include $(REQUIRE_CONFIG)/RULES_DEV
include $(E3_REQUIRE_CONFIG)/RULES_DEV
EPICS_BASE=/epics/base-7.0.5
EPICS_BASE=/epics/base-7.0.8.1
E3_REQUIRE_NAME:=require
E3_REQUIRE_VERSION:=3.4.1
E3_REQUIRE_VERSION:=5.1.1
# The definitions shown below can also be placed in an untracked RELEASE.local
......
# -*- mode: Makefile;-*-
# include $(EPICS_BASE)/configure/RULES
include $(REQUIRE_CONFIG)/DEFINES_FT
#
# We cannot use file operation in CentOS7.4,
# because Makefile version is 3.8.
include $(REQUIRE_CONFIG)/RULES_E3
include $(REQUIRE_CONFIG)/RULES_EPICS
include $(E3_REQUIRE_CONFIG)/RULES_E3
include $(TOP)/configure/module/RULES_REQUIRE
include $(REQUIRE_CONFIG)/RULES_PATCH
include $(REQUIRE_CONFIG)/RULES_VARS
include $(E3_REQUIRE_CONFIG)/DEFINES_FT
include $(E3_REQUIRE_CONFIG)/RULES_PATCH
include $(TOP)/configure/module/RULES_TEST
include $(E3_REQUIRE_CONFIG)/RULES_VARS
ifneq (,$(findstring dev,$(MAKECMDGOALS)))
include $(REQUIRE_CONFIG)/RULES_DEV
include $(E3_REQUIRE_CONFIG)/RULES_DEV
endif
......@@ -7,8 +7,8 @@
FILE_FILTER:= %~ %\#
E3_TEST_SCRIPT := $(TOP)/tools/test_installed_modules.sh
#
E3_SHELL_FILES := $(wildcard $(E3_MODULE_SRC_PATH)/tools/iocsh*.bash)
E3_IOC_CFG_FILES += $(E3_MODULE_SRC_PATH)/tools/setE3Env.bash
E3_SHELL_FILES := $(wildcard $(E3_MODULE_SRC_PATH)/tools/iocsh*)
E3_IOC_CFG_FILES += $(E3_MODULE_SRC_PATH)/tools/activate
E3_IOC_CFG_FILES += $(E3_MODULE_SRC_PATH)/tools/promptE3Env.bash
E3_REQUIRE_CONF_FILES := $(filter-out $(FILE_FILTER), $(wildcard $(TOP)/configure/E3/*))
......@@ -22,18 +22,17 @@ endif
install: requireconf
requireconf: e3-site-path e3-require-path
$(QUIET) install -m 755 $(wildcard $(E3_MODULE_SRC_PATH)/tools/*.tcl) $(E3_REQUIRE_TOOLS)/
$(QUIET) install -m 644 $(E3_MODULE_SRC_PATH)/tools/driver.makefile $(E3_REQUIRE_TOOLS)/
$(QUIET) install -m 755 $(E3_MODULE_SRC_PATH)/tools/*.sh $(E3_REQUIRE_TOOLS)/
$(QUIET) install -m 755 $(E3_MODULE_SRC_PATH)/tools/revision_number $(E3_REQUIRE_TOOLS)/
$(QUIET) install -m 755 $(E3_SHELL_FILES) $(E3_REQUIRE_BIN)/
$(QUIET) install -m 644 $(E3_IOC_CFG_FILES) $(E3_REQUIRE_BIN)/
$(QUIET) install -m 644 $(E3_REQUIRE_CONF_FILES) $(E3_REQUIRE_CONFIG)/
$(QUIET) install -m 644 $(E3_REQUIRE_CONF_FILES) $(E3_REQUIRE_LOCATION)/configure/
e3-require-path:
$(QUIET) install -d -m 755 $(E3_REQUIRE_TOOLS)
$(QUIET) install -d -m 755 $(E3_REQUIRE_BIN)
$(QUIET) install -d -m 755 $(E3_REQUIRE_CONFIG)
$(QUIET) install -d -m 755 $(E3_REQUIRE_LOCATION)/configure
e3-site-path:
......@@ -52,9 +51,6 @@ forceuninstall: conf
consistency_checks:
.PHONY: hdrs
hdrs:
VARS_EXCLUDES+=FILE_FILTER
VARS_EXCLUDES+=E3_SHELL_FILES
VARS_EXCLUDES+=E3_IOC_CFG_FILES
......
record (waveform, "$(REQUIRE_IOC):MODULES")
record(waveform, "$(REQUIRE_IOC):Modules")
{
field (DESC, "List of loaded modules")
field (FTVL, "STRING")
field (NELM, "$(MODULE_COUNT)")
field (PINI, "YES")
field(DESC, "Names of loaded modules")
field(FTVL, "STRING")
field(NELM, "$(MODULE_COUNT)")
field(PINI, "YES")
field(DISP, "1")
info(Q:group, {
"$(REQUIRE_IOC):LoadedModules":{"value.MODS":{+trigger:"*",+channel:"VAL"}}
})
}
record (waveform, "$(REQUIRE_IOC):VERSIONS")
record (waveform, "$(REQUIRE_IOC):Versions")
{
field (DESC, "Versions of loaded modules")
field (FTVL, "STRING")
field (NELM, "$(MODULE_COUNT)")
field (PINI, "YES")
info(Q:group, {
"$(REQUIRE_IOC):LoadedModules":{"value.VERS":{+type:"plain",+channel:"VAL"}}
})
}
record (waveform, "$(REQUIRE_IOC):MOD_VER")
record(waveform, "$(REQUIRE_IOC):ModuleVersions")
{
field (DESC, "List of loaded modules")
field (FTVL, "CHAR")
field (NELM, "$(BUFFER_SIZE)")
field (PINI, "YES")
field(DESC, "Name and version of the loaded modules")
field(FTVL, "CHAR")
field(NELM, "$(BUFFER_SIZE)")
field(PINI, "YES")
field(DISP, "1")
}
record (stringin, "$(REQUIRE_IOC):$(MODULE)_VER")
record(stringin, "$(REQUIRE_IOC):$(MODULE)Version")
{
field (DESC, "Module $(MODULE) version")
field (VAL, "$(VERSION)")
field (PINI, "YES")
field(DESC, "Module $(MODULE) version")
field(VAL, "$(VERSION)")
field(PINI, "YES")
field(DISP, "1")
}
record(stringin,"$(REQUIRE_IOC):BaseVersion")
{
field(DESC, "EPICS Base version")
field(DTYP, "getenv")
field(INP, "@EPICS_VERSION_FULL")
field(PINI, "YES")
field(DISP, "1")
}
# This record contains labels for the created NTTable, named $(REQUIRE_IOC):LoadedModules.
record(aai, "$(REQUIRE_IOC):Labels")
{
field(DESC, "Labels for the NTTable")
field(FTVL, "STRING")
field(NELM, "2")
field(INP, {const:["Module", "Version"]})
field(PINI, "YES")
field(DISP, "1")
info(Q:group, {
"$(REQUIRE_IOC):LoadedModules":{
+id:"epics:nt/NTTable:1.0",
"labels":{+type:"plain", +channel:"VAL"}
}
})
}
/* Copyright (C) 2020 Dirk Zimoch */
/* Copyright (C) 2020-2023 European Spallation Source, ERIC */
#include <dbAccess.h>
#include <epicsExport.h>
#include <epicsStdio.h>
#include <epicsString.h>
#include <errlog.h>
#include <errno.h>
#include <initHooks.h>
#include <iocsh.h>
#include <stdlib.h>
#include <string.h>
struct cmditem {
struct cmditem *next;
char *cmd;
};
struct cmditem *cmdlist, **cmdlast = &cmdlist;
void afterInitHook(initHookState state) {
if (state != initHookAfterIocRunning) return;
struct cmditem *item = cmdlist;
struct cmditem *next = NULL;
while (item) {
printf("%s\n", item->cmd);
if (iocshCmd(item->cmd)) {
errlogPrintf("afterInit: Command '%s' failed to run\n", item->cmd);
};
next = item->next;
free(item->cmd);
free(item);
item = next;
}
}
static struct cmditem *newItem(char *cmd) {
struct cmditem *item;
item = malloc(sizeof(struct cmditem));
if (item == NULL) {
return NULL;
}
item->cmd = epicsStrDup(cmd);
item->next = NULL;
*cmdlast = item;
cmdlast = &item->next;
return item;
}
static const iocshFuncDef afterInitDef = {
"afterInit", 1,
(const iocshArg *[]){
&(iocshArg){"commandline", iocshArgString},
}};
static void afterInitFunc(const iocshArgBuf *args) {
static int first_time = 1;
char *cmd;
if (first_time) {
first_time = 0;
initHookRegister(afterInitHook);
}
if (interruptAccept) {
errlogPrintf("afterInit can only be used before iocInit\n");
return;
}
cmd = args[0].sval;
if (!cmd || !cmd[0]) {
errlogPrintf("Usage: afterInit \"command\"\n");
return;
}
struct cmditem *item = newItem(cmd);
if (!item)
errlogPrintf("afterInit: error adding command %s; %s", cmd,
strerror(errno));
}
static void afterInitRegister(void) {
static int firstTime = 1;
if (firstTime) {
firstTime = 0;
iocshRegister(&afterInitDef, afterInitFunc);
}
}
epicsExportRegistrar(afterInitRegister);
registrar(afterInitRegister)
#include "asprintf.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
/* some implementations have __va_copy instead of va_copy */
#if !defined(va_copy) && defined(__va_copy)
#define va_copy __va_copy
#endif
int vasprintf(char **pbuffer, const char *format, va_list ap) {
int len = -1;
#ifdef va_copy
va_list ap2;
va_copy(ap2, ap);
#else
/* if we have no va_copy, we probably don't need one */
#define ap2 ap
#endif
#if defined(_WIN32)
len = _vscprintf(format, ap2);
#else
len = vsnprintf(NULL, 0, format, ap2);
#endif
#ifdef va_copy
va_end(ap2);
#endif
if (len <= 0) {
fprintf(stderr, "vasprintf: error calculating needed size\n");
return -1;
}
*pbuffer = malloc(len + 1);
if (*pbuffer == NULL)
return -1;
return vsprintf(*pbuffer, format, ap);
}
int asprintf(char **pbuffer, const char *format, ...) {
va_list ap;
int len;
va_start(ap, format);
len = vasprintf(pbuffer, format, ap);
va_end(ap);
return len;
}
#ifndef asprintf_h
#define asprintf_h
#ifdef __cplusplus
extern "C" {
#endif
#include <stdarg.h>
#ifndef __GNUC__
#define __attribute__(arg)
#endif
int asprintf(char **pbuffer, const char *format, ...)
__attribute__((__format__(__printf__, 2, 3)));
int vasprintf(char **pbuffer, const char *format, va_list ap)
__attribute__((__format__(__printf__, 2, 0)));
#ifdef __cplusplus
}
#endif
#endif
#include "common.h"
#include <dbAccess.h>
#include <errlog.h>
#include <errno.h>
#ifdef __MACH__
#include <mach/error.h>
#else
#include <error.h>
#endif
#include <limits.h>
#include <osiFileName.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *realpathSeparator(const char *location) {
size_t size = 0;
char *buffer = realpath(location, NULL);
if (!buffer) {
debug("require: realpath(%s) failed\n", location);
errlogPrintf("require: %s", strerror(errno));
return NULL;
}
size = strnlen(buffer, PATH_MAX);
/* linux realpath removes trailing slash */
if (buffer[size - 1] != OSI_PATH_SEPARATOR[0]) {
char *tmp = realloc(buffer, size + sizeof(OSI_PATH_SEPARATOR));
if (!tmp) {
free(buffer);
return NULL;
}
buffer = tmp;
strcpy(buffer + size, OSI_PATH_SEPARATOR);
}
return buffer;
}
int putenvprintf(const char *format, ...) {
va_list ap;
char *var = NULL;
char *val = NULL;
int status = 0;
if (!format) return -1;
va_start(ap, format);
if (vasprintf(&var, format, ap) < 0) {
errlogPrintf("require putenvprintf %s", strerror(errno));
return errno;
}
va_end(ap);
debug("require: putenv(\"%s\")\n", var);
val = strchr(var, '=');
if (!val) {
fprintf(stderr, "putenvprintf: string contains no =: %s\n", var);
status = -1;
} else {
*val++ = 0;
if (setenv(var, val, 1) != 0) {
errlogPrintf("require putenvprintf: setenv failed %s", strerror(errno));
status = errno;
}
}
free(var);
return status;
}
void pathAdd(const char *varname, const char *dirname) {
char *old_path = NULL;
if (!varname || !dirname) {
errlogPrintf("usage: pathAdd \"ENVIRONMENT_VARIABLE\",\"directory\"\n");
errlogPrintf(
" Adds or moves the directory to the front of the "
"ENVIRONMENT_VARIABLE\n");
errlogPrintf(" but after a leading \".\".\n");
return;
}
/* add directory to front */
old_path = getenv(varname);
if (old_path == NULL) {
putenvprintf("%s=." OSI_PATH_LIST_SEPARATOR "%s", varname, dirname);
} else {
size_t len = strnlen(dirname, PATH_MAX);
char *p = NULL;
/* skip over "." at the beginning */
if (old_path[0] == '.' && old_path[1] == OSI_PATH_LIST_SEPARATOR[0])
old_path += 2;
/* If directory is already in path, move it to front */
p = old_path;
while ((p = strstr(p, dirname)) != NULL) {
if ((p == old_path || *(p - 1) == OSI_PATH_LIST_SEPARATOR[0]) &&
(p[len] == 0 || p[len] == OSI_PATH_LIST_SEPARATOR[0])) {
if (p == old_path) break; /* already at front, nothing to do */
memmove(old_path + len + 1, old_path, p - old_path - 1);
strcpy(old_path, dirname);
old_path[len] = OSI_PATH_LIST_SEPARATOR[0];
debug("require: modified %s=%s\n", varname, old_path);
break;
}
p += len;
}
if (p == NULL) /* add new directory to the front (after "." )*/
putenvprintf("%s=." OSI_PATH_LIST_SEPARATOR "%s" OSI_PATH_LIST_SEPARATOR
"%s",
varname, dirname, old_path);
}
}
#ifndef __COMMON_H__
#define __COMMON_H__
#include <stdio.h>
extern int requireDebug;
#define debug(...) \
if (requireDebug) printf(__VA_ARGS__)
char *realpathSeparator(const char *location);
int putenvprintf(const char *format, ...);
void pathAdd(const char *varname, const char *dirname);
#endif /*__COMMON_H_*/