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

Subversion Repositories eco32

[/] [eco32/] [trunk/] [hwtests/] [xcptest/] [lib.c] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 hellwig
/*
2
 * lib.c -- the library
3
 */
4
 
5
 
6
#include "common.h"
7
#include "lib.h"
8
#include "stdarg.h"
9
#include "start.h"
10
 
11
 
12
/**************************************************************/
13
 
14
 
15
/*
16
 * This is only for debugging.
17
 * Place a breakpoint at the very beginning of this routine
18
 * and call it wherever you want to break execution.
19
 */
20
void debugBreak(void) {
21
}
22
 
23
 
24
/**************************************************************/
25
 
26
 
27
/*
28
 * Count the length of a string (without terminating null character).
29
 */
30
int strlen(const char *s) {
31
  const char *p;
32
 
33
  p = s;
34
  while (*p != '\0') {
35
    p++;
36
  }
37
  return p - s;
38
}
39
 
40
 
41
/*
42
 * Compare two strings.
43
 * Return a number < 0, = 0, or > 0 iff the first string is less
44
 * than, equal to, or greater than the second one, respectively.
45
 */
46
int strcmp(const char *s, const char *t) {
47
  while (*s == *t) {
48
    if (*s == '\0') {
49
      return 0;
50
    }
51
    s++;
52
    t++;
53
  }
54
  return *s - *t;
55
}
56
 
57
 
58
/*
59
 * Copy string t to string s (includes terminating null character).
60
 */
61
char *strcpy(char *s, const char *t) {
62
  char *p;
63
 
64
  p = s;
65
  while ((*p = *t) != '\0') {
66
    p++;
67
    t++;
68
  }
69
  return s;
70
}
71
 
72
 
73
/*
74
 * Append string t to string s.
75
 */
76
char *strcat(char *s, const char *t) {
77
  char *p;
78
 
79
  p = s;
80
  while (*p != '\0') {
81
    p++;
82
  }
83
  while ((*p = *t) != '\0') {
84
    p++;
85
    t++;
86
  }
87
  return s;
88
}
89
 
90
 
91
/*
92
 * Locate character c in string s.
93
 */
94
char *strchr(const char *s, char c) {
95
  while (*s != c) {
96
    if (*s == '\0') {
97
      return NULL;
98
    }
99
    s++;
100
  }
101
  return (char *) s;
102
}
103
 
104
 
105
/*
106
 * Extract the next token from the string s, delimited
107
 * by any character from the delimiter string t.
108
 */
109
char *strtok(char *s, const char *t) {
110
  static char *p;
111
  char *q;
112
 
113
  if (s != NULL) {
114
    p = s;
115
  } else {
116
    p++;
117
  }
118
  while (*p != '\0' && strchr(t, *p) != NULL) {
119
    p++;
120
  }
121
  if (*p == '\0') {
122
    return NULL;
123
  }
124
  q = p++;
125
  while (*p != '\0' && strchr(t, *p) == NULL) {
126
    p++;
127
  }
128
  if (*p != '\0') {
129
    *p = '\0';
130
  } else {
131
    p--;
132
  }
133
  return q;
134
}
135
 
136
 
137
/**************************************************************/
138
 
139
 
140
/*
141
 * Determine if a character is 'white space'.
142
 */
143
static Bool isspace(char c) {
144
  Bool res;
145
 
146
  switch (c) {
147
    case ' ':
148
    case '\f':
149
    case '\n':
150
    case '\r':
151
    case '\t':
152
    case '\v':
153
      res = true;
154
      break;
155
    default:
156
      res = false;
157
      break;
158
  }
159
  return res;
160
}
161
 
162
 
163
/*
164
 * Check for valid digit, and convert to value.
165
 */
166
static Bool checkDigit(char c, int base, int *value) {
167
  if (c >= '0' && c <= '9') {
168
    *value = c - '0';
169
  } else
170
  if (c >= 'A' && c <= 'Z') {
171
    *value = c - 'A' + 10;
172
  } else
173
  if (c >= 'a' && c <= 'z') {
174
    *value = c - 'a' + 10;
175
  } else {
176
    return false;
177
  }
178
  return *value < base;
179
}
180
 
