This is Unofficial EPICS BASE Doxygen Site
macLib.h File Reference

Text macro substitution routines. More...

#include "ellLib.h"
#include "libComAPI.h"
+ Include dependency graph for macLib.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  MAC_HANDLE
 Macro substitution context, for use by macLib routines only. More...
 

Macros

#define MAC_SIZE   256
 Maximum size of a macro name or value. More...
 

Functions

Core Library

The core library provides a minimal set of basic operations.

LIBCOM_API long epicsStdCall macCreateHandle (MAC_HANDLE **handle, const char *pairs[])
 Creates a new macro substitution context. More...
 
LIBCOM_API void epicsStdCall macSuppressWarning (MAC_HANDLE *handle, int falseTrue)
 Disable or enable warning messages. More...
 
LIBCOM_API long epicsStdCall macExpandString (MAC_HANDLE *handle, const char *src, char *dest, long capacity)
 Expand a string which may contain macro references. More...
 
LIBCOM_API long epicsStdCall macPutValue (MAC_HANDLE *handle, const char *name, const char *value)
 Sets the value of a specific macro. More...
 
LIBCOM_API long epicsStdCall macGetValue (MAC_HANDLE *handle, const char *name, char *value, long capacity)
 Returns the value of a macro. More...
 
LIBCOM_API long epicsStdCall macDeleteHandle (MAC_HANDLE *handle)
 Marks a handle invalid, and frees all storage associated with it. More...
 
LIBCOM_API long epicsStdCall macPushScope (MAC_HANDLE *handle)
 Marks the start of a new scoping level. More...
 
LIBCOM_API long epicsStdCall macPopScope (MAC_HANDLE *handle)
 Retrieve the last pushed scope (like stack operations) More...
 
LIBCOM_API long epicsStdCall macReportMacros (MAC_HANDLE *handle)
 Reports details of current definitions. More...
 
Utility Library

These convenience functions are intended for applications to use and provide a more convenient interface for some purposes.

LIBCOM_API long epicsStdCall macParseDefns (MAC_HANDLE *handle, const char *defns, char **pairs[])
 Parse macro definitions into an array of {name, value} pairs. More...
 
LIBCOM_API long epicsStdCall macInstallMacros (MAC_HANDLE *handle, char *pairs[])
 Install set of {name, value} pairs as definitions. More...
 
LIBCOM_API char *epicsStdCall macEnvExpand (const char *str)
 Expand environment variables in a string. More...
 
LIBCOM_API char *epicsStdCall macDefExpand (const char *str, MAC_HANDLE *macros)
 Expands macros and environment variables in a string. More...
 

Detailed Description

Text macro substitution routines.

Author
William Lupton, W. M. Keck Observatory

This general purpose macro substitution library is used for all macro substitutions in EPICS Base.

Most routines return 0 (OK) on success, -1 (ERROR) on failure, or small positive values for extra info. The macGetValue() and macExpandString() routines depart from this and return information both on success / failure and on value length. Errors and warnings are reported using errlogPrintf().

Definition in file macLib.h.

Macro Definition Documentation

#define MAC_SIZE   256

Maximum size of a macro name or value.

Definition at line 36 of file macLib.h.

Function Documentation

LIBCOM_API long epicsStdCall macCreateHandle ( MAC_HANDLE **  handle,
const char *  pairs[] 
)

Creates a new macro substitution context.

Returns
0 = OK; <0 = ERROR
Parameters
handlepointer to variable to receive pointer to new macro substitution context
pairspointer to NULL-terminated array of {name,value} pair strings. A NULL value implies undefined; a NULL pairs argument implies no macros.

Definition at line 100 of file macCore.c.

