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