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

Subversion Repositories plasma

[/] [plasma/] [trunk/] [kernel/] [libc.c] - Blame information for rev 302

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

Line No. Rev Author Line
1 138 rhoads
/*--------------------------------------------------------------------
2
 * TITLE: ANSI C Library
3
 * AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
4
 * DATE CREATED: 12/17/05
5 171 rhoads
 * FILENAME: libc.c
6 138 rhoads
 * PROJECT: Plasma CPU core
7
 * COPYRIGHT: Software placed into the public domain by the author.
8
 *    Software 'as is' without warranty.  Author liable for nothing.
9
 * DESCRIPTION:
10
 *    Subset of the ANSI C library
11
 *--------------------------------------------------------------------*/
12
#define NO_ELLIPSIS
13
#include "rtos.h"
14
 
15
 
16
char *strcpy(char *dst, const char *src)
17
{
18 258 rhoads
   char *dstSave=dst;
19 138 rhoads
   int c;
20
   do
21
   {
22
      c = *dst++ = *src++;
23
   } while(c);
24 258 rhoads
   return dstSave;
25 138 rhoads
}
26
 
27
 
28
char *strncpy(char *dst, const char *src, int count)
29
{
30
   int c=1;
31 258 rhoads
   char *dstSave=dst;
32 138 rhoads
   while(count-- > 0 && c)
33
      c = *dst++ = *src++;
34
   *dst = 0;
35 258 rhoads
   return dstSave;
36 138 rhoads
}
37
 
38
 
39
char *strcat(char *dst, const char *src)
40
{
41
   int c;
42 258 rhoads
   char *dstSave=dst;
43 138 rhoads
   while(*dst)
44
      ++dst;
45
   do
46
   {
47
      c = *dst++ = *src++;
48
   } while(c);
49 258 rhoads
   return dstSave;
50 138 rhoads
}
51
 
52
 
53
char *strncat(char *dst, const char *src, int count)
54
{
55
   int c=1;
56 258 rhoads
   char *dstSave=dst;
57 138 rhoads
   while(*dst && --count > 0)
58
      ++dst;
59
   while(--count > 0 && c)
60
      c = *dst++ = *src++;
61
   *dst = 0;
62 258 rhoads
   return dstSave;
63 138 rhoads
}
64
 
65
 
66
int strcmp(const char *string1, const char *string2)
67
{
68
   int diff, c;
69
   for(;;)
70
   {
71
      diff = *string1++ - (c = *string2++);
72
      if(diff)
73
         return diff;
74
      if(c == 0)
75
         return 0;
76
   }
77
}
78
 
79
 
80
int strncmp(const char *string1, const char *string2, int count)
81
{
82
   int diff, c;
83
   while(count-- > 0)
84
   {
85
      diff = *string1++ - (c = *string2++);
86
      if(diff)
87
         return diff;
88
      if(c == 0)
89
         return 0;
90
   }
91
   return 0;
92
}
93
 
94
 
95 149 rhoads
char *strstr(const char *string, const char *find)
96 138 rhoads
{
97
   int i;
98
   for(;;)
99
   {
100
      for(i = 0; string[i] == find[i] && find[i]; ++i) ;
101
      if(find[i] == 0)
102 149 rhoads
         return (char*)string;
103 138 rhoads
      if(*string++ == 0)
104
         return NULL;
105
   }
106
}
107
 
108
 
109
int strlen(const char *string)
110
{
111
   const char *base=string;
112
   while(*string++) ;
113
   return string - base - 1;
114
}
115
 
116
 
117
void *memcpy(void *dst, const void *src, unsigned long bytes)
118
{
119 249 rhoads
   if(((uint32)dst | (uint32)src | bytes) & 3)
120
   {
121
      uint8 *Dst = (uint8*)dst, *Src = (uint8*)src;
122
      while((int)bytes-- > 0)
123
         *Dst++ = *Src++;
124
   }
125
   else
126
   {
127
      uint32 *Dst32 = (uint32*)dst, *Src32 = (uint32*)src;
128
      bytes >>= 2;
129
      while((int)bytes-- > 0)
130
         *Dst32++ = *Src32++;
131
   }
132 138 rhoads
   return dst;
133
}
134
 
