Home | History | Annotate | Download | only in src
      1 /* Locations for Bison
      2 
      3    Copyright (C) 2002, 2004-2012 Free Software Foundation, Inc.
      4 
      5    This file is part of Bison, the GNU Compiler Compiler.
      6 
      7    This program is free software: you can redistribute it and/or modify
      8    it under the terms of the GNU General Public License as published by
      9    the Free Software Foundation, either version 3 of the License, or
     10    (at your option) any later version.
     11 
     12    This program is distributed in the hope that it will be useful,
     13    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15    GNU General Public License for more details.
     16 
     17    You should have received a copy of the GNU General Public License
     18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19 
     20 #ifndef LOCATION_H_
     21 # define LOCATION_H_
     22 
     23 # include "uniqstr.h"
     24 
     25 /* A boundary between two characters.  */
     26 typedef struct
     27 {
     28   /* The name of the file that contains the boundary.  */
     29   uniqstr file;
     30 
     31   /* If nonnegative, the (origin-1) line that contains the boundary.
     32      If this is INT_MAX, the line number has overflowed.
     33 
     34      Meaningless and not displayed if negative.
     35   */
     36   int line;
     37 
     38   /* If nonnegative, the (origin-1) column just after the boundary.
     39      This is neither a byte count, nor a character count; it is a
     40      column count.  If this is INT_MAX, the column number has
     41      overflowed.
     42 
     43      Meaningless and not displayed if negative.
     44   */
     45   int column;
     46 
     47 } boundary;
     48 
     49 /* Set the position of \a a. */
     50 static inline void
     51 boundary_set (boundary *b, const char *f, int l, int c)
     52 {
     53   b->file = f;
     54   b->line = l;
     55   b->column = c;
     56 }
     57 
     58 /* Return -1, 0, 1, depending whether a is before, equal, or
     59    after b.  */
     60 static inline int
     61 boundary_cmp (boundary a, boundary b)
     62 {
     63   int res = strcmp (a.file, b.file);
     64   if (!res)
     65     res = a.line - b.line;
     66   if (!res)
     67     res = a.column - b.column;
     68   return res;
     69 }
     70 
     71 /* Return nonzero if A and B are equal boundaries.  */
     72 static inline bool
     73 equal_boundaries (boundary a, boundary b)
     74 {
     75   return (a.column == b.column
     76 	  && a.line == b.line
     77 	  && UNIQSTR_EQ (a.file, b.file));
     78 }
     79 
     80 /* A location, that is, a region of source code.  */
     81 typedef struct
     82 {
     83   /* Boundary just before the location starts.  */
     84   boundary start;
     85 
     86   /* Boundary just after the location ends.  */
     87   boundary end;
     88 
     89 } location;
     90 
     91 #define GRAM_LTYPE location
     92 
     93 #define EMPTY_LOCATION_INIT {{NULL, 0, 0}, {NULL, 0, 0}}
     94 extern location const empty_location;
     95 
     96 /* Set *LOC and adjust scanner cursor to account for token TOKEN of
     97    size SIZE.  */
     98 void location_compute (location *loc,
     99 		       boundary *cur, char const *token, size_t size);
    100 
    101 /* Print location to file. Return number of actually printed
    102    characters.  */
    103 unsigned location_print (FILE *out, location loc);
    104 
    105 /* Free any allocated ressources and close any open file handles that are
    106    left-over by the usage of location_caret.  */
    107 void cleanup_caret (void);
    108 
    109 /* Output to OUT the line and caret corresponding to location LOC.  */
    110 void location_caret (FILE *out, location loc);
    111 
    112 /* Return -1, 0, 1, depending whether a is before, equal, or
    113    after b.  */
    114 static inline int
    115 location_cmp (location a, location b)
    116 {
    117   int res = boundary_cmp (a.start, b.start);
    118   if (!res)
    119     res = boundary_cmp (a.end, b.end);
    120   return res;
    121 }
    122 
    123 /* LOC_STR must be formatted as `file:line.column', it will be modified.  */
    124 void boundary_set_from_string (boundary *bound, char *loc_str);
    125 
    126 #endif /* ! defined LOCATION_H_ */
    127