69 const char *term,
const char **
rawval,
char **
value,
74 static void cpy2val(
const char *src,
char **
value,
char *valend );
75 static char *Strdup(
const char *
string );
83 #define MAC_MAGIC 0xbadcafe 88 #define FLAG_SUPPRESS_WARNINGS 0x1 89 #define FLAG_USE_ENVIRONMENT 0x80 104 const char * pairs[] )
116 if ( handle ==
NULL ) {
117 errlogPrintf(
"macCreateHandle: failed to allocate context\n" );
130 if (pairs && pairs[0] && !strcmp(pairs[0],
"") && pairs[1] && !strcmp(pairs[1],
"environ") && !pairs[3]) {
135 for ( ; pairs && pairs[0]; pairs += 2 ) {
136 if (
macPutValue( handle, pairs[0], pairs[1] ) < 0 ) {
190 errlogPrintf(
"macExpandString: NULL or invalid handle\n" );
195 if ( handle->
debug & 1 )
196 printf(
"macExpandString( %s, capacity = %ld )\n", src, capacity );
203 if ( expand( handle ) < 0 )
204 errlogPrintf(
"macExpandString: failed to expand raw values\n" );
207 entry.
name = (
char *) src;
208 entry.
type =
"string";
215 trans( handle, &entry, 0,
"", &s, &d, d + capacity - 1 );
219 length = ( entry.
error ) ? -length : length;
222 if ( handle->
debug & 1 )
223 printf(
"macExpandString() -> %ld\n", length );
244 errlogPrintf(
"macPutValue: NULL or invalid handle\n" );
248 if ( handle->
debug & 1 )
249 printf(
"macPutValue( %s, %s )\n", name, value ? value :
"NULL" );
253 if ( value ==
NULL ) {
259 while ( ( entry = lookup( handle, name,
FALSE ) ) !=
NULL ) {
260 int done = strcmp(entry->
type,
"environment variable") == 0;
261 delete( handle, entry );
271 entry = lookup( handle, name,
FALSE );
276 entry = create( handle, name,
FALSE );
277 if ( entry ==
NULL ) {
278 errlogPrintf(
"macPutValue: failed to create macro %s = %s\n",
282 entry->
type =
"macro";
287 if (
rawval( handle, entry, value ) ==
NULL ) {
288 errlogPrintf(
"macPutValue: failed to copy macro %s = %s\n",
294 return strlen( value );
316 errlogPrintf(
"macGetValue: NULL or invalid handle\n" );
321 if ( handle->
debug & 1 )
322 printf(
"macGetValue( %s )\n", name );
325 entry = lookup( handle, name,
FALSE );
329 if ( capacity <= 1 || value ==
NULL ) {
330 return ( entry ==
NULL ) ? -1 : 0;
334 if ( entry ==
NULL ) {
335 strncpy( value, name, capacity );
336 return ( value[capacity-1] ==
'\0' ) ? - (long) strlen( name ) : -capacity;
341 if ( expand( handle ) < 0 ) {
342 errlogPrintf(
"macGetValue: failed to expand raw values\n" );
343 strncpy( value, name, capacity );
344 return ( value[capacity-1] ==
'\0' ) ? - (long) strlen( name ) : -capacity;
349 strncpy( value, entry->
value, capacity );
350 length = ( value[capacity-1] ==
'\0' ) ? entry->
length : capacity;
367 errlogPrintf(
"macDeleteHandle: NULL or invalid handle\n" );
372 if ( handle->
debug & 1 )
373 printf(
"macDeleteHandle()\n" );
376 for ( entry = first( handle ); entry !=
NULL; entry = nextEntry ) {
377 nextEntry = next( entry );
378 delete( handle, entry );
399 errlogPrintf(
"macPushScope: NULL or invalid handle\n" );
404 if ( handle->
debug & 1 )
405 printf(
"macPushScope()\n" );
411 entry = create( handle,
"<scope>",
TRUE );
412 if ( entry ==
NULL ) {
417 entry->
type =
"scope marker";
434 errlogPrintf(
"macPopScope: NULL or invalid handle\n" );
439 if ( handle->
debug & 1 )
440 printf(
"macPopScope()\n" );
443 if ( handle->
level == 0 ) {
449 entry = lookup( handle,
"<scope>",
TRUE );
450 if ( entry ==
NULL ) {
456 for ( ; entry !=
NULL; entry = nextEntry ) {
457 nextEntry = next( entry );
458 delete( handle, entry );
474 const char *format =
"%-1s %-16s %-16s %s\n";
479 errlogPrintf(
"macReportMacros: NULL or invalid handle\n" );
484 if ( expand( handle ) < 0 )
485 errlogPrintf(
"macGetValue: failed to expand raw values\n" );
488 printf( format,
"e",
"name",
"rawval",
"value" );
489 printf( format,
"-",
"----",
"------",
"-----" );
490 for ( entry = first( handle ); entry !=
NULL; entry = next( entry ) ) {
495 printf( format,
"s",
"----",
"------",
"-----" );
547 if ( entry !=
NULL ) {
577 if ( handle->
debug & 2 )
578 printf(
"lookup-> level = %d, name = %s, special = %d\n",
582 for ( entry = last( handle ); entry !=
NULL; entry = previous( entry ) ) {
583 if ( entry->
special != special )
585 if ( strcmp(
name, entry->
name ) == 0 )
588 if ( (special ==
FALSE) && (entry ==
NULL) &&
594 entry->
type =
"environment variable";
601 if ( handle->
debug & 2 )
602 printf(
"<-lookup level = %d, name = %s, result = %p\n",
615 entry->
rawval = Strdup( value );
636 free( entry->
value );
651 if ( !handle->
dirty )
654 for ( entry = first( handle ); entry !=
NULL; entry = next( entry ) ) {
656 if ( handle->
debug & 2 )
669 value = entry->
value;
672 trans( handle, entry, 1,
"", &rawval, &value, entry->
value +
MAC_SIZE );
688 const char *term,
const char **
rawval,
char **
value,
702 discard = (
level > 0 );
705 if ( handle->
debug & 2 )
706 printf(
"trans-> entry = %p, level = %d, capacity = %u, discard = %s, " 707 "rawval = %s\n", entry,
level, (
unsigned int)(valend - *
value), discard ?
"T" :
"F", *
rawval );
719 if ( discard )
continue;
722 else if ( *r ==
'"' || *r ==
'\'' ) {
724 if ( discard )
continue;
728 macRef = ( *r ==
'$' &&
729 *( r + 1 ) !=
'\0' &&
730 strchr(
"({", *( r + 1 ) ) !=
NULL );
733 if ( macRef && quote !=
'\'' ) {
735 refer ( handle, entry,
level, &r, &v, valend );
740 if ( *r ==
'\\' && *( r + 1 ) !=
'\0' ) {
741 if ( v < valend && !discard ) *v++ =
'\\';
742 if ( v < valend ) *v++ = *++r;
747 if ( v < valend ) *v++ = *r;
751 if ( v <= valend ) *v =
'\0';
756 if ( handle->
debug & 2 )
757 printf(
"<-trans level = %d, length = %4u, value = %s\n",
763 *
rawval = ( *r ==
'\0' ) ? r - 1 : r;
779 char refname[
MAC_SIZE + 1] = {
'\0'};
782 const char *defval =
NULL;
784 const char *errval =
NULL;
788 if ( handle->
debug & 2 )
789 printf(
"refer-> entry = %p, level = %d, capacity = %u, rawval = %s\n",
794 macEnd = ( *r ==
'(' ) ?
"=,)" :
"=,}";
799 trans( handle, entry,
level + 1, macEnd, &r, &rn, rn +
MAC_SIZE );
805 int flags = handle->
flags;
813 dflt.
type =
"default value";
815 trans( handle, &dflt,
level + 1, macEnd+1, &r, &v, v);
817 handle->
flags = flags;
823 int flags = handle->
flags;
826 subs.
type =
"scoped macro";
832 while ( *r ==
',' ) {
833 char subname[
MAC_SIZE + 1] = {
'\0'};
842 trans( handle, &subs,
level + 1, macEnd, &r, &sn, sn +
MAC_SIZE );
850 trans( handle, &subs,
level + 1, macEnd+1, &r, &sv,
859 handle->
flags = flags;
863 refentry = lookup( handle, refname,
FALSE );
868 if ( !handle->
dirty ) {
870 cpy2val( refentry->
value, &v, valend );
874 const char *rv = refentry->
rawval;
876 trans( handle, entry,
level + 1,
"", &rv, &v, valend );
883 errval =
",recursive)";
885 errlogPrintf(
"macLib: %s %s is recursive (expanding %s %s)\n",
893 trans( handle, entry,
level + 1, macEnd+1, &defval, &v, valend );
897 errval =
",undefined)";
899 errlogPrintf(
"macLib: macro %s is undefined (expanding %s %s)\n",
900 refname, entry->
type, entry->
name );
905 if ( v < valend ) *v++ =
'$';
906 if ( v < valend ) *v++ =
'(';
907 cpy2val( refname, &v, valend );
909 if ( v < valend ) *v++ =
')';
913 cpy2val( errval, &v, valend );
921 if ( handle->
debug & 2 )
922 printf(
"<-refer level = %d, length = %4u, value = %s\n",
934 static void cpy2val(
const char *src,
char **
value,
char *valend)
937 while ((v < valend) && (*v = *src++)) { v++; }
945 static char *Strdup(
const char *
string )
950 strcpy( copy,
string );
long magic
magic number (used for authentication)
long epicsStdCall macGetValue(MAC_HANDLE *handle, const char *name, char *value, long capacity)
Returns the value of a macro.
#define FLAG_SUPPRESS_WARNINGS
Miscellaneous macro definitions.
A library to manage storage that is allocated and quickly freed.
#define ellPrevious(PNODE)
Find the previous node in list.
void copy(PVValueArray< T > &pvFrom, size_t fromOffset, size_t fromStride, PVValueArray< T > &pvTo, size_t toOffset, size_t toStride, size_t count)
Copy a subarray from one scalar array to another.
long epicsStdCall macExpandString(MAC_HANDLE *handle, const char *src, char *dest, long capacity)
Expand a string which may contain macro references.
void ellAdd(ELLLIST *pList, ELLNODE *pNode)
Adds a node to the end of a list.
#define ellNext(PNODE)
Find the next node in list.
int flags
operating mode flags
Macro substitution context, for use by macLib routines only.
struct mac_entry MAC_ENTRY
void epicsStdCall macSuppressWarning(MAC_HANDLE *handle, int suppress)
Disable or enable warning messages.
void dbmfFree(void *mem)
Free the memory allocated by dbmfMalloc.
int dirty
values need expanding from raw values?
#define ellLast(PLIST)
Find the last node in list.
int errlogPrintf(const char *pFormat,...)
long epicsStdCall macReportMacros(MAC_HANDLE *handle)
Reports details of current definitions.
long epicsStdCall macDeleteHandle(MAC_HANDLE *handle)
Marks a handle invalid, and frees all storage associated with it.
long epicsStdCall macPopScope(MAC_HANDLE *handle)
Retrieve the last pushed scope (like stack operations)
ELLLIST list
macro name / value list
long epicsStdCall macCreateHandle(MAC_HANDLE **pHandle, const char *pairs[])
Creates a new macro substitution context.
#define ellInit(PLIST)
Initialize a list type.
#define MAC_SIZE
Maximum size of a macro name or value.
Text macro substitution routines.
long epicsStdCall macPutValue(MAC_HANDLE *handle, const char *name, const char *value)
Sets the value of a specific macro.
void ellDelete(ELLLIST *pList, ELLNODE *pNode)
Deletes a node from a list.
void * dbmfMalloc(size_t size)
Allocate memory.
#define FLAG_USE_ENVIRONMENT
long epicsStdCall macPushScope(MAC_HANDLE *handle)
Marks the start of a new scoping level.
#define ellFirst(PLIST)
Find the first node in list.