15 /****** ROBODoc/RB_Analyse_Document [3.0i]
17 * RB_Analyse_Document -- scan document for headers and store them
19 * RB_Analyse_Document (document)
20 * RB_Analyse_Document (FILE *)
22 * Searches the document for headers. Stores information about
23 * any headers that are found in a linked list. Information
24 * that is stored includes, the name of the header, its version
25 * number, and its contents.
27 * document - a pointer to a file with the document to be
29 * the gobal buffer line_buffer.
31 * 1) A linked list pointed to by the global variable
32 * first_header that contains information about each
35 * Using fseek and ftell because gcc doesn't know fgetpos and fsetpos,
36 * on the sun unix system that I use.
43 RB_Analyse_Document (FILE * document)
50 (header_type = RB_Find_Marker (document)) != NO_HEADER;
53 struct RB_header *new_header;
57 ((header_type == INTERNAL_HEADER) &&
58 !(course_of_action & (DO_INCLUDE_INTERNAL | DO_INTERNAL_ONLY)))
60 ((header_type != INTERNAL_HEADER) &&
61 (course_of_action & DO_INTERNAL_ONLY))
63 (header_type == BLANK_HEADER)
69 new_header = RB_Alloc_Header ();
70 RB_Insert_In_List (&first_header, new_header);
71 new_header->type = header_type;
72 if ((new_header->name = RB_Find_Header_Name ()) != NULL)
74 RB_Say ("found header [line %5d]: \"%s\"\n",
75 line_number, new_header->name);
77 if ((new_header->function_name
78 = RB_Function_Name (new_header->name)) == NULL)
80 if ((new_header->function_name
81 = RB_Function_Name (line_buffer)) == NULL)
83 RB_Panic ("Can't determine the \"function\" name.\n");
85 cur_file_pos = (long) ftell (document);
86 if ((real_size = RB_Find_End_Marker (document,
92 fseek (document, cur_file_pos, 0);
93 if ((contents = malloc ((new_header->size +
97 fread (contents, new_header->size, sizeof (char), document);
99 contents[real_size] = '\0';
100 new_header->contents = contents;
101 new_header->size = real_size;
104 RB_Panic ("out of memory! [Alloc Header Contents]\n");
108 RB_Panic ("found header with no end marker \"%s\"\n",
114 RB_Panic ("found header marker but no name [line %d]\n",
120 if (header_type != BLANK_HEADER)
122 if ((name = RB_Find_Header_Name ()) != NULL)
124 new_header = RB_Alloc_Header ();
126 RB_Find_End_Marker (document, &new_header->size))
129 RB_Free_Header (new_header);
130 RB_Panic ("found header with no end marker \"%s\"\n", name);
134 RB_Free_Header (new_header);
139 RB_Panic ("found header marker but no name [line %d]\n",
147 /****** END RB_Analyse_Document *******/
152 /****f* ROBODoc/RB_Function_Name [2.0x]
154 * RB_Function_Name -- get pointer to the function name.
156 * char *RB_NamePart(char *header_name)
158 * A header name is consists of two parts. The module name and
159 * the function name. This returns a pointer to the function name.
160 * The name "function name" is a bit obsolete. It is really the name
161 * of any of objects that can be documented; classes, methods,
162 * variables, functions, projects, etc.
167 RB_Function_Name (char *header_name)
174 if ((cur_char = header_name) != NULL)
176 for (; (c = *cur_char) != '\0'; ++cur_char)
178 if ('/' == *cur_char)
188 temp = malloc((strlen(name) + 1) * sizeof(char));
196 /*** RB_Name_Part ***/
200 /****** ROBODoc/RB_Find_Marker [3.0h]
202 * RB_Find_Marker -- Search for header marker in document.
204 * header_type = RB_Find_Marker (document)
205 * int RB_Find_Marker (FILE *)
207 * Read document file line by line, and search each line for the
208 * any of the headers defined in the array header_markers
210 * document - pointer to the file to be searched.
211 * the gobal buffer line_buffer.
215 * (1) NO_HEADER - no header found, end of file reached
218 * (4) INTERNAL_HEADER
220 * Bad use of feof(), fgets().
227 RB_Find_Marker (FILE * document)
230 int marker, marker_type;
231 char *cur_char, *cur_mchar;
233 marker_type = NO_HEADER;
236 while (!feof (document) && !found)
239 fgets (line_buffer, MAX_LINE_LEN, document);
240 if (!feof (document))
244 ((cur_mchar = header_markers[marker]) != NULL) && !found;
247 for (found = TRUE, cur_char = line_buffer;
248 *cur_mchar && *cur_char && found;
249 cur_mchar++, cur_char++)
251 if (tolower(*cur_mchar) != tolower(*cur_char))
260 marker_type = MAIN_HEADER;
263 marker_type = GENERIC_HEADER;
266 marker_type = INTERNAL_HEADER;
269 marker_type = FUNCTION_HEADER;
272 marker_type = STRUCT_HEADER;
275 marker_type = CLASS_HEADER;
278 marker_type = METHOD_HEADER;
281 marker_type = CONSTANT_HEADER;
284 marker_type = VARIABLE_HEADER;
287 RB_Say ("%s: WARNING, [line %d] undefined headertype,"
288 " using GENERIC\n", whoami, line_number);
289 marker_type = GENERIC_HEADER;
294 if (!found || feof (document))
296 marker_type = NO_HEADER;
298 else if (marker_type == GENERIC_HEADER)
300 skip_while (*cur_char == '*');
301 if (*cur_char == '/')
303 marker_type = BLANK_HEADER;
309 /******** END RB_Find_Marker ******/
312 /****** ROBODoc/RB_Find_End_Marker [3.0h]
314 * RB_Find_End_Marker -- Search for end marker in document.
316 * result = RB_Find_End_Marker (document)
317 * int RB_Find_End_Marker (FILE *)
319 * Searches line by line till any of the markers in the
320 * array: end_markers is found.
322 * document - pointer to the file to be searched.
323 * int *total_size - external size
324 * the gobal buffer line_buffer.
326 * real_size if end marker was found
327 * 0 - no end marker was found
334 RB_Find_End_Marker (FILE * document, int *total_size)
340 char *cur_char, *cur_mchar;
342 while (!feof (document) && !found)
344 cur_char = line_buffer;
346 fgets (cur_char, MAX_LINE_LEN, document);
347 ++line_number; /* global linecounter *koessi */
349 line_len = strlen (cur_char);
350 real_size += line_len;
352 if (!feof (document))
355 ((cur_mchar = end_markers[marker]) != NULL) && !found;
358 for (found = TRUE, cur_char = line_buffer;
359 *cur_mchar && *cur_char && found;
360 cur_mchar++, cur_char++)
362 if (tolower(*cur_mchar) != tolower(*cur_char))
369 *total_size = real_size;
371 return real_size - line_len;
376 /***** RB_Find_End_Marker *****/
379 /****** ROBODoc/RB_Find_Header_Name [3.0b]
381 * RB_Find_Header_Name -- search for header name
383 * result = RB_Find_Header_Name ()
384 * char *RB_Find_Header_Name ()
386 * Searches the line buffer for the header name.
387 * It assumes that the header name follows after the
388 * header marker, seperated by one or more spaces, and terminated
389 * by one or more spaces or a '\n'.
390 * It allocates an array of chars and copies the name to this array.
392 * the gobal buffer line_buffer.
394 * pointer to the allocated array of chars that contains the name,
395 * terminated with a '\0'.
396 * NULL if no header name was found.
397 * MODIFICATION HISTORY
398 * 8. August 1995 -- optimized by koessi
400 * RB_Find_Function_Name(), RB_WordLen(), RB_StrDup()
405 RB_Find_Header_Name (void)
409 cur_char = line_buffer;
410 skip_while (*cur_char != '*');
411 skip_while (!isspace (*cur_char));
412 skip_while (isspace (*cur_char));
418 if (strchr(cur_char, '\n'))
419 *strchr(cur_char, '\n') = '\0';
421 len = RB_WordLen(cur_char);
423 n = calloc(len + 1, sizeof(*cur_char));
424 strncpy(n, cur_char, len);
430 /***** RB_Find_Header_Name *****/
433 /****** ROBODoc/RB_Find_Item [3.0b]
435 * RB_Find_Item -- find item in header contents.
437 * item_type = RB_Find_Item (next_line,item_line)
439 * int RB_Find_Item (char **, char **)
441 * Searches the header contents line by line, looking
442 * for an item Indicator.
444 * next_line - pointer to a pointer that points to line
445 * at which the search will start.
447 * next_line - pointer to a pointer that points to begin of the line
448 * after the line the item was found on.
449 * item_line - pointer to a pointer that points to the line the item
452 * item_type - one of possible items indicators.
457 RB_Find_Item (char **next_line, char **item_line)
459 char *cur_char = *next_line;
462 for (item_type = NO_ITEM;
463 *cur_char && (item_type == NO_ITEM);
466 *item_line = cur_char;
467 cur_char = RB_Skip_Remark_Marker (cur_char);
469 skip_while (isspace (*cur_char) && *cur_char != '\n');
470 if (isupper (*cur_char))
472 char *item_begin = cur_char;
475 skip_while (isupper (*cur_char));
477 if (isspace (*cur_char) && *cur_char)
479 skip_while (isspace (*cur_char) && *cur_char != '\n');
481 /* Item consists of two words ? */
482 if (isupper (*cur_char) && *cur_char)
484 skip_while (isupper (*cur_char));
486 skip_while (isspace (*cur_char) && *cur_char != '\n');
488 if (*cur_char == '\n')
490 char old_char = *item_end;
493 item_type = RB_Get_Item_Type (item_begin);
494 *item_end = old_char;
499 if (item_type == NO_ITEM)
507 /* advance item_line to end of comment block when we have no more items */
508 if (item_type == NO_ITEM)
510 *item_line = cur_char;
512 *next_line = cur_char;
516 /***** RB_Find_Item *****/
519 /****** ROBODoc/RRB_Number_Duplicate_Headers
521 * RB_Number_Duplicate_Headers -- number duplicate headers
523 * RB_Number_Duplicate_Headers (void)
525 * Extends the function name with an additional number if there
526 * are several components with the same name.
527 * Otherwise there will be labels with the same name in HTML
528 * which confuses the browser.
533 RB_Number_Duplicate_Headers (void)
535 struct RB_header *cur_header;
536 struct RB_header *dup_header;
537 for (cur_header = first_header;
539 cur_header = cur_header->next_header)
543 for (dup_header = cur_header->next_header;
545 dup_header = dup_header->next_header)
547 if (strcmp(cur_header->function_name,
548 dup_header->function_name) == 0) {
551 sprintf(number, "(%d)", nr);
552 new_name = malloc ((strlen(number) + 1 +
553 strlen(dup_header->function_name) + 1 ) * sizeof(char));
554 if (new_name == NULL)
555 RB_Panic ("out of memory! [Number Duplicates]\n");
556 sprintf(new_name, "%s%s", dup_header->function_name,
558 free(dup_header->function_name);
559 dup_header->function_name = new_name;
568 /****** ROBODoc/RB_Make_Index_Tables [3.0b]
570 * RB_Make_Index_Tables
572 * void RB_Make_Index_Tables (void)
574 * Creates sorted index tables of headers and links to speed up
575 * matching links later on.
579 * Modifies header_index & link_index
586 RB_Make_Index_Tables ()
588 int nr_of_headers, header;
589 int nr_of_links, link;
590 struct RB_link *cur_link;
591 struct RB_header *cur_header;
593 for (cur_header = first_header, nr_of_headers = 0;
595 cur_header = cur_header->next_header)
598 for (cur_link = first_link, nr_of_links = 0;
600 cur_link = cur_link->next_link)
607 RB_Say ("Allocating Header Index Table\n");
608 header_index = malloc (nr_of_headers * sizeof (struct RB_header **));
610 header_index_size = nr_of_headers;
612 RB_Panic ("out of memory! [Make Index Tables]\n");
614 /* Fill Index Table */
615 for (cur_header = first_header, header = 0;
617 cur_header = cur_header->next_header, header++)
618 header_index[header] = cur_header;
620 /* Sort Index Table */
621 RB_Say ("Sorting Header Index Table\n");
622 for (sort1 = 0; sort1 < nr_of_headers; sort1++)
624 struct RB_header *temp;
626 for (sort2 = sort1; sort2 < nr_of_headers; sort2++)
628 if (strcmp (header_index[sort1]->function_name,
629 header_index[sort2]->function_name) > 0)
631 temp = header_index[sort1];
632 header_index[sort1] = header_index[sort2];
633 header_index[sort2] = temp;
642 RB_Say ("Allocating Link Index Table\n");
643 link_index = malloc (nr_of_links * sizeof (struct RB_link **));
645 link_index_size = nr_of_links;
647 RB_Panic ("out of memory! [Make Index Tables]\n");
649 /* Fill Index Table */
650 for (cur_link = first_link, link = 0;
652 cur_link = cur_link->next_link, link++)
654 link_index[link] = cur_link;
657 /* Sort Index Table */
658 RB_Say ("Sorting Link Index Table\n");
659 for (sort1 = 0; sort1 < nr_of_links; sort1++)
661 struct RB_link *temp;
663 for (sort2 = sort1; sort2 < nr_of_links; sort2++)
665 if (strcmp (link_index[sort1]->label_name,
666 link_index[sort2]->label_name) > 0)
668 temp = link_index[sort1];
669 link_index[sort1] = link_index[sort2];
670 link_index[sort2] = temp;
677 /****** RB_Make_Index_Tables *****/