Ejemplo n.º 1
0
int linkedlist_add_at(linkedlist _list, void* data, int i)
{
    linkedlist_t* list = (linkedlist_t*) _list;
    node* slider, *n;

    if(i > (list->size - 1))
        return add_at_last(list, data);

    if(i == 0)
        return add_at_first(list, data);
    else
    {
        slider = find_by_index(list, i);
        n = node_new(data);
        set_next(get_prev(slider), n);
        set_prev(n, get_prev(slider));
        set_next(n, slider);
        list->size++;
        return list->size;
    }
}
Ejemplo n.º 2
0
/* OpenColumnWrite
 *  open a column for write
 *
 *  "idx" [ OUT ] - return parameter for 1-based column index.
 *
 *  "col" [ OUT, NULL OKAY ] - optional return parameter for
 *  newly opened column.
 *
 *  "name" [ IN ] - NUL terminated string in UTF-8 giving column name
 *
 *  "datatype" [ IN ] - NUL terminated string in ASCII
 *   describing fully qualified column data type
 */
LIB_EXPORT rc_t CC SRATableOpenColumnWrite ( SRATable *self,
    uint32_t *idx, SRAColumn **col, const char *name, const char *datatype )
{
    rc_t rc;
    SRAColumn *rslt;
    uint32_t ndx, cndx;
    
    if (self == NULL)
        return RC(RC_MODULE, RC_TARGET, rcOpening, rcSelf, rcNull);
    
    if (name == NULL || idx == NULL)
        return RC(RC_MODULE, RC_TARGET, rcOpening, rcParam, rcNull);
    
    *idx = 0;
    
    if (datatype && datatype[0])
    {
        SRADBG(("adding column (%s)%s\n", datatype, name));
        rc = VCursorAddColumn(self->curs, &ndx, "(%s)%s", datatype, name);
    }
    else
    {
        SRADBG(("adding column %s\n", name));
        rc = VCursorAddColumn(self->curs, &ndx, "%s", name);
    }
    
    if (rc != 0)
    {
        /* it's okay if the column is already there
           any other rc is a hard error */
        if (GetRCState ( rc ) != rcExists)
            return rc;
        
        if ( ! find_by_index(&self->wcol, ndx, &cndx) )
        {
            /* severe internal error */
            return RC ( RC_MODULE, RC_TARGET, rcOpening, rcNoObj, rcNotFound );
        }

        /* get the uncounted reference to column from table */
        rslt = VectorGet(&self->wcol, cndx);
    }
    else
    {
        VTypedecl type;
        VTypedesc desc;
        
        rslt = malloc(sizeof *rslt );
        if (rslt == NULL)
            return RC(RC_MODULE, rcColumn, rcConstructing, rcMemory, rcExhausted);
        
        rc = VCursorDatatype(self->curs, ndx, &type, &desc);
        if (rc == 0)
        {
            /* this object will sit uncounted within the table
               when the table goes away, it will douse the columns
               without regard to their reference count. see below */
            KRefcountInit(&rslt->refcount, 0, "SRAColumn", "OpenColumnWrite", name);

            /* the column has no reference to the table, so after this
               there will only be an uncounted reference from table to column */
            rslt->tbl = NULL;
            rslt->idx = ndx;
            rslt->read_only = false;
            rslt->elem_bits = VTypedescSizeof(&desc);

            rc = VectorAppend(&self->wcol, &cndx, rslt);
        }

        if ( rc != 0 )
        {
            free ( rslt );
            return rc;
        }
    }

    /* see if user wants a reference */
    if ( col != NULL )
    {
        /* the first column reference exported will take
           the refcount from zero to one */
        SRAColumnAddRef ( rslt );

        /* the first exported reference will need to be reflected
           to the table. this will ensure that the table never tries
           to whack its columns as long as they are held externally,
           because the table itself will be kept alive. when the last
           column reference is released, it will also release the table */
        if ( rslt -> tbl == NULL )
            rslt -> tbl = SRATableAttach ( self );

        *col = rslt;
    }

    *idx = cndx + 1;
    return rc;
}
Ejemplo n.º 3
0
/**
 *  Find the definition entry for the name passed in.
 *  It is okay to find block entries IFF they are found on the
 *  current level.  Once you start traversing up the tree,
 *  the macro must be a text macro.  Return an indicator saying if
 *  the element has been indexed (so the caller will not try
 *  to traverse the list of twins).
 */
