|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
/**
|
|
Packit Service |
96b5d3 |
* @file agUtils.c
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* Various utilities for AutoGen.
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* @addtogroup autogen
|
|
Packit Service |
96b5d3 |
* @{
|
|
Packit Service |
96b5d3 |
*/
|
|
Packit Service |
96b5d3 |
/*
|
|
Packit Service |
96b5d3 |
* This file is part of AutoGen.
|
|
Packit Service |
96b5d3 |
* Copyright (C) 1992-2016 Bruce Korb - all rights reserved
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* AutoGen is free software: you can redistribute it and/or modify it
|
|
Packit Service |
96b5d3 |
* under the terms of the GNU General Public License as published by the
|
|
Packit Service |
96b5d3 |
* Free Software Foundation, either version 3 of the License, or
|
|
Packit Service |
96b5d3 |
* (at your option) any later version.
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* AutoGen is distributed in the hope that it will be useful, but
|
|
Packit Service |
96b5d3 |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
96b5d3 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
Packit Service |
96b5d3 |
* See the GNU General Public License for more details.
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* You should have received a copy of the GNU General Public License along
|
|
Packit Service |
96b5d3 |
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
Packit Service |
96b5d3 |
*/
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
/* = = = START-STATIC-FORWARD = = = */
|
|
Packit Service |
96b5d3 |
static void
|
|
Packit Service |
96b5d3 |
define_base_name(void);
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
static void
|
|
Packit Service |
96b5d3 |
put_defines_into_env(void);
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
static void
|
|
Packit Service |
96b5d3 |
open_trace_file(char ** av, tOptDesc * odsc);
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
static void
|
|
Packit Service |
96b5d3 |
check_make_dep_env(void);
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
static char const *
|
|
Packit Service |
96b5d3 |
skip_quote(char const * qstr);
|
|
Packit Service |
96b5d3 |
/* = = = END-STATIC-FORWARD = = = */
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
/**
|
|
Packit Service |
96b5d3 |
* Print a file system error fatal error message and die.
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* @param[in] op the operation that failed.
|
|
Packit Service |
96b5d3 |
* @param[in] fname the file name the operation was on.
|
|
Packit Service |
96b5d3 |
* @noreturn
|
|
Packit Service |
96b5d3 |
*/
|
|
Packit Service |
96b5d3 |
LOCAL void
|
|
Packit Service |
96b5d3 |
fswarn(char const * op, char const * fname)
|
|
Packit Service |
96b5d3 |
{
|
|
Packit Service |
96b5d3 |
fprintf(stderr, FS_ERR_WARNING, errno, strerror(errno), op, fname);
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
/**
|
|
Packit Service |
96b5d3 |
* Allocating printf function. It either works or kills the program.
|
|
Packit Service |
96b5d3 |
* @param[in] pzFmt the input format
|
|
Packit Service |
96b5d3 |
* @returns the allocated, formatted result string.
|
|
Packit Service |
96b5d3 |
*/
|
|
Packit Service |
96b5d3 |
LOCAL char *
|
|
Packit Service |
96b5d3 |
aprf(char const * pzFmt, ...)
|
|
Packit Service |
96b5d3 |
{
|
|
Packit Service |
96b5d3 |
char * pz;
|
|
Packit Service |
96b5d3 |
va_list ap;
|
|
Packit Service |
96b5d3 |
va_start(ap, pzFmt);
|
|
Packit Service |
96b5d3 |
(void)vasprintf(&pz, pzFmt, ap);
|
|
Packit Service |
96b5d3 |
va_end(ap);
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
if (pz == NULL) {
|
|
Packit Service |
96b5d3 |
char z[ 2 * SCRIBBLE_SIZE ];
|
|
Packit Service |
96b5d3 |
snprintf(z, sizeof(z), APRF_ALLOCATE_FAIL, pzFmt);
|
|
Packit Service |
96b5d3 |
AG_ABEND(z);
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
return pz;
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
/**
|
|
Packit Service |
96b5d3 |
* Figure out what base name to use. --base-name was not specified.
|
|
Packit Service |
96b5d3 |
* Base it on the definitions file, if available.
|
|
Packit Service |
96b5d3 |
*/
|
|
Packit Service |
96b5d3 |
static void
|
|
Packit Service |
96b5d3 |
define_base_name(void)
|
|
Packit Service |
96b5d3 |
{
|
|
Packit Service |
96b5d3 |
char const * pz;
|
|
Packit Service |
96b5d3 |
char * pzD;
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
if (! ENABLED_OPT(DEFINITIONS)) {
|
|
Packit Service |
96b5d3 |
OPT_ARG(BASE_NAME) = DFT_BASE_NAME;
|
|
Packit Service |
96b5d3 |
return;
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
pz = strrchr(OPT_ARG(DEFINITIONS), '/');
|
|
Packit Service |
96b5d3 |
/*
|
|
Packit Service |
96b5d3 |
* Point to the character after the last '/', or to the full
|
|
Packit Service |
96b5d3 |
* definition file name, if there is no '/'.
|
|
Packit Service |
96b5d3 |
*/
|
|
Packit Service |
96b5d3 |
pz = (pz == NULL) ? OPT_ARG(DEFINITIONS) : (pz + 1);
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
/*
|
|
Packit Service |
96b5d3 |
* IF input is from stdin, then use "stdin"
|
|
Packit Service |
96b5d3 |
*/
|
|
Packit Service |
96b5d3 |
if ((pz[0] == '-') && (pz[1] == NUL)) {
|
|
Packit Service |
96b5d3 |
OPT_ARG(BASE_NAME) = STDIN_FILE_NAME;
|
|
Packit Service |
96b5d3 |
return;
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
/*
|
|
Packit Service |
96b5d3 |
* Otherwise, use the basename of the definitions file
|
|
Packit Service |
96b5d3 |
*/
|
|
Packit Service |
96b5d3 |
OPT_ARG(BASE_NAME) = \
|
|
Packit Service |
96b5d3 |
pzD = AGALOC(strlen(pz)+1, "derived base");
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
while ((*pz != NUL) && (*pz != '.')) *(pzD++) = *(pz++);
|
|
Packit Service |
96b5d3 |
*pzD = NUL;
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
/**
|
|
Packit Service |
96b5d3 |
* Put the -D option arguments into the environment.
|
|
Packit Service |
96b5d3 |
* This makes them accessible to Guile/Scheme code, too.
|
|
Packit Service |
96b5d3 |
*/
|
|
Packit Service |
96b5d3 |
static void
|
|
Packit Service |
96b5d3 |
put_defines_into_env(void)
|
|
Packit Service |
96b5d3 |
{
|
|
Packit Service |
96b5d3 |
int ct = STACKCT_OPT(DEFINE);
|
|
Packit Service |
96b5d3 |
char const ** ppz = STACKLST_OPT(DEFINE);
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
do {
|
|
Packit Service |
96b5d3 |
char const * pz = *(ppz++);
|
|
Packit Service |
96b5d3 |
/*
|
|
Packit Service |
96b5d3 |
* IF there is no associated value, THEN set it to '1'.
|
|
Packit Service |
96b5d3 |
* There are weird problems with empty defines.
|
|
Packit Service |
96b5d3 |
* FIXME: we loose track of this memory. Don't know what to do,
|
|
Packit Service |
96b5d3 |
* really, there is no good recovery mechanism for environment
|
|
Packit Service |
96b5d3 |
* data.
|
|
Packit Service |
96b5d3 |
*/
|
|
Packit Service |
96b5d3 |
if (strchr(pz, '=') == NULL) {
|
|
Packit Service |
96b5d3 |
size_t siz = strlen(pz)+3;
|
|
Packit Service |
96b5d3 |
char * p = AGALOC(siz, "env define");
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
strcpy(p, pz);
|
|
Packit Service |
96b5d3 |
strcpy(p+siz-3, DFT_ENV_VAL);
|
|
Packit Service |
96b5d3 |
pz = p;
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
/*
|
|
Packit Service |
96b5d3 |
* Now put it in the environment
|
|
Packit Service |
96b5d3 |
*/
|
|
Packit Service |
96b5d3 |
putenv((char *)pz);
|
|
Packit Service |
96b5d3 |
} while (--ct > 0);
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
/**
|
|
Packit Service |
96b5d3 |
* Open trace output file.
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* If the name starts with a pipe character (vertical bar), then
|
|
Packit Service |
96b5d3 |
* use popen on the command. If it starts with ">>", then append
|
|
Packit Service |
96b5d3 |
* to the file name that follows that.
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* The trace output starts with the command and arguments used to
|
|
Packit Service |
96b5d3 |
* start autogen.
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* @param[in] av autogen's argument vector
|
|
Packit Service |
96b5d3 |
* @param[in] odsc option descriptor with file name string argument
|
|
Packit Service |
96b5d3 |
*/
|
|
Packit Service |
96b5d3 |
static void
|
|
Packit Service |
96b5d3 |
open_trace_file(char ** av, tOptDesc * odsc)
|
|
Packit Service |
96b5d3 |
{
|
|
Packit Service |
96b5d3 |
char const * fname = odsc->optArg.argString;
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
trace_is_to_pipe = (*fname == '|');
|
|
Packit Service |
96b5d3 |
if (trace_is_to_pipe)
|
|
Packit Service |
96b5d3 |
trace_fp = popen(++fname, "w");
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
else if ((fname[0] == '>') && (fname[1] == '>')) {
|
|
Packit Service |
96b5d3 |
fname = SPN_WHITESPACE_CHARS(fname + 2);
|
|
Packit Service |
96b5d3 |
trace_fp = fopen(fname, "a");
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
else
|
|
Packit Service |
96b5d3 |
trace_fp = fopen(fname, "w");
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
if (trace_fp == NULL)
|
|
Packit Service |
96b5d3 |
fserr(AUTOGEN_EXIT_FS_ERROR, "fopen", fname);
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
#ifdef _IONBF
|
|
Packit Service |
96b5d3 |
setvbuf(trace_fp, NULL, _IONBF, 0);
|
|
Packit Service |
96b5d3 |
#endif
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
fprintf(trace_fp, TRACE_START_FMT, (unsigned int)getpid(), *av);
|
|
Packit Service |
96b5d3 |
while (*(++av) != NULL)
|
|
Packit Service |
96b5d3 |
fprintf(trace_fp, TRACE_AG_ARG_FMT, *av);
|
|
Packit Service |
96b5d3 |
fprintf(trace_fp, TRACE_START_GUILE, libguile_ver);
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
/**
|
|
Packit Service |
96b5d3 |
* Check the environment for make dependency info. We look for
|
|
Packit Service |
96b5d3 |
* AUTOGEN_MAKE_DEP, but if that is not found, we also look for
|
|
Packit Service |
96b5d3 |
* DEPENDENCIES_OUTPUT. To do dependency tracking at all, we
|
|
Packit Service |
96b5d3 |
* must find one of these environment variables and it must
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* * be non-empty
|
|
Packit Service |
96b5d3 |
* * not contain a variation on "no"
|
|
Packit Service |
96b5d3 |
* * not contain a variation on "false"
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* Furthermore, to specify a file name, the contents must not contain
|
|
Packit Service |
96b5d3 |
* some variation on "yes" or "true".
|
|
Packit Service |
96b5d3 |
*/
|
|
Packit Service |
96b5d3 |
static void
|
|
Packit Service |
96b5d3 |
check_make_dep_env(void)
|
|
Packit Service |
96b5d3 |
{
|
|
Packit Service |
96b5d3 |
bool have_opt_string = false;
|
|
Packit Service |
96b5d3 |
bool set_opt = false;
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
char const * mdep = getenv(AG_MAKE_DEP_NAME);
|
|
Packit Service |
96b5d3 |
if (mdep == NULL) {
|
|
Packit Service |
96b5d3 |
mdep = getenv(DEP_OUT_NAME);
|
|
Packit Service |
96b5d3 |
if (mdep == NULL)
|
|
Packit Service |
96b5d3 |
return;
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
switch (*mdep) {
|
|
Packit Service |
96b5d3 |
case NUL: break;
|
|
Packit Service |
96b5d3 |
case '1':
|
|
Packit Service |
96b5d3 |
set_opt = (mdep[0] == '1');
|
|
Packit Service |
96b5d3 |
/* FALLTHROUGH */
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
case '0':
|
|
Packit Service |
96b5d3 |
if (mdep[1] != NUL)
|
|
Packit Service |
96b5d3 |
have_opt_string = true;
|
|
Packit Service |
96b5d3 |
break;
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
case 'y':
|
|
Packit Service |
96b5d3 |
case 'Y':
|
|
Packit Service |
96b5d3 |
set_opt = true;
|
|
Packit Service |
96b5d3 |
have_opt_string = (streqvcmp(mdep + 1, YES_NAME_STR+1) != 0);
|
|
Packit Service |
96b5d3 |
break;
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
case 'n':
|
|
Packit Service |
96b5d3 |
case 'N':
|
|
Packit Service |
96b5d3 |
set_opt = \
|
|
Packit Service |
96b5d3 |
have_opt_string = (streqvcmp(mdep + 1, NO_NAME_STR+1) != 0);
|
|
Packit Service |
96b5d3 |
break;
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
case 't':
|
|
Packit Service |
96b5d3 |
case 'T':
|
|
Packit Service |
96b5d3 |
set_opt = true;
|
|
Packit Service |
96b5d3 |
have_opt_string = (streqvcmp(mdep + 1, TRUE_NAME_STR+1) != 0);
|
|
Packit Service |
96b5d3 |
break;
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
case 'f':
|
|
Packit Service |
96b5d3 |
case 'F':
|
|
Packit Service |
96b5d3 |
set_opt = \
|
|
Packit Service |
96b5d3 |
have_opt_string = (streqvcmp(mdep + 1, FALSE_NAME_STR+1) != 0);
|
|
Packit Service |
96b5d3 |
break;
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
default:
|
|
Packit Service |
96b5d3 |
have_opt_string = \
|
|
Packit Service |
96b5d3 |
set_opt = true;
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
if (! set_opt) return;
|
|
Packit Service |
96b5d3 |
if (! have_opt_string) {
|
|
Packit Service |
96b5d3 |
SET_OPT_MAKE_DEP("");
|
|
Packit Service |
96b5d3 |
return;
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
{
|
|
Packit Service |
96b5d3 |
char * pz = AGALOC(strlen(mdep) + 5, "mdep");
|
|
Packit Service |
96b5d3 |
char * fp = pz;
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
*(pz++) = 'F';
|
|
Packit Service |
96b5d3 |
for (;;) {
|
|
Packit Service |
96b5d3 |
int ch = *(unsigned char *)(mdep++);
|
|
Packit Service |
96b5d3 |
if (IS_END_TOKEN_CHAR(ch))
|
|
Packit Service |
96b5d3 |
break;
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
*(pz++) = (char)ch;
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
*pz = NUL;
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
SET_OPT_SAVE_OPTS(fp);
|
|
Packit Service |
96b5d3 |
mdep = SPN_WHITESPACE_CHARS(mdep);
|
|
Packit Service |
96b5d3 |
if (*mdep == NUL)
|
|
Packit Service |
96b5d3 |
return;
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
pz = fp;
|
|
Packit Service |
96b5d3 |
*(pz++) = 'T';
|
|
Packit Service |
96b5d3 |
for (;;) {
|
|
Packit Service |
96b5d3 |
int ch = *(unsigned char *)(mdep++);
|
|
Packit Service |
96b5d3 |
if (IS_END_TOKEN_CHAR(ch))
|
|
Packit Service |
96b5d3 |
break;
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
*(pz++) = (char)ch;
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
*pz = NUL;
|
|
Packit Service |
96b5d3 |
SET_OPT_SAVE_OPTS(fp);
|
|
Packit Service |
96b5d3 |
AGFREE(fp);
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
LOCAL void
|
|
Packit Service |
96b5d3 |
process_ag_opts(int arg_ct, char ** arg_vec)
|
|
Packit Service |
96b5d3 |
{
|
|
Packit Service |
96b5d3 |
/*
|
|
Packit Service |
96b5d3 |
* Advance the argument counters and pointers past any
|
|
Packit Service |
96b5d3 |
* command line options
|
|
Packit Service |
96b5d3 |
*/
|
|
Packit Service |
96b5d3 |
{
|
|
Packit Service |
96b5d3 |
int optCt = optionProcess(&autogenOptions, arg_ct, arg_vec);
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
/*
|
|
Packit Service |
96b5d3 |
* Make sure we have a source file, even if it is "-" (stdin)
|
|
Packit Service |
96b5d3 |
*/
|
|
Packit Service |
96b5d3 |
switch (arg_ct - optCt) {
|
|
Packit Service |
96b5d3 |
case 1:
|
|
Packit Service |
96b5d3 |
if (! HAVE_OPT(DEFINITIONS)) {
|
|
Packit Service |
96b5d3 |
OPT_ARG(DEFINITIONS) = *(arg_vec + optCt);
|
|
Packit Service |
96b5d3 |
break;
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
/* FALLTHROUGH */
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
default:
|
|
Packit Service |
96b5d3 |
usage_message(DOOPT_TOO_MANY_DEFS, ag_pname);
|
|
Packit Service |
96b5d3 |
/* NOTREACHED */
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
case 0:
|
|
Packit Service |
96b5d3 |
if (! HAVE_OPT(DEFINITIONS))
|
|
Packit Service |
96b5d3 |
OPT_ARG(DEFINITIONS) = DFT_DEF_INPUT_STR;
|
|
Packit Service |
96b5d3 |
break;
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
if ((OPT_VALUE_TRACE > TRACE_NOTHING) && HAVE_OPT(TRACE_OUT))
|
|
Packit Service |
96b5d3 |
open_trace_file(arg_vec, &DESC(TRACE_OUT));
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
start_time = time(NULL) - 1;
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
if (! HAVE_OPT(TIMEOUT))
|
|
Packit Service |
96b5d3 |
OPT_ARG(TIMEOUT) = (char const *)AG_DEFAULT_TIMEOUT;
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
/*
|
|
Packit Service |
96b5d3 |
* IF the definitions file has been disabled,
|
|
Packit Service |
96b5d3 |
* THEN a template *must* have been specified.
|
|
Packit Service |
96b5d3 |
*/
|
|
Packit Service |
96b5d3 |
if ( (! ENABLED_OPT(DEFINITIONS))
|
|
Packit Service |
96b5d3 |
&& (! HAVE_OPT(OVERRIDE_TPL)) )
|
|
Packit Service |
96b5d3 |
AG_ABEND(NO_TEMPLATE_ERR_MSG);
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
/*
|
|
Packit Service |
96b5d3 |
* IF we do not have a base-name option, then we compute some value
|
|
Packit Service |
96b5d3 |
*/
|
|
Packit Service |
96b5d3 |
if (! HAVE_OPT(BASE_NAME))
|
|
Packit Service |
96b5d3 |
define_base_name();
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
check_make_dep_env();
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
if (HAVE_OPT(MAKE_DEP))
|
|
Packit Service |
96b5d3 |
start_dep_file();
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
strequate(OPT_ARG(EQUATE));
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
/*
|
|
Packit Service |
96b5d3 |
* IF we have some defines to put in our environment, ...
|
|
Packit Service |
96b5d3 |
*/
|
|
Packit Service |
96b5d3 |
if (HAVE_OPT(DEFINE))
|
|
Packit Service |
96b5d3 |
put_defines_into_env();
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
/**
|
|
Packit Service |
96b5d3 |
* look for a define string. It may be in our DEFINE option list
|
|
Packit Service |
96b5d3 |
* (preferred result) or in the environment. Look up both.
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* @param[in] de_name name to look for
|
|
Packit Service |
96b5d3 |
* @param[in] check_env whether or not to look in environment
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* @returns a pointer to the string, if found, or NULL.
|
|
Packit Service |
96b5d3 |
*/
|
|
Packit Service |
96b5d3 |
LOCAL char const *
|
|
Packit Service |
96b5d3 |
get_define_str(char const * de_name, bool check_env)
|
|
Packit Service |
96b5d3 |
{
|
|
Packit Service |
96b5d3 |
char const ** ppz;
|
|
Packit Service |
96b5d3 |
int ct;
|
|
Packit Service |
96b5d3 |
if (HAVE_OPT(DEFINE)) {
|
|
Packit Service |
96b5d3 |
ct = STACKCT_OPT( DEFINE);
|
|
Packit Service |
96b5d3 |
ppz = STACKLST_OPT(DEFINE);
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
while (ct-- > 0) {
|
|
Packit Service |
96b5d3 |
char const * pz = *(ppz++);
|
|
Packit Service |
96b5d3 |
char * pzEq = strchr(pz, '=');
|
|
Packit Service |
96b5d3 |
int res;
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
if (pzEq != NULL)
|
|
Packit Service |
96b5d3 |
*pzEq = NUL;
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
res = strcmp(de_name, pz);
|
|
Packit Service |
96b5d3 |
if (pzEq != NULL)
|
|
Packit Service |
96b5d3 |
*pzEq = '=';
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
if (res == 0)
|
|
Packit Service |
96b5d3 |
return (pzEq != NULL) ? pzEq+1 : zNil;
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
return check_env ? getenv(de_name) : NULL;
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
/**
|
|
Packit Service |
96b5d3 |
* The following routine scans over quoted text, shifting it in the process
|
|
Packit Service |
96b5d3 |
* and eliminating the starting quote, ending quote and any embedded
|
|
Packit Service |
96b5d3 |
* backslashes. They may be used to embed the quote character in the quoted
|
|
Packit Service |
96b5d3 |
* text. The quote character is whatever character the argument is pointing
|
|
Packit Service |
96b5d3 |
* at when this procedure is called.
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* @param[in,out] in_q input quoted string/output unquoted
|
|
Packit Service |
96b5d3 |
* @returns the address of the byte after the original closing quote.
|
|
Packit Service |
96b5d3 |
*/
|
|
Packit Service |
96b5d3 |
LOCAL char *
|
|
Packit Service |
96b5d3 |
span_quote(char * in_q)
|
|
Packit Service |
96b5d3 |
{
|
|
Packit Service |
96b5d3 |
char qc = *in_q; /* Save the quote character type */
|
|
Packit Service |
96b5d3 |
char * dp = in_q++; /* Destination pointer */
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
while (*in_q != qc) {
|
|
Packit Service |
96b5d3 |
switch (*dp++ = *in_q++) {
|
|
Packit Service |
96b5d3 |
case NUL:
|
|
Packit Service |
96b5d3 |
return in_q-1; /* Return address of terminating NUL */
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
case '\\':
|
|
Packit Service |
96b5d3 |
if (qc != '\'') {
|
|
Packit Service |
96b5d3 |
int ct = (int)ao_string_cook_escape_char(in_q, dp-1, 0x7F);
|
|
Packit Service |
96b5d3 |
if (dp[-1] == 0x7F) dp--;
|
|
Packit Service |
96b5d3 |
in_q += ct;
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
} else
|
|
Packit Service |
96b5d3 |
switch (*in_q) {
|
|
Packit Service |
96b5d3 |
case '\\':
|
|
Packit Service |
96b5d3 |
case '\'':
|
|
Packit Service |
96b5d3 |
case '#':
|
|
Packit Service |
96b5d3 |
dp[-1] = *in_q++;
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
break;
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
default:
|
|
Packit Service |
96b5d3 |
;
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
*dp = NUL;
|
|
Packit Service |
96b5d3 |
return in_q+1; /* Return addr of char after the terminating quote */
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
/**
|
|
Packit Service |
96b5d3 |
* The following routine skips over quoted text. The quote character is
|
|
Packit Service |
96b5d3 |
* whatever character the argument is pointing at when this procedure is
|
|
Packit Service |
96b5d3 |
* called.
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* @param[in] qstr input quoted string/output unquoted
|
|
Packit Service |
96b5d3 |
* @returns the address of the byte after the original closing quote.
|
|
Packit Service |
96b5d3 |
*/
|
|
Packit Service |
96b5d3 |
static char const *
|
|
Packit Service |
96b5d3 |
skip_quote(char const * qstr)
|
|
Packit Service |
96b5d3 |
{
|
|
Packit Service |
96b5d3 |
char qc = *qstr++; /* Save the quote character type */
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
while (*qstr != qc) {
|
|
Packit Service |
96b5d3 |
switch (*qstr++) {
|
|
Packit Service |
96b5d3 |
case NUL:
|
|
Packit Service |
96b5d3 |
return qstr-1; /* Return address of terminating NUL */
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
case '\\':
|
|
Packit Service |
96b5d3 |
if (qc == '\'') {
|
|
Packit Service |
96b5d3 |
/*
|
|
Packit Service |
96b5d3 |
* Single quoted strings process the backquote specially
|
|
Packit Service |
96b5d3 |
* only in front of these three characters:
|
|
Packit Service |
96b5d3 |
*/
|
|
Packit Service |
96b5d3 |
switch (*qstr) {
|
|
Packit Service |
96b5d3 |
case '\\':
|
|
Packit Service |
96b5d3 |
case '\'':
|
|
Packit Service |
96b5d3 |
case '#':
|
|
Packit Service |
96b5d3 |
qstr++;
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
} else {
|
|
Packit Service |
96b5d3 |
char p[10]; /* provide a scratch pad for escape processing */
|
|
Packit Service |
96b5d3 |
qstr += ao_string_cook_escape_char(qstr, p, 0x7F);
|
|
Packit Service |
96b5d3 |
} /* if (q == '\'') */
|
|
Packit Service |
96b5d3 |
} /* switch (*qstr++) */
|
|
Packit Service |
96b5d3 |
} /* while (*qstr != q) */
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
return qstr+1; /* Return addr of char after the terminating quote */
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
/**
|
|
Packit Service |
96b5d3 |
* Skip over scheme expression. We need to find what follows it.
|
|
Packit Service |
96b5d3 |
* Guile will carefully parse it later.
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* @param[in] scan where to start search
|
|
Packit Service |
96b5d3 |
* @param[in] end point beyond which not to go
|
|
Packit Service |
96b5d3 |
* @returns character after closing parenthesis or "end",
|
|
Packit Service |
96b5d3 |
* which ever comes first.
|
|
Packit Service |
96b5d3 |
*/
|
|
Packit Service |
96b5d3 |
LOCAL char const *
|
|
Packit Service |
96b5d3 |
skip_scheme(char const * scan, char const * end)
|
|
Packit Service |
96b5d3 |
{
|
|
Packit Service |
96b5d3 |
int level = 0;
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
for (;;) {
|
|
Packit Service |
96b5d3 |
scan = BRK_SCHEME_NOTE_CHARS(scan);
|
|
Packit Service |
96b5d3 |
if (scan >= end)
|
|
Packit Service |
96b5d3 |
return end;
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
switch (*(scan++)) {
|
|
Packit Service |
96b5d3 |
case '(':
|
|
Packit Service |
96b5d3 |
level++;
|
|
Packit Service |
96b5d3 |
break;
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
case ')':
|
|
Packit Service |
96b5d3 |
if (--level == 0)
|
|
Packit Service |
96b5d3 |
return scan;
|
|
Packit Service |
96b5d3 |
break;
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
case '"':
|
|
Packit Service |
96b5d3 |
scan = skip_quote(scan-1);
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
/**
|
|
Packit Service |
96b5d3 |
* scan past an expression. An expression is either a Scheme
|
|
Packit Service |
96b5d3 |
* expression starting and ending with balanced parentheses,
|
|
Packit Service |
96b5d3 |
* or a quoted string or a sequence of non-whitespace characters.
|
|
Packit Service |
96b5d3 |
* semicolons denote a comment that extends to the next newline.
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* @param [in] src input text
|
|
Packit Service |
96b5d3 |
* @param [in] len the maximum length to scan over
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* @returns a pointer to the character next after the expression end.
|
|
Packit Service |
96b5d3 |
*/
|
|
Packit Service |
96b5d3 |
LOCAL char const *
|
|
Packit Service |
96b5d3 |
skip_expr(char const * src, size_t len)
|
|
Packit Service |
96b5d3 |
{
|
|
Packit Service |
96b5d3 |
char const * end = src + len;
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
guess_again:
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
src = SPN_WHITESPACE_CHARS(src);
|
|
Packit Service |
96b5d3 |
if (src >= end)
|
|
Packit Service |
96b5d3 |
return end;
|
|
Packit Service |
96b5d3 |
switch (*src) {
|
|
Packit Service |
96b5d3 |
case ';':
|
|
Packit Service |
96b5d3 |
src = strchr(src, NL);
|
|
Packit Service |
96b5d3 |
if (src == NULL)
|
|
Packit Service |
96b5d3 |
return end;
|
|
Packit Service |
96b5d3 |
goto guess_again;
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
case '(':
|
|
Packit Service |
96b5d3 |
return skip_scheme(src, end);
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
case '"':
|
|
Packit Service |
96b5d3 |
case '\'':
|
|
Packit Service |
96b5d3 |
case '`':
|
|
Packit Service |
96b5d3 |
src = skip_quote(src);
|
|
Packit Service |
96b5d3 |
return (src > end) ? end : src;
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
default:
|
|
Packit Service |
96b5d3 |
break;
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
|
|
Packit Service |
96b5d3 |
src = BRK_WHITESPACE_CHARS(src);
|
|
Packit Service |
96b5d3 |
return (src > end) ? end : src;
|
|
Packit Service |
96b5d3 |
}
|
|
Packit Service |
96b5d3 |
/**
|
|
Packit Service |
96b5d3 |
* @}
|
|
Packit Service |
96b5d3 |
*
|
|
Packit Service |
96b5d3 |
* Local Variables:
|
|
Packit Service |
96b5d3 |
* mode: C
|
|
Packit Service |
96b5d3 |
* c-file-style: "stroustrup"
|
|
Packit Service |
96b5d3 |
* indent-tabs-mode: nil
|
|
Packit Service |
96b5d3 |
* End:
|
|
Packit Service |
96b5d3 |
* end of agen5/agUtils.c */
|