135
 
136 144 rhoads
void *memmove(void *dst, const void *src, unsigned long bytes)
137
{
138
   uint8 *Dst = (uint8*)dst;
139
   uint8 *Src = (uint8*)src;
140
   if(Dst < Src)
141
   {
142
      while((int)bytes-- > 0)
143
         *Dst++ = *Src++;
144
   }
145
   else
146
   {
147
      Dst += bytes;
148
      Src += bytes;
149
      while((int)bytes-- > 0)
150
         *--Dst = *--Src;
151
   }
152
   return dst;
153
}
154
 
155
 
156 138 rhoads
int memcmp(const void *cs, const void *ct, unsigned long bytes)
157
{
158
   uint8 *Dst = (uint8*)cs;
159
   uint8 *Src = (uint8*)ct;
160
   int diff;
161
   while((int)bytes-- > 0)
162
   {
163
      diff = *Dst++ - *Src++;
164
      if(diff)
165
         return diff;
166
   }
167
   return 0;
168
}
169
 
170
 
171
void *memset(void *dst, int c, unsigned long bytes)
172
{
173
   uint8 *Dst = (uint8*)dst;
174
   while((int)bytes-- > 0)
175
      *Dst++ = (uint8)c;
176
   return dst;
177
}
178
 
179
 
180
int abs(int n)
181
{
182
   return n>=0 ? n : -n;
183
}
184
 
185
 
186
static uint32 Rand1=0x1f2bcda3, Rand2=0xdeafbeef, Rand3=0xc5134306;
187 149 rhoads
int rand(void)
188 138 rhoads
{
189
   int shift;
190
   Rand1 += 0x13423123 + Rand2;
191
   Rand2 += 0x2312fdea + Rand3;
192
   Rand3 += 0xf2a12de1;
193
   shift = Rand3 & 31;
194
   Rand1 = (Rand1 << (32 - shift)) | (Rand1 >> shift);
195
   Rand3 ^= Rand1;
196
   shift = (Rand3 >> 8) & 31;
197
   Rand2 = (Rand2 << (32 - shift)) | (Rand2 >> shift);
198
   return Rand1;
199
}
200
 
201
 
202
void srand(unsigned int seed)
203
{
204
   Rand1 = seed;
205
}
206
 
207
 
208 302 rhoads
long strtol(const char *s, char **end, int base)
209 138 rhoads
{
210
   int i;
211
   unsigned long ch, value=0, neg=0;
212
 
213
   if(s[0] == '-')
214
   {
215
      neg = 1;
216
      ++s;
217
   }
218
   if(s[0] == '0' && s[1] == 'x')
219
   {
220
      base = 16;
221
      s += 2;
222
   }
223
   for(i = 0; i <= 8; ++i)
224
   {
225
      ch = *s++;
226
      if('0' <= ch && ch <= '9')
227
         ch -= '0';
228
      else if('A' <= ch && ch <= 'Z')
229
         ch = ch - 'A' + 10;
230
      else if('a' <= ch && ch <= 'z')
231
         ch = ch - 'a' + 10;
232
      else
233
         break;
234
      value = value * base + ch;
235
   }
236
   if(end)
237 302 rhoads
      *end = (char*)s - 1;
238 138 rhoads
   if(neg)
239
      value = -(int)value;
240
   return value;
241
}
242
 
243
 
244
int atoi(const char *s)
245
{
246
   return strtol(s, NULL, 10);
247
}
248
 
249
 
