/alps/pcitool

To get this branch, use:
bzr branch http://suren.me/webbzr/alps/pcitool
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <string.h>
4
#include <strings.h>
5
6
#include "pci.h"
7
#include "pcilib.h"
8
#include "unit.h"
9
#include "error.h"
10
309 by Suren A. Chilingaryan
Base functions for views
11
static pcilib_unit_transform_t pcilib_unit_transform_null = { NULL, NULL };
12
310 by Suren A. Chilingaryan
Introduce hashes
13
int pcilib_add_units(pcilib_t *ctx, size_t n, const pcilib_unit_description_t *desc) {
14
    size_t i;
15
    int err = 0;
16
17
    if (!n) {
18
        for (n = 0; desc[n].name; n++);
19
    }
20
21
    if ((ctx->num_units + n + 1) > ctx->alloc_units) {
22
	size_t size;
23
	pcilib_unit_description_t *units;
24
25
        for (size = ctx->alloc_units; size < 2 * (n + ctx->num_units + 1); size <<= 1);
26
27
        units = (pcilib_unit_description_t*)realloc(ctx->units, size * sizeof(pcilib_unit_description_t));
28
        if (!units) return PCILIB_ERROR_MEMORY;
29
30
        ctx->units = units;
31
        ctx->alloc_units = size;
32
33
        ctx->model_info.units = units;
34
    }
35
36
        // ToDo: Check if exists...
37
    for (i = 0; i < n; i++) {
315 by Suren A. Chilingaryan
Support properties of arbitrary type
38
        pcilib_unit_t unit = pcilib_find_unit_by_name(ctx, desc[i].name);
39
        if (unit != PCILIB_UNIT_INVALID) {
40
            pcilib_clean_units(ctx, ctx->num_units);
41
            pcilib_error("Unit %s is already defined in the model", desc[i].name);
42
            return PCILIB_ERROR_EXIST;
43
        }
44
310 by Suren A. Chilingaryan
Introduce hashes
45
        pcilib_unit_context_t *unit_ctx = (pcilib_unit_context_t*)malloc(sizeof(pcilib_unit_context_t));
46
        if (!unit_ctx) {
315 by Suren A. Chilingaryan
Support properties of arbitrary type
47
            pcilib_clean_units(ctx, ctx->num_units);
48
            return PCILIB_ERROR_MEMORY;
310 by Suren A. Chilingaryan
Introduce hashes
49
        }
315 by Suren A. Chilingaryan
Support properties of arbitrary type
50
310 by Suren A. Chilingaryan
Introduce hashes
51
        memset(unit_ctx, 0, sizeof(pcilib_unit_context_t));
52
        unit_ctx->unit = ctx->num_units + i;
53
        unit_ctx->name = desc[i].name;
54
55
        HASH_ADD_KEYPTR(hh, ctx->unit_hash, unit_ctx->name, strlen(unit_ctx->name), unit_ctx);
56
        memcpy(ctx->units + ctx->num_units + i, &desc[i], sizeof(pcilib_unit_description_t));
57
    }
58
315 by Suren A. Chilingaryan
Support properties of arbitrary type
59
    ctx->num_units += n;
60
    memset(ctx->units + ctx->num_units, 0, sizeof(pcilib_unit_description_t));
310 by Suren A. Chilingaryan
Introduce hashes
61
62
    return err;
63
}
64
315 by Suren A. Chilingaryan
Support properties of arbitrary type
65
void pcilib_clean_units(pcilib_t *ctx, pcilib_unit_t start) {
310 by Suren A. Chilingaryan
Introduce hashes
66
    pcilib_unit_context_t *s, *tmp;
67
68
    if (ctx->unit_hash) {
69
        HASH_ITER(hh, ctx->unit_hash, s, tmp) {
315 by Suren A. Chilingaryan
Support properties of arbitrary type
70
            if (s->unit >= start) {
71
                HASH_DEL(ctx->unit_hash, s);
72
                free(s);
73
            }
310 by Suren A. Chilingaryan
Introduce hashes
74
        }
75
    }
76
315 by Suren A. Chilingaryan
Support properties of arbitrary type
77
    memset(&ctx->units[start], 0, sizeof(pcilib_unit_description_t));
78
    ctx->num_units = start;
310 by Suren A. Chilingaryan
Introduce hashes
79
}
80
309 by Suren A. Chilingaryan
Base functions for views
81
pcilib_unit_t pcilib_find_unit_by_name(pcilib_t *ctx, const char *name) {
310 by Suren A. Chilingaryan
Introduce hashes
82
    pcilib_unit_context_t *unit_ctx = NULL;
83
84
    HASH_FIND_STR(ctx->unit_hash, name, unit_ctx);
85
    if (unit_ctx) return unit_ctx->unit;
86
87
/*
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
88
    pcilib_unit_t i;
89
    for(i = 0; ctx->units[i].name; i++) {
309 by Suren A. Chilingaryan
Base functions for views
90
        if (!strcasecmp(ctx->units[i].name, name))
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
91
	    return i;
92
    }
310 by Suren A. Chilingaryan
Introduce hashes
93
*/
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
94
    return PCILIB_UNIT_INVALID;
95
}
96
309 by Suren A. Chilingaryan
Base functions for views
97
pcilib_unit_transform_t *pcilib_find_transform_by_unit_names(pcilib_t *ctx, const char *from, const char *to) {
98
    int i;
99
    pcilib_unit_t unit;
100
101
    if ((!from)||(!to))
102
	return NULL;
103
104
    if (!strcasecmp(from, to)) 
105
	return &pcilib_unit_transform_null;
106
107
    unit = pcilib_find_unit_by_name(ctx, from);
108
    if (unit == PCILIB_UNIT_INVALID) return NULL;
109
110
    for (i = 0; ctx->units[unit].transforms[i].unit; i++) {
111
        if (!strcasecmp(ctx->units[unit].transforms[i].unit, to))
112
            return &ctx->units[unit].transforms[i];
113
    }
114
115
    return NULL;
116
}
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
117
315 by Suren A. Chilingaryan
Support properties of arbitrary type
118
int pcilib_transform_unit(pcilib_t *ctx, const pcilib_unit_transform_t *trans, pcilib_value_t *value) {
309 by Suren A. Chilingaryan
Base functions for views
119
    int err;
120
315 by Suren A. Chilingaryan
Support properties of arbitrary type
121
    if (trans->transform) {
122
        err = pcilib_py_eval_string(ctx, trans->transform, value);
123
        if (err) return err;
124
125
        value->unit = trans->unit;
126
    } else if (trans->unit) {
127
        value->unit = trans->unit;
128
    } 
129
309 by Suren A. Chilingaryan
Base functions for views
130
    return 0;
131
}
132
133
134
int pcilib_transform_unit_by_name(pcilib_t *ctx, const char *to, pcilib_value_t *value) {
135
    pcilib_unit_transform_t *trans;
136
137
    if (!value->unit) {
138
        pcilib_warning("Can't transform unit of the value with unspecified unit");
139
        return PCILIB_ERROR_INVALID_ARGUMENT;
140
    }
141
142
    trans = pcilib_find_transform_by_unit_names(ctx, value->unit, to);
143
    if (!trans) {
144
        pcilib_warning("Can't transform unit (%s) to (%s)", value->unit, to);
145
        return PCILIB_ERROR_NOTSUPPORTED;
146
    }
147
148
    return pcilib_transform_unit(ctx, trans, value);
149
}