static tDefEntry*
find_def(char * pzName, tDefCtx* pDefCtx, ag_bool* pIsIndexed)
{
    char *       brace;
    char         br_ch;
    tDefEntry *  ent;
    ag_bool      dummy;
    ag_bool      noNesting    = AG_FALSE;

    static int   nestingDepth = 0;

    /*
     *  IF we are at the start of a search, then canonicalize the name
     *  we are hunting for, copying it to a modifiable buffer, and
     *  initialize the "indexed" boolean to false (we have not found
     *  an index yet).
     */
    if (nestingDepth == 0) {
        canonicalizeName(zDefinitionName, pzName, (int)strlen(pzName));
        pzName = zDefinitionName;

        if (pIsIndexed != NULL)
             *pIsIndexed = AG_FALSE;
        else pIsIndexed  = &dummy;

        if (*pzName == name_sep_ch) {
            noNesting = AG_TRUE;
            pzName++;
        }
    }

    brace  = BRK_NAME_SEP_CHARS(pzName);
    br_ch  = *brace;
    *brace = NUL;

    if (br_ch == '[') *pIsIndexed = AG_TRUE;

    for (;;) {
        /*
         *  IF we are at the end of the definitions (reached ROOT),
         *  THEN it is time to bail out.
         */
        ent = pDefCtx->pDefs;
        if (ent == NULL)
            return NULL;

        do  {
            /*
             *  IF the name matches
             *  THEN break out of the double loop
             */
            if (strcmp(ent->pzDefName, pzName) == 0)
                goto found_def_entry;

            ent = ent->pNext;
        } while (ent != NULL);

        /*
         *  IF we are nested, then we cannot change the definition level.
         *  So, we did not find anything.
         */
        if ((nestingDepth != 0) || noNesting)
            return NULL;

        /*
         *  Let's go try the definitions at the next higher level.
         */
        pDefCtx = pDefCtx->pPrev;
        if (pDefCtx == NULL)
            return NULL;
    } found_def_entry:;

    /*
     *  At this point, we have found the entry that matches the supplied name,
     *  up to the '[' or name_sep_ch or NUL character.  It *must* be one of
     *  those three characters.
     */
    *brace = br_ch;

    switch (br_ch) {
    case NUL:
        return ent;

    case '[':
        /*
         *  We have to find a specific entry in a list.
         */
        brace = SPN_WHITESPACE_CHARS(brace + 1);

        ent = find_by_index(ent, brace);
        if (ent == NULL)
            return ent;

        /*
         *  We must find the closing brace, or there is an error
         */
        brace = strchr(brace, ']');
        if (brace == NULL)
            ILLFORMEDNAME();

        /*
         *  What follows the closing brace?  IF we are at the end of the
         *  definition, THEN return what we found.  However, if there's
         *  another name, then we have to go look that one up, too.
         */
        switch (*++brace) {
        case NUL:
            return ent;

        case '.': case '/':
            /*
             *  Which one?  One is valid, the other not and it is not known
             *  at compile time.
             */
            if (*brace == name_sep_ch) {
                pzName = brace + 1;
                break;
            }
            /* FALLTHROUGH */

        default:
            ILLFORMEDNAME();
        }
        break;

    case '.': case '/':
        if (br_ch == name_sep_ch) {
            /*
             *  Which one?  One is valid, the other not and it is not known
             *  at compile time.
             *
             *  It is a segmented value name.  Set the name pointer
             *  to the next segment and search starting from the newly
             *  available set of definitions.
             */
            pzName = brace + 1;
            break;
        }
        /* FALLTHROUGH */

    default:
        ILLFORMEDNAME();
    }

    /*
     *  We cannot find a member of a non-block type macro definition.
     */
    if (ent->valType != VALTYP_BLOCK)
        return NULL;

    /*
     *  Loop through all the twins of the entry we found until
     *  we find the entry we want.  We ignore twins if we just
     *  used a subscript.
     */
    nestingDepth++;
    {
        tDefCtx ctx = { NULL, &currDefCtx };

        ctx.pDefs = ent->val.pDefEntry;

        for (;;) {
            tDefEntry* res;

            res = find_def(pzName, &ctx, pIsIndexed);
            if ((res != NULL) || (br_ch == '[')) {
                nestingDepth--;
                return res;
            }
            ent = ent->pTwin;
            if (ent == NULL)
                break;
            ctx.pDefs = ent->val.pDefEntry;
        }
    }

    nestingDepth--;
    return NULL;
}
Ejemplo n.º 4
0
void* linkedlist_remove_at(linkedlist _list, int i)
{
    node* n = find_by_index((linkedlist_t*)_list, i);
    if(NULL == n) return NULL;
    return linkedlist_remove(_list, n->data);
}
Ejemplo n.º 5
0
const void* linkedlist_get(linkedlist list, int i)
{
    node* n = find_by_index((linkedlist_t*)list, i);
    if(NULL == n) return NULL;
    return n->data;
}