1: 2: #include "lint.h" 3: #ifndef lint 4: static char sccs_id[] = "@(#)min.c 2.1 8/13/82"; 5: #endif lint 6: #include <ctype.h> 7: #include <stdio.h> 8: #include <ape.h> 9: m_in(a,b,f) /* input a number base b from file f into a */ 10: MINT *a; FILE *f; 11: { MINT x,y,ten; 12: int sign; 13: register int c; 14: short qten,qy; 15: 16: if (b<2) aperror("m_in: bad input base"); 17: xfree(a); 18: sign=1; 19: ten.len=1; 20: ten.val= &qten; 21: qten=b; 22: x.len=0; 23: y.len=1; 24: y.val= &qy; 25: while ((c=getc(f)) != EOF && (c == '\n' || c == ' ' 26: || c == '\t')) ; /* skip over white space to number */ 27: if (c == '+' || c == '-') /* catch sign */ 28: sign = (c = '+') ? 1 : -1; 29: else 30: ignore(ungetc (c,f)); 31: while ((c=getc(f)) != EOF) 32: switch(c) 33: { 34: case '\\': 35: c = getc(f); /* should be '\n'; more number follows */ 36: if (c != '\n') ignore(ungetc(c,f)); 37: continue; 38: case '\t': 39: case '\n': a->len *= sign; 40: xfree(&x); 41: return(0); /* tabs or newlines will end the number; 42: the first one is eaten */ 43: case ' ': 44: continue; /* spaces allowed in middle of big numbers 45: for the sake of clarity */ 46: default: if (isdigit(c)) 47: { qy=c-'0'; 48: mult(&x,&ten,a); 49: madd(a,&y,a); 50: move(a,&x); 51: continue; 52: } 53: else if (isalpha(c)) 54: { 55: if (((c == 'x') || (c == 'X')) && (b == 16)) 56: continue; /* allow 0x as hex marker */ 57: qy = c + 10 - ((c >= 'a') ? 'a' : 'A'); 58: /* ascii only! */ 59: mult(&x,&ten,a); 60: madd(a,&y,a); 61: move(a,&x); 62: continue; 63: } 64: else 65: { ignore(ungetc(c,f)); 66: a->len *= sign; 67: xfree(&x); 68: return(0); 69: } 70: } 71: xfree(&x); 72: return(EOF); 73: } 74: 75: sm_in(a,b,s) /* like m_in, but for a number represented 76: * as a character string s. 77: * Spaces are allowed only in longer numbers-- 78: * otherwise, any non-digits 79: * other than initial white space or signs 80: * (or letters for bases > 10) cause termination 81: * of input at that point */ 82: PMINT a; 83: char *s; 84: { 85: int sign=1, length; 86: long int ln; 87: MINT x,y,ten; 88: short qten,qy; 89: 90: 91: if (b<2) aperror("m_in: bad input base"); 92: xfree(a); 93: 94: /* First check to see whether ltom (or itom) would 95: * be adequate for input. The magic numbers used 96: * here depend on long ints being 32 bits. */ 97: 98: length = strlen(s); 99: /* do the most important cases the easy way: */ 100: if ((b==10 && length < 10) || 101: (b==8 && length <=10) || 102: (b==16 && length <=7)) 103: { 104: simpleconvert(a,b,s); 105: return; 106: } 107: if (b <10 && length < (18-b) ) 108: /* a crude estimate, to be sure! */ 109: { 110: /* skip intitial white space, if any */ 111: while (*s == ' ' || *s == '\n' || *s == '\t') ++s; 112: ln=0L; 113: if (*s == '+' || *s == '-') /* catch sign */ 114: sign = (*s++ = '+') ? 1 : -1; 115: while ( *s >= '0' && *s < b+'0') 116: { 117: ln *= b; 118: ln += (*s++ - '0'); 119: } 120: ln *= sign; 121: makemint(a,ln); 122: return; 123: } 124: /* For bases between 10 and 16, 125: * allow for letter digits: */ 126: if (b < 16 && length <= 7) 127: { 128: /* skip intitial white space, if any */ 129: while (*s == ' ' || *s == '\n' || *s == '\t') ++s; 130: ln=0L; 131: if (*s == '+' || *s == '-') /* catch sign */ 132: sign = (*s++ = '+') ? 1 : -1; 133: while (s != '\0') 134: { 135: ln *= b; 136: if (isdigit(*s)) 137: { 138: ln += (*s++ - '0'); 139: } 140: /* This works for sensible alphabets only! */ 141: else if ( (*s >= 'a' && *s <= 'f') || 142: (*s >= 'A' && *s <= 'F') ) 143: { 144: ln += *s + 10 - ( (*s >= 'a') ? 'a' : 'A'); 145: ++s; 146: } 147: else break; 148: } 149: ln *= sign; 150: makemint(a,ln); 151: return; 152: } 153: 154: /* Otherwise we have to use the ape 155: * routines to do the mults and adds: */ 156: 157: ten.len=1; 158: ten.val= &qten; 159: qten=b; 160: x.len=0; 161: y.len=1; 162: y.val= &qy; 163: while (*s != '\0' && (*s == '\n' || *s == ' ' 164: || *s == '\t')) ++s; 165: /* skip over white space to number */ 166: if (*s == '+' || *s == '-') /* catch sign */ 167: sign = (*s++ = '+') ? 1 : -1; 168: for(; *s != '\0'; ++s) 169: if (*s == ' ') 170: continue; /* spaces allowed in middle of big numbers 171: for the sake of clarity */ 172: else if (isdigit(*s)) 173: { qy = *s-'0'; 174: mult(&x,&ten,a); 175: madd(a,&y,a); 176: move(a,&x); 177: continue; 178: } 179: else if (isalpha(*s)) 180: { 181: if (((*s == 'x') || (*s == 'X')) && (b == 16)) 182: continue; /* allow 0x as hex marker */ 183: qy = *s + 10 - ((*s >= 'a') ? 'a' : 'A'); 184: /* ascii only! */ 185: mult(&x,&ten,a); 186: madd(a,&y,a); 187: move(a,&x); 188: continue; 189: } 190: else 191: { 192: a->len *= sign; 193: xfree(&x); 194: return; 195: } 196: xfree(&x); 197: return; 198: } 199: 200: simpleconvert(a,b,s) 201: PMINT a; 202: int b; 203: char *s; 204: { 205: long int ln; 206: int ok; 207: 208: switch(b) 209: { 210: case(10) : ok = sscanf(s,"%ld",&ln); break; 211: case(8) : ok = sscanf(s,"%lo",&ln); break; 212: case(16) : ok = sscanf(s,"%lx",&ln); break; 213: default : fprintf(stderr, "Not so simple!\n"); ok=0; break; 214: } 215: if (ok) 216: makemint(a,ln); 217: else 218: fprintf(stderr, "Can\'t convert %s\n",s); 219: return; 220: }