181
 
182
/*
183
 * Convert initial part of string to unsigned long integer.
184
 */
185
unsigned long strtoul(const char *s, char **endp, int base) {
186
  unsigned long res;
187
  int sign;
188
  int digit;
189
 
190
  res = 0;
191
  while (isspace(*s)) {
192
    s++;
193
  }
194
  if (*s == '+') {
195
    sign = 1;
196
    s++;
197
  } else
198
  if (*s == '-') {
199
    sign = -1;
200
    s++;
201
  } else {
202
    sign = 1;
203
  }
204
  if (base == 0 || base == 16) {
205
    if (*s == '0' &&
206
        (*(s + 1) == 'x' || *(s + 1) == 'X')) {
207
      /* base is 16 */
208
      s += 2;
209
      base = 16;
210
    } else {
211
      /* base is 0 or 16, but number does not start with "0x" */
212
      if (base == 0) {
213
        if (*s == '0') {
214
          s++;
215
          base = 8;
216
        } else {
217
          base = 10;
218
        }
219
      } else {
220
        /* take base as is */
221
      }
222
    }
223
  } else {
224
    /* take base as is */
225
  }
226
  while (checkDigit(*s, base, &digit)) {
227
    res *= base;
228
    res += digit;
229
    s++;
230
  }
231
  if (endp != NULL) {
232
    *endp = (char *) s;
233
  }
234
  return sign * res;
235
}
236
 
237
 
238
/**************************************************************/
239
 
240
 
241
/*
242
 * Exchange two array items of a given size.
243
 */
244
static void xchg(char *p, char *q, int size) {
245
  char t;
246
 
247
  while (size--) {
248
    t = *p;
249
    *p++ = *q;
250
    *q++ = t;
251
  }
252
}
253
 
254
 
255
/*
256
 * This is a recursive version of quicksort.
257
 */
258
static void sort(char *l, char *r, int size,
259
                 int (*cmp)(const void *, const void *)) {
260
  char *i;
261
  char *j;
262
  char *x;
263
 
264
  i = l;
265
  j = r;
266
  x = l + (((r - l) / size) / 2) * size;
267
  do {
268
    while (cmp(i, x) < 0) {
269
      i += size;
270
    }
271
    while (cmp(x, j) < 0) {
272
      j -= size;
273
    }
274
    if (i <= j) {
275
      /* exchange array elements i and j */
276
      /* attention: update x if it is one of these */
277
      if (x == i) {
278
        x = j;
279
      } else
280
      if (x == j) {
281
        x = i;
282
      }
283
      xchg(i, j, size);
284
      i += size;
285
      j -= size;
286
    }
287
  } while (i <= j);
288
  if (l < j) {
289
    sort(l, j, size, cmp);
290
  }
291
  if (i < r) {
292
    sort(i, r, size, cmp);
293
  }
294
}
295
 
296
 
297
/*
298
 * External interface for the quicksort algorithm.
299
 */
300
void qsort(void *base, int n, int size,
301
           int (*cmp)(const void *, const void*)) {
302
  sort((char *) base, (char *) base + (n - 1) * size, size, cmp);
303
}
304
 
305
 
306
/**************************************************************/
307
 
308
 
309
/*
310
 * Input a character from the console.
311
 */
312
char getchar(void) {
313
  return cin();
314
}
315
 
316
 
317
/*
318
 * Output a character on the console.
319
 * Replace LF by CR/LF.
320
 */
321
void putchar(char c) {
322
  if (c == '\n') {
323
    cout('\r');
324
  }
325
  cout(c);
326
}
327
 
328
 
329
/*
330
 * Output a string on the console.
331
 * Replace LF by CR/LF.
332
 */
333
void puts(const char *s) {
334
  while (*s != '\0') {
335
    putchar(*s);
336
    s++;
337
  }
338
}
339
 
340
 
341
/**************************************************************/
342
 
343
 
344
/*
345
 * Count the number of characters needed to represent
346
 * a given number in base 10.
347
 */
