/* **++ ** FACILITY: SCA Example ** ** MODULE DESCRIPTION: ** ** This module contains the function expand_string. ** ** AUTHORS: ** ** John ** ** CREATION DATE: 7-Aug-1991 ** ** DESIGN ISSUES: ** ** None ** ** MODIFICATION HISTORY: ** ** {@tbs@}... **-- */ /* ** ** INCLUDE FILES ** */ #include #include #include #include "types.h" extern int trnlit__conatend, trnlit__escatend, trnlit__badescape, trnlit__dashatbeg, trnlit__dashatend, trnlit__rangorder, trnlit__rangerror; /* **++ ** FUNCTIONAL DESCRIPTION: ** ** Convert translation strings to vectors. ** ** expand_string takes the translation strings as specified by the user, ** including special syntax for control characters, ranges, and special ** characters, and converts them to simple vectors of characters. ** ** Expand the string str into the code vector codes, of length ncodes. ** It is assumed that an initial "-" has been stripped from str. If ** expand_string is successful, it will return 1. Otherwise, it will ** return a condition code, and return textual error information in ** error_text. ** ** Note that no error code is returned if the code vector overflows. This ** is because this will result in a more informative error later - either ** "Duplicated code in original string", or "Replacement string is longer ** than original string". ** ** FORMAL PARAMETERS: ** ** str: ** The original string as specified by the user. ** ** codes: ** The resulting code vector. ** ** ncodes: ** The length of the resulting code vector. ** ** error_text: ** If there's an error, textual information will be put into this ** parameter. ** ** RETURN VALUE: ** ** If successful, then 1. ** If not, then a condition code. ** ** SIDE EFFECTS: ** ** None ** ** DESIGN: ** ** We use a single while loop to step through all the characters in the ** original string, and a compound if statement to perform an action ** appropriate to each character. It is possible for individual actions ** to consume more characters; thus, the index variable i, which is one of ** the control variables for the while loop, is incremented in more than ** one place. ** **-- */ int expand_string ( param_string str, code_vector codes, code_vector_length *ncodes, param_string error_text) { int i; char c; code_value cod; int status; /* ** Initialize variables. */ status = 1; /* Assume success. */ error_text = ""; i = 0; *ncodes = 0; /* ** Loop through the string, as long as we have no errors, and don't ** process more than code_vector_limit number of resulting characters. */ while ((i != strlen(str)) && (status == 1) && (*ncodes != code_vector_limit)) { /* ** Increment i and get next character. */ i = i + 1; c = str[i]; /* ** Parse the current character. */ if (c == '^') { /* ** Process a control character code: ^X. */ if (i == strlen(str)) { /* ** No more characters. Indicate an error. */ status = trnlit__conatend; } else { /* ** Got it. Set the corresponding control character (low 5 ** bits). */ *ncodes = *ncodes + 1; codes[*ncodes] = str[i+1] & 31; i = i + 1; } } else if (c == '@') { /* ** Process an escaped code: @X. */ if (i == strlen(str)) { /* ** No more characters - indicate an error. */ status = trnlit__escatend; } else { /* ** There is one. Get it and parse it. */ i = i + 1; switch (str[i]) { case 'b': case 'B': cod = 8; /* Backspace */ case 't': case 'T': cod = 9; /* Tab */ case 'd': case 'D': cod = del_code; /* Delete */ case 'n': case 'N': cod = newline; /* Newline */ case '@': case '-': case '^': cod = str[i]; /* Escaped literal character */ default: status = trnlit__badescape; error_text = malloc (2); strncpy (error_text, &str[i], 1); cod = 0; } *ncodes = *ncodes + 1; codes[*ncodes] = cod; } } else if (c == '-') { /* ** Process a character range. */ if (i == 1) { /* ** The hyphen is the first character. Indicate that error. */ status = trnlit__dashatbeg; } else if (i == strlen(str)) { /* ** The hyphen is the last character. Indicate an error. */ status = trnlit__dashatend; } else if ( (isupper (str[i-1]) && isupper (str[i+1]) ) || (islower (str[i-1]) && islower (str[i+1]) ) || (isdigit (str[i-1]) && isdigit (str[i+1]) ) ) { /* ** Make sure the characters for the range are in ascending ** order. */ if (str[i-1] > str[i+1]) { /* ** They're in descending order. Indicate an error. */ status = trnlit__rangorder; error_text = malloc (4); strncpy (error_text, &str[i-1], 3); } else { /* ** They're ok. Set all corresponding values in the vector ** appropriately. */ c = str[i-1]; i = i + 1; while ((c != str[i]) && (*ncodes != code_vector_limit)) { *ncodes = *ncodes + 1; c = c + 1; codes[*ncodes] = c; } } } else { /* ** The range is invalid. Indicate an error. */ status = trnlit__rangerror; error_text = malloc (4); strncpy (error_text, &str[i-1], 3); } } else { /* ** Include a normal character in the string. */ *ncodes = *ncodes + 1; codes[*ncodes] = c; } } return status; }