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); }
53len=[0-9]+  { printf("About read token where %s\n",yytext); }
540+          { }
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 */
67static size_t total_mem=0;
68
69/* track the amount of memory for ptr. */
70struct memsz {
71    void* p;
72    size_t sz;
73};
74
75static struct memsz * ptrs=0;  /* Array of pairs. */
76static int nptrs=0; /* Number of pairs in array. */
77static int arrsz=0; /* Capacity of array. */
78
79static 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
88void * 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
119void * 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
142void 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
164int main(void);
165
166int
167main (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