evio
5.2
|
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
#include <pthread.h>
#include <assert.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "evio.h"
Macros | |
#define | _GNU_SOURCE |
#define | EV_READFILE 0 |
#define | EV_READPIPE 1 |
#define | EV_READSOCK 2 |
#define | EV_READBUF 3 |
#define | EV_WRITEFILE 4 |
#define | EV_WRITEPIPE 5 |
#define | EV_WRITESOCK 6 |
#define | EV_WRITEBUF 7 |
#define | EV_MAGIC 0xc0da0100 |
Number used to determine data endian. More... | |
#define | EV_BLOCKSIZE_V3 8192 |
Version 3's fixed block size in 32 bit words. More... | |
#define | EV_BLOCKSIZE_V4 500000 |
Version 4's target block size in 32 bit words (16MB). More... | |
#define | EV_BLOCKSIZE_MIN 16 |
Minimum block size in 32 bit words allowed if size reset (32kB) More... | |
#define | EV_BLOCKSIZE_MAX 33554432 |
The upper limit of maximum size for a single block used for writing is 2^25 ints or words. More... | |
#define | EV_VERSION_MASK 0xFF |
In version 4, lowest 8 bits are version, rest is bit info. More... | |
#define | EV_DICTIONARY_MASK 0x100 |
In version 4, dictionary presence is 9th bit in version/info word. More... | |
#define | EV_LASTBLOCK_MASK 0x200 |
In version 4, "last block" is 10th bit in version/info word. More... | |
#define | EV_FIRSTEVENT_MASK 0x4000 |
In version 4, "first event" is 15th bit in version/info word. More... | |
#define | EV_EVENTS_MAX 100000 |
In version 4, upper limit on maximum max number of events per block. More... | |
#define | EV_EVENTS_MAX_DEF 10000 |
In version 4, default max number of events per block. More... | |
#define | EV_SPLIT_SIZE 2000000000L |
In version 4, if splitting file, default split size in bytes (2GB) More... | |
#define | EV_READ_BYTES_V3 16384000 |
In versions 1-3, default size for a single file read in bytes. More... | |
#define | EV_HD_BLKSIZ 0 |
Position of blk hdr word for size of block in 32-bit words. More... | |
#define | EV_HD_BLKNUM 1 |
Position of blk hdr word for block number, starting at 0. More... | |
#define | EV_HD_HDSIZ 2 |
Position of blk hdr word for size of header in 32-bit words (=8). More... | |
#define | EV_HD_COUNT 3 |
Position of blk hdr word for number of events in block (version 4+). More... | |
#define | EV_HD_START 3 |
Position of blk hdr word for first start of event in this block (ver 1-3). More... | |
#define | EV_HD_USED 4 |
Position of blk hdr word for number of words used in block (<= BLKSIZ) (ver 1-3). More... | |
#define | EV_HD_RESVD1 4 |
Position of blk hdr word for reserved (ver 4+). More... | |
#define | EV_HD_VER 5 |
Position of blk hdr word for version of file format (+ bit info in ver 4+). More... | |
#define | EV_HD_RESVD2 6 |
Position of blk hdr word for reserved. More... | |
#define | EV_HD_MAGIC 7 |
Position of blk hdr word for magic number for endianness tracking. More... | |
#define | setDictionaryBit(a) ((a)[EV_HD_VER] |= EV_DICTIONARY_MASK) |
Turn on 9th bit to indicate dictionary included in block. More... | |
#define | clearDictionaryBit(a) ((a)[EV_HD_VER] &= ~EV_DICTIONARY_MASK) |
Turn off 9th bit to indicate dictionary included in block. More... | |
#define | hasDictionary(a) (((a)[EV_HD_VER] & EV_DICTIONARY_MASK) > 0 ? 1 : 0) |
Is there a dictionary in this block? More... | |
#define | hasDictionaryInt(i) ((i & EV_DICTIONARY_MASK) > 0 ? 1 : 0) |
Is there a dictionary in this block? More... | |
#define | setLastBlockBit(a) ((a)[EV_HD_VER] |= EV_LASTBLOCK_MASK) |
Turn on 10th bit to indicate last block of file/transmission. More... | |
#define | clearLastBlockBit(a) ((a)[EV_HD_VER] &= ~EV_LASTBLOCK_MASK) |
Turn off 10th bit to indicate last block of file/transmission. More... | |
#define | clearLastBlockBitInt(i) (i &= ~EV_LASTBLOCK_MASK) |
Turn off 10th bit to indicate last block of file/transmission. More... | |
#define | isLastBlock(a) (((a)[EV_HD_VER] & EV_LASTBLOCK_MASK) > 0 ? 1 : 0) |
Is this the last block of file/transmission? More... | |
#define | isLastBlockInt(i) ((i & EV_LASTBLOCK_MASK) > 0 ? 1 : 0) |
Is this the last block of file/transmission? More... | |
#define | initBlockHeader(a) |
Initialize a block header. More... | |
#define | initBlockHeader2(a, b) |
Initialize a block header. More... | |
Functions | |
int | evopen_ (char *filename, char *flags, int *handle, int fnlen, int flen) |
Fortran interface to evOpen. More... | |
int | evread_ (int *handle, uint32_t *buffer, uint32_t *buflen) |
Fortran interface to evRead. More... | |
int | evwrite_ (int *handle, const uint32_t *buffer) |
Fortran interface to evWrite. More... | |
int | evclose_ (int *handle) |
Fortran interface to evClose. More... | |
int | evioctl_ (int *handle, char *request, void *argp, int reqlen) |
Fortran interface to evIoctl. More... | |
int | evIsLastBlock (uint32_t sixthWord) |
Routine to take the 6th word of a block header and tell whether it's the last block or not. More... | |
void | evPrintBuffer (uint32_t *p, uint32_t len, int swap) |
Routine to print the contents of a buffer. More... | |
char * | evStrReplace (char *orig, const char *replace, const char *with) |
This routine substitutes a given string for a specified substring. More... | |
char * | evStrReplaceEnvVar (const char *orig) |
This routine finds constructs of the form and replaces it with the value of the ENV environmental variable if it exists or with nothing if it doesn't. More... | |
char * | evStrFindSpecifiers (const char *orig, int *specifierCount) |
This routine checks a string for C-style printing integer format specifiers. More... | |
char * | evStrRemoveSpecifiers (const char *orig) |
This routine checks a string for C-style printing integer format specifiers. More... | |
int | evGenerateBaseFileName (char *origName, char **baseName, int *count) |
This routine generates a (base) file name from a name containing format specifiers and enviromental variables. More... | |
char * | evGenerateFileName (EVFILE *a, int specifierCount, int runNumber, int splitting, int splitNumber, char *runType, uint32_t streamId) |
This method generates a complete file name from the previously determined baseFileName obtained from calling evGenerateBaseFileName and stored in the evOpen handle. More... | |
int | evOpen (char *filename, char *flags, int *handle) |
This function opens a file for either reading or writing evio format data. More... | |
int | evOpenBuffer (char *buffer, uint32_t bufLen, char *flags, int *handle) |
This function allows for either reading or writing evio format data from a buffer. More... | |
int | evOpenSocket (int sockFd, char *flags, int *handle) |
This function allows for either reading or writing evio format data from a TCP socket. More... | |
int | evOpenFake (char *filename, char *flags, int *handle, char **evf) |
int | evRead (int handle, uint32_t *buffer, uint32_t buflen) |
This routine reads from an evio format file/socket/buffer opened with routines evOpen, evOpenBuffer, or evOpenSocket and returns the next event in the buffer arg. More... | |
int | evReadAlloc (int handle, uint32_t **buffer, uint32_t *buflen) |
This routine reads an evio bank from an evio format file/socket/buffer opened with routines evOpen, evOpenBuffer, or evOpenSocket, allocates a buffer and fills it with the bank. More... | |
int | evReadNoCopy (int handle, const uint32_t **buffer, uint32_t *buflen) |
This routine reads from an evio format file/buffer/socket opened with routines evOpen, evOpenBuffer, or evOpenSocket and returns a pointer to the next event residing in an internal buffer. More... | |
int | evReadRandom (int handle, const uint32_t **pEvent, uint32_t *buflen, uint32_t eventNumber) |
This routine does a random access read from an evio format file/buffer opened with routines evOpen or evOpenBuffer. More... | |
int | evWrite (int handle, const uint32_t *buffer) |
This routine writes an evio event to an internal buffer containing evio data. More... | |
int | evFlush (int handle) |
This function flushes any remaining internally buffered data to file/socket. More... | |
int | evClose (int handle) |
This routine flushes any existing evio format data in an internal buffer (written to with evWrite) to the final destination file/socket/buffer opened with routines evOpen, evOpenBuffer, or evOpenSocket. More... | |
int | evGetFileName (int handle, char *name, size_t maxLength) |
This routine gets the name of the file currently being written to and opened with evOpen, Returned string may NOT be written into. More... | |
int | evGetBufferLength (int handle, uint32_t *length) |
This routine returns the number of bytes written into a buffer so far when given a handle provided by calling evOpenBuffer. More... | |
int | evIoctl (int handle, char *request, void *argp) |
This routine changes various evio parameters used in reading and writing. More... | |
int | evGetRandomAccessTable (int handle, uint32_t ***const table, uint32_t *len) |
This routine gets an array of event pointers if the handle was opened in random access mode. More... | |
int | evGetDictionary (int handle, char **dictionary, uint32_t *len) |
This routine gets the dictionary associated with this handle if there is any. More... | |
int | evWriteDictionary (int handle, char *xmlDictionary) |
This routine writes an optional dictionary as the first event of an evio file/socket/buffer. More... | |
int | evWriteFirstEvent (int handle, const uint32_t *firstEvent) |
This routine writes an optional "first event" after any dictionary in an evio file/socket/buffer. More... | |
int | evCreateFirstEventBlock (const uint32_t *firstEvent, int localEndian, void **block, uint32_t *words) |
This routine takes the given "first event" (evio bank) and places it into a properly formatted evio block (evio file format) with the proper bit set in the block header labeling content as a first event. More... | |
int | evStringsToBuf (uint32_t *buffer, int bufLen, char **strings, int stringCount, int *dataLen) |
This routine writes an array of strings, in evio format, into the given buffer. More... | |
int | evBufToStrings (char *buffer, int bufLen, char ***pStrArray, int *strCount) |
This routine unpacks/parses an evio format buffer containing strings into an array of strings. More... | |
const char * | evGetTypename (int type) |
This routine returns a string representation of an evio type. More... | |
int | evIsContainer (int type) |
This routine return true (1) if given type is a container, else returns false (0). More... | |
char * | evPerror (int error) |
This routine returns a string describing the given error value. More... | |
Variables | |
EVFILE ** | handleList = NULL |
Let's take a look at an evio block header also
known as a physical record header.
In versions 1, 2 & 3, evio files impose an anachronistic
block structure. The complication that arises is that logical records
(events) will sometimes cross physical record boundaries.
Evio block header, versions 1,2 & 3:
MSB(31) LSB(0)
<— 32 bits ---------------------—>
+----------------------------------—+
+ Block Size +
+----------------------------------—+
+ Block Number +
+----------------------------------—+
+ Header Size = 8 +
+----------------------------------—+
+ Start +
+----------------------------------—+
+ Used +
+----------------------------------—+
+ Version +
+----------------------------------—+
+ Reserved +
+----------------------------------—+
+ Magic # +
+----------------------------------—+
Block Size = number of 32 bit ints in block (including this one).
This is fixed for versions 1-3, generally at 8192 (32768 bytes)
Block Number = id number (starting at 1)
Header Size = number of 32 bit nts in this header (always 8)
Start = offset to first event header in block relative to start of block
Used = # of used/valid words (header + data) in block,
(normally = block size, but in last block may be smaller)
Version = evio format version
Reserved = reserved
Magic # = magic number (0xc0da0100) used to check endianness
In version 4, only an integral number of complete
events will be contained in a single block.
Evio block header, version 4:
MSB(31) LSB(0)
<— 32 bits ---------------------—>
+----------------------------------—+
+ Block Size +
+----------------------------------—+
+ Block Number +
+----------------------------------—+
+ Header Length = 8 +
+----------------------------------—+
+ Event Count +
+----------------------------------—+
+ Reserved +
+----------------------------------—+
+ Bit info + Version +
+----------------------------------—+
+ Reserved +
+----------------------------------—+
+ Magic Number +
+----------------------------------—+
Block Size = number of ints in block (including this one).
Block Number = id number (starting at 1)
Header Length = number of ints in this header (EV_HDSIZ which is currently 8)
Event Count = number of events in this block (always an integral #).
NOTE: this value should not be used to parse the following
events since the first block may have a dictionary whose
presence is not included in this count.
Bit info & Version = Lowest 8 bits are the version number (4).
Upper 24 bits contain bit info.
If a dictionary is included as the first event, bit #9 is set (=1)
Magic # = magic number (0xc0da0100) used to check endianness
Bit info (24 bits) has the following bits defined (starting at 1):
Bit 9 = true if dictionary is included (relevant for first block only)
Bit 10 = true if this block is the last block in file or network transmission
Bits 11-14 = type of events following (ROC Raw = 0, Physics = 1, PartialPhysics = 2,
DisentangledPhysics = 3, User = 4, Control = 5, Prestart = 6, Go = 7,
Pause = 8, End = 9, Other = 15)
Bit 15 = true if block contains "first" event which gets written in each file split
Bits 11-15 are ONLY for the CODA online use of evio.
That's because only a single CODA event TYPE is placed into
a single ET or cMsg buffer. Each user or control event has its own
buffer. Thus all events parsed from a single buffer will be of a single CODA type.
COMPOSITE DATA:
This is a new type of data (value = 0xf) which originated with Hall B.
It is a composite type and allows for possible expansion in the future
if there is a demand. Basically it allows the user to specify a custom
format by means of a string - stored in a tagsegment. The data in that
format follows in a bank. The routine to swap this data must be provided
by the definer of the composite type - in this case Hall B. The swapping
function is plugged into this evio library's swapping routine.
Here's what it looks like.
MSB(31) LSB(0)
<— 32 bits ---------------------—>
+------—+---—+-----------------—+
+ tag + type + length + –> tagsegment header
+------—+---—+-----------------—+
+ Data Format String +
+ +
+----------------------------------—+
+ length + \
+-------------—+------—+-------—+ \ bank header
+ tag + type + num + /
+-------------—+------—+-------—+ /
+ Data +
+ +
+----------------------------------—+
The beginning tagsegment is a normal evio tagsegment containing a string
(type = 0x3). Currently its type and tag are not used - at least not for
data formatting.
The bank is a normal evio bank header with data following.
The format string is used to read/write this data so that takes care of any
padding that may exist. As with the tagsegment, the tags and type are ignored.
#define _GNU_SOURCE |
#define clearDictionaryBit | ( | a | ) | ((a)[EV_HD_VER] &= ~EV_DICTIONARY_MASK) |
Turn off 9th bit to indicate dictionary included in block.
#define clearLastBlockBit | ( | a | ) | ((a)[EV_HD_VER] &= ~EV_LASTBLOCK_MASK) |
Turn off 10th bit to indicate last block of file/transmission.
#define clearLastBlockBitInt | ( | i | ) | (i &= ~EV_LASTBLOCK_MASK) |
Turn off 10th bit to indicate last block of file/transmission.
#define EV_BLOCKSIZE_MAX 33554432 |
The upper limit of maximum size for a single block used for writing is 2^25 ints or words.
This gives block sizes of about 134MB. It is a soft limit since a single event larger than this limit may need to be written.
Referenced by evIoctl().
#define EV_BLOCKSIZE_MIN 16 |
Minimum block size in 32 bit words allowed if size reset (32kB)
Referenced by evIoctl().
#define EV_BLOCKSIZE_V3 8192 |
Version 3's fixed block size in 32 bit words.
#define EV_BLOCKSIZE_V4 500000 |
Version 4's target block size in 32 bit words (16MB).
It is a soft limit since a single event larger than this limit may need to be written.
#define EV_DICTIONARY_MASK 0x100 |
In version 4, dictionary presence is 9th bit in version/info word.
#define EV_EVENTS_MAX 100000 |
In version 4, upper limit on maximum max number of events per block.
Referenced by evIoctl().
#define EV_EVENTS_MAX_DEF 10000 |
In version 4, default max number of events per block.
#define EV_FIRSTEVENT_MASK 0x4000 |
In version 4, "first event" is 15th bit in version/info word.
Referenced by evCreateFirstEventBlock().
#define EV_HD_BLKNUM 1 |
Position of blk hdr word for block number, starting at 0.
#define EV_HD_BLKSIZ 0 |
Position of blk hdr word for size of block in 32-bit words.
#define EV_HD_COUNT 3 |
Position of blk hdr word for number of events in block (version 4+).
#define EV_HD_HDSIZ 2 |
Position of blk hdr word for size of header in 32-bit words (=8).
#define EV_HD_MAGIC 7 |
Position of blk hdr word for magic number for endianness tracking.
#define EV_HD_RESVD1 4 |
Position of blk hdr word for reserved (ver 4+).
#define EV_HD_RESVD2 6 |
Position of blk hdr word for reserved.
#define EV_HD_START 3 |
Position of blk hdr word for first start of event in this block (ver 1-3).
#define EV_HD_USED 4 |
Position of blk hdr word for number of words used in block (<= BLKSIZ) (ver 1-3).
#define EV_HD_VER 5 |
Position of blk hdr word for version of file format (+ bit info in ver 4+).
Referenced by evIoctl().
#define EV_LASTBLOCK_MASK 0x200 |
In version 4, "last block" is 10th bit in version/info word.
Referenced by evCreateFirstEventBlock(), and evIsLastBlock().
#define EV_MAGIC 0xc0da0100 |
Number used to determine data endian.
#define EV_READ_BYTES_V3 16384000 |
In versions 1-3, default size for a single file read in bytes.
Equivalent to 500, 32,768 byte blocks. This constant MUST BE an integer multiple of 32768.
#define EV_READBUF 3 |
Referenced by evIoctl(), evRead(), evReadNoCopy(), and evReadRandom().
#define EV_READFILE 0 |
Referenced by evClose(), evIoctl(), evRead(), evReadNoCopy(), and evReadRandom().
#define EV_READPIPE 1 |
Referenced by evClose(), evIoctl(), evRead(), and evReadNoCopy().
#define EV_READSOCK 2 |
Referenced by evIoctl(), evRead(), and evReadNoCopy().
#define EV_SPLIT_SIZE 2000000000L |
In version 4, if splitting file, default split size in bytes (2GB)
#define EV_VERSION_MASK 0xFF |
In version 4, lowest 8 bits are version, rest is bit info.
Referenced by evIoctl().
#define EV_WRITEBUF 7 |
Referenced by evClose(), evIoctl(), evWriteDictionary(), and evWriteFirstEvent().
#define EV_WRITEFILE 4 |
Referenced by evClose(), evFlush(), evGenerateFileName(), evGetFileName(), evIoctl(), evOpenFake(), evWriteDictionary(), and evWriteFirstEvent().
#define EV_WRITEPIPE 5 |
Referenced by evClose(), evFlush(), evIoctl(), evWriteDictionary(), and evWriteFirstEvent().
#define EV_WRITESOCK 6 |
Referenced by evClose(), evFlush(), evIoctl(), evWriteDictionary(), and evWriteFirstEvent().
#define hasDictionary | ( | a | ) | (((a)[EV_HD_VER] & EV_DICTIONARY_MASK) > 0 ? 1 : 0) |
Is there a dictionary in this block?
#define hasDictionaryInt | ( | i | ) | ((i & EV_DICTIONARY_MASK) > 0 ? 1 : 0) |
Is there a dictionary in this block?
#define initBlockHeader | ( | a | ) |
Initialize a block header.
#define initBlockHeader2 | ( | a, | |
b | |||
) |
Initialize a block header.
Referenced by evIoctl().
#define isLastBlock | ( | a | ) | (((a)[EV_HD_VER] & EV_LASTBLOCK_MASK) > 0 ? 1 : 0) |
Is this the last block of file/transmission?
#define isLastBlockInt | ( | i | ) | ((i & EV_LASTBLOCK_MASK) > 0 ? 1 : 0) |
Is this the last block of file/transmission?
#define setDictionaryBit | ( | a | ) | ((a)[EV_HD_VER] |= EV_DICTIONARY_MASK) |
Turn on 9th bit to indicate dictionary included in block.
#define setLastBlockBit | ( | a | ) | ((a)[EV_HD_VER] |= EV_LASTBLOCK_MASK) |
Turn on 10th bit to indicate last block of file/transmission.
int evGenerateBaseFileName | ( | char * | origName, |
char ** | baseName, | ||
int * | count | ||
) |
This routine generates a (base) file name from a name containing format specifiers and enviromental variables.
The given name may contain up to 2, C-style integer format specifiers (such as %03d, or x). If more than 2 are found, an error is returned.
If no "0" precedes any integer between the "%" and the "d" or "x" of the format specifier, it will be added automatically in order to avoid spaces in the final, generated file name. In the evGenerateFileName(EVFILE *, int, int, int, int, char *, uint32_t) routine, the first occurrence will be substituted with the given runNumber value. If the file is being split, the second will be substituted with the split number.
The file name may contain characters of the form which will be substituted with the value of the associated environmental variable or a blank string if none is found.
origName | file name to modify |
baseName | pointer which gets filled with resulting file name |
count | pointer to int filled with number of format specifiers found |
References evStrFindSpecifiers(), evStrReplaceEnvVar(), S_EVFILE_ALLOCFAIL, S_EVFILE_BADARG, S_FAILURE, and S_SUCCESS.
char* evGenerateFileName | ( | EVFILE * | a, |
int | specifierCount, | ||
int | runNumber, | ||
int | splitting, | ||
int | splitNumber, | ||
char * | runType, | ||
uint32_t | streamId | ||
) |
This method generates a complete file name from the previously determined baseFileName obtained from calling evGenerateBaseFileName and stored in the evOpen handle.
All occurrences of the string "%s" in the baseFileName will be substituted with the value of the runType arg or nothing if the runType is null.
If evio data is to be split up into multiple files (split > 0), numbers are used to distinguish between the split files with splitNumber. If baseFileName contains C-style int format specifiers (specifierCount > 0), then the first occurrence will be substituted with the given runNumber value. If the file is being split, the second will be substituted with the splitNumber. If 2 specifiers exist and the file is not being split, no substitutions are made. If no specifier for the splitNumber exists, it is tacked onto the end of the file name. It returns the final file name or NULL if error. Free the result if non-NULL.
If multiple streams of data, each writing a file, end up with the same file name, they can be differentiated by a stream id number. If the id is > 0, the string, ".strm" is appended to the very end of the file followed by the id number (e.g. filename.strm1). This is done after the run type, run number, split numbers, and env vars have been inserted into the file name.
a | evio handle (contains file name to use as a basis for the generated file name) |
specifierCount | number of C-style int format specifiers in file name arg |
runNumber | CODA run number |
splitting | is file being split (split > 0)? 1 - yes, 0 - no |
splitNumber | number of the split file |
runType | run type name |
streamId | streamId number (100 > id > -1) |
References evfilestruct::baseFileName, EV_WRITEFILE, evStrRemoveSpecifiers(), evStrReplace(), and evfilestruct::rw.
int evIsLastBlock | ( | uint32_t | sixthWord | ) |
Routine to take the 6th word of a block header and tell whether it's the last block or not.
sixthWord | 6th word of an evio block header |
References EV_LASTBLOCK_MASK.
int evOpenFake | ( | char * | filename, |
char * | flags, | ||
int * | handle, | ||
char ** | evf | ||
) |
References evfilestruct::baseFileName, EV_WRITEFILE, evfilestruct::rw, and S_SUCCESS.
Routine to print the contents of a buffer.
p | pointer to buffer |
len | number of 32-bit words to print out |
swap | swap if true |
References EVIO_SWAP32.
char* evStrFindSpecifiers | ( | const char * | orig, |
int * | specifierCount | ||
) |
This routine checks a string for C-style printing integer format specifiers.
More specifically, it checks for nd and nx where n can be multiple digits. It makes sure that there is at least one digit between % and x/d and that the first digit is a "0" so that generated filenames contain no white space. It returns the modified string or NULL if error. Free the result if non-NULL. It also returns the number of valid specifiers found in the orig argument.
orig | string to be checked/modified |
specifierCount | pointer to int which gets filled with the number of valid format specifiers in the orig arg |
References evStrReplace().
Referenced by evGenerateBaseFileName().
char* evStrRemoveSpecifiers | ( | const char * | orig | ) |
This routine checks a string for C-style printing integer format specifiers.
More specifically, it checks for nd and nx where n can be multiple digits. It removes all such specifiers and returns the modified string or NULL if error. Free the result if non-NULL.
orig | string to be checked/modified |
Referenced by evGenerateFileName().
char* evStrReplace | ( | char * | orig, |
const char * | replace, | ||
const char * | with | ||
) |
This routine substitutes a given string for a specified substring.
Free the result if non-NULL.
orig | string to modify |
replace | substring in orig arg to replace |
with | string to substitute for replace arg |
Referenced by evGenerateFileName(), evStrFindSpecifiers(), and evStrReplaceEnvVar().
char* evStrReplaceEnvVar | ( | const char * | orig | ) |
This routine finds constructs of the form and replaces it with the value of the ENV environmental variable if it exists or with nothing if it doesn't.
Simple enough to do without regular expressions. Free the result if non-NULL.
orig | string to modify |
References evStrReplace().
Referenced by evGenerateBaseFileName().
EVFILE** handleList = NULL |