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 |
}
|