OpenCores
URL https://opencores.org/ocsvn/riscv_vhdl/riscv_vhdl/trunk

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [debugger/] [src/] [common/] [attribute.cpp] - Blame information for rev 3

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 sergeykhbr
/**
2
 * @file
3
 * @copyright  Copyright 2016 GNSS Sensor Ltd. All right reserved.
4
 * @author     Sergey Khabarov - sergeykhbr@gmail.com
5
 * @brief      Core attribute methods implementation.
6
 */
7
 
8
#include "api_core.h"
9
#include "autobuffer.h"
10
#include "iservice.h"
11
#include "api_utils.h"
12
#include <cstdlib>
13
 
14
namespace debugger {
15
 
16
static const int64_t MIN_ALLOC_BYTES = 1 << 12;
17
static AttributeType NilAttribute;
18
static AutoBuffer strBuffer;
19
 
20
char *attribute_to_string(const AttributeType *attr);
21 3 sergeykhbr
int string_to_attribute(const char *cfg, int &off, AttributeType *out);
22 2 sergeykhbr
 
23
void AttributeType::attr_free() {
24
    if (size()) {
25
        if (is_string()) {
26
            RISCV_free(u_.string);
27
        } else if (is_data() && size() > 8) {
28
            RISCV_free(u_.data);
29
        } else if (is_list()) {
30
            for (unsigned i = 0; i < size(); i++) {
31
                u_.list[i].attr_free();
32
            }
33
            RISCV_free(u_.list);
34
        } else if (is_dict()) {
35
            for (unsigned i = 0; i < size(); i++) {
36
                u_.dict[i].key_.attr_free();
37
                u_.dict[i].value_.attr_free();
38
            }
39
            RISCV_free(u_.dict);
40
        }
41
    }
42
    kind_ = Attr_Invalid;
43
    size_ = 0;
44
    u_.integer = 0;
45
}
46
 
47
void AttributeType::clone(const AttributeType *v) {
48
    attr_free();
49
 
50
    if (v->is_string()) {
51
        this->make_string(v->to_string());
52
    } else if (v->is_data()) {
53
        this->make_data(v->size(), v->data());
54
    } else if (v->is_list()) {
55
        make_list(v->size());
56
        for (unsigned i = 0; i < v->size(); i++ ) {
57
            u_.list[i].clone(v->list(i));
58
        }
59
    } else if (v->is_dict()) {
60
        make_dict();
61
        realloc_dict(v->size());
62
        for (unsigned i = 0; i < v->size(); i++ ) {
63
            u_.dict[i].key_.make_string(v->dict_key(i)->to_string());
64
            u_.dict[i].value_.clone(v->dict_value(i));
65
        }
66
    } else {
67
        this->kind_ = v->kind_;
68
        this->u_ = v->u_;
69
        this->size_ = v->size_;
70
    }
71
}
72
 
73
bool AttributeType::is_equal(const char *v) {
74
    if (!is_string()) {
75
        return false;
76
    }
77
    return !strcmp(to_string(), v);
78
}
79
 
80
 
81
AttributeType &AttributeType::operator=(const AttributeType& other) {
82
    if (&other != this) {
83
        clone(&other);
84
    }
85
    return *this;
86
}
87
 
88
 
89
const AttributeType &AttributeType::operator[](unsigned idx) const {
90
    if (is_list()) {
91
        return u_.list[idx];
92
    } else if (is_dict()) {
93
        return u_.dict[idx].value_;
94
    } else {
95
        RISCV_printf(NULL, LOG_ERROR, "%s", "Non-indexed attribute type");
96
    }
97
    return NilAttribute;
98
}
99
 
100
AttributeType &AttributeType::operator[](unsigned idx) {
101
    if (is_list()) {
102
        return u_.list[idx];
103
    } else if (is_dict()) {
104
        return u_.dict[idx].value_;
105
    } else {
106
        RISCV_printf(NULL, LOG_ERROR, "%s", "Non-indexed attribute type");
107
    }
108
    return NilAttribute;
109
}
110
 
111
const AttributeType &AttributeType::operator[](const char *key) const {
112
    for (unsigned i = 0; i < size(); i++) {
113
        if (strcmp(key, u_.dict[i].key_.to_string()) == 0) {
114
            return u_.dict[i].value_;
115
        }
116
    }
117
    AttributeType *pthis = const_cast<AttributeType*>(this);
118
    pthis->realloc_dict(size()+1);
119
    pthis->u_.dict[size()-1].key_.make_string(key);
120
    pthis->u_.dict[size()-1].value_.make_nil();
121
    return u_.dict[size()-1].value_;
122
}
123
 
124
AttributeType &AttributeType::operator[](const char *key) {
125
    for (unsigned i = 0; i < size(); i++) {
126
        if (strcmp(key, u_.dict[i].key_.to_string()) == 0) {
127
            return u_.dict[i].value_;
128
        }
129
    }
130
    realloc_dict(size()+1);
131
    u_.dict[size()-1].key_.make_string(key);
132
    u_.dict[size()-1].value_.make_nil();
133
    return u_.dict[size()-1].value_;
134
}
135
 
136
const uint8_t &AttributeType::operator()(unsigned idx) const {
137
    if (idx > size()) {
138
        RISCV_printf(NULL, LOG_ERROR, "Data index '%d' out of range.", idx);
139
        return u_.data[0];
140
    }
141
    if (size_ > 8) {
142
        return u_.data[idx];
143
    }
144
    return u_.data_bytes[idx];
145
}
146
 
147
void AttributeType::make_string(const char *value) {
148
    attr_free();
149
    if (value) {
150
        kind_ = Attr_String;
151
        size_ = (unsigned)strlen(value);
152
        u_.string = static_cast<char *>(RISCV_malloc(size_ + 1));
153
        memcpy(u_.string, value, size_ + 1);
154
    } else {
155
        kind_ = Attr_Nil;
156
    }
157
}
158
 
159
void AttributeType::make_data(unsigned size) {
160
    attr_free();
161
    kind_ = Attr_Data;
162
    size_ = size;
163
    if (size > 8) {
164
        u_.data = static_cast<uint8_t *>(RISCV_malloc(size_));
165
    }
166
}
167
 
168
void AttributeType::make_data(unsigned size, const void *data) {
169
    attr_free();
170
    kind_ = Attr_Data;
171
    size_ = size;
172
    if (size > 8) {
173
        u_.data = static_cast<uint8_t *>(RISCV_malloc(size_));
174
        memcpy(u_.data, data, size);
175
    } else {
176
        memcpy(u_.data_bytes, data, size);
177
    }
178
}
179
 
180
void AttributeType::make_list(unsigned size) {
181
    attr_free();
182
    kind_ = Attr_List;
183
    if (size) {
184
        realloc_list(size);
185
    }
186
}
187
 
188
void AttributeType::realloc_list(unsigned size) {
189
    size_t req_sz = (size * sizeof(AttributeType) + MIN_ALLOC_BYTES - 1)
190
                   / MIN_ALLOC_BYTES;
191
    size_t cur_sz = (size_ * sizeof(AttributeType) + MIN_ALLOC_BYTES - 1)
192
                  / MIN_ALLOC_BYTES;
193
    if (req_sz > cur_sz ) {
194
        AttributeType * t1 = static_cast<AttributeType *>(
195
                RISCV_malloc(MIN_ALLOC_BYTES * req_sz));
196
        memcpy(t1, u_.list, size_ * sizeof(AttributeType));
197
        memset(&t1[size_], 0,
198
                (MIN_ALLOC_BYTES * req_sz) - size_ * sizeof(AttributeType));
199
        if (size_) {
200
            RISCV_free(u_.list);
201
        }
202
        u_.list = t1;
203
    }
204
    size_ = size;
205
}
206
 
207
void AttributeType::insert_to_list(unsigned idx, const AttributeType *item) {
208
    if (idx > size_) {
209
        RISCV_printf(NULL, LOG_ERROR, "%s", "Insert index out of bound");
210
        return;
211
    }
212
    size_t new_sz = ((size_ + 1) * sizeof(AttributeType) + MIN_ALLOC_BYTES - 1)
213
                  / MIN_ALLOC_BYTES;
214
    AttributeType * t1 = static_cast<AttributeType *>(
215
                RISCV_malloc(MIN_ALLOC_BYTES * new_sz));
216
    memset(t1 + idx, 0, sizeof(AttributeType));  // Fix bug request #4
217
 
218
    memcpy(t1, u_.list, idx * sizeof(AttributeType));
219
    t1[idx].clone(item);
220
    memcpy(&t1[idx + 1], &u_.list[idx], (size_ - idx) * sizeof(AttributeType));
221
    memset(&t1[size_ + 1], 0,
222
          (MIN_ALLOC_BYTES * new_sz) - (size_ + 1) * sizeof(AttributeType));
223
    if (size_) {
224
        RISCV_free(u_.list);
225
    }
226
    u_.list = t1;
227
    size_++;
228
}
229
 
230
void AttributeType::remove_from_list(unsigned idx) {
231
    if (idx >= size_) {
232
        RISCV_printf(NULL, LOG_ERROR, "%s", "Remove index out of range");
233
        return;
234
    }
235
    (*this)[idx].attr_free();
236
    if (idx == (size() - 1)) {
237
        size_ -= 1;
238
    } else if (idx < size ()) {
239
        swap_list_item(idx, size() - 1);
240
        size_ -= 1;
241
    }
242
}
243
 
244
void AttributeType::trim_list(unsigned start, unsigned end) {
245
    for (unsigned i = start; i < (size_ - end); i++) {
246
        u_.list[start + i].attr_free();
247
        u_.list[start + i] = u_.list[end + i];
248
    }
249
    size_ -= (end - start);
250
}
251
 
252
void AttributeType::swap_list_item(unsigned n, unsigned m) {
253
    if (n == m) {
254
        return;
255
    }
256
    unsigned tsize = u_.list[n].size_;
257
    KindType tkind = u_.list[n].kind_;
258
    int64_t tinteger = u_.list[n].u_.integer;
259
    u_.list[n].size_ = u_.list[m].size_;
260
    u_.list[n].kind_ = u_.list[m].kind_;
261
    u_.list[n].u_.integer = u_.list[m].u_.integer;
262
    u_.list[m].size_ = tsize;
263
    u_.list[m].kind_ = tkind;
264
    u_.list[m].u_.integer = tinteger;
265
}
266
 
267
 
268
int partition(AttributeType *A, int lo, int hi, int lst_idx) {
269
    AttributeType *pivot = &(*A)[hi];
270
    bool do_swap;
271
    int i = lo - 1;
272
    for (int j = lo; j < hi; j++) {
273
        AttributeType &item = (*A)[j];
274
        do_swap = false;
275
        if (item.is_string()) {
276
            if (strcmp(item.to_string(), pivot->to_string()) <= 0) {
277
                do_swap = true;
278
            }
279
        } else if (item.is_int64()) {
280
            if (item.to_int64() <= pivot->to_int64()) {
281
                do_swap = true;
282
            }
283
        } else if (item.is_uint64()) {
284
            if (item.to_uint64() <= pivot->to_uint64()) {
285
                do_swap = true;
286
            }
287
        } else if (item.is_list()) {
288
            AttributeType &t1 = item[lst_idx];
289
            if (t1.is_string() &&
290
                strcmp(t1.to_string(), (*pivot)[lst_idx].to_string()) <= 0) {
291
                do_swap = true;
292
            } else if (t1.is_int64() &&
293
                t1.to_int64() <= (*pivot)[lst_idx].to_int64()) {
294
                do_swap = true;
295
            } else if (t1.is_uint64() &&
296
                t1.to_uint64() <= (*pivot)[lst_idx].to_uint64()) {
297
                do_swap = true;
298
            }
299
        } else {
300
            RISCV_printf(NULL, LOG_ERROR, "%s",
301
                        "Not supported attribute type for sorting");
302
            return i + 1;
303
        }
304
 
305
        if (do_swap) {
306
            i = i + 1;
307
            A->swap_list_item(i, j);
308
        }
309
    }
310
    A->swap_list_item(i + 1, hi);
311
    return i + 1;
312
}
313
 
314
void quicksort(AttributeType *A, int lo, int hi, int lst_idx) {
315
    if (lo >= hi) {
316
        return;
317
    }
318
    int p = partition(A, lo, hi, lst_idx);
319
    quicksort(A, lo, p - 1, lst_idx);
320
    quicksort(A, p + 1, hi, lst_idx);
321
}
322
 
323
void AttributeType::sort(int idx) {
324
    if (!is_list()) {
325
        RISCV_printf(NULL, LOG_ERROR, "%s",
326
                    "Sort algorithm can applied only to list attribute");
327
    }
328
    quicksort(this, 0, static_cast<int>(size()) - 1, idx);
329
}
330
 
331
bool AttributeType::has_key(const char *key) const {
332
    for (unsigned i = 0; i < size(); i++) {
333
        if (strcmp(u_.dict[i].key_.to_string(), key) == 0
334
            && !u_.dict[i].value_.is_nil()) {
335
            return true;
336
        }
337
    }
338
    return false;
339
}
340
 
341
const AttributeType *AttributeType::dict_key(unsigned idx) const {
342
    return &u_.dict[idx].key_;
343
}
344
AttributeType *AttributeType::dict_key(unsigned idx) {
345
    return &u_.dict[idx].key_;
346
}
347
 
348
const AttributeType *AttributeType::dict_value(unsigned idx) const {
349
    return &u_.dict[idx].value_;
350
}
351
AttributeType *AttributeType::dict_value(unsigned idx) {
352
    return &u_.dict[idx].value_;
353
}
354
 
355
void AttributeType::make_dict() {
356
    attr_free();
357
    kind_ = Attr_Dict;
358
    size_ = 0;
359
    u_.dict = NULL;
360
}
361
 
362
void AttributeType::realloc_dict(unsigned size) {
363
    size_t req_sz = (size * sizeof(AttributePairType) + MIN_ALLOC_BYTES - 1)
364
                  / MIN_ALLOC_BYTES;
365
    size_t cur_sz = (size_ * sizeof(AttributePairType) + MIN_ALLOC_BYTES - 1)
366
                  / MIN_ALLOC_BYTES;
367
    if (req_sz > cur_sz ) {
368
        AttributePairType * t1 = static_cast<AttributePairType *>(
369
                RISCV_malloc(MIN_ALLOC_BYTES * req_sz));
370
        memcpy(t1, u_.dict, size_ * sizeof(AttributePairType));
371
        memset(&t1[size_], 0,
372
                (MIN_ALLOC_BYTES * req_sz) - size_ * sizeof(AttributePairType));
373
        if (size_) {
374
            RISCV_free(u_.dict);
375
        }
376
        u_.dict = t1;
377
    }
378
    size_ = size;
379
}
380
 
381
char *AttributeType::to_config() {
382
    strBuffer.clear();
383
    attribute_to_string(this);
384
    return strBuffer.getBuffer();
385
}
386
 
387
void AttributeType::from_config(const char *str) {
388 3 sergeykhbr
    int off = 0;
389
    string_to_attribute(str, off, this);
390 2 sergeykhbr
}
391
 
392
char *attribute_to_string(const AttributeType *attr) {
393
    IService *iserv;
394
    AutoBuffer *buf = &strBuffer;
395
    if (attr->is_nil()) {
396
        buf->write_string("None");
397
    } else if (attr->is_int64() || attr->is_uint64()) {
398
        buf->write_uint64(attr->to_uint64());
399
    } else if (attr->is_string()) {
400
        buf->write_string('\'');
401
        buf->write_string(attr->to_string());
402
        buf->write_string('\'');
403
    } else if (attr->is_bool()) {
404
        if (attr->to_bool()) {
405
            buf->write_string("true");
406
        } else {
407
            buf->write_string("false");
408
        }
409
    } else if (attr->is_list()) {
410
        AttributeType list_item;
411
        unsigned list_sz = attr->size();
412
        buf->write_string('[');
413
        for (unsigned i = 0; i < list_sz; i++) {
414
            list_item = (*attr)[i];
415
            attribute_to_string(&list_item);
416
            if (i < (list_sz - 1)) {
417
                buf->write_string(',');
418
            }
419
        }
420
        buf->write_string(']');
421
    } else if (attr->is_dict()) {
422
        AttributeType dict_item;
423
        unsigned dict_sz = attr->size();;
424
        buf->write_string('{');
425
 
426
        for (unsigned i = 0; i < dict_sz; i++) {
427
            buf->write_string('\'');
428
            buf->write_string(attr->u_.dict[i].key_.to_string());
429
            buf->write_string('\'');
430
            buf->write_string(':');
431
            const AttributeType &dict_value = (*attr)[i];
432
            attribute_to_string(&dict_value);
433
            if (i < (dict_sz - 1)) {
434
                buf->write_string(',');
435
            }
436
        }
437
        buf->write_string('}');
438
    } else if (attr->is_data()) {
439
        buf->write_string('(');
440
        if (attr->size() > 0) {
441
            for (unsigned n = 0; n < attr->size()-1;  n++) {
442
                buf->write_byte((*attr)(n));
443
                buf->write_string(',');
444
            }
445
            buf->write_byte((*attr)(attr->size()-1));
446
        }
447
        buf->write_string(')');
448
    } else if (attr->is_iface()) {
449
        IFace *iface = attr->to_iface();
450
        if (strcmp(iface->getFaceName(), IFACE_SERVICE) == 0) {
451
            iserv = static_cast<IService *>(iface);
452
            buf->write_string('{');
453
            buf->write_string("'Type':'");
454
            buf->write_string(iface->getFaceName());
455
            buf->write_string("','ModuleName':'");
456
            buf->write_string(iserv->getObjName());
457
            buf->write_string("'}");
458
        } else {
459
            RISCV_printf(NULL, LOG_ERROR,
460
                        "Not implemented interface to dict. method");
461
        }
462
    } else if (attr->is_floating()) {
463
        char fstr[64];
464
        RISCV_sprintf(fstr, sizeof(fstr), "%.4f", attr->to_float());
465
        buf->write_string(fstr);
466
    }
467
    return buf->getBuffer();
468
}
469
 
470 3 sergeykhbr
int skip_special_symbols(const char *cfg, int off) {
471
    const char *pcur = &cfg[off];
472 2 sergeykhbr
    while (*pcur == ' ' || *pcur == '\r' || *pcur == '\n' || *pcur == '\t') {
473
        pcur++;
474 3 sergeykhbr
        off++;
475 2 sergeykhbr
    }
476 3 sergeykhbr
    return off;
477 2 sergeykhbr
}
478
 
479 3 sergeykhbr
int string_to_attribute(const char *cfg, int &off,
480
                         AttributeType *out) {
481
    off = skip_special_symbols(cfg, off);
482
    int checkstart = off;
483
    if (cfg[off] == '\'' || cfg[off] == '"') {
484 2 sergeykhbr
        AutoBuffer buf;
485 3 sergeykhbr
        uint8_t t1 = cfg[off];
486 2 sergeykhbr
        int str_sz = 0;
487 3 sergeykhbr
        const char *pcur = &cfg[++off];
488 2 sergeykhbr
        while (*pcur != t1 && *pcur != '\0') {
489
            pcur++;
490
            str_sz++;
491
        }
492 3 sergeykhbr
        buf.write_bin(&cfg[off], str_sz);
493 2 sergeykhbr
        out->make_string(buf.getBuffer());
494 3 sergeykhbr
        off += str_sz;
495
        if (cfg[off] != t1) {
496
            RISCV_printf(NULL, LOG_ERROR,
497
                        "JSON parser error: Wrong string format");
498
            out->attr_free();
499
            return -1;
500
        }
501
        off = skip_special_symbols(cfg, off + 1);
502
    } else if (cfg[off] == '[') {
503
        off = skip_special_symbols(cfg, off + 1);
504 2 sergeykhbr
        AttributeType new_item;
505
        out->make_list(0);
506 3 sergeykhbr
        while (cfg[off] != ']' && cfg[off] != '\0') {
507
            if (string_to_attribute(cfg, off, &new_item)) {
508
                /* error handling */
509
                out->attr_free();
510
                return -1;
511
            }
512 2 sergeykhbr
            out->realloc_list(out->size() + 1);
513
            (*out)[out->size() - 1] = new_item;
514
 
515 3 sergeykhbr
            off = skip_special_symbols(cfg, off);
516
            if (cfg[off] == ',') {
517
                off = skip_special_symbols(cfg, off + 1);
518 2 sergeykhbr
            }
519
        }
520 3 sergeykhbr
        if (cfg[off] != ']') {
521
            RISCV_printf(NULL, LOG_ERROR,
522
                        "JSON parser error: Wrong list format");
523
            out->attr_free();
524
            return -1;
525
        }
526
        off = skip_special_symbols(cfg, off + 1);
527
    } else if (cfg[off] == '{') {
528 2 sergeykhbr
        AttributeType new_key;
529
        AttributeType new_value;
530
        out->make_dict();
531 3 sergeykhbr
        off = skip_special_symbols(cfg, off + 1);
532
        while (cfg[off] != '}' && cfg[off] != '\0') {
533
            if (string_to_attribute(cfg, off, &new_key)) {
534
                RISCV_printf(NULL, LOG_ERROR,
535
                            "JSON parser error: Wrong dictionary key");
536
                out->attr_free();
537
                return -1;
538 2 sergeykhbr
            }
539 3 sergeykhbr
            off = skip_special_symbols(cfg, off);
540
            if (cfg[off] != ':') {
541
                out->attr_free();
542
                RISCV_printf(NULL, LOG_ERROR,
543
                            "JSON parser error: Wrong dictionary delimiter");
544
                return -1;
545
            }
546
            off = skip_special_symbols(cfg, off + 1);
547
            if (string_to_attribute(cfg, off, &new_value)) {
548
                RISCV_printf(NULL, LOG_ERROR,
549
                            "JSON parser error: Wrong dictionary value");
550
                out->attr_free();
551
                return -1;
552
            }
553 2 sergeykhbr
 
554
            (*out)[new_key.to_string()] = new_value;
555
 
556 3 sergeykhbr
            off = skip_special_symbols(cfg, off);
557
            if (cfg[off] == ',') {
558
                off = skip_special_symbols(cfg, off + 1);
559 2 sergeykhbr
            }
560
        }
561 3 sergeykhbr
        if (cfg[off] != '}') {
562
            RISCV_printf(NULL, LOG_ERROR,
563
                        "JSON parser error: Wrong dictionary format");
564
            out->attr_free();
565
            return -1;
566
        }
567
        off = skip_special_symbols(cfg, off + 1);
568 2 sergeykhbr
 
569
        if (out->has_key("Type")) {
570
            if (strcmp((*out)["Type"].to_string(), IFACE_SERVICE) == 0) {
571
                IService *iserv;
572
                iserv = static_cast<IService *>(
573
                        RISCV_get_service((*out)["ModuleName"].to_string()));
574
                out->attr_free();
575
                *out = AttributeType(iserv);
576
            } else {
577
                RISCV_printf(NULL, LOG_ERROR,
578
                        "Not implemented string to dict. attribute");
579
            }
580
        }
581 3 sergeykhbr
    } else if (cfg[off] == '(') {
582 2 sergeykhbr
        AutoBuffer buf;
583
        char byte_value;
584 3 sergeykhbr
        off = skip_special_symbols(cfg, off);
585
        while (cfg[off] != ')' && cfg[off] != '\0') {
586 2 sergeykhbr
            byte_value = 0;
587
            for (int n = 0; n < 2; n++) {
588 3 sergeykhbr
                if (cfg[off] >= 'A' && cfg[off] <= 'F') {
589
                    byte_value = (byte_value << 4) | ((cfg[off] - 'A') + 10);
590 2 sergeykhbr
                } else {
591 3 sergeykhbr
                    byte_value = (byte_value << 4) | (cfg[off] - '0');
592 2 sergeykhbr
                }
593 3 sergeykhbr
                off++;
594 2 sergeykhbr
            }
595
            buf.write_bin(&byte_value, 1);
596
 
597 3 sergeykhbr
            off = skip_special_symbols(cfg, off);
598
            if (cfg[off] != ',') {
599
                RISCV_printf(NULL, LOG_ERROR,
600
                            "JSON parser error: Wrong data dytes delimiter");
601
                out->attr_free();
602
                return -1;
603 2 sergeykhbr
            }
604 3 sergeykhbr
            off = skip_special_symbols(cfg, off + 1);
605 2 sergeykhbr
        }
606 3 sergeykhbr
        if (cfg[off] != ')') {
607
            RISCV_printf(NULL, LOG_ERROR,
608
                        "JSON parser error: Wrong data format");
609
            out->attr_free();
610
            return -1;
611
        }
612 2 sergeykhbr
        out->make_data(buf.size(), buf.getBuffer());
613 3 sergeykhbr
        off = skip_special_symbols(cfg, off + 1);
614
    } else if (cfg[off] == 'N' && cfg[off + 1] == 'o' && cfg[off + 2] == 'n'
615
                && cfg[off + 3] == 'e') {
616
        out->make_nil();
617
        off = skip_special_symbols(cfg, off + 4);
618
    } else if (cfg[off] == 'f' && cfg[off + 1] == 'a' && cfg[off + 2] == 'l'
619
                && cfg[off + 3] == 's' && cfg[off + 4] == 'e') {
620
        out->make_boolean(false);
621
        off = skip_special_symbols(cfg, off + 5);
622
    } else if (cfg[off] == 't' && cfg[off + 1] == 'r' && cfg[off + 2] == 'u'
623
            && cfg[off + 3] == 'e') {
624
        out->make_boolean(true);
625
        off = skip_special_symbols(cfg, off + 4);
626 2 sergeykhbr
    } else {
627 3 sergeykhbr
        char digits[64] = {0};
628
        int digits_cnt = 0;
629
        bool negative = false;
630
        if (cfg[off] == '0' && cfg[off + 1] == 'x') {
631
            off += 2;
632
            digits[digits_cnt++] = '0';
633
            digits[digits_cnt++] = 'x';
634
        } else if (cfg[off] == '-') {
635
            negative = true;
636
            off++;
637
        }
638
        while (digits_cnt < 63 && ((cfg[off] >= '0' && cfg[off] <= '9')
639
            || (cfg[off] >= 'a' && cfg[off] <= 'f')
640
            || (cfg[off] >= 'A' && cfg[off] <= 'F'))) {
641
            digits[digits_cnt++] = cfg[off++];
642
            digits[digits_cnt] = 0;
643
        }
644
        int64_t t1 = strtoull(digits, NULL, 0);
645
        if (cfg[off] == '.') {
646
            digits_cnt = 0;
647
            digits[0] = 0;
648
            double divrate = 1.0;
649
            double d1 = static_cast<double>(t1);
650
            off++;
651
            while (digits_cnt < 63 && cfg[off] >= '0' && cfg[off] <= '9') {
652
                digits[digits_cnt++] = cfg[off++];
653 2 sergeykhbr
                digits[digits_cnt] = 0;
654 3 sergeykhbr
                divrate *= 10.0;
655 2 sergeykhbr
            }
656 3 sergeykhbr
            t1 = strtoull(digits, NULL, 0);
657
            d1 += static_cast<double>(t1)/divrate;
658
            if (negative) {
659
                d1 = -d1;
660 2 sergeykhbr
            }
661 3 sergeykhbr
            out->make_floating(d1);
662
        } else {
663
            if (negative) {
664
                t1 = -t1;
665 2 sergeykhbr
            }
666 3 sergeykhbr
            out->make_int64(t1);
667 2 sergeykhbr
        }
668 3 sergeykhbr
        off = skip_special_symbols(cfg, off);
669 2 sergeykhbr
    }
670 3 sergeykhbr
    /** Guard to skip wrong formatted string and avoid hanging: */
671
    if (off == checkstart) {
672
        RISCV_printf(NULL, LOG_ERROR,
673
                    "JSON parser error: Can't detect format");
674
        out->attr_free();
675
        return -1;
676
    }
677
    return 0;
678 2 sergeykhbr
}
679
 
680
}  // namespace debugger

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.