hschumann2/TempleOS-Source-Code
0838
1 2I64 Str2I64(U8 *st,I64 radix=10,U8 **_end_ptr=NULL)3{//String to I64. Similar to strtoul().4//Allows radix change with "0x20" "0b1010" "0d123" "0o18".5 //Be careful of Str2I64("0b101",16)-->0xB101.6 Bool neg=FALSE;7 I64 ch,res=0;8 if (!st || !(2<=radix<=36)) {9 if (_end_ptr) *_end_ptr=st;10 return 0;11 }12 while (Bt(char_bmp_white_space,*st))13 st++;14 while (TRUE)15 switch (*st) {16 case '-':17 st++;18 neg=!neg;19 break;20 case '+':21 st++;22 break;23 case '0':24 st++;25 ch=ToUpper(*st);26 if (ch>='B' && (radix<=10 || ch>'A'+radix-11))27 switch (ch) {28 case 'B': radix=2; st++; break;29 case 'D': radix=10; st++; break;30 case 'X': radix=16; st++; break;31 }32 default:33 goto ai_cont;34 }35ai_cont:36 while (ch=ToUpper(*st++)) {37 if (radix>10) {38 if ('0'<=ch<='9')39 res=res*radix+ch-'0';40 else if ('A'<=ch<='A'+radix-11)41 res=res*radix+ch-'A'+10;42 else43 break;44 } else if ('0'<=ch<='0'+radix-1)45 res=res*radix+ch-'0';46 else47 break;48 }49 if (_end_ptr) *_end_ptr=st-1;50 if (neg)51 return -res;52 else53 return res;54}55 56F64 Str2F64(U8 *src,U8 **_end_ptr=NULL)57{/*String to F64.58Does not allow more than 18-digits59before or after the decimal point60because the numbers before and after61the decimal point are stored62in 64-bits. Use exponentiated forms63to avoid this.64*/65 I64 i,j,k,ch;66 F64 d;67 Bool neg=FALSE,neg_e=FALSE;68 69 ch=*src++;70 while (Bt(char_bmp_white_space,ch))71 ch=*src++;72 if (ch=='-') {73 neg=TRUE;74 ch=*src++;75 }76 if (!StrNCmp(src-1,"inf",3)) {77 d=inf;78 src+=3;79 goto a2f_end;80 }81 if (*src=='inf') {82 d=inf;83 src++;84 goto a2f_end;85 }86 i=0;87 while (TRUE) {88 if (Bt(char_bmp_dec_numeric,ch))89 i=i*10+ch-'0';90 else {91 if (ch=='.' || ch=='e' || ch=='E')92 break;93 d=i;94 goto a2f_end;95 }96 ch=*src++;97 }98 if (ch=='.')99 ch=*src++;100 k=0;101 while (TRUE) {102 if (Bt(char_bmp_dec_numeric,ch)) {103 i=i*10+ch-'0';104 k++;105 } else {106 if (ch=='e' || ch=='E')107 break;108 d=i*Pow10I64(-k);109 goto a2f_end;110 }111 ch=*src++;112 }113 ch=*src++;114 if (ch=='-') {115 neg_e=TRUE;116 ch=*src++;117 }118 j=0;119 while (TRUE) {120 if (Bt(char_bmp_dec_numeric,ch))121 j=j*10+ch-'0';122 else {123 if (neg_e)124 d=i*Pow10I64(-j-k);125 else126 d=i*Pow10I64(j-k);127 goto a2f_end;128 }129 ch=*src++;130 }131a2f_end:132 if (_end_ptr) *_end_ptr=src-1;133 if (neg)134 return -d;135 else136 return d;137}138 139CDate Str2Date(U8 *_src)140{/*"*+nnnn", "*-nnnn", "mm/dd", "mm/dd/yy"141It also supports some funs142SM() start of mon143EM() end of mon144SY() start of year145EY() end of year146Full expressions are not implimented147but you can do stuff like SM(*-7)+3148and it will return the 3rd day after149the start of mon for seven days before150today.151*/152 CDate res=0;153 CDateStruct ds,ds_now;154 U8 *src=MStrUtil(_src,SUF_REM_SPACES|SUF_TO_UPPER),155 *v=StrNew(src),156 *ptr=src;157 Bool start_mon=FALSE,end_mon=FALSE,158 start_year=FALSE,end_year=FALSE;159 160 MemSet(&ds,0,sizeof(CDateStruct));161 if (!StrNCmp(ptr,"SM(",3)) {162 ptr+=3;163 start_mon=TRUE;164 } else if (!StrNCmp(ptr,"EM(",3)) {165 ptr+=3;166 end_mon=TRUE;167 } else if (!StrNCmp(ptr,"SY(",3)) {168 ptr+=3;169 start_year=TRUE;170 } else if (!StrNCmp(ptr,"EY(",3)) {171 ptr+=3;172 end_year=TRUE;173 }174 if (*ptr=='*') {175 ptr++;176 if (*ptr=='+' || *ptr=='-')177 res.date=Str2I64(ptr,,&ptr);178 res+=Now+local_time_offset;179 } else {180 StrFirstRem(ptr,"/",v); //Put mon into v181 ds.mon=Str2I64(v);182 if (StrOcc(ptr,'/')) {183 StrFirstRem(ptr,"/",v); //Put day into v leaving year in ptr184 ds.day_of_mon=Str2I64(v);185 ds.year=Str2I64(ptr,,&ptr);186 if (ds.year<100) //if not 4 digit year187 ds.year+=2000;188 } else {189 ds.day_of_mon=Str2I64(ptr,,&ptr);190 Date2Struct(&ds_now,Now+local_time_offset);191 ds.year=ds_now.year;192 }193 res=Struct2Date(&ds);194 }195 if (*ptr==')') ptr++;196 197 if (start_mon)198 res.date=FirstDayOfMon(res.date);199 else if (end_mon)200 res.date=LastDayOfMon(res.date);201 else if (start_year)202 res.date=FirstDayOfYear(res.date);203 else if (end_year)204 res.date=LastDayOfYear(res.date);205 206 if (*ptr=='+' || *ptr=='-')207 res.date+=Str2I64(ptr);208 Free(src);209 Free(v);210 return res-local_time_offset;211}212 213U8 *StrScan(U8 *src,U8 *fmt,...)214{/*Opposite of sprintf(). Pass ptrs to data to be scanned-in.215For "%s", pass ptr to ptr (be careful because addr216of array is the same as array--create ptr to array217and take addr.218*/219 U8 *buf,*ptr,**pptr;220 Bool left_justify=FALSE;221 I64 ch,cur_arg=0,i,len,*i_ptr,dec_len;222 F64 *d_ptr;223 if (!fmt)224 throw('Scan');225 while (ch = *fmt++) {226 if (ch=='%') {227 if (*fmt=='%') {228 src++;229 fmt++;230 } else {231 if (*fmt=='-') {232 left_justify=TRUE;233 fmt++;234 } else235 left_justify=FALSE;236 len=0;237 while ('0'<=*fmt<='9')238 len=len*10+ (*fmt++ -'0');239 if (*fmt=='*') {240 fmt++;241 if (cur_arg>=argc)242 throw('Scan');243 len=argv[cur_arg++];244 }245 ch=*fmt++;246 if (ch && !len) {247 ptr=src;248 while (*ptr && *ptr!=*fmt)249 ptr++;250 len=ptr-src;251 } else {252 if (ch=='.') {253 dec_len=0;254 while ('0'<=*fmt<='9')255 dec_len=dec_len*10+ (*fmt++-'0');256 if (*fmt=='*') {257 fmt++;258 if (cur_arg>=argc)259 throw('Scan');260 dec_len=argv[cur_arg++];261 }262 ch=*fmt++;263 }264 }265 buf=MAlloc(len+1);266 for (i=0;i<len;i++)267 buf[i]=*src++;268 buf[i]=0;269 switch (ch) {270 case 's':271 if (cur_arg>=argc)272 throw('Scan');273 pptr=argv[cur_arg++];274 StrCpy(*pptr,buf);275 break;276 case 'c':277 if (cur_arg>=argc)278 throw('Scan');279 ptr=argv[cur_arg++];280 *ptr=*buf;281 break;282 case 'C':283 if (cur_arg>=argc)284 throw('Scan');285 ptr=argv[cur_arg++];286 *ptr=ToUpper(*buf);287 break;288 case 'z':289 if (cur_arg+1>=argc)290 throw('Scan');291 i_ptr=argv[cur_arg++];292 *i_ptr=LstMatch(buf,argv[cur_arg++]);293 break;294 case 'Z':295 if (cur_arg+1>=argc)296 throw('Scan');297 i_ptr=argv[cur_arg++];298 *i_ptr=DefineMatch(buf,argv[cur_arg++]);299 break;300 case 'd':301 if (cur_arg>=argc)302 throw('Scan');303 i_ptr=argv[cur_arg++];304 *i_ptr=Str2I64(buf);305 break;306 case 'X':307 if (cur_arg>=argc)308 throw('Scan');309 i_ptr=argv[cur_arg++];310 *i_ptr=Str2I64(buf,16);311 break;312 case 'b':313 if (cur_arg>=argc)314 throw('Scan');315 i_ptr=argv[cur_arg++];316 *i_ptr=Str2I64(buf,2);317 break;318 case 'e':319 case 'f':320 case 'g':321 case 'n':322 if (cur_arg>=argc)323 throw('Scan');324 d_ptr=argv[cur_arg++];325 *d_ptr=Str2F64(buf);326 break;327 case 'D':328 if (cur_arg>=argc)329 throw('Scan');330 i_ptr=argv[cur_arg++];331 *i_ptr=Str2Date(buf);332 break;333 }334 Free(buf);335 }336 } else337 src++;338 }339 return src;340}341 