108 {
109  MAC_HANDLE *handle; /* pointer to macro substitution context */
110 
111  /* ensure NULL handle pointer is returned on error */
112  *pHandle = NULL;
113 
114  /* allocate macro substitution context */
115  handle = ( MAC_HANDLE * ) dbmfMalloc( sizeof( MAC_HANDLE ) );
116  if ( handle == NULL ) {
117  errlogPrintf( "macCreateHandle: failed to allocate context\n" );
118  return -1;
119  }
120 
121  /* initialize context */
122  handle->magic = MAC_MAGIC;
123  handle->dirty = FALSE;
124  handle->level = 0;
125  handle->debug = 0;
126  handle->flags = 0;
127  ellInit( &handle->list );
128 
129  /* use environment variables if so specified */
130  if (pairs && pairs[0] && !strcmp(pairs[0],"") && pairs[1] && !strcmp(pairs[1],"environ") && !pairs[3]) {
131  handle->flags |= FLAG_USE_ENVIRONMENT;
132  }
133  else {
134  /* if supplied, load macro definitions */
135  for ( ; pairs && pairs[0]; pairs += 2 ) {
136  if ( macPutValue( handle, pairs[0], pairs[1] ) < 0 ) {
137  dbmfFree( handle );
138  return -1;
139  }
140  }
141  }
142 
143  /* set returned handle pointer */
144  *pHandle = handle;
145 
146  return 0;
147 }
long magic
magic number (used for authentication)
Definition: macLib.h:43
#define FALSE
Definition: dbDefs.h:32
#define NULL
Definition: catime.c:38
int flags
operating mode flags
Definition: macLib.h:48
Macro substitution context, for use by macLib routines only.
Definition: macLib.h:42
void dbmfFree(void *mem)
Free the memory allocated by dbmfMalloc.
Definition: dbmf.c:175
int dirty
values need expanding from raw values?
Definition: macLib.h:44
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
#define MAC_MAGIC
Definition: macCore.c:83
ELLLIST list
macro name / value list
Definition: macLib.h:47
int debug
debugging level
Definition: macLib.h:46
#define ellInit(PLIST)
Initialize a list type.
Definition: ellLib.h:76
int level
scoping level
Definition: macLib.h:45
long epicsStdCall macPutValue(MAC_HANDLE *handle, const char *name, const char *value)
Sets the value of a specific macro.
Definition: macCore.c:233
void * dbmfMalloc(size_t size)
Allocate memory.
Definition: dbmf.c:97
#define FLAG_USE_ENVIRONMENT
Definition: macCore.c:89
LIBCOM_API char* epicsStdCall macDefExpand ( const char *  str,
MAC_HANDLE macros 
)

Expands macros and environment variables in a string.

Returns
Expanded string; NULL if any undefined macros were used.

This routine is similar to macEnvExpand() but allows an optional handle to be passed in that may contain additional macro definitions. These macros are appended to the set of macros from environment variables when expanding the string.

Parameters
strstring to be expanded
macrosopaque handle; may be NULL if only environment variables are to be used

Definition at line 26 of file macEnv.c.

27 {
28  MAC_HANDLE *handle;
29  static const char * pairs[] = { "", "environ", NULL, NULL };
30  long destCapacity = 128;
31  char *dest = NULL;
32  int n;
33 
34  if (macros) {
35  handle = macros;
36  } else {
37  if (macCreateHandle(&handle, pairs)){
38  errlogMessage("macDefExpand: macCreateHandle failed.");
39  return NULL;
40  }
41  }
42 
43  do {
44  destCapacity *= 2;
45  /*
46  * Use free/malloc rather than realloc since there's no need to
47  * keep the original contents.
48  */
49  free(dest);
50  dest = malloc(destCapacity);
51  if(!dest)
52  goto done;
53 
54  n = macExpandString(handle, str, dest, destCapacity);
55  } while (n >= (destCapacity - 1));
56 
57  if (n < 0) {
58  free(dest);
59  dest = NULL;
60  } else {
61  size_t unused = destCapacity - ++n;
62 
63  if (unused >= 20)
64  dest = realloc(dest, n);
65  }
66 
67 done:
68  if (macros == NULL) {
69  if (macDeleteHandle(handle)) {
70  errlogMessage("macDefExpand: macDeleteHandle failed.");
71  }
72  }
73  return dest;
74 }
#define NULL
Definition: catime.c:38
#define str(v)
long epicsStdCall macExpandString(MAC_HANDLE *handle, const char *src, char *dest, long capacity)
Expand a string which may contain macro references.
Definition: macCore.c:174
Macro substitution context, for use by macLib routines only.
Definition: macLib.h:42
int errlogMessage(const char *message)
Definition: errlog.c:180
long epicsStdCall macDeleteHandle(MAC_HANDLE *handle)
Marks a handle invalid, and frees all storage associated with it.
Definition: macCore.c:360
long epicsStdCall macCreateHandle(MAC_HANDLE **pHandle, const char *pairs[])
Creates a new macro substitution context.
Definition: macCore.c:100
void done(int k)
Definition: antelope.c:77
LIBCOM_API long epicsStdCall macDeleteHandle ( MAC_HANDLE handle)

Marks a handle invalid, and frees all storage associated with it.

Returns
0 = OK; <0 = ERROR
Note
Note that this does not free any strings into which macro values have been returned. Macro values are always returned into strings which were pre-allocated by the caller.
Parameters
handleopaque handle

