(root)/
bison-3.8.2/
src/
location.h
       1  /* Locations for Bison
       2  
       3     Copyright (C) 2002, 2004-2015, 2018-2021 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 <https://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.  */
      31  typedef struct
      32  {
      33    /* The name of the file that contains the boundary.  */
      34    uniqstr file;
      35  
      36    /* If positive, the line (starting at 1) that contains the boundary.
      37       If this is INT_MAX, the line number has overflowed.
      38  
      39       Meaningless and not displayed if nonpositive.
      40    */
      41    int line;
      42  
      43    /* If positive, the column (starting at 1) just after the boundary.
      44       This is neither a byte count, nor a character count; it is a
      45       (visual) column count.  If this is INT_MAX, the column number has
      46       overflowed.
      47  
      48       Meaningless and not displayed if nonpositive.  */
      49    int column;
      50  
      51    /* If nonnegative, the byte number (starting at 0) in the current
      52       line.  Not displayed (unless --trace=location).  */
      53    int byte;
      54  
      55  } boundary;
      56  
      57  /* Set the position of \a p. */
      58  static inline void
      59  boundary_set (boundary *p, const char *f, int l, int c, int b)
      60  {
      61    p->file = f;
      62    p->line = l;
      63    p->column = c;
      64    p->byte = b;
      65  }
      66  
      67  /* Return -1, 0, 1, depending whether a is before, equal, or
      68     after b.  */
      69  static inline int
      70  boundary_cmp (boundary a, boundary b)
      71  {
      72    /* Locations with no file first.  */
      73    int res =
      74      a.file && b.file ? strcmp (a.file, b.file)
      75      : a.file ? 1
      76      : b.file ? -1
      77      : 0;
      78    if (!res)
      79      res = a.line - b.line;
      80    if (!res)
      81      res = a.column - b.column;
      82    return res;
      83  }
      84  
      85  /* Return nonzero if A and B are equal boundaries.  */
      86  static inline bool
      87  equal_boundaries (boundary a, boundary b)
      88  {
      89    return (a.column == b.column
      90            && a.line == b.line
      91            && UNIQSTR_EQ (a.file, b.file));
      92  }
      93  
      94  /* A location, that is, a region of source code.  */
      95  typedef struct
      96  {
      97    /* Boundary just before the location starts.  */
      98    boundary start;
      99  
     100    /* Boundary just after the location ends.  */
     101    boundary end;
     102  
     103  } location;
     104  
     105  # define GRAM_LTYPE location
     106  
     107  # define EMPTY_LOCATION_INIT {{NULL, 0, 0, 0}, {NULL, 0, 0, 0}}
     108  extern location const empty_loc;
     109  
     110  /* Set *LOC and adjust scanner cursor to account for token TOKEN of
     111     size SIZE.  */
     112  void location_compute (location *loc,
     113                         boundary *cur, char const *token, size_t size);
     114  
     115  /* Print location to file.
     116     Return number of actually printed characters.
     117     Warning: uses quotearg's slot 3. */
     118  int location_print (location loc, FILE *out);
     119  
     120  /* Prepare the use of location_caret.  */
     121  void caret_init (void);
     122  
     123  /* Free any allocated resources and close any open file handles that are
     124     left-over by the usage of location_caret.  */
     125  void caret_free (void);
     126  
     127  /* If -fcaret is enabled, quote the line containing LOC onto OUT.
     128     Highlight the part of LOC with the color STYLE.  */
     129  void location_caret (location loc, const char* style, FILE *out);
     130  
     131  /* If -fcaret is enabled, display a suggestion of replacement for LOC
     132     with S.  To call after location_caret.  */
     133  void location_caret_suggestion (location loc, const char *s, FILE *out);
     134  
     135  /* Return -1, 0, 1, depending whether a is before, equal, or
     136     after b.  */
     137  static inline int
     138  location_cmp (location a, location b)
     139  {
     140    int res = boundary_cmp (a.start, b.start);
     141    if (!res)
     142      res = boundary_cmp (a.end, b.end);
     143    return res;
     144  }
     145  
     146  /* Whether this is the empty location.  */
     147  bool location_empty (location loc);
     148  
     149  /* STR must be formatted as 'file:line.column@byte' or 'file:line.column'.
     150     It may be '<command line>:3.-1@-1', with -1 to denote no-column/no-byte.
     151     STR will be modified.  */
     152  void boundary_set_from_string (boundary *bound, char *str);
     153  
     154  #endif /* ! defined LOCATION_H_ */