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
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); }
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); }
60 ")"         { printf("yy_pop_state()\n");yy_pop_state();}
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 
yyalloc(yy_size_t n)88 void * yyalloc(yy_size_t n)
89 {
90     void * p;
91     int i;
92 
93     total_mem += n;
94     p = (void*)malloc(n);
95 
96     if( nptrs >= arrsz){
97         /* increase array size by 1 */
98         arrsz++;
99         ptrs = (struct memsz*)realloc( ptrs, arrsz * sizeof(struct memsz));
100         ptrs[nptrs].p = 0;
101         ptrs[nptrs].sz = 0;
102     }
103 
104     /* find a null slot */
105     for(i=0; i < arrsz ; i++)
106         if (ptrs[i].p == 0) {
107             ptrs[i].p = p;
108             ptrs[i].sz = n;
109         }
110 
111     nptrs++;
112     printf("yyflex_alloc(%8ld) total=%8ld return=%#10lx\n",(long)n,(long)total_mem,(long)p);
113     dump_mem(stdout);
114     return p;
115 }
116 
yyrealloc(void * p,yy_size_t n)117 void * yyrealloc(void* p, yy_size_t n)
118 {
119     int i;
120     for (i=0; i < arrsz; i++)
121         if ( ptrs[i].p == p){
122             total_mem -= ptrs[i].sz;
123             total_mem += n;
124             ptrs[i].p = (void*)realloc(p,n);
125             ptrs[i].sz = n;
126 
127             printf("yyflex_realloc(%#10lx,%8ld) total=%8ld return=%8lx\n",
128                     (long)p,(long)n,(long)total_mem,(long)ptrs[i].p);
129             dump_mem(stdout);
130             return ptrs[i].p;
131         }
132 
133     fprintf(stderr,"ERROR: yyflex_realloc could not locate pointer %#lx.\n",(long)p);
134     dump_mem(stdout);
135     exit(1);
136 }
137 
yyfree(void * p)138 void yyfree(void* p)
139 {
140     int i;
141     for (i=0; i < arrsz; i++)
142         if ( ptrs[i].p == p){
143             total_mem -= ptrs[i].sz;
144             free(p);
145             ptrs[i].p = 0;
146             ptrs[i].sz = 0;
147             nptrs--;
148             printf("yyflex_free(%#10lx) total=%8ld\n",(long)p,(long)total_mem);
149             dump_mem(stdout);
150             return;
151         }
152 
153     fprintf(stderr,"ERROR: yyflex_free could not locate pointer %#lx.\n",(long)p);
154     dump_mem(stdout);
155     exit(1);
156 }
157 
158 int main(void);
159 
160 int
main()161 main ()
162 {
163     arrsz = 1;
164     ptrs  = (struct memsz*)calloc(1,sizeof(struct memsz));
165     nptrs = 0;
166 
167     yyin = stdin;
168     yyout = stdout;
169     yylex();
170     yylex_destroy();
171     free(ptrs);
172 
173     if ( nptrs > 0 || total_mem > 0){
174         fprintf(stderr,"Oops. Looks like a memory leak: nptrs=%d, unfreed memory=%ld\n",nptrs,(long)total_mem);
175         exit(1);
176     }
177     printf("TEST RETURNING OK.\n");
178     return 0;
179 }
180