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 /* Same except remove trailing dot (.). -Pekka */
59 RB_FilePartStart (char *file_name)
64 if ((cur_char = file_name) != NULL)
66 for (; (c = *cur_char) != '\0'; ++cur_char)
68 if ((c == '/') || (c == ':'))
71 while ('/' == *cur_char)
80 if (strchr(file_name, '.'))
81 *strchr(file_name, '.') = '\0';
86 /*** RB_File_Part ***/
90 /****f* ROBODoc/RB_Analyse_Defaults_File [3.0b]
92 * RB_Analyse_Defaults_file -- read default from defaults file
94 * RB_Analyse_Defaults_file
96 * Read the default vaules from the default file.
98 * FS: The use of while (!feof(defaults_file)) {
99 * is wrong here. Should check return value of
105 RB_Analyse_Defaults_File ()
109 /* defaults file in working directory? */
110 defaults_file = fopen ("robodoc.defaults", "r");
111 if (defaults_file == NULL)
113 /* try again from the directory from
114 which this application was started */
117 char path[_MAX_PATH], *c;
119 strcpy (path, whoami);
120 if ((c = strrchr (path, '\\')) != NULL)
125 strcat (path, "robodoc.defaults");
126 defaults_file = fopen (path, "r");
128 /* non-windows ... to be done */
129 #endif /* _MSC_VER */
131 if (defaults_file != NULL)
133 while (!feof (defaults_file))
139 fgets (line_buffer, MAX_LINE_LEN, defaults_file);
141 if (*line_buffer != '\n')
145 item_type = RB_Get_Item_Type (line_buffer);
146 if (item_type != NO_ITEM)
150 item_attributes[item_type] = ITEM_NAME_LARGE_FONT;
152 cur_char = line_buffer + strlen (item_names[item_type]);
153 for (; *cur_char && isspace (*cur_char); cur_char++);
157 for (values = cur_char;
158 *cur_char && !isspace (*cur_char);
165 item_attr = RB_Get_Item_Attr (values);
166 if (item_attr != MAKE_NORMAL)
168 RB_Say ("Default: %s = %s\n",
169 item_names[item_type],
170 item_attr_names[item_attr]);
171 item_attributes[item_type] |=
172 (1 << (item_attr + 1));
175 for (cur_char++; *cur_char && isspace (*cur_char);
181 fclose (defaults_file);
183 /* else { printf("%s: WARNING, robodoc.defaults file was not found.\n",
184 * whoami); printf("\t\tyou should really use one.\n"); } */
191 /****f* ROBODoc/RB_Skip_Remark_Marker [2.0e]
193 * RB_Skip_Remark_Marker
195 * text = RB_Skip_Remark_Marker (line_buffer)
198 * Scan and search for a recognized remark marker; skip past the
199 * marker to the body of the text
201 * This should be in generator.c
206 RB_Skip_Remark_Marker (char *line_buffer)
209 char *cur_char, *cur_mchar;
214 ((cur_mchar = remark_markers[marker]) != NULL) && !found;
217 for (found = TRUE, cur_char = line_buffer;
218 *cur_mchar && *cur_char && found;
219 cur_mchar++, cur_char++)
221 if (tolower(*cur_mchar) != tolower(*cur_char))
233 /****f* ROBODoc/RB_Slow_Sort [2.0]
235 * RB_Slow_Sort -- sort list of headers alphabetically
239 * Sorts the list of headers according to the header name
240 * in alphabetically fashion.
242 * This isn't a particularly speedy way of sorting.
249 struct RB_header *cur_header, *unsorted_headers, *bigger_header;
251 if ((unsorted_headers = first_header) != NULL)
254 for (first_header = NULL;
255 unsorted_headers->next_header;)
257 for (bigger_header = unsorted_headers,
258 cur_header = bigger_header->next_header;
260 cur_header = cur_header->next_header)
262 if (strcmp (cur_header->name, bigger_header->name) > 0)
263 bigger_header = cur_header;
265 RB_Remove_From_List (&unsorted_headers, bigger_header);
266 RB_Insert_In_List (&first_header, bigger_header);
268 RB_Insert_In_List (&first_header, unsorted_headers);
275 /****f* ROBODoc/RB_Insert_In_List [2.0]
277 * RB_Insert_In_List -- Insert a header in a list.
279 * RB_Insert_In_List (anchor,new_header)
281 * RB_Insert_In_List (struct RB_header **, struct RB_header *)
283 * Insert a node in a doubly linked list.
285 * anchor - pointer to the first node in the list.
286 * new_header - node to be inserted.
287 * MODIFICATION HISTORY
288 * 8. August 1995 -- optimized by koessi
295 RB_Insert_In_List (struct RB_header **anchor,
296 struct RB_header *new_header)
298 struct RB_header *old_header;
300 if ((old_header = *anchor) != NULL)
301 old_header->prev_header = new_header;
302 new_header->next_header = old_header;
303 new_header->prev_header = NULL;
304 *anchor = new_header;
307 /*** RB_Insert_In_List ***/
309 /****f* ROBODoc/RB_Reverse_List [2.0]
311 * RB_Reverse_List -- Insert a header in a list.
313 * RB_Reverse_List (void)
318 * MODIFICATION HISTORY
326 RB_Reverse_List (void)
328 struct RB_header *cur_header;
329 struct RB_header *temp_header;
331 for (cur_header = first_header;
335 first_header = cur_header;
336 temp_header = cur_header->next_header;
337 cur_header->next_header = cur_header->prev_header;
338 cur_header->prev_header = temp_header;
339 cur_header = temp_header;
346 /****f* ROBODoc/RB_Remove_From_List [2.0]
348 * RB_Remove_From_List -- remove a header from a list.
350 * RB_Remove_From_List (anchor, old_header)
351 * RB_Remove_From_List (struct RB_header **, struct RB_header *)
352 * MODIFICATION HISTORY
353 * 8. August 1995 -- optimized by koessi
358 RB_Remove_From_List (struct RB_header **anchor,
359 struct RB_header *old_header)
361 struct RB_header *next_header = old_header->next_header;
362 struct RB_header *prev_header = old_header->prev_header;
365 next_header->prev_header = prev_header;
367 prev_header->next_header = next_header;
369 *anchor = next_header;
375 /****f* ROBODoc/RB_Alloc_Header [2.01]
377 * RB_Alloc_Header -- oop
379 * struct RB_header *RB_Alloc_Header( void )
381 * allocate the struct RB_header
383 * struct RB_header * -- all attributes/pointers set to zero
392 RB_Alloc_Header (void)
394 struct RB_header *new_header;
396 if ((new_header = malloc (sizeof (struct RB_header))) != NULL)
397 memset (new_header, 0, sizeof (struct RB_header));
399 RB_Panic ("out of memory! [Alloc Header]\n");
406 /****f* ROBODoc/RB_Free_Header [2.01]
408 * RB_Free_Header -- oop
410 * void RB_Free_Header( struct RB_header *header )
412 * free struct RB_header and associated strings
414 * struct RB_header *header -- this one
418 * RB_Alloc_Header(), RB_Close_The_Shop()
423 RB_Free_Header (struct RB_header *header)
428 free (header->version);
431 if (header->contents)
432 free (header->contents);
440 /****i* ROBODoc/RB_WordLen [2.01]
442 * RB_WordLen -- like strlen
444 * int RB_WordLen( char *str )
446 * get the amount of bytes until next space
448 * char *str -- the word
450 * int -- length of the next word or 0
454 * RB_Find_Header_Name()
459 RB_WordLen (char *str)
464 for (len = 0; ((c = *str) != '\0') && !isspace (c) && (c != '\n');
472 /****i* ROBODoc/RB_StrDup [2.01]
476 * char *RB_StrDup( char *str )
478 * duplicate the given string
480 * char *str -- source
482 * char * -- destination
489 RB_StrDup (char *str)
492 if ((dupstr = malloc ((strlen (str) + 1) * sizeof (char))) != NULL)
493 strcpy (dupstr, str);
495 RB_Panic ("out of memory! [StrDup]\n");
502 /****f* ROBODoc/RB_CookStr [3.0h]
506 * char *RB_CookStr( char *str )
508 * duplicate the given string, massaging it for the current output_mode
510 * char *str -- source
512 * char * -- destination
516 * Doesn't try/need to be as aggressive as RB_Generate_Item_Body()
521 RB_CookStr (char *str)
523 static char work_buf[MAX_LINE_LEN];
531 for (i = 0; ((c = *str++) != '\0') && (i < (MAX_LINE_LEN - 1));)
536 if (i < (MAX_LINE_LEN - 1))
555 for (; (c = *str++) != '\0';)
557 if (isalnum (c) || c == '.' || c == '_')
565 return RB_StrDup (str);
569 return RB_StrDup (work_buf);
575 /****f* ROBODoc/RB_Say [2.01]
579 * void RB_Say( char *what, char *why, ... )
581 * say what's going on
583 * char *format -- formatstring
591 RB_Say (char *format,...)
595 if (course_of_action & DO_TELL)
597 va_start (ap, format);
598 printf ("%s: ", whoami);
599 vprintf (format, ap);
607 /****f* ROBODoc/RB_Panic [2.01]
609 * RB_Panic -- free resources and shut down
611 * void RB_Panic( char *format, char *why, ... )
613 * Print error message.
614 * Frees all resources used by robodoc.
617 * char *format -- formatstring
625 RB_Panic (char *format,...)
629 va_start (ap, format);
630 printf ("%s: FATAL ERROR - [line %d]\n", whoami, line_number);
631 printf ("%s: %s\n%s: ", whoami, line_buffer, whoami);
632 vprintf (format, ap);
633 printf ("%s: closing down...\n", whoami);
635 RB_Close_The_Shop ();
644 /****f* ROBODoc/RB_Str_Case_Cmp
648 * int RB_Str_Case_Cmp(char *, char *)
649 * result = RB_Str_Case_Cmp(s, t)
651 * Compare two strings, regardless of the case of the characters.
660 RB_Str_Case_Cmp (char *s, char *t)
662 for (; tolower (*s) == tolower (*t); s++, t++)
665 return (int) (tolower (*s) - tolower (*t));
671 /****f* ROBODoc/RB_TimeStamp
673 * RB_TimeStamp -- print a time stamp
678 RB_TimeStamp (FILE * f)
681 char timeBuffer[255];
684 strftime (timeBuffer, 255, "%a %b %d %H:%M:%S %Y\n", localtime (&ttp));
685 fprintf (f, "%s", timeBuffer);