3 * \brief Helper functions to read record contents.
7 * Copyright (c) 2011, ETH Zurich.
10 * This file is distributed under the terms in the attached LICENSE file.
11 * If you do not find this file, copies can be found by writing to:
12 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
19 #include <barrelfish/barrelfish.h>
21 #include <dist2/getset.h>
22 #include <dist2/parser/ast.h>
25 * \brief Reads the content of a record string based on the provided format.
26 * Currently supported %d (int64_t*), %f (double*?), %s (char**).
27 * TODO: more detailed docs!
29 * \param record Record to read.
30 * \param format What you want to read.
31 * \param ... Values read are stored in the provided arguments.
34 * \retval DIST2_ERR_ATTRIBUTE_NOT_FOUND
35 * \retval DIST2_ERR_TYPE_MISMATCH
36 * \retval DIST2_ERR_RECORD_NAME_MISMATCH
37 * \retval DIST2_ERR_ATTRIBUTE_MISMATCH
39 errval_t dist_read(const char* record, const char* format, ...)
41 errval_t err = SYS_ERR_OK;
43 va_start(args, format);
49 // Parse record and format strings
50 struct ast_object* ast = NULL;
51 struct ast_object* format_ast = NULL;
53 err = generate_ast(record, &ast);
54 if(err_is_fail(err)) {
57 err = generate_ast(format, &format_ast);
58 if(err_is_fail(err)) {
63 struct ast_object* format_name = format_ast->u.on.name;
64 switch(format_name->type) {
66 if(format_name->u.scn.c != 's') {
67 err = DIST2_ERR_INVALID_FORMAT;
70 s = va_arg(args, char**);
71 *s = ast->u.on.name->u.in.str;
72 // Remove from AST so client has to free it
73 ast->u.on.name->u.in.str = NULL;
76 case nodeType_Variable:
77 // Just ignore record name
81 err = DIST2_ERR_INVALID_FORMAT;
87 struct ast_object* attr = format_ast->u.on.attrs;
88 for(; attr != NULL; attr = attr->u.an.next) {
90 struct ast_object* format_attr = attr->u.an.attr;
93 assert(format_attr->type == nodeType_Pair);
94 assert(format_attr->u.pn.left->type == nodeType_Ident);
95 if(format_attr->u.pn.right->type != nodeType_Scan) {
96 err = DIST2_ERR_INVALID_FORMAT;
100 // Try to find attribute in record AST
101 struct ast_object* record_attr = ast_find_attribute(ast,
102 format_attr->u.pn.left->u.in.str);
103 if(record_attr == NULL) {
104 err = DIST2_ERR_UNKNOWN_ATTRIBUTE;
107 struct ast_object* value = record_attr->u.pn.right;
109 switch(format_attr->u.pn.right->u.scn.c) {
111 s = va_arg(args, char**);
112 if(value->type == nodeType_Ident) {
113 *s = value->u.in.str;
114 value->u.in.str = NULL;
116 else if(value->type == nodeType_String) {
117 *s = value->u.sn.str;
118 value->u.sn.str = NULL;
121 err = DIST2_ERR_INVALID_FORMAT;
127 i = va_arg(args, int64_t*);
128 if(value->type == nodeType_Constant) {
129 *i = value->u.cn.value;
133 err = DIST2_ERR_INVALID_FORMAT;
139 d = va_arg(args, double*);
140 if(value->type == nodeType_Float) {
141 *d = value->u.fn.value;
145 err = DIST2_ERR_INVALID_FORMAT;
151 err = DIST2_ERR_INVALID_FORMAT;
160 free_ast(format_ast);