34 using namespace basis;
37 using namespace nodes;
47 #define BASE_LOG(s) program_wide_logger::get().log(s)
48 #define SHOW_LINE a_sprintf("line %d: ", _line_number)
50 #define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), SHOW_LINE + s)
51 #define DEADLY_LINE (astring(func) + a_sprintf(", line %d: ", _line_number))
73 for (
int i = _next_index; i <
elements(); i++) {
106 _last_parent(_mark_tree),
107 _last_node(_mark_tree),
108 _links_seen(new symbol_int),
116 WHACK(_category_names);
122 nick = astring::empty_string();
124 int indy = name.
find(
'[');
127 while ( (nick[nick.
end()] ==
' ') || (nick[nick.
end()] ==
']') )
129 name.
zap(indy, name.
end());
138 FUNCDEF(
"magic_category_comparison");
145 if (a_name.
iequals(b_name))
return true;
146 if (a_nick.
t() && a_nick.
iequals(b_name))
return true;
147 if (b_nick.
t() && a_name.
iequals(b_nick))
return true;
148 if (a_nick.
t() && b_nick.
t() && a_nick.
iequals(b_nick))
return true;
159 if (check.
compare(finding, index, 0, finding.
length(),
false)) {
160 index += finding.
length();
186 bool to_return = a.
compare(b, prune_a, prune_b, bigger_len,
false);
199 #ifdef DEBUG_MARKS_TREE
201 LOG(
astring(
"trying upwards find for parent node ") + parent_name);
205 #ifdef DEBUG_MARKS_TREE
206 LOG(
astring(
"upwards find failed seeking on last_parent node ")
216 #ifdef DEBUG_MARKS_TREE
217 LOG(
astring(
"upwards find failed seeking on last_node ") + parent_name);
226 LOG(
astring(
"failed to find parent node ") + parent_name);
231 _mark_tree->
attach(new_node);
237 #ifdef DEBUG_MARKS_TREE
238 LOG(
astring(
"found parent node ") + parent_name);
248 const astring &category_name = items[1];
249 const astring &parent_name = items[2];
253 LOG(
astring(
"category ") + category_name +
" under " + parent_name
254 +
" has extra fields!");
262 #ifdef DEBUG_MARKS_TREE
263 LOG(
astring(
"skipping parent node for ") + category_name);
270 break_name(category_name, main_name, nickname);
273 if (found1 || found2) {
275 if (found1) catnames = *found1;
277 if (!!catnames) catnames +=
" and ";
280 LOG(
astring(
"category name \"") + category_name
281 +
"\" in conflict with existing: " + catnames);
289 LOG(
astring(
"found existing category for main name: ") + main_name);
299 LOG(
astring(
"returning existing category for main name: ") + main_name
300 +
" as: " + fake_it->
name());
306 LOG(
astring(
"found existing category for nickname: ") + nickname);
316 LOG(
astring(
"returning existing category for nickname: ") + nickname
317 +
" as: " + fake_it->
name());
321 LOG(
"==> failure to find a match for either category!");
322 deadly_error(class_name(), func,
"collision resolution code failed; "
323 "please fix category error");
328 _category_names->
add(main_name, main_name);
329 if (!!nickname) _category_names->
add(nickname, nickname);
332 _last_parent = parent;
335 for (
int i = 0; i < parent->
branches(); i++) {
339 #ifdef DEBUG_MARKS_TREE
344 LOG(
astring(
"category ") + category_name +
" already exists under "
345 + parent_name +
".");
355 _last_node = new_node;
359 #ifdef DEBUG_MARKS_TREE
360 LOG(
astring(
"attaching node ") + category_name +
" to parent "
369 astring description = items[1];
370 astring parent_name = items[2];
372 if (items.
length() >= 4) url = items[3];
376 while (url[url.
end()] ==
'/') {
382 LOG(
astring(
"link ") + description +
" under " + parent_name
384 }
else if (items.
length() > 4) {
385 LOG(
astring(
"link ") + description +
" under " + parent_name
386 +
" has extra fields!");
391 _last_parent = parent;
397 LOG(
a_sprintf(
"Duplicate Link: line %d already has ", *found) + url);
413 astring current_line = current_line_in;
417 if (current_line.
contains(
"http:")) {
418 astring hold_curr = current_line;
419 int indy = current_line.
find(
"http:");
420 hold_curr.
zap(0, indy - 1);
421 current_line =
astring(
" "
422 "<a href=\"") + hold_curr +
"\">" + hold_curr +
"</a>";
423 }
else if (current_line.
t()) {
425 current_line.
zap(0, 0);
437 if (!input_file.
good())
439 "the input file could not be opened");
449 current_line.
zap(current_line.
end(), current_line.
end());
452 if (!current_line.
length()) {
457 }
else if (current_line[0] ==
'#') {
462 bool parsed = list_parsing::parse_csv_line(current_line, items);
465 astring(
"the line could not be parsed: ") + current_line);
467 LOG(
"bad formatting on this line.");
470 if (items[0].iequals(
"C")) {
473 LOG(
astring(
"failed to get a node for ") + items[1]);
475 }
else if (items[0].iequals(
"L")) {
479 astring(
"unknown format in line: ") + current_line);
bool case_insense_compare(const astring &a, const astring &b)
const astring & HTTP_HEAD
const int ESTIMATED_ELEMENTS
a_sprintf is a specialization of astring that provides printf style support.
int length() const
Returns the current reported length of the allocated C array.
Provides a dynamically resizable ASCII character string.
bool t() const
t() is a shortcut for the string being "true", as in non-empty.
virtual void zap(int start, int end)
Deletes the characters between "start" and "end" inclusively.
bool substring(astring &target, int start, int end) const
a version that stores the substring in an existing "target" string.
void strip_spaces(how_to_strip way=FROM_BOTH_SIDES)
removes excess space characters from string's beginning, end or both.
bool iequals(const astring &that) const
returns true if this is case-insensitively equal to "that".
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.
bool compare(const astring &to_compare, int start_first, int start_second, int count, bool case_sensitive) const
Compares "this" string with "to_compare".
int find(char to_find, int position=0, bool reverse=false) const
Locates "to_find" in "this".
bool contains(const astring &to_find) const
Returns true if "to_find" is contained in this string or false if not.
static int find_prune_point(const basis::astring &to_prune)
attempts to locate the real start of the root URL in "to_prune".
inner_mark_tree * process_category(const structures::string_array &items)
inner_mark_tree * find_parent(const basis::astring &parent_name)
void process_comment(const basis::astring ¤t_line_in)
int read_csv_file(const basis::astring &input_filename)
void process_link(const structures::string_array &items)
static bool advance(int &index, const basis::astring &check, const basis::astring &finding)
moves the "index" forward if the "finding" string is the head of "check".
static basis::astring prune_link_down(const basis::astring &to_prune)
static bool magic_category_comparison(const basis::astring &a, const basis::astring &b)
static bool excellent_link_comparator(const basis::astring &a, const basis::astring &b)
static void break_name(const basis::astring &to_break, basis::astring &name, basis::astring &nick)
inner_mark_tree & access_root()
Provides file managment services using the standard I/O support.
int getline(basis::abyte *buffer, int desired_size)
reads a line of text (terminated by a return) into the "buffer".
bool good()
returns true if the file seems to be in the appropriate desired state.
basis::astring _description
void add(link_record *new_rec, bool sort=true)
An object representing the interstitial cell in most linked data structures.
void sort()
sorts the sub-nodes of this symbol_tree.
symbol_tree * find(const basis::astring &to_find, find_methods how, basis::string_comparator_function *comp=NULL_POINTER)
returns the node specified by "to_find" or NULL_POINTER.
const basis::astring & name() const
returns the name of this node.
symbol_tree * branch(int index) const
returns the "index"th branch.
virtual int branches() const
Returns the number of branches currently connected to this tree.
virtual void attach(tree *new_branch)
Attaches the specified branch to the current tree.
int elements() const
the maximum number of elements currently allowed in this amorph.
basis::outcome put(int field, const link_record *data)
Enters an object into the field at index "field" in the amorph.
basis::outcome append(const link_record *data)
puts "data" on the end of this amorph.
basis::outcome insert(int position, int lines_to_add)
Adds "lines_to_add" indices to the amorph at the index "position".
link_record * borrow(int field)
Returns a pointer to the information at the index "field".
An array of strings with some additional helpful methods.
Provides a symbol_table that holds strings as the content.
Maintains a list of names, where each name has a type and some contents.
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.
#define non_continuable_error(c, f, i)
an extra piece of information used, if available, in bounds_halt below.
#define deadly_error(c, f, i)
#define NULL_POINTER
The value representing a pointer to nothing.
#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.
type maximum(type a, type b)
minimum returns the lesser of two values.
bool negative(const type &a)
negative returns true if "a" is less than zero.
const int KILOBYTE
Number of bytes in a kilobyte.
A platform independent way to obtain the timestamp of a file.
A logger that sends to the console screen using the standard output device.
A dynamic container class that holds any kind of object via pointers.
bool is_eol(char to_check)