cgul_varsub_cxx.h File Reference

C++ wrapper for cgul_varsub More...

#include "cgul_convspec_cxx.h"
#include "cgul_exception_cxx.h"
#include "cgul_string_cxx.h"
#include "cgul_varsub.h"
Include dependency graph for cgul_varsub_cxx.h:
This graph shows which files directly or indirectly include this file:

Typedefs

typedef int(* cgul_varsub_cxx__lookup_t) (const char *varname, cgul_string_cxx *dst, void *data)
 
typedef int(* cgul_varsub_formatted_cxx__lookup_t) (const char *varname, cgul_convspec_cxx *cs, cgul_string_cxx *dst, void *data)
 

Functions

int cgul_varsub_cxx__callback_adaptor (cgul_exception_t *cex, const char *varname, cgul_string_t dst, void *data)
 
int cgul_varsub_formatted_cxx__callback_adaptor (cgul_exception_t *cex, const char *varname, cgul_convspec_t cs, cgul_string_t dst, void *data)
 
void cgul_varsub_cxx (const char *src, cgul_string_cxx *dst, cgul_varsub_cxx__lookup_t f, void *data)
 
void cgul_varsub_formatted_cxx (const char *src, cgul_string_cxx *dst, cgul_varsub_formatted_cxx__lookup_t f, void *data)
 

Detailed Description

C++ wrapper for cgul_varsub.

Author
Paul Serice

Typedef Documentation

§ cgul_varsub_cxx__lookup_t

typedef int(* cgul_varsub_cxx__lookup_t) (const char *varname, cgul_string_cxx *dst, void *data)

This typedef defines the lookup function used by cgul_varsub_cxx() to substitute a variable with its value. When cgul_varsub_cxx() encounters a variable, it passes the name of the variable to the lookup function in varname. The lookup function should then append the value associated with varname to the destination string dst.

Note that the dst that is passed into the lookup function is the same dst that is passed into cgul_varsub_cxx(). By altering dst, the lookup function is directly altering the result that will be returned to the caller.

The lookup function should return 1 if the lookup was performed and substituted for varname. On the other hand, if the lookup failed, 0 should be returned so cgul_varsub_cxx() will know to insert varname into dst literally.

If an error occurs during the execution of the lookup function, it should be handled in the lookup function. If the lookup function lets a C++ exception escape, it will be quashed by cgul_varsub_cxx__callback_adaptor() to avoid having the C++ exception stomp on the C stack.

Parameters
[in]varnamevariable name
[in,out]dstdestination string
[in]dataclient data
Returns
whether the lookup was successful

§ cgul_varsub_formatted_cxx__lookup_t

typedef int(* cgul_varsub_formatted_cxx__lookup_t) (const char *varname, cgul_convspec_cxx *cs, cgul_string_cxx *dst, void *data)

This typedef defines the lookup function used by cgul_varsub_formatted_cxx() to substitute the variable varname with its value using an optional printf()-style conversion specification cs. The lookup function should not try to delete cs.

If cgul_varsub_formatted_cxx() does not find a conversion specification or if it detects that there is a problem with the conversion specification, it will set cs to NULL. Thus, the lookup function must check to make sure cs is not NULL before attempting to dereference it.

cgul_varsub_formatted_cxx() considers conversion specifications like "%*s", "%.*s", or "%*.*s" to be invalid because they serve no good purpose in this context, and they have negative security implications. The lookup function will be called with cs set to NULL if they are detected.

Thus to validate cs, the lookup function primarily needs to verify that the type of the conversion specification matches the type of the value that is being appended. After this is verified, it should then be safe to call cs->serialize() to convert cs to a format string that can then be used with dst->append_sprintf() in order to append varname to dst.

Note that the dst that is passed into the lookup function is the same dst that is passed into cgul_varsub_formatted_cxx(). By altering dst, the lookup function is directly altering the result that will be returned to the caller.

The lookup function should return 1 if the lookup was performed and substituted for varname. On the other hand, if the lookup failed, 0 should be returned so cgul_varsub_formatted_cxx() will know to insert varname into dst literally.

If an error occurs during the execution of the lookup function, it should be handled in the lookup function. If the lookup function lets a C++ exception escape, it will be quashed by cgul_varsub_formatted_cxx__callback_adaptor() to avoid having the C++ exception stomp on the C stack.

Parameters
[in]varnamevariable name
[in]csconversion specification or NULL
[in,out]dstdestination string
[in]dataclient data
Returns
whether the lookup was successful

Function Documentation

§ cgul_varsub_cxx__callback_adaptor()

int cgul_varsub_cxx__callback_adaptor ( cgul_exception_t cex,
const char *  varname,
cgul_string_t  dst,
void *  data 
)
inline

The adoptor used by cgul_varsub_cxx() as the direct callback for the C cgul_varsub() function. It in turn calls the user's C++ callback.

Parameters
[in]cexc-style exception
[in]varnamevariable name
[in,out]dstdestination string
[in]dataclient data
Returns
whether the lookup was successful

