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