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