File: index-scan.l

package info (click to toggle)
libguestfs 1%3A1.44.0-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 118,932 kB
  • sloc: ansic: 458,017; ml: 51,424; sh: 13,191; java: 9,578; makefile: 7,931; cs: 6,328; haskell: 5,674; python: 3,871; perl: 3,528; erlang: 2,446; xml: 1,347; ruby: 350; pascal: 257; javascript: 157; lex: 135; yacc: 128; cpp: 10
file content (153 lines) | stat: -rw-r--r-- 4,702 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/* libguestfs virt-builder tool -*- fundamental -*-
 * Copyright (C) 2013 Red Hat Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

%top{
#include <config.h>
}

%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* Silence gcc warnings from the generated code. */
#if defined(__GNUC__)
#pragma GCC diagnostic push
/* flex creates macros that it doesn't use */
#pragma GCC diagnostic ignored "-Wunused-macros"
/* on aarch64, flex doesn't know that char is unsigned */
#pragma GCC diagnostic ignored "-Wsign-compare"
/* on debian-mipsel, flex doesn't create prototypes for all functions */
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
#endif

#include "index-struct.h"
#include "index-parse.h"

#define YY_EXTRA_TYPE struct parse_context *
#define YY_USER_ACTION yylloc->first_line = yylloc->last_line = yylineno;

extern void scanner_init (yyscan_t *scanner, struct parse_context *context, FILE *in);
extern void scanner_destroy (yyscan_t scanner);

#if (YY_FLEX_MAJOR_VERSION > 2) \
  || ((YY_FLEX_MAJOR_VERSION == 2) && (YY_FLEX_MINOR_VERSION > 6)) \
  || ((YY_FLEX_MAJOR_VERSION == 2) && (YY_FLEX_MINOR_VERSION == 6) && (YY_FLEX_SUBMINOR_VERSION >= 1))
#define IS_EOF 0
#else
#define IS_EOF EOF
#endif

%}

%option nounput
%option noyywrap
%option yylineno
%option reentrant
%option bison-bridge
%option bison-locations

%%

 /* Apart from the PGP prologue/epilogue which is a hack, the
  * scanning strategy is to deal with the file strictly line by
  * line, and pass those lines up to the parser which deals with
  * whether they appear in the right order to be meaningful.
  * Note that flex does longest-match.
  */

  /* Ignore comments - '#' MUST appear at the start of a line. */
^"#".*\n                { yyextra->seen_comments++; }

  /* An empty line is significant. */
^\n                                     { return EMPTY_LINE; }

  /* [...] marks beginning of a section. */
^"["[-A-Za-z0-9._]+"]"[[:blank:]]*\n {
                      const char *end = strrchr (yytext, ']');
                      yylval->str = strndup (yytext+1, end-yytext-1);
                      return SECTION_HEADER;
                    }

  /* field=value or field[subfield]=value */
^[A-Za-z0-9_.]+("["[A-Za-z0-9_,.]+"]")?"=".*\n {
                      size_t i = strcspn (yytext, "=[");
                      yylval->field = malloc (sizeof (struct field));
                      yylval->field->next = NULL;
                      yylval->field->key = strndup (yytext, i);
                      if (yytext[i] == '[') {
                        const size_t j = strcspn (yytext+i+1, "]");
                        yylval->field->subkey = strndup (yytext+i+1, j);
                        i += 1+j+1;
                      } else {
                        yylval->field->subkey = NULL;
                      }
                      /* Note we chop the final \n off here. */
                      yylval->field->value = strndup (yytext+i+1, yyleng-(i+2));
                      return FIELD;
                    }

  /* Continuation line for multi-line values. */
^[[:blank:]].*\n        {
                      yylval->str = strndup (yytext+1, yyleng-2);
                      return VALUE_CONT;
                    }

 /* Hack to eat the PGP prologue. */
^"-----BEGIN PGP SIGNED MESSAGE-----\n"  {
  int c, prevnl = 0;

  /* Eat everything to the first blank line. */
  while ((c = input (yyscanner)) != IS_EOF) {
    if (c == '\n' && prevnl)
      break;
    prevnl = c == '\n';
  }

  return PGP_PROLOGUE;
}

 /* Hack to eat the PGP epilogue. */
^"-----BEGIN PGP SIGNATURE-----\n"  {
  /* Eat everything to the end of the file. */
  while (input (yyscanner) != IS_EOF)
    ;

  return PGP_EPILOGUE;
}

 /* anything else is an error */
. {
  return UNKNOWN_LINE;
}

%%

void
scanner_init (yyscan_t *scanner, struct parse_context *context, FILE *in)
{
  yylex_init (scanner);
  yyset_extra (context, *scanner);
  yyset_in (in, *scanner);
}

void
scanner_destroy (yyscan_t scanner)
{
  yylex_destroy (scanner);
}