Definition at line 360 of file macCore.c.

362 {
363  MAC_ENTRY *entry, *nextEntry;
364 
365  /* check handle */
366  if ( handle == NULL || handle->magic != MAC_MAGIC ) {
367  errlogPrintf( "macDeleteHandle: NULL or invalid handle\n" );
368  return -1;
369  }
370 
371  /* debug output */
372  if ( handle->debug & 1 )
373  printf( "macDeleteHandle()\n" );
374 
375  /* delete all entries */
376  for ( entry = first( handle ); entry != NULL; entry = nextEntry ) {
377  nextEntry = next( entry );
378  delete( handle, entry );
379  }
380 
381  /* clear magic field and free context structure */
382  handle->magic = 0;
383  dbmfFree( handle );
384 
385  return 0;
386 }
long magic
magic number (used for authentication)
Definition: macLib.h:43
#define printf
Definition: epicsStdio.h:41
#define NULL
Definition: catime.c:38
void dbmfFree(void *mem)
Free the memory allocated by dbmfMalloc.
Definition: dbmf.c:175
Definition: macCore.c:39
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
#define MAC_MAGIC
Definition: macCore.c:83
int debug
debugging level
Definition: macLib.h:46
LIBCOM_API char* epicsStdCall macEnvExpand ( const char *  str)

Expand environment variables in a string.

Returns
Expanded string; NULL if any undefined macros were used.

This routine expands a string which may contain macros that are environment variables. It parses the string looking for such references and passes them to macGetValue() for translation. It uses malloc() to allocate space for the expanded string and returns a pointer to this null-terminated string. It returns NULL if the source string contains any undefined references.

Parameters
strstring to be expanded

Definition at line 20 of file macEnv.c.

21 {
22  return macDefExpand(str, NULL);
23 }
#define NULL
Definition: catime.c:38
#define str(v)
char *epicsStdCall macDefExpand(const char *str, MAC_HANDLE *macros)
Expands macros and environment variables in a string.
Definition: macEnv.c:26
LIBCOM_API long epicsStdCall macExpandString ( MAC_HANDLE handle,
const char *  src,
char *  dest,
long  capacity 
)

Expand a string which may contain macro references.

Returns
Returns the length of the expanded string, <0 if any macro are undefined

This routine parses the src string looking for macro references and passes any it finds to macGetValue() for translation.

Note
The return value is similar to that of macGetValue(). Its absolute value is the number of characters copied to dest. If the return value is negative, at least one undefined macro was left unexpanded.
Parameters
handleopaque handle
srcsource string
destdestination string
capacitycapacity of destination buffer (dest)

Definition at line 174 of file macCore.c.

182 {
184  const char *s;
185  char *d;
186  long length;
187 
188  /* check handle */
189  if ( handle == NULL || handle->magic != MAC_MAGIC ) {
190  errlogPrintf( "macExpandString: NULL or invalid handle\n" );
191  return -1;
192  }
193 
194  /* debug output */
195  if ( handle->debug & 1 )
196  printf( "macExpandString( %s, capacity = %ld )\n", src, capacity );
197 
198  /* Check size */
199  if (capacity <= 1)
200  return -1;
201 
202  /* expand raw values if necessary */
203  if ( expand( handle ) < 0 )
204  errlogPrintf( "macExpandString: failed to expand raw values\n" );
205 
206  /* fill in necessary fields in fake macro entry structure */
207  entry.name = (char *) src;
208  entry.type = "string";
209  entry.error = FALSE;
210 
211  /* expand the string */
212  s = src;
213  d = dest;
214  *d = '\0';
215  trans( handle, &entry, 0, "", &s, &d, d + capacity - 1 );
216 
217  /* return +/- #chars copied depending on successful expansion */
218  length = d - dest;
219  length = ( entry.error ) ? -length : length;
220 
221  /* debug output */
222  if ( handle->debug & 1 )
223  printf( "macExpandString() -> %ld\n", length );
224 
225  return length;
226 }
long magic
magic number (used for authentication)
Definition: macLib.h:43
#define FALSE
Definition: dbDefs.h:32
char * type
Definition: macCore.c:42
#define printf
Definition: epicsStdio.h:41
#define NULL
Definition: catime.c:38
char * name
Definition: macCore.c:41
Definition: macCore.c:39
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
int error
Definition: macCore.c:46
#define MAC_MAGIC
Definition: macCore.c:83
int debug
debugging level
Definition: macLib.h:46
LIBCOM_API long epicsStdCall macGetValue ( MAC_HANDLE handle,
const char *  name,
char *  value,
long  capacity 
)

