Remove address from GPLv2 headers
[coreboot.git] / util / cbfstool / fmd_parser.y
blobcaa2beb45f1bc36dbe618f46b43089f2ba393cf1
1 /*
2 * fmd_parser.y, parser generator for flashmap descriptor language
4 * Copyright (C) 2015 Google, Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc.
21 #include "fmd_scanner.h"
22 #include "common.h"
24 #include <stdlib.h>
26 struct flashmap_descriptor *res = NULL;
29 %union {
30 unsigned intval;
31 char *strval;
32 struct unsigned_option maybe_intval;
33 struct flashmap_descriptor *region_ptr;
34 struct descriptor_list region_listhdr;
37 %code requires {
38 #include "fmd.h"
39 #include "option.h"
41 #include <stdbool.h>
43 struct descriptor_node {
44 struct flashmap_descriptor *val;
45 struct descriptor_node *next;
48 struct descriptor_list {
49 size_t len;
50 struct descriptor_node *head;
51 struct descriptor_node *tail;
54 extern struct flashmap_descriptor *res;
56 struct flashmap_descriptor *parse_descriptor(char *name,
57 struct unsigned_option offset, struct unsigned_option size,
58 struct descriptor_list children);
59 void yyerror(const char *s);
62 %token <intval> INTEGER
63 %token OCTAL
64 %token <strval> STRING
66 %type <region_ptr> flash_region
67 %type <strval> region_name
68 %type <strval> region_annotation_opt
69 %type <strval> region_annotation
70 %type <maybe_intval> region_offset_opt
71 %type <maybe_intval> region_offset
72 %type <maybe_intval> region_size_opt
73 %type <maybe_intval> region_size
74 %type <region_listhdr> region_list_opt
75 %type <region_listhdr> region_list
76 %type <region_listhdr> region_list_entries
80 flash_chip: region_name region_offset_opt region_size region_list
82 if (!(res = parse_descriptor($1, $2, $3, $4)))
83 YYABORT;
85 flash_region: region_name region_annotation_opt region_offset_opt
86 region_size_opt region_list_opt
88 struct flashmap_descriptor *node = parse_descriptor($1, $3, $4, $5);
89 if (!node)
90 YYABORT;
92 char *annotation = $2;
93 if (annotation && !fmd_process_annotation_impl(node, annotation)) {
94 ERROR("Section '%s' has unexpected annotation '(%s)'\n",
95 node->name, annotation);
96 YYABORT;
98 free(annotation);
100 $$ = node;
102 region_name: STRING
104 if (!$1) {
105 perror("E: While allocating section name");
106 YYABORT;
109 region_annotation_opt: { $$ = NULL; }
110 | region_annotation;
111 region_annotation: '(' STRING ')' { $$ = $2; };
112 region_offset_opt: { $$ = (struct unsigned_option){false, 0}; }
113 | region_offset;
114 region_offset: '@' INTEGER { $$ = (struct unsigned_option){true, $2}; };
115 region_size_opt: { $$ = (struct unsigned_option){false, 0}; }
116 | region_size;
117 region_size: INTEGER { $$ = (struct unsigned_option){true, $1}; };
118 region_list_opt:
120 $$ = (struct descriptor_list)
121 {.len = 0, .head = NULL, .tail = NULL};
123 | region_list;
124 region_list: '{' region_list_entries '}' { $$ = $2; };
125 region_list_entries: flash_region
127 struct descriptor_node *node = malloc(sizeof(*node));
128 if (!node) {
129 perror("E: While allocating linked list node");
130 YYABORT;
132 node->val = $1;
133 node->next = NULL;
134 $$ = (struct descriptor_list){.len = 1, .head = node, .tail = node};
136 | region_list_entries flash_region
138 struct descriptor_node *node = malloc(sizeof(*node));
139 if (!node) {
140 perror("E: While allocating linked list node");
141 YYABORT;
143 node->val = $2;
144 node->next = NULL;
146 $1.tail->next = node;
147 $$ = (struct descriptor_list)
148 {.len = $1.len + 1, .head = $1.head, .tail = node};
153 struct flashmap_descriptor *parse_descriptor(char *name,
154 struct unsigned_option offset, struct unsigned_option size,
155 struct descriptor_list children)
157 struct flashmap_descriptor *region = malloc(sizeof(*region));
158 if (!region) {
159 perror("E: While allocating descriptor section");
160 return NULL;
162 region->name = name;
163 region->offset_known = offset.val_known;
164 region->offset = offset.val;
165 region->size_known = size.val_known;
166 region->size = size.val;
167 region->list_len = children.len;
168 if (region->list_len) {
169 region->list = malloc(region->list_len * sizeof(*region->list));
170 if (!region->list) {
171 perror("E: While allocating node children array");
172 return NULL;
174 struct descriptor_node *cur_node = children.head;
175 for (unsigned idx = 0; idx < region->list_len; ++idx) {
176 region->list[idx] = cur_node->val;
178 struct descriptor_node *next_node = cur_node->next;
179 free(cur_node);
180 cur_node = next_node;
182 } else {
183 region->list = NULL;
185 return region;
188 void yyerror(const char *s)
190 fprintf(stderr, "%s\n", s);