BRL-CAD
|
Given a series of input strings and formatting parameters, construct an output version of an input string with contents arranged into multiple columns. More...
Files | |
file | column.h |
file | vls.h |
Data Structures | |
struct | bu_column_state |
struct | bu_vls |
Macros | |
#define | BU_COLUMN_ALL -1 |
#define | BU_COLUMN_ALIGN_LEFT 0 |
#define | BU_COLUMN_ALIGN_RIGHT 1 |
#define | BU_COLUMN_ALIGN_CENTER_LEFT_BIAS 2 |
#define | BU_COLUMN_ALIGN_CENTER_RIGHT_BIAS 3 |
#define | BU_VLS_NULL ((struct bu_vls *)0) |
#define | BU_CK_VLS(_vp) BU_CKMAG(_vp, BU_VLS_MAGIC, "bu_vls") |
#define | BU_VLS_INIT(_vp) |
#define | BU_VLS_INIT_ZERO { BU_VLS_MAGIC, NULL, 0, 0, 0 } |
#define | BU_VLS_IS_INITIALIZED(_vp) (((struct bu_vls *)(_vp) != BU_VLS_NULL) && ((_vp)->vls_magic == BU_VLS_MAGIC)) |
Typedefs | |
typedef struct bu_vls | bu_vls_t |
typedef int(* | bu_vls_uniq_t) (struct bu_vls *v, void *data) |
Functions | |
int | bu_column_print (struct bu_vls *o, struct bu_column_state *s) |
int | bu_column_add (struct bu_column_state *s, const char *str) |
int | bu_column_set_alignment (struct bu_column_state *s, int colnum, int alignment) |
int | bu_column_set_width (struct bu_column_state *s, int colnum, int width) |
int | bu_column_clear (struct bu_column_state *s) |
int | bu_column_reset (struct bu_column_state *s) |
void | bu_vls_init (struct bu_vls *vp) |
DEPRECATED void | bu_vls_init_if_uninit (struct bu_vls *vp) |
struct bu_vls * | bu_vls_vlsinit (void) |
char * | bu_vls_addr (const struct bu_vls *vp) |
const char * | bu_vls_cstr (const struct bu_vls *vp) |
void | bu_vls_extend (struct bu_vls *vp, size_t extra) |
void | bu_vls_setlen (struct bu_vls *vp, size_t newlen) |
size_t | bu_vls_strlen (const struct bu_vls *vp) |
void | bu_vls_trunc (struct bu_vls *vp, int len) |
void | bu_vls_nibble (struct bu_vls *vp, b_off_t len) |
void | bu_vls_free (struct bu_vls *vp) |
void | bu_vls_vlsfree (struct bu_vls *vp) |
char * | bu_vls_strdup (const struct bu_vls *vp) |
char * | bu_vls_strgrab (struct bu_vls *vp) |
void | bu_vls_strcpy (struct bu_vls *vp, const char *s) |
void | bu_vls_strncpy (struct bu_vls *vp, const char *s, size_t n) |
void | bu_vls_strcat (struct bu_vls *vp, const char *s) |
void | bu_vls_strncat (struct bu_vls *vp, const char *s, size_t n) |
void | bu_vls_vlscat (struct bu_vls *dest, const struct bu_vls *src) |
void | bu_vls_vlscatzap (struct bu_vls *dest, struct bu_vls *src) |
int | bu_vls_strcmp (struct bu_vls *s1, struct bu_vls *s2) |
int | bu_vls_strncmp (struct bu_vls *s1, struct bu_vls *s2, size_t n) |
void | bu_vls_from_argv (struct bu_vls *vp, int argc, const char *argv[]) |
void | bu_vls_fwrite (FILE *fp, const struct bu_vls *vp) |
void | bu_vls_write (int fd, const struct bu_vls *vp) |
int | bu_vls_read (struct bu_vls *vp, int fd) |
int | bu_vls_gets (struct bu_vls *vp, FILE *fp) |
void | bu_vls_putc (struct bu_vls *vp, int c) |
void | bu_vls_trimspace (struct bu_vls *vp) |
void | bu_vls_printf (struct bu_vls *vls, const char *fmt,...) _BU_ATTR_PRINTF23 |
void | bu_vls_sprintf (struct bu_vls *vls, const char *fmt,...) _BU_ATTR_PRINTF23 |
void | bu_vls_spaces (struct bu_vls *vp, size_t cnt) |
size_t | bu_vls_print_positions_used (const struct bu_vls *vp) |
void | bu_vls_detab (struct bu_vls *vp) |
void | bu_vls_prepend (struct bu_vls *vp, const char *str) |
void | bu_vls_substr (struct bu_vls *dest, const struct bu_vls *src, size_t begin, size_t nchars) |
void | bu_vls_vprintf (struct bu_vls *vls, const char *fmt, va_list ap) |
bu_vls_vprintf implementation More... | |
const char * | bu_vls_encode (struct bu_vls *vp, const char *str) |
Routines to encode/decode strings into bu_vls structures. More... | |
const char * | bu_vls_decode (struct bu_vls *vp, const char *str) |
int | bu_vls_simplify (struct bu_vls *vp, const char *keep, const char *de_dup, const char *trim) |
Automatic string generation routines. More... | |
int | bu_vls_incr (struct bu_vls *name, const char *regex_str, const char *incr_spec, bu_vls_uniq_t uniq_test, void *data) |
Given a series of input strings and formatting parameters, construct an output version of an input string with contents arranged into multiple columns.
Variable length strings provide a way for programmers to easily handling dynamic strings - they serve a function similar to that of std::string in C++.
This frees the programmer from concerns about having character arrays large enough to hold strings.
Assumption: libc-provided sprintf() function is safe to use in parallel, on parallel systems.
#define BU_CK_VLS | ( | _vp | ) | BU_CKMAG(_vp, BU_VLS_MAGIC, "bu_vls") |
#define BU_VLS_INIT | ( | _vp | ) |
initializes a bu_vls struct without allocating any memory.
#define BU_VLS_INIT_ZERO { BU_VLS_MAGIC, NULL, 0, 0, 0 } |
#define BU_VLS_IS_INITIALIZED | ( | _vp | ) | (((struct bu_vls *)(_vp) != BU_VLS_NULL) && ((_vp)->vls_magic == BU_VLS_MAGIC)) |
returns truthfully whether a bu_vls struct has been initialized. is not reliable unless the struct has been allocated with BU_ALLOC(), bu_calloc(), or a previous call to bu_vls_init() or BU_VLS_INIT() has been made.
typedef int(* bu_vls_uniq_t) (struct bu_vls *v, void *data) |
callback type for bu_vls_incr()
int bu_column_print | ( | struct bu_vls * | o, |
struct bu_column_state * | s | ||
) |
Generate an output string based on the specified layout and contents in the bu_column_state s. Return the number of items printed, or -1 if there is an error.
Any uninitialized layout state will be calculated according to layout logic derived from BSD UNIX's column and ls commands. The following defaults are assumed or calculated, but pre-existing non-empty default values will be respected if set. Note that if any of the parameters in bu_column_state are changed, the caller must re-run bu_column_compute to re-generate the new layout. If column count and width are unset, they will be determined at print time.
Terminal width: 80 Column count: input dependent Column widths: input dependent Column alignment: left aligned Column delimiter: space Row prefix: none Row suffix: none Fill order: column first
int bu_column_add | ( | struct bu_column_state * | s, |
const char * | str | ||
) |
Add a string to the layout. Return codes:
-1 could not add successfully, str is not in layout 0 added n number of characters that could not be added. If column count and/or width are set to fixed values that prevent the full contents of str from being added, the return code tells the caller how many characters had to be truncated to make it fit in the layout. This will not happen with unset column count and width, since the layout will be finalized based on the inputs at print time.
int bu_column_set_alignment | ( | struct bu_column_state * | s, |
int | colnum, | ||
int | alignment | ||
) |
int bu_column_set_width | ( | struct bu_column_state * | s, |
int | colnum, | ||
int | width | ||
) |
int bu_column_clear | ( | struct bu_column_state * | s | ) |
int bu_column_reset | ( | struct bu_column_state * | s | ) |
void bu_vls_init | ( | struct bu_vls * | vp | ) |
No storage should be allocated at this point, and bu_vls_addr() must be able to live with that.
DEPRECATED void bu_vls_init_if_uninit | ( | struct bu_vls * | vp | ) |
DEPRECATED: use if (!vls) bu_vls_init(vls)
If a VLS is uninitialized, initialize it. If it is already initialized, leave it alone, caller wants to append to it.
struct bu_vls * bu_vls_vlsinit | ( | void | ) |
Allocate storage for a struct bu_vls, call bu_vls_init on it, and return the result. Allows for creation of dynamically allocated VLS strings.
char * bu_vls_addr | ( | const struct bu_vls * | vp | ) |
Return a pointer to the null-terminated string in the vls array. If no storage has been allocated yet, give back a valid string.
const char * bu_vls_cstr | ( | const struct bu_vls * | vp | ) |
Return a pointer to the null-terminated string in the vls array. If no storage has been allocated yet, give back a valid string. (At the moment this function is a mnemonically-named convenience function which returns a call to bu_vls_addr.)
void bu_vls_extend | ( | struct bu_vls * | vp, |
size_t | extra | ||
) |
Ensure that the provided VLS has at least 'extra' characters of space available. Additional space is allocated in minimum step sized amounts and may allocate more than requested.
void bu_vls_setlen | ( | struct bu_vls * | vp, |
size_t | newlen | ||
) |
Ensure that the vls has a length of at least 'newlen', and make that the current length.
Useful for subroutines that are planning on mucking with the data array themselves. Not advisable, but occasionally useful.
Does not change the offset from the front of the buffer, if any. Does not initialize the value of any of the new bytes.
size_t bu_vls_strlen | ( | const struct bu_vls * | vp | ) |
Return length of the string, in bytes, not including the null terminator.
void bu_vls_trunc | ( | struct bu_vls * | vp, |
int | len | ||
) |
Truncate string to at most 'len' characters. If 'len' is negative, trim off that many from the end. If 'len' is zero, don't release storage – user is probably just going to refill it again, e.g. with bu_vls_gets().
"Nibble" 'len' characters off the front of the string. Changes the length and offset; no data is copied.
'len' may be positive or negative. If negative, characters are un-nibbled.
void bu_vls_free | ( | struct bu_vls * | vp | ) |
Releases the memory used for the string buffer.
void bu_vls_vlsfree | ( | struct bu_vls * | vp | ) |
Releases the memory used for the string buffer and the memory for the vls structure
char * bu_vls_strdup | ( | const struct bu_vls * | vp | ) |
Return a dynamic copy of a vls. Memory for the string being returned is acquired using bu_malloc() implying the caller must bu_free() the returned string.
char * bu_vls_strgrab | ( | struct bu_vls * | vp | ) |
Like bu_vls_strdup(), but destructively grab the string from the source argument 'vp'. This is more efficient than bu_vls_strdup() for those instances where the source argument 'vp' is no longer needed by the caller, as it avoids a potentially long buffer copy.
The source string is destroyed, as if bu_vls_free() had been called.
void bu_vls_strcpy | ( | struct bu_vls * | vp, |
const char * | s | ||
) |
Empty the vls string, and copy in a regular string.
void bu_vls_strncpy | ( | struct bu_vls * | vp, |
const char * | s, | ||
size_t | n | ||
) |
Empty the vls string, and copy in a regular string, up to N bytes long.
void bu_vls_strcat | ( | struct bu_vls * | vp, |
const char * | s | ||
) |
Concatenate a new string onto the end of the existing vls string.
void bu_vls_strncat | ( | struct bu_vls * | vp, |
const char * | s, | ||
size_t | n | ||
) |
Concatenate a new string onto the end of the existing vls string.
Concatenate a new vls string onto the end of an existing vls string. The storage of the source string is not affected.
Concatenate a new vls string onto the end of an existing vls string. The storage of the source string is released (zapped).
Lexicographically compare two vls strings. Returns an integer greater than, equal to, or less than 0, according as the string s1 is greater than, equal to, or less than the string s2.
Lexicographically compare two vls strings up to n characters. Returns an integer greater than, equal to, or less than 0, according as the string s1 is greater than, equal to, or less than the string s2.
void bu_vls_from_argv | ( | struct bu_vls * | vp, |
int | argc, | ||
const char * | argv[] | ||
) |
Given and argc & argv pair, convert them into a vls string of space-separated words.
void bu_vls_fwrite | ( | FILE * | fp, |
const struct bu_vls * | vp | ||
) |
Write the VLS to the provided file pointer.
void bu_vls_write | ( | int | fd, |
const struct bu_vls * | vp | ||
) |
Write the VLS to the provided file descriptor.
int bu_vls_read | ( | struct bu_vls * | vp, |
int | fd | ||
) |
Read the remainder of a UNIX file onto the end of a vls.
Returns - nread number of characters read 0 if EOF encountered immediately -1 read error
int bu_vls_gets | ( | struct bu_vls * | vp, |
FILE * | fp | ||
) |
Append a newline-terminated string from the file pointed to by "fp" to the end of the vls pointed to by "vp". The newline from the file is read, but not stored into the vls.
The most common error is to forget to bu_vls_trunc(vp, 0) before reading the next line into the vls.
Returns - >=0 the length of the resulting vls -1 on EOF where no characters were read or added to the vls
void bu_vls_putc | ( | struct bu_vls * | vp, |
int | c | ||
) |
Append the given character to the vls.
void bu_vls_trimspace | ( | struct bu_vls * | vp | ) |
Remove leading and trailing white space from a vls string.
void bu_vls_printf | ( | struct bu_vls * | vls, |
const char * | fmt, | ||
... | |||
) |
Format a string into a vls using standard variable arguments.
s continues to be a regular null-terminated 'C' string (char *). V is a libbu variable-length string (struct bu_vls *).
Other format specifiers should behave identical to printf().
This routine appends to the given vls similar to how vprintf appends to stdout (see bu_vls_sprintf for overwriting the vls). The implementation ends up calling bu_vls_vprintf().
void bu_vls_sprintf | ( | struct bu_vls * | vls, |
const char * | fmt, | ||
... | |||
) |
Format a string into a vls, setting the vls to the given print specifier expansion. This routine truncates any existing vls contents beforehand (i.e. it doesn't append, see bu_vls_vprintf for appending to the vls).
s continues to be a regular 'C' string, null terminated. V is a pointer to a (struct bu_vls *) string.
void bu_vls_spaces | ( | struct bu_vls * | vp, |
size_t | cnt | ||
) |
Efficiently append 'cnt' spaces to the current vls.
size_t bu_vls_print_positions_used | ( | const struct bu_vls * | vp | ) |
Returns number of printed spaces used on final output line of a potentially multi-line vls. Useful for making decisions on when to line-wrap.
Accounts for normal UNIX tab-expansion: 1 2 3 4 1234567890123456789012345678901234567890 x x x x
0-7 --> 8, 8-15 --> 16, 16-23 --> 24, etc.
void bu_vls_detab | ( | struct bu_vls * | vp | ) |
Given a vls, return a version of that string which has had all "tab" characters converted to the appropriate number of spaces according to the UNIX tab convention.
void bu_vls_prepend | ( | struct bu_vls * | vp, |
const char * | str | ||
) |
Add a string to the beginning of the vls.
Copy a substring from a source vls into a destination vls
where:
begin - the index (0-based) of the beginning character position in the source vls nchars - the number of characters to copy
void bu_vls_vprintf | ( | struct bu_vls * | vls, |
const char * | fmt, | ||
va_list | ap | ||
) |
bu_vls_vprintf implementation
Format a string into a vls using a varargs list.
s continues to be a regular null-terminated 'C' string (char *). V is a libbu variable-length string (struct bu_vls *).
Other format specifiers should behave identical to printf().
This routine appends to the given vls similar to how vprintf appends to stdout (see bu_vls_sprintf for overwriting the vls).
const char * bu_vls_encode | ( | struct bu_vls * | vp, |
const char * | str | ||
) |
Routines to encode/decode strings into bu_vls structures.
given an input string, wrap the string in double quotes if there is a space and append it to the provided bu_vls. escape any existing double quotes.
TODO: consider a specifiable quote character and octal encoding instead of double quote wrapping. perhaps specifiable encode type: BU_ENCODE_QUOTE BU_ENCODE_OCTAL BU_ENCODE_XML
More thoughts on encode/decode - the nature of "quoting" is going to vary depending on the usage context and the language. For some applications, HEX or BASE64 may be appropriate. For others (like the problems with arbitrary strings in Tcl which initially motivated these functions) such wholesale encoding is not needed and it is just a subset of characters that must be escaped or otherwise identified.
Given the large set of possible scenarios, it definitely makes sense to allow an encoding specifying variable, and probably other optional variables (which may be NULL, depending on the encoding type) specifying active characters (that need quoting) and an escape character (or characters? does it take more than one in some scenarios? perhaps start and end of escape strings would be the most general?)
This probably makes sense as its own header given that is is really a feature on top of vls rather than something integral to vls itself - it would be workable (maybe even practical, if the final length of the encoded data can be pre-determined) to just work with char arrays: see bu_str_escape()
the behavior of this routine is subject to change but should remain a reversible operation when used in conjunction with bu_vls_decode().
returns a pointer to the encoded string (i.e., the substring held within the bu_vls)
const char * bu_vls_decode | ( | struct bu_vls * | vp, |
const char * | str | ||
) |
given an encoded input string, unwrap the string from any surrounding double quotes and unescape any embedded double quotes.
the behavior of this routine is subject to change but should remain the reverse operation of bu_vls_encode().
returns a pointer to the decoded string (i.e., the substring held within the bu_vls)
int bu_vls_simplify | ( | struct bu_vls * | vp, |
const char * | keep, | ||
const char * | de_dup, | ||
const char * | trim | ||
) |
Automatic string generation routines.
There are many situations where a calling program, given an input string, needs to produce automatically derived output strings that satisfy some criteria (incremented, special characters removed, etc.) The functions below perform this type of work. A problem frequently encountered when working with strings in BRL-CAD is the presence of special characters, characters active in the scripting language being applied, or other problematic contents that interfere with processing or readability of strings. This function takes a vls as an input and simplifies it as follows:
1) Reduce characters present to alpha-numeric characters and those characters supplied to the routine in the "keep" string. Substitute is performed as follows:
2) Collapses duplicate characters in the "de_dup" string.
3) Remove leading and trailing characters in the "trim' string.
Returns 0 if string was not altered, 1 otherwise.
int bu_vls_incr | ( | struct bu_vls * | name, |
const char * | regex_str, | ||
const char * | incr_spec, | ||
bu_vls_uniq_t | uniq_test, | ||
void * | data | ||
) |
A problem frequently encountered when generating names is generating names that are in some sense structured but avoid colliding. For example, given a geometry object named:
* engine_part.s *
An application wanting to make multiple copies of engine_part.s automatically might want to produce a list of names such as:
* engine_part.s-1, engine_part.s-2, engine_part.s-3, ... *
However, it is equally plausible that the desired pattern might be:
* engine_part_0010.s, engine_part_0020.s, engine_part_0030.s, ... *
This function implements an engine for generating the "next" name in a sequence, given an initial name supplied by the caller and (optionally) information to identify the incrementor in the string and the incrementing behavior desired. bu_vls_incr does not track any "state" for individual strings - all information is contained either in the current state of the input string itself or the incrementation specifier (more details on the latter can be found below.)
[in,out] | name | Contains the "seed" string for the name generation. Upon return the old string is cleared and the new one resides in name |
[in] | regex_str | Optional - user supplied regular expression for locating the incrementer substring. |
[in] | incr_spec | Optional - string of colon separated parameters defining function behavior. |
[in] | uniq_test | Optional - uniqueness testing function. |
[in] | data | Optional - data to pass to the uniq_test function call. |
bu_vls_incr uses regular expressions to identify the numerical part of a supplied string. By default, if no regular expression is supplied by the caller, bu_vls_incr will use a numerical sequence at the end of the string (more precisely, it will use the last sequence of numbers if and only if there are no non-numerical characters between that sequence and the end of the string.) If no appropriate match is found, the incrementer will be appended to the end of the string.
When no pre-existing number is found to start the sequence, the default behavior is to treat the existing string as the "0"-th item in the sequence. In such cases bu_vls_incr will thus return one, not zero, as the first incremented name in the sequence.
If the caller wishes to be more sophisticated about where incrementers are found in strings, they may supply their own regular expression that uses parenthesis bounded matchers to identify numerical identifiers. For example, the regular expression:
* ([-_:]*[0-9]+[-_:]*)[^0-9]*$ *
will instruct bu_vls_incr to define not just the last number but the last number and any immediately surrounding separator characters as the subset of the string to process. Combined with a custom incrementation specifier, this option allows calling programs to exercise broad flexibility in how they process strings.
The caller may optionally specify incrementation behavior with an incrementer specification string, which has the following form: "minwidth:init:max:step[:left_sepchar:right_sepchar]"
The table below explains the individual elements.
"minwidth:init:max:step[:left_sepchar:right_sepchar]" | |
---|---|
minwidth | specifies the minimum number of digits used when printing the incrementer substring |
init | specifies the initial minimum value to use when returning an incremented string. Overrides the string-based value if that value is less than the init value. |
max | specifies the maximum value of the incrementer - if the step takes the value past this number, the counter "rolls over" to the init value. |
step | value by which the incrementor value is increased |
left_sepchar | optional - specify a character to insert to the left of the numerical substring |
right_sepchar | optional - specify a character to insert to the right of the numerical substring |
In the case of minwidth, init, max, and step a '0' always indicates unspecified (i.e. "default") behavior. So, an incrementer specified as 0:0:0:0 would behave as follows:
minwidth: width found in string, or standard printf handling if nothing useful is found. For example, engine_part-001.s would by default be incremented to engine_part-002.s, preserving the prefix zeros.
init: from initial name string, or 0 if not found
max: LONG_MAX
step: 1
The last two separator chars are optional - they are useful if the caller wants to guarantee a separation between the active incremented substring and its surroundings. For example, the following would prefix the incrementer output with an underscore and add a suffix with a dash:
* 0:0:0:0:_:- *
To generate a suffix pattern, e.g.,:
* engine_part.s-1, engine_part.s-2, engine_part.s-3, ... *
Example code is as follows:
Here we show an infix case. There is no number present in the original string, we want the number before the .s suffix, we're incrementing by more than 1, we want four numerical digits in the string, and we want an underscore prefix spacer before the number:
* engine_part_0010.s, engine_part_0020.s, engine_part_0030.s, ... *
To set this up correctly we take advantage of the bu_path_component function and construct an initial "seed" string with a zero incrementer where we need it: