ccl.c revision 2259
1160814Ssimon/* ccl - routines for character classes */
2160814Ssimon
3160814Ssimon/*-
4160814Ssimon * Copyright (c) 1990 The Regents of the University of California.
5160814Ssimon * All rights reserved.
6160814Ssimon *
7160814Ssimon * This code is derived from software contributed to Berkeley by
8160814Ssimon * Vern Paxson.
9160814Ssimon *
10160814Ssimon * The United States Government has rights in this work pursuant
11160814Ssimon * to contract no. DE-AC03-76SF00098 between the United States
12160814Ssimon * Department of Energy and the University of California.
13160814Ssimon *
14160814Ssimon * Redistribution and use in source and binary forms are permitted provided
15160814Ssimon * that: (1) source distributions retain this entire copyright notice and
16160814Ssimon * comment, and (2) distributions including binaries display the following
17160814Ssimon * acknowledgement:  ``This product includes software developed by the
18160814Ssimon * University of California, Berkeley and its contributors'' in the
19160814Ssimon * documentation or other materials provided with the distribution and in
20160814Ssimon * all advertising materials mentioning features or use of this software.
21160814Ssimon * Neither the name of the University nor the names of its contributors may
22160814Ssimon * be used to endorse or promote products derived from this software without
23160814Ssimon * specific prior written permission.
24160814Ssimon * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
25160814Ssimon * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
26160814Ssimon * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27160814Ssimon */
28160814Ssimon
29160814Ssimon/* $Header: /home/daffy/u0/vern/flex/RCS/ccl.c,v 2.9 93/09/16 20:32:14 vern Exp $ */
30160814Ssimon
31160814Ssimon#include "flexdef.h"
32160814Ssimon
33160814Ssimon/* ccladd - add a single character to a ccl */
34160814Ssimon
35160814Ssimonvoid ccladd( cclp, ch )
36160814Ssimonint cclp;
37160814Ssimonint ch;
38160814Ssimon	{
39160814Ssimon	int ind, len, newpos, i;
40160814Ssimon
41160814Ssimon	check_char( ch );
42160814Ssimon
43160814Ssimon	len = ccllen[cclp];
44160814Ssimon	ind = cclmap[cclp];
45160814Ssimon
46160814Ssimon	/* check to see if the character is already in the ccl */
47160814Ssimon
48160814Ssimon	for ( i = 0; i < len; ++i )
49160814Ssimon		if ( ccltbl[ind + i] == ch )
50160814Ssimon			return;
51160814Ssimon
52160814Ssimon	newpos = ind + len;
53160814Ssimon
54160814Ssimon	if ( newpos >= current_max_ccl_tbl_size )
55160814Ssimon		{
56160814Ssimon		current_max_ccl_tbl_size += MAX_CCL_TBL_SIZE_INCREMENT;
57160814Ssimon
58160814Ssimon		++num_reallocs;
59160814Ssimon
60160814Ssimon		ccltbl = reallocate_Character_array( ccltbl,
61160814Ssimon						current_max_ccl_tbl_size );
62160814Ssimon		}
63160814Ssimon
64160814Ssimon	ccllen[cclp] = len + 1;
65160814Ssimon	ccltbl[newpos] = ch;
66160814Ssimon	}
67160814Ssimon
68160814Ssimon
69160814Ssimon/* cclinit - return an empty ccl */
70160814Ssimon
71160814Ssimonint cclinit()
72160814Ssimon	{
73160814Ssimon	if ( ++lastccl >= current_maxccls )
74160814Ssimon		{
75160814Ssimon		current_maxccls += MAX_CCLS_INCREMENT;
76160814Ssimon
77160814Ssimon		++num_reallocs;
78160814Ssimon
79160814Ssimon		cclmap = reallocate_integer_array( cclmap, current_maxccls );
80160814Ssimon		ccllen = reallocate_integer_array( ccllen, current_maxccls );
81160814Ssimon		cclng = reallocate_integer_array( cclng, current_maxccls );
82160814Ssimon		}
83160814Ssimon
84160814Ssimon	if ( lastccl == 1 )
85160814Ssimon		/* we're making the first ccl */
86160814Ssimon		cclmap[lastccl] = 0;
87160814Ssimon
88160814Ssimon	else
89160814Ssimon		/* The new pointer is just past the end of the last ccl.
90160814Ssimon		 * Since the cclmap points to the \first/ character of a
91160814Ssimon		 * ccl, adding the length of the ccl to the cclmap pointer
92160814Ssimon		 * will produce a cursor to the first free space.
93160814Ssimon		 */
94160814Ssimon		cclmap[lastccl] = cclmap[lastccl - 1] + ccllen[lastccl - 1];
95160814Ssimon
96160814Ssimon	ccllen[lastccl] = 0;
97160814Ssimon	cclng[lastccl] = 0;	/* ccl's start out life un-negated */
98264331Sjkim
99160814Ssimon	return lastccl;
100160814Ssimon	}
101160814Ssimon
102160814Ssimon
103160814Ssimon/* cclnegate - negate the given ccl */
104160814Ssimon
105160814Ssimonvoid cclnegate( cclp )
106160814Ssimonint cclp;
107160814Ssimon	{
108160814Ssimon	cclng[cclp] = 1;
109160814Ssimon	}
110160814Ssimon
111160814Ssimon
112160814Ssimon/* list_character_set - list the members of a set of characters in CCL form
113160814Ssimon *
114160814Ssimon * Writes to the given file a character-class representation of those
115160814Ssimon * characters present in the given CCL.  A character is present if it
116160814Ssimon * has a non-zero value in the cset array.
117238405Sjkim */
118160814Ssimon
119160814Ssimonvoid list_character_set( file, cset )
120160814SsimonFILE *file;
121160814Ssimonint cset[];
122160814Ssimon	{
123160814Ssimon	register int i;
124160814Ssimon
125160814Ssimon	putc( '[', file );
126160814Ssimon
127160814Ssimon	for ( i = 0; i < csize; ++i )
128160814Ssimon		{
129160814Ssimon		if ( cset[i] )
130160814Ssimon			{
131160814Ssimon			register int start_char = i;
132160814Ssimon
133160814Ssimon			putc( ' ', file );
134264331Sjkim
135264331Sjkim			fputs( readable_form( i ), file );
136160814Ssimon
137160814Ssimon			while ( ++i < csize && cset[i] )
138160814Ssimon				;
139160814Ssimon
140160814Ssimon			if ( i - 1 > start_char )
141160814Ssimon				/* this was a run */
142160814Ssimon				fprintf( file, "-%s", readable_form( i - 1 ) );
143160814Ssimon
144160814Ssimon			putc( ' ', file );
145160814Ssimon			}
146160814Ssimon		}
147160814Ssimon
148160814Ssimon	putc( ']', file );
149160814Ssimon	}
150160814Ssimon