1 | /* |
2 | * Utility functions for handling cvecs |
3 | * This file is #included by regcomp.c. |
4 | * |
5 | * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved. |
6 | * |
7 | * Development of this software was funded, in part, by Cray Research Inc., |
8 | * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics |
9 | * Corporation, none of whom are responsible for the results. The author |
10 | * thanks all of them. |
11 | * |
12 | * Redistribution and use in source and binary forms -- with or without |
13 | * modification -- are permitted for any purpose, provided that |
14 | * redistributions in source form retain this entire copyright notice and |
15 | * indicate the origin and nature of any modifications. |
16 | * |
17 | * I'd appreciate being given credit for this package in the documentation |
18 | * of software which uses it, but that is not a requirement. |
19 | * |
20 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, |
21 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY |
22 | * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL |
23 | * HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; |
26 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
27 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
28 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
29 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
30 | * |
31 | * src/backend/regex/regc_cvec.c |
32 | * |
33 | */ |
34 | |
35 | /* |
36 | * Notes: |
37 | * Only (selected) functions in _this_ file should treat the chr arrays |
38 | * of a cvec as non-constant. |
39 | */ |
40 | |
41 | /* |
42 | * newcvec - allocate a new cvec |
43 | */ |
44 | static struct cvec * |
45 | newcvec(int nchrs, /* to hold this many chrs... */ |
46 | int nranges) /* ... and this many ranges */ |
47 | { |
48 | size_t nc = (size_t) nchrs + (size_t) nranges * 2; |
49 | size_t n = sizeof(struct cvec) + nc * sizeof(chr); |
50 | struct cvec *cv = (struct cvec *) MALLOC(n); |
51 | |
52 | if (cv == NULL) |
53 | return NULL; |
54 | cv->chrspace = nchrs; |
55 | cv->chrs = (chr *) (((char *) cv) + sizeof(struct cvec)); |
56 | cv->ranges = cv->chrs + nchrs; |
57 | cv->rangespace = nranges; |
58 | return clearcvec(cv); |
59 | } |
60 | |
61 | /* |
62 | * clearcvec - clear a possibly-new cvec |
63 | * Returns pointer as convenience. |
64 | */ |
65 | static struct cvec * |
66 | clearcvec(struct cvec *cv) |
67 | { |
68 | assert(cv != NULL); |
69 | cv->nchrs = 0; |
70 | cv->nranges = 0; |
71 | cv->cclasscode = -1; |
72 | return cv; |
73 | } |
74 | |
75 | /* |
76 | * addchr - add a chr to a cvec |
77 | */ |
78 | static void |
79 | addchr(struct cvec *cv, /* character vector */ |
80 | chr c) /* character to add */ |
81 | { |
82 | assert(cv->nchrs < cv->chrspace); |
83 | cv->chrs[cv->nchrs++] = c; |
84 | } |
85 | |
86 | /* |
87 | * addrange - add a range to a cvec |
88 | */ |
89 | static void |
90 | addrange(struct cvec *cv, /* character vector */ |
91 | chr from, /* first character of range */ |
92 | chr to) /* last character of range */ |
93 | { |
94 | assert(cv->nranges < cv->rangespace); |
95 | cv->ranges[cv->nranges * 2] = from; |
96 | cv->ranges[cv->nranges * 2 + 1] = to; |
97 | cv->nranges++; |
98 | } |
99 | |
100 | /* |
101 | * getcvec - get a transient cvec, initialized to empty |
102 | * |
103 | * The returned cvec is valid only until the next call of getcvec, which |
104 | * typically will recycle the space. Callers should *not* free the cvec |
105 | * explicitly; it will be cleaned up when the struct vars is destroyed. |
106 | * |
107 | * This is typically used while interpreting bracket expressions. In that |
108 | * usage the cvec is only needed momentarily until we build arcs from it, |
109 | * so transientness is a convenient behavior. |
110 | */ |
111 | static struct cvec * |
112 | getcvec(struct vars *v, /* context */ |
113 | int nchrs, /* to hold this many chrs... */ |
114 | int nranges) /* ... and this many ranges */ |
115 | { |
116 | /* recycle existing transient cvec if large enough */ |
117 | if (v->cv != NULL && nchrs <= v->cv->chrspace && |
118 | nranges <= v->cv->rangespace) |
119 | return clearcvec(v->cv); |
120 | |
121 | /* nope, make a new one */ |
122 | if (v->cv != NULL) |
123 | freecvec(v->cv); |
124 | v->cv = newcvec(nchrs, nranges); |
125 | if (v->cv == NULL) |
126 | ERR(REG_ESPACE); |
127 | |
128 | return v->cv; |
129 | } |
130 | |
131 | /* |
132 | * freecvec - free a cvec |
133 | */ |
134 | static void |
135 | freecvec(struct cvec *cv) |
136 | { |
137 | FREE(cv); |
138 | } |
139 | |