xref: /freebsd/sbin/veriexec/manifest_lexer.l (revision a03411e84728e9b267056fd31c7d1d9d1dc1b01e)
1 %{
2 /*-
3  * Copyright (c) 2004-2018, Juniper Networks, Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
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  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
18  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
20  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #include <stdio.h>
28 #include <string.h>
29 #include "veriexec.h"
30 #include "manifest_parser.h"
31 
32 #define YY_NO_UNPUT
33 
34 int lineno = 1;
35 int bol = 1;
36 extern int parser_version;
37 
38 void yyerror(const char *message);
39 void warning(const char *message);
40 int yylex(void);
41 
42 %}
43 
44 %%
45 
46 \n {
47 	lineno++;
48 	bol=1;
49 	return EOL;
50 }
51 
52 [/a-zA-Z0-9\.][^ \t\n=]*  {
53 	yylval.string = strdup(yytext);
54 	if (bol) {
55 		bol=0;
56 		return PATH;
57 	} else
58 		return STRING;
59 }
60 
61 = {
62 	return EQ;
63 }
64 
65 
66 [ \t\r] ;  /* eat white ones */
67 
68 #>[0-9]+ {
69         /*
70          * If we are older than the specified version
71          * ignore rest of line, otherwise just discard this token.
72          */
73         int skip = atoi(&yytext[2]);
74 
75         VERBOSE(3, ("%s: skip if %d <= %d\n", yytext, parser_version, skip));
76         if (parser_version <= skip) {
77 		/* treat as a comment, yyless() is cheaper than yyunput() */
78 		yytext[yyleng - 1] = '#';
79 		yyless(2);
80         }
81 }
82 
83 #[^>\n].* ;      /* comment */
84 
85 .    yyerror("invalid character");
86 
87 %%
88 
89 static char *manifest_file = NULL;
90 
91 struct string_buf {
92 	const char *buf;
93 	size_t pos, size;
94 };
95 
96 static int
97 read_string_buf (void *token, char *dest, int count)
98 {
99 	struct string_buf *str_buf_p = (struct string_buf *)token;
100 	ssize_t n;
101 
102 	if (count < 0)
103 		return 0;
104 
105 	n = str_buf_p->size - str_buf_p->pos;
106 	if (count < n)
107 		n = count;
108 
109 	memcpy(dest, str_buf_p->buf + str_buf_p->pos, n);
110 	str_buf_p->pos += n;
111 
112 	return n;
113 }
114 
115 FILE *
116 manifest_open (const char *file, const char *file_content)
117 {
118 	static struct string_buf str_buf;
119 
120 	if (manifest_file) {
121 		free(manifest_file);
122 		fclose(yyin);
123 	}
124 
125 	str_buf.buf  = file_content;
126 	str_buf.pos  = 0;
127 	str_buf.size = strlen(file_content);
128 	yyin = fropen(&str_buf, read_string_buf);
129 	if (yyin) {
130 		manifest_file = strdup(file);
131 		lineno = 1;
132 		manifest_parser_init();
133 	} else
134 		manifest_file = NULL;
135 	return yyin;
136 }
137 
138 void
139 yyerror(const char *string)
140 {
141 	fprintf(stderr, "%s: %d: %s at %s\n",
142 	    manifest_file, lineno, string, yytext);
143 }
144 
145 int
146 yywrap(void)
147 {
148 	return (1);
149 }
150