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 4

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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