Header And Logo

PostgreSQL
| The world's most advanced open source database.

regc_cvec.c

Go to the documentation of this file.
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 }