]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.bin/dtc/input_buffer.cc
Import tzdata 2017c
[FreeBSD/FreeBSD.git] / usr.bin / dtc / input_buffer.cc
1 /*-
2  * Copyright (c) 2013 David Chisnall
3  * All rights reserved.
4  *
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.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
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.
17  *
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
28  * SUCH DAMAGE.
29  *
30  * $FreeBSD$
31  */
32
33 #include "input_buffer.hh"
34 #include <ctype.h>
35 #include <errno.h>
36 #include <limits.h>
37 #include <stdint.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <functional>
42 #ifndef NDEBUG
43 #include <iostream>
44 #endif
45
46
47 #include <sys/stat.h>
48 #include <sys/mman.h>
49 #include <assert.h>
50 #include <fcntl.h>
51 #include <unistd.h>
52
53 #ifndef MAP_PREFAULT_READ
54 #define MAP_PREFAULT_READ 0
55 #endif
56
57 using std::string;
58
59 namespace
60 {
61 /**
62  * Subclass of input_buffer that mmap()s a file and owns the resulting memory.
63  * When this object is destroyed, the memory is unmapped.
64  */
65 struct mmap_input_buffer : public dtc::input_buffer
66 {
67         string fn;
68         const string &filename() const override
69         {
70                 return fn;
71         }
72         /**
73          * Constructs a new buffer from the file passed in as a file
74          * descriptor.
75          */
76         mmap_input_buffer(int fd, string &&filename);
77         /**
78          * Unmaps the buffer, if one exists.
79          */
80         virtual ~mmap_input_buffer();
81 };
82 /**
83  * Input buffer read from standard input.  This is used for reading device tree
84  * blobs and source from standard input.  It reads the entire input into
85  * malloc'd memory, so will be very slow for large inputs.  DTS and DTB files
86  * are very rarely more than 10KB though, so this is probably not a problem.
87  */
88 struct stream_input_buffer : public dtc::input_buffer
89 {
90         const string &filename() const override
91         {
92                 static string n = "<standard input>";
93                 return n;
94         }
95         /**
96          * The buffer that will store the data read from the standard input.
97          */
98         std::vector<char> b;
99         /**
100          * Constructs a new buffer from the standard input.
101          */
102         stream_input_buffer();
103 };
104
105 mmap_input_buffer::mmap_input_buffer(int fd, string &&filename)
106         : input_buffer(0, 0), fn(filename)
107 {
108         struct stat sb;
109         if (fstat(fd, &sb))
110         {
111                 perror("Failed to stat file");
112         }
113         size = sb.st_size;
114         buffer = (const char*)mmap(0, size, PROT_READ, MAP_PRIVATE |
115                         MAP_PREFAULT_READ, fd, 0);
116         if (buffer == MAP_FAILED)
117         {
118                 perror("Failed to mmap file");
119                 exit(EXIT_FAILURE);
120         }
121 }
122
123 mmap_input_buffer::~mmap_input_buffer()
124 {
125         if (buffer != 0)
126         {
127                 munmap((void*)buffer, size);
128         }
129 }
130
131 stream_input_buffer::stream_input_buffer() : input_buffer(0, 0)
132 {
133         int c;
134         while ((c = fgetc(stdin)) != EOF)
135         {
136                 b.push_back(c);
137         }
138         buffer = b.data();
139         size = b.size();
140 }
141
142 } // Anonymous namespace
143
144
145 namespace dtc
146 {
147
148 void
149 input_buffer::skip_to(char c)
150 {
151         while ((cursor < size) && (buffer[cursor] != c))
152         {
153                 cursor++;
154         }
155 }
156
157 void
158 text_input_buffer::skip_to(char c)
159 {
160         while (!finished() && (*(*this) != c))
161         {
162                 ++(*this);
163         }
164 }
165
166 void
167 text_input_buffer::skip_spaces()
168 {
169         if (finished()) { return; }
170         char c = *(*this);
171         bool last_nl = false;
172         while ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\f')
173                || (c == '\v') || (c == '\r'))
174         {
175                 last_nl = ((c == '\n') || (c == '\r'));
176                 ++(*this);
177                 if (finished())
178                 {
179                         c = '\0';
180                 }
181                 else
182                 {
183                         c = *(*this);
184                 }
185         }
186         // Skip C preprocessor leftovers
187         if ((c == '#') && ((cursor == 0) || last_nl))
188         {
189                 skip_to('\n');
190                 skip_spaces();
191         }
192         if (consume("/include/"))
193         {
194                 handle_include();
195                 skip_spaces();
196         }
197 }
198
199 void
200 text_input_buffer::handle_include()
201 {
202         bool reallyInclude = true;
203         if (consume("if "))
204         {
205                 next_token();
206                 string name = parse_property_name();
207                 if (defines.count(name) > 0)
208                 {
209                         reallyInclude = true;
210                 }
211                 consume('/');
212         }
213         next_token();
214         if (!consume('"'))
215         {
216                 parse_error("Expected quoted filename");
217                 return;
218         }
219         auto loc = location();
220         string file = parse_to('"');
221         consume('"');
222         if (!reallyInclude)
223         {
224                 return;
225         }
226         string include_file = dir + '/' + file;
227         auto include_buffer = input_buffer::buffer_for_file(include_file, false);
228         if (include_buffer == 0)
229         {
230                 for (auto i : include_paths)
231                 {
232                         include_file = i + '/' + file;
233                         include_buffer = input_buffer::buffer_for_file(include_file, false);
234                         if (include_buffer != 0)
235                         {
236                                 break;
237                         }
238                 }
239         }
240         if (depfile)
241         {
242                 putc(' ', depfile);
243                 fputs(include_file.c_str(), depfile);
244         }
245         if (!include_buffer)
246         {
247                 loc.report_error("Unable to locate input file");
248                 return;
249         }
250         input_stack.push(std::move(include_buffer));
251 }
252
253 input_buffer
254 input_buffer::buffer_from_offset(int offset, int s)
255 {
256         if (offset < 0)
257         {
258                 return input_buffer();
259         }
260         if (s == 0)
261         {
262                 s = size - offset;
263         }
264         if (offset > size)
265         {
266                 return input_buffer();
267         }
268         if (s > (size-offset))
269         {
270                 return input_buffer();
271         }
272         return input_buffer(&buffer[offset], s);
273 }
274
275 bool
276 input_buffer::consume(const char *str)
277 {
278         int len = strlen(str);
279         if (len > size - cursor)
280         {
281                 return false;
282         }
283         else
284         {
285                 for (int i=0 ; i<len ; ++i)
286                 {
287                         if (str[i] != (*this)[i])
288                         {
289                                 return false;
290                         }
291                 }
292                 cursor += len;
293                 return true;
294         }
295         return false;
296 }
297
298 bool
299 input_buffer::consume_integer(unsigned long long &outInt)
300 {
301         // The first character must be a digit.  Hex and octal strings
302         // are prefixed by 0 and 0x, respectively.
303         if (!isdigit((*this)[0]))
304         {
305                 return false;
306         }
307         char *end= const_cast<char*>(&buffer[size]);
308         outInt = strtoull(&buffer[cursor], &end, 0);
309         if (end == &buffer[cursor])
310         {
311                 return false;
312         }
313         cursor = end - buffer;
314         return true;
315 }
316
317 namespace {
318
319 /**
320  * Convenience typedef for the type that we use for all values.
321  */
322 typedef unsigned long long valty;
323
324 /**
325  * Expression tree currently being parsed.
326  */
327 struct expression
328 {
329         typedef text_input_buffer::source_location source_location;
330         /**
331          * The type that is returned when computing the result.  The boolean value
332          * indicates whether this is a valid expression.
333          *
334          * FIXME: Once we can use C++17, this should be `std::optional`.
335          */
336         typedef std::pair<valty, bool> result;
337         /**
338          * Evaluate this node, taking into account operator precedence.
339          */
340         virtual result operator()() = 0;
341         /**
342          * Returns the precedence of this node.  Lower values indicate higher
343          * precedence.
344          */
345         virtual int precedence() = 0;
346         /**
347          * Constructs an expression, storing the location where it was created.
348          */
349         expression(source_location l) : loc(l) {}
350         virtual ~expression() {}
351 #ifndef NDEBUG
352         /**
353          * Dumps this expression to `std::cerr`, appending a newline if `nl` is
354          * `true`.
355          */
356         void dump(bool nl=false)
357         {
358                 void *ptr = this;
359                 if (ptr == nullptr)
360                 {
361                         std::cerr << "{nullptr}\n";
362                         return;
363                 }
364                 dump_impl();
365                 if (nl)
366                 {
367                         std::cerr << '\n';
368                 }
369         }
370         private:
371         /**
372          * Method that sublcasses override to implement the behaviour of `dump()`.
373          */
374         virtual void dump_impl() = 0;
375 #endif
376         protected:
377         source_location loc;
378 };
379
380 /**
381  * Expression wrapping a single integer.  Leaf nodes in the expression tree.
382  */
383 class terminal_expr : public expression
384 {
385         /**
386          * The value that this wraps.
387          */
388         valty val;
389         /**
390          * Evaluate.  Trivially returns the value that this class wraps.
391          */
392         result operator()() override
393         {
394                 return {val, true};
395         }
396         int precedence() override
397         {
398                 return 0;
399         }
400         public:
401         /**
402          * Constructor.
403          */
404         terminal_expr(source_location l, valty v) : expression(l), val(v) {}
405 #ifndef NDEBUG
406         void dump_impl() override { std::cerr << val; }
407 #endif
408 };
409
410 /**
411  * Parenthetical expression.  Exists to make the contents opaque.
412  */
413 struct paren_expression : public expression
414 {
415         /**
416          * The expression within the parentheses.
417          */
418         expression_ptr subexpr;
419         /**
420          * Constructor.  Takes the child expression as the only argument.
421          */
422         paren_expression(source_location l, expression_ptr p) : expression(l),
423         subexpr(std::move(p)) {}
424         int precedence() override
425         {
426                 return 0;
427         }
428         /**
429          * Evaluate - just forwards to the underlying expression.
430          */
431         result operator()() override
432         {
433                 return (*subexpr)();
434         }
435 #ifndef NDEBUG
436         void dump_impl() override
437         {
438                 std::cerr << " (";
439                 subexpr->dump();
440                 std::cerr << ") ";
441         }
442 #endif
443 };
444
445 /**
446  * Template class for unary operators.  The `OpChar` template parameter is
447  * solely for debugging and makes it easy to print the expression.  The `Op`
448  * template parameter is a function object that implements the operator that
449  * this class provides.  Most of these are provided by the `<functional>`
450  * header.
451  */
452 template<char OpChar, class Op>
453 class unary_operator : public expression
454 {
455         /**
456          * The subexpression for this unary operator.
457          */
458         expression_ptr subexpr;
459         result operator()() override
460         {
461                 Op op;
462                 result s = (*subexpr)();
463                 if (!s.second)
464                 {
465                         return s;
466                 }
467                 return {op(s.first), true};
468         }
469         /**
470          * All unary operators have the same precedence.  They are all evaluated
471          * before binary expressions, but after parentheses.
472          */
473         int precedence() override
474         {
475                 return 3;
476         }
477         public:
478         unary_operator(source_location l, expression_ptr p) :
479                 expression(l), subexpr(std::move(p)) {}
480 #ifndef NDEBUG
481         void dump_impl() override
482         {
483                 std::cerr << OpChar;
484                 subexpr->dump();
485         }
486 #endif
487 };
488
489 /**
490  * Abstract base class for binary operators.  Allows the tree to be modified
491  * without knowing what the operations actually are.
492  */
493 struct binary_operator_base : public expression
494 {
495         using expression::expression;
496         /**
497          * The left side of the expression.
498          */
499         expression_ptr lhs;
500         /**
501          * The right side of the expression.
502          */
503         expression_ptr rhs;
504         /**
505          * Insert a node somewhere down the path of left children, until it would
506          * be preempting something that should execute first.
507          */
508         void insert_left(binary_operator_base *new_left)
509         {
510                 if (lhs->precedence() < new_left->precedence())
511                 {
512                         new_left->rhs = std::move(lhs);
513                         lhs.reset(new_left);
514                 }
515                 else
516                 {
517                         static_cast<binary_operator_base*>(lhs.get())->insert_left(new_left);
518                 }
519         }
520 };
521
522 /**
523  * Template class for binary operators.  The precedence and the operation are
524  * provided as template parameters.
525  */
526 template<int Precedence, class Op>
527 struct binary_operator : public binary_operator_base
528 {
529         result operator()() override
530         {
531                 Op op;
532                 result l = (*lhs)();
533                 result r = (*rhs)();
534                 if (!(l.second && r.second))
535                 {
536                         return {0, false};
537                 }
538                 return {op(l.first, r.first), true};
539         }
540         int precedence() override
541         {
542                 return Precedence;
543         }
544 #ifdef NDEBUG
545         /**
546          * Constructor.  Takes the name of the operator as an argument, for
547          * debugging.  Only stores it in debug mode.
548          */
549         binary_operator(source_location l, const char *) :
550                 binary_operator_base(l) {}
551 #else
552         const char *opName;
553         binary_operator(source_location l, const char *o) :
554                 binary_operator_base(l), opName(o) {}
555         void dump_impl() override
556         {
557                 lhs->dump();
558                 std::cerr << opName;
559                 rhs->dump();
560         }
561 #endif
562 };
563
564 /**
565  * Ternary conditional operators (`cond ? true : false`) are a special case -
566  * there are no other ternary operators.
567  */
568 class ternary_conditional_operator : public expression
569 {
570         /**
571          * The condition for the clause.
572          */
573         expression_ptr cond;
574         /**
575          * The expression that this evaluates to if the condition is true.
576          */
577         expression_ptr lhs;
578         /**
579          * The expression that this evaluates to if the condition is false.
580          */
581         expression_ptr rhs;
582         result operator()() override
583         {
584                 result c = (*cond)();
585                 result l = (*lhs)();
586                 result r = (*rhs)();
587                 if (!(l.second && r.second && c.second))
588                 {
589                         return {0, false};
590                 }
591                 return c.first ? l : r;
592         }
593         int precedence() override
594         {
595                 // The actual precedence of a ternary conditional operator is 15, but
596                 // its associativity is the opposite way around to the other operators,
597                 // so we fudge it slightly.
598                 return 3;
599         }
600 #ifndef NDEBUG
601         void dump_impl() override
602         {
603                 cond->dump();
604                 std::cerr << " ? ";
605                 lhs->dump();
606                 std::cerr << " : ";
607                 rhs->dump();
608         }
609 #endif
610         public:
611         ternary_conditional_operator(source_location sl,
612                                      expression_ptr c,
613                                      expression_ptr l,
614                                      expression_ptr r) :
615                 expression(sl), cond(std::move(c)), lhs(std::move(l)),
616                 rhs(std::move(r)) {}
617 };
618
619 template<typename T>
620 struct lshift
621 {
622         constexpr T operator()(const T &lhs, const T &rhs) const
623         {
624                 return lhs << rhs;
625         }
626 };
627 template<typename T>
628 struct rshift
629 {
630         constexpr T operator()(const T &lhs, const T &rhs) const
631         {
632                 return lhs >> rhs;
633         }
634 };
635 template<typename T>
636 struct unary_plus
637 {
638         constexpr T operator()(const T &val) const
639         {
640                 return +val;
641         }
642 };
643 // TODO: Replace with std::bit_not once we can guarantee C++14 as a baseline.
644 template<typename T>
645 struct bit_not
646 {
647         constexpr T operator()(const T &val) const
648         {
649                 return ~val;
650         }
651 };
652
653 template<typename T>
654 struct divmod : public binary_operator<5, T>
655 {
656         using binary_operator<5, T>::binary_operator;
657         using typename binary_operator_base::result;
658         result operator()() override
659         {
660                 result r = (*binary_operator_base::rhs)();
661                 if (r.second && (r.first == 0))
662                 {
663                         expression::loc.report_error("Division by zero");
664                         return {0, false};
665                 }
666                 return binary_operator<5, T>::operator()();
667         }
668 };
669
670 } // anonymous namespace
671
672
673 expression_ptr text_input_buffer::parse_binary_expression(expression_ptr lhs)
674 {
675         next_token();
676         binary_operator_base *expr = nullptr;
677         char op = *(*this);
678         source_location l = location();
679         switch (op)
680         {
681                 default:
682                         return lhs;
683                 case '+':
684                         expr = new binary_operator<6, std::plus<valty>>(l, "+");
685                         break;
686                 case '-':
687                         expr = new binary_operator<6, std::minus<valty>>(l, "-");
688                         break;
689                 case '%':
690                         expr = new divmod<std::modulus<valty>>(l, "/");
691                         break;
692                 case '*':
693                         expr = new binary_operator<5, std::multiplies<valty>>(l, "*");
694                         break;
695                 case '/':
696                         expr = new divmod<std::divides<valty>>(l, "/");
697                         break;
698                 case '<':
699                         switch (peek())
700                         {
701                                 default:
702                                         parse_error("Invalid operator");
703                                         return nullptr;
704                                 case ' ':
705                                 case '(':
706                                 case '0'...'9':
707                                         expr = new binary_operator<8, std::less<valty>>(l, "<");
708                                         break;
709                                 case '=':
710                                         ++(*this);
711                                         expr = new binary_operator<8, std::less_equal<valty>>(l, "<=");
712                                         break;
713                                 case '<':
714                                         ++(*this);
715                                         expr = new binary_operator<7, lshift<valty>>(l, "<<");
716                                         break;
717                         }
718                         break;
719                 case '>':
720                         switch (peek())
721                         {
722                                 default:
723                                         parse_error("Invalid operator");
724                                         return nullptr;
725                                 case '(':
726                                 case ' ':
727                                 case '0'...'9':
728                                         expr = new binary_operator<8, std::greater<valty>>(l, ">");
729                                         break;
730                                 case '=':
731                                         ++(*this);
732                                         expr = new binary_operator<8, std::greater_equal<valty>>(l, ">=");
733                                         break;
734                                 case '>':
735                                         ++(*this);
736                                         expr = new binary_operator<7, rshift<valty>>(l, ">>");
737                                         break;
738                                         return lhs;
739                         }
740                         break;
741                 case '=':
742                         if (peek() != '=')
743                         {
744                                 parse_error("Invalid operator");
745                                 return nullptr;
746                         }
747                         expr = new binary_operator<9, std::equal_to<valty>>(l, "==");
748                         break;
749                 case '!':
750                         if (peek() != '=')
751                         {
752                                 parse_error("Invalid operator");
753                                 return nullptr;
754                         }
755                         cursor++;
756                         expr = new binary_operator<9, std::not_equal_to<valty>>(l, "!=");
757                         break;
758                 case '&':
759                         if (peek() == '&')
760                         {
761                                 expr = new binary_operator<13, std::logical_and<valty>>(l, "&&");
762                         }
763                         else
764                         {
765                                 expr = new binary_operator<10, std::bit_and<valty>>(l, "&");
766                         }
767                         break;
768                 case '|':
769                         if (peek() == '|')
770                         {
771                                 expr = new binary_operator<12, std::logical_or<valty>>(l, "||");
772                         }
773                         else
774                         {
775                                 expr = new binary_operator<14, std::bit_or<valty>>(l, "|");
776                         }
777                         break;
778                 case '?':
779                 {
780                         consume('?');
781                         expression_ptr true_case = parse_expression();
782                         next_token();
783                         if (!true_case || !consume(':'))
784                         {
785                                 parse_error("Expected : in ternary conditional operator");
786                                 return nullptr;
787                         }
788                         expression_ptr false_case = parse_expression();
789                         if (!false_case)
790                         {
791                                 parse_error("Expected false condition for ternary operator");
792                                 return nullptr;
793                         }
794                         return expression_ptr(new ternary_conditional_operator(l, std::move(lhs),
795                                                 std::move(true_case), std::move(false_case)));
796                 }
797         }
798         ++(*this);
799         next_token();
800         expression_ptr e(expr);
801         expression_ptr rhs(parse_expression());
802         if (!rhs)
803         {
804                 return nullptr;
805         }
806         expr->lhs = std::move(lhs);
807         if (rhs->precedence() < expr->precedence())
808         {
809                 expr->rhs = std::move(rhs);
810         }
811         else
812         {
813                 // If we're a normal left-to-right expression, then we need to insert
814                 // this as the far-left child node of the rhs expression
815                 binary_operator_base *rhs_op =
816                         static_cast<binary_operator_base*>(rhs.get());
817                 rhs_op->insert_left(expr);
818                 e.release();
819                 return rhs;
820         }
821         return e;
822 }
823
824 expression_ptr text_input_buffer::parse_expression(bool stopAtParen)
825 {
826         next_token();
827         unsigned long long leftVal;
828         expression_ptr lhs;
829         source_location l = location();
830         switch (*(*this))
831         {
832                 case '0'...'9':
833                         if (!consume_integer(leftVal))
834                         {
835                                 return nullptr;
836                         }
837                         lhs.reset(new terminal_expr(l, leftVal));
838                         break;
839                 case '(':
840                 {
841                         consume('(');
842                         expression_ptr &&subexpr = parse_expression();
843                         if (!subexpr)
844                         {
845                                 return nullptr;
846                         }
847                         lhs.reset(new paren_expression(l, std::move(subexpr)));
848                         if (!consume(')'))
849                         {
850                                 return nullptr;
851                         }
852                         if (stopAtParen)
853                         {
854                                 return lhs;
855                         }
856                         break;
857                 }
858                 case '+':
859                 {
860                         consume('+');
861                         expression_ptr &&subexpr = parse_expression();
862                         if (!subexpr)
863                         {
864                                 return nullptr;
865                         }
866                         lhs.reset(new unary_operator<'+', unary_plus<valty>>(l, std::move(subexpr)));
867                         break;
868                 }
869                 case '-':
870                 {
871                         consume('-');
872                         expression_ptr &&subexpr = parse_expression();
873                         if (!subexpr)
874                         {
875                                 return nullptr;
876                         }
877                         lhs.reset(new unary_operator<'-', std::negate<valty>>(l, std::move(subexpr)));
878                         break;
879                 }
880                 case '!':
881                 {
882                         consume('!');
883                         expression_ptr &&subexpr = parse_expression();
884                         if (!subexpr)
885                         {
886                                 return nullptr;
887                         }
888                         lhs.reset(new unary_operator<'!', std::logical_not<valty>>(l, std::move(subexpr)));
889                         break;
890                 }
891                 case '~':
892                 {
893                         consume('~');
894                         expression_ptr &&subexpr = parse_expression();
895                         if (!subexpr)
896                         {
897                                 return nullptr;
898                         }
899                         lhs.reset(new unary_operator<'~', bit_not<valty>>(l, std::move(subexpr)));
900                         break;
901                 }
902         }
903         if (!lhs)
904         {
905                 return nullptr;
906         }
907         return parse_binary_expression(std::move(lhs));
908 }
909
910 bool
911 text_input_buffer::consume_integer_expression(unsigned long long &outInt)
912 {
913         switch (*(*this))
914         {
915                 case '(':
916                 {
917                         expression_ptr e(parse_expression(true));
918                         if (!e)
919                         {
920                                 return false;
921                         }
922                         auto r = (*e)();
923                         if (r.second)
924                         {
925                                 outInt = r.first;
926                                 return true;
927                         }
928                         return false;
929                 }
930                 case '0'...'9':
931                         return consume_integer(outInt);
932                 default:
933                         return false;
934         }
935 }
936
937 bool
938 input_buffer::consume_hex_byte(uint8_t &outByte)
939 {
940         if (!ishexdigit((*this)[0]) && !ishexdigit((*this)[1]))
941         {
942                 return false;
943         }
944         outByte = (digittoint((*this)[0]) << 4) | digittoint((*this)[1]);
945         cursor += 2;
946         return true;
947 }
948
949 text_input_buffer&
950 text_input_buffer::next_token()
951 {
952         auto &self = *this;
953         int start;
954         do {
955                 start = cursor;
956                 skip_spaces();
957                 if (finished())
958                 {
959                         return self;
960                 }
961                 // Parse /* comments
962                 if (*self == '/' && peek() == '*')
963                 {
964                         // eat the start of the comment
965                         ++self;
966                         ++self;
967                         do {
968                                 // Find the ending * of */
969                                 while ((*self != '\0') && (*self != '*') && !finished())
970                                 {
971                                         ++self;
972                                 }
973                                 // Eat the *
974                                 ++self;
975                         } while ((*self != '\0') && (*self != '/') && !finished());
976                         // Eat the /
977                         ++self;
978                 }
979                 // Parse // comments
980                 if ((*self == '/' && peek() == '/'))
981                 {
982                         // eat the start of the comment
983                         ++self;
984                         ++self;
985                         // Find the ending of the line
986                         while (*self != '\n' && !finished())
987                         {
988                                 ++self;
989                         }
990                         // Eat the \n
991                         ++self;
992                 }
993         } while (start != cursor);
994         return self;
995 }
996
997 void
998 text_input_buffer::parse_error(const char *msg)
999 {
1000         if (input_stack.empty())
1001         {
1002                 fprintf(stderr, "Error: %s\n", msg);
1003                 return;
1004         }
1005         input_buffer &b = *input_stack.top();
1006         parse_error(msg, b, b.cursor);
1007 }
1008 void
1009 text_input_buffer::parse_error(const char *msg,
1010                                input_buffer &b,
1011                                int loc)
1012 {
1013         int line_count = 1;
1014         int line_start = 0;
1015         int line_end = loc;
1016         if (loc < 0 || loc > b.size)
1017         {
1018                 return;
1019         }
1020         for (int i=loc ; i>0 ; --i)
1021         {
1022                 if (b.buffer[i] == '\n')
1023                 {
1024                         line_count++;
1025                         if (line_start == 0)
1026                         {
1027                                 line_start = i+1;
1028                         }
1029                 }
1030         }
1031         for (int i=loc+1 ; i<b.size ; ++i)
1032         {
1033                 if (b.buffer[i] == '\n')
1034                 {
1035                         line_end = i;
1036                         break;
1037                 }
1038         }
1039         fprintf(stderr, "Error at %s:%d:%d: %s\n", b.filename().c_str(), line_count, loc - line_start, msg);
1040         fwrite(&b.buffer[line_start], line_end-line_start, 1, stderr);
1041         putc('\n', stderr);
1042         for (int i=0 ; i<(loc-line_start) ; ++i)
1043         {
1044                 char c = (b.buffer[i+line_start] == '\t') ? '\t' : ' ';
1045                 putc(c, stderr);
1046         }
1047         putc('^', stderr);
1048         putc('\n', stderr);
1049 }
1050 #ifndef NDEBUG
1051 void
1052 input_buffer::dump()
1053 {
1054         fprintf(stderr, "Current cursor: %d\n", cursor);
1055         fwrite(&buffer[cursor], size-cursor, 1, stderr);
1056 }
1057 #endif
1058
1059
1060 namespace
1061 {
1062 /**
1063  * The source files are ASCII, so we provide a non-locale-aware version of
1064  * isalpha.  This is a class so that it can be used with a template function
1065  * for parsing strings.
1066  */
1067 struct is_alpha
1068 {
1069         static inline bool check(const char c)
1070         {
1071                 return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') &&
1072                         (c <= 'Z'));
1073         }
1074 };
1075 /**
1076  * Check whether a character is in the set allowed for node names.  This is a
1077  * class so that it can be used with a template function for parsing strings.
1078  */
1079 struct is_node_name_character
1080 {
1081         static inline bool check(const char c)
1082         {
1083                 switch(c)
1084                 {
1085                         default:
1086                                 return false;
1087                         case 'a'...'z': case 'A'...'Z': case '0'...'9':
1088                         case ',': case '.': case '+': case '-':
1089                         case '_':
1090                                 return true;
1091                 }
1092         }
1093 };
1094 /**
1095  * Check whether a character is in the set allowed for property names.  This is
1096  * a class so that it can be used with a template function for parsing strings.
1097  */
1098 struct is_property_name_character
1099 {
1100         static inline bool check(const char c)
1101         {
1102                 switch(c)
1103                 {
1104                         default:
1105                                 return false;
1106                         case 'a'...'z': case 'A'...'Z': case '0'...'9':
1107                         case ',': case '.': case '+': case '-':
1108                         case '_': case '#':
1109                                 return true;
1110                 }
1111         }
1112 };
1113
1114 template<class T>
1115 string parse(text_input_buffer &s)
1116 {
1117         std::vector<char> bytes;
1118         for (char c=*s ; T::check(c) ; c=*(++s))
1119         {
1120                 bytes.push_back(c);
1121         }
1122         return string(bytes.begin(), bytes.end());
1123 }
1124
1125 }
1126
1127 string
1128 text_input_buffer::parse_node_name()
1129 {
1130         return parse<is_node_name_character>(*this);
1131 }
1132
1133 string
1134 text_input_buffer::parse_property_name()
1135 {
1136         return parse<is_property_name_character>(*this);
1137 }
1138
1139 string
1140 text_input_buffer::parse_node_or_property_name(bool &is_property)
1141 {
1142         if (is_property)
1143         {
1144                 return parse_property_name();
1145         }
1146         std::vector<char> bytes;
1147         for (char c=*(*this) ; is_node_name_character::check(c) ; c=*(++(*this)))
1148         {
1149                 bytes.push_back(c);
1150         }
1151         for (char c=*(*this) ; is_property_name_character::check(c) ; c=*(++(*this)))
1152         {
1153                 bytes.push_back(c);
1154                 is_property = true;
1155         }
1156         return string(bytes.begin(), bytes.end());
1157 }
1158
1159 string
1160 input_buffer::parse_to(char stop)
1161 {
1162         std::vector<char> bytes;
1163         for (char c=*(*this) ; c != stop ; c=*(++(*this)))
1164         {
1165                 bytes.push_back(c);
1166         }
1167         return string(bytes.begin(), bytes.end());
1168 }
1169
1170 string
1171 text_input_buffer::parse_to(char stop)
1172 {
1173         std::vector<char> bytes;
1174         for (char c=*(*this) ; c != stop ; c=*(++(*this)))
1175         {
1176                 if (finished())
1177                 {
1178                         break;
1179                 }
1180                 bytes.push_back(c);
1181         }
1182         return string(bytes.begin(), bytes.end());
1183 }
1184
1185 char
1186 text_input_buffer::peek()
1187 {
1188         return (*input_stack.top())[1];
1189 }
1190
1191 std::unique_ptr<input_buffer>
1192 input_buffer::buffer_for_file(const string &path, bool warn)
1193 {
1194         if (path == "-")
1195         {
1196                 std::unique_ptr<input_buffer> b(new stream_input_buffer());
1197                 return b;
1198         }
1199         int source = open(path.c_str(), O_RDONLY);
1200         if (source == -1)
1201         {
1202                 if (warn)
1203                 {
1204                         fprintf(stderr, "Unable to open file '%s'.  %s\n", path.c_str(), strerror(errno));
1205                 }
1206                 return 0;
1207         }
1208         struct stat st;
1209         if (fstat(source, &st) == 0 && S_ISDIR(st.st_mode))
1210         {
1211                 if (warn)
1212                 {
1213                         fprintf(stderr, "File %s is a directory\n", path.c_str());
1214                 }
1215                 close(source);
1216                 return 0;
1217         }
1218         std::unique_ptr<input_buffer> b(new mmap_input_buffer(source, string(path)));
1219         close(source);
1220         return b;
1221 }
1222
1223 } // namespace dtc
1224