/src/postgres/src/backend/regex/regc_cvec.c
Line | Count | Source |
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 | 0 | { |
48 | 0 | size_t nc = (size_t) nchrs + (size_t) nranges * 2; |
49 | 0 | size_t n = sizeof(struct cvec) + nc * sizeof(chr); |
50 | 0 | struct cvec *cv = (struct cvec *) MALLOC(n); |
51 | |
|
52 | 0 | if (cv == NULL) |
53 | 0 | return NULL; |
54 | 0 | cv->chrspace = nchrs; |
55 | 0 | cv->chrs = (chr *) (((char *) cv) + sizeof(struct cvec)); |
56 | 0 | cv->ranges = cv->chrs + nchrs; |
57 | 0 | cv->rangespace = nranges; |
58 | 0 | return clearcvec(cv); |
59 | 0 | } |
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 | 0 | { |
68 | 0 | assert(cv != NULL); |
69 | 0 | cv->nchrs = 0; |
70 | 0 | cv->nranges = 0; |
71 | 0 | cv->cclasscode = -1; |
72 | 0 | return cv; |
73 | 0 | } |
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 | 0 | { |
82 | 0 | assert(cv->nchrs < cv->chrspace); |
83 | 0 | cv->chrs[cv->nchrs++] = c; |
84 | 0 | } |
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 | 0 | { |
94 | 0 | assert(cv->nranges < cv->rangespace); |
95 | 0 | cv->ranges[cv->nranges * 2] = from; |
96 | 0 | cv->ranges[cv->nranges * 2 + 1] = to; |
97 | 0 | cv->nranges++; |
98 | 0 | } |
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 | 0 | { |
116 | | /* recycle existing transient cvec if large enough */ |
117 | 0 | if (v->cv != NULL && nchrs <= v->cv->chrspace && |
118 | 0 | nranges <= v->cv->rangespace) |
119 | 0 | return clearcvec(v->cv); |
120 | | |
121 | | /* nope, make a new one */ |
122 | 0 | if (v->cv != NULL) |
123 | 0 | freecvec(v->cv); |
124 | 0 | v->cv = newcvec(nchrs, nranges); |
125 | 0 | if (v->cv == NULL) |
126 | 0 | ERR(REG_ESPACE); |
127 | |
|
128 | 0 | return v->cv; |
129 | 0 | } |
130 | | |
131 | | /* |
132 | | * freecvec - free a cvec |
133 | | */ |
134 | | static void |
135 | | freecvec(struct cvec *cv) |
136 | 0 | { |
137 | 0 | FREE(cv); |
138 | 0 | } |