1 /*
2  *  Msged support routines for Pacific C
3  *
4  *  Written by Paul Edwards and Matthew Parker and released
5  *  to the public domain.
6  */
7 
8 #include <stddef.h>
9 #include <ctype.h>
10 #include <time.h>
11 #include <unixio.h>
12 #include <dos.h>
13 
strtol(const char * nptr,char ** endptr,int base)14 long int strtol(const char *nptr, char **endptr, int base)
15 {
16     long x = 0;
17     int undecided = 0;
18 
19     if (base == 0)
20     {
21         undecided = 1;
22     }
23     while (1)
24     {
25         if (isdigit(*nptr))
26         {
27             if (base == 0)
28             {
29                 if (*nptr == '0')
30                 {
31                     base = 8;
32                 }
33                 else
34                 {
35                     base = 10;
36                     undecided = 0;
37                 }
38             }
39             x = x * base + (*nptr - '0');
40             nptr++;
41         }
42         else if (isalpha(*nptr))
43         {
44             if ((*nptr == 'X') || (*nptr == 'x'))
45             {
46                 if ((base == 0) || ((base == 8) && undecided))
47                 {
48                     base = 16;
49                     undecided = 0;
50                 }
51                 else
52                 {
53                     break;
54                 }
55             }
56             else
57             {
58                 x = x * base + (toupper((unsigned char)*nptr) - 'A') + 10;
59                 nptr++;
60             }
61         }
62         else
63         {
64             break;
65         }
66     }
67     if (endptr != NULL)
68     {
69         *endptr = (char *)nptr;
70     }
71     return x;
72 }
73 
sopen(char * filename,unsigned int access,int flags,...)74 int sopen(char *filename, unsigned int access, int flags,...)
75 {
76     int fp;
77 
78     fp = open(filename, access);
79     if (fp == -1 && access == 1)
80     {
81         creat(filename, 0666);
82         fp = open(filename, access);
83     }
84     return fp;
85 }
86 
bdos(int func,unsigned reg_dx,unsigned char reg_al)87 int bdos(int func, unsigned reg_dx, unsigned char reg_al)
88 {
89     union REGS r;
90     r.h.ah = func;
91     r.h.al = reg_al;
92     r.x.dx = reg_dx;
93     int86(0x21, &r, &r);
94     return r.x.ax;
95 }
96 
97 /*
98  *  Scalar date routines, public domain by Ray Gardner.
99  *
100  *  These will work over the range 1-01-01 thru 14699-12-31.  The
101  *  functions written by Ray are isleap, months_to_days, years_to_days,
102  *  ymd_to_scalar, scalar_to_ymd.  Modified slightly by Paul Edwards.
103  */
104 
isleap(unsigned yr)105 static int isleap(unsigned yr)
106 {
107     return yr % 400 == 0 || (yr % 4 == 0 && yr % 100 != 0);
108 }
109 
months_to_days(unsigned month)110 static unsigned months_to_days(unsigned month)
111 {
112     return (month * 3057 - 3007) / 100;
113 }
114 
years_to_days(unsigned yr)115 static long years_to_days(unsigned yr)
116 {
117     return yr * 365L + yr / 4 - yr / 100 + yr / 400;
118 }
119 
ymd_to_scalar(unsigned yr,unsigned mo,unsigned day)120 static long ymd_to_scalar(unsigned yr, unsigned mo, unsigned day)
121 {
122     long scalar;
123     scalar = day + months_to_days(mo);
124     if (mo > 2)
125     {
126         /* adjust if past February */
127         scalar -= isleap(yr) ? 1 : 2;
128     }
129     yr--;
130     scalar += years_to_days(yr);
131     return scalar;
132 }
133 
mktime(struct tm * timeptr)134 time_t mktime(struct tm * timeptr)
135 {
136     time_t tt;
137     if (timeptr->tm_year < 70 || timeptr->tm_year > 120)
138     {
139         tt = (time_t) -1;
140     }
141     else
142     {
143         tt = ymd_to_scalar(timeptr->tm_year + 1900, timeptr->tm_mon,
144           timeptr->tm_mday) - ymd_to_scalar(1970, 1, 1);
145         tt = tt * 24 + timeptr->tm_hour;
146         tt = tt * 60 + timeptr->tm_min;
147         tt = tt * 60 + timeptr->tm_sec;
148     }
149     return tt;
150 }
151