PROCEDURE Castre(VAR asc: PACKED ARRAY [lo..hi: integer] OF char; VAR rea: real; VAR pos: integer); EXTERNAL; {*USER* CASTRE converts an input string of ASCII characters in ASC to a real number using a decimal (base 10) radix. The compiler determines whether this is single (4bytes) or double (8 bytes) precision real. At this time, we are compiling all Pascal-2 with the /DOUBLE switch, making all reals double precision. The real number is returned in REA. ASC must be a valid type0 or type1 string. POS specifies starting point in the string (array). Upon exit from this procedure, POS will be left pointing to the position of the terminating character or the end of the string, whichever comes first. Leading space or tab character(s) are ignored. The number will be considered negative if a leading "-" minus sign is encountered, and the number will be considered positive is a leading "+" plus sign or no sign at all is encountered. The plus or minus sign needs to precede the first ascii digit, but can be separated from that first digit by any number of (ignored) space or tab characters. Commas can be used in the conventional locations for thousands, millions, etc. If commas are used in the number, they must be in the conventional locations, or they will result in a conversion error. Conversion of the ascii string will continue until a terminator character is encountered or the end of the string is encountered. A terminator character will be any non digit that occurs after the first valid digit (0-9, or decimal point) character is encountered. Conventional commas imbedded in the number after the first valid digit and before the decimal point will not be considered terminator characters and will be ignored. A decimal point can be either explicit or implied. A decimal point will be implied if a terminator character is encountered after a valid digit, or the end of the string is encountered after a valid digit. IMPORTANT note - since we ignore commas embeeded in numbers preceding a decimal point, commas are not always terminator characters. Keep that in mind when more than one real number is in the ascii string. In cases where you will have multiple numbers in a string, and you wish to allow commas embedded in the number, it is recommended that you use explicit decimal points for all numbers, or use seperator (terminator) characters other than commas to eliminate any ambiguity. POS will be left pointing at the terminating character (or end of string + 1), so you may use it to go on to the next number. Thus you can parse strings like "34.5,+538.,456.334,891.345 -.884,,3.,45.4". Where no valid number is found before the next terminator (such as the ",," in the example), a value of zero will be returned. Remember that this routine handles arrays using the string conventions. The length of a type 0 string is determined by the 0 element of the array, and the length of a type 1 string is determined by the first null character in the string. Be careful if you use strings made up of left justified numbers with extra blank padding to the right of the number. The first blank encountered will act as the terminator. If you keep POS where it is and call CASTRE again, the remaining blanks will be read as another number and give you a zero. This is nice in that an all blank string like " " will return a value of zero. It does also mean that a string like "34.5 " will return a value of 34.5, the first time you call CASTRE, and if you do not alter POS, will return a 0, the second time you call CASTRE. Real numbers can vary from 1E-38 to 1E+38. We do check for overflow/underflow, and will signal that overflow/underflow would occur if the conversion were attempted by returning negative value of the terminator character position in POS. If misplaced commas or numbers without decimal points are used, a negative value will be returned in POS. Because the procedure cannot guess what was intended, the value of POS will be the negative value of the character position following the initial POS position supplied. Remember that single precision real numbers (4 bytes) will give you about 7 digits of precision while double precision real numbers (8 bytes) will give you about 15 digits of precision. *ERROR CODES* Normal errors can be detected by the returned value of POS. You can check the value of POS against the value you expected to determine if the conversion was complete. For example, if a string contains a single number to be converted, and there are no trailing blanks, POS should be returned with the same value as SLEN of that string. Likewise, if there are multiple numbers separated by commas in the string, you should get the expected number of values back by repeatedly calling CASTRE until POS is equal to SLEN of the string. POS must always advance by 2 or more for any reasonable number, since 1 digit plus a decimal point is a reasonable number. Use POS as the subscript into the string to verify that the desired separator character (like a comma or a space) was used. If POS points to something else, the proper separator was not used. If POS is negative, overflow or underflow occurred in the conversion, or misplaced commas or omitted decimal point made it impossible to interpret the number for a conversion. The following error messages can appear when using CASTRE. They normally indicate a programming error. SLEN is used to validate a type0 or type1 string. See SLEN for those errors. CASTRE -- Not type0/type1 or illegal postition: n (string in ASC not a valid type0 or type1 string, or string is an empty string, or value in POS in not within string lower and upper subscripts) }