250 149 rhoads
char *itoa(int num, char *dst, int base)
251 138 rhoads
{
252 149 rhoads
   int digit, negate=0, place;
253
   char c, text[20];
254 138 rhoads
 
255
   if(base == 10 && num < 0)
256
   {
257
      num = -num;
258
      negate = 1;
259
   }
260 149 rhoads
   text[16] = 0;
261
   for(place = 15; place >= 0; --place)
262 138 rhoads
   {
263 187 rhoads
      digit = (unsigned int)num % (unsigned int)base;
264 149 rhoads
      if(num == 0 && place < 15 && base == 10 && negate)
265 138 rhoads
      {
266 149 rhoads
         c = '-';
267 138 rhoads
         negate = 0;
268
      }
269
      else if(digit < 10)
270
         c = (char)('0' + digit);
271
      else
272
         c = (char)('a' + digit - 10);
273 149 rhoads
      text[place] = c;
274
      num = (unsigned int)num / (unsigned int)base;
275
      if(num == 0 && negate == 0)
276
         break;
277 138 rhoads
   }
278 149 rhoads
   strcpy(dst, text + place);
279
   return dst;
280 138 rhoads
}
281
 
282
 
283
int sprintf(char *s, const char *format,
284
            int arg0, int arg1, int arg2, int arg3,
285
            int arg4, int arg5, int arg6, int arg7)
286
{
287
   int argv[8];
288
   int argc=0, width, length;
289 187 rhoads
   char f, text[20], fill;
290 138 rhoads
 
291
   argv[0] = arg0; argv[1] = arg1; argv[2] = arg2; argv[3] = arg3;
292
   argv[4] = arg4; argv[5] = arg5; argv[6] = arg6; argv[7] = arg7;
293
 
294
   for(;;)
295
   {
296
      f = *format++;
297
      if(f == 0)
298
         return argc;
299
      else if(f == '%')
300
      {
301
         width = 0;
302 187 rhoads
         fill = ' ';
303 138 rhoads
         f = *format++;
304 187 rhoads
         while('0' <= f && f <= '9')
305 138 rhoads
         {
306 187 rhoads
            width = width * 10 + f - '0';
307 138 rhoads
            f = *format++;
308
         }
309 187 rhoads
         if(f == '.')
310
         {
311
            fill = '0';
312
            f = *format++;
313
         }
314
         if(f == 0)
315
            return argc;
316 138 rhoads
 
317
         if(f == 'd')
318 149 rhoads
         {
319 187 rhoads
            memset(s, fill, width);
320 149 rhoads
            itoa(argv[argc++], text, 10);
321
            length = (int)strlen(text);
322
            if(width < length)
323
               width = length;
324
            strcpy(s + width - length, text);
325
         }
326 138 rhoads
         else if(f == 'x' || f == 'f')
327 149 rhoads
         {
328
            memset(s, '0', width);
329
            itoa(argv[argc++], text, 16);
330
            length = (int)strlen(text);
331
            if(width < length)
332
               width = length;
333
            strcpy(s + width - length, text);
334
         }
335 138 rhoads
         else if(f == 'c')
336
         {
337
            *s++ = (char)argv[argc++];
338
            *s = 0;
339
         }
340
         else if(f == 's')
341
         {
342
            length = strlen((char*)argv[argc]);
343
            if(width > length)
344
            {
345
               memset(s, ' ', width - length);
346
               s += width - length;
347
            }
348
            strcpy(s, (char*)argv[argc++]);
349
         }
350
         s += strlen(s);
351
      }
352
      else if(f == '\\')
353
      {
354
         f = *format++;
355
         if(f == 0)
356
            return argc;
357
         else if(f == 'n')
358
            *s++ = '\n';
359
         else if(f == 'r')
360
            *s++ = '\r';
361
         else if(f == 't')
362
            *s++ = '\t';
363
      }
364
      else
365
      {
366
         *s++ = f;
367
      }
368
      *s = 0;
369
   }
370
}
371
 
372
 
373
int sscanf(const char *s, const char *format,
374
           int arg0, int arg1, int arg2, int arg3,
375
           int arg4, int arg5, int arg6, int arg7)
