Changeset 7b87e1d in mainline


Ignore:
Timestamp:
2018-08-02T11:39:22Z (6 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
233a3a06
Parents:
1c398db2
git-author:
Jiri Svoboda <jiri@…> (2018-08-01 17:38:51)
git-committer:
Jiri Svoboda <jiri@…> (2018-08-02 11:39:22)
Message:

Implement SIF attributes.

Location:
uspace/lib/sif
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/sif/private/sif.h

    r1c398db2 r7b87e1d  
    3939
    4040#include <adt/list.h>
     41#include <adt/odict.h>
    4142#include <stdio.h>
    4243
     
    5455};
    5556
     57/** SIF attribute */
     58typedef struct {
     59        /** Node to which this attribute belongs */
     60        struct sif_node *node;
     61        /** Link to @c node->attrs */
     62        odlink_t lattrs;
     63        /** Attribute name */
     64        char *aname;
     65        /** Attribute value */
     66        char *avalue;
     67} sif_attr_t;
     68
    5669/** SIF node */
    5770struct sif_node {
     
    6275        /** Node type */
    6376        char *ntype;
     77        /** Attributes (of sif_attr_t) */
     78        odict_t attrs;
    6479        /** Child nodes */
    6580        list_t children;
  • uspace/lib/sif/src/sif.c

    r1c398db2 r7b87e1d  
    6060 */
    6161
     62#include <adt/list.h>
     63#include <adt/odict.h>
    6264#include <errno.h>
    6365#include <stdio.h>
     
    6971static errno_t sif_export_node(sif_node_t *, FILE *);
    7072static errno_t sif_import_node(sif_node_t *, FILE *, sif_node_t **);
     73static sif_attr_t *sif_node_first_attr(sif_node_t *);
     74static sif_attr_t *sif_node_next_attr(sif_attr_t *);
     75static void sif_attr_delete(sif_attr_t *);
     76static void *sif_attr_getkey(odlink_t *);
     77static int sif_attr_cmp(void *, void *);
    7178
    7279/** Create new SIF node.
    7380 *
    74  * @param parent Parent onde
     81 * @param parent Parent node
    7582 * @return Pointer to new node on success or @c NULL if out of memory
    7683 */
     
    8491
    8592        node->parent = parent;
     93        odict_initialize(&node->attrs, sif_attr_getkey, sif_attr_cmp);
    8694        list_initialize(&node->children);
    8795
     
    92100 *
    93101 * Delete a SIF node that has been already unlinked from the tree.
     102 * This will also delete any attributes or child nodes.
    94103 *
    95104 * @param node Node
     
    97106static void sif_node_delete(sif_node_t *node)
    98107{
     108        sif_attr_t *attr;
     109        sif_node_t *child;
     110
    99111        if (node == NULL)
    100112                return;
    101113
     114        assert(!link_used(&node->lparent));
     115
    102116        if (node->ntype != NULL)
    103117                free(node->ntype);
    104118
     119        attr = sif_node_first_attr(node);
     120        while (attr != NULL) {
     121                odict_remove(&attr->lattrs);
     122                sif_attr_delete(attr);
     123                attr = sif_node_first_attr(node);
     124        }
     125
     126        child = sif_node_first_child(node);
     127        while (child != NULL) {
     128                list_remove(&child->lparent);
     129                sif_node_delete(child);
     130                child = sif_node_first_child(node);
     131        }
     132
    105133        free(node);
     134}
     135
     136/** Create new SIF attribute.
     137 *
     138 * @param node Containing node
     139 * @return Pointer to new node on success or @c NULL if out of memory
     140 */
     141static sif_attr_t *sif_attr_new(sif_node_t *node)
     142{
     143        sif_attr_t *attr;
     144
     145        attr = calloc(1, sizeof(sif_attr_t));
     146        if (attr == NULL)
     147                return NULL;
     148
     149        attr->node = node;
     150        return attr;
     151}
     152
     153/** Delete SIF attribute.
     154 *
     155 * Delete a SIF attribute that has been already unlinked from is node.
     156 *
     157 * @param attr Attribute
     158 */
     159static void sif_attr_delete(sif_attr_t *attr)
     160{
     161        if (attr == NULL)
     162                return;
     163
     164        assert(!odlink_used(&attr->lattrs));
     165
     166        if (attr->aname != NULL)
     167                free(attr->aname);
     168        if (attr->avalue != NULL)
     169                free(attr->avalue);
     170
     171        free(attr);
    106172}
    107173
     
    114180 */
    115181errno_t sif_create(const char *fname, sif_sess_t **rsess)
     182{
     183        sif_sess_t *sess;
     184        sif_node_t *root = NULL;
     185        sif_trans_t *trans = NULL;
     186        errno_t rc;
     187        FILE *f;
     188
     189        sess = calloc(1, sizeof(sif_sess_t));
     190        if (sess == NULL)
     191                return ENOMEM;
     192
     193        root = sif_node_new(NULL);
     194        if (root == NULL) {
     195                rc = ENOMEM;
     196                goto error;
     197        }
     198
     199        root->ntype = str_dup("sif");
     200        if (root->ntype == NULL) {
     201                rc = ENOMEM;
     202                goto error;
     203        }
     204
     205        f = fopen(fname, "w");
     206        if (f == NULL) {
     207                rc = EIO;
     208                goto error;
     209        }
     210
     211        sess->f = f;
     212        sess->root = root;
     213
     214        /* Run a dummy trasaction to marshall initial repo state to file */
     215        rc = sif_trans_begin(sess, &trans);
     216        if (rc != EOK)
     217                goto error;
     218
     219        rc = sif_trans_end(trans);
     220        if (rc != EOK)
     221                goto error;
     222
     223        *rsess = sess;
     224        return EOK;
     225error:
     226        if (trans != NULL)
     227                sif_trans_abort(trans);
     228        sif_node_delete(root);
     229        free(sess);
     230        return rc;
     231}
     232
     233/** Open an existing SIF repository.
     234 *
     235 * @param fname File name
     236 * @param rsess Place to store pointer to new session.
     237 *
     238 * @return EOK on success or error code
     239 */
     240errno_t sif_open(const char *fname, sif_sess_t **rsess)
    116241{
    117242        sif_sess_t *sess;
     
    124249                return ENOMEM;
    125250
    126         root = sif_node_new(NULL);
    127         if (root == NULL) {
    128                 rc = ENOMEM;
    129                 goto error;
    130         }
    131 
    132         root->ntype = str_dup("sif");
    133         if (root->ntype == NULL) {
    134                 rc = ENOMEM;
    135                 goto error;
    136         }
    137 
    138         f = fopen(fname, "w");
     251        f = fopen(fname, "r+");
    139252        if (f == NULL) {
    140253                rc = EIO;
    141254                goto error;
    142255        }
     256
     257        rc = sif_import_node(NULL, f, &root);
     258        if (rc != EOK)
     259                goto error;
     260
     261        if (str_cmp(root->ntype, "sif") != 0) {
     262                rc = EIO;
     263                goto error;
     264        }
     265
     266        sess->root = root;
    143267
    144268        sess->f = f;
     
    152276}
    153277
    154 /** Open an existing SIF repository.
    155  *
    156  * @param fname File name
    157  * @param rsess Place to store pointer to new session.
    158  *
    159  * @return EOK on success or error code
    160  */
    161 errno_t sif_open(const char *fname, sif_sess_t **rsess)
    162 {
    163         sif_sess_t *sess;
    164         sif_node_t *root = NULL;
    165         errno_t rc;
    166         FILE *f;
    167 
    168         sess = calloc(1, sizeof(sif_sess_t));
    169         if (sess == NULL)
    170                 return ENOMEM;
    171 
    172         f = fopen(fname, "r+");
    173         if (f == NULL) {
    174                 rc = EIO;
    175                 goto error;
    176         }
    177 
    178         rc = sif_import_node(NULL, f, &root);
    179         if (rc != EOK)
    180                 goto error;
    181 
    182         if (str_cmp(root->ntype, "sif") != 0) {
    183                 rc = EIO;
    184                 goto error;
    185         }
    186 
    187         sess->root = root;
    188 
    189         sess->f = f;
    190         sess->root = root;
    191         *rsess = sess;
    192         return EOK;
    193 error:
    194         sif_node_delete(root);
    195         free(sess);
    196         return rc;
    197 }
    198 
    199278/** Close SIF session.
    200279 *
     
    274353const char *sif_node_get_attr(sif_node_t *node, const char *aname)
    275354{
    276         return NULL;
     355        odlink_t *link;
     356        sif_attr_t *attr;
     357
     358        link = odict_find_eq(&node->attrs, (void *)aname, NULL);
     359        if (link == NULL)
     360                return NULL;
     361
     362        attr = odict_get_instance(link, sif_attr_t, lattrs);
     363        return attr->avalue;
    277364}
    278365
     
    296383
    297384/** Commit SIF transaction.
     385 *
     386 * Commit and free the transaction. If an error is returned, that means
     387 * the transaction has not been freed (and sif_trans_abort() must be used).
    298388 *
    299389 * @param trans Transaction
     
    320410void sif_trans_abort(sif_trans_t *trans)
    321411{
     412        free(trans);
    322413}
    323414
     
    461552void sif_node_destroy(sif_trans_t *trans, sif_node_t *node)
    462553{
    463         sif_node_t *child;
    464 
    465         child = sif_node_first_child(node);
    466         while (child != NULL) {
    467                 sif_node_destroy(trans, child);
    468                 child = sif_node_first_child(node);
    469         }
    470 
    471554        list_remove(&node->lparent);
    472555        sif_node_delete(node);
     
    483566 */
    484567errno_t sif_node_set_attr(sif_trans_t *trans, sif_node_t *node,
    485     const char *aname, const char *value)
    486 {
     568    const char *aname, const char *avalue)
     569{
     570        odlink_t *link;
     571        sif_attr_t *attr;
     572        char *cvalue;
     573
     574        link = odict_find_eq(&node->attrs, (void *)aname, NULL);
     575
     576        if (link != NULL) {
     577                attr = odict_get_instance(link, sif_attr_t, lattrs);
     578                cvalue = str_dup(avalue);
     579                if (cvalue == NULL)
     580                        return ENOMEM;
     581
     582                free(attr->avalue);
     583                attr->avalue = cvalue;
     584        } else {
     585                attr = sif_attr_new(node);
     586                if (attr == NULL)
     587                        return ENOMEM;
     588
     589                attr->aname = str_dup(aname);
     590                if (attr->aname == NULL) {
     591                        sif_attr_delete(attr);
     592                        return ENOMEM;
     593                }
     594
     595                attr->avalue = str_dup(avalue);
     596                if (attr->avalue == NULL) {
     597                        sif_attr_delete(attr);
     598                        return ENOMEM;
     599                }
     600
     601                odict_insert(&attr->lattrs, &node->attrs, NULL);
     602        }
     603
    487604        return EOK;
    488605}
     
    500617    const char *aname)
    501618{
     619        odlink_t *link;
     620        sif_attr_t *attr;
     621
     622        link = odict_find_eq(&node->attrs, (void *)aname, NULL);
     623        if (link == NULL)
     624                return;
     625
     626        attr = odict_get_instance(link, sif_attr_t, lattrs);
     627        odict_remove(link);
     628        sif_attr_delete(attr);
    502629}
    503630
     
    601728}
    602729
     730/** Import SIF attribute from file.
     731 *
     732 * @param node Node under which attribute shou
     733 * @param f File
     734 * @param rattr Place to store pointer to imported SIF attribute
     735 * @return EOK on success, EIO on I/O error
     736 */
     737static errno_t sif_import_attr(sif_node_t *node, FILE *f, sif_attr_t **rattr)
     738{
     739        errno_t rc;
     740        char *aname = NULL;
     741        char *avalue = NULL;
     742        sif_attr_t *attr;
     743        int c;
     744
     745        rc = sif_import_string(f, &aname);
     746        if (rc != EOK)
     747                goto error;
     748
     749        c = fgetc(f);
     750        if (c != '=') {
     751                rc = EIO;
     752                goto error;
     753        }
     754
     755        rc = sif_import_string(f, &avalue);
     756        if (rc != EOK)
     757                goto error;
     758
     759        attr = sif_attr_new(node);
     760        if (attr == NULL) {
     761                rc = ENOMEM;
     762                goto error;
     763        }
     764
     765        attr->aname = aname;
     766        attr->avalue = avalue;
     767
     768        *rattr = attr;
     769        return EOK;
     770error:
     771        if (aname != NULL)
     772                free(aname);
     773        if (avalue != NULL)
     774                free(avalue);
     775        return rc;
     776}
     777
     778
     779/** Export SIF attribute to file.
     780 *
     781 * @param attr SIF attribute
     782 * @param f File
     783 * @return EOK on success, EIO on I/O error
     784 */
     785static errno_t sif_export_attr(sif_attr_t *attr, FILE *f)
     786{
     787        errno_t rc;
     788
     789        rc = sif_export_string(attr->aname, f);
     790        if (rc != EOK)
     791                return rc;
     792
     793        if (fputc('=', f) == EOF)
     794                return EIO;
     795
     796        rc = sif_export_string(attr->avalue, f);
     797        if (rc != EOK)
     798                return rc;
     799
     800        return EOK;
     801}
     802
    603803/** Export SIF node to file.
    604804 *
     
    610810{
    611811        errno_t rc;
     812        sif_attr_t *attr;
    612813        sif_node_t *child;
    613814
     
    615816        if (rc != EOK)
    616817                return rc;
     818
     819        /* Attributes */
     820
     821        if (fputc('(', f) == EOF)
     822                return EIO;
     823
     824        attr = sif_node_first_attr(node);
     825        while (attr != NULL) {
     826                rc = sif_export_attr(attr, f);
     827                if (rc != EOK)
     828                        return rc;
     829
     830                attr = sif_node_next_attr(attr);
     831        }
     832
     833        if (fputc(')', f) == EOF)
     834                return EIO;
     835
     836        /* Child nodes */
    617837
    618838        if (fputc('{', f) == EOF)
     
    646866        sif_node_t *node = NULL;
    647867        sif_node_t *child;
     868        sif_attr_t *attr;
    648869        char *ntype;
    649870        int c;
     
    659880        node->ntype = ntype;
    660881
     882        /* Attributes */
     883
    661884        c = fgetc(f);
    662         if (c != '{') {
     885        if (c != '(') {
    663886                rc = EIO;
    664887                goto error;
     
    671894        }
    672895
    673         while (c != '}') {
     896        while (c != ')') {
    674897                ungetc(c, f);
    675898
    676                 rc = sif_import_node(node, f, &child);
     899                rc = sif_import_attr(node, f, &attr);
    677900                if (rc != EOK)
    678901                        goto error;
    679902
    680                 list_append(&child->lparent, &node->children);
     903                odict_insert(&attr->lattrs, &node->attrs, NULL);
    681904
    682905                c = fgetc(f);
     
    687910        }
    688911
     912        /* Child nodes */
     913
     914        c = fgetc(f);
     915        if (c != '{') {
     916                rc = EIO;
     917                goto error;
     918        }
     919
     920        c = fgetc(f);
     921        if (c == EOF) {
     922                rc = EIO;
     923                goto error;
     924        }
     925
     926        while (c != '}') {
     927                ungetc(c, f);
     928
     929                rc = sif_import_node(node, f, &child);
     930                if (rc != EOK)
     931                        goto error;
     932
     933                list_append(&child->lparent, &node->children);
     934
     935                c = fgetc(f);
     936                if (c == EOF) {
     937                        rc = EIO;
     938                        goto error;
     939                }
     940        }
     941
    689942        *rnode = node;
    690943        return EOK;
     
    694947}
    695948
     949/** Get first attribute or a node.
     950 *
     951 * @param node SIF node
     952 * @return First attribute or @c NULL if there is none
     953 */
     954static sif_attr_t *sif_node_first_attr(sif_node_t *node)
     955{
     956        odlink_t *link;
     957
     958        link = odict_first(&node->attrs);
     959        if (link == NULL)
     960                return NULL;
     961
     962        return odict_get_instance(link, sif_attr_t, lattrs);
     963}
     964
     965/** Get next attribute or a node.
     966 *
     967 * @param cur Current attribute
     968 * @return Next attribute or @c NULL if there is none
     969 */
     970static sif_attr_t *sif_node_next_attr(sif_attr_t *cur)
     971{
     972        odlink_t *link;
     973
     974        link = odict_next(&cur->lattrs, &cur->node->attrs);
     975        if (link == NULL)
     976                return NULL;
     977
     978        return odict_get_instance(link, sif_attr_t, lattrs);
     979}
     980
     981/** Get key callback for ordered dictionary of node attributes.
     982 *
     983 * @param link Ordered dictionary link of attribute
     984 * @return Pointer to attribute name
     985 */
     986static void *sif_attr_getkey(odlink_t *link)
     987{
     988        return (void *)odict_get_instance(link, sif_attr_t, lattrs)->aname;
     989}
     990
     991/** Comparison callback for  ordered dictionary of node attributes.
     992 *
     993 * @param a Name of first attribute
     994 * @param b Name of second attribute
     995 * @return Less than zero, zero or greater than zero, if a < b, a == b, a > b,
     996 *         respectively.
     997 */
     998static int sif_attr_cmp(void *a, void *b)
     999{
     1000        char *ca, *cb;
     1001
     1002        ca = (char *)a;
     1003        cb = (char *)b;
     1004
     1005        return str_cmp(ca, cb);
     1006}
     1007
    6961008/** @}
    6971009 */
  • uspace/lib/sif/test/sif.c

    r1c398db2 r7b87e1d  
    3030#include <pcut/pcut.h>
    3131#include <stdio.h>
     32#include <str.h>
    3233#include "../include/sif.h"
    3334
     
    5354        rc = sif_create(fname, &sess);
    5455        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     56
     57        rc = sif_close(sess);
     58        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     59
     60        rv = remove(fname);
     61        PCUT_ASSERT_INT_EQUALS(0, rv);
     62}
     63
     64/** Test sif_open. */
     65PCUT_TEST(sif_open)
     66{
     67        sif_sess_t *sess;
     68        errno_t rc;
     69        int rv;
     70        char *fname;
     71        char *p;
     72
     73        fname = calloc(L_tmpnam, 1);
     74        PCUT_ASSERT_NOT_NULL(fname);
     75
     76        p = tmpnam(fname);
     77        PCUT_ASSERT_TRUE(p == fname);
     78
     79        rc = sif_create(fname, &sess);
     80        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     81
     82        rc = sif_close(sess);
     83        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     84
     85        rc = sif_open(fname, &sess);
     86        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     87
     88        rc = sif_close(sess);
     89        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     90
     91        rv = remove(fname);
     92        PCUT_ASSERT_INT_EQUALS(0, rv);
     93}
     94
     95/** Test sif_get_root. */
     96PCUT_TEST(sif_get_root)
     97{
     98        sif_sess_t *sess;
     99        sif_node_t *root;
     100        errno_t rc;
     101        int rv;
     102        char *fname;
     103        char *p;
     104
     105        fname = calloc(L_tmpnam, 1);
     106        PCUT_ASSERT_NOT_NULL(fname);
     107
     108        p = tmpnam(fname);
     109        PCUT_ASSERT_TRUE(p == fname);
     110
     111        rc = sif_create(fname, &sess);
     112        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     113
     114        root = sif_get_root(sess);
     115        PCUT_ASSERT_NOT_NULL(root);
     116        PCUT_ASSERT_INT_EQUALS(0, str_cmp(sif_node_get_type(root), "sif"));
    55117
    56118        rc = sif_close(sess);
     
    297359}
    298360
     361/** Test sif_node_destroy. */
     362PCUT_TEST(sif_node_destroy)
     363{
     364        sif_sess_t *sess;
     365        sif_node_t *root;
     366        sif_node_t *ca;
     367        sif_node_t *cb;
     368        sif_node_t *cc;
     369        sif_node_t *c1;
     370        sif_node_t *c2;
     371        sif_node_t *c3;
     372        sif_trans_t *trans;
     373        errno_t rc;
     374        int rv;
     375        char *fname;
     376        char *p;
     377
     378        fname = calloc(L_tmpnam, 1);
     379        PCUT_ASSERT_NOT_NULL(fname);
     380
     381        p = tmpnam(fname);
     382        PCUT_ASSERT_TRUE(p == fname);
     383
     384        rc = sif_create(fname, &sess);
     385        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     386
     387        root = sif_get_root(sess);
     388
     389        rc = sif_trans_begin(sess, &trans);
     390        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     391
     392        rc = sif_node_append_child(trans, root, "a", &ca);
     393        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     394
     395        rc = sif_node_append_child(trans, root, "b", &cb);
     396        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     397
     398        rc = sif_node_append_child(trans, root, "c", &cc);
     399        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     400
     401        rc = sif_trans_end(trans);
     402        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     403
     404        rc = sif_trans_begin(sess, &trans);
     405        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     406
     407        sif_node_destroy(trans, cb);
     408
     409        rc = sif_trans_end(trans);
     410        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     411
     412        c1 = sif_node_first_child(root);
     413        PCUT_ASSERT_TRUE(c1 == ca);
     414
     415        c2 = sif_node_next_child(c1);
     416        PCUT_ASSERT_TRUE(c2 == cc);
     417
     418        c3 = sif_node_next_child(c2);
     419        PCUT_ASSERT_TRUE(c3 == NULL);
     420
     421        rc = sif_close(sess);
     422        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     423
     424        rv = remove(fname);
     425        PCUT_ASSERT_INT_EQUALS(0, rv);
     426}
     427
     428/** Test sif_node_set_attr. */
     429PCUT_TEST(sif_node_set_attr)
     430{
     431        sif_sess_t *sess;
     432        sif_node_t *root;
     433        sif_node_t *node;
     434        sif_trans_t *trans;
     435        errno_t rc;
     436        int rv;
     437        char *fname;
     438        char *p;
     439        const char *aval;
     440
     441        fname = calloc(L_tmpnam, 1);
     442        PCUT_ASSERT_NOT_NULL(fname);
     443
     444        p = tmpnam(fname);
     445        PCUT_ASSERT_TRUE(p == fname);
     446
     447        rc = sif_create(fname, &sess);
     448        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     449
     450        root = sif_get_root(sess);
     451
     452        rc = sif_trans_begin(sess, &trans);
     453        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     454
     455        rc = sif_node_append_child(trans, root, "node", &node);
     456        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     457
     458        rc = sif_node_set_attr(trans, node, "a", "?");
     459        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     460
     461        rc = sif_node_set_attr(trans, node, "a", "X");
     462        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     463
     464        rc = sif_node_set_attr(trans, node, "b", "Y");
     465        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     466
     467        rc = sif_trans_end(trans);
     468        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     469
     470        aval = sif_node_get_attr(node, "a");
     471        PCUT_ASSERT_INT_EQUALS(0, str_cmp(aval, "X"));
     472
     473        aval = sif_node_get_attr(node, "b");
     474        PCUT_ASSERT_INT_EQUALS(0, str_cmp(aval, "Y"));
     475
     476        aval = sif_node_get_attr(node, "c");
     477        PCUT_ASSERT_NULL((void *) aval); // XXX PCUT_ASSERT_NULL does not accept const pointer
     478
     479        rc = sif_close(sess);
     480        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     481
     482        rv = remove(fname);
     483        PCUT_ASSERT_INT_EQUALS(0, rv);
     484}
     485
     486/** Test sif_node_unset_attr. */
     487PCUT_TEST(sif_node_unset_attr)
     488{
     489        sif_sess_t *sess;
     490        sif_node_t *root;
     491        sif_node_t *node;
     492        sif_trans_t *trans;
     493        errno_t rc;
     494        int rv;
     495        char *fname;
     496        char *p;
     497        const char *aval;
     498
     499        fname = calloc(L_tmpnam, 1);
     500        PCUT_ASSERT_NOT_NULL(fname);
     501
     502        p = tmpnam(fname);
     503        PCUT_ASSERT_TRUE(p == fname);
     504
     505        rc = sif_create(fname, &sess);
     506        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     507
     508        root = sif_get_root(sess);
     509
     510        rc = sif_trans_begin(sess, &trans);
     511        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     512
     513        rc = sif_node_append_child(trans, root, "node", &node);
     514        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     515
     516        rc = sif_node_set_attr(trans, node, "a", "X");
     517        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     518
     519        rc = sif_trans_end(trans);
     520        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     521
     522        aval = sif_node_get_attr(node, "a");
     523        PCUT_ASSERT_INT_EQUALS(0, str_cmp(aval, "X"));
     524
     525        rc = sif_trans_begin(sess, &trans);
     526        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     527
     528        sif_node_unset_attr(trans, node, "a");
     529        sif_node_unset_attr(trans, node, "b");
     530
     531        rc = sif_trans_end(trans);
     532        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     533
     534        aval = sif_node_get_attr(node, "a");
     535        PCUT_ASSERT_NULL((void *) aval); // XXX PCUT_ASSERT_NULL does not accept const pointer
     536
     537        rc = sif_close(sess);
     538        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     539
     540        rv = remove(fname);
     541        PCUT_ASSERT_INT_EQUALS(0, rv);
     542}
     543
     544/** Test persistence of nodes and attributes. */
     545PCUT_TEST(sif_persist)
     546{
     547        sif_sess_t *sess;
     548        sif_node_t *root;
     549        sif_node_t *node;
     550        sif_trans_t *trans;
     551        errno_t rc;
     552        int rv;
     553        char *fname;
     554        char *p;
     555        const char *aval;
     556
     557        fname = calloc(L_tmpnam, 1);
     558        PCUT_ASSERT_NOT_NULL(fname);
     559
     560        p = tmpnam(fname);
     561        PCUT_ASSERT_TRUE(p == fname);
     562
     563        rc = sif_create(fname, &sess);
     564        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     565
     566        root = sif_get_root(sess);
     567
     568        rc = sif_trans_begin(sess, &trans);
     569        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     570
     571        rc = sif_node_append_child(trans, root, "node", &node);
     572        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     573
     574        rc = sif_node_set_attr(trans, node, "a", "X");
     575        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     576
     577        rc = sif_trans_end(trans);
     578        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     579
     580        rc = sif_close(sess);
     581        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     582
     583        /* Now reopen the repository */
     584
     585        rc = sif_open(fname, &sess);
     586        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     587
     588        root = sif_get_root(sess);
     589
     590        node = sif_node_first_child(root);
     591        PCUT_ASSERT_NOT_NULL(node);
     592        PCUT_ASSERT_INT_EQUALS(0, str_cmp(sif_node_get_type(node), "node"));
     593
     594        aval = sif_node_get_attr(node, "a");
     595        PCUT_ASSERT_INT_EQUALS(0, str_cmp(aval, "X"));
     596
     597        rc = sif_close(sess);
     598        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     599
     600        rv = remove(fname);
     601        PCUT_ASSERT_INT_EQUALS(0, rv);
     602}
     603
     604
    299605PCUT_EXPORT(sif);
Note: See TracChangeset for help on using the changeset viewer.