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

Subversion Repositories mlite

[/] [mlite/] [trunk/] [kernel/] [libc.c] - Blame information for rev 199

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

powered by: WebSVN 2.1.0

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