158314Sache/* A set of byte positions. 221308Sache Copyright (C) 1989-1998, 2000, 2002 Free Software Foundation, Inc. 321308Sache Written by Douglas C. Schmidt <schmidt@ics.uci.edu> 4165675Sache and Bruno Haible <bruno@clisp.org>. 521308Sache 621308Sache This file is part of GNU GPERF. 721308Sache 821308Sache GNU GPERF is free software; you can redistribute it and/or modify 921308Sache it under the terms of the GNU General Public License as published by 1021308Sache the Free Software Foundation; either version 2, or (at your option) 1158314Sache any later version. 1221308Sache 1321308Sache GNU GPERF is distributed in the hope that it will be useful, 1421308Sache but WITHOUT ANY WARRANTY; without even the implied warranty of 1521308Sache MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1621308Sache GNU General Public License for more details. 1721308Sache 1821308Sache You should have received a copy of the GNU General Public License 1921308Sache along with this program; see the file COPYING. 2021308Sache If not, write to the Free Software Foundation, Inc., 2121308Sache 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 2258314Sache 2321308Sache/* Specification. */ 2421308Sache#include "positions.h" 2521308Sache 2621308Sache#include <stdio.h> 2721308Sache#include <stdlib.h> /* declares exit() */ 2821308Sache#include <string.h> 2921308Sache 3021308Sache/* ---------------------------- Class Positions ---------------------------- */ 3121308Sache 3221308Sache/* Set operations. Assumes the array is in reverse order. */ 3321308Sache 3421308Sachebool 3526497SachePositions::contains (int pos) const 3626497Sache{ 3721308Sache unsigned int count = _size; 3821308Sache const int *p = _positions + _size - 1; 3921308Sache 4021308Sache for (; count > 0; p--, count--) 4121308Sache { 4221308Sache if (*p == pos) 4326497Sache return true; 4421308Sache if (*p > pos) 4521308Sache break; 4621308Sache } 47119614Sache return false; 4821308Sache} 4921308Sache 5021308Sachevoid 5121308SachePositions::add (int pos) 5221308Sache{ 5321308Sache set_useall (false); 5421308Sache 5521308Sache unsigned int count = _size; 5658314Sache 5758314Sache if (count == MAX_SIZE) 5858314Sache { 5921308Sache fprintf (stderr, "Positions::add internal error: overflow\n"); 6021308Sache exit (1); 6121308Sache } 6221308Sache 63119614Sache int *p = _positions + _size - 1; 64119614Sache 65119614Sache for (; count > 0; p--, count--) 66119614Sache { 67119614Sache if (*p == pos) 6821308Sache { 69119614Sache fprintf (stderr, "Positions::add internal error: duplicate\n"); 70136759Speter exit (1); 71119614Sache } 72119614Sache if (*p > pos) 73119614Sache break; 74119614Sache p[1] = p[0]; 75119614Sache } 7621308Sache p[1] = pos; 7758314Sache _size++; 7821308Sache} 7921308Sache 80165675Sachevoid 81165675SachePositions::remove (int pos) 8221308Sache{ 8321308Sache set_useall (false); 84165675Sache 85165675Sache unsigned int count = _size; 86165675Sache if (count > 0) 87165675Sache { 88165675Sache int *p = _positions + _size - 1; 89165675Sache 90165675Sache if (*p == pos) 91165675Sache { 9221308Sache _size--; 9321308Sache return; 9421308Sache } 9521308Sache if (*p < pos) 9621308Sache { 9721308Sache int prev = *p; 9821308Sache 9921308Sache for (;;) 10021308Sache { 10121308Sache p--; 10221308Sache count--; 10321308Sache if (count == 0) 10421308Sache break; 10521308Sache if (*p == pos) 10621308Sache { 10721308Sache *p = prev; 10821308Sache _size--; 10921308Sache return; 11021308Sache } 11121308Sache if (*p > pos) 11221308Sache break; 11321308Sache int curr = *p; 11421308Sache *p = prev; 11521308Sache prev = curr; 11621308Sache } 11721308Sache } 11821308Sache } 11921308Sache fprintf (stderr, "Positions::remove internal error: not found\n"); 12075409Sache exit (1); 12121308Sache} 12221308Sache 12321308Sache/* Output in external syntax. */ 12421308Sachevoid 12521308SachePositions::print () const 12621308Sache{ 127157188Sache if (_useall) 12821308Sache printf ("*"); 12921308Sache else 13021308Sache { 13121308Sache bool first = true; 13221308Sache bool seen_LASTCHAR = false; 13321308Sache unsigned int count = _size; 134157188Sache const int *p = _positions + _size - 1; 13521308Sache 136157188Sache for (; count > 0; p--) 137157188Sache { 138157188Sache count--; 139157188Sache if (*p == LASTCHAR) 14021308Sache seen_LASTCHAR = true; 14121308Sache else 14221308Sache { 143157188Sache if (!first) 144165675Sache printf (","); 145157188Sache printf ("%d", *p + 1); 14621308Sache if (count > 0 && p[-1] == *p + 1) 14721308Sache { 14821308Sache printf ("-"); 14921308Sache do 15021308Sache { 15121308Sache p--; 15221308Sache count--; 15321308Sache } 15421308Sache while (count > 0 && p[-1] == *p + 1); 15521308Sache printf ("%d", *p + 1); 15621308Sache } 15721308Sache first = false; 15821308Sache } 15921308Sache } 16021308Sache if (seen_LASTCHAR) 16121308Sache { 16221308Sache if (!first) 16321308Sache printf (","); 16421308Sache printf ("$"); 16521308Sache } 16621308Sache } 16721308Sache} 16875409Sache 16975409Sache/* ------------------------------------------------------------------------- */ 17075409Sache 17121308Sache#ifndef __OPTIMIZE__ 172165675Sache 17375409Sache#define INLINE /* not inline */ 17421308Sache#include "positions.icc" 17521308Sache#undef INLINE 17621308Sache 17721308Sache#endif /* not defined __OPTIMIZE__ */ 17821308Sache