]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/gperf/src/positions.cc
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / gperf / src / positions.cc
1 /* A set of byte positions.
2    Copyright (C) 1989-1998, 2000, 2002 Free Software Foundation, Inc.
3    Written by Douglas C. Schmidt <schmidt@ics.uci.edu>
4    and Bruno Haible <bruno@clisp.org>.
5
6    This file is part of GNU GPERF.
7
8    GNU GPERF 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 2, or (at your option)
11    any later version.
12
13    GNU GPERF 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; see the file COPYING.
20    If not, write to the Free Software Foundation, Inc.,
21    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
22
23 /* Specification. */
24 #include "positions.h"
25
26 #include <stdio.h>
27 #include <stdlib.h> /* declares exit() */
28 #include <string.h>
29
30 /* ---------------------------- Class Positions ---------------------------- */
31
32 /* Set operations.  Assumes the array is in reverse order.  */
33
34 bool
35 Positions::contains (int pos) const
36 {
37   unsigned int count = _size;
38   const int *p = _positions + _size - 1;
39
40   for (; count > 0; p--, count--)
41     {
42       if (*p == pos)
43         return true;
44       if (*p > pos)
45         break;
46     }
47   return false;
48 }
49
50 void
51 Positions::add (int pos)
52 {
53   set_useall (false);
54
55   unsigned int count = _size;
56
57   if (count == MAX_SIZE)
58     {
59       fprintf (stderr, "Positions::add internal error: overflow\n");
60       exit (1);
61     }
62
63   int *p = _positions + _size - 1;
64
65   for (; count > 0; p--, count--)
66     {
67       if (*p == pos)
68         {
69           fprintf (stderr, "Positions::add internal error: duplicate\n");
70           exit (1);
71         }
72       if (*p > pos)
73         break;
74       p[1] = p[0];
75     }
76   p[1] = pos;
77   _size++;
78 }
79
80 void
81 Positions::remove (int pos)
82 {
83   set_useall (false);
84
85   unsigned int count = _size;
86   if (count > 0)
87     {
88       int *p = _positions + _size - 1;
89
90       if (*p == pos)
91         {
92           _size--;
93           return;
94         }
95       if (*p < pos)
96         {
97           int prev = *p;
98
99           for (;;)
100             {
101               p--;
102               count--;
103               if (count == 0)
104                 break;
105               if (*p == pos)
106                 {
107                   *p = prev;
108                   _size--;
109                   return;
110                 }
111               if (*p > pos)
112                 break;
113               int curr = *p;
114               *p = prev;
115               prev = curr;
116             }
117         }
118     }
119   fprintf (stderr, "Positions::remove internal error: not found\n");
120   exit (1);
121 }
122
123 /* Output in external syntax.  */
124 void
125 Positions::print () const
126 {
127   if (_useall)
128     printf ("*");
129   else
130     {
131       bool first = true;
132       bool seen_LASTCHAR = false;
133       unsigned int count = _size;
134       const int *p = _positions + _size - 1;
135
136       for (; count > 0; p--)
137         {
138           count--;
139           if (*p == LASTCHAR)
140             seen_LASTCHAR = true;
141           else
142             {
143               if (!first)
144                 printf (",");
145               printf ("%d", *p + 1);
146               if (count > 0 && p[-1] == *p + 1)
147                 {
148                   printf ("-");
149                   do
150                     {
151                       p--;
152                       count--;
153                     }
154                   while (count > 0 && p[-1] == *p + 1);
155                   printf ("%d", *p + 1);
156                 }
157               first = false;
158             }
159         }
160       if (seen_LASTCHAR)
161         {
162           if (!first)
163             printf (",");
164           printf ("$");
165         }
166     }
167 }
168
169 /* ------------------------------------------------------------------------- */
170
171 #ifndef __OPTIMIZE__
172
173 #define INLINE /* not inline */
174 #include "positions.icc"
175 #undef INLINE
176
177 #endif /* not defined __OPTIMIZE__ */