348
static int countPrintn(long n) {
349
  long a;
350
  int res;
351
 
352
  res = 0;
353
  if (n < 0) {
354
    res++;
355
    n = -n;
356
  }
357
  a = n / 10;
358
  if (a != 0) {
359
    res += countPrintn(a);
360
  }
361
  return res + 1;
362
}
363
 
364
 
365
/*
366
 * Output a number in base 10.
367
 */
368
static void *printn(void *(*emit)(void *, char), void *arg,
369
                    int *nchar, long n) {
370
  long a;
371
 
372
  if (n < 0) {
373
    arg = emit(arg, '-');
374
    (*nchar)++;
375
    n = -n;
376
  }
377
  a = n / 10;
378
  if (a != 0) {
379
    arg = printn(emit, arg, nchar, a);
380
  }
381
  arg = emit(arg, n % 10 + '0');
382
  (*nchar)++;
383
  return arg;
384
}
385
 
386
 
387
/*
388
 * Count the number of characters needed to represent
389
 * a given number in a given base.
390
 */
391
static int countPrintu(unsigned long n, unsigned long b) {
392
  unsigned long a;
393
  int res;
394
 
395
  res = 0;
396
  a = n / b;
397
  if (a != 0) {
398
    res += countPrintu(a, b);
399
  }
400
  return res + 1;
401
}
402
 
403
 
404
/*
405
 * Output a number in a given base.
406
 */
407
static void *printu(void *(*emit)(void *, char), void *arg,
408
                    int *nchar, unsigned long n, unsigned long b,
409
                    Bool upperCase) {
410
  unsigned long a;
411
 
412
  a = n / b;
413
  if (a != 0) {
414
    arg = printu(emit, arg, nchar, a, b, upperCase);
415
  }
416
  if (upperCase) {
417
    arg = emit(arg, "0123456789ABCDEF"[n % b]);
418
    (*nchar)++;
419
  } else {
420
    arg = emit(arg, "0123456789abcdef"[n % b]);
421
    (*nchar)++;
422
  }
423
  return arg;
424
}
425
 
426
 
427
/*
428
 * Output a number of filler characters.
429
 */
430
static void *fill(void *(*emit)(void *, char), void *arg,
431
                  int *nchar, int numFillers, char filler) {
432
  while (numFillers-- > 0) {
433
    arg = emit(arg, filler);
434
    (*nchar)++;
435
  }
436
  return arg;
437
}
438
 
439
 
440
/*
441
 * This function does the real work of formatted printing.
442
 */
443
static int doPrintf(void *(*emit)(void *, char), void *arg,
444
                    const char *fmt, va_list ap) {
445
  int nchar;
446
  char c;
447
  int n;
448
  long ln;
449
  unsigned int u;
450
  unsigned long lu;
451
  char *s;
452
  Bool negFlag;
453
  char filler;
454
  int width, count;
455
 
456
  nchar = 0;
457
  while (1) {
458
    while ((c = *fmt++) != '%') {
459
      if (c == '\0') {
460
        return nchar;
461
      }
462
      arg = emit(arg, c);
463
      nchar++;
464
    }
465
    c = *fmt++;
466
    if (c == '-') {
467
      negFlag = true;
468
      c = *fmt++;
469
    } else {
470
      negFlag = false;
471
    }
472
    if (c == '0') {
473
      filler = '0';
474
      c = *fmt++;
475
    } else {
476
      filler = ' ';
477
    }
478
    width = 0;
479
    while (c >= '0' && c <= '9') {
480
      width *= 10;
481
      width += c - '0';
482
      c = *fmt++;
483
    }
484
    if (c == 'd') {
485
      n = va_arg(ap, int);
486
      count = countPrintn(n);
487
      if (width > 0 && !negFlag) {
488
        arg = fill(emit, arg, &nchar, width - count, filler);
489
      }
490
      arg = printn(emit, arg, &nchar, n);
491
      if (width > 0 && negFlag) {
492
        arg = fill(emit, arg, &nchar, width - count, filler);
493
      }
494
    } else
495
    if (c == 'u' || c == 'o' || c == 'x' || c == 'X') {
496
      u = va_arg(ap, int);
497
      count = countPrintu(u,
498
                c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10));
499
      if (width > 0 && !negFlag) {
500
        arg = fill(emit, arg, &nchar, width - count, filler);
501
      }
502
      arg = printu(emit, arg, &nchar, u,
503
                   c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10),
504
                   c == 'X');
505
      if (width > 0 && negFlag) {
506
        arg = fill(emit, arg, &nchar, width - count, filler);
507
      }
508
    } else