376
{
377
   int argv[8];
378 187 rhoads
   int argc=0;
379
   char f, *ptr;
380 138 rhoads
 
381
   argv[0] = arg0; argv[1] = arg1; argv[2] = arg2; argv[3] = arg3;
382
   argv[4] = arg4; argv[5] = arg5; argv[6] = arg6; argv[7] = arg7;
383
 
384
   for(;;)
385
   {
386
      if(*s == 0)
387
         return argc;
388
      f = *format++;
389
      if(f == 0)
390
         return argc;
391
      else if(f == '%')
392
      {
393
         while(isspace(*s))
394
            ++s;
395
         f = *format++;
396
         if(f == 0)
397
            return argc;
398
         if(f == 'd')
399 302 rhoads
            *(int*)argv[argc++] = strtol(s, (char**)&s, 10);
400 138 rhoads
         else if(f == 'x')
401 302 rhoads
            *(int*)argv[argc++] = strtol(s, (char**)&s, 16);
402 138 rhoads
         else if(f == 'c')
403
            *(char*)argv[argc++] = *s++;
404
         else if(f == 's')
405
         {
406 207 rhoads
            ptr = (char*)argv[argc++];
407 187 rhoads
            while(!isspace(*s))
408
               *ptr++ = *s++;
409
            *ptr = 0;
410 138 rhoads
         }
411
      }
412
      else
413
      {
414
         if(f == '\\')
415
         {
416
            f = *format++;
417
            if(f == 0)
418
               return argc;
419
            else if(f == 'n')
420
               f = '\n';
421
            else if(f == 'r')
422
               f = '\r';
423
            else if(f == 't')
424
               f = '\t';
425
         }
426
         while(*s && *s != f)
427
            ++s;
428
         if(*s)
429
            ++s;
430
      }
431
   }
432
}
433
 
434 149 rhoads
 
435 171 rhoads
#ifdef INCLUDE_DUMP
436
/*********************** dump ***********************/
437 149 rhoads
void dump(const unsigned char *data, int length)
438
{
439
   int i, index=0, value;
440
   char string[80];
441
   memset(string, 0, sizeof(string));
442
   for(i = 0; i < length; ++i)
443
   {
444
      if((i & 15) == 0)
445
      {
446
         if(strlen(string))
447
            printf("%s\n", string);
448
         printf("%4x ", i);
449
         memset(string, 0, sizeof(string));
450
         index = 0;
451
      }
452
      value = data[i];
453
      printf("%2x ", value);
454
      if(isprint(value))
455
         string[index] = (char)value;
456
      else
457
         string[index] = '.';
458
      ++index;
459
   }
460
   for(; index < 16; ++index)
461
      printf("   ");
462
   printf("%s\n", string);
463
}
464 171 rhoads
#endif //INCLUDE_DUMP
465 149 rhoads
 
466
 
467 171 rhoads
#ifdef INCLUDE_QSORT
468
/*********************** qsort ***********************/
469
static void QsortSwap(char *base, long left, long right, long size)
470
{
471 249 rhoads
   int temp, i;
472
   char *ptrLeft, *ptrRight;
473
   ptrLeft = base + left * size;
474
   ptrRight = base + right * size;
475
   for(i = 0; i < size; ++i)
476
   {
477
      temp = ptrLeft[i];
478
      ptrLeft[i] = ptrRight[i];
479
      ptrRight[i] = (char)temp;
480
   }
481 171 rhoads
}
482 149 rhoads
 
483 171 rhoads
 
484
//Modified from K&R
485
static void qsort2(void *base, long left, long right, long size,
486
      int (*cmp)(const void *,const void *))
487
{
488
   int i, last;
489 187 rhoads
   char *base2=(char*)base, *pivot;
490 171 rhoads
   if(left >= right)
491
      return;
492
   QsortSwap(base2, left, (left + right)/2, size);
493
   last = left;
494 187 rhoads
   pivot = &base2[left*size];
495 171 rhoads
   for(i = left + 1; i <= right; ++i)
496
   {
497 187 rhoads
      if(cmp(&base2[i*size], pivot) < 0)
498 171 rhoads
         QsortSwap(base2, ++last, i, size);
499
   }
500
   QsortSwap(base2, left, last, size);
501
   qsort2(base, left, last-1, size, cmp);
502
   qsort2(base, last+1, right, size, cmp);
503
}
504
 
