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

Subversion Repositories plasma

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

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

powered by: WebSVN 2.1.0

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