/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 | | * Note: in current usage, nchrs and nranges are never so large that we risk |
45 | | * integer overflow in these size calculations, even with 32-bit size_t. |
46 | | */ |
47 | | static struct cvec * |
48 | | newcvec(int nchrs, /* to hold this many chrs... */ |
49 | | int nranges) /* ... and this many ranges */ |
50 | 0 | { |
51 | 0 | size_t nc = (size_t) nchrs + (size_t) nranges * 2; |
52 | 0 | size_t n = sizeof(struct cvec) + nc * sizeof(chr); |
53 | 0 | struct cvec *cv = (struct cvec *) MALLOC(n); |
54 | |
|
55 | 0 | if (cv == NULL) |
56 | 0 | return NULL; |
57 | 0 | cv->chrspace = nchrs; |
58 | 0 | cv->chrs = (chr *) (((char *) cv) + sizeof(struct cvec)); |
59 | 0 | cv->ranges = cv->chrs + nchrs; |
60 | 0 | cv->rangespace = nranges; |
61 | 0 | return clearcvec(cv); |
62 | 0 | } |
63 | | |
64 | | /* |
65 | | * clearcvec - clear a possibly-new cvec |
66 | | * Returns pointer as convenience. |
67 | | */ |
68 | | static struct cvec * |
69 | | clearcvec(struct cvec *cv) |
70 | 0 | { |
71 | 0 | assert(cv != NULL); |
72 | 0 | cv->nchrs = 0; |
73 | 0 | cv->nranges = 0; |
74 | 0 | cv->cclasscode = -1; |
75 | 0 | return cv; |
76 | 0 | } |
77 | | |
78 | | /* |
79 | | * addchr - add a chr to a cvec |
80 | | */ |
81 | | static void |
82 | | addchr(struct cvec *cv, /* character vector */ |
83 | | chr c) /* character to add */ |
84 | 0 | { |
85 | 0 | assert(cv->nchrs < cv->chrspace); |
86 | 0 | cv->chrs[cv->nchrs++] = c; |
87 | 0 | } |
88 | | |
89 | | /* |
90 | | * addrange - add a range to a cvec |
91 | | */ |
92 | | static void |
93 | | addrange(struct cvec *cv, /* character vector */ |
94 | | chr from, /* first character of range */ |
95 | | chr to) /* last character of range */ |
96 | 0 | { |
97 | 0 | assert(cv->nranges < cv->rangespace); |
98 | 0 | cv->ranges[cv->nranges * 2] = from; |
99 | 0 | cv->ranges[cv->nranges * 2 + 1] = to; |
100 | 0 | cv->nranges++; |
101 | 0 | } |
102 | | |
103 | | /* |
104 | | * getcvec - get a transient cvec, initialized to empty |
105 | | * |
106 | | * The returned cvec is valid only until the next call of getcvec, which |
107 | | * typically will recycle the space. Callers should *not* free the cvec |
108 | | * explicitly; it will be cleaned up when the struct vars is destroyed. |
109 | | * |
110 | | * This is typically used while interpreting bracket expressions. In that |
111 | | * usage the cvec is only needed momentarily until we build arcs from it, |
112 | | * so transientness is a convenient behavior. |
113 | | */ |
114 | | static struct cvec * |
115 | | getcvec(struct vars *v, /* context */ |
116 | | int nchrs, /* to hold this many chrs... */ |
117 | | int nranges) /* ... and this many ranges */ |
118 | 0 | { |
119 | | /* recycle existing transient cvec if large enough */ |
120 | 0 | if (v->cv != NULL && nchrs <= v->cv->chrspace && |
121 | 0 | nranges <= v->cv->rangespace) |
122 | 0 | return clearcvec(v->cv); |
123 | | |
124 | | /* nope, make a new one */ |
125 | 0 | if (v->cv != NULL) |
126 | 0 | freecvec(v->cv); |
127 | 0 | v->cv = newcvec(nchrs, nranges); |
128 | 0 | if (v->cv == NULL) |
129 | 0 | ERR(REG_ESPACE); |
130 | |
|
131 | 0 | return v->cv; |
132 | 0 | } |
133 | | |
134 | | /* |
135 | | * freecvec - free a cvec |
136 | | */ |
137 | | static void |
138 | | freecvec(struct cvec *cv) |
139 | 0 | { |
140 | 0 | FREE(cv); |
141 | 0 | } |