7 #include <stdarg.h> /* for RB_Say() */
20 /****f* ROBODoc/RB_FilePart [2.0x]
24 * char *RB_FilePart(char *file_name)
26 * return the basename (like Amiga/Dos/FilePart())
34 RB_FilePart (char *file_name)
39 if ((cur_char = file_name) != NULL)
41 for (; (c = *cur_char) != '\0'; ++cur_char)
43 if ((c == '/') || (c == ':'))
46 while ('/' == *cur_char)
57 /*** RB_File_Part ***/
61 /****f* ROBODoc/RB_Analyse_Defaults_File [3.0b]
63 * RB_Analyse_Defaults_file -- read default from defaults file
65 * RB_Analyse_Defaults_file
67 * Read the default vaules from the default file.
69 * FS: The use of while (!feof(defaults_file)) {
70 * is wrong here. Should check return value of
76 RB_Analyse_Defaults_File ()
80 /* defaults file in working directory? */
81 defaults_file = fopen ("robodoc.defaults", "r");
82 if (defaults_file == NULL)
84 /* try again from the directory from
85 which this application was started */
88 char path[_MAX_PATH], *c;
90 strcpy (path, whoami);
91 if ((c = strrchr (path, '\\')) != NULL)
96 strcat (path, "robodoc.defaults");
97 defaults_file = fopen (path, "r");
99 /* non-windows ... to be done */
100 #endif /* _MSC_VER */
102 if (defaults_file != NULL)
104 while (!feof (defaults_file))
110 fgets (line_buffer, MAX_LINE_LEN, defaults_file);
112 if (*line_buffer != '\n')
116 item_type = RB_Get_Item_Type (line_buffer);
117 if (item_type != NO_ITEM)
121 item_attributes[item_type] = ITEM_NAME_LARGE_FONT;
123 cur_char = line_buffer + strlen (item_names[item_type]);
124 for (; *cur_char && isspace (*cur_char); cur_char++);
128 for (values = cur_char;
129 *cur_char && !isspace (*cur_char);
136 item_attr = RB_Get_Item_Attr (values);
137 if (item_attr != MAKE_NORMAL)
139 RB_Say ("Default: %s = %s\n",
140 item_names[item_type],
141 item_attr_names[item_attr]);
142 item_attributes[item_type] |=
143 (1 << (item_attr + 1));
146 for (cur_char++; *cur_char && isspace (*cur_char);
152 fclose (defaults_file);
154 /* else { printf("%s: WARNING, robodoc.defaults file was not found.\n",
155 * whoami); printf("\t\tyou should really use one.\n"); } */
162 /****f* ROBODoc/RB_Skip_Remark_Marker [2.0e]
164 * RB_Skip_Remark_Marker
166 * text = RB_Skip_Remark_Marker (line_buffer)
169 * Scan and search for a recognized remark marker; skip past the
170 * marker to the body of the text
172 * This should be in generator.c
177 RB_Skip_Remark_Marker (char *line_buffer)
180 char *cur_char, *cur_mchar;
185 ((cur_mchar = remark_markers[marker]) != NULL) && !found;
188 for (found = TRUE, cur_char = line_buffer;
189 *cur_mchar && *cur_char && found;
190 cur_mchar++, cur_char++)
192 if (tolower(*cur_mchar) != tolower(*cur_char))
204 /****f* ROBODoc/RB_Slow_Sort [2.0]
206 * RB_Slow_Sort -- sort list of headers alphabetically
210 * Sorts the list of headers according to the header name
211 * in alphabetically fashion.
213 * This isn't a particularly speedy way of sorting.
220 struct RB_header *cur_header, *unsorted_headers, *bigger_header;
222 if ((unsorted_headers = first_header) != NULL)
225 for (first_header = NULL;
226 unsorted_headers->next_header;)
228 for (bigger_header = unsorted_headers,
229 cur_header = bigger_header->next_header;
231 cur_header = cur_header->next_header)
233 if (strcmp (cur_header->name, bigger_header->name) > 0)
234 bigger_header = cur_header;
236 RB_Remove_From_List (&unsorted_headers, bigger_header);
237 RB_Insert_In_List (&first_header, bigger_header);
239 RB_Insert_In_List (&first_header, unsorted_headers);
246 /****f* ROBODoc/RB_Insert_In_List [2.0]
248 * RB_Insert_In_List -- Insert a header in a list.
250 * RB_Insert_In_List (anchor,new_header)
252 * RB_Insert_In_List (struct RB_header **, struct RB_header *)
254 * Insert a node in a doubly linked list.
256 * anchor - pointer to the first node in the list.
257 * new_header - node to be inserted.
258 * MODIFICATION HISTORY
259 * 8. August 1995 -- optimized by koessi
266 RB_Insert_In_List (struct RB_header **anchor,
267 struct RB_header *new_header)
269 struct RB_header *old_header;
271 if ((old_header = *anchor) != NULL)
272 old_header->prev_header = new_header;
273 new_header->next_header = old_header;
274 new_header->prev_header = NULL;
275 *anchor = new_header;
278 /*** RB_Insert_In_List ***/
280 /****f* ROBODoc/RB_Reverse_List [2.0]
282 * RB_Reverse_List -- Insert a header in a list.
284 * RB_Reverse_List (void)
289 * MODIFICATION HISTORY
297 RB_Reverse_List (void)
299 struct RB_header *cur_header;
300 struct RB_header *temp_header;
302 for (cur_header = first_header;
306 first_header = cur_header;
307 temp_header = cur_header->next_header;
308 cur_header->next_header = cur_header->prev_header;
309 cur_header->prev_header = temp_header;
310 cur_header = temp_header;
317 /****f* ROBODoc/RB_Remove_From_List [2.0]
319 * RB_Remove_From_List -- remove a header from a list.
321 * RB_Remove_From_List (anchor, old_header)
322 * RB_Remove_From_List (struct RB_header **, struct RB_header *)
323 * MODIFICATION HISTORY
324 * 8. August 1995 -- optimized by koessi
329 RB_Remove_From_List (struct RB_header **anchor,
330 struct RB_header *old_header)
332 struct RB_header *next_header = old_header->next_header;
333 struct RB_header *prev_header = old_header->prev_header;
336 next_header->prev_header = prev_header;
338 prev_header->next_header = next_header;
340 *anchor = next_header;
346 /****f* ROBODoc/RB_Alloc_Header [2.01]
348 * RB_Alloc_Header -- oop
350 * struct RB_header *RB_Alloc_Header( void )
352 * allocate the struct RB_header
354 * struct RB_header * -- all attributes/pointers set to zero
363 RB_Alloc_Header (void)
365 struct RB_header *new_header;
367 if ((new_header = malloc (sizeof (struct RB_header))) != NULL)
368 memset (new_header, 0, sizeof (struct RB_header));
370 RB_Panic ("out of memory! [Alloc Header]\n");
377 /****f* ROBODoc/RB_Free_Header [2.01]
379 * RB_Free_Header -- oop
381 * void RB_Free_Header( struct RB_header *header )
383 * free struct RB_header and associated strings
385 * struct RB_header *header -- this one
389 * RB_Alloc_Header(), RB_Close_The_Shop()
394 RB_Free_Header (struct RB_header *header)
399 free (header->version);
402 if (header->contents)
403 free (header->contents);
411 /****i* ROBODoc/RB_WordLen [2.01]
413 * RB_WordLen -- like strlen
415 * int RB_WordLen( char *str )
417 * get the amount of bytes until next space
419 * char *str -- the word
421 * int -- length of the next word or 0
425 * RB_Find_Header_Name()
430 RB_WordLen (char *str)
435 for (len = 0; ((c = *str) != '\0') && !isspace (c) && (c != '\n');
443 /****i* ROBODoc/RB_StrDup [2.01]
447 * char *RB_StrDup( char *str )
449 * duplicate the given string
451 * char *str -- source
453 * char * -- destination
460 RB_StrDup (char *str)
463 if ((dupstr = malloc ((strlen (str) + 1) * sizeof (char))) != NULL)
464 strcpy (dupstr, str);
466 RB_Panic ("out of memory! [StrDup]\n");
473 /****f* ROBODoc/RB_CookStr [3.0h]
477 * char *RB_CookStr( char *str )
479 * duplicate the given string, massaging it for the current output_mode
481 * char *str -- source
483 * char * -- destination
487 * Doesn't try/need to be as aggressive as RB_Generate_Item_Body()
492 RB_CookStr (char *str)
494 static char work_buf[MAX_LINE_LEN];
502 for (i = 0; ((c = *str++) != '\0') && (i < (MAX_LINE_LEN - 1));)
507 if (i < (MAX_LINE_LEN - 1))
526 for (; (c = *str++) != '\0';)
528 if (isalnum (c) || c == '.' || c == '_')
536 return RB_StrDup (str);
540 return RB_StrDup (work_buf);
546 /****f* ROBODoc/RB_Say [2.01]
550 * void RB_Say( char *what, char *why, ... )
552 * say what's going on
554 * char *format -- formatstring
562 RB_Say (char *format,...)
566 if (course_of_action & DO_TELL)
568 va_start (ap, format);
569 printf ("%s: ", whoami);
570 vprintf (format, ap);
578 /****f* ROBODoc/RB_Panic [2.01]
580 * RB_Panic -- free resources and shut down
582 * void RB_Panic( char *format, char *why, ... )
584 * Print error message.
585 * Frees all resources used by robodoc.
588 * char *format -- formatstring
596 RB_Panic (char *format,...)
600 va_start (ap, format);
601 printf ("%s: FATAL ERROR - [line %d]\n", whoami, line_number);
602 printf ("%s: %s\n%s: ", whoami, line_buffer, whoami);
603 vprintf (format, ap);
604 printf ("%s: closing down...\n", whoami);
606 RB_Close_The_Shop ();
615 /****f* ROBODoc/RB_Str_Case_Cmp
619 * int RB_Str_Case_Cmp(char *, char *)
620 * result = RB_Str_Case_Cmp(s, t)
622 * Compare two strings, regardless of the case of the characters.
631 RB_Str_Case_Cmp (char *s, char *t)
633 for (; tolower (*s) == tolower (*t); s++, t++)
636 return (int) (tolower (*s) - tolower (*t));
642 /****f* ROBODoc/RB_TimeStamp
644 * RB_TimeStamp -- print a time stamp
649 RB_TimeStamp (FILE * f)
652 char timeBuffer[255];
655 strftime (timeBuffer, 255, "%a %b %d %H:%M:%S %Y\n", localtime (&ttp));
656 fprintf (f, "%s", timeBuffer);