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

Subversion Repositories plasma

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

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

powered by: WebSVN 2.1.0

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