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 | 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 | /* Specification. */ |
22 | #include "positions.h" |
23 | |
24 | #include <stdio.h> |
25 | #include <stdlib.h> /* declares exit() */ |
26 | #include <string.h> |
27 | |
28 | /* ---------------------------- Class Positions ---------------------------- */ |
29 | |
30 | /* Set operations. Assumes the array is in reverse order. */ |
31 | |
32 | bool |
33 | Positions::contains (int pos) const |
34 | { |
35 | unsigned int count = _size; |
36 | const int *p = _positions + _size - 1; |
37 | |
38 | for (; count > 0; p--, count--) |
39 | { |
40 | if (*p == pos) |
41 | return true; |
42 | if (*p > pos) |
43 | break; |
44 | } |
45 | return false; |
46 | } |
47 | |
48 | void |
49 | Positions::add (int pos) |
50 | { |
51 | set_useall (false); |
52 | |
53 | unsigned int count = _size; |
54 | |
55 | if (count == MAX_SIZE) |
56 | { |
57 | fprintf (stderr, "Positions::add internal error: overflow\n" ); |
58 | exit (1); |
59 | } |
60 | |
61 | int *p = _positions + _size - 1; |
62 | |
63 | for (; count > 0; p--, count--) |
64 | { |
65 | if (*p == pos) |
66 | { |
67 | fprintf (stderr, "Positions::add internal error: duplicate\n" ); |
68 | exit (1); |
69 | } |
70 | if (*p > pos) |
71 | break; |
72 | p[1] = p[0]; |
73 | } |
74 | p[1] = pos; |
75 | _size++; |
76 | } |
77 | |
78 | void |
79 | Positions::remove (int pos) |
80 | { |
81 | set_useall (false); |
82 | |
83 | unsigned int count = _size; |
84 | if (count > 0) |
85 | { |
86 | int *p = _positions + _size - 1; |
87 | |
88 | if (*p == pos) |
89 | { |
90 | _size--; |
91 | return; |
92 | } |
93 | if (*p < pos) |
94 | { |
95 | int prev = *p; |
96 | |
97 | for (;;) |
98 | { |
99 | p--; |
100 | count--; |
101 | if (count == 0) |
102 | break; |
103 | if (*p == pos) |
104 | { |
105 | *p = prev; |
106 | _size--; |
107 | return; |
108 | } |
109 | if (*p > pos) |
110 | break; |
111 | int curr = *p; |
112 | *p = prev; |
113 | prev = curr; |
114 | } |
115 | } |
116 | } |
117 | fprintf (stderr, "Positions::remove internal error: not found\n" ); |
118 | exit (1); |
119 | } |
120 | |
121 | /* Output in external syntax. */ |
122 | void |
123 | Positions::print () const |
124 | { |
125 | if (_useall) |
126 | printf ("*" ); |
127 | else |
128 | { |
129 | bool first = true; |
130 | bool seen_LASTCHAR = false; |
131 | unsigned int count = _size; |
132 | const int *p = _positions + _size - 1; |
133 | |
134 | for (; count > 0; p--) |
135 | { |
136 | count--; |
137 | if (*p == LASTCHAR) |
138 | seen_LASTCHAR = true; |
139 | else |
140 | { |
141 | if (!first) |
142 | printf ("," ); |
143 | printf ("%d" , *p + 1); |
144 | if (count > 0 && p[-1] == *p + 1) |
145 | { |
146 | printf ("-" ); |
147 | do |
148 | { |
149 | p--; |
150 | count--; |
151 | } |
152 | while (count > 0 && p[-1] == *p + 1); |
153 | printf ("%d" , *p + 1); |
154 | } |
155 | first = false; |
156 | } |
157 | } |
158 | if (seen_LASTCHAR) |
159 | { |
160 | if (!first) |
161 | printf ("," ); |
162 | printf ("$" ); |
163 | } |
164 | } |
165 | } |
166 | |
167 | /* ------------------------------------------------------------------------- */ |
168 | |
169 | #ifndef __OPTIMIZE__ |
170 | |
171 | #define INLINE /* not inline */ |
172 | #include "positions.icc" |
173 | #undef INLINE |
174 | |
175 | #endif /* not defined __OPTIMIZE__ */ |
176 | |