Referenced by cgul_varsub_cxx().

§ cgul_varsub_formatted_cxx__callback_adaptor()

int cgul_varsub_formatted_cxx__callback_adaptor ( cgul_exception_t cex,
const char *  varname,
cgul_convspec_t  cs,
cgul_string_t  dst,
void *  data 
)
inline

The adoptor used by cgul_varsub_formatted_cxx() as the direct callback for the C cgul_varsub_formatted() function. It in turn calls the user's C++ callback.

Parameters
[in,out]cexc-style exception
[in]varnamevariable name
[in]csconversion specification or NULL
[in,out]dstdestination string
[in]dataclient data
Returns
whether the lookup was successful

Referenced by cgul_varsub_formatted_cxx().

§ cgul_varsub_cxx()

void cgul_varsub_cxx ( const char *  src,
cgul_string_cxx dst,
cgul_varsub_cxx__lookup_t  f,
void *  data 
)
inline

This function performs variable substitution on the string src appending the result to dst. If an error occurs, an exception is thrown. If an exception is thrown, dst will contain a partial result.

The syntax for variable names embedded in src should follow the same syntax that is used by the Bourne shell. For example if name="Mr. President", "Hello, $name!" or "Hello, ${name}!" will yield "Hello, Mr. President!" after basic variable substitution is performed.

Any character can be escaped by prefixing it with the backslash character. The following conventional escape sequences produce the conventional results:

    "\a", "\b", "\t", "\n", "\v", "\f", "\r", "\\", "\$"

The client is responsible for providing the lookup function f that maps variable names to values. f is free to treat the variable names creatively. By placing the variable names in braces, it is possible to embed extra information in the source string src because the name is everything between the braces and is not limited to alphanumeric or underscore characters. f just needs to be written to handle the extra information. (See cgul_varsub_formatted_cxx() for an example of how to take advantage of this feature.)

When using braces to demarcate variable names, it is worth knowing that braces nest, and escape sequences are enabled. If you escape a brace, it will be treated like any other character at the current brace level. An escaped brace will not increase or decrease the current brace level, and it will not match any other brace.

data will be passed to f as the client data. Typically, data will hold the data needed by f to perform the lookup.

See tests/main_varsub_cxx.cc for a simple example of how to write a lookup function f.

Parameters
[in]srcsource string
[out]dstdestination string
[in]flookup function
[in]dataclient data
See also
cgul_varsub_formatted_cxx()
cgul_varsub_cxx__lookup_t

References cgul_varsub(), cgul_varsub__lookup_t, cgul_varsub_cxx__callback_adaptor(), and cgul_string_cxx::get_obj().

§ cgul_varsub_formatted_cxx()

void cgul_varsub_formatted_cxx ( const char *  src,
cgul_string_cxx dst,
cgul_varsub_formatted_cxx__lookup_t  f,
void *  data 
)
inline

This function performs variable substitution on the string src appending the result to dst. If an optional printf()-style conversion specification is embedded in the variable name, it will be used to format the variable when appending to dst. If an error occurs, an exception is thrown. If an exception is thrown, dst will contain a partial result.

As explained in the comments for cgul_varsub(), it understands the Bourne shell convention of placing braces around the name of a variable. When braces are used, everything between the braces is treat as the literal name of the variable including non-alphanumeric characters. This makes it possible to embed an optional printf()-style conversion specification in the name of the variable.

This underlying cgul_varsub_formatted() function registers a local callback with cgul_varsub() so that cgul_varsub() can parse the source string src. Each time cgul_varsub() detects a variable name, the local callback is invoked. The local callback then splits the string into the real variable name and an option printf()-style conversion specification which is (eventually) passed to f.

For example, if src is set to "${key:%32s}", cgul_varsub() will call the local callback with the variable name set to "key:%32s". The local callback will split the string into the real variable name ("key") and its conversion specification ("%32s"). The local callback will then (eventually) cause f to be passed the real variable name and its conversion specification.

If the optional conversion specification is missing or invalid, f will be called with the conversion specification set to NULL. Conversion specifications like "%*s", "%.*s", or "%*.*s" are considered to be invalid because they serve no good purpose in this context, and they have negative security implications.

Any character can be escaped by prefixing it with the backslash character. The following conventional escape sequences produce the conventional results:

    "\a", "\b", "\t", "\n", "\v", "\f", "\r", "\\", "\$"

data will be passed to f as the client data. Typically, data will hold the data needed by f to perform the lookup.

See tests/main_varsub_formatted_cxx.cc for an example of how to write the lookup function f.

Parameters
[in]srcsource string
[out]dstdestination string
[in]flookup function
[in]dataclient data
See also
cgul_varsub_cxx()
cgul_varsub_formatted_cxx__lookup_t

References cgul_varsub_formatted(), cgul_varsub_formatted_cxx__callback_adaptor(), and cgul_string_cxx::get_obj().