1 /*
2 * This file is part of flex.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * Neither the name of the University nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE.
22 */
23
24 %{
25 /* A template scanner file to build "scanner.c".
26 * The whole idea is to cause memory realloc by
27 * 1. pushing a lot on the condition stack, and
28 * 2. eating input greater than YY_BUF_SIZE
29 */
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include "config.h"
33
34 /* Insanely small read buffer. This pretty much guarantees at least one realloc. */
35 #ifdef YY_BUF_SIZE
36 #undef YY_BUF_SIZE
37 #endif
38 #define YY_BUF_SIZE 8
39
40 %}
41
42 %option 8bit prefix="test"
43 %option nounput nomain noyywrap noinput noyy_top_state
44 %option warn stack nodefault reentrant
45 %option noyyalloc noyyrealloc noyyfree
46
47 %x parens
48
49 %%
50
51 <INITIAL>{
52 "(" { printf("yy_push_state(parens)\n"); yy_push_state(parens,yyscanner); }
53 len=[0-9]+ { printf("About read token where %s\n",yytext); }
54 0+ { }
55 .|\n { }
56 }
57
58 <parens>{
59 "(" { printf("yy_push_state(parens)\n"); yy_push_state(parens,yyscanner); }
60 ")" { printf("yy_pop_state()\n");yy_pop_state(yyscanner);}
61 [^()\n]+ { }
62 .|\n { }
63 }
64
65 %%
66 /* total memory allocated */
67 static size_t total_mem=0;
68
69 /* track the amount of memory for ptr. */
70 struct memsz {
71 void* p;
72 size_t sz;
73 };
74
75 static struct memsz * ptrs=0; /* Array of pairs. */
76 static int nptrs=0; /* Number of pairs in array. */
77 static int arrsz=0; /* Capacity of array. */
78
dump_mem(FILE * fp)79 static void dump_mem(FILE* fp){
80 int i;
81 fprintf(fp,"\tptrs[%d] = {", nptrs);
82 for (i=0; i < arrsz; i++)
83 fprintf(fp," {%#lx,%ld},", (long)ptrs[i].p, (long)ptrs[i].sz);
84
85 fprintf(fp,"}\n");
86 }
87
testalloc(yy_size_t n,void * yyscanner)88 void * testalloc(yy_size_t n , void* yyscanner)
89 {
90 (void)yyscanner;
91
92 void * p;
93 int i;
94
95 total_mem += n;
96 p = malloc(n);
97
98 if( nptrs >= arrsz){
99 /* increase array size by 1 */
100 arrsz++;
101 ptrs = realloc(ptrs, (size_t) arrsz * sizeof(struct memsz));
102 ptrs[nptrs].p = 0;
103 ptrs[nptrs].sz = 0;
104 }
105
106 /* find a null slot */
107 for(i=0; i < arrsz ; i++)
108 if (ptrs[i].p == 0) {
109 ptrs[i].p = p;
110 ptrs[i].sz = n;
111 }
112
113 nptrs++;
114 printf("yyflex_alloc(%8ld) total=%8ld return=%#10lx\n",(long)n,(long)total_mem,(long)p);
115 dump_mem(stdout);
116 return p;
117 }
118
testrealloc(void * p,yy_size_t n,void * yyscanner)119 void * testrealloc(void* p, yy_size_t n , void* yyscanner)
120 {
121 (void)yyscanner;
122
123 int i;
124 for (i=0; i < arrsz; i++)
125 if ( ptrs[i].p == p){
126 total_mem -= ptrs[i].sz;
127 total_mem += n;
128 ptrs[i].p = realloc(p, n);
129 ptrs[i].sz = n;
130
131 printf("yyflex_realloc(%#10lx,%8ld) total=%8ld return=%8lx\n",
132 (long)p,(long)n,(long)total_mem,(long)ptrs[i].p);
133 dump_mem(stdout);
134 return ptrs[i].p;
135 }
136
137 fprintf(stderr,"ERROR: yyflex_realloc could not locate pointer %#lx.\n",(long)p);
138 dump_mem(stdout);
139 exit(1);
140 }
141
testfree(void * p,void * yyscanner)142 void testfree(void* p , void* yyscanner)
143 {
144 (void)yyscanner;
145
146 int i;
147 for (i=0; i < arrsz; i++)
148 if ( ptrs[i].p == p){
149 total_mem -= ptrs[i].sz;
150 free(p);
151 ptrs[i].p = 0;
152 ptrs[i].sz = 0;
153 nptrs--;
154 printf("yyflex_free(%#10lx) total=%8ld\n",(long)p,(long)total_mem);
155 dump_mem(stdout);
156 return;
157 }
158
159 fprintf(stderr,"ERROR: yyflex_free could not locate pointer %#lx.\n",(long)p);
160 dump_mem(stdout);
161 exit(1);
162 }
163
164 int main(void);
165
166 int
main(void)167 main (void)
168 {
169 yyscan_t scanner;
170 arrsz = 1;
171 ptrs = calloc(1, sizeof(struct memsz));
172 nptrs = 0;
173
174 testlex_init(&scanner);
175 testset_in(stdin,scanner);
176 testset_out(stdout,scanner);
177 testlex(scanner);
178 testlex_destroy(scanner);
179 free(ptrs);
180
181 if ( nptrs > 0 || total_mem > 0){
182 fprintf(stderr,"Oops. Looks like a memory leak: nptrs=%d, unfreed memory=%ld\n",nptrs,(long)total_mem);
183 exit(1);
184 }
185 printf("TEST RETURNING OK.\n");
186 return 0;
187 }
188