Returns the value of a macro.

Returns
Returns the length of the value string, <0 if undefined

value will be zero-terminated if the length of the value is less than capacity. The return value is the number of characters copied to value (see below for behavior if the macro is undefined). If capacity is zero, no characters will be copied to value (which may be NULL) and the call can be used to check whether the macro is defined.

Note
Truncation of the value is not reported, applications should assume that truncation has occurred if the return value is equal to capacity.

If the macro is undefined, the macro reference will be returned in the value string (if permitted by maxlen) and the function value will be minus the number of characters copied. Note that treatment of capacity is intended to be consistent with the strncpy() routine.

If the value contains macro references, these references will be expanded recursively. This expansion will detect a direct or indirect self reference.

Macro references begin with a "$" immediately followed by either a "(" or a "{" character. The macro name comes next, and may optionally be succeeded by an "=" and a default value, which will be returned if the named macro is undefined at the moment of expansion. A reference is terminated by the matching ")" or "}" character.

Parameters
handleopaque handle
namemacro name or reference
valuestring to receive macro value or name argument if macro is undefined
capacitycapacity of destination buffer (value)

Definition at line 301 of file macCore.c.

310 {
311  MAC_ENTRY *entry; /* pointer to this macro's entry structure */
312  long length; /* number of characters returned */
313 
314  /* check handle */
315  if ( handle == NULL || handle->magic != MAC_MAGIC ) {
316  errlogPrintf( "macGetValue: NULL or invalid handle\n" );
317  return -1;
318  }
319 
320  /* debug output */
321  if ( handle->debug & 1 )
322  printf( "macGetValue( %s )\n", name );
323 
324  /* look up macro name */
325  entry = lookup( handle, name, FALSE );
326 
327  /* if capacity <= 1 or VALUE == NULL just return -1 / 0 for undefined /
328  defined macro */
329  if ( capacity <= 1 || value == NULL ) {
330  return ( entry == NULL ) ? -1 : 0;
331  }
332 
333  /* if not found, copy name to value and return minus #chars copied */
334  if ( entry == NULL ) {
335  strncpy( value, name, capacity );
336  return ( value[capacity-1] == '\0' ) ? - (long) strlen( name ) : -capacity;
337  }
338 
339  /* expand raw values if necessary; if fail (can only fail because of
340  memory allocation failure), return same as if not found */
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;
345  }
346 
347  /* copy value and return +/- #chars copied depending on successful
348  expansion */
349  strncpy( value, entry->value, capacity );
350  length = ( value[capacity-1] == '\0' ) ? entry->length : capacity;
351 
352  return ( entry->error ) ? -length : length;
353 }
long magic
magic number (used for authentication)
Definition: macLib.h:43
Definition: link.h:174
#define FALSE
Definition: dbDefs.h:32
#define printf
Definition: epicsStdio.h:41
char * value
Definition: macCore.c:44
#define NULL
Definition: catime.c:38
Definition: macCore.c:39
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
int error
Definition: macCore.c:46
#define MAC_MAGIC
Definition: macCore.c:83
int debug
debugging level
Definition: macLib.h:46
size_t length
Definition: macCore.c:45
LIBCOM_API long epicsStdCall macInstallMacros ( MAC_HANDLE handle,
char *  pairs[] 
)

Install set of {name, value} pairs as definitions.

Returns
Number of macros defined; <0 = ERROR

This takes an array of pairs as defined above and installs them as definitions by calling macPutValue(). The pairs array is terminated by a NULL pointer.

Parameters
handleopaque handle
pairspointer to NULL-terminated array of {name,value} pair strings; a NULL value implies undefined; a NULL argument implies no macros

Definition at line 253 of file macUtil.c.

260 {
261  int n;
262  char **p;
263 
264  /* debug output */
265  if ( handle->debug & 1 )
266  printf( "macInstallMacros( %s, %s, ... )\n",
267  pairs && pairs[0] ? pairs[0] : "NULL",
268  pairs && pairs[1] ? pairs[1] : "NULL" );
269 
270  /* go through array defining macros */
271  for ( n = 0, p = pairs; p != NULL && p[0] != NULL; n++, p += 2 ) {
272  if ( macPutValue( handle, p[0], p[1] ) < 0 )
273  return -1;
274  }
275 
276  /* debug output */
277  if ( handle->debug & 1 )
278  printf( "macInstallMacros() -> %d\n", n );
279 
280  /* return number of macros defined */
281  return n;
282 }
#define printf
Definition: epicsStdio.h:41
#define NULL
Definition: catime.c:38
int debug
debugging level
Definition: macLib.h:46
long epicsStdCall macPutValue(MAC_HANDLE *handle, const char *name, const char *value)
Sets the value of a specific macro.
Definition: macCore.c:233
LIBCOM_API long epicsStdCall macParseDefns ( MAC_HANDLE handle,
const char *  defns,
char **  pairs[] 
)

