1228060Sbapt/* A set of byte positions. 2228060Sbapt Copyright (C) 1989-1998, 2000, 2002 Free Software Foundation, Inc. 3228060Sbapt Written by Douglas C. Schmidt <schmidt@ics.uci.edu> 4228060Sbapt and Bruno Haible <bruno@clisp.org>. 5228060Sbapt 6228060Sbapt This file is part of GNU GPERF. 7228060Sbapt 8228060Sbapt GNU GPERF is free software; you can redistribute it and/or modify 9228060Sbapt it under the terms of the GNU General Public License as published by 10228060Sbapt the Free Software Foundation; either version 2, or (at your option) 11228060Sbapt any later version. 12228060Sbapt 13228060Sbapt GNU GPERF is distributed in the hope that it will be useful, 14228060Sbapt but WITHOUT ANY WARRANTY; without even the implied warranty of 15228060Sbapt MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16228060Sbapt GNU General Public License for more details. 17228060Sbapt 18228060Sbapt You should have received a copy of the GNU General Public License 19228060Sbapt along with this program; see the file COPYING. 20228060Sbapt If not, write to the Free Software Foundation, Inc., 21228060Sbapt 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 22228060Sbapt 23228060Sbapt/* Specification. */ 24228060Sbapt#include "positions.h" 25228060Sbapt 26228060Sbapt#include <stdio.h> 27228060Sbapt#include <stdlib.h> /* declares exit() */ 28228060Sbapt#include <string.h> 29228060Sbapt 30228060Sbapt/* ---------------------------- Class Positions ---------------------------- */ 31228060Sbapt 32228060Sbapt/* Set operations. Assumes the array is in reverse order. */ 33228060Sbapt 34228060Sbaptbool 35228060SbaptPositions::contains (int pos) const 36228060Sbapt{ 37228060Sbapt unsigned int count = _size; 38228060Sbapt const int *p = _positions + _size - 1; 39228060Sbapt 40228060Sbapt for (; count > 0; p--, count--) 41228060Sbapt { 42228060Sbapt if (*p == pos) 43228060Sbapt return true; 44228060Sbapt if (*p > pos) 45228060Sbapt break; 46228060Sbapt } 47228060Sbapt return false; 48228060Sbapt} 49228060Sbapt 50228060Sbaptvoid 51228060SbaptPositions::add (int pos) 52228060Sbapt{ 53228060Sbapt set_useall (false); 54228060Sbapt 55228060Sbapt unsigned int count = _size; 56228060Sbapt 57228060Sbapt if (count == MAX_SIZE) 58228060Sbapt { 59228060Sbapt fprintf (stderr, "Positions::add internal error: overflow\n"); 60228060Sbapt exit (1); 61228060Sbapt } 62228060Sbapt 63228060Sbapt int *p = _positions + _size - 1; 64228060Sbapt 65228060Sbapt for (; count > 0; p--, count--) 66228060Sbapt { 67228060Sbapt if (*p == pos) 68228060Sbapt { 69228060Sbapt fprintf (stderr, "Positions::add internal error: duplicate\n"); 70228060Sbapt exit (1); 71228060Sbapt } 72228060Sbapt if (*p > pos) 73228060Sbapt break; 74228060Sbapt p[1] = p[0]; 75228060Sbapt } 76228060Sbapt p[1] = pos; 77228060Sbapt _size++; 78228060Sbapt} 79228060Sbapt 80228060Sbaptvoid 81228060SbaptPositions::remove (int pos) 82228060Sbapt{ 83228060Sbapt set_useall (false); 84228060Sbapt 85228060Sbapt unsigned int count = _size; 86228060Sbapt if (count > 0) 87228060Sbapt { 88228060Sbapt int *p = _positions + _size - 1; 89228060Sbapt 90228060Sbapt if (*p == pos) 91228060Sbapt { 92228060Sbapt _size--; 93228060Sbapt return; 94228060Sbapt } 95228060Sbapt if (*p < pos) 96228060Sbapt { 97228060Sbapt int prev = *p; 98228060Sbapt 99228060Sbapt for (;;) 100228060Sbapt { 101228060Sbapt p--; 102228060Sbapt count--; 103228060Sbapt if (count == 0) 104228060Sbapt break; 105228060Sbapt if (*p == pos) 106228060Sbapt { 107228060Sbapt *p = prev; 108228060Sbapt _size--; 109228060Sbapt return; 110228060Sbapt } 111228060Sbapt if (*p > pos) 112228060Sbapt break; 113228060Sbapt int curr = *p; 114228060Sbapt *p = prev; 115228060Sbapt prev = curr; 116228060Sbapt } 117228060Sbapt } 118228060Sbapt } 119228060Sbapt fprintf (stderr, "Positions::remove internal error: not found\n"); 120228060Sbapt exit (1); 121228060Sbapt} 122228060Sbapt 123228060Sbapt/* Output in external syntax. */ 124228060Sbaptvoid 125228060SbaptPositions::print () const 126228060Sbapt{ 127228060Sbapt if (_useall) 128228060Sbapt printf ("*"); 129228060Sbapt else 130228060Sbapt { 131228060Sbapt bool first = true; 132228060Sbapt bool seen_LASTCHAR = false; 133228060Sbapt unsigned int count = _size; 134228060Sbapt const int *p = _positions + _size - 1; 135228060Sbapt 136228060Sbapt for (; count > 0; p--) 137228060Sbapt { 138228060Sbapt count--; 139228060Sbapt if (*p == LASTCHAR) 140228060Sbapt seen_LASTCHAR = true; 141228060Sbapt else 142228060Sbapt { 143228060Sbapt if (!first) 144228060Sbapt printf (","); 145228060Sbapt printf ("%d", *p + 1); 146228060Sbapt if (count > 0 && p[-1] == *p + 1) 147228060Sbapt { 148228060Sbapt printf ("-"); 149228060Sbapt do 150228060Sbapt { 151228060Sbapt p--; 152228060Sbapt count--; 153228060Sbapt } 154228060Sbapt while (count > 0 && p[-1] == *p + 1); 155228060Sbapt printf ("%d", *p + 1); 156228060Sbapt } 157228060Sbapt first = false; 158228060Sbapt } 159228060Sbapt } 160228060Sbapt if (seen_LASTCHAR) 161228060Sbapt { 162228060Sbapt if (!first) 163228060Sbapt printf (","); 164228060Sbapt printf ("$"); 165228060Sbapt } 166228060Sbapt } 167228060Sbapt} 168228060Sbapt 169228060Sbapt/* ------------------------------------------------------------------------- */ 170228060Sbapt 171228060Sbapt#ifndef __OPTIMIZE__ 172228060Sbapt 173228060Sbapt#define INLINE /* not inline */ 174228060Sbapt#include "positions.icc" 175228060Sbapt#undef INLINE 176228060Sbapt 177228060Sbapt#endif /* not defined __OPTIMIZE__ */ 178