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

Subversion Repositories eco32

[/] [eco32/] [trunk/] [hwtests/] [kbdtest/] [lib.c] - Blame information for rev 42

Go to most recent revision | 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
 
331
 
332
/*
333
 * Count the number of characters needed to represent
334
 * a given number in base 10.
335
 */
336
static int countPrintn(long n) {
337
  long a;
338
  int res;
339
 
340
  res = 0;
341
  if (n < 0) {
342
    res++;
343
    n = -n;
344
  }
345
  a = n / 10;
346
  if (a != 0) {
347
    res += countPrintn(a);
348
  }
349
  return res + 1;
350
}
351
 
352
 
353
/*
354
 * Output a number in base 10.
355
 */
356
static void *printn(void *(*emit)(void *, char), void *arg,
357
                    int *nchar, long n) {
358
  long a;
359
 
360
  if (n < 0) {
361
    arg = emit(arg, '-');
362
    (*nchar)++;
363
    n = -n;
364
  }
365
  a = n / 10;
366
  if (a != 0) {
367
    arg = printn(emit, arg, nchar, a);
368
  }
369
  arg = emit(arg, n % 10 + '0');
370
  (*nchar)++;
371
  return arg;
372
}
373
 
374
 
375
/*
376
 * Count the number of characters needed to represent
377
 * a given number in a given base.
378
 */
379
static int countPrintu(unsigned long n, unsigned long b) {
380
  unsigned long a;
381
  int res;
382
 
383
  res = 0;
384
  a = n / b;
385
  if (a != 0) {
386
    res += countPrintu(a, b);
387
  }
388
  return res + 1;
389
}
390
 
391
 
392
/*
393
 * Output a number in a given base.
394
 */
395
static void *printu(void *(*emit)(void *, char), void *arg,
396
                    int *nchar, unsigned long n, unsigned long b,
397
                    Bool upperCase) {
398
  unsigned long a;
399
 
400
  a = n / b;
401
  if (a != 0) {
402
    arg = printu(emit, arg, nchar, a, b, upperCase);
403
  }
404
  if (upperCase) {
405
    arg = emit(arg, "0123456789ABCDEF"[n % b]);
406
    (*nchar)++;
407
  } else {
408
    arg = emit(arg, "0123456789abcdef"[n % b]);
409
    (*nchar)++;
410
  }
411
  return arg;
412
}
413
 
414
 
415
/*
416
 * Output a number of filler characters.
417
 */
418
static void *fill(void *(*emit)(void *, char), void *arg,
419
                  int *nchar, int numFillers, char filler) {
420
  while (numFillers-- > 0) {
421
    arg = emit(arg, filler);
422
    (*nchar)++;
423
  }
424
  return arg;
425
}
426
 
427
 
428
/*
429
 * This function does the real work of formatted printing.
430
 */
431
static int doPrintf(void *(*emit)(void *, char), void *arg,
432
                    const char *fmt, va_list ap) {
433
  int nchar;
434
  char c;
435
  int n;
436
  long ln;
437
  unsigned int u;
438
  unsigned long lu;
439
  char *s;
440
  Bool negFlag;
441
  char filler;
442
  int width, count;
443
 
444
  nchar = 0;
445
  while (1) {
446
    while ((c = *fmt++) != '%') {
447
      if (c == '\0') {
448
        return nchar;
449
      }
450
      arg = emit(arg, c);
451
      nchar++;
452
    }
453
    c = *fmt++;
454
    if (c == '-') {
455
      negFlag = true;
456
      c = *fmt++;
457
    } else {
458
      negFlag = false;
459
    }
460
    if (c == '0') {
461
      filler = '0';
462
      c = *fmt++;
463
    } else {
464
      filler = ' ';
465
    }
466
    width = 0;
467
    while (c >= '0' && c <= '9') {
468
      width *= 10;
469
      width += c - '0';
470
      c = *fmt++;
471
    }
472
    if (c == 'd') {
473
      n = va_arg(ap, int);
474
      count = countPrintn(n);
475
      if (width > 0 && !negFlag) {
476
        arg = fill(emit, arg, &nchar, width - count, filler);
477
      }
478
      arg = printn(emit, arg, &nchar, n);
479
      if (width > 0 && negFlag) {
480
        arg = fill(emit, arg, &nchar, width - count, filler);
481
      }
482
    } else
483
    if (c == 'u' || c == 'o' || c == 'x' || c == 'X') {
484
      u = va_arg(ap, int);
485
      count = countPrintu(u,
486
                c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10));
487
      if (width > 0 && !negFlag) {
488
        arg = fill(emit, arg, &nchar, width - count, filler);
489
      }
490
      arg = printu(emit, arg, &nchar, u,
491
                   c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10),
492
                   c == 'X');
493
      if (width > 0 && negFlag) {
494
        arg = fill(emit, arg, &nchar, width - count, filler);
495
      }
496
    } else
