BRL-CAD
Variable-length Strings

Given a series of input strings and formatting parameters, construct an output version of an input string with contents arranged into multiple columns. More...

Collaboration diagram for Variable-length Strings:

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_vlsbu_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)
 

Detailed Description

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.

Macro Definition Documentation

◆ BU_COLUMN_ALL

#define BU_COLUMN_ALL   -1

Definition at line 54 of file column.h.

◆ BU_COLUMN_ALIGN_LEFT

#define BU_COLUMN_ALIGN_LEFT   0

Definition at line 100 of file column.h.

◆ BU_COLUMN_ALIGN_RIGHT

#define BU_COLUMN_ALIGN_RIGHT   1

Definition at line 101 of file column.h.

◆ BU_COLUMN_ALIGN_CENTER_LEFT_BIAS

#define BU_COLUMN_ALIGN_CENTER_LEFT_BIAS   2

Definition at line 102 of file column.h.

◆ BU_COLUMN_ALIGN_CENTER_RIGHT_BIAS

#define BU_COLUMN_ALIGN_CENTER_RIGHT_BIAS   3

Definition at line 103 of file column.h.

◆ BU_VLS_NULL

#define BU_VLS_NULL   ((struct bu_vls *)0)

Definition at line 61 of file vls.h.

◆ BU_CK_VLS

#define BU_CK_VLS (   _vp)    BU_CKMAG(_vp, BU_VLS_MAGIC, "bu_vls")

assert the integrity of a bu_vls struct.

Definition at line 66 of file vls.h.

◆ BU_VLS_INIT

#define BU_VLS_INIT (   _vp)
Value:
{ \
(_vp)->vls_magic = BU_VLS_MAGIC; \
(_vp)->vls_str = NULL; \
(_vp)->vls_offset = (_vp)->vls_len = (_vp)->vls_max = 0; \
}
#define BU_VLS_MAGIC
Definition: magic.h:74

initializes a bu_vls struct without allocating any memory.

Definition at line 71 of file vls.h.

◆ BU_VLS_INIT_ZERO

#define BU_VLS_INIT_ZERO   { BU_VLS_MAGIC, NULL, 0, 0, 0 }

macro suitable for declaration statement initialization of a bu_vls struct. does not allocate memory.

Definition at line 81 of file vls.h.

◆ BU_VLS_IS_INITIALIZED

#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.

Definition at line 89 of file vls.h.

Typedef Documentation

◆ bu_vls_t

typedef struct bu_vls bu_vls_t

Definition at line 60 of file vls.h.

◆ bu_vls_uniq_t

typedef int(* bu_vls_uniq_t) (struct bu_vls *v, void *data)

callback type for bu_vls_incr()

Definition at line 507 of file vls.h.

Function Documentation

◆ bu_column_print()

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

◆ bu_column_add()

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.

◆ bu_column_set_alignment()

int bu_column_set_alignment ( struct bu_column_state s,
int  colnum,
int  alignment 
)

◆ bu_column_set_width()

int bu_column_set_width ( struct bu_column_state s,
int  colnum,
int  width 
)

◆ bu_column_clear()

int bu_column_clear ( struct bu_column_state s)

◆ bu_column_reset()

int bu_column_reset ( struct bu_column_state s)

◆ bu_vls_init()

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.

◆ bu_vls_init_if_uninit()

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.

◆ bu_vls_vlsinit()

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.

◆ bu_vls_addr()

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.

◆ bu_vls_cstr()

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.)

◆ bu_vls_extend()

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.

◆ bu_vls_setlen()

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.

◆ bu_vls_strlen()

size_t bu_vls_strlen ( const struct bu_vls vp)

Return length of the string, in bytes, not including the null terminator.

◆ bu_vls_trunc()

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().

◆ bu_vls_nibble()

void bu_vls_nibble ( struct bu_vls vp,
b_off_t  len 
)

"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.

◆ bu_vls_free()

void bu_vls_free ( struct bu_vls vp)

Releases the memory used for the string buffer.

◆ bu_vls_vlsfree()

void bu_vls_vlsfree ( struct bu_vls vp)

Releases the memory used for the string buffer and the memory for the vls structure

◆ bu_vls_strdup()

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.

◆ bu_vls_strgrab()

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.

◆ bu_vls_strcpy()

void bu_vls_strcpy ( struct bu_vls vp,
const char *  s 
)

Empty the vls string, and copy in a regular string.

◆ bu_vls_strncpy()

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.

◆ bu_vls_strcat()

void bu_vls_strcat ( struct bu_vls vp,
const char *  s 
)

Concatenate a new string onto the end of the existing vls string.

◆ bu_vls_strncat()

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.

◆ bu_vls_vlscat()

void bu_vls_vlscat ( struct bu_vls dest,
const struct bu_vls src 
)