Parse macro definitions into an array of {name, value} pairs.

Returns
Number of macros found; <0 = ERROR

This takes a set of macro definitions in "a=xxx,b=yyy" format and converts them into an array of pointers to character strings which are, in order, "first name", "first value", "second name", "second value" etc. The array is terminated with two NULL pointers and all storage is allocated contiguously so that it can be freed with a single call to free().

This routine is independent of any handle and provides a generally useful service which may be used elsewhere. Any macro references in values are not expanded at this point since the referenced macros may be defined or redefined before the macro actually has to be translated.

Shell-style escapes and quotes are supported, as are things like "A=B,B=$(C$(A)),CA=CA,CB=CB" (sets B to "CB"). White space is significant within values but ignored elsewhere (i.e. surrounding "=" and "," characters).

The function returns the number of definitions encountered, or -1 if the supplied string is invalid.

Parameters
handleopaque handle; may be NULL if debug messages are not required.
defnsmacro definitions in "a=xxx,b=yyy" format
pairsaddress of variable to receive pointer to NULL-terminated array of {name, value} pair strings; all storage is allocated contiguously

Definition at line 32 of file macUtil.c.

43 {
44  static const size_t altNumMax = 4;
45  size_t numMax;
46  int i;
47  int num;
48  int quote;
49  int escape;
50  size_t nbytes;
51  const char **ptr;
52  const char **end;
53  int *del;
54  char *memCp, **memCpp;
55  const char *c;
56  char *s, *d, **p;
57  enum { preName, inName, preValue, inValue } state;
58 
59  /* debug output */
60  if ( handle && (handle->debug & 1) )
61  printf( "macParseDefns( %s )\n", defns );
62 
63  /* allocate temporary pointer arrays; in worst case they need to have
64  as many entries as the length of the defns string */
65  numMax = strlen( defns );
66  if ( numMax < altNumMax )
67  numMax = altNumMax;
68  ptr = (const char **) calloc( numMax, sizeof( char * ) );
69  end = (const char **) calloc( numMax, sizeof( char * ) );
70  del = (int *) calloc( numMax, sizeof( int ) );
71  if ( ptr == NULL || end == NULL || del == NULL ) goto error;
72 
73  /* go through definitions, noting pointers to starts and ends of macro
74  names and values; honor quotes and escapes; ignore white space
75  around assignment and separator characters */
76  num = 0;
77  del[0] = FALSE;
78  quote = 0;
79  state = preName;
80  for ( c = (const char *) defns; *c != '\0'; c++ ) {
81 
82  /* handle quotes */
83  if ( quote )
84  quote = ( *c == quote ) ? 0 : quote;
85  else if ( *c == '\'' || *c == '"' )
86  quote = *c;
87 
88  /* handle escapes (pointer incremented below) */
89  escape = ( *c == '\\' && *( c + 1 ) != '\0' );
90 
91  switch ( state ) {
92  case preName:
93  if ( !quote && !escape && ( isspace( (int) *c ) || *c == ',' ) ) break;
94  ptr[num] = c;
95  state = inName;
96  /* fall through (may be empty name) */
97 
98  case inName:
99  if ( quote || escape || ( *c != '=' && *c != ',' ) ) break;
100  end[num] = c;
101  while ( end[num] > ptr[num] && isspace( (int) *( end[num] - 1 ) ) )
102  end[num]--;
103  num++;
104  del[num] = FALSE;
105  state = preValue;
106  if ( *c != ',' ) break;
107  del[num] = TRUE;
108  /* fall through (','; will delete) */
109 
110  case preValue:
111  if ( !quote && !escape && isspace( (int) *c ) ) break;
112  ptr[num] = c;
113  state = inValue;
114  /* fall through (may be empty value) */
115 
116  case inValue:
117  if ( quote || escape || *c != ',' ) break;
118  end[num] = c;
119  while ( end[num] > ptr[num] && isspace( (int) *( end[num] - 1 ) ) )
120  end[num]--;
121  num++;
122  del[num] = FALSE;
123  state = preName;
124  break;
125  }
126 
127  /* if this was escape, increment pointer now (couldn't do
128  before because could have ignored escape at start of name
129  or value) */
130  if ( escape ) c++;
131  }
132 
133  /* tidy up from state at end of string */
134  switch ( state ) {
135  case preName:
136  break;
137  case inName:
138  end[num] = c;
139  while ( end[num] > ptr[num] && isspace( (int) *( end[num] - 1 ) ) )
140  end[num]--;
141  num++;
142  del[num] = TRUE;
143  case preValue:
144  ptr[num] = c;
145  case inValue:
146  end[num] = c;
147  while ( end[num] > ptr[num] && isspace( (int) *( end[num] - 1 ) ) )
148  end[num]--;
149  num++;
150  del[num] = FALSE;
151  }
152 
153  /* debug output */
154  if ( handle != NULL && handle->debug & 4 )
155  for ( i = 0; i < num; i += 2 )
156  printf( "[%ld] %.*s = [%ld] %.*s (%s) (%s)\n",
157  (long) (end[i+0] - ptr[i+0]), (int) (end[i+0] - ptr[i+0]), ptr[i+0],
158  (long) (end[i+1] - ptr[i+1]), (int) (end[i+1] - ptr[i+1]), ptr[i+1],
159  del[i+0] ? "del" : "nodel",
160  del[i+1] ? "del" : "nodel" );
161 
162  /* calculate how much memory to allocate: pointers followed by
163  strings */
164  nbytes = ( num + 2 ) * sizeof( char * );
165  for ( i = 0; i < num; i++ )
166  nbytes += end[i] - ptr[i] + 1;
167 
168  /* allocate memory and set returned pairs pointer */
169  memCp = malloc( nbytes );
170  if ( memCp == NULL ) goto error;
171  memCpp = ( char ** ) memCp;
172  *pairs = memCpp;
173 
174  /* copy pointers and strings (memCpp accesses the pointer section
175  and memCp accesses the string section) */
176  memCp += ( num + 2 ) * sizeof( char * );
177  for ( i = 0; i < num; i++ ) {
178 
179  /* if no '=' followed the name, macro will be deleted */
180  if ( del[i] )
181  *memCpp++ = NULL;
182  else
183  *memCpp++ = memCp;
184 
185  /* copy value regardless of the above */
186  strncpy( memCp, (const char *) ptr[i], end[i] - ptr[i] );
187  memCp += end[i] - ptr[i];
188  *memCp++ = '\0';
189  }
190 
191  /* add two NULL pointers */
192  *memCpp++ = NULL;
193  *memCpp++ = NULL;
194 
195  /* remove quotes and escapes from names in place (unlike values, they
196  will not be re-parsed) */
197  for ( p = *pairs; *p != NULL; p += 2 ) {
198  quote = 0;
199  for ( s = d = *p; *s != '\0'; s++ ) {
200 
201  /* quotes are not copied */
202  if ( quote ) {
203  if ( *s == quote ) {
204  quote = 0;
205  continue;
206  }
207  }
208  else if ( *s == '\'' || *s == '"' ) {
209  quote = *s;
210  continue;
211  }
212 
213  /* escapes are not copied but next character is */
214  if ( *s == '\\' && *( s + 1 ) != '\0' )
215  s++;
216 
217  /* others are copied */
218  *d++ = *s;
219  }
220 
221  /* need to terminate destination */
222  *d++ = '\0';
223  }
224 
225  /* free workspace */
226  free( ( void * ) ptr );
227  free( ( void * ) end );
228  free( ( char * ) del );
229 
230  /* debug output */
231  if ( handle != NULL && handle->debug & 1 )
232  printf( "macParseDefns() -> %d\n", num / 2 );
233 
234  /* success exit; return number of definitions */
235  return num / 2;
236 
237  /* error exit */
238 error:
239  errlogPrintf( "macParseDefns: failed to allocate memory\n" );
240  if ( ptr != NULL ) free( ( void * ) ptr );
241  if ( end != NULL ) free( ( void * ) end );
242  if ( del != NULL ) free( ( char * ) del );
243  *pairs = NULL;
244  return -1;
245 }
#define FALSE
Definition: dbDefs.h:32
#define quote(v)
int i
Definition: scan.c:967
#define printf
Definition: epicsStdio.h:41
#define NULL
Definition: catime.c:38
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
int debug
debugging level
Definition: macLib.h:46
#define TRUE
Definition: dbDefs.h:27
LIBCOM_API long epicsStdCall macPopScope ( MAC_HANDLE handle)

