]>
git.ipfire.org Git - thirdparty/gcc.git/blob - texinfo/info/makedoc.c
1 /* makedoc.c -- Make DOC.C and FUNS.H from input files. */
3 /* This file is part of GNU Info, a program for reading online documentation
6 Copyright (C) 1993 Free Software Foundation, Inc.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 Written by Brian Fox (bfox@ai.mit.edu). */
24 /* This program grovels the contents of the source files passed as arguments
25 and writes out a file of function pointers and documentation strings, and
26 a header file which describes the contents. This only does the functions
27 declared with DECLARE_INFO_COMMAND. */
31 #include <sys/types.h>
32 #if defined (HAVE_SYS_FILE_H)
34 #endif /* HAVE_SYS_FILE_H */
38 #if !defined (O_RDONLY)
39 #if defined (HAVE_SYS_FCNTL_H)
40 #include <sys/fcntl.h>
41 #else /* !HAVE_SYS_FCNTL_H */
43 #endif /* !HAVE_SYS_FCNTL_H */
44 #endif /* !O_RDONLY */
46 extern void *xmalloc (), *xrealloc ();
47 static void fatal_file_error ();
49 /* Name of the header file which receives the declarations of functions. */
50 static char *funs_filename
= "funs.h";
52 /* Name of the documentation to function pointer file. */
53 static char *doc_filename
= "doc.c";
55 static char *doc_header
[] = {
56 "/* doc.c -- Generated structure containing function names and doc strings.",
58 " This file was automatically made from various source files with the",
59 " command \"%s\". DO NOT EDIT THIS FILE, only \"%s.c\".",
63 static char *doc_header_1
[] = {
64 " An entry in the array FUNCTION_DOC_ARRAY is made for each command",
65 " found in the above files; each entry consists of a function pointer,",
66 #if defined (NAMED_FUNCTIONS)
67 " a string which is the user-visible name of the function,",
68 #endif /* NAMED_FUNCTIONS */
69 " and a string which documents its purpose. */",
72 "#include \"funs.h\"",
74 "FUNCTION_DOC function_doc_array[] = {",
79 /* How to remember the locations of the functions found so that Emacs
80 can use the information in a tag table. */
82 char *name
; /* Name of the tag. */
83 int line
; /* Line number at which it appears. */
84 long char_offset
; /* Character offset at which it appears. */
88 char *filename
; /* Name of the file containing entries. */
89 long entrylen
; /* Total number of characters in tag block. */
90 EMACS_TAG
**entries
; /* Entries found in FILENAME. */
95 EMACS_TAG_BLOCK
**emacs_tags
= (EMACS_TAG_BLOCK
**)NULL
;
96 int emacs_tags_index
= 0;
97 int emacs_tags_slots
= 0;
99 #define DECLARATION_STRING "\nDECLARE_INFO_COMMAND"
101 static void process_one_file ();
102 static void maybe_dump_tags ();
103 static FILE *must_fopen ();
112 FILE *funs_stream
, *doc_stream
;
114 for (i
= 1; i
< argc
; i
++)
115 if (strcmp (argv
[i
], "-tags") == 0)
123 funs_filename
= "/dev/null";
124 doc_filename
= "/dev/null";
127 funs_stream
= must_fopen (funs_filename
, "w");
128 doc_stream
= must_fopen (doc_filename
, "w");
130 fprintf (funs_stream
,
131 "/* %s -- Generated declarations for Info commands. */\n",
134 for (i
= 0; doc_header
[i
]; i
++)
136 fprintf (doc_stream
, doc_header
[i
], argv
[0], argv
[0]);
137 fprintf (doc_stream
, "\n");
141 " Source files groveled to make this file include:\n\n");
143 for (i
= 1; i
< argc
; i
++)
144 fprintf (doc_stream
, "\t%s\n", argv
[i
]);
146 fprintf (doc_stream
, "\n");
148 for (i
= 0; doc_header_1
[i
]; i
++)
149 fprintf (doc_stream
, "%s\n", doc_header_1
[i
]);
152 for (i
= 1; i
< argc
; i
++)
160 fprintf (doc_stream
, "/* Commands found in \"%s\". */\n", curfile
);
161 fprintf (funs_stream
, "\n/* Functions declared in \"%s\". */\n",
164 process_one_file (curfile
, doc_stream
, funs_stream
);
168 " { (VFunction *)NULL, (char *)NULL, (char *)NULL }\n};\n");
170 fclose (funs_stream
);
174 maybe_dump_tags (stdout
);
178 /* Dumping out the contents of an Emacs tags table. */
180 maybe_dump_tags (stream
)
185 /* Print out the information for each block. */
186 for (i
= 0; i
< emacs_tags_index
; i
++)
189 register EMACS_TAG_BLOCK
*block
;
190 register EMACS_TAG
*etag
;
194 block
= emacs_tags
[i
];
196 /* Calculate the length of the dumped block first. */
197 for (j
= 0; j
< block
->entries_index
; j
++)
200 etag
= block
->entries
[j
];
201 block_len
+= 3 + strlen (etag
->name
);
202 sprintf (digits
, "%d,%d", etag
->line
, etag
->char_offset
);
203 block_len
+= strlen (digits
);
206 /* Print out the defining line. */
207 fprintf (stream
, "\f\n%s,%d\n", block
->filename
, block_len
);
209 /* Print out the individual tags. */
210 for (j
= 0; j
< block
->entries_index
; j
++)
212 etag
= block
->entries
[j
];
214 fprintf (stream
, "%s,\177%d,%d\n",
215 etag
->name
, etag
->line
, etag
->char_offset
);
220 /* Keeping track of names, line numbers and character offsets of functions
221 found in source files. */
222 static EMACS_TAG_BLOCK
*
223 make_emacs_tag_block (filename
)
226 EMACS_TAG_BLOCK
*block
;
228 block
= (EMACS_TAG_BLOCK
*)xmalloc (sizeof (EMACS_TAG_BLOCK
));
229 block
->filename
= strdup (filename
);
231 block
->entries
= (EMACS_TAG
**)NULL
;
232 block
->entries_index
= 0;
233 block
->entries_slots
= 0;
238 add_tag_to_block (block
, name
, line
, char_offset
)
239 EMACS_TAG_BLOCK
*block
;
246 tag
= (EMACS_TAG
*)xmalloc (sizeof (EMACS_TAG
));
249 tag
->char_offset
= char_offset
;
250 add_pointer_to_array (tag
, block
->entries_index
, block
->entries
,
251 block
->entries_slots
, 50, EMACS_TAG
*);
254 /* Read the file represented by FILENAME into core, and search it for Info
255 function declarations. Output the declarations in various forms to the
256 DOC_STREAM and FUNS_STREAM. */
258 process_one_file (filename
, doc_stream
, funs_stream
)
260 FILE *doc_stream
, *funs_stream
;
262 int descriptor
, decl_len
;
263 char *buffer
, *decl_str
;
267 EMACS_TAG_BLOCK
*block
;
269 if (stat (filename
, &finfo
) == -1)
270 fatal_file_error (filename
);
272 descriptor
= open (filename
, O_RDONLY
, 0666);
274 if (descriptor
== -1)
275 fatal_file_error (filename
);
277 file_size
= (long) finfo
.st_size
;
278 buffer
= (char *)xmalloc (1 + file_size
);
279 read (descriptor
, buffer
, file_size
);
283 decl_str
= DECLARATION_STRING
;
284 decl_len
= strlen (decl_str
);
286 block
= make_emacs_tag_block (filename
);
295 #if defined (NAMED_FUNCTIONS)
297 #endif /* NAMED_FUNCTIONS */
299 for (; offset
< (file_size
- decl_len
); offset
++)
301 if (buffer
[offset
] == '\n')
304 line_start
= offset
+ 1;
307 if (strncmp (buffer
+ offset
, decl_str
, decl_len
) == 0)
318 /* Skip forward until we find the open paren. */
319 while (point
< file_size
)
321 if (buffer
[point
] == '\n')
324 line_start
= point
+ 1;
326 else if (buffer
[point
] == '(')
332 while (point
++ < file_size
)
334 if (!whitespace_or_newline (buffer
[point
]))
336 else if (buffer
[point
] == '\n')
339 line_start
= point
+ 1;
343 if (point
>= file_size
)
346 /* Now looking at name of function. Get it. */
347 for (offset
= point
; buffer
[offset
] != ','; offset
++);
348 func
= (char *)xmalloc (1 + (offset
- point
));
349 strncpy (func
, buffer
+ point
, offset
- point
);
350 func
[offset
- point
] = '\0';
352 /* Remember this tag in the current block. */
356 tag_name
= (char *)xmalloc (1 + (offset
- line_start
));
357 strncpy (tag_name
, buffer
+ line_start
, offset
- line_start
);
358 tag_name
[offset
- line_start
] = '\0';
359 add_tag_to_block (block
, tag_name
, line_number
, point
);
362 #if defined (NAMED_FUNCTIONS)
363 /* Generate the user-visible function name from the function's name. */
370 if (strncmp (name_start
, "info_", 5) == 0)
373 func_name
= strdup (name_start
);
375 /* Fix up "ea" commands. */
376 if (strncmp (func_name
, "ea_", 3) == 0)
378 char *temp_func_name
;
380 temp_func_name
= (char *)xmalloc (10 + strlen (func_name
));
381 strcpy (temp_func_name
, "echo_area_");
382 strcat (temp_func_name
, func_name
+ 3);
384 func_name
= temp_func_name
;
387 for (i
= 0; func_name
[i
]; i
++)
388 if (func_name
[i
] == '_')
391 #endif /* NAMED_FUNCTIONS */
393 /* Find doc string. */
396 while (point
< file_size
)
398 if (buffer
[point
] == '\n')
401 line_start
= point
+ 1;
404 if (buffer
[point
] == '"')
412 while (offset
< file_size
)
414 if (buffer
[offset
] == '\n')
417 line_start
= offset
+ 1;
420 if (buffer
[offset
] == '\\')
422 else if (buffer
[offset
] == '"')
429 if (offset
>= file_size
)
432 doc
= (char *)xmalloc (1 + (offset
- point
));
433 strncpy (doc
, buffer
+ point
, offset
- point
);
434 doc
[offset
- point
] = '\0';
436 #if defined (NAMED_FUNCTIONS)
437 fprintf (doc_stream
, " { %s, \"%s\", %s },\n", func
, func_name
, doc
);
439 #else /* !NAMED_FUNCTIONS */
440 fprintf (doc_stream
, " { %s, %s },\n", func
, doc
);
441 #endif /* !NAMED_FUNCTIONS */
443 fprintf (funs_stream
, "extern void %s ();\n", func
);
449 /* If we created any tags, remember this file on our global list. Otherwise,
450 free the memory already allocated to it. */
452 add_pointer_to_array (block
, emacs_tags_index
, emacs_tags
,
453 emacs_tags_slots
, 10, EMACS_TAG_BLOCK
*);
456 free (block
->filename
);
462 fatal_file_error (filename
)
465 fprintf (stderr
, "Couldn't manipulate the file %s.\n", filename
);
470 must_fopen (filename
, mode
)
471 char *filename
, *mode
;
475 stream
= fopen (filename
, mode
);
477 fatal_file_error (filename
);