505
 
506
void qsort(void *base,
507
           long n,
508
           long size,
509
           int (*cmp)(const void *,const void *))
510
{
511
   qsort2(base, 0, n-1, size, cmp);
512
}
513
 
514
 
515
void *bsearch(const void *key,
516
              const void *base,
517
              long n,
518
              long size,
519
              int (*cmp)(const void *,const void *))
520
{
521
   long cond, low=0, high=n-1, mid;
522
   char *base2=(char*)base;
523
   while(low <= high)
524
   {
525
      mid = (low + high)/2;
526
      cond = cmp(key, &base2[mid*size]);
527
      if(cond < 0)
528
         high = mid - 1;
529
      else if(cond > 0)
530
         low = mid + 1;
531
      else
532
         return &base2[mid * size];
533
   }
534 187 rhoads
   return NULL;
535 171 rhoads
}
536
#endif //INCLUDE_QSORT
537
 
538
 
539
#ifdef INCLUDE_TIMELIB
540
/************************* time.h ***********************/
541
#define SEC_PER_YEAR (365L*24*60*60)
542
#define SEC_PER_DAY (24L*60*60)
543
//typedef unsigned long time_t;  //start at 1/1/80
544
//struct tm {
545
//   int tm_sec;      //(0,59)
546
//   int tm_min;      //(0,59)
547
//   int tm_hour;     //(0,23)
548
//   int tm_mday;     //(1,31)
549
//   int tm_mon;      //(0,11)
550 187 rhoads
//   int tm_year;     //(0,n) from 1900
551 171 rhoads
//   int tm_wday;     //(0,6)     calculated
552
//   int tm_yday;     //(0,365)   calculated
553 199 rhoads
//   int tm_isdst;    //hour adjusted for day light savings
554 171 rhoads
//};
555
static const unsigned short DaysUntilMonth[]=
556
   {0,31,59,90,120,151,181,212,243,273,304,334,365};
557
static const unsigned short DaysInMonth[]=
558
   {31,28,31,30,31,30,31,31,30,31,30,31};
559 187 rhoads
static time_t DstTimeIn, DstTimeOut;
560 171 rhoads
 
561 199 rhoads
 
562
/* Leap year if divisible by 4.  Centenary years should only be
563
   leap-years if they were divisible by 400. */