497
    if (c == 'l') {
498
      c = *fmt++;
499
      if (c == 'd') {
500
        ln = va_arg(ap, long);
501
        count = countPrintn(ln);
502
        if (width > 0 && !negFlag) {
503
          arg = fill(emit, arg, &nchar, width - count, filler);
504
        }
505
        arg = printn(emit, arg, &nchar, ln);
506
        if (width > 0 && negFlag) {
507
          arg = fill(emit, arg, &nchar, width - count, filler);
508
        }
509
      } else
510
      if (c == 'u' || c == 'o' || c == 'x' || c == 'X') {
511
        lu = va_arg(ap, long);
512
        count = countPrintu(lu,
513
                  c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10));
514
        if (width > 0 && !negFlag) {
515
          arg = fill(emit, arg, &nchar, width - count, filler);
516
        }
517
        arg = printu(emit, arg, &nchar, lu,
518
                     c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10),
519
                     c == 'X');
520
        if (width > 0 && negFlag) {
521
          arg = fill(emit, arg, &nchar, width - count, filler);
522
        }
523
      } else {
524
        arg = emit(arg, 'l');
525
        nchar++;
526
        arg = emit(arg, c);
527
        nchar++;
528
      }
529
    } else
530
    if (c == 's') {
531
      s = va_arg(ap, char *);
532
      count = strlen(s);
533
      if (width > 0 && !negFlag) {
534
        arg = fill(emit, arg, &nchar, width - count, filler);
535
      }
536
      while ((c = *s++) != '\0') {
537
        arg = emit(arg, c);
538
        nchar++;
539
      }
540
      if (width > 0 && negFlag) {
541
        arg = fill(emit, arg, &nchar, width - count, filler);
542
      }
543
    } else
544
    if (c == 'c') {
545
      c = va_arg(ap, char);
546
      arg = emit(arg, c);
547
      nchar++;
548
    } else {
549
      arg = emit(arg, c);
550
      nchar++;
551
    }
552
  }
553
  /* never reached */
554
  return 0;
555
}
556
 
557
 
558
/*
559
 * Emit a character to the console.
560
 */
561
static void *emitToConsole(void *dummy, char c) {
562
  putchar(c);
563
  return dummy;
564
}
565
 
566
 
567
/*
568
 * Formatted output with a variable argument list.
569
 */
570
static int vprintf(const char *fmt, va_list ap) {
571
  int n;
572
 
573
  n = doPrintf(emitToConsole, NULL, fmt, ap);
574
  return n;
575
}
576
 
577
 
578
/*
579
 * Formatted output.
580
 */
581
int printf(const char *fmt, ...) {
582
  int n;
583
  va_list ap;
584
 
585
  va_start(ap, fmt);
586
  n = vprintf(fmt, ap);
587
  va_end(ap);
588
  return n;
589
}
590
 
591
 
592
/*
593
 * Emit a character to a buffer.
594
 */
595
static void *emitToBuffer(void *bufptr, char c) {
596
  *(char *)bufptr = c;
597
  return (char *) bufptr + 1;
598
}
599
 
600
 
601
/*
602
 * Formatted output into a buffer with a variable argument list.
603
 */
604
static int vsprintf(char *s, const char *fmt, va_list ap) {
605
  int n;
606
 
607
  n = doPrintf(emitToBuffer, s, fmt, ap);
608
  s[n] = '\0';
609
  return n;
610
}
611
 
612
 
613
/*
614
 * Formatted output into a buffer.
615
 */
616
int sprintf(char *s, const char *fmt, ...) {
617
  int n;
618
  va_list ap;
619
 
620
  va_start(ap, fmt);
621
  n = vsprintf(s, fmt, ap);
622
  va_end(ap);
623
  return n;
624
}

powered by: WebSVN 2.1.0

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