-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathaudit2.c
More file actions
executable file
·150 lines (147 loc) · 3.2 KB
/
audit2.c
File metadata and controls
executable file
·150 lines (147 loc) · 3.2 KB
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
/*******************************************************************************
*
* ansi_c audit routines
* the only types supported by the ansi_c compiler:
*
* Input type1, type2: Return type:
* VOID, NUL CHAR
* CHAR, NUL CHAR
* INT, NUL INT
* UNSIGNED, CHAR UNSIGNED_CHAR
* UNSIGNED, INT UNSIGNED_INT
* UNSIGNED_CHAR, NUL UNSIGNED_CHAR
* UNSIGNED_INT, NUL UNSIGNED_INT
*
* also support typedef char identifier or typedef int identifier
*
* TYPEDEF, CHAR TYPEDEF_CHAR
* TYPEDEF, INT TYPEDEF_INT
*
******************************************************************************/
/*
* audit the type specifiers
* only support TYPEDEF CHAR or INT or
* support VOID, [UNSIGNED] CHAR or INT - everything to one byte CHAR
$$.token = audit_declaration_specifiers( $1.token, 0);
$$.token = audit_declaration_specifiers( $1.token, $2.token);
*/
int audit_declaration_specifiers( int type1, int type2)
{
switch( type1)
{
case VOID:
if( ! type2)
return CHAR;
break;
case CHAR:
if( ! type2)
return CHAR;
break;
case INT:
if( ! type2)
return INT;
break;
case UNSIGNED:
switch( type2)
{
case CHAR:
return UNSIGNED_CHAR;
case INT:
return UNSIGNED_INT;
}
break;
case UNSIGNED_CHAR:
if( ! type2)
return UNSIGNED_CHAR;
break;
case UNSIGNED_INT:
if( ! type2)
return UNSIGNED_INT;
break;
case TYPEDEF:
switch( type2)
{
case CHAR:
return TYPEDEF_CHAR;
case INT:
return TYPEDEF_INT;
}
break;
}
fprintf( stderr, "Error: unsupported data type: %s %s\n", tokens[ type1], tokens[ type2]);
data.errors++;
return CHAR;
}
/*******************************************************************************
*
* typedef table routines
*
******************************************************************************/
/*
* print the typedef table
*/
void print_typedef_table( void)
{
if( data.typedef_table)
{
printf( "typedef table:\n");
print_clips_list( data.typedef_table);
}
}
/*
* find the identifier in the typedef table linked list
*/
CLIPS *find_typedef( char *text, int length)
{
CLIPS *lists;
/*
* search the clips list using the buffer length and string compare to match
*/
for( lists = data.typedef_table; lists; lists = lists->next)
{
if( lists->length == length && ! strcmp( lists->buffer, text))
return( lists);
}
return( lists);
}
/*
* type an identifier in typedef table
$$.token = typedef_declaration( $1.token, $2.clips);
*/
CLIPS *typedef_declaration( int type_specifier, CLIPS *identifier)
{
CLIPS *clips;
int type;
/*
* first search for same identifier string
*/
clips = find_typedef( identifier->buffer, identifier->length);
if( clips)
{
fprintf( stderr, "Error: typedef already defined for: %s\n", clips->buffer);
data.errors++;
return( identifier);
}
switch( type_specifier)
{
case TYPEDEF_CHAR:
identifier->token = CHAR;
break;
case TYPEDEF_INT:
identifier->token = INT;
break;
default:
fprintf( stderr, "Warning typedef not supported for: %s\n", clips->buffer);
data.warnings++;
return( identifier);
}
/*
* attach it to the head of the typedef table list (LIFO)
*/
identifier->next = data.typedef_table;
data.typedef_table = identifier;
/*
* return
*/
return( (CLIPS*)0);
}