int str$$lzerotrim (struct dsc$descriptor_s *sd1) { int i,j,count; char *s1_ptr; unsigned short s1_len; str$analyze_sdesc (sd1,&s1_len, &s1_ptr); i = 0; while ( (s1_ptr[i] == '0') && ( i < s1_len-1 ) ) // while leading zero { if (s1_ptr[i] == '0' ) // have leading zero { for (j = i; j < s1_len; j++) // shuffle string { s1_ptr[j] = s1_ptr[j+1]; } i=0; s1_len--; count--; } else { i++; } } // Resize descriptor if needed str$get1_dx (&s1_len, &*sd1); return count; }
unsigned int str$$resize(struct dsc$descriptor_s* dest, unsigned short size) { unsigned long result = STR$_NORMAL; unsigned short usize; int resize; usize = (unsigned short) size; /* * Generate the proper memory to store the result in. * Dependent on the type of string. */ switch(dest->dsc$b_class) { case DSC$K_CLASS_Z: case DSC$K_CLASS_S: case DSC$K_CLASS_SD: case DSC$K_CLASS_A: case DSC$K_CLASS_NCA: /* * We can't change the size of this. Live with * whatever we've got. */ if (dest->dsc$a_pointer == 0) { DOSIGNAL(STR$_FATINTERR); result = STR$_FATINTERR; } break; case DSC$K_CLASS_D: /* * Try to allocate a different size */ result = str$get1_dx(&usize, dest); break; case DSC$K_CLASS_VS: /* * Better be pointing at something */ if (dest->dsc$a_pointer == 0) { DOSIGNAL(STR$_FATINTERR); result = STR$_FATINTERR; } resize = min(dest->dsc$w_length, usize); *((unsigned short int*)dest->dsc$a_pointer) = resize; break; default: DOSIGNAL(STR$_ILLSTRCLA); result = STR$_ILLSTRCLA; } return result; }
int str$$rzerotrim (struct dsc$descriptor_s *sd1, long *exp) { int i, status; char *s1_ptr; unsigned short s1_len; status = str$analyze_sdesc (sd1,&s1_len, &s1_ptr); i = s1_len-1; while ( (s1_ptr[i] == '0') && (i > 0 ) ) { if (s1_ptr[i] == '0' ) { s1_ptr[i] = ' '; (*exp)++; s1_len--; } i--; } // Resize descriptor status = str$get1_dx (&s1_len, sd1); str$analyze_sdesc (sd1,&s1_len, &s1_ptr); return status; }
unsigned long str$mul (const unsigned long *asign, const long *aexp, const struct dsc$descriptor_s *adigits, const unsigned long *bsign, const long *bexp, const struct dsc$descriptor_s *bdigits, unsigned long *csign, long *cexp, struct dsc$descriptor_s *cdigits) { unsigned short s1_len, s2_len, s3_len, temp_len; char *s1_ptr, *s2_ptr, *s3_ptr; unsigned long index, max_len, min_len; int i,j,k; unsigned long status; int sum,carry; char *a,*b,*c; status = STR$_NORMAL; index = 0; a = (char *) calloc(MAXSTR,1); b = (char *) calloc(MAXSTR,1); c = (char *) calloc(MAXSTR,1); if ( a == NULL ) { status = STR$_INSVIRMEM; } if ( b == NULL ) { status = STR$_INSVIRMEM; } if ( c == NULL ) { status = STR$_INSVIRMEM; } // Check the sign field is 1 or 0 if ( *asign == 1 || *asign == 0 ) ; else status = LIB$_INVARG; if ( *bsign == 1 || *bsign == 0) ; else status = LIB$_INVARG; if (( *asign == 0 ) && ( *bsign == 0 )) *csign = 0; if (( *asign == 0 ) && ( *bsign == 1 )) *csign = 1; if (( *asign == 1 ) && ( *bsign == 0 )) *csign = 1; if (( *asign == 1 ) && ( *bsign == 1 )) *csign = 0; // Get the length of the input strings and how much room for the output str$analyze_sdesc (adigits, &s1_len, &s1_ptr); str$analyze_sdesc (bdigits, &s2_len, &s2_ptr); str$analyze_sdesc (cdigits, &s3_len, &s3_ptr); strcpy (s3_ptr,"0"); // Quick abort if (status != STR$_NORMAL) { return status; } // zero out the accumulator for (i=0; i < MAXSTR; i++ ) { a[i] = '0'; b[i] = '0'; c[i] = 0; } // Move in the largest number - we need to keep the alignment correct // char string is "right to left" alignment // start at location specified by the exponent max_len = ( s1_len > s2_len ) ? s1_len : s2_len; min_len = ( s1_len > s2_len) ? s2_len : s1_len; // Copy input strings to working storage for (i = 0; i < s1_len; i++ ) { a[i] = s1_ptr[i]; } for (i = 0; i < s2_len; i++ ) { b[i] = s2_ptr[i]; } // Set the output exponent *cexp = *aexp + *bexp; max_len = s1_len + s2_len; sum = 0; carry = 0; k = max_len; for (j = s2_len; j > 0; j--) { k = max_len - s2_len + j; for ( i = s1_len; i > 0; i-- ) { sum = ( b[j-1] - '0' ) * ( a[i-1] - '0'); sum += carry; carry = 0; c[k] += sum % 10; if (c[k] > 9 ) { c[k] -= 10; c[k-1] += 1; } sum -= sum % 10; carry = sum / 10; sum = 0; k--; } } c[k] = carry; // Truncate output sum string to 65536 MAXUINT16 if ( max_len > MAXUINT16 ) { status = STR$_TRU; max_len = MAXUINT16; } // Free any memory that is passed into us. str$free1_dx (cdigits); temp_len = (unsigned short) max_len + 1; str$get1_dx(&temp_len, cdigits); str$analyze_sdesc (cdigits,&s3_len, &s3_ptr); for (i = 0; i <= max_len; i++) { s3_ptr[i] = (c[i] + '0'); } free (a); free (b); free (c); str$$lzerotrim (cdigits); str$$rzerotrim (cdigits,cexp); str$$iszerotrim(cdigits,cexp); return status; }
unsigned long str$find_first_substring (const struct dsc$descriptor_s *s1, long *index, long *subindex, struct dsc$descriptor_s *sub, ...) { int i, status, result; long j; char *s1_ptr,*s2_ptr; struct dsc$descriptor_s *sd_ptr, temp_sd, temp2_sd; unsigned short s1_len, s2_len,temp_len; va_list ap; *index = 0; sd_ptr = 0; *subindex = 0; str$analyze_sdesc (s1,&s1_len,&s1_ptr); str$analyze_sdesc (sub,&s2_len,&s2_ptr); va_start(ap,sub); // make ap point to first unnamed arg sd_ptr = sub; do { ++*subindex; str$analyze_sdesc (sd_ptr,&s2_len,&s2_ptr); if ( (s1_len >= s2_len ) && (s2_len != 0 )) { for (i = 1; i < (s1_len - s2_len + 2); i++ ) { j = i; temp_len = s2_len; temp_sd.dsc$w_length = 0; temp_sd.dsc$b_class = DSC$K_CLASS_D; temp_sd.dsc$b_dtype = DSC$K_DTYPE_D; temp_sd.dsc$a_pointer = NULL; temp2_sd.dsc$w_length = 0; temp2_sd.dsc$b_class = DSC$K_CLASS_D; temp2_sd.dsc$b_dtype = DSC$K_DTYPE_D; temp2_sd.dsc$a_pointer = NULL; str$get1_dx (&temp_len,&temp_sd); str$get1_dx (&temp_len,&temp2_sd); str$right (&temp_sd,s1,&j); j = s2_len; str$left(&temp2_sd,&temp_sd,&j); result = str$compare(&temp2_sd,sd_ptr); str$free1_dx (&temp_sd); str$free1_dx (&temp2_sd); if (result == 0) { *index = i; i = s1_len - s2_len + 2; va_end(ap); return 1; } } } else { status = 0; } sd_ptr = va_arg(ap,struct dsc$descriptor_s *); } while ( sd_ptr != NULL ); va_end(ap); // clean up argument pointer *subindex = 0; // not found set back to zero return 0; }
void str$$malloc_sd(struct dsc$descriptor_s *temp_sd, char *string) { int i; unsigned short temp_len; char maxstring [MAXCSTR16], temp_string[5]; if ( strcmp(string,"NULL") == 0 ) { temp_sd->dsc$w_length = 0; temp_sd->dsc$b_class = DSC$K_CLASS_D; temp_sd->dsc$b_dtype = DSC$K_DTYPE_T; temp_sd->dsc$a_pointer = NULL; } // make the largest number possible 65535 9's else if ( strcmp(string,"MAXCSTR16") == 0 ) { for (i=0; i < MAXCSTR16; i++) maxstring[i] = '9'; temp_sd->dsc$w_length = 0; temp_sd->dsc$b_class = DSC$K_CLASS_D; temp_sd->dsc$b_dtype = DSC$K_DTYPE_T; temp_sd->dsc$a_pointer = NULL; temp_len = MAXCSTR16; str$get1_dx (&temp_len, temp_sd); str$copy_r (temp_sd, &temp_len, maxstring); } else if ( strcmp(string,"BLANK") == 0 ) { temp_sd->dsc$w_length = 0; temp_sd->dsc$b_class = DSC$K_CLASS_D; temp_sd->dsc$b_dtype = DSC$K_DTYPE_T; temp_sd->dsc$a_pointer = NULL; temp_len = 1; temp_string[0] = ' '; str$get1_dx (&temp_len, temp_sd); str$copy_r (temp_sd, &temp_len,temp_string); } else if ( strcmp(string,"TAB") == 0 ) { temp_sd->dsc$w_length = 0; temp_sd->dsc$b_class = DSC$K_CLASS_D; temp_sd->dsc$b_dtype = DSC$K_DTYPE_T; temp_sd->dsc$a_pointer = NULL; temp_len = 1; temp_string[0] = '\t'; str$get1_dx (&temp_len, temp_sd); str$copy_r (temp_sd, &temp_len,temp_string); } else { /* default action copy string value in */ temp_sd->dsc$w_length = 0; temp_sd->dsc$b_class = DSC$K_CLASS_D; temp_sd->dsc$b_dtype = DSC$K_DTYPE_T; temp_sd->dsc$a_pointer = NULL; temp_len = strlen (string); str$get1_dx (&temp_len, temp_sd); str$copy_r (temp_sd, &temp_len,string); } return; }
unsigned long str$add ( const unsigned long *asign, const long *aexp, const struct dsc$descriptor_s *adigits, const unsigned long *bsign, const long *bexp, const struct dsc$descriptor_s *bdigits, unsigned long *csign, long *cexp, struct dsc$descriptor_s *cdigits) { unsigned short s1_len, s2_len, s3_len, temp_len; char *s1_ptr, *s2_ptr, *s3_ptr; unsigned long index,max_len,min_len; int i,j,k; unsigned long status; signed long min_exp,max_exp, a_size, b_size, max_size, min_size; char ctemp; int sum,carry; char *a,*b,*c; status = STR$_NORMAL; index = 0; a = (char *) calloc(MAXSTR,1); b = (char *) calloc(MAXSTR,1); c = (char *) calloc(MAXSTR,1); if ( a == NULL ) { status = STR$_INSVIRMEM; } if ( b == NULL ) { status = STR$_INSVIRMEM; } if ( c == NULL ) { status = STR$_INSVIRMEM; } // Check the sign field is 1 or 0 if ( *asign == 1 || *asign == 0 ) ; else status = LIB$_INVARG; if ( *bsign == 1 || *bsign == 0) ; else status = LIB$_INVARG; // If we have a negative sign then call str$subtract // c = -a + b if (( *asign == 1 ) && (*bsign == 0 )) { status = str$sub(asign,aexp,adigits,bsign,bexp,bdigits,csign,cexp,cdigits); return status; } // c = a - b if (( *asign == 0 ) && (*bsign == 1 )) { status = str$sub(asign,aexp,adigits,bsign,bexp,bdigits,csign,cexp,cdigits); return status; } // c = -a + -b *csign = 0; if (( *asign == 1 ) && ( *bsign == 1)) { *csign = 1; } // Get the length of the input strings and how much room for the output str$analyze_sdesc (adigits, &s1_len, &s1_ptr); str$analyze_sdesc (bdigits, &s2_len, &s2_ptr); str$analyze_sdesc (cdigits, &s3_len, &s3_ptr); if ( s3_ptr != NULL ) { str$free1_dx (cdigits); printf ("Destination must be NULL\n"); return STR$_FATINTERR; } // Quick abort if (status != STR$_NORMAL) { return status; } // Move in the largest number - we need to keep the alignment correct // char string is "right to left" alignment // start at location specified by the exponent max_exp = ( *aexp > *bexp ) ? *aexp : *bexp; // get largest exp min_exp = ( *aexp > *bexp ) ? *bexp : *aexp; max_len = ( s1_len > s2_len ) ? s1_len : s2_len; min_len = ( s1_len > s2_len) ? s2_len : s1_len; a_size = ( *aexp + s1_len ); b_size = ( *bexp + s2_len ); max_size= ( a_size > b_size ) ? a_size : b_size; min_size= ( a_size > b_size ) ? b_size : a_size; // The strings don't overlap just return the largest if ( max_size - min_size > UINT16_MAX ) { //Don't Overlap returning largest if ( *aexp > *bexp ) { *cexp = *aexp; str$copy_dx (cdigits,adigits); } else { *cexp = *bexp; str$copy_dx(cdigits,bdigits); } return STR$_TRU; } // Copy input strings to working storage for (i = 0; i < s1_len; i++ ) { a[i] = s1_ptr[i]; } for (j = 0; j < s2_len; j++ ) { b[j] = s2_ptr[j]; } // Set the output exponent *cexp = min_exp; // Add zero's to the end of the number for remaining exponent if ( *aexp > *bexp ) { for ( i = s1_len; i < s1_len + max_exp - min_exp; i++) a[i] = '0'; s1_len += max_exp - min_exp; } if ( *aexp < *bexp ) { for ( i = s2_len; i < s2_len + max_exp - min_exp; i++) b[i] = '0'; s2_len += max_exp - min_exp; } sum = 0; carry = 0; ctemp = '0'; i = s1_len; j = s2_len; // New max string length max_len = ( s1_len > s2_len ) ? s1_len : s2_len ; for (k =(int) max_len; k > 0; k-- ) { if ( i > 0 ) { sum += a[i-1] - '0'; } if ( j > 0 ) { sum += b[j-1] - '0'; } sum += carry; carry = 0; if ( sum > 9 ) { carry = 1; sum -= 10; } ctemp = sum + '0'; sum = 0; c[k-1] = ctemp; i--; j--; } if ( carry == 1 ) { for (i = max_len-1; i >= 0; i-- ) { c[i+1] = c[i]; } c[0] = (char) (carry + '0'); max_len++; } // Truncate output sum string to 65536 MAXUINT16 if ( max_len > MAXUINT16 ) { status = STR$_TRU; max_len = MAXUINT16; } // Free any memory that is passed into us. temp_len = max_len; str$free1_dx(cdigits); str$get1_dx(&temp_len,cdigits); str$analyze_sdesc (cdigits,&s3_len,&s3_ptr); for (i = 0; i < max_len; i++) { s3_ptr[i] = c[i]; } free (a); free (b); free (c); str$$lzerotrim (&*cdigits); str$$rzerotrim (&*cdigits,&*cexp); str$$iszerotrim (&*cdigits,&*cexp); return status; }