xref: /openbsd/usr.bin/lex/ccl.c (revision 898184e3)
1 /*	$OpenBSD: ccl.c,v 1.6 2003/06/04 17:34:44 millert Exp $	*/
2 
3 /* ccl - routines for character classes */
4 
5 /*-
6  * Copyright (c) 1990 The Regents of the University of California.
7  * All rights reserved.
8  *
9  * This code is derived from software contributed to Berkeley by
10  * Vern Paxson.
11  *
12  * The United States Government has rights in this work pursuant
13  * to contract no. DE-AC03-76SF00098 between the United States
14  * Department of Energy and the University of California.
15  *
16  * Redistribution and use in source and binary forms, with or without
17  * modification, are permitted provided that the following conditions
18  * are met:
19  *
20  * 1. Redistributions of source code must retain the above copyright
21  *    notice, this list of conditions and the following disclaimer.
22  * 2. Redistributions in binary form must reproduce the above copyright
23  *    notice, this list of conditions and the following disclaimer in the
24  *    documentation and/or other materials provided with the distribution.
25  *
26  * Neither the name of the University nor the names of its contributors
27  * may be used to endorse or promote products derived from this software
28  * without specific prior written permission.
29  *
30  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
31  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
32  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
33  * PURPOSE.
34  */
35 
36 /* $Header: /home/cvs/src/usr.bin/lex/ccl.c,v 1.6 2003/06/04 17:34:44 millert Exp $ */
37 
38 #include "flexdef.h"
39 
40 /* ccladd - add a single character to a ccl */
41 
42 void ccladd( cclp, ch )
43 int cclp;
44 int ch;
45 	{
46 	int ind, len, newpos, i;
47 
48 	check_char( ch );
49 
50 	len = ccllen[cclp];
51 	ind = cclmap[cclp];
52 
53 	/* check to see if the character is already in the ccl */
54 
55 	for ( i = 0; i < len; ++i )
56 		if ( ccltbl[ind + i] == ch )
57 			return;
58 
59 	newpos = ind + len;
60 
61 	if ( newpos >= current_max_ccl_tbl_size )
62 		{
63 		current_max_ccl_tbl_size += MAX_CCL_TBL_SIZE_INCREMENT;
64 
65 		++num_reallocs;
66 
67 		ccltbl = reallocate_Character_array( ccltbl,
68 						current_max_ccl_tbl_size );
69 		}
70 
71 	ccllen[cclp] = len + 1;
72 	ccltbl[newpos] = ch;
73 	}
74 
75 
76 /* cclinit - return an empty ccl */
77 
78 int cclinit()
79 	{
80 	if ( ++lastccl >= current_maxccls )
81 		{
82 		current_maxccls += MAX_CCLS_INCREMENT;
83 
84 		++num_reallocs;
85 
86 		cclmap = reallocate_integer_array( cclmap, current_maxccls );
87 		ccllen = reallocate_integer_array( ccllen, current_maxccls );
88 		cclng = reallocate_integer_array( cclng, current_maxccls );
89 		}
90 
91 	if ( lastccl == 1 )
92 		/* we're making the first ccl */
93 		cclmap[lastccl] = 0;
94 
95 	else
96 		/* The new pointer is just past the end of the last ccl.
97 		 * Since the cclmap points to the \first/ character of a
98 		 * ccl, adding the length of the ccl to the cclmap pointer
99 		 * will produce a cursor to the first free space.
100 		 */
101 		cclmap[lastccl] = cclmap[lastccl - 1] + ccllen[lastccl - 1];
102 
103 	ccllen[lastccl] = 0;
104 	cclng[lastccl] = 0;	/* ccl's start out life un-negated */
105 
106 	return lastccl;
107 	}
108 
109 
110 /* cclnegate - negate the given ccl */
111 
112 void cclnegate( cclp )
113 int cclp;
114 	{
115 	cclng[cclp] = 1;
116 	}
117 
118 
119 /* list_character_set - list the members of a set of characters in CCL form
120  *
121  * Writes to the given file a character-class representation of those
122  * characters present in the given CCL.  A character is present if it
123  * has a non-zero value in the cset array.
124  */
125 
126 void list_character_set( file, cset )
127 FILE *file;
128 int cset[];
129 	{
130 	int i;
131 
132 	putc( '[', file );
133 
134 	for ( i = 0; i < csize; ++i )
135 		{
136 		if ( cset[i] )
137 			{
138 			int start_char = i;
139 
140 			putc( ' ', file );
141 
142 			fputs( readable_form( i ), file );
143 
144 			while ( ++i < csize && cset[i] )
145 				;
146 
147 			if ( i - 1 > start_char )
148 				/* this was a run */
149 				fprintf( file, "-%s", readable_form( i - 1 ) );
150 
151 			putc( ' ', file );
152 			}
153 		}
154 
155 	putc( ']', file );
156 	}
157