Retrieve the last pushed scope (like stack operations)

Returns
0 = OK; <0 = ERROR

See macPushScope()

Parameters
handleopaque handle

Definition at line 427 of file macCore.c.

429 {
430  MAC_ENTRY *entry, *nextEntry;
431 
432  /* check handle */
433  if ( handle == NULL || handle->magic != MAC_MAGIC ) {
434  errlogPrintf( "macPopScope: NULL or invalid handle\n" );
435  return -1;
436  }
437 
438  /* debug output */
439  if ( handle->debug & 1 )
440  printf( "macPopScope()\n" );
441 
442  /* check scoping level isn't already zero */
443  if ( handle->level == 0 ) {
444  errlogPrintf( "macPopScope: no scope to pop\n" );
445  return -1;
446  }
447 
448  /* look up most recent scope entry */
449  entry = lookup( handle, "<scope>", TRUE );
450  if ( entry == NULL ) {
451  errlogPrintf( "macPopScope: no scope to pop\n" );
452  return -1;
453  }
454 
455  /* delete scope entry and all macros defined since it */
456  for ( ; entry != NULL; entry = nextEntry ) {
457  nextEntry = next( entry );
458  delete( handle, entry );
459  }
460 
461  /* decrement scoping level */
462  handle->level--;
463 
464  return 0;
465 }
long magic
magic number (used for authentication)
Definition: macLib.h:43
#define printf
Definition: epicsStdio.h:41
#define NULL
Definition: catime.c:38
Definition: macCore.c:39
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
#define MAC_MAGIC
Definition: macCore.c:83
int debug
debugging level
Definition: macLib.h:46
#define TRUE
Definition: dbDefs.h:27
int level
scoping level
Definition: macLib.h:45
LIBCOM_API long epicsStdCall macPushScope ( MAC_HANDLE handle)

