2 * Copyright (c) 2013 David Chisnall
5 * This software was developed by SRI International and the University of
6 * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
7 * ("CTSRD"), as part of the DARPA CRASH research programme.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 #include "input_buffer.hh"
46 #ifndef MAP_PREFAULT_READ
47 #define MAP_PREFAULT_READ 0
54 input_buffer::skip_spaces()
56 if (cursor >= size) { return; }
57 if (cursor < 0) { return; }
58 char c = buffer[cursor];
59 while ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\f')
60 || (c == '\v') || (c == '\r'))
75 input_buffer::buffer_from_offset(int offset, int s)
83 return input_buffer();
85 if (s > (size-offset))
87 return input_buffer();
89 return input_buffer(&buffer[offset], s);
93 input_buffer::consume(const char *str)
95 int len = strlen(str);
96 if (len > size - cursor)
102 for (int i=0 ; i<len ; ++i)
104 if (str[i] != buffer[cursor + i])
116 input_buffer::consume_integer(long long &outInt)
118 // The first character must be a digit. Hex and octal strings
119 // are prefixed by 0 and 0x, respectively.
120 if (!isdigit((*this)[0]))
125 outInt = strtoll(&buffer[cursor], &end, 0);
126 if (end == &buffer[cursor])
130 cursor = end - buffer;
135 input_buffer::consume_hex_byte(uint8_t &outByte)
137 if (!ishexdigit((*this)[0]) && !ishexdigit((*this)[1]))
141 outByte = (digittoint((*this)[0]) << 4) | digittoint((*this)[1]);
147 input_buffer::next_token()
154 if ((*this)[0] == '/' && (*this)[1] == '*')
156 // eat the start of the comment
160 // Find the ending * of */
161 while ((**this != '\0') && (**this != '*'))
167 } while ((**this != '\0') && (**this != '/'));
171 // Parse // comments and # comments
172 if (((*this)[0] == '/' && (*this)[1] == '/') ||
175 // eat the start of the comment
178 // Find the ending of the line
179 while (**this != '\n')
186 } while (start != cursor);
191 input_buffer::parse_error(const char *msg)
195 int line_end = cursor;
196 for (int i=cursor ; i>0 ; --i)
198 if (buffer[i] == '\n')
207 for (int i=cursor+1 ; i<size ; ++i)
209 if (buffer[i] == '\n')
215 fprintf(stderr, "Error on line %d: %s\n", line_count, msg);
216 fwrite(&buffer[line_start], line_end-line_start, 1, stderr);
218 for (int i=0 ; i<(cursor-line_start) ; ++i)
220 char c = (buffer[i+line_start] == '\t') ? '\t' : ' ';
229 fprintf(stderr, "Current cursor: %d\n", cursor);
230 fwrite(&buffer[cursor], size-cursor, 1, stderr);
233 mmap_input_buffer::mmap_input_buffer(int fd) : input_buffer(0, 0)
238 perror("Failed to stat file");
241 buffer = (const char*)mmap(0, size, PROT_READ,
242 MAP_PREFAULT_READ, fd, 0);
245 perror("Failed to mmap file");
249 mmap_input_buffer::~mmap_input_buffer()
253 munmap((void*)buffer, size);
257 stream_input_buffer::stream_input_buffer() : input_buffer(0, 0)
260 while ((c = fgetc(stdin)) != EOF)