예제 #1
0
static int sortByName(const void *a, const void *b) {
  HDF **ha = (HDF **)a;
  HDF **hb = (HDF **)b;

  /* fprintf(stderr, "%s <=> %s\n", hdf_obj_name(*ha), hdf_obj_name(*hb));  */
  return strcasecmp(hdf_obj_name(*ha), hdf_obj_name(*hb));
}
예제 #2
0
파일: mjson.c 프로젝트: kingiol/cmoon
void mjson_asm_objs(HDF *hdf, struct json_object **out)
{
    if (hdf == NULL)
        return;

    struct json_object *jret, *jso;
    char *val, *type;
    bool array = false;

    type = mcs_obj_attr(hdf, "type");
    if (type && !strcmp(type, "array")) {
        array = true;
        jret = json_object_new_array();
    } else {
        jret = json_object_new_object();
    }

    hdf = hdf_obj_child(hdf);

    while (hdf) {
        jso = NULL;
        
        if ((val = hdf_obj_value(hdf)) != NULL) {
            type = mcs_obj_attr(hdf, "type");
            if (type != NULL && !strcmp(type, "int")) {
                jso = json_object_new_int(atoi(val));
            } else {
                jso = json_object_new_string(val);
            }
            if (array)
                json_object_array_add(jret, jso);
            else
                json_object_object_add(jret, hdf_obj_name(hdf), jso);
        }

        if (hdf_obj_child(hdf) != NULL) {
            mjson_asm_objs(hdf, &jso);
            if (array)
                json_object_array_add(jret, jso);
            else
                json_object_object_add(jret, hdf_obj_name(hdf), jso);
        }
        
        hdf = hdf_obj_next(hdf);
    }

    *out = jret;
}
예제 #3
0
/* load a specified version of the file, version -1 is latest */
NEOERR * rcfs_load (const char *path, int version, char **data)
{
  NEOERR *err;
  char fpath[_POSIX_PATH_MAX];

  if (version == -1)
  {
    HDF *meta, *vers;
    int x;

    err = rcfs_meta_load (path, &meta);
    if (err) return nerr_pass (err);
    for (vers = hdf_get_child (meta, "Versions");
	vers;
	vers = hdf_obj_next (vers))
    {
      x = atoi (hdf_obj_name (vers));
      if (x > version) version = x;
    }
    hdf_destroy (&meta);
  }
  snprintf (fpath, sizeof (fpath), "%s,%d", path, version);
  err = ne_load_file (fpath, data);
  return nerr_pass (err);
}
예제 #4
0
파일: cgi.cpp 프로젝트: leegoex/flinter
void CGI::TranslatePost(void *cgi, Tree *posts,
                        std::map<std::string, File> *files)
{
    ::CGI *c = reinterpret_cast< ::CGI *>(cgi);

    HDF *parent = hdf_get_obj(c->hdf, "Query");
    if (!parent) {
        return;
    }

    HDF *next = hdf_obj_child(parent);
    while (next) {
        HDF *child = next;
        next = hdf_obj_next(next);

        const char *k = hdf_obj_name(child);
        const char *v = hdf_obj_value(child);
        if (!k || !v) {
            continue;
        }

        if (!TranslateFile(c, k, files)) {
            posts->Set(k, v);
        }
    }
}
예제 #5
0
파일: mcs.c 프로젝트: pombredanne/cmoon
void mcs_hdf_rep(HDF *data, HDF *dst)
{
    char *srcstr, *repstr;
    
    if (!data || !dst) return;

    HDF *datarow = hdf_obj_child(data);
    while (datarow) {
        HDF *child = hdf_obj_child(dst);
        while (child) {
            if (hdf_obj_child(child)) {
                return mcs_hdf_rep(data, child);
            }

            srcstr = hdf_obj_value(child);
            repstr = mstr_repstr(1, srcstr,
                                 hdf_obj_name(datarow),
                                 hdf_obj_value(datarow));
            hdf_set_value(child, NULL, repstr);
            free(repstr);

            child = hdf_obj_next(child);
        }
        
        datarow = hdf_obj_next(datarow);
    }
}
예제 #6
0
파일: j_neo_util.c 프로젝트: bigclean/moc
JNIEXPORT jstring JNICALL Java_org_clearsilver_HDF__1objName(
    JNIEnv *env, jclass objClass, jint hdf_obj_ptr) {
  HDF *hdf = (HDF *)hdf_obj_ptr;
  char *name;
  jstring retval = NULL;

  name = hdf_obj_name(hdf);
  if (name != NULL) {
    retval =  (*env)->NewStringUTF(env, name);
  }
  return retval;
}
예제 #7
0
int wkm_cfg_to_opts(struct wkman *wkman, struct cfg *cfg) {
	HDF *base_hdf = (HDF*)cfg;
	HDF *hdf;
	int rval = 0;
	dbg1("%s %s()", wkman->dev->serial, __func__);
	for(hdf = hdf_obj_child(base_hdf); hdf; hdf = hdf_obj_next(hdf)) {
		const char *key = hdf_obj_name(hdf);
		const char *val_str = hdf_obj_value(hdf);
		int val = atoi(val_str);
		rval += wkm_set_value(wkman, key, val);
	}
	return rval;
}
예제 #8
0
파일: cshdf.c 프로젝트: bigml/mbase
int main(int argc, char **argv, char **envp)
{
    char key[10];
    HDF *bignode;

    mtc_init("cshdf", 7);

    hdf_init(&bignode);

    for (int i = 0; i < 5003929; i++) {
        mstr_rand_string_with_len(key, 10);

        hdf_set_valuef(bignode, "%s.today=10", key);
        hdf_set_valuef(bignode, "%s.toweek=11", key);
        hdf_set_valuef(bignode, "%s.tomonth=12", key);
        hdf_set_valuef(bignode, "%s.total=234", key);

        if (i % 10000 == 0) printf("%d\n", i);
    }

    //hdf_dump(bignode, NULL);

    printf("child num %d\n", mcs_get_child_num(bignode, NULL));

    int count = 0;

    mtimer_start();

    HDF *cnode = hdf_obj_child(bignode);
    while (cnode) {
        char *name = hdf_obj_name(cnode);

        if (mcs_get_int_valuef(bignode, 0, "%s.today", name) != 10) printf("error\n");
        if (mcs_get_int_valuef(bignode, 0, "%s.toweek", name) != 11) printf("error\n");
        if (mcs_get_int_valuef(bignode, 0, "%s.tomonth", name) != 12) printf("error\n");
        if (mcs_get_int_valuef(bignode, 0, "%s.total", name) != 234) printf("error\n");

        count++;

        cnode = hdf_obj_next(cnode);
    }

    mtimer_stop("get time");

    printf("get child count %d\n", count);

    hdf_destroy(&bignode);

    return 0;
}
예제 #9
0
파일: ldml.c 프로젝트: bigml/mgate
NEOERR* ldml_parse_file(char *dir, char *name, HASH *outhash)
{
    char fname[_POSIX_PATH_MAX], *attrval = NULL;
    HDF *node, *child, *dhdf;
    STRING str;
    NEOERR *err;

    memset(fname, 0x0, sizeof(fname));
    snprintf(fname, sizeof(fname), "%s/%s", dir, name);

    err = hdf_init(&node);
    if (err != STATUS_OK) return nerr_pass(err);

    err = hdf_read_file(node, fname);
    if (err != STATUS_OK) return nerr_pass(err);

    child = hdf_obj_child(node);
    while (child != NULL) {
        mtc_dbg("parse node %s", hdf_obj_name(child));
        string_init(&str);

        attrval = mcs_obj_attr(child, "merge");
        if (attrval) {
            ULIST *list;
            string_array_split(&list, attrval, ",", 10);
            ITERATE_MLIST(list) {
                snprintf(fname, sizeof(fname), "%s/%s",
                         dir, neos_strip((char*)list->items[t_rsv_i]));
                err = hdf_init(&dhdf);
                JUMP_NOK(err, wnext);
                err = hdf_read_file(dhdf, fname);
                JUMP_NOK(err, wnext);
                err = hdf_copy(child, NULL, dhdf);
                JUMP_NOK(err, wnext);
            }
            uListDestroy(&list, ULIST_FREE);
        }

    wnext:
        string_clear(&str);
        child = hdf_obj_next(child);
    }

    err = hash_insert(outhash, (void*)strdup(name), (void*)node);
    JUMP_NOK(err, wnext);

    return STATUS_OK;
}
예제 #10
0
static PyObject * p_hdf_obj_name (PyObject *self, PyObject *args)
{
  HDFObject *ho = (HDFObject *)self;
  PyObject *rv;
  char *r;

  r = hdf_obj_name (ho->data);
  if (r == NULL)
  {
    rv = Py_None;
    Py_INCREF(rv);
    return rv;
  }
  rv = Py_BuildValue ("s", r);
  return rv;
}
예제 #11
0
파일: cgi.cpp 프로젝트: leegoex/flinter
void CGI::TranslateHDF(void *cgi, const std::string &node, Tree *maps)
{
    ::CGI *c = reinterpret_cast< ::CGI *>(cgi);

    HDF *parent = hdf_get_obj(c->hdf, node.c_str());
    if (!parent) {
        return;
    }

    HDF *child = hdf_obj_child(parent);
    while (child) {
        const char *k = hdf_obj_name(child);
        const char *v = hdf_obj_value(child);
        if (k && v) {
            maps->Set(k, v);
        }

        child = hdf_obj_next(child);
    }
}
예제 #12
0
int main(void) {
  HDF *hdf_1, *hdf_2;
  HDF *cur_node,*last_node;

  hdf_init(&hdf_1);

  hdf_read_file(hdf_1,"hdf_copy_test.hdf");
  hdf_dump(hdf_1,NULL);

  cur_node = hdf_get_obj(hdf_1,"Chart");
  last_node = cur_node;

  cur_node = hdf_get_obj(cur_node,"next_stage");
  while (hdf_get_obj(cur_node,"next_stage") && strcmp(hdf_get_value(cur_node,"Bucket.FieldId",""),"QUEUE")) {
    last_node = cur_node;
    cur_node = hdf_get_obj(cur_node,"next_stage");
  }

  if (hdf_get_obj(cur_node,"next_stage")) {
    hdf_copy(hdf_1,"TempHolderPlace",hdf_get_obj(cur_node,"next_stage"));
  }
  ne_warn("Delete tree from node: %s", hdf_obj_name(last_node));
  hdf_remove_tree(last_node,"next_stage");

  hdf_dump(hdf_1,NULL);
  fprintf(stderr,"-----------------\n");


  hdf_copy(last_node,"next_stage",hdf_get_obj(hdf_1,"TempHolderPlace"));
  hdf_dump(hdf_1,NULL);

  /* Test copy and destroy, make sure we actually copy everything and
   * don't reference anything */
  hdf_init(&hdf_2);
  hdf_copy(hdf_2, "", hdf_1);
  hdf_destroy(&hdf_1);
  hdf_dump(hdf_2, NULL);
  hdf_destroy(&hdf_2);

  return 0;
}
예제 #13
0
파일: tree_cs.cpp 프로젝트: goreliu/flinter
bool Tree::ParseFromHdfInternal(struct _hdf *hdf)
{
    while (hdf) {
        const char *key = hdf_obj_name(hdf);
        const char *value = hdf_obj_value(hdf);
        if (!value) {
            value = "";
        }

        std::string full_path = GetFullPath(key);
        Tree *child = new Tree(full_path, key, value);
        _children.insert(std::make_pair(key, child));

        HDF *hc = hdf_obj_child(hdf);
        if (!child->ParseFromHdfInternal(hc)) {
            return false;
        }

        hdf = hdf_obj_next(hdf);
    }

    return true;
}
예제 #14
0
파일: ltpl.c 프로젝트: adderly/cmoon
NEOERR* ltpl_parse_file(HASH *dbh, HASH *evth,
                        void *lib, char *dir, char *name, HASH *outhash)
{
    char *tp = NULL, *tpl = NULL, *val = NULL;
    HDF *node = NULL, *dhdf = NULL, *child = NULL, *thdf = NULL;
    CSPARSE *cs = NULL;
    STRING str;
    char fname[_POSIX_PATH_MAX], tok[64], *outfile;
    NEOERR* (*data_handler)(HDF *hdf, HASH *dbh, HASH *evth);
    NEOERR *err;
    
    memset(fname, 0x0, sizeof(fname));
    snprintf(fname, sizeof(fname), "%s/%s", dir, name);
    err = hdf_init(&node);
    if (err != STATUS_OK) return nerr_pass(err);
 
    err = hdf_read_file(node, fname);
    if (err != STATUS_OK) return nerr_pass(err);

    child = hdf_obj_child(node);
    while (child != NULL) {
        mtc_dbg("parse node %s", hdf_obj_name(child));
        string_init(&str);

        val = mcs_obj_attr(child, "merge");
        if (val) {
            ULIST *list;
            string_array_split(&list, val, ",", 10);
            ITERATE_MLIST(list) {
                snprintf(fname, sizeof(fname), "%s/%s",
                         dir, neos_strip((char*)list->items[t_rsv_i]));
                err = hdf_init(&dhdf);
                JUMP_NOK(err, wnext);
                err = hdf_read_file(dhdf, fname);
                JUMP_NOK(err, wnext);
                err = hdf_copy(child, NULL, dhdf);
                JUMP_NOK(err, wnext);
            }
            uListDestroy(&list, ULIST_FREE);
        }

        /*
         * can't use dataset directly, because we'll destroy the whole node
         */
        err = hdf_init(&dhdf);
        JUMP_NOK(err, wnext);
        err = hdf_get_node(child, PRE_CFG_DATASET, &thdf);
        JUMP_NOK(err, wnext);
        err = hdf_copy(dhdf, NULL, thdf);
        JUMP_NOK(err, wnext);
        
        err = cs_init(&cs, dhdf);
        JUMP_NOK(err, wnext);

        hdf_set_value(cs->hdf, "hdf.loadpaths.tpl", PATH_TPL);
        hdf_set_value(cs->hdf, "hdf.loadpaths.local", dir);

        err = cgi_register_strfuncs(cs);
        JUMP_NOK(err, wnext);
        err = mcs_register_bitop_functions(cs);
        JUMP_NOK(err, wnext);
        err = mcs_register_mkd_functions(cs);
        JUMP_NOK(err, wnext);
        err = mcs_register_string_uslice(cs);
        JUMP_NOK(err, wnext);

        tpl = hdf_get_value(child, PRE_CFG_LAYOUT, "null.html");
        snprintf(fname, sizeof(fname), "%s/%s", PATH_TPL, tpl);
        err = cs_parse_file(cs, fname);
        JUMP_NOK(err, wnext);

        if (outhash != NULL) {
            /*
             * store template for rend stage use
             */
            hdf_set_value(cs->hdf, PRE_RESERVE"."PRE_CFG_LAYOUT, tpl);
            
            /*
             * strdup the key, baby, because we'll free the hdf later
             */
            err = hash_insert(outhash, (void*)strdup(hdf_obj_name(child)), (void*)cs);
            JUMP_NOK(err, wnext);

            snprintf(tok, sizeof(tok), "%s_hdf", hdf_obj_name(child));
            err = hash_insert(outhash, (void*)strdup(tok), (void*)cs->hdf);
            JUMP_NOK(err, wnext);
        }

        if ((outfile = hdf_get_value(child, PRE_CFG_OUTPUT, NULL)) != NULL) {
            ltpl_prepare_rend(cs->hdf, tpl);
                
            /*
             * get_data
             */
            val = hdf_get_value(child, PRE_CFG_DATAER, NULL);
            if (val != NULL && lib) {
                data_handler = dlsym(lib, val);
                if( (tp = dlerror()) != NULL) {
                    mtc_err("%s", tp);
                    //continue;
                } else {
                    err = (*data_handler)(cs->hdf, dbh, evth);
                    TRACE_NOK(err);
                }
            }

            err = cs_render(cs, &str, mcs_strcb);
            JUMP_NOK(err, wnext);

            /*
             * produce output filename
             */
            val = mcs_hdf_attr(child, PRE_CFG_OUTPUT, "ftime");
            if (val) {
                char tm[LEN_TM];
                mutil_getdatetime(tm, sizeof(tm), val, 0);
                outfile = mstr_repstr(1, outfile, "$ftime$", tm);
            }
            snprintf(fname, sizeof(fname), PATH_DOC"%s", outfile);

            /*
             * output file
             */
            err = mfile_makesure_dir(fname);
            JUMP_NOK(err, wnext);

            err = mcs_str2file(str, fname);
            JUMP_NOK(err, wnext);
#ifdef DEBUG_HDF
            snprintf(fname, sizeof(fname), "%s/hdf.%s",
                     TC_ROOT, hdf_obj_name(child));
            hdf_write_file(child, fname);
#endif
        }

    wnext:
        if (cs != NULL && outhash == NULL)
            cs_destroy(&cs);
        string_clear(&str);
        child = hdf_obj_next(child);
    }
        
    if (node != NULL) hdf_destroy(&node);

    return STATUS_OK;
}
예제 #15
0
파일: ltpl.c 프로젝트: kingiol/cmoon
NEOERR* ltpl_parse_file(HASH *dbh, void *lib, char *dir, char *name, HASH *outhash)
{
    char *tp = NULL, *tpl = NULL, *val = NULL;
    HDF *node = NULL, *dhdf = NULL, *child = NULL;
    CSPARSE *cs = NULL;
    STRING str;
    char fname[_POSIX_PATH_MAX], tok[64];
    NEOERR* (*data_handler)(HDF *hdf, HASH *dbh);
    NEOERR *err;
    
    memset(fname, 0x0, sizeof(fname));
    snprintf(fname, sizeof(fname), "%s/%s", dir, name);
    err = hdf_init(&node);
    if (err != STATUS_OK) return nerr_pass(err);

    err = hdf_read_file(node, fname);
    if (err != STATUS_OK) return nerr_pass(err);

    child = hdf_obj_child(node);
    while (child != NULL) {
        mtc_dbg("parse node %s", hdf_obj_name(child));
        string_init(&str);

        val = mutil_obj_attr(child, "merge");
        if (val) {
            snprintf(fname, sizeof(fname), "%s/%s", dir, val);
            err = hdf_init(&dhdf);
            JUMP_NOK(err, wnext);
            err = hdf_read_file(dhdf, fname);
            JUMP_NOK(err, wnext);
            err = hdf_copy(child, NULL, dhdf);
            JUMP_NOK(err, wnext);
        }
        
        err = cs_init(&cs, hdf_get_obj(child, PRE_CFG_DATASET));
        JUMP_NOK(err, wnext);
            
        hdf_set_value(cs->hdf, "hdf.loadpaths.local", dir);

        err = cgi_register_strfuncs(cs);
        JUMP_NOK(err, wnext);
        err = mcs_register_bitop_functions(cs);
        JUMP_NOK(err, wnext);
        err = mcs_register_mkd_functions(cs);
        JUMP_NOK(err, wnext);

        tpl = hdf_get_value(child, PRE_CFG_LAYOUT, "null.html");
        snprintf(fname, sizeof(fname), "%s/%s", PATH_TPL, tpl);
        err = cs_parse_file(cs, fname);
        JUMP_NOK(err, wnext);

        if (outhash != NULL) {
            /*
             * strdup the key, baby, because we'll free the hdf later
             */
            err = hash_insert(outhash, (void*)strdup(hdf_obj_name(child)), (void*)cs);
            JUMP_NOK(err, wnext);
            if (hdf_get_obj(child, PRE_CFG_DATASET)) {
                err = hdf_init(&dhdf);
                JUMP_NOK(err, wnext);
                err = hdf_copy(dhdf, NULL, hdf_get_obj(child, PRE_CFG_DATASET));
                JUMP_NOK(err, wnext);
                snprintf(tok, sizeof(tok), "%s_hdf", hdf_obj_name(child));
                err = hash_insert(outhash, (void*)strdup(tok), (void*)dhdf);
                JUMP_NOK(err, wnext);
            }
        }
            
        if (hdf_get_value(child, PRE_CFG_OUTPUT, NULL) != NULL) {
            ltpl_prepare_rend(hdf_get_obj(child, PRE_CFG_DATASET), tpl);
                
            /*
             * get_data
             */
            val = hdf_get_value(child, PRE_CFG_DATAER, NULL);
            if (val != NULL && lib) {
                data_handler = dlsym(lib, val);
                if( (tp = dlerror()) != NULL) {
                    mtc_err("%s", tp);
                    //continue;
                } else {
                    err = (*data_handler)(hdf_get_obj(child, PRE_CFG_DATASET), dbh);
                    TRACE_NOK(err);
                }
            }
                
            err = cs_render(cs, &str, mcs_strcb);
            JUMP_NOK(err, wnext);
                
            snprintf(fname, sizeof(fname), PATH_DOC"%s",
                     hdf_get_value(child, PRE_CFG_OUTPUT, "null.html"));
            err = mutil_makesure_dir(fname);
            JUMP_NOK(err, wnext);

            err = mcs_str2file(str, fname);
            JUMP_NOK(err, wnext);
#ifdef DEBUG_HDF
            snprintf(fname, sizeof(fname), "%s/hdf.%s",
                     TC_ROOT, hdf_obj_name(child));
            hdf_write_file(child, fname);
#endif
        }

    wnext:
        if (cs != NULL && outhash == NULL)
            cs_destroy(&cs);
        string_clear(&str);
        child = hdf_obj_next(child);
    }
        
    if (node != NULL) hdf_destroy(&node);

    return STATUS_OK;
}
예제 #16
0
NEOERR * rcfs_save (const char *path, const char *data, const char *user, 
                    const char *log)
{
  NEOERR *err;
  HDF *meta = NULL, *vers;
  char fpath[_POSIX_PATH_MAX];
  char buf[256];
  int version = 0;
  int fd;
  int lock;
  int x, l, w;

  err = rcfs_lock (path, &lock);
  if (err) return nerr_pass (err);
  do
  {
    err = rcfs_meta_load (path, &meta);
    if (err && nerr_handle (&err, NERR_NOT_FOUND))
    {
      /* new file! */
      err = hdf_init (&meta);
    }
    if (err) return nerr_pass (err);
    for (vers = hdf_get_child (meta, "Versions");
	vers;
	vers = hdf_obj_next (vers))
    {
      x = atoi (hdf_obj_name (vers));
      if (x > version) version = x;
    }

    /* new version */
    version++;
    snprintf (fpath, sizeof (fpath), "%s,%d", path, version);
    fd = open (fpath, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
    if (fd == -1)
    {
      err = nerr_raise_errno (NERR_IO, "Unable to create file %s", fpath);
      break;
    }
    l = strlen(data);
    w = write (fd, data, l);
    if (w != l)
    {
      err = nerr_raise_errno (NERR_IO, "Unable to write file %s", fpath);
      close (fd);
      break;
    }
    close (fd);
    snprintf (buf, sizeof(buf), "Versions.%d.Log", version);
    err = hdf_set_value (meta, buf, log);
    if (err) break;
    snprintf (buf, sizeof(buf), "Versions.%d.User", version);
    err = hdf_set_value (meta, buf, user);
    if (err) break;
    snprintf (buf, sizeof(buf), "Versions.%d.Date", version);
    err = hdf_set_int_value (meta, buf, ne_timef());
    if (err) break;
    err = _meta_save (path, meta);
  } while (0);

  rcfs_unlock (lock);
  hdf_destroy (&meta);
  return nerr_pass (err);
}
예제 #17
0
파일: hdf.cpp 프로젝트: 292388900/hhvm
std::string Hdf::getName(bool markVisited /* = true */) const {
  HDF *hdf = getRaw();
  char *name = hdf_obj_name(hdf);
  if (markVisited) hdf_set_visited(hdf, 1);
  return name ? name : "";
}
예제 #18
0
파일: neo_hdf.c 프로젝트: F4m3uS/hiphop-php
static NEOERR* _hdf_read_string (HDF *hdf, const char **str, STRING *line,
                                 const char *path, int *lineno,
                                 int include_handle, int expect_end_brace) {
  NEOERR *err;
  HDF *lower;
  char *s;
  char *name, *value;
  HDF_ATTR *attr = NULL;

  while (**str != '\0')
  {
    /* Reset string length, but don't free the reserved buffer */
    line->len = 0;
    err = _copy_line_advance(str, line);
    if (err) return nerr_pass(err);
    attr = NULL;
    (*lineno)++;
    s = line->buf;
    SKIPWS(s);
    if ((!strncmp(s, "#include ", 9) || !strncmp(s, "-include ", 9)) && include_handle != INCLUDE_IGNORE)
    {
      int required = !strncmp(s, "#include ", 9);
      if (include_handle == INCLUDE_ERROR)
      {
	return nerr_raise (NERR_PARSE,
                           "[%d]: #include not supported in string parse",
                           *lineno);
      }
      else if (include_handle < INCLUDE_MAX_DEPTH)
      {
        int l;
        s += 9;
        name = neos_strip(s);
        l = strlen(name);
        if (name[0] == '"' && name[l-1] == '"')
        {
          name[l-1] = '\0';
          name++;
        }
        char fullpath[PATH_MAX];
        if (name[0] != '/') {
          memset(fullpath, 0, PATH_MAX);

          char *p = strrchr(path, '/');
          if (p == NULL) {
            char pwd[PATH_MAX];
            memset(pwd, 0, PATH_MAX);
            getcwd(pwd, PATH_MAX);
            snprintf(fullpath, PATH_MAX, "%s/%s", pwd, name);
          } else {
            int dir_len = p - path + 1;
            snprintf(fullpath, PATH_MAX, "%s", path);
            snprintf(fullpath + dir_len, PATH_MAX - dir_len, "%s", name);
          }
          name = fullpath;
        }
        err = hdf_read_file_internal(hdf, name, include_handle + 1);
        if (err != STATUS_OK && required)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else {
        return nerr_raise (NERR_MAX_RECURSION,
                           "[%d]: Too many recursion levels.",
                           *lineno
                           );
      }
    }
    else if (s[0] == '#')
    {
      /* comment: pass */
    }
    else if (s[0] == '}') /* up */
    {
      s = neos_strip(s);
      if (strcmp(s, "}"))
      {
        err = nerr_raise(NERR_PARSE,
	    "[%s:%d] Trailing garbage on line following }: %s", path, *lineno,
	    line->buf);
        return err;
      }
      return STATUS_OK;
    }
    else if (s[0])
    {
      /* Valid hdf name is [0-9a-zA-Z_.]+ */
      int splice = *s == '@';
      if (splice) s++;
      name = s;
      while (*s && (isalnum(*s) || *s == '_' || *s == '.' || *s == '*')) s++;
      SKIPWS(s);

      char num[16];
      static int counter = 0;
      if (*name == '*') {
        snprintf(num, sizeof(num), "%d", counter++);
        name = num;
      }

      if (s[0] == '[') /* attributes */
      {
	*s = '\0';
	name = neos_strip(name);
	s++;
	err = parse_attr(&s, &attr);
	if (err)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
	SKIPWS(s);
      }
      if (splice) {
        name = neos_strip(name);
        HDF *h = hdf_get_obj(hdf->top, name);
        if (h) {
          HDF *c = hdf_obj_child(h);
          while (c) {
            err = hdf_copy (hdf, hdf_obj_name(c), c);
            if (err != STATUS_OK) break;
            c = hdf_obj_next(c);
          }
        }
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      } else if (s[0] == '=') /* assignment */
      {
	*s = '\0';
	name = neos_strip(name);
	s++;
	value = neos_strip(s);
	err = _set_value (hdf, name, value, 1, 1, 0, attr, NULL);
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else if (s[0] == ':' && s[1] == '=') /* copy */
      {
	*s = '\0';
	name = neos_strip(name);
	s+=2;
	value = neos_strip(s);
        HDF *h = hdf_get_obj(hdf->top, value);
        if (!h)
        {
	  err = nerr_raise(NERR_PARSE,
                           "[%s:%d] Failed to copy a node that is not loaded "
                           "yet: %s", path, *lineno, value);
          return err;
        }
        err = hdf_copy(hdf, name, h);
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else if (s[0] == '!' && s[1] == '=') /* exec */
      {
	*s = '\0';
	name = neos_strip(name);
	s+=2;
	value = neos_strip(s);

        FILE *f = popen(value, "r");
	if (f == NULL)
        {
	  err = nerr_raise(NERR_PARSE,
                           "[%s:%d] Failed to exec specified command: %s",
                           path, *lineno, line->buf);
          return err;
        }
        char *content = _read_file(f);
        fclose(f);
        int len = strlen(content);
        if (len > 0 && content[len - 1] == '\n') {
          content[len - 1] = '\0'; // remove \n artifact
        }
	err = _set_value (hdf, name, content, 1, 1, 0, attr, NULL);
        free(content);

	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else if (s[0] == ':') /* link */
      {
	*s = '\0';
	name = neos_strip(name);
	s++;
	value = neos_strip(s);
	err = _set_value (hdf, name, value, 1, 1, 1, attr, NULL);
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else if (s[0] == '{') /* deeper */
      {
	*s = '\0';
	name = neos_strip(name);
	lower = hdf_get_obj (hdf, name);
	if (lower == NULL)
	{
	  err = _set_value (hdf, name, NULL, 1, 1, 0, attr, &lower);
	}
	else
	{
	  err = _set_value (lower, NULL, lower->value, 1, 1, 0, attr, NULL);
	}
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
	err = _hdf_read_string (lower, str, line, path, lineno, include_handle,
                                1);
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else if (s[0] == '<' && s[1] == '<') /* multi-line assignment */
      {
	char *m;
	int msize = 0;
	int mmax = 128;
	int l;

	*s = '\0';
	name = neos_strip(name);
	s+=2;
	value = neos_strip(s);
	l = strlen(value);
	if (l == 0)
        {
	  err = nerr_raise(NERR_PARSE,
	      "[%s:%d] No multi-assignment terminator given: %s", path, *lineno,
	      line->buf);
          return err;
        }
	m = (char *) malloc (mmax * sizeof(char));
	if (m == NULL)
        {
	  return nerr_raise(NERR_NOMEM,
	    "[%s:%d] Unable to allocate memory for multi-line assignment to %s",
	    path, *lineno, name);
        }
	while (_copy_line (str, m+msize, mmax-msize) != 0)
	{
          (*lineno)++;
	  if (!strncmp(value, m+msize, l) && isspace(m[msize+l]))
	  {
	    m[msize] = '\0';
	    break;
	  }
	  msize += strlen(m+msize);
	  if (msize + l + 10 > mmax)
	  {
	    void *new_ptr;
	    mmax += 128;
	    new_ptr = realloc (m, mmax * sizeof(char));
	    if (new_ptr == NULL)
	    {
        free(m);
	      return nerr_raise(NERR_NOMEM,
		  "[%s:%d] Unable to allocate memory for multi-line assignment to %s: size=%d",
		  path, *lineno, name, mmax);
      }
      m = (char *) new_ptr;
	  }
	}
	err = _set_value (hdf, name, m, 0, 1, 0, attr, NULL);
	if (err != STATUS_OK)
	{
	  free (m);
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
	}

      }
      else
      {
	err = nerr_raise(NERR_PARSE, "[%s:%d] Unable to parse line %s", path,
	    *lineno, line->buf);
        return err;
      }
    }
  }
  if (expect_end_brace) {
    err = nerr_raise(NERR_PARSE, "[%s:%d] Missing matching }", path, *lineno);
    return err;
  }
  return STATUS_OK;
}