File: enum.c

package info (click to toggle)
c2man 2.41-10
  • links: PTS
  • area: main
  • in suites: slink
  • size: 788 kB
  • ctags: 863
  • sloc: ansic: 6,559; sh: 5,095; yacc: 839; lex: 621; makefile: 226; perl: 81
file content (179 lines) | stat: -rw-r--r-- 3,890 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/* $Id: enum.c,v 2.0.1.1 1993/08/31 05:07:21 greyham Exp $
 * enumerator operations
 */
#include "c2man.h"
#include "strconcat.h"
#include "enum.h"
#include "manpage.h"

SymbolTable *enum_table;	/* enum symbol table */

/* we have to keep a list of EnumeratorLists because:
 * - unnamed EnumeratorLists can't go in the symbol table.
 * - a single EnumeratorList can be typedef'ed or enum'ed to more than one
 *   symbol, in which case it is referenced from the typedef_table or
 *   enum_table repectively more than once.
 */
EnumeratorList *first_list = NULL, **last_next_list = &first_list;

/* Initialize a list of enumerators.*/
EnumeratorList *
new_enumerator_list (enumerator)
     Enumerator *enumerator;
{
    Enumerator *p;
    EnumeratorList *list;
    
    list = (EnumeratorList *)safe_malloc(sizeof *list);
    *last_next_list = list;
    last_next_list = &list->next;
    list->next = NULL;
    
    p = (Enumerator *)safe_malloc(sizeof(Enumerator));
    *p = *enumerator;
    
    list->first = list->last = p;
    p->next = NULL;
    return list;
}

/* Add the enumerator to the list. */
void
add_enumerator_list (list, enumerator)
     EnumeratorList *list;
     Enumerator *enumerator;
{
    Enumerator *p;

    p = (Enumerator *)safe_malloc((unsigned)sizeof(Enumerator));
    *p = *enumerator;

    list->last->next = p;
    list->last = p;
    p->next = NULL;
}

/* Free storage used by the elements in the enumerator list. */
void
free_enumerator_list (enumerator_list)
     EnumeratorList *enumerator_list;
{
    Enumerator *p, *next;

    p = enumerator_list->first;
    while (p != NULL) {
	next = p->next;
	free_enumerator(p);
	free(p);
	p = next;
    }
}


void
new_enumerator(e, name, comment_before, comment_after)
     Enumerator *e;
     char *name;
     char *comment_before;
     char *comment_after;
{
    e-> name = name;
    e-> comment = comment_after ? comment_after : comment_before;
    e-> group_comment = comment_before && comment_after ? comment_before : NULL;
}

/* Free the storage used by the enumerator.*/
void
free_enumerator (param)
     Enumerator *param;
{
    free(param->name);
    safe_free(param->comment);
    safe_free(param->group_comment);
}

/* add a comment to the last enumerator in the list */
int
comment_last_enumerator(list, comment)
     EnumeratorList *list;
     char *comment;
{
    if (list->last->comment)
    {
	if (list->last->group_comment)
	{
	    enumerator_error(list->last->name);
	    free(comment);
	    return 0;
	}

	list->last->group_comment = list->last->comment;
    }

    list->last->comment = comment;
    return 1;
}

/* enum namespace management */
void add_enum_symbol(name, enum_list)
     char *name;
     EnumeratorList *enum_list;
{
    Symbol *entry = new_symbol(enum_table, name, DS_NONE);
    
    if (entry)
    {
	entry->value.enum_list = enum_list;
	entry->valtype = SYMVAL_ENUM;
    }
}

/* look for the Enumerator list associated with the symbol */
EnumeratorList *find_enum_symbol(name)
     char *name;
{
    Symbol *entry = find_symbol(enum_table, name);
    
    if (entry)
    	return entry->value.enum_list;
    else
    	return NULL;
}

void destroy_enum_lists()
{
    EnumeratorList *list, *next;
    
    /* free all the enumerator lists */
    for (list = first_list; list; list = next)
    {
	next = list->next;
	free_enumerator_list(list);
	free(list);
    }
}

/* create new typedef symbols */
void new_typedef_symbols(decl_spec, decl_list)
     DeclSpec *decl_spec;
     DeclaratorList *decl_list;
{
    Declarator *d;
    
    for (d = decl_list->first; d; d = d-> next)
    {
	Symbol *s = new_symbol(typedef_names, d->name, DS_NONE);
	
	if (s && decl_spec->enum_list)
	{
	    s->value.enum_list = decl_spec->enum_list;
	    s->valtype = SYMVAL_ENUM;
	}
    }
}

void enumerator_error(name)
     char *name;
{
    yyerror("enumerator '%s' has multiple comments", name);
}