Concatenate a new vls string onto the end of an existing vls string. The storage of the source string is not affected.

◆ bu_vls_vlscatzap()

void bu_vls_vlscatzap ( struct bu_vls dest,
struct bu_vls src 
)

Concatenate a new vls string onto the end of an existing vls string. The storage of the source string is released (zapped).

◆ bu_vls_strcmp()

int bu_vls_strcmp ( struct bu_vls s1,
struct bu_vls s2 
)

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.

◆ bu_vls_strncmp()

int bu_vls_strncmp ( struct bu_vls s1,
struct bu_vls s2,
size_t  n 
)

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.

◆ bu_vls_from_argv()

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.

◆ bu_vls_fwrite()

void bu_vls_fwrite ( FILE *  fp,
const struct bu_vls vp 
)

Write the VLS to the provided file pointer.

◆ bu_vls_write()

void bu_vls_write ( int  fd,
const struct bu_vls vp 
)

Write the VLS to the provided file descriptor.

◆ bu_vls_read()

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

◆ bu_vls_gets()

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

◆ bu_vls_putc()

void bu_vls_putc ( struct bu_vls vp,
int  c 
)

Append the given character to the vls.

◆ bu_vls_trimspace()

void bu_vls_trimspace ( struct bu_vls vp)

Remove leading and trailing white space from a vls string.

◆ bu_vls_printf()

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().

◆ bu_vls_sprintf()

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.

◆ bu_vls_spaces()

void bu_vls_spaces ( struct bu_vls vp,
size_t  cnt 
)

Efficiently append 'cnt' spaces to the current vls.

◆ bu_vls_print_positions_used()

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.

◆ bu_vls_detab()

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.

◆ bu_vls_prepend()

void bu_vls_prepend ( struct bu_vls vp,
const char *  str 
)

Add a string to the beginning of the vls.

◆ bu_vls_substr()

void bu_vls_substr ( struct bu_vls dest,
const struct bu_vls src,
size_t  begin,
size_t  nchars 
)

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

◆ bu_vls_vprintf()

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).

◆ bu_vls_encode()

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)

◆ bu_vls_decode()

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)

◆ bu_vls_simplify()

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:

  • Skip any character in the "keep" string
  • Replace diacritic characters(code >= 192) from the extended ASCII set with a specific mapping from the standard ASCII set. See discussion at: http://stackoverflow.com/questions/14094621/ for more about this.
  • Replace any non-keep characters that aren't replaced by other approaches with the '_' underscore character

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.

◆ bu_vls_incr()

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.)

Parameters
[in,out]nameContains the "seed" string for the name generation. Upon return the old string is cleared and the new one resides in name
[in]regex_strOptional - user supplied regular expression for locating the incrementer substring.
[in]incr_specOptional - string of colon separated parameters defining function behavior.
[in]uniq_testOptional - uniqueness testing function.
[in]dataOptional - data to pass to the uniq_test function call.

Incrementer Substring Identification

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.

Specifying Incrementor Behavior

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_sepcharoptional - 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:_:-
* 

Examples

To generate a suffix pattern, e.g.,:

* engine_part.s-1, engine_part.s-2, engine_part.s-3, ...
* 

Example code is as follows:

struct bu_vls name = BU_VLS_INIT_ZERO;
bu_vls_sprintf(&name, "engine_part.s");
for (int i = 0; i < 10; i++) {
bu_vls_incr(&name, NULL, "0:0:0:0:-", NULL, NULL);
bu_log("%s\n", bu_vls_cstr(&name));
}
bu_vls_free(&name);
int bu_log(const char *,...) _BU_ATTR_PRINTF12
void bu_vls_free(struct bu_vls *vp)
void bu_vls_sprintf(struct bu_vls *vls, const char *fmt,...) _BU_ATTR_PRINTF23
#define BU_VLS_INIT_ZERO
Definition: vls.h:81
int bu_vls_incr(struct bu_vls *name, const char *regex_str, const char *incr_spec, bu_vls_uniq_t uniq_test, void *data)
const char * bu_vls_cstr(const struct bu_vls *vp)
Definition: vls.h:53

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:

const char *estr = "engine_part.s"
struct bu_vls name = BU_VLS_INIT_ZERO;
bu_vls_sprintf(&name, "%s0.%s",
for (int i = 0; i < 10; i++) {
bu_vls_incr(&name, NULL, "4:10:0:10:_", NULL, NULL);
bu_log("%s\n", bu_vls_cstr(&name));
}
bu_vls_free(&name);
int bu_path_component(struct bu_vls *component, const char *path, bu_path_component_t type)
@ BU_PATH_EXTLESS
Definition: path.h:162
@ BU_PATH_EXT
Definition: path.h:161