-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathlemon.c
192 lines (179 loc) · 5.13 KB
/
lemon.c
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
180
181
182
183
184
185
186
187
188
189
190
191
192
/*
** This file contains all sources (including headers) to the LEMON
** LALR(1) parser generator. The sources have been combined into a
** single file to make it easy to include LEMON in the source tree
** and Makefile of another program.
**
** The author of this program disclaims copyright.
*/
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <assert.h>
#define ISSPACE(X) isspace((unsigned char)(X))
#define ISDIGIT(X) isdigit((unsigned char)(X))
#define ISALNUM(X) isalnum((unsigned char)(X))
#define ISALPHA(X) isalpha((unsigned char)(X))
#define ISUPPER(X) isupper((unsigned char)(X))
#define ISLOWER(X) islower((unsigned char)(X))
#ifndef __WIN32__
# if defined(_WIN32) || defined(WIN32)
# define __WIN32__
# endif
#endif
#ifdef __WIN32__
#ifdef __cplusplus
extern "C" {
#endif
extern int access(const char *path, int mode);
#ifdef __cplusplus
}
#endif
#else
#include <unistd.h>
#endif
/* #define PRIVATE static */
#define PRIVATE
#ifdef TEST
#define MAXRHS 5 /* Set low to exercise exception code */
#else
#define MAXRHS 1000
#endif
extern void memory_error();
static int showPrecedenceConflict = 0;
static char *msort(char*,char**,int(*)(const char*,const char*));
/*
** Compilers are getting increasingly pedantic about type conversions
** as C evolves ever closer to Ada.... To work around the latest problems
** we have to define the following variant of strlen().
*/
#define lemonStrlen(X) ((int)strlen(X))
/*
** Compilers are starting to complain about the use of sprintf() and strcpy(),
** saying they are unsafe. So we define our own versions of those routines too.
**
** There are three routines here: lemon_sprintf(), lemon_vsprintf(), and
** lemon_addtext(). The first two are replacements for sprintf() and vsprintf().
** The third is a helper routine for vsnprintf() that adds texts to the end of a
** buffer, making sure the buffer is always zero-terminated.
**
** The string formatter is a minimal subset of stdlib sprintf() supporting only
** a few simply conversions:
**
** %d
** %s
** %.*s
**
*/
static void lemon_addtext(
char *zBuf, /* The buffer to which text is added */
int *pnUsed, /* Slots of the buffer used so far */
const char *zIn, /* Text to add */
int nIn, /* Bytes of text to add. -1 to use strlen() */
int iWidth /* Field width. Negative to left justify */
){
if( nIn<0 ) for(nIn=0; zIn[nIn]; nIn++){}
while( iWidth>nIn ){ zBuf[(*pnUsed)++] = ' '; iWidth--; }
if( nIn==0 ) return;
memcpy(&zBuf[*pnUsed], zIn, nIn);
*pnUsed += nIn;
while( (-iWidth)>nIn ){ zBuf[(*pnUsed)++] = ' '; iWidth++; }
zBuf[*pnUsed] = 0;
}
static int lemon_vsprintf(char *str, const char *zFormat, va_list ap){
int i, j, k, c;
int nUsed = 0;
const char *z;
char zTemp[50];
str[0] = 0;
for(i=j=0; (c = zFormat[i])!=0; i++){
if( c=='%' ){
int iWidth = 0;
lemon_addtext(str, &nUsed, &zFormat[j], i-j, 0);
c = zFormat[++i];
if( ISDIGIT(c) || (c=='-' && ISDIGIT(zFormat[i+1])) ){
if( c=='-' ) i++;
while( ISDIGIT(zFormat[i]) ) iWidth = iWidth*10 + zFormat[i++] - '0';
if( c=='-' ) iWidth = -iWidth;
c = zFormat[i];
}
if( c=='d' ){
int v = va_arg(ap, int);
if( v<0 ){
lemon_addtext(str, &nUsed, "-", 1, iWidth);
v = -v;
}else if( v==0 ){
lemon_addtext(str, &nUsed, "0", 1, iWidth);
}
k = 0;
while( v>0 ){
k++;
zTemp[sizeof(zTemp)-k] = (v%10) + '0';
v /= 10;
}
lemon_addtext(str, &nUsed, &zTemp[sizeof(zTemp)-k], k, iWidth);
}else if( c=='s' ){
z = va_arg(ap, const char*);
lemon_addtext(str, &nUsed, z, -1, iWidth);
}else if( c=='.' && memcmp(&zFormat[i], ".*s", 3)==0 ){
i += 2;
k = va_arg(ap, int);
z = va_arg(ap, const char*);
lemon_addtext(str, &nUsed, z, k, iWidth);
}else if( c=='%' ){
lemon_addtext(str, &nUsed, "%", 1, 0);
}else{
fprintf(stderr, "illegal format\n");
exit(1);
}
j = i+1;
}
}
lemon_addtext(str, &nUsed, &zFormat[j], i-j, 0);
return nUsed;
}
static int lemon_sprintf(char *str, const char *format, ...){
va_list ap;
int rc;
va_start(ap, format);
rc = lemon_vsprintf(str, format, ap);
va_end(ap);
return rc;
}
static void lemon_strcpy(char *dest, const char *src){
while( (*(dest++) = *(src++))!=0 ){}
}
static void lemon_strcat(char *dest, const char *src){
while( *dest ) dest++;
lemon_strcpy(dest, src);
}
/* a few forward declarations... */
struct rule;
struct lemon;
struct action;
static struct action *Action_new(void);
static struct action *Action_sort(struct action *);
#include "build.h"
#include "configlist.h"
#include "error.h"
#include "option.h"
#include "parse.h"
#include "plink.h"
#include "report.h"
#include "set.h"
#include "struct.h"
#include "table.h"
#include "action.c"
#include "build.c"
#include "configlist.c"
#include "error.c"
#include "main.c"
#include "msort.c"
#include "option.c"
#include "parse.c"
#include "plink.c"
#include "report.c"
#include "set.c"
#include "table.c"