509
    if (c == 'l') {
510
      c = *fmt++;
511
      if (c == 'd') {
512
        ln = va_arg(ap, long);
513
        count = countPrintn(ln);
514
        if (width > 0 && !negFlag) {
515
          arg = fill(emit, arg, &nchar, width - count, filler);
516
        }
517
        arg = printn(emit, arg, &nchar, ln);
518
        if (width > 0 && negFlag) {
519
          arg = fill(emit, arg, &nchar, width - count, filler);
520
        }
521
      } else
522
      if (c == 'u' || c == 'o' || c == 'x' || c == 'X') {
523
        lu = va_arg(ap, long);
524
        count = countPrintu(lu,
525
                  c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10));
526
        if (width > 0 && !negFlag) {
527
          arg = fill(emit, arg, &nchar, width - count, filler);
528
        }
529
        arg = printu(emit, arg, &nchar, lu,
530
                     c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10),
531
                     c == 'X');
532
        if (width > 0 && negFlag) {
533
          arg = fill(emit, arg, &nchar, width - count, filler);
534
        }
535
      } else {
536
        arg = emit(arg, 'l');
537
        nchar++;
538
        arg = emit(arg, c);
539
        nchar++;
540
      }
541
    } else
542
    if (c == 's') {
543
      s = va_arg(ap, char *);
544
      count = strlen(s);
545
      if (width > 0 && !negFlag) {
546
        arg = fill(emit, arg, &nchar, width - count, filler);
547
      }
548
      while ((c = *s++) != '\0') {
549
        arg = emit(arg, c);
550
        nchar++;
551
      }
552
      if (width > 0 && negFlag) {
553
        arg = fill(emit, arg, &nchar, width - count, filler);
554
      }
555
    } else
556
    if (c == 'c') {
557
      c = va_arg(ap, char);
558
      arg = emit(arg, c);
559
      nchar++;
560
    } else {
561
      arg = emit(arg, c);
562
      nchar++;
563
    }
564
  }
565
  /* never reached */
566
  return 0;
567
}
568
 
569
 
570
/*
571
 * Emit a character to the console.
572
 */
573
static void *emitToConsole(void *dummy, char c) {
574
  putchar(c);
575
  return dummy;
576
}
577
 
578
 
579
/*
580
 * Formatted output with a variable argument list.
581
 */
582
static int vprintf(const char *fmt, va_list ap) {
583
  int n;
584
 
585
  n = doPrintf(emitToConsole, NULL, fmt, ap);
586
  return n;
587
}
588
 
589
 
590
/*
591
 * Formatted output.
592
 */
593
int printf(const char *fmt, ...) {
594
  int n;
595
  va_list ap;
596
 
597
  va_start(ap, fmt);
598
  n = vprintf(fmt, ap);
599
  va_end(ap);
600
  return n;
601
}
602
 
603
 
604
/*
605
 * Emit a character to a buffer.
606
 */
607
static void *emitToBuffer(void *bufptr, char c) {
608
  *(char *)bufptr = c;
609
  return (char *) bufptr + 1;
610
}
611
 
612
 
613
/*
614
 * Formatted output into a buffer with a variable argument list.
615
 */
616
static int vsprintf(char *s, const char *fmt, va_list ap) {
617
  int n;
618
 
619
  n = doPrintf(emitToBuffer, s, fmt, ap);
620
  s[n] = '\0';
621
  return n;
622
}
623
 
624
 
625
/*
626
 * Formatted output into a buffer.
627
 */
628
int sprintf(char *s, const char *fmt, ...) {
629
  int n;
630
  va_list ap;
631
 
632
  va_start(ap, fmt);
633
  n = vsprintf(s, fmt, ap);
634
  va_end(ap);
635
  return n;
636
}

powered by: WebSVN 2.1.0

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