564 171 rhoads
static int IsLeapYear(int year)
565
{
566
   return(((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0));
567
}
568
 
569
time_t mktime(struct tm *tp)
570
{
571
   time_t seconds;
572
   unsigned long days, y, year;
573
 
574
   days = tp->tm_mday - 1 + DaysUntilMonth[tp->tm_mon] +
575
      365 * (tp->tm_year - 80);
576
   seconds = (unsigned long)tp->tm_sec + 60L * (tp->tm_min +
577
      60L * (tp->tm_hour + 24L * days));
578 199 rhoads
   if(tp->tm_isdst)
579
      seconds -= 60 * 60;
580 171 rhoads
   year = 1900 + tp->tm_year - (tp->tm_mon < 2);
581
   for(y = 1980; y <= year; y += 4)
582
   {
583
      if(y % 100 != 0 || y % 400 == 0)
584
         seconds += SEC_PER_DAY;
585
   }
586
   return seconds;
587
}
588
 
589 187 rhoads
 
590 171 rhoads
void gmtime_r(const time_t *tp, struct tm *out)
591
{
592 187 rhoads
   time_t seconds, delta, secondsIn=*tp;
593
   int isLeapYear;
594 171 rhoads
   unsigned long year, month;
595
 
596 187 rhoads
   out->tm_isdst = 0;
597
   if(DstTimeIn <= secondsIn && secondsIn < DstTimeOut)
598
   {
599 199 rhoads
      secondsIn += 60 * 60;
600 187 rhoads
      out->tm_isdst = 1;
601
   }
602
   seconds = secondsIn;
603 171 rhoads
   for(year = 0; ; ++year)
604
   {
605
      delta = SEC_PER_YEAR + IsLeapYear(1980 + year) * SEC_PER_DAY;
606
      if(seconds >= delta)
607
         seconds -= delta;
608
      else
609
         break;
610
   }
611 187 rhoads
   out->tm_year = year + 80;
612 171 rhoads
   isLeapYear = IsLeapYear(1980 + year);
613
   for(month = 0; ; ++month)
614
   {
615
      delta = SEC_PER_DAY * (DaysInMonth[month] + (isLeapYear && (month == 1)));
616
      if(seconds >= delta)
617
         seconds -= delta;
618
      else
619
         break;
620
   }
621
   out->tm_mon = month;
622
   out->tm_mday = seconds / SEC_PER_DAY;
623 187 rhoads
   out->tm_yday = DaysUntilMonth[month] + out->tm_mday;
624 171 rhoads
   seconds -= out->tm_mday * SEC_PER_DAY;
625 187 rhoads
   ++out->tm_mday;
626 171 rhoads
   out->tm_hour = seconds / (60 * 60);
627
   seconds -= out->tm_hour * (60 * 60);
628
   out->tm_min = seconds / 60;
629
   seconds -= out->tm_min * 60;
630
   out->tm_sec = seconds;
631 187 rhoads
   seconds = secondsIn % (SEC_PER_DAY * 7);
632
   out->tm_wday = (seconds / SEC_PER_DAY + 2) % 7; /* 1/1/80 is a Tue */
633
   //printf("%4.d/%2.d/%2.d:%2.d:%2.d:%2.d\n", 
634
   //         out->tm_year+1900, out->tm_mon+1, out->tm_mday,
635
   //         out->tm_hour, out->tm_min, out->tm_sec);
636
}
637 171 rhoads
 
638 187 rhoads
 
639
void gmtimeDst(time_t dstTimeIn, time_t dstTimeOut)
640
{
641
   DstTimeIn = dstTimeIn;
642
   DstTimeOut = dstTimeOut;
643 171 rhoads
}
644 199 rhoads
 
645
 
646
//DST from 2am on the second Sunday in March to 2am first Sunday in November
647
void gmtimeDstSet(time_t *tp, time_t *dstTimeIn, time_t *dstTimeOut)
648
{
649
   time_t seconds, timeIn, timeOut;
650
   struct tm tmDate;
651
   int year, days;
652
 
653
   DstTimeIn = 0;
654
   DstTimeOut = 0;
655
   gmtime_r(tp, &tmDate);
656
   year = tmDate.tm_year;
657
 
658
   //March 1, year, 2AM -> second Sunday
659
   tmDate.tm_year = year;
660
   tmDate.tm_mon = 2;
661
   tmDate.tm_mday = 1;
662
   tmDate.tm_hour = 2;
663
   tmDate.tm_min = 0;
664
   tmDate.tm_sec = 0;
665
   seconds = mktime(&tmDate);
666
   gmtime_r(&seconds, &tmDate);
667
   days = 7 - tmDate.tm_wday + 7;
668
   *dstTimeIn = timeIn = seconds + days * SEC_PER_DAY;
669
 
670
   //November 1, year, 2AM -> first Sunday
671
   tmDate.tm_year = year;
672
   tmDate.tm_mon = 10;
673
   tmDate.tm_mday = 1;
674
   tmDate.tm_hour = 2;
675
   tmDate.tm_min = 0;
676
   tmDate.tm_sec = 0;
677
   seconds = mktime(&tmDate);
678
   gmtime_r(&seconds, &tmDate);
679
   days = 7 - tmDate.tm_wday;
680
   *dstTimeOut = timeOut = seconds + days * SEC_PER_DAY;
681
 
682
   DstTimeIn = timeIn;
683
   DstTimeOut = timeOut;
684
}
685 171 rhoads
#endif //INCLUDE_TIMELIB
686
 

powered by: WebSVN 2.1.0

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