|
|
1.1 ! root 1: /* Copyright 1990, AT&T Bell Labs */ ! 2: ! 3: /* Canonicalize the number string pointed to by dp, of length ! 4: len. Put the result in kp. ! 5: ! 6: A field of length zero, or all blank, is regarded as 0. ! 7: Over/underflow is rendered as huge or zero and properly signed. ! 8: It happens 1e+-1022. ! 9: ! 10: Canonicalized strings may be compared as strings of unsigned ! 11: chars. For good measure, a canonical string has no zero bytes. ! 12: ! 13: Syntax: optionally signed floating point, with optional ! 14: leading spaces. A syntax deviation ends the number. ! 15: ! 16: Form of output: packed in 4-bit nibbles. First ! 17: 3 nibbles count the number N of significant digits ! 18: before the decimal point. The quantity actually stored ! 19: is 2048+sign(x)*(N+1024). Further nibbles contain ! 20: 1 decimal digit d each, stored as d+2 if x is positive ! 21: and as 10-d if x is negative. Leading and trailing ! 22: zeros are stripped, and a trailing "digit" d = -1 ! 23: is appended. (The trailing digit handled like all others, ! 24: so encodes as 1 or 0xb according to the sign of x.) ! 25: An odd number of nibbles is padded with zero. ! 26: ! 27: Buglet: overflow is reported if output is exactly filled. ! 28: ! 29: */ ! 30: #include "fsort.h" ! 31: ! 32: #define encode(x) (neg? 10-(x): (x)+2) ! 33: #define putdig(x) (nib? (*dig=encode(x)<<4, nib=0): \ ! 34: (*dig++|=encode(x), nib=1)) ! 35: ! 36: static int gflag; ! 37: ! 38: int ! 39: gcode(uchar *dp, uchar*kp, int len, struct field *f) ! 40: { ! 41: int ret; ! 42: gflag++; ! 43: ret = ncode(dp, kp, len, f); ! 44: gflag--; ! 45: return ret; ! 46: } ! 47: ! 48: int ! 49: ncode(uchar *dp, uchar*kp, int len, struct field *f) ! 50: { ! 51: uchar *dig = kp + 1; /* byte for next digit */ ! 52: int nib = 0; /* high nibble 1, low nibble 0 */ ! 53: uchar *cp = dp; ! 54: uchar *ep = cp + len; /* end pointer */ ! 55: int zeros = 0; /* count zeros seen but not installed */ ! 56: int sigdig = 1024; ! 57: int neg = f->rflag; /* 0 for +, 1 for - */ ! 58: int decimal = 0; ! 59: int n, inv; ! 60: ! 61: kp[1] = 0; ! 62: for( ; cp<ep ; cp++) /* eat blanks */ ! 63: if(*cp!=' ' && *cp!='\t') ! 64: break; ! 65: if(cp < ep) /* eat sign */ ! 66: switch(*cp) { ! 67: case '-': ! 68: neg ^= 1; ! 69: case '+': ! 70: cp++; ! 71: } ! 72: for( ; cp<ep; cp++) /* eat leading zeros */ ! 73: if(*cp != '0') ! 74: break; ! 75: if(*cp=='.' && cp<ep) { /* decimal point among lead zeros */ ! 76: decimal++; ! 77: for(cp++; cp<ep; cp++) { ! 78: if(*cp != '0') ! 79: break; ! 80: sigdig--; ! 81: } ! 82: } ! 83: if(*cp>'9' || *cp<'0' || cp>=ep) { /* no sig digit*/ ! 84: sigdig = 0; ! 85: neg = 0; ! 86: goto retzero; ! 87: } ! 88: for( ; cp<ep; cp++) { ! 89: switch(*cp) { ! 90: default: ! 91: goto out; ! 92: case '.': ! 93: if(decimal) ! 94: goto out; ! 95: decimal++; ! 96: continue; ! 97: case '0': ! 98: zeros++; ! 99: if(!decimal) ! 100: sigdig++; ! 101: continue; ! 102: case '1': case '2': case '3': case '4': case '5': ! 103: case '6': case '7': case '8': case '9': ! 104: for( ; zeros>0; zeros--) ! 105: putdig(0); ! 106: n = *cp - '0'; ! 107: putdig(n); ! 108: if(!decimal) ! 109: sigdig++; ! 110: continue; ! 111: case 'e': ! 112: case 'E': ! 113: if(!gflag) ! 114: goto out; ! 115: inv = 1; ! 116: if(cp < ep) switch(*++cp) { ! 117: case '-': ! 118: inv = -1; ! 119: case '+': ! 120: cp++; ! 121: } ! 122: if(*cp>'9' || *cp<'0' || cp>=ep) ! 123: goto out; ! 124: for(n=0; cp<ep; cp++) { ! 125: int c = *cp; ! 126: if(c<'0' || c>'9') ! 127: break; ! 128: if((n = 10*n+c-'0') >= 0) ! 129: continue; ! 130: sigdig = 2047*inv; ! 131: goto out; ! 132: } ! 133: sigdig += n*inv; ! 134: goto out; ! 135: } ! 136: } ! 137: out: ! 138: if(sigdig<0 || sigdig>=2047) { ! 139: sigdig = sigdig<0? 0: 2047; ! 140: warn("numeric field overflow", (char*)dp, len); ! 141: dig = kp + 1; ! 142: *dig = 0; ! 143: nib = 0; ! 144: } ! 145: retzero: ! 146: if(neg) ! 147: sigdig = 2048 - sigdig; ! 148: else ! 149: sigdig = 2048 + sigdig; ! 150: kp[0] = sigdig >> 4; ! 151: kp[1] |= sigdig << 4; ! 152: putdig(-1); ! 153: return dig - kp + 1 - nib; ! 154: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.