1/* $NetBSD$ */ 2 3/* 4 * This file is part of flex. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE. 24 */ 25 26%{ 27/* A file to build "scanner.c". */ 28/* This tests that we can use "yyextra". 29 We buffer all input into a growable array, then print it. 30 We run diff on the input and output. 31*/ 32 33#include <stdio.h> 34#include <stdlib.h> 35#include "config.h" 36 37 38/* We'll store the entire input in this buffer, growing as necessary. */ 39struct Check { 40 char foo; 41 char *bar; 42 char qux; 43}; 44 45/* Save char into junk array at next position. */ 46static void check_extra ( yyscan_t scanner ); 47 48/* Special yyalloc */ 49void *yyalloc ( size_t size, yyscan_t scanner ); 50 51%} 52 53%option 8bit outfile="scanner.c" prefix="test" 54%option nounput nomain noyywrap nodefault 55%option warn 56%option extra-type="struct Check *" 57%option reentrant 58%option noyyalloc 59 60 61%% 62 63.|\r|\n { check_extra (yyscanner); } 64 65%% 66 67int main(void); 68 69int 70main () 71{ 72 yyscan_t scanner; 73 struct Check check; 74 75 check.foo = 'a'; 76 check.bar = NULL; 77 check.qux = 'z'; 78 79 testlex_init_extra(&check, &scanner); 80 testset_in(stdin, scanner); 81 testset_out(stdout, scanner); 82 83 /* Test to confirm that yyalloc was called from 84 * yylex_init_extra with the yyextra argument. 85 */ 86 check_extra(scanner); 87 88 testlex(scanner); 89 90 testlex_destroy(scanner); 91 return 0; 92} 93 94void *yyalloc(size_t size, yyscan_t scanner) 95{ 96 struct Check *check; 97 check = testget_extra(scanner); 98 99 if (!check->bar) 100 check->bar = "Hello World"; 101 102 check_extra(scanner); 103 104 return malloc(size); 105} 106 107/* Save char into junk array at next position. */ 108static void check_extra(yyscan_t scanner) 109{ 110 struct Check *check; 111 check = testget_extra(scanner); 112 113 if (check->foo != 'a') { 114 fprintf(stderr, "foo is not 'a'\n"); 115 exit(1); 116 } 117 if (strcmp(check->bar, "Hello World") != 0) { 118 fprintf(stderr, "bar is not Hello World\n"); 119 exit(1); 120 } 121 if (check->qux != 'z') { 122 fprintf(stderr, "qux is not 'z'\n"); 123 exit(1); 124 } 125} 126