29 #ifdef DEBUG_VARIABLE_TOKENIZER
31 #define LOG(to_print) printf("%s\n", astring(to_print).s());
36 using namespace basis;
42 variable_tokenizer::variable_tokenizer(
int max_bits)
56 _assignments(new
astring(assignment)),
57 _separators(new
astring(separator)),
66 const astring "es,
bool nesting,
int max_bits)
68 _assignments(new
astring(assignment)),
69 _separators(new
astring(separator)),
92 WHACK(_implementation);
100 { *_comments = comments; }
109 {
return !!_implementation->
find(name); }
119 if (
this == &to_copy)
return *
this;
120 *_implementation = *to_copy._implementation;
121 *_separators = *to_copy._separators;
122 *_assignments = *to_copy._assignments;
123 *_quotes = *to_copy._quotes;
124 _nesting = to_copy._nesting;
125 _add_spaces = to_copy._add_spaces;
132 if (!found)
return "";
149 && (astring::matches(*_separators,
'\n')
150 || astring::matches(*_separators,
'\r')) )
return true;
151 return astring::matches(*_separators, to_check);
155 {
return astring::matches(*_assignments, to_check); }
158 {
return astring::matches(*_quotes, to_check); }
161 {
return astring::matches(*_comments, to_check); }
163 #define COOL to_tokenize.length()
168 current = to_tokenize[0]; \
169 to_tokenize.zap(0, 0); \
175 astring to_tokenize(to_tokenize_in);
180 bool just_ate_blank_line =
false;
192 while (
COOL && parser_bits::white_space(current)) {
194 if (!parser_bits::white_space(current)) {
206 if (parser_bits::white_space_no_cr(current))
210 bool handle_as_comment =
false;
214 just_ate_blank_line =
false;
218 handle_as_comment =
true;
223 just_ate_blank_line =
true;
231 _implementation->
add(name, value);
233 LOG(
astring(
"got comment: ") + name +
" -> " + value);
237 just_ate_blank_line =
false;
250 if (!
separator(current) && !parser_bits::white_space(current) )
252 LOG(
astring(
"last add: ") + name +
" -> " + value);
253 _implementation->
add(name, value);
258 while (
COOL && parser_bits::white_space_no_cr(current))
CHOP;
260 bool found_assignment =
false;
264 found_assignment =
true;
268 while (
COOL && parser_bits::white_space_no_cr(current))
CHOP;
276 bool ignore_separator =
false;
278 if (!q_stack.
size()) {
280 ignore_separator =
true;
281 q_stack.
push(current);
282 }
else if (current == q_stack.
top()) {
288 ignore_separator =
true;
295 q_stack.
push(current);
298 ignore_separator =
true;
300 }
else if (q_stack.
size()) {
303 ignore_separator =
true;
307 if (!ignore_separator &&
separator(current)) {
316 if (!
separator(current) && !parser_bits::white_space(current) ) {
320 if (found_assignment && !value) {
330 while (parser_bits::white_space_no_cr(name[name.
end()]))
334 while (parser_bits::white_space(value[value.
end()]))
337 LOG(
astring(
"normal add: ") + name +
" -> " + value);
338 _implementation->
add(name, value);
339 just_ate_blank_line =
true;
353 for (
int i = 0; i < _separators->
length(); i++) {
354 char sep = _separators->
get(i);
364 bool added_sep =
false;
365 for (
int i = 0; i < _implementation->
symbols(); i++) {
367 if (!string_table::is_comment(_implementation->
name(i))) {
369 accumulator += _implementation->
name(i);
370 if (_implementation->operator [](i).t()) {
371 if (_add_spaces) accumulator +=
" ";
372 accumulator += _assignments->
get(0);
373 if (_add_spaces) accumulator +=
" ";
374 accumulator += _implementation->operator [](i);
378 if (_implementation->operator [](i).t())
379 accumulator += _implementation->operator [](i);
383 accumulator += parser_bits::platform_eol_to_chars();
386 accumulator += _separators->
get(0);
392 accumulator.
zap(accumulator.
end() - 1, accumulator.
end());
a_sprintf is a specialization of astring that provides printf style support.
Provides a dynamically resizable ASCII character string.
bool t() const
t() is a shortcut for the string being "true", as in non-empty.
virtual char get(int index) const
a constant peek at the string's internals at the specified index.
virtual void zap(int start, int end)
Deletes the characters between "start" and "end" inclusively.
void insert(int position, const astring &to_insert)
Copies "to_insert" into "this" at the "position".
void reset()
clears out the contents string.
bool equal_to(const char *that) const
returns true if "that" is equal to this.
int end() const
returns the index of the last (non-null) character in the string.
int length() const
Returns the current length of the string.
Manages a bank of textual definitions of variables.
variable_tokenizer & operator=(const variable_tokenizer &to_copy)
makes this variable_tokenizer identical to "to_copy".
bool okay_for_variable_name(char to_check) const
true if "to_check" is a valid variable name character.
bool comment_char(char to_check) const
true if "to_check" is a registered comment character.
bool is_eol_a_separator() const
reports whether any of the separators are an EOL character.
const structures::string_table & table() const
provides a constant peek at the string_table holding the values.
bool exists(const basis::astring &name) const
returns true if the "name" exists in the variable_tokenizer.
void reset()
clears all of the entries out.
bool assignment(char to_check) const
true if "to_check" is a valid assignment operator.
const basis::astring & separators() const
provides a peek at the separators list.
const basis::astring & assignments() const
provides a peek at the assignments list.
basis::astring find(const basis::astring &name) const
locates the value for a variable named "name" if it exists.
variable_tokenizer(int max_bits=DEFAULT_MAX_BITS)
creates a variable_tokenizer with the default characters.
virtual ~variable_tokenizer()
bool separator(char to_check) const
true if "to_check" is a valid separator.
int symbols() const
returns the number of entries in the variable_tokenizer.
bool quote_mark(char to_check) const
true if "to_check" is a member of the quotes list.
basis::astring text_form() const
creates a new token list as a string of text.
void set_comment_chars(const basis::astring &comments)
establishes a set of characters in "comments" as the comment items.
const basis::astring & quotes() const
provides a peek at the quotes list.
bool parse(const basis::astring &to_tokenize)
parses the string using our established sentinel characters.
An abstraction that represents a stack data structure.
basis::outcome push(const contents &element)
Enters a new element onto the top of the stack.
int size() const
returns the size of the stack.
contents & top()
Returns the top element from the stack but doesn't change the stack.
stack_kinds kind() const
returns the type of stack that was constructed.
basis::outcome pop()
Removes the top element on the stack.
Provides a symbol_table that holds strings as the content.
const basis::astring & name(int index) const
returns the name held at the "index".
contents * find(const basis::astring &name) const
returns the contents held for "name" or NULL_POINTER if it wasn't found.
basis::outcome add(const basis::astring &name, const contents &storage)
Enters a symbol name into the table along with some contents.
int symbols() const
returns the number of symbols listed in the table.
#define FUNCDEF(func_in)
FUNCDEF sets the name of a function (and plugs it into the callstack).
The guards collection helps in testing preconditions and reporting errors.
void WHACK(contents *&ptr)
deletion with clearing of the pointer.
A dynamic container class that holds any kind of object via pointers.
bool is_eol(char to_check)
#define STRTAB_COMMENT_PREFIX
anything beginning with this is considered a comment.
const char * SPECIAL_VALUE