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 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 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 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 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 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