00001 /* 00002 * Utility functions for handling cvecs 00003 * This file is #included by regcomp.c. 00004 * 00005 * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved. 00006 * 00007 * Development of this software was funded, in part, by Cray Research Inc., 00008 * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics 00009 * Corporation, none of whom are responsible for the results. The author 00010 * thanks all of them. 00011 * 00012 * Redistribution and use in source and binary forms -- with or without 00013 * modification -- are permitted for any purpose, provided that 00014 * redistributions in source form retain this entire copyright notice and 00015 * indicate the origin and nature of any modifications. 00016 * 00017 * I'd appreciate being given credit for this package in the documentation 00018 * of software which uses it, but that is not a requirement. 00019 * 00020 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 00021 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 00022 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 00023 * HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00024 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00025 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 00026 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 00027 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 00028 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 00029 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00030 * 00031 * src/backend/regex/regc_cvec.c 00032 * 00033 */ 00034 00035 /* 00036 * Notes: 00037 * Only (selected) functions in _this_ file should treat chr* as non-constant. 00038 */ 00039 00040 /* 00041 * newcvec - allocate a new cvec 00042 */ 00043 static struct cvec * 00044 newcvec(int nchrs, /* to hold this many chrs... */ 00045 int nranges) /* ... and this many ranges */ 00046 { 00047 size_t nc = (size_t) nchrs + (size_t) nranges * 2; 00048 size_t n = sizeof(struct cvec) + nc * sizeof(chr); 00049 struct cvec *cv = (struct cvec *) MALLOC(n); 00050 00051 if (cv == NULL) 00052 return NULL; 00053 cv->chrspace = nchrs; 00054 cv->chrs = (chr *) (((char *) cv) + sizeof(struct cvec)); 00055 cv->ranges = cv->chrs + nchrs; 00056 cv->rangespace = nranges; 00057 return clearcvec(cv); 00058 } 00059 00060 /* 00061 * clearcvec - clear a possibly-new cvec 00062 * Returns pointer as convenience. 00063 */ 00064 static struct cvec * 00065 clearcvec(struct cvec * cv) 00066 { 00067 assert(cv != NULL); 00068 cv->nchrs = 0; 00069 cv->nranges = 0; 00070 return cv; 00071 } 00072 00073 /* 00074 * addchr - add a chr to a cvec 00075 */ 00076 static void 00077 addchr(struct cvec * cv, /* character vector */ 00078 chr c) /* character to add */ 00079 { 00080 assert(cv->nchrs < cv->chrspace); 00081 cv->chrs[cv->nchrs++] = (chr) c; 00082 } 00083 00084 /* 00085 * addrange - add a range to a cvec 00086 */ 00087 static void 00088 addrange(struct cvec * cv, /* character vector */ 00089 chr from, /* first character of range */ 00090 chr to) /* last character of range */ 00091 { 00092 assert(cv->nranges < cv->rangespace); 00093 cv->ranges[cv->nranges * 2] = (chr) from; 00094 cv->ranges[cv->nranges * 2 + 1] = (chr) to; 00095 cv->nranges++; 00096 } 00097 00098 /* 00099 * getcvec - get a transient cvec, initialized to empty 00100 * 00101 * The returned cvec is valid only until the next call of getcvec, which 00102 * typically will recycle the space. Callers should *not* free the cvec 00103 * explicitly; it will be cleaned up when the struct vars is destroyed. 00104 * 00105 * This is typically used while interpreting bracket expressions. In that 00106 * usage the cvec is only needed momentarily until we build arcs from it, 00107 * so transientness is a convenient behavior. 00108 */ 00109 static struct cvec * 00110 getcvec(struct vars * v, /* context */ 00111 int nchrs, /* to hold this many chrs... */ 00112 int nranges) /* ... and this many ranges */ 00113 { 00114 /* recycle existing transient cvec if large enough */ 00115 if (v->cv != NULL && nchrs <= v->cv->chrspace && 00116 nranges <= v->cv->rangespace) 00117 return clearcvec(v->cv); 00118 00119 /* nope, make a new one */ 00120 if (v->cv != NULL) 00121 freecvec(v->cv); 00122 v->cv = newcvec(nchrs, nranges); 00123 if (v->cv == NULL) 00124 ERR(REG_ESPACE); 00125 00126 return v->cv; 00127 } 00128 00129 /* 00130 * freecvec - free a cvec 00131 */ 00132 static void 00133 freecvec(struct cvec * cv) 00134 { 00135 FREE(cv); 00136 }