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.  */
26typedef 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. */
50static inline void
51boundary_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.  */
60static inline int
61boundary_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.  */
72static inline bool
73equal_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.  */
81typedef 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}}
94extern location const empty_location;
95
96/* Set *LOC and adjust scanner cursor to account for token TOKEN of
97   size SIZE.  */
98void 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.  */
103unsigned 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.  */
107void cleanup_caret (void);
108
109/* Output to OUT the line and caret corresponding to location LOC.  */
110void location_caret (FILE *out, location loc);
111
112/* Return -1, 0, 1, depending whether a is before, equal, or
113   after b.  */
114static inline int
115location_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.  */
124void boundary_set_from_string (boundary *bound, char *loc_str);
125
126#endif /* ! defined LOCATION_H_ */
127