Marks the start of a new scoping level.

Returns
0 = OK; <0 = ERROR

Marks all macro definitions added after this call as belonging to another scope. These macros will be lost on a macPopScope() call and those at the current scope will be re-instated.

Parameters
handleopaque handle

Definition at line 392 of file macCore.c.

394 {
395  MAC_ENTRY *entry;
396 
397  /* check handle */
398  if ( handle == NULL || handle->magic != MAC_MAGIC ) {
399  errlogPrintf( "macPushScope: NULL or invalid handle\n" );
400  return -1;
401  }
402 
403  /* debug output */
404  if ( handle->debug & 1 )
405  printf( "macPushScope()\n" );
406 
407  /* increment scoping level */
408  handle->level++;
409 
410  /* create new "special" entry of name "<scope>" */
411  entry = create( handle, "<scope>", TRUE );
412  if ( entry == NULL ) {
413  handle->level--;
414  errlogPrintf( "macPushScope: failed to push scope\n" );
415  return -1;
416  } else {
417  entry->type = "scope marker";
418  }
419 
420  return 0;
421 }
long magic
magic number (used for authentication)
Definition: macLib.h:43
char * type
Definition: macCore.c:42
#define printf
Definition: epicsStdio.h:41
#define NULL
Definition: catime.c:38
Definition: macCore.c:39
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
#define MAC_MAGIC
Definition: macCore.c:83
int debug
debugging level
Definition: macLib.h:46
#define TRUE
Definition: dbDefs.h:27
int level
scoping level
Definition: macLib.h:45
LIBCOM_API long epicsStdCall macPutValue ( MAC_HANDLE handle,
const char *  name,
const char *  value 
)

Sets the value of a specific macro.

