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