/* Long package amended and extended to support BDS 1.50 library added lcomp - compare two strings (as per documentation) ltoas - long to ascii scaled atols - ascii to long scaled function numbers 0,7,8 have not yet been identified and are marked as UK1,UK3,UK4 below. a few functions in the documentation have not been done yet but are trivial to implement when required. */ #define UK1 0 #define COMP 1 #define ADD 2 #define SUB 3 #define MUL 4 #define DIV 5 #define MOD 6 #define UK3 7 #define UK4 8 /* ladd adds the addend and augend to produce a 32 bit signed result in sum. A pointer to sum is returned. */ char *ladd(sum,addend,augend) char sum[], addend[], augend[]; { char *long(); return (long(ADD,sum,addend,augend)); } /* lsub subtracts subtrahend from minuend and places the 32 bit signed difference in difference. A pointer to difference is returned. */ char *lsub(difference,minuend,subtrahend) char difference[], minuend[], subtrahend[]; { char *long(); return (long(SUB,difference,minuend,subtrahend)); } /* lmul multiplies plier and plicand together and places the signed low order 32 bit product in product. A pointer to product is returned. */ char *lmul(product,plier,plicand) char product[], plier[], plicand[]; { char *long(); return (long(MUL,product,plier,plicand)); } /* scale must be from 0 to 9 */ char *lmuls(product,plier,plicand,scale) char product[],plier[],plicand[]; int scale; { char *long(); char ten[4],five[4]; ten[3]=0x0a; ten[1]=ten[2]=ten[0]=0; five[3]=0x05; five[1]=five[2]=five[0]=0; long(MUL,product,plier,plicand); /* round and scale */ while (scale--) { long(ADD,product,product,five); long(DIV,product,product,ten); } return(&product); } /* ldiv divides dividend by divisor and places the signed low order 32 bits of the quotient in quotient. A pointer to quotient is returned. ldivs takes account of a scale when performing the division - 0 <= scale < 10 */ char *ldiv(quotient,dividend,divisor) char quotient[], dividend[], divisor[]; { char *long(); return (long(DIV,quotient,dividend,divisor)); } char *ldivs(quotient,dividend,divisor,scale) char quotient[], dividend[], divisor[]; int scale; { char *long(); char ten[4]; ten[3]=0x0a; ten[1]=ten[2]=ten[0]=0; while (scale--) long(MUL,dividend,dividend,ten); long(DIV,quotient,dividend,divisor); } /* lmod places the 31 bit positive remainder resulting from the division of dividend by divisor into residue. A pointer to residue is returned. */ char *lmod(residue,dividend,divisor) char residue[], dividend[], divisor[]; { char *long(); return (long(MOD,residue,dividend,divisor)); } /* lneg places the 32 bit signed negative of orignum in negnum and returns a pointer to it. */ char *lneg(negnum,orignum) char negnum[], orignum[]; { char *long(), work[4], i; for (i=0; i<4; ++i) work[i]=0; return (long(SUB,negnum,work,orignum)); } /* lcomp returns -1,0,1 depending on result of leftr */ int lcomp(left,right) char left[], right[]; { return(long(COMP,left,right)); } /* itol converts an integer to long form. A pointer to the longform is returned. */ char *itol(longform,i) char longform[]; int i; { longform[1]=longform[0]=0; if (i<0) longform[1]=longform[0]=0xff; longform[2]=i>>8; longform[3]=i&0xff; return longform; } /* ltoi returns a properly signed integer containing the low order 15 bits of precision of the long integer longint. The value of this integer is placed in i and is returned by this function. */ ltoi(longint) char longint[4]; { int i; char work[4]; for (i=0; i<4; ++i) work[i]=longint[i]; if (work[0]>127) lneg(work,work); i=(work[2]<<8)+work[3]; if (longint[0]>127) i=-i; return i; } /* atol converts the ASCII string s to a long integer placed in longint and returns a pointer to longint. Acceptable format for atol is: any amount of white space followed by an optional sign followed by a string of decimal digits. The first non-decimal digit stops the scan. The method used is an adaptation of that presented in Kernighan and Ritchie. */ char *atols(longint,s,scale) char longint[]; char s[]; int scale; { int i, j; char wstr[20]; char *wptr,*sptr; sptr = &s[0]; wptr = &wstr[0]; /* white space */ while (*sptr == ' ' || *sptr == '\t') sptr++; /* a sign */ if (*sptr == '-' || *sptr == '+') *wptr++ = *sptr++; /* integral digits */ while (isdigit(*sptr)) *wptr++ = *sptr++; /* have we got a dot */ if (*sptr == '.') { sptr++; while (scale--) if (isdigit(*sptr)) *wptr++ = *sptr++; else *wptr++ = '0'; } else while (scale--) *wptr++ = '0'; /* end of string */ *wptr++ = 0; return(atol(longint,wstr)); } char *atol(longint,s) char longint[], s[]; { char work[4], ten[4]; int i, j, n, sign; /* form a constant.. */ ten[3]=0x0a; ten[1]=ten[2]=ten[0]=0; /* first skip white space... */ for (i=0; s[i]==' ' || s[i]=='\n' || s[i]=='\t'; i++); /* now get the sign... */ sign=1; if (s[i]=='+' || s[i]=='-') sign=(s[i++]=='+') ? 1 : -1; /* and convert the string straightforwardly... */ for (j=0; j<4; ++j) longint[j]=0; while (s[i]>='0' && s[i]<='9') { for (j=0; j<4; ++j) work[j]=0; work[3]=s[i++]-'0'; lmul(longint,ten,longint); ladd(longint,longint,work); } /* not forgetting the original sign... */ if (sign==-1) lneg(longint,longint); return longint; } /* ltoa converts the long integer longint to an ASCII string which is placed in s. If longint is negative a minus sign is prefixes the string. The algorithm used is an adaptation of itoa presented in Kernighan and Ritchie. */ ltoas(sptr,inlong,scale) char *sptr; char inlong[]; int scale; { int i, j; char work[20]; char *wptr,*fptr,*tptr; /* Special case - get rid of integers */ if (scale == 0) return(ltoa(sptr,inlong)); /* get the full string */ ltoa(work,inlong); wptr = &work[0]; /* minimum length */ if (*wptr == '-') j = scale + 3; else j = scale + 2; i = strlen(wptr) + 1; if (j < i) j = i; /* point at last digits */ fptr = &wptr[i-2]; tptr = sptr + j; *tptr-- = 0; while (scale--) if ((fptr < wptr) || (*fptr == '-')) *tptr-- = '0'; else *tptr-- = *fptr--; *tptr-- = '.'; if ((fptr < wptr) || (*fptr == '-')) *tptr-- = '0'; while (fptr >= wptr) *tptr-- = *fptr--; return (sptr); } ltoa(s,inlong) char s[], inlong[]; { char c, work[4], ten[4], longint[4]; int i, j, k, sign; ten[3]=0x0a; ten[1]=ten[2]=ten[0]=0; sign=1; for(i=0 ; i<4 ; i++) longint[i] = inlong[i]; /* check the sign... */ if (longint[0]>127) { sign=-1; lneg(longint,longint); } /* convert, generating digits backwards in s[]... */ i=0; do { lmod(work,longint,ten); s[i++]=work[3]+'0'; ldiv(longint,longint,ten); } while ((longint[0]|longint[1]|longint[2]| longint[3])!=0); /* postfix a minus sign if needed... */ if (sign==-1) s[i++]='-'; s[i]='\0'; /* and turn the whole thing around in place. */ k=strlen(s); for (i=0, j=k-1; i