/* ebrowse.c --- parsing files for the ebrowse C++ browser
- Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001
- Free Software Foundation Inc.
+ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+ 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
- Author: Gerd Moellmann <gerd@gnu.org>
- Maintainer: FSF
-
This file is part of GNU Emacs.
GNU Emacs is free software; you can redistribute it and/or modify
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with GNU Emacs; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+ along with GNU Emacs; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
+
+#ifdef HAVE_STDLIB_H
#include <stdlib.h>
+#endif
+
+#ifdef HAVE_STRING_H
#include <string.h>
+#endif
+
#include <ctype.h>
#include <assert.h>
#include "getopt.h"
#define BUFFER_POS() (in - inbuffer)
-/* If current lookahead is CSTRING, the following points to the
+/* If current lookahead is CSTRING, the following points to the
first character in the string constant. Used for recognizing
extern "C". */
if (p == NULL)
{
yyerror ("out of memory", NULL);
- exit (1);
+ exit (EXIT_FAILURE);
}
return p;
}
if (p == NULL)
{
yyerror ("out of memory", NULL);
- exit (1);
+ exit (EXIT_FAILURE);
}
return p;
}
h %= TABLE_SIZE;
for (sym = class_table[h]; sym; sym = sym->next)
- if (streq (name, sym->name) && sym->namesp == scope)
+ if (streq (name, sym->name)
+ && ((!sym->namesp && !scope)
+ || (sym->namesp && scope
+ && streq (sym->namesp->name, scope->name))))
break;
if (sym == NULL)
{
lnk = (struct link *) xmalloc (sizeof *lnk);
lnk2 = (struct link *) xmalloc (sizeof *lnk2);
-
+
lnk->sym = sub;
lnk->next = p;
case SC_FRIEND:
list = &cls->friends;
break;
-
+
case SC_TYPE:
list = &cls->types;
break;
-
+
case SC_STATIC:
list = var ? &cls->static_vars : &cls->static_fns;
break;
-
+
default:
list = var ? &cls->vars : &cls->fns;
break;
a bit set giving additional information about the member (see the
F_* defines). */
-void
+void
add_global_decl (name, regexp, pos, hash, var, sc, flags)
char *name, *regexp;
int pos;
case SC_FRIEND:
list = &cls->friends;
break;
-
+
case SC_TYPE:
list = &cls->types;
break;
-
+
case SC_STATIC:
list = var ? &cls->static_vars : &cls->static_fns;
break;
-
+
default:
list = var ? &cls->vars : &cls->fns;
break;
struct sym *context;
{
struct sym *p = NULL;
-
+
for (p = all_namespaces; p; p = p->next)
{
if (streq (p->name, name) && (p->namesp == context))
return p;
}
-
+
/* Find namespace alias with name NAME. If not found return NULL. */
size * sizeof *namespace_stack);
namespace_stack_size = size;
}
-
+
namespace_stack[namespace_sp++] = current_namespace;
current_namespace = p;
}
struct sym *p;
{
int len;
-
+
if (p->namesp)
sym_scope_1 (p->namesp);
ensure_scope_buffer_room (len + 1);
strcat (scope_buffer, p->name);
scope_buffer_len += len;
-
+
if (HAS_FLAG (p->flags, F_TEMPLATE))
{
ensure_scope_buffer_room (3);
strcat (scope_buffer, "<>");
scope_buffer_len += 2;
}
-
+
return scope_buffer;
}
scope_buffer_size = 1024;
scope_buffer = (char *) xmalloc (scope_buffer_size);
}
-
+
*scope_buffer = '\0';
scope_buffer_len = 0;
-
+
if (p->namesp)
sym_scope_1 (p->namesp);
{
fputs (CLASS_STRUCT, fp);
PUTSTR (root->name, fp);
-
+
/* Print scope, if any. */
if (root->namesp)
PUTSTR (sym_scope (root), fp);
else
PUTSTR (NULL, fp);
-
+
/* Print flags. */
fprintf (fp, "%u", root->flags);
PUTSTR (root->filename, fp);
add_define (yytext, regexp, pos);
}
}
-
+
while (c && (c != '\n' || in_comment || in_string))
{
if (c == '\\')
}
else if (c == '"')
in_string = !in_string;
-
+
if (c == '\n')
INCREMENT_LINENO;
{
in = inbuffer;
yyline = 1;
-
+
if (yytext == NULL)
{
int size = 256;
case '{':
close = '}';
break;
-
+
case '(':
close = ')';
break;
-
+
case '<':
close = '>';
break;
-
+
case '[':
close = ']';
break;
-
+
default:
abort ();
}
}
}
+void
+skip_initializer ()
+{
+ for (;;)
+ {
+ switch (LA1)
+ {
+ case ';':
+ case ',':
+ case YYEOF:
+ return;
+
+ case '{':
+ case '[':
+ case '(':
+ skip_matching ();
+ break;
+
+ default:
+ MATCH ();
+ break;
+ }
+ }
+}
/* Build qualified namespace alias (A::B::c) and return it. */
{
switch (LA1)
{
- /* Skip over grouping parens or parameter lists in parameter
+ /* Skip over grouping parens or parameter lists in parameter
declarations. */
case '(':
skip_matching ();
{
char *last_id;
unsigned ident_type_hash = 0;
-
+
parse_qualified_param_ident_or_type (&last_id);
if (last_id)
{
case DOUBLE: case ENUM: case FLOAT: case INT:
case LONG: case SHORT: case SIGNED: case STRUCT:
case UNION: case UNSIGNED: case VOLATILE: case WCHAR:
- case ELLIPSIS:
+ case ELLIPSIS:
type_seen = 1;
hash = (hash << 1) ^ LA1;
MATCH ();
if (LOOKING_AT (')'))
{
MATCH ();
-
+
if (LOOKING_AT (CONST))
{
/* We can overload the same function on `const' */
case EXPLICIT:
SET_FLAG (flags, F_EXPLICIT);
goto typeseen;
-
+
case MUTABLE:
SET_FLAG (flags, F_MUTABLE);
goto typeseen;
{
regexp = matching_regexp ();
pos = BUFFER_POS ();
-
+
if (cls != NULL)
{
if (type_seen || !paren_seen)
add_member_decl (cls, id, regexp, pos, hash, 0, sc, vis, 0);
}
}
-
+
MATCH ();
print_info ();
}
parse_classname ()
{
struct sym *last_class = NULL;
-
+
while (LOOKING_AT (IDENT))
{
last_class = add_sym (yytext, last_class);
skip_matching ();
SET_FLAG (last_class->flags, F_TEMPLATE);
}
-
+
if (!LOOKING_AT (DCOLON))
break;
-
+
MATCH ();
}
static char *id = NULL;
char *s;
int len;
-
+
MATCH ();
if (LOOKING_AT2 (NEW, DELETE))
s = token_string (LA1);
MATCH ();
-
+
len = strlen (s) + 10;
if (len > id_size)
{
}
strcpy (id, s);
- /* Vector new or delete? */
+ /* Vector new or delete? */
if (LOOKING_AT ('['))
{
strcat (id, "[");
MATCH ();
-
+
if (LOOKING_AT (']'))
{
strcat (id, "]");
char *id = NULL;
size_t id_size = 0;
int enter = 0;
-
+
while (LOOKING_AT (IDENT))
{
int len = strlen (yytext) + 1;
settings. */
if ((tag != CLASS && !f_structs) || (nested && !f_nested_classes))
current = NULL;
- else
+ else
{
current = add_sym (yytext, containing);
current->pos = BUFFER_POS ();
{
switch (LA1)
{
- case VIRTUAL: case PUBLIC: case PROTECTED: case PRIVATE:
+ case VIRTUAL: case PUBLIC: case PROTECTED: case PRIVATE:
MATCH ();
break;
}
}
+/* Add to class *CLS information for the declaration of variable or
+ type *ID. If *CLS is null, this means a global declaration. SC is
+ the storage class of *ID. FLAGS is a bit set giving additional
+ information about the member (see the F_* defines). */
+
+void
+add_declarator (cls, id, flags, sc)
+ struct sym **cls;
+ char **id;
+ int flags, sc;
+{
+ if (LOOKING_AT2 (';', ','))
+ {
+ /* The end of a member variable or of an access declaration
+ `X::f'. To distinguish between them we have to know whether
+ type information has been seen. */
+ if (*id)
+ {
+ char *regexp = matching_regexp ();
+ int pos = BUFFER_POS ();
+
+ if (*cls)
+ add_member_defn (*cls, *id, regexp, pos, 0, 1, SC_UNKNOWN, flags);
+ else
+ add_global_defn (*id, regexp, pos, 0, 1, sc, flags);
+ }
+
+ MATCH ();
+ print_info ();
+ }
+ else if (LOOKING_AT ('{'))
+ {
+ if (sc == SC_TYPE && *id)
+ {
+ /* A named enumeration. */
+ char *regexp = matching_regexp ();
+ int pos = BUFFER_POS ();
+ add_global_defn (*id, regexp, pos, 0, 1, sc, flags);
+ }
+
+ skip_matching ();
+ print_info ();
+ }
+
+ xfree (*id);
+ *id = NULL;
+ *cls = NULL;
+}
/* Parse a declaration. */
sc = SC_TYPE;
MATCH ();
break;
-
+
case STATIC:
sc = SC_STATIC;
MATCH ();
}
case '=':
- /* Assumed to be the start of an initialization in this context.
- Skip over everything up to ';'. */
- skip_to (';');
+ /* Assumed to be the start of an initialization in this
+ context. */
+ skip_initializer ();
break;
+ case ',':
+ add_declarator (&cls, &id, flags, sc);
+ break;
+
case OPERATOR:
{
char *s = operator_name (&sc);
}
}
- if (LOOKING_AT (';'))
- {
- /* The end of a member variable or of an access declaration
- `X::f'. To distinguish between them we have to know whether
- type information has been seen. */
- if (id)
- {
- char *regexp = matching_regexp ();
- int pos = BUFFER_POS ();
-
- if (cls)
- add_member_defn (cls, id, regexp, pos, 0, 1, SC_UNKNOWN, flags);
- else
- add_global_defn (id, regexp, pos, 0, 1, sc, flags);
- }
-
- MATCH ();
- print_info ();
- }
- else if (LOOKING_AT ('{'))
- {
- if (sc == SC_TYPE && id)
- {
- /* A named enumeration. */
- regexp = matching_regexp ();
- pos = BUFFER_POS ();
- add_global_defn (id, regexp, pos, 0, 1, sc, flags);
- }
-
- skip_matching ();
- print_info ();
- }
-
- xfree (id);
+ add_declarator (&cls, &id, flags, sc);
}
for (;;)
{
char *prev_in = in;
-
+
switch (LA1)
{
case NAMESPACE:
{
char *namespace_name = xstrdup (yytext);
MATCH ();
-
+
if (LOOKING_AT ('='))
{
struct link *qna = match_qualified_namespace_alias ();
if (qna)
register_namespace_alias (namespace_name, qna);
-
+
if (skip_to (';') == ';')
MATCH ();
}
{
/* This is `extern "C"'. */
MATCH ();
-
+
if (LOOKING_AT ('{'))
{
MATCH ();
SET_FLAG (flags, F_EXTERNC);
}
break;
-
+
case TEMPLATE:
MATCH ();
SKIP_MATCHING_IF ('<');
case '}':
return 0;
-
+
default:
declaration (flags);
flags = start_flags;
{
char *start = path_list;
struct search_path *p;
-
+
while (*path_list && *path_list != PATH_LIST_SEPARATOR)
++path_list;
-
+
p = (struct search_path *) xmalloc (sizeof *p);
p->path = (char *) xmalloc (path_list - start + 1);
memcpy (p->path, start, path_list - start);
static int buffer_size;
struct search_path *path;
int flen = strlen (file) + 1; /* +1 for the slash */
-
+
filename = xstrdup (file);
for (path = search_path; path && fp == NULL; path = path->next)
buffer_size = max (len + 1, 2 * buffer_size);
buffer = (char *) xrealloc (buffer, buffer_size);
}
-
+
strcpy (buffer, path->path);
strcat (buffer, "/");
strcat (buffer, file);
fp = fopen (buffer, "r");
}
-
+
/* Try the original file name. */
if (fp == NULL)
fp = fopen (file, "r");
if (fp == NULL)
yyerror ("cannot open", NULL);
-
+
return fp;
}
int error;
{
puts (USAGE);
- exit (error ? 1 : 0);
+ exit (error ? EXIT_FAILURE : EXIT_SUCCESS);
}
version ()
{
printf ("ebrowse %s\n", VERSION);
- puts ("Copyright (C) 1992-1999, 2000, 2001 Free Software Foundation, Inc.");
+ puts ("Copyright (C) 1992-2006 Free Software Foundation, Inc.");
puts ("This program is distributed under the same terms as Emacs.");
- exit (0);
+ exit (EXIT_SUCCESS);
}
char *file;
{
FILE *fp;
-
+
fp = open_file (file);
if (fp)
- {
+ {
int nread, nbytes;
/* Give a progress indication if needed. */
inbuffer_size = nread + READ_CHUNK_SIZE + 1;
inbuffer = (char *) xrealloc (inbuffer, inbuffer_size);
}
-
+
nbytes = fread (inbuffer + nread, 1, READ_CHUNK_SIZE, fp);
if (nbytes <= 0)
break;
buffer[i++] = c;
}
-
+
if (c == EOF && i == 0)
return NULL;
-
+
if (i == buffer_size)
{
buffer_size = max (100, buffer_size * 2);
case 'p':
info_position = atoi (optarg);
break;
-
+
case 'n':
f_nested_classes = 0;
break;
case 'x':
f_regexps = 0;
break;
-
+
/* Add the name of a file containing more input files. */
case 'f':
if (n_input_files == input_filenames_size)
yyerror ("error getting size of file `%s'", out_filename);
else if (rc == 0)
yyerror ("file `%s' is empty", out_filename);
-
+
fclose (fp);
}
-
+
yyout = fopen (out_filename, f_append ? "a" : "w");
if (yyout == NULL)
{
yyerror ("cannot open output file `%s'", out_filename);
- exit (1);
+ exit (EXIT_FAILURE);
}
}
for (i = 0; i < n_input_files; ++i)
{
FILE *fp = fopen (input_filenames[i], "r");
-
+
if (fp == NULL)
yyerror ("cannot open input file `%s'", input_filenames[i]);
else
if (yyout != stdout)
fclose (yyout);
- return 0;
+ return EXIT_SUCCESS;
}
+/* arch-tag: fc03b4bc-91a9-4c3d-b3b9-12a77fa86dd8
+ (do not change this comment) */
-/* ebrowse.c ends here. */
+/* ebrowse.c ends here */