Esempio n. 1
0
PUBLIC DBnamescheme *
DBMakeNamescheme(char const *fmt, ...)
{
    va_list ap;
    int i, j, k, n, pass, ncspecs, done, saved_narrefs;
    DBnamescheme *rv = 0;
    DBfile *dbfile = 0;
    char const *relpath = 0;

    /* We have nothing to do for a null or empty format string */
    if (fmt == 0 || *fmt == '\0')
        return 0;

    /* Start by allocating an empty name scheme */
    rv = DBAllocNamescheme();

    // set the delimeter character
    n = 0;
    while (fmt[n] != '\0')
    {
        if (fmt[n] == '%' && fmt[n+1] != '%')
            break;
        n++;
    }
    if (fmt[n] == '%') // have at least one conversion spec
        rv->delim = fmt[0];
    else
        rv->delim = '\0';
    
    /* compute length up to max of 4096 of initial segment of fmt representing
       the printf-style format string. */
    n = 1;
    while (n < 4096 && fmt[n] != '\0' && fmt[n] != rv->delim)
        n++;
    if (n == 4096) /* we pick arb. upper bound in length of 4096 */
    {
        DBFreeNamescheme(rv);
        return 0;
    }

    /* grab just the part of fmt that is the printf-style format string */
    rv->fmt = STRNDUP(&fmt[1],n-1);
    rv->fmtlen = n-1;

    /* In 2 passes, count conversion specs. and then setup pointers to each */ 
    for (pass = 0; pass < 2; pass++)
    {
        if (pass == 1)
        {
            rv->fmtptrs = (const char **) calloc(rv->ncspecs+1, sizeof(char*));
            rv->ncspecs = 0;
        }
        for (i = 0; i < rv->fmtlen-1; i++)
        {
            if (rv->fmt[i] == '%' && 
                rv->fmt[i+1] != '%')
            {
                if (pass == 1)
                    rv->fmtptrs[rv->ncspecs] = &(rv->fmt[i]);
                rv->ncspecs++;
            }
        }
    }
    rv->fmtptrs[rv->ncspecs] = &(rv->fmt[n+1]);

    /* If there are no conversion specs., we have nothing to do */
    /* However, in this case, assume the first char is a real char. */
    if (rv->ncspecs == 0)
    {
        free(rv->fmt);
        rv->fmt = STRNDUP(&fmt[0],n);
        rv->fmtlen = n;
        return rv;
    }

    /* Make a pass through rest of fmt string to count array refs in the
       expression substrings. */
    i = n+1;
    while (i < 4096 && fmt[i] != '\0')
    {
        if (fmt[i] == '$' || fmt[i] == '#')
            rv->narrefs++;
        i++;
    }
    if (i == 4096)
    {
        DBFreeNamescheme(rv);
        return 0;
    }

    /* allocate various arrays needed by the naming scheme */
    rv->exprstrs = (char **) calloc(rv->ncspecs, sizeof(char*));
    if (rv->narrefs > 0)
    {
        void *dummy;

        rv->arrnames = (char **) calloc(rv->narrefs, sizeof(char*));
        rv->arrvals  = (void **) calloc(rv->narrefs, sizeof(void*));
        rv->arrsizes =   (int *) calloc(rv->narrefs, sizeof(int));

        /* If we have non-zero ext. array references, then we may have the case of
           '0, DBfile*'. So, check for that now */
        va_start(ap, fmt);
        dummy = va_arg(ap, void *);
        if (dummy == 0)
        {
            dbfile = va_arg(ap, DBfile *);
            relpath = va_arg(ap, char const *);
            rv->arralloc = 1;
        }
Esempio n. 2
0
PUBLIC DBnamescheme *
DBMakeNamescheme(const char *fmt, ...)
{
    va_list ap;
    int i, j, k, n, pass, ncspecs, done;
    DBnamescheme *rv = 0;

    /* We have nothing to do for a null or empty format string */
    if (fmt == 0 || *fmt == '\0')
        return 0;

    /* Start by allocating an empty name scheme */
    rv = DBAllocNamescheme();
    
    /* set the delimeter character */
    rv->delim = fmt[0];

    /* compute length up to max of 4096 of initial segment of fmt representing
       the printf-style format string. */
    n = 1;
    while (n < 4096 && fmt[n] != '\0' && fmt[n] != rv->delim)
        n++;
    if (n == 4096) /* we pick arb. upper bound in length of 4096 */
    {
        DBFreeNamescheme(rv);
        return 0;
    }

    /* grab just the part of fmt that is the printf-style format string */
    rv->fmt = STRNDUP(&fmt[1],n-1);
    rv->fmtlen = n-1;

    /* In 2 passes, count conversion specs. and then setup pointers to each */ 
    for (pass = 0; pass < 2; pass++)
    {
        if (pass == 1)
        {
            rv->fmtptrs = (const char **) calloc(rv->ncspecs+1, sizeof(char*));
            rv->ncspecs = 0;
        }
        for (i = 0; i < rv->fmtlen-1; i++)
        {
            if (rv->fmt[i] == '%' && 
                rv->fmt[i+1] != '%')
            {
                if (pass == 1)
                    rv->fmtptrs[rv->ncspecs] = &(rv->fmt[i]);
                rv->ncspecs++;
            }
        }
    }
    rv->fmtptrs[rv->ncspecs] = &(rv->fmt[n+1]);

    /* If there are no conversion specs., we have nothing to do */
    if (rv->ncspecs == 0)
        return rv;

    /* Make a pass through rest of fmt string to count array refs in the
       expression substrings. */
    i = n+1;
    while (i < 4096 && fmt[i] != '\0')
    {
        if (fmt[i] == '$' || fmt[i] == '#')
            rv->narrefs++;
        i++;
    }
    if (i == 4096)
    {
        DBFreeNamescheme(rv);
        return 0;
    }

    /* allocate various arrays needed by the naming scheme */
    rv->exprstrs = (char **) calloc(rv->ncspecs, sizeof(char*));
    if (rv->narrefs > 0)
    {
        rv->arrnames = (char **) calloc(rv->narrefs, sizeof(char*));
        rv->arrvals  = (const int **) calloc(rv->narrefs, sizeof(int*));
    }

    /* Ok, now go through rest of fmt string a second time and grab each
       expression that goes with each conversion spec. Also, handle array refs */
    i = n+1;
    rv->narrefs = 0;
    ncspecs = 0;
    va_start(ap, fmt);
    done = 0;
    while (!done)
    {
        if (fmt[i] == '$' || fmt[i] == '#')
        {
            for (j = 1; fmt[i+j] != '['; j++)
                ;
            for (k = 0; k < rv->narrefs; k++)
            {
                if (strncmp(&fmt[i+1],rv->arrnames[k],j-1) == 0)
                    break;
            }
            if (k == rv->narrefs)
            {
                rv->arrnames[k] = STRNDUP(&fmt[i+1], j-1);
                rv->arrvals[k] = va_arg(ap, const int *);
                rv->narrefs++;
            }
        }
        else if (fmt[i] == rv->delim || fmt[i] == '\0')