xref: /illumos-gate/usr/src/cmd/lp/lib/filters/regex.c (revision 7c478bd9)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
23 /*	  All Rights Reserved  	*/
24 
25 
26 /*
27  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
28  * Use is subject to license terms.
29  */
30 
31 #pragma ident	"%Z%%M%	%I%	%E% SMI"
32 
33 /* EMACS_MODES: !fill, lnumb, !overwrite, !nodelete, !picture */
34 
35 #include "sys/types.h"
36 #include "regexpr.h"
37 #include "regex.h"
38 #include "string.h"
39 
40 /**
41  ** match() - TEST MATCH OF TEMPLATE/PATTERN WITH PARAMETER
42  **/
43 
44 int
45 #if	defined(__STDC__)
46 match (
47 	char *			re,
48 	char *			value
49 )
50 #else
51 match (re, value)
52 	register char *		re;
53 	register char *		value;
54 #endif
55 {
56 	int			ret;
57 
58 	/*
59 	 * We want exact matches, just as if the regular expression
60 	 * was ^...$, to explicitly match the beginning and end of line.
61 	 * Using "advance" instead of "step" takes care of the ^ and
62 	 * checking where the match left off takes care of the $.
63 	 * We don't do something silly like add the ^ and $ ourselves,
64 	 * because the user may have done that already.
65 	 */
66 	ret = advance(value, re);
67 	if (ret && *loc2)
68 		ret = 0;
69 	return (ret);
70 }
71 
72 /**
73  ** replace() - REPLACE TEMPLATE WITH EXPANDED REGULAR EXPRESSION MATCH
74  **/
75 
76 size_t
77 #if	defined(__STDC__)
78 replace (
79 	char **			pp,
80 	char *			result,
81 	char *			value,
82 	int			nbra
83 )
84 #else
85 replace (pp, result, value)
86 	char **			pp;
87 	char *			result;
88 	char *			value;
89 	int			nbra;
90 #endif
91 {
92 	register char *		p;
93 	register char *		q;
94 
95 	register size_t		ncount	= 0;
96 
97 
98 /*
99  * Count and perhaps copy a single character:
100  */
101 #define	CCPY(SRC)	if ((ncount++, pp)) \
102 				*p++ = SRC
103 
104 /*
105  * Count and perhaps copy a string:
106  */
107 #define	SCPY(SRC)	if (pp) { \
108 				register char *	r; \
109 				for (r = (SRC); *r; ncount++) \
110 					*p++ = *r++; \
111 			} else \
112 				ncount += strlen(SRC)
113 
114 
115 	if (pp)
116 		p = *pp;
117 
118 	for (q = result; *q; q++)  switch (*q) {
119 
120 	case '*':
121 	case '&':
122 		SCPY (value);
123 		break;
124 
125 	case '\\':
126 		switch (*++q) {
127 		case '1':
128 		case '2':
129 		case '3':
130 		case '4':
131 		case '5':
132 		case '6':
133 		case '7':
134 		case '8':
135 		case '9':
136 		{
137 			register int		n = *q-'1';
138 
139 			if (n < nbra) {
140 				register char		c = *(braelist[n]);
141 
142 				*(braelist[n]) = 0;
143 				SCPY (braslist[n]);
144 				*(braelist[n]) = c;
145 			}
146 			break;
147 		}
148 
149 		default:
150 			CCPY (*q);
151 			break;
152 		}
153 		break;
154 
155 	default:
156 		CCPY (*q);
157 		break;
158 	}
159 
160 	if (pp)
161 		*pp = p;
162 
163 	return (ncount);
164 }
165