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