|
|
1.1 root 1: /*
2:
1.1.1.3 root 3: Copyright 1990,1991,1992 Eric R. Smith.
4:
1.1.1.5 root 5: Copyright 1992,1993 Atari Corporation.
1.1.1.3 root 6:
7: All rights reserved.
1.1 root 8:
9: */
10:
11:
12:
13: /*
14:
15: * misc. utility routines
16:
17: */
18:
19:
20:
21: #include "mint.h"
22:
23:
24:
25: /*
26:
27: * given an address, find the corresponding memory region in this program's
28:
29: * memory map
30:
31: */
32:
33:
34:
35: MEMREGION *
36:
37: addr2mem(a)
38:
39: virtaddr a;
40:
41: {
42:
43: int i;
44:
45:
46:
47: for (i = 0; i < curproc->num_reg; i++) {
48:
49: if (a == curproc->addr[i])
50:
51: return curproc->mem[i];
52:
53: }
54:
55: return 0;
56:
57: }
58:
59:
60:
61: /*
62:
63: * given a pid, return the corresponding process
64:
65: */
66:
67:
68:
69: PROC *
70:
71: pid2proc(pid)
72:
73: int pid;
74:
75: {
76:
77: PROC *p;
78:
79:
80:
81: for (p = proclist; p; p = p->gl_next) {
82:
83: if (p->pid == pid)
84:
85: return p;
86:
87: }
88:
89: return 0;
90:
91: }
92:
93:
94:
95: /*
96:
97: * return a new pid
98:
99: */
100:
101:
102:
103: int
104:
105: newpid()
106:
107: {
108:
109: static int _maxpid = 1;
110:
111: int i;
112:
113: #ifndef NDEBUG
114:
115: int j = 0;
116:
117: #endif
118:
119:
120:
121: do {
122:
123: i = _maxpid++;
124:
125: if (_maxpid >= 1000) _maxpid = 1;
126:
127: assert(j++ < 1000);
128:
129: } while (pid2proc(i));
130:
131:
132:
133: return i;
134:
135: }
136:
137:
138:
139: /*
140:
141: * zero out a block of memory, quickly; the block must be word-aligned,
142:
143: * and should be long-aligned for speed reasons
144:
145: */
146:
147:
148:
149: void
150:
151: zero(place, size)
152:
153: char *place;
154:
155: long size;
156:
157: {
158:
1.1.1.2 root 159: long cruft;
1.1 root 160:
1.1.1.5 root 161: long blocksize;
162:
1.1 root 163:
164:
165: cruft = size % 256; /* quickzero does 256 byte blocks */
166:
1.1.1.5 root 167: blocksize = size/256; /* divide by 256 */
1.1 root 168:
1.1.1.5 root 169: if (blocksize > 0) {
1.1 root 170:
1.1.1.5 root 171: quickzero(place, blocksize);
1.1 root 172:
1.1.1.5 root 173: place += (blocksize*256);
1.1 root 174:
175: }
176:
1.1.1.5 root 177: while (cruft > 0) {
178:
179: *place++ = 0;
1.1 root 180:
1.1.1.5 root 181: cruft--;
1.1 root 182:
183: }
184:
185: }
186:
187:
188:
189: #ifdef JUNK_MEM
190:
191: void
192:
193: fillwjunk(place, size)
194:
195: long *place;
196:
197: long size;
198:
199: {
200:
201: while (size > 0) {
202:
203: *place++ = size;
204:
205: size -= 4;
206:
207: }
208:
209: }
210:
211: #endif
212:
213:
214:
215: /*
216:
217: * kernel memory allocation routines
218:
219: */
220:
221:
222:
1.1.1.5 root 223: #define KERMEM_THRESHOLD (QUANTUM-8)
224:
225: #if 0
226:
227: #define KERMEM_SIZE QUANTUM
228:
229: #else
230:
231: #define KERMEM_SIZE ((KERMEM_THRESHOLD+8)*2)
232:
233: #endif
1.1.1.3 root 234:
1.1.1.2 root 235: #define KMAGIC ((MEMREGION *)0x87654321L)
1.1 root 236:
1.1.1.3 root 237: #define NKMAGIC 0x19870425L
1.1 root 238:
239:
240:
1.1.1.2 root 241: void * ARGS_ON_STACK
1.1 root 242:
243: kmalloc(size)
244:
245: long size;
246:
247: {
248:
1.1.1.4 root 249: MEMREGION *m;
1.1 root 250:
251: MEMREGION **p;
252:
1.1.1.3 root 253: long *lp;
1.1 root 254:
255:
1.1.1.3 root 256:
257: /*
258:
259: * increase size by two pointers' worth: the first contains
260:
261: * a pointer to the region descriptor for this block, and the
262:
263: * second contains KMAGIC. If the block came from nalloc,
264:
265: * then they both contain NKMAGIC.
266:
267: */
268:
269: size += sizeof(m) + sizeof(m);
1.1 root 270:
271: /*
272:
1.1.1.3 root 273: * for small requests, we use nalloc first
1.1 root 274:
275: */
276:
1.1.1.3 root 277: tryagain:
278:
279: if (size < KERMEM_THRESHOLD) {
280:
281: lp = nalloc(size);
1.1 root 282:
1.1.1.3 root 283: if (lp) {
1.1 root 284:
1.1.1.3 root 285: *lp++ = NKMAGIC;
1.1 root 286:
1.1.1.3 root 287: *lp++ = NKMAGIC;
1.1 root 288:
1.1.1.3 root 289: TRACELOW(("kmalloc(%lx) -> (nalloc) %lx",size,lp));
1.1 root 290:
1.1.1.3 root 291: return lp;
1.1 root 292:
1.1.1.3 root 293: }
1.1 root 294:
1.1.1.3 root 295: else {
1.1 root 296:
1.1.1.3 root 297: DEBUG(("kmalloc(%lx): nalloc is out of memory",size));
1.1 root 298:
299:
300:
1.1.1.3 root 301: /* If this is commented out, then we fall through to try_getregion */
302:
1.1.1.5 root 303: if (0 == (m = get_region(alt, KERMEM_SIZE, PROT_S))) {
1.1.1.3 root 304:
1.1.1.5 root 305: if (0 == (m = get_region(core, KERMEM_SIZE, PROT_S))) {
1.1.1.3 root 306:
307: DEBUG(("No memory for another arena"));
308:
309: goto try_getregion;
310:
311: }
312:
313: }
314:
1.1.1.5 root 315: lp = (long *)m->loc;
316:
317: *lp++ = (long)KMAGIC;
318:
319: *lp++ = (long)m;
320:
321: nalloc_arena_add((void *)lp,KERMEM_SIZE - 2*SIZEOF(long));
322:
1.1.1.3 root 323: goto tryagain;
324:
325: }
1.1 root 326:
327: }
328:
1.1.1.3 root 329:
330:
331: try_getregion:
332:
333: m = get_region(alt, size, PROT_S);
334:
335:
336:
337: if (!m) m = get_region(core, size, PROT_S);
338:
339:
340:
1.1 root 341: if (m) {
342:
343: p = (MEMREGION **)m->loc;
344:
345: *p++ = KMAGIC;
346:
347: *p++ = m;
348:
1.1.1.3 root 349: TRACELOW(("kmalloc(%lx) -> (get_region) %lx",size,p));
350:
1.1 root 351: return (void *)p;
352:
353: }
354:
355: else {
356:
1.1.1.3 root 357: TRACELOW(("kmalloc(%lx) -> (fail)",size));
358:
359: #if 0
360:
361: /* this is a serious offense; I want to hear about it */
362:
363: /* maybe Allan wanted to hear about it, but ordinary users
364:
365: * won't! -- ERS
366:
367: */
368:
369: NALLOC_DUMP();
370:
371: BIG_MEM_DUMP(0,0);
372:
373: #endif
374:
1.1 root 375: return 0;
376:
377: }
378:
379: }
380:
381:
382:
383: /* allocate from ST memory only */
384:
385:
386:
387: void *
388:
389: kcore(size)
390:
391: long size;
392:
393: {
394:
1.1.1.2 root 395: MEMREGION *m;
1.1 root 396:
397: MEMREGION **p;
398:
399:
400:
401: size += sizeof(m) + sizeof (m);
402:
1.1.1.3 root 403: m = get_region(core, size, PROT_S);
1.1 root 404:
405:
406:
407: if (m) {
408:
409: p = (MEMREGION **)m->loc;
410:
411: *p++ = KMAGIC;
412:
413: *p++ = m;
414:
415: return (void *)p;
416:
417: }
418:
419: else {
420:
421: return 0;
422:
423: }
424:
425: }
426:
427:
428:
1.1.1.2 root 429: void ARGS_ON_STACK
1.1 root 430:
431: kfree(place)
432:
433: void *place;
434:
435: {
436:
437: MEMREGION **p;
438:
439: MEMREGION *m;
440:
441:
442:
1.1.1.3 root 443: TRACELOW(("kfree(%lx)",place));
444:
445:
446:
1.1 root 447: if (!place) return;
448:
449: p = place;
450:
451: p -= 2;
452:
1.1.1.3 root 453: if (*p == (MEMREGION *)NKMAGIC) {
454:
455: nfree(p);
456:
457: return;
458:
459: }
460:
461: else if (*p++ != KMAGIC) {
1.1 root 462:
463: FATAL("kfree: memory not allocated by kmalloc");
464:
465: }
466:
1.1.1.2 root 467: m = *p;
1.1 root 468:
469: if (--m->links != 0) {
470:
471: FATAL("kfree: block has %d links", m->links);
472:
473: }
474:
475: free_region(m);
476:
477: }
478:
479:
480:
481: /*
482:
483: * "user" memory allocation routines; the kernel can use these to
484:
485: * allocate/free memory that will be attached in some way to a process
486:
487: * (and freed automatically when the process exits)
488:
489: */
490:
1.1.1.2 root 491: void * ARGS_ON_STACK
1.1 root 492:
493: umalloc(size)
494:
495: long size;
496:
497: {
498:
499: return (void *)m_xalloc(size, 3);
500:
501: }
502:
503:
504:
1.1.1.2 root 505: void ARGS_ON_STACK
1.1 root 506:
507: ufree(block)
508:
509: void *block;
510:
511: {
512:
513: (void)m_free((virtaddr)block);
514:
515: }
516:
517:
518:
519: /*
520:
521: * convert a time in milliseconds to a GEMDOS style date/time
522:
523: * timeptr[0] gets the time, timeptr[1] the date.
524:
525: * BUG/FEATURE: in the conversion, it is assumed that all months have
526:
527: * 30 days and all years have 360 days.
528:
529: */
530:
531:
532:
1.1.1.2 root 533: void ARGS_ON_STACK
1.1 root 534:
535: ms_time(ms, timeptr)
536:
537: ulong ms;
538:
539: short *timeptr;
540:
541: {
542:
543: ulong secs;
544:
545: short tsec, tmin, thour;
546:
547: short tday, tmonth, tyear;
548:
549:
550:
551: secs = ms / 1000;
552:
553: tsec = secs % 60;
554:
555: secs /= 60; /* secs now contains # of minutes */
556:
557: tmin = secs % 60;
558:
559: secs /= 60; /* secs now contains # of hours */
560:
561: thour = secs % 24;
562:
563: secs /= 24; /* secs now contains # of days */
564:
565: tday = secs % 30;
566:
567: secs /= 30;
568:
569: tmonth = secs % 12;
570:
571: tyear = secs / 12;
572:
573: *timeptr++ = (thour << 11) | (tmin << 5) | (tsec >> 1);
574:
575: *timeptr = (tyear << 9) | ((tmonth + 1) << 5) | (tday+1);
576:
577: }
578:
579:
580:
581: /*
582:
583: * unixtim(time, date): convert a Dos style (time, date) pair into
584:
585: * a Unix time (seconds from midnight Jan 1., 1970)
586:
587: */
588:
589:
590:
1.1.1.6 ! root 591: static int const
1.1 root 592:
593: mth_start[13] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
594:
595:
596:
1.1.1.2 root 597: long ARGS_ON_STACK
1.1 root 598:
599: unixtim(time, date)
600:
601: unsigned time, date;
602:
603: {
604:
605: int sec, min, hour;
606:
607: int mday, mon, year;
608:
609: long y, s;
610:
611:
612:
613: sec = (time & 31) << 1;
614:
615: min = (time >> 5) & 63;
616:
617: hour = (time >> 11) & 31;
618:
619: mday = date & 31;
620:
621: mon = ((date >> 5) & 15) - 1;
622:
623: year = 80 + ((date >> 9) & 255);
624:
625:
626:
627: /* calculate tm_yday here */
628:
629: y = (mday - 1) + mth_start[mon] + /* leap year correction */
630:
631: ( ( (year % 4) != 0 ) ? 0 : (mon > 1) );
632:
633:
634:
635: s = (sec) + (min * 60L) + (hour * 3600L) +
636:
637: (y * 86400L) + ((year - 70) * 31536000L) +
638:
639: ((year - 69)/4) * 86400L;
640:
641:
642:
643: return s;
644:
645: }
646:
647:
648:
649: /* convert a Unix time into a DOS time. The longword returned contains
650:
651: the time word first, then the date word.
652:
653: BUG: we completely ignore any time zone information.
654:
655: */
656:
657: #define SECS_PER_MIN (60L)
658:
659: #define SECS_PER_HOUR (3600L)
660:
661: #define SECS_PER_DAY (86400L)
662:
663: #define SECS_PER_YEAR (31536000L)
664:
665: #define SECS_PER_LEAPYEAR (SECS_PER_DAY + SECS_PER_YEAR)
666:
667:
668:
669: static int
670:
671: days_per_mth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
672:
673:
674:
1.1.1.2 root 675: long ARGS_ON_STACK
1.1 root 676:
677: dostim(t)
678:
679: long t;
680:
681: {
682:
683: unsigned long time, date;
684:
685: int tm_hour, tm_min, tm_sec;
686:
687: int tm_year, tm_mon, tm_mday;
688:
689: int i;
690:
691:
692:
693: if (t <= 0) return 0;
694:
695:
696:
697: tm_year = 70;
698:
699: while (t >= SECS_PER_YEAR) {
700:
701: if ((tm_year & 0x3) == 0) {
702:
703: if (t < SECS_PER_LEAPYEAR)
704:
705: break;
706:
707: t -= SECS_PER_LEAPYEAR;
708:
709: } else {
710:
711: t -= SECS_PER_YEAR;
712:
713: }
714:
715: tm_year++;
716:
717: }
718:
1.1.1.2 root 719: tm_mday = (int)(t/SECS_PER_DAY);
1.1 root 720:
721: days_per_mth[1] = (tm_year & 0x3) ? 28 : 29;
722:
723: for (i = 0; tm_mday >= days_per_mth[i]; i++)
724:
725: tm_mday -= days_per_mth[i];
726:
727: tm_mon = i+1;
728:
729: tm_mday++;
730:
731: t = t % SECS_PER_DAY;
732:
1.1.1.2 root 733: tm_hour = (int)(t/SECS_PER_HOUR);
1.1 root 734:
735: t = t % SECS_PER_HOUR;
736:
1.1.1.2 root 737: tm_min = (int)(t/SECS_PER_MIN);
1.1 root 738:
1.1.1.2 root 739: tm_sec = (int)(t % SECS_PER_MIN);
1.1 root 740:
741:
742:
743: if (tm_year < 80) {
744:
745: tm_year = 80;
746:
747: tm_mon = tm_mday = 1;
748:
749: tm_hour = tm_min = tm_sec = 0;
750:
751: }
752:
753:
754:
755: time = (tm_hour << 11) | (tm_min << 5) | (tm_sec >> 1);
756:
757: date = ((tm_year - 80) & 0x7f) << 9;
758:
759: date |= ((tm_mon) << 5) | (tm_mday);
760:
761: return (time << 16) | date;
762:
763: }
764:
765:
766:
767: /*
768:
769: * Case insensitive string comparison. note that this only returns
770:
771: * 0 (match) or nonzero (no match), and that the returned value
772:
773: * is not a reliable indicator of any "order".
774:
775: */
776:
777:
778:
1.1.1.2 root 779: int ARGS_ON_STACK
1.1 root 780:
781: strnicmp(str1, str2, len)
782:
783: register const char *str1, *str2;
784:
785: register int len;
786:
787: {
788:
789: register char c1, c2;
790:
791:
792:
793: do {
794:
795: c1 = *str1++; if (isupper(c1)) c1 = tolower(c1);
796:
797: c2 = *str2++; if (isupper(c2)) c2 = tolower(c2);
798:
799: } while (--len >= 0 && c1 && c1 == c2);
800:
801:
802:
803: if (len < 0 || c1 == c2)
804:
805: return 0;
806:
807: return c1 - c2;
808:
809: }
810:
811:
812:
1.1.1.2 root 813: int ARGS_ON_STACK
1.1 root 814:
815: stricmp(str1, str2)
816:
817: const char *str1, *str2;
818:
819: {
820:
821: return strnicmp(str1, str2, 0x7fff);
822:
823: }
824:
825:
826:
827:
828:
829: /*
830:
831: * string utilities: strlwr() converts a string to lower case, strupr()
832:
833: * converts it to upper case
834:
835: */
836:
837:
838:
1.1.1.2 root 839: char * ARGS_ON_STACK
1.1 root 840:
841: strlwr(s)
842:
843: char *s;
844:
845: {
846:
847: char c;
848:
849: char *old = s;
850:
851:
852:
853: while ((c = *s) != 0) {
854:
855: if (isupper(c)) {
856:
857: *s = _tolower(c);
858:
859: }
860:
861: s++;
862:
863: }
864:
865: return old;
866:
867: }
868:
869:
870:
1.1.1.2 root 871: char * ARGS_ON_STACK
1.1 root 872:
873: strupr(s)
874:
875: char *s;
876:
877: {
878:
879: char c;
880:
881: char *old = s;
882:
883:
884:
885: while ((c = *s) != 0) {
886:
887: if (islower(c)) {
888:
889: *s = _toupper(c);
890:
891: }
892:
893: s++;
894:
895: }
896:
897: return old;
898:
899: }
900:
901:
902:
903: #ifdef OWN_LIB
904:
905:
906:
907: /*
908:
909: * Case sensitive comparison functions.
910:
911: */
912:
913:
914:
915: int
916:
917: strncmp(str1, str2, len)
918:
919: register const char *str1, *str2;
920:
921: register int len;
922:
923: {
924:
925: register char c1, c2;
926:
927:
928:
929: do {
930:
931: c1 = *str1++;
932:
933: c2 = *str2++;
934:
935: } while (--len >= 0 && c1 && c1 == c2);
936:
937:
938:
939: if (len < 0) return 0;
940:
941:
942:
943: return c1 - c2;
944:
945: }
946:
947:
948:
949: int
950:
951: strcmp(str1, str2)
952:
953: const char *str1, *str2;
954:
955: {
956:
957: register char c1, c2;
958:
959:
960:
961: do {
962:
963: c1 = *str1++;
964:
965: c2 = *str2++;
966:
967: } while (c1 && c1 == c2);
968:
969:
970:
971: return c1 - c2;
972:
973: }
974:
975:
976:
977:
978:
979: /*
980:
981: * some standard string functions
982:
983: */
984:
985:
986:
987: char *
988:
989: strcat(dst, src)
990:
991: char *dst;
992:
993: const char *src;
994:
995: {
996:
997: register char *_dscan;
998:
999:
1000:
1001: for (_dscan = dst; *_dscan; _dscan++) ;
1002:
1.1.1.2 root 1003: while ((*_dscan++ = *src++) != 0) ;
1.1 root 1004:
1005: return dst;
1006:
1007: }
1008:
1009:
1010:
1011: char *
1012:
1013: strcpy(dst, src)
1014:
1015: char *dst;
1016:
1017: const char *src;
1018:
1019: {
1020:
1021: register char *_dscan = dst;
1022:
1.1.1.2 root 1023: while ((*_dscan++ = *src++) != 0) ;
1.1 root 1024:
1025: return dst;
1026:
1027: }
1028:
1029:
1030:
1031: char *
1032:
1033: strncpy(dst, src, len)
1034:
1035: char *dst;
1036:
1037: const char *src;
1038:
1039: int len;
1040:
1041: {
1042:
1043: register char *_dscan = dst;
1044:
1.1.1.2 root 1045: while (--len >= 0 && (*_dscan++ = *src++) != 0)
1.1 root 1046:
1047: continue;
1048:
1049: while (--len >= 0)
1050:
1051: *_dscan++ = 0;
1052:
1053: return dst;
1054:
1055: }
1056:
1057:
1058:
1059: int
1060:
1061: strlen(scan)
1062:
1063: const char *scan;
1064:
1065: {
1066:
1067: register const char *_start = scan+1;
1068:
1069: while (*scan++) ;
1070:
1071: return (int)((long)scan - (long)_start);
1072:
1073: }
1074:
1075:
1076:
1077: /*
1078:
1079: * strrchr: find the last occurence of a character in a string
1080:
1081: */
1082:
1083: char *
1084:
1085: strrchr(str, which)
1086:
1087: const char *str;
1088:
1089: register int which;
1090:
1091: {
1092:
1093: register unsigned char c, *s;
1094:
1095: register char *place;
1096:
1097:
1098:
1099: s = (unsigned char *)str;
1100:
1101: place = 0;
1102:
1103: do {
1104:
1105: c = *s++;
1106:
1107: if (c == which)
1108:
1109: place = (char *)s-1;
1110:
1111: } while (c);
1112:
1113: return place;
1114:
1115: }
1116:
1117:
1118:
1119: unsigned char _ctype[256] =
1120:
1121: {
1122:
1123: _CTc, _CTc, _CTc, _CTc, /* 0x00..0x03 */
1124:
1125: _CTc, _CTc, _CTc, _CTc, /* 0x04..0x07 */
1126:
1127: _CTc, _CTc|_CTs, _CTc|_CTs, _CTc|_CTs, /* 0x08..0x0B */
1128:
1129: _CTc|_CTs, _CTc|_CTs, _CTc, _CTc, /* 0x0C..0x0F */
1130:
1131:
1132:
1133: _CTc, _CTc, _CTc, _CTc, /* 0x10..0x13 */
1134:
1135: _CTc, _CTc, _CTc, _CTc, /* 0x14..0x17 */
1136:
1137: _CTc, _CTc, _CTc, _CTc, /* 0x18..0x1B */
1138:
1139: _CTc, _CTc, _CTc, _CTc, /* 0x1C..0x1F */
1140:
1141:
1142:
1143: _CTs, _CTp, _CTp, _CTp, /* 0x20..0x23 */
1144:
1145: _CTp, _CTp, _CTp, _CTp, /* 0x24..0x27 */
1146:
1147: _CTp, _CTp, _CTp, _CTp, /* 0x28..0x2B */
1148:
1149: _CTp, _CTp, _CTp, _CTp, /* 0x2C..0x2F */
1150:
1151:
1152:
1153: _CTd|_CTx, _CTd|_CTx, _CTd|_CTx, _CTd|_CTx, /* 0x30..0x33 */
1154:
1155: _CTd|_CTx, _CTd|_CTx, _CTd|_CTx, _CTd|_CTx, /* 0x34..0x37 */
1156:
1157: _CTd|_CTx, _CTd|_CTx, _CTp, _CTp, /* 0x38..0x3B */
1158:
1159: _CTp, _CTp, _CTp, _CTp, /* 0x3C..0x3F */
1160:
1161:
1162:
1163: _CTp, _CTu|_CTx, _CTu|_CTx, _CTu|_CTx, /* 0x40..0x43 */
1164:
1165: _CTu|_CTx, _CTu|_CTx, _CTu|_CTx, _CTu, /* 0x44..0x47 */
1166:
1167: _CTu, _CTu, _CTu, _CTu, /* 0x48..0x4B */
1168:
1169: _CTu, _CTu, _CTu, _CTu, /* 0x4C..0x4F */
1170:
1171:
1172:
1173: _CTu, _CTu, _CTu, _CTu, /* 0x50..0x53 */
1174:
1175: _CTu, _CTu, _CTu, _CTu, /* 0x54..0x57 */
1176:
1177: _CTu, _CTu, _CTu, _CTp, /* 0x58..0x5B */
1178:
1179: _CTp, _CTp, _CTp, _CTp, /* 0x5C..0x5F */
1180:
1181:
1182:
1183: _CTp, _CTl|_CTx, _CTl|_CTx, _CTl|_CTx, /* 0x60..0x63 */
1184:
1185: _CTl|_CTx, _CTl|_CTx, _CTl|_CTx, _CTl, /* 0x64..0x67 */
1186:
1187: _CTl, _CTl, _CTl, _CTl, /* 0x68..0x6B */
1188:
1189: _CTl, _CTl, _CTl, _CTl, /* 0x6C..0x6F */
1190:
1191:
1192:
1193: _CTl, _CTl, _CTl, _CTl, /* 0x70..0x73 */
1194:
1195: _CTl, _CTl, _CTl, _CTl, /* 0x74..0x77 */
1196:
1197: _CTl, _CTl, _CTl, _CTp, /* 0x78..0x7B */
1198:
1199: _CTp, _CTp, _CTp, _CTc, /* 0x7C..0x7F */
1200:
1201:
1202:
1203: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80..0x8F */
1204:
1205: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90..0x9F */
1206:
1207: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0..0xAF */
1208:
1209: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0..0xBF */
1210:
1211: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0..0xCF */
1212:
1213: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0..0xDF */
1214:
1215: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0..0xEF */
1216:
1217: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xF0..0xFF */
1218:
1219: };
1220:
1221:
1222:
1223: int toupper(c)
1224:
1225: int c;
1226:
1227: {
1228:
1229: return(islower(c) ? (c ^ 0x20) : (c));
1230:
1231: }
1232:
1233:
1234:
1235: int tolower(c)
1236:
1237: int c;
1238:
1239: {
1240:
1241: return(isupper(c) ? (c ^ 0x20) : (c));
1242:
1243: }
1244:
1245:
1246:
1247: /*
1248:
1249: * converts a decimal string to an integer
1250:
1251: */
1252:
1253:
1254:
1.1.1.2 root 1255: long
1.1 root 1256:
1.1.1.2 root 1257: atol(s)
1.1 root 1258:
1259: const char *s;
1260:
1261: {
1262:
1.1.1.2 root 1263: long d = 0;
1.1 root 1264:
1265: int negflag = 0;
1266:
1267: int c;
1268:
1269:
1270:
1271: while (*s && isspace(*s)) s++;
1272:
1273: while (*s == '-' || *s == '+') {
1274:
1275: if (*s == '-')
1276:
1277: negflag ^= 1;
1278:
1279: s++;
1280:
1281: }
1282:
1.1.1.2 root 1283: while ((c = *s++) != 0 && isdigit(c)) {
1.1 root 1284:
1285: d = 10 * d + (c - '0');
1286:
1287: }
1288:
1289: if (negflag) d = -d;
1290:
1291: return d;
1292:
1293: }
1294:
1295:
1296:
1297: #endif /* OWN_LIB */
1298:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.