Returns
Returns the length of the value string.
Note
If value is NULL, all instances of name are undefined at all scoping levels (the named macro doesn't have to exist in this case). Macros referenced in value need not be defined at this point.
Parameters
handleopaque handle
namemacro name
valuemacro value

Definition at line 233 of file macCore.c.

239 {
240  MAC_ENTRY *entry; /* pointer to this macro's entry structure */
241 
242  /* check handle */
243  if ( handle == NULL || handle->magic != MAC_MAGIC ) {
244  errlogPrintf( "macPutValue: NULL or invalid handle\n" );
245  return -1;
246  }
247 
248  if ( handle->debug & 1 )
249  printf( "macPutValue( %s, %s )\n", name, value ? value : "NULL" );
250 
251  /* handle NULL value case: if name was found, delete entry (may be
252  several entries at different scoping levels) */
253  if ( value == NULL ) {
254  /*
255  * FIXME: shouldn't be able to delete entries from lower scopes
256  * NOTE: when this is changed, this functionality of removing
257  * a macro from all scopes will still be needed by iocshEnvClear
258  */
259  while ( ( entry = lookup( handle, name, FALSE ) ) != NULL ) {
260  int done = strcmp(entry->type, "environment variable") == 0;
261  delete( handle, entry );
262 
263  if (done)
264  break;
265  }
266 
267  return 0;
268  }
269 
270  /* look up macro name */
271  entry = lookup( handle, name, FALSE );
272 
273  /* new entry must be created if macro doesn't exist or if it only
274  exists at a lower scoping level */
275  if ( entry == NULL || entry->level < handle->level ) {
276  entry = create( handle, name, FALSE );
277  if ( entry == NULL ) {
278  errlogPrintf( "macPutValue: failed to create macro %s = %s\n",
279  name, value );
280  return -1;
281  } else {
282  entry->type = "macro";
283  }
284  }
285 
286  /* copy raw value */
287  if ( rawval( handle, entry, value ) == NULL ) {
288  errlogPrintf( "macPutValue: failed to copy macro %s = %s\n",
289  name, value ) ;
290  return -1;
291  }
292 
293  /* return length of value */
294  return strlen( value );
295 }
long magic
magic number (used for authentication)
Definition: macLib.h:43
Definition: link.h:174
#define FALSE
Definition: dbDefs.h:32
char * type
Definition: macCore.c:42
#define printf
Definition: epicsStdio.h:41
#define NULL
Definition: catime.c:38
int level
Definition: macCore.c:49
Definition: macCore.c:39
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
#define MAC_MAGIC
Definition: macCore.c:83
int debug
debugging level
Definition: macLib.h:46
void done(int k)
Definition: antelope.c:77
int level
scoping level
Definition: macLib.h:45
LIBCOM_API long epicsStdCall macReportMacros ( MAC_HANDLE handle)

Reports details of current definitions.

Returns
0 = OK; <0 = ERROR This sends details of current definitions to standard output, and is intended purely for debugging purposes.
Parameters
handleopaque handle

Definition at line 471 of file macCore.c.

473 {
474  const char *format = "%-1s %-16s %-16s %s\n";
475  MAC_ENTRY *entry;
476 
477  /* check handle */
478  if ( handle == NULL || handle->magic != MAC_MAGIC ) {
479  errlogPrintf( "macReportMacros: NULL or invalid handle\n" );
480  return -1;
481  }
482 
483  /* expand raw values if necessary; report but ignore failure */
484  if ( expand( handle ) < 0 )
485  errlogPrintf( "macGetValue: failed to expand raw values\n" );
486 
487  /* loop through macros, reporting names and values */
488  printf( format, "e", "name", "rawval", "value" );
489  printf( format, "-", "----", "------", "-----" );
490  for ( entry = first( handle ); entry != NULL; entry = next( entry ) ) {
491 
492  /* differentiate between "special" (scope marker) and ordinary
493  entries */
494  if ( entry->special )
495  printf( format, "s", "----", "------", "-----" );
496  else
497  printf( format, entry->error ? "*" : " ", entry->name,
498  entry->rawval ? entry->rawval : "",
499  entry->value ? entry->value : "");
500  }
501 
502  return 0;
503 }
long magic
magic number (used for authentication)
Definition: macLib.h:43
#define printf
Definition: epicsStdio.h:41
char * value
Definition: macCore.c:44
#define NULL
Definition: catime.c:38
char * name
Definition: macCore.c:41
int special
Definition: macCore.c:48
Definition: macCore.c:39
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
int error
Definition: macCore.c:46
#define MAC_MAGIC
Definition: macCore.c:83
char * rawval
Definition: macCore.c:43
LIBCOM_API void epicsStdCall macSuppressWarning ( MAC_HANDLE handle,
int  falseTrue 
)

Disable or enable warning messages.

The macExpandString() routine prints warnings when it cant expand a macro. This routine can be used to silence those warnings. A non zero value will suppress the warning messages from subsequent library routines given the same handle.

Parameters
handleopaque handle
falseTrue0 means issue, 1 means suppress

Definition at line 154 of file macCore.c.

158 {
159  if ( handle && handle->magic == MAC_MAGIC ) {
160  handle->flags = (handle->flags & ~FLAG_SUPPRESS_WARNINGS) |
161  (suppress ? FLAG_SUPPRESS_WARNINGS : 0);
162  }
163 }
long magic
magic number (used for authentication)
Definition: macLib.h:43
#define FLAG_SUPPRESS_WARNINGS
Definition: macCore.c:88
int flags
operating mode flags
Definition: macLib.h:48
#define MAC_MAGIC
Definition: macCore.c:83