/alps/pcitool

To get this branch, use:
bzr branch http://darksoft.org/webbzr/alps/pcitool
353 by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov
1
#define _POSIX_C_SOURCE 200809L
309 by Suren A. Chilingaryan
Base functions for views
2
#include <stdio.h>
3
#include <stdlib.h>
4
#include <string.h>
5
#include <math.h>
6
7
8
#include "pcilib.h"
9
#include "value.h"
10
#include "error.h"
11
#include "unit.h"
314 by Suren A. Chilingaryan
Support writting register views
12
#include "tools.h"
309 by Suren A. Chilingaryan
Base functions for views
13
14
void pcilib_clean_value(pcilib_t *ctx, pcilib_value_t *val) {
15
    if (!val) return;
16
17
    if (val->data) {
18
        free(val->data);
19
        val->data = NULL;
20
    }
21
22
    memset(val, 0, sizeof(pcilib_value_t));
23
}
24
25
int pcilib_copy_value(pcilib_t *ctx, pcilib_value_t *dst, const pcilib_value_t *src) {
26
    if (dst->type != PCILIB_TYPE_INVALID)
27
        pcilib_clean_value(ctx, dst);
28
29
    memcpy(dst, src, sizeof(pcilib_value_t));
30
31
    if ((src->size)&&(src->data)) {
32
        dst->data = malloc(src->size);
33
        if (!dst->data) {
34
            dst->type = PCILIB_TYPE_INVALID;
35
            return PCILIB_ERROR_MEMORY;
36
        }
37
38
        memcpy(dst->data, src->data, src->size);
39
    }
40
41
    return 0;
42
}
43
44
int pcilib_set_value_from_float(pcilib_t *ctx, pcilib_value_t *value, double fval) {
45
    pcilib_clean_value(ctx, value);
46
47
    value->type = PCILIB_TYPE_DOUBLE;
48
    value->fval = fval;
49
50
    return 0;
51
}
52
53
int pcilib_set_value_from_int(pcilib_t *ctx, pcilib_value_t *value, long ival) {
54
    pcilib_clean_value(ctx, value);
55
56
    value->type = PCILIB_TYPE_LONG;
57
    value->ival = ival;
58
59
    return 0;
60
}
61
312 by Suren A. Chilingaryan
Support transform views
62
int pcilib_set_value_from_register_value(pcilib_t *ctx, pcilib_value_t *value, pcilib_register_value_t regval) {
63
    return pcilib_set_value_from_int(ctx, value, regval);
64
}
65
311 by Suren A. Chilingaryan
Implement enum view
66
int pcilib_set_value_from_static_string(pcilib_t *ctx, pcilib_value_t *value, const char *str) {
67
    pcilib_clean_value(ctx, value);
68
69
    value->type = PCILIB_TYPE_STRING;
70
    value->sval = str;
71
72
    return 0;
73
}
74
353 by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov
75
int pcilib_set_value_from_string(pcilib_t *ctx, pcilib_value_t *value, const char *str) {
76
    size_t len;
77
78
    pcilib_clean_value(ctx, value);
79
80
    len = strlen(str) + 1;
81
    if (len < sizeof(value->str)) {
82
	memcpy(value->str, str, len);
83
	value->sval = value->str;
84
    } else {
85
        value->data = (void*)strdup(str);
86
        if (!value->data) return PCILIB_ERROR_MEMORY;
87
88
	value->size = strlen(str) + 1;
89
	value->sval = value->data;
90
    }
91
    value->type = PCILIB_TYPE_STRING;
92
93
    return 0;
94
}
95
312 by Suren A. Chilingaryan
Support transform views
96
double pcilib_get_value_as_float(pcilib_t *ctx, const pcilib_value_t *val, int *ret) {
97
    int err;
98
    double res;
99
    pcilib_value_t copy = {0};
100
101
    err = pcilib_copy_value(ctx, &copy, val);
102
    if (err) {
103
        if (ret) *ret = err;
104
        return 0.;
105
    }
106
107
    err = pcilib_convert_value_type(ctx, &copy, PCILIB_TYPE_DOUBLE);
108
    if (err) {
109
        if (ret) *ret = err;
110
        return 0.;
111
    }
112
113
    if (ret) *ret = 0;
114
    res = copy.fval;
115
116
    pcilib_clean_value(ctx, &copy);
117
118
    return res;
119
}
120
121
long pcilib_get_value_as_int(pcilib_t *ctx, const pcilib_value_t *val, int *ret) {
122
    int err;
123
    long res;
124
    pcilib_value_t copy = {0};
125
126
    err = pcilib_copy_value(ctx, &copy, val);
127
    if (err) {
128
        if (ret) *ret = err;
129
        return 0;
130
    }
131
132
    err = pcilib_convert_value_type(ctx, &copy, PCILIB_TYPE_LONG);
133
    if (err) {
134
        if (ret) *ret = err;
135
        return 0;
136
    }
137
138
    if (ret) *ret = 0;
139
    res = copy.ival;
140
141
    pcilib_clean_value(ctx, &copy);
142
143
    return res;
144
}
145
146
pcilib_register_value_t pcilib_get_value_as_register_value(pcilib_t *ctx, const pcilib_value_t *val, int *ret) {
147
    int err;
148
    pcilib_register_value_t res;
149
    pcilib_value_t copy = {0};
150
151
    err = pcilib_copy_value(ctx, &copy, val);
152
    if (err) {
153
        if (ret) *ret = err;
154
        return 0.;
155
    }
156
157
    err = pcilib_convert_value_type(ctx, &copy, PCILIB_TYPE_LONG);
158
    if (err) {
159
        if (ret) *ret = err;
160
        return 0.;
161
    }
162
163
    if (ret) *ret = 0;
164
    res = copy.ival;
165
323 by Suren A. Chilingaryan
Add few messages to inform about precision problems while converting polymorphic values
166
    if (copy.ival < 0)
167
        pcilib_warning("Data corruption while converting negative polymorph value (%li) to the register type, result %u", copy.ival, res);
168
312 by Suren A. Chilingaryan
Support transform views
169
    pcilib_clean_value(ctx, &copy);
170
171
    return res;
172
}
173
174
175
311 by Suren A. Chilingaryan
Implement enum view
176
309 by Suren A. Chilingaryan
Base functions for views
177
/*
178
double pcilib_value_get_float(pcilib_value_t *val) {
179
    pcilib_value_t copy;
180
181
    if (val->type == PCILIB_TYPE_DOUBLE)
182
        return val->fval;
183
184
    err = pcilib_copy_value(&copy, val);
185
    if (err) ???
186
}
187
188
189
long pcilib_value_get_int(pcilib_value_t *val) {
190
}
191
*/
192
193
int pcilib_convert_value_unit(pcilib_t *ctx, pcilib_value_t *val, const char *unit_name) {
194
    if (val->type == PCILIB_TYPE_INVALID) {
195
        pcilib_error("Can't convert uninitialized value");
196
        return PCILIB_ERROR_NOTINITIALIZED;
197
    }
198
199
    if ((val->type != PCILIB_TYPE_DOUBLE)&&(val->type != PCILIB_TYPE_LONG)) {
200
        pcilib_error("Can't convert value of type %u, only values with integer and float types can be converted to different units", val->type);
201
        return PCILIB_ERROR_INVALID_ARGUMENT;
202
    }
203
204
    if (!val->unit) {
205
        pcilib_error("Can't convert value with the unspecified unit");
206
        return PCILIB_ERROR_INVALID_ARGUMENT;
207
    }
208
209
    pcilib_unit_t unit = pcilib_find_unit_by_name(ctx, val->unit);
210
    if (unit == PCILIB_UNIT_INVALID) {
211
        pcilib_error("Can't convert unrecognized unit %s", val->unit);
212
        return PCILIB_ERROR_NOTFOUND;
213
    }
214
215
    return pcilib_transform_unit_by_name(ctx, unit_name, val);
216
}
217
218
int pcilib_convert_value_type(pcilib_t *ctx, pcilib_value_t *val, pcilib_value_type_t type) {
219
    if (val->type == PCILIB_TYPE_INVALID) {
220
        pcilib_error("Can't convert uninitialized value");
221
        return PCILIB_ERROR_NOTINITIALIZED;
222
    }
223
224
    switch (type) {
225
     case PCILIB_TYPE_STRING:
226
        switch (val->type) {
227
         case PCILIB_TYPE_STRING:
311 by Suren A. Chilingaryan
Implement enum view
228
            return 0;
309 by Suren A. Chilingaryan
Base functions for views
229
         case PCILIB_TYPE_DOUBLE:
230
            sprintf(val->str, (val->format?val->format:"%lf"), val->fval);
231
            val->format = NULL;
232
            break;
233
         case PCILIB_TYPE_LONG:
234
            sprintf(val->str, (val->format?val->format:"%li"), val->ival);
235
            val->format = NULL;
236
            break;
237
         default:
238
            return PCILIB_ERROR_NOTSUPPORTED;
239
        }
240
        val->sval = val->str;
241
        break;
242
     case PCILIB_TYPE_DOUBLE:
243
        switch (val->type) {
244
         case PCILIB_TYPE_STRING:
245
            if (sscanf(val->sval, "%lf", &val->fval) != 1) {
246
                pcilib_warning("Can't convert string (%s) to float", val->sval);
247
                return PCILIB_ERROR_INVALID_DATA;
248
            }
249
            val->format = NULL;
250
            break;
251
         case PCILIB_TYPE_DOUBLE:
311 by Suren A. Chilingaryan
Implement enum view
252
            return 0;
309 by Suren A. Chilingaryan
Base functions for views
253
         case PCILIB_TYPE_LONG:
254
            val->fval = val->ival;
255
            val->format = NULL;
256
            break;
257
         default:
258
            return PCILIB_ERROR_NOTSUPPORTED;
259
        }
260
        break;
261
     case PCILIB_TYPE_LONG:
262
        switch (val->type) {
263
         case PCILIB_TYPE_STRING:
314 by Suren A. Chilingaryan
Support writting register views
264
            if (pcilib_isnumber(val->sval)) {
265
                if (sscanf(val->sval, "%li", &val->ival) != 1) {
266
                    pcilib_warning("Can't convert string (%s) to int", val->sval);
267
                    return PCILIB_ERROR_INVALID_DATA;
268
                }
269
                val->format = NULL;
270
            } else if (pcilib_isxnumber(val->sval)) {
271
                if (sscanf(val->sval, "%lx", &val->ival) != 1) {
272
                    pcilib_warning("Can't convert string (%s) to int", val->sval);
273
                    return PCILIB_ERROR_INVALID_DATA;
274
                }
275
                val->format = "0x%lx";
276
            } else {
309 by Suren A. Chilingaryan
Base functions for views
277
                pcilib_warning("Can't convert string (%s) to int", val->sval);
278
                return PCILIB_ERROR_INVALID_DATA;
279
            }
280
            break;
281
         case PCILIB_TYPE_DOUBLE:
323 by Suren A. Chilingaryan
Add few messages to inform about precision problems while converting polymorphic values
282
            if (val->fval != round(val->fval))
283
                pcilib_info("Precision is lost while converting float value %lf to integer %.0lf", val->fval, round(val->fval));
284
309 by Suren A. Chilingaryan
Base functions for views
285
            val->ival = round(val->fval);
286
            val->format = NULL;
287
            break;
288
         case PCILIB_TYPE_LONG:
311 by Suren A. Chilingaryan
Implement enum view
289
            return 0;
309 by Suren A. Chilingaryan
Base functions for views
290
         default:
291
            return PCILIB_ERROR_NOTSUPPORTED;
292
        }
293
     break;
294
     default:
295
        return PCILIB_ERROR_NOTSUPPORTED;
296
    }
297
315 by Suren A. Chilingaryan
Support properties of arbitrary type
298
    val->type = type;
309 by Suren A. Chilingaryan
Base functions for views
299
    return 0;
300
}