1 #include <stdlib.h>
2 #include <windows.h>
3
4
isspace(int c)5 int isspace(int c) {
6 if ((c >= 0x09) && (c <= 0x0D)) return 1;
7 else if (c == 0x20) return 1;
8 return 0;
9 }
10
isdigit(int c)11 int isdigit(int c) {
12 if ((c >= '0') && (c <= '9')) return 1;
13 else return 0;
14 }
15
isxdigit(int c)16 int isxdigit(int c) {
17 if ((c >= '0') && (c <= '9')) return 1;
18 else if ((c >= 'a') && (c <= 'f')) return 1;
19 else if ((c >= 'A') && (c <= 'F')) return 1;
20 else return 0;
21 }
22
isalpha(int c)23 int isalpha(int c) {
24 if ((c >= 'a') && (c <= 'z')) return 1;
25 else if ((c >= 'A') && (c <= 'Z')) return 1;
26 else return 0;
27 }
28
isalnum(int c)29 int isalnum(int c) {
30 if ((c >= '0') && (c <= '9')) return 1;
31 else if ((c >= 'a') && (c <= 'z')) return 1;
32 else if ((c >= 'A') && (c <= 'Z')) return 1;
33 else return 0;
34 }
35
checkDigit(char ch,int base)36 static int checkDigit(char ch, int base) {
37 int n;
38
39 if (ch >= '0' && ch <= '9') n = ch - '0';
40 else if (ch >= 'a' && ch <= 'z') n = ch + 10 - 'a';
41 else if (ch >= 'A' && ch <= 'Z') n = ch + 10 - 'A';
42 else return -1;
43
44 return n >= base ? -1 : n;
45 }
46
strtol(const char * s,char ** endptr,int base)47 long strtol(const char *s, char **endptr, int base) {
48 const char *sc;
49 char sign;
50 int actualbase;
51 double result;
52
53 /* if the base is illegal, then return 0; */
54 if (! (base >= 2 && base <= 36) ){
55 if (endptr) *endptr = (char *)s;
56 return 0;
57 }
58
59 /* skip leading spaces */
60 for (sc = s; *sc == ' '; ++sc);
61
62 /* parse the sign */
63 if (*sc == '-' || *sc == '+') {
64 sign = *sc;
65 sc++;
66 }
67 else {
68 sign = '+';
69 }
70
71 /* the default base = 10 */
72 actualbase = base == 0 ? 10 : base;
73
74 /* if base is undefined, and number starts '0x', then we have base 16 */
75 if (base == 0 && sc[0] == '0' && (sc[1] == 'x' || sc[1] == 'X')) { actualbase = 16; sc += 2; }
76
77 /* else if base is undefined, and number starts '0', then we have base 8 */
78 else if (base == 0 && sc[0] == '0') actualbase = 8;
79
80 /* else if base == 16, then skip any leading '0x' */
81 else if (base == 16 && sc[0] == '0' && (sc[1] == 'x' || sc[1] == 'X')) sc += 2;
82
83 /* skip leading zeroes */
84 for (; *sc == '0'; ++sc);
85
86 /* the result so far is 0. We are going to work with doubles because these give 52 bits of accuracy */
87 result = 0.0;
88
89 /* sc now points to the first unprocessed digit. Keep processing until first non digit or overflow */
90 for (;;) {
91 int d = checkDigit(*sc, actualbase);
92
93 /* if the digit was illegal, then we have terminated */
94 if (d < 0) {
95 if (endptr) *endptr = (char *)sc;
96 return sign == '-' ? -(long)result : (long)result;
97 }
98
99 /* roll in the new digit */
100 result = result * actualbase + d;
101
102 /* check for overflow */
103 if (sign == '+' && result > (double)LONG_MAX) {
104 if (endptr) *endptr = (char *)(sc+1);
105 return LONG_MAX;
106 }
107 if (sign == '-' && result > -(double)LONG_MIN) {
108 if (endptr) *endptr = (char *)(sc+1);
109 return LONG_MIN;
110 }
111
112 /* go on to the next character */
113 sc++;
114 }
115 }
116
117 /*
118 * Implement rename and unlink in win32 procedures. This is complicated
119 * by the fact that these procedures take wide chars.
120 */
121
122 #define MAX_FILENAME_LEN 128
123
rename(const char * oldname,const char * newname)124 int rename(const char *oldname, const char *newname) {
125 int succ;
126 short soldname[MAX_FILENAME_LEN];
127 short snewname[MAX_FILENAME_LEN];
128
129 MultiByteToWideChar(CP_ACP, 0, oldname, strlen(oldname)+1, soldname, MAX_FILENAME_LEN);
130 MultiByteToWideChar(CP_ACP, 0, newname, strlen(newname)+1, snewname, MAX_FILENAME_LEN);
131 succ = MoveFile(soldname, snewname);
132 return !succ;
133 }
134
unlink(char * name)135 int unlink(char *name) {
136 int succ;
137 short wname[MAX_FILENAME_LEN];
138
139 MultiByteToWideChar(CP_ACP, 0, name, strlen(name)+1, wname, MAX_FILENAME_LEN);
140
141 succ = DeleteFile(wname);
142 return !succ;
143 }
144
calloc(size_t nelem,size_t size)145 void *calloc(size_t nelem, size_t size) {
146 const size_t n = nelem*size;
147 char *p = malloc(n);
148
149 if (p) memset(p, '\0', n);
150 return p;
151 }
152