/* * Copyright (C) 1995-1997 Christopher D. Granz * * This header may not be removed. * * Refer to the file "License" included in this package for further * information and before using any of the following. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <limits.h> #include "sapphire.h" /* * Functions */ static int _compar( const void *p1, const void *p2 ) { char *pStr1 = *( (char **) p1 ); char *pStr2 = *( (char **) p2 ); char c1; char c2; int iResult = 0; int i; for ( i = 0; pStr1[i] != '\0' && pStr2[i] != '\0'; i++ ) { c1 = UPPER( pStr1[i] ); c2 = UPPER( pStr2[i] ); if ( ( iResult = ( c1 > c2 ? 1 : ( c1 < c2 ? -1 : 0 ) ) ) ) break; } return ( iResult ); } /* * Performs an alphabetacal sort on an array of strings (char pointers.) */ char **asort( char **ppSort, int iNumEle ) { if ( iNumEle > 0 ) qsort( ppSort, iNumEle, sizeof( char * ), &_compar ); return ( ppSort ); } char *sone_arg( char *pList, char *pArg ) { static char cOutput[MAX_STRING]; int i, iPos, iOPos; i = 0; iPos = 0; iOPos = 0; while ( isspace( pList[iPos] ) != 0 ) iPos++; do { if ( pList[iPos] == '\0' || i >= ( MAX_INPUT - 1 ) ) break; pArg[i++] = pList[iPos++]; } while ( isspace( pList[iPos] ) == 0 ); pArg[i] = '\0'; while ( isspace( pList[iPos] ) != 0 ) iPos++; while ( pList[iPos] != '\0' && iOPos < ( MAX_INPUT - 1 ) ) cOutput[iOPos++] = pList[iPos++]; cOutput[iOPos] = '\0'; return ( cOutput ); } /* * Get the first word from a list. */ char *one_arg( char *pList, char *pArg ) { char *pOutput = new_buffer( ); int i, iPos, iOPos; i = 0; iPos = 0; iOPos = 0; while ( isspace( pList[iPos] ) != 0 ) iPos++; do { if ( pList[iPos] == '\0' || i >= ( MAX_INPUT - 1 ) ) break; pArg[i++] = pList[iPos++]; } while ( isspace( pList[iPos] ) == 0 ); pArg[i] = '\0'; while ( isspace( pList[iPos] ) != 0 ) iPos++; while ( pList[iPos] != '\0' && iOPos < ( MAX_INPUT - 1 ) ) pOutput[iOPos++] = pList[iPos++]; pOutput[iOPos] = '\0'; return ( pOutput ); } char *one_arg_2( char *pList, char *pArg ) { int i, iPos, iOPos; i = 0; iPos = 0; iOPos = 0; while ( isspace( pList[iPos] ) != 0 ) iPos++; do { if ( pList[iPos] == '\0' || i >= ( MAX_INPUT - 1 ) ) break; pArg[i++] = pList[iPos++]; } while ( isspace( pList[iPos] ) == 0 ); pArg[i] = '\0'; while ( isspace( pList[iPos] ) != 0 ) iPos++; return ( &pList[iPos] ); } char *sedit_str( char *pList, char *pStr, char c1, char *p1 ) { static char cOutput[MAX_STRING]; int i, i2, iPos = 0; bool b; while ( isspace( pList[iPos] ) ) iPos++; if ( pList[iPos] == c1 ) iPos++; while ( isspace( pList[iPos] ) ) iPos++; for ( i = 0; ; i++, iPos++ ) { if ( i >= MAX_STRING ) goto warning; for ( b = FALSE, i2 = 0; p1[i2] != '\0'; i2++ ) { if ( pList[iPos] == p1[i2] ) { b = TRUE; break; } } if ( b == TRUE || pList[iPos] == '\0' ) break; pStr[i] = pList[iPos]; } pStr[i] = '\0'; while ( isspace( pList[iPos] ) ) iPos++; for ( i = 0; ; i++, iPos++ ) { if ( i >= MAX_STRING ) goto warning; if ( pList[iPos] == '\0' ) break; cOutput[i] = pList[iPos]; } cOutput[i] = '\0'; return ( cOutput ); warning: pStr[0] = '\0'; wcwarning( "Parse string: String too long." ); return ( EMPTY_STRING ); } /* * Copys pList into pStr until the character is equal to one of the * characters in p1. If the first character is c1, it will be skiped. * Returns what is left on pList (including the terminating character). * Basicly this is more complex version of one_arg(). */ char *edit_str( char *pList, char *pStr, char c1, char *p1 ) { char *pOutput = new_buffer( ); int i, i2, iPos = 0; bool b; while ( isspace( pList[iPos] ) ) iPos++; if ( pList[iPos] == c1 ) iPos++; while ( isspace( pList[iPos] ) ) iPos++; for ( i = 0; ; i++, iPos++ ) { if ( i >= MAX_STRING ) goto warning; for ( b = FALSE, i2 = 0; p1[i2] != '\0'; i2++ ) { if ( pList[iPos] == p1[i2] ) { b = TRUE; break; } } if ( b == TRUE || pList[iPos] == '\0' ) break; pStr[i] = pList[iPos]; } pStr[i] = '\0'; while ( isspace( pList[iPos] ) ) iPos++; for ( i = 0; ; i++, iPos++ ) { if ( i >= MAX_STRING ) goto warning; if ( pList[iPos] == '\0' ) break; pOutput[i] = pList[iPos]; } pOutput[i] = '\0'; return ( pOutput ); warning: pStr[0] = '\0'; wcwarning( "Parse string: String too long." ); return ( EMPTY_STRING ); } char *edit_str_2( char *pList, char *pStr, char c1, char *p1 ) { int i, i2, iPos = 0; bool b; while ( isspace( pList[iPos] ) ) iPos++; if ( pList[iPos] == c1 ) iPos++; while ( isspace( pList[iPos] ) ) iPos++; for ( i = 0; ; i++, iPos++ ) { if ( i >= MAX_STRING ) goto warning; for ( b = FALSE, i2 = 0; p1[i2] != '\0'; i2++ ) { if ( pList[iPos] == p1[i2] ) { b = TRUE; break; } } if ( b == TRUE || pList[iPos] == '\0' ) break; pStr[i] = pList[iPos]; } pStr[i] = '\0'; while ( isspace( pList[iPos] ) ) iPos++; return ( &pList[iPos] ); warning: pStr[0] = '\0'; wcwarning( "Parse string: String too long." ); return ( EMPTY_STRING ); } char *sedit_str_plus( char *pList, char *pStr, char c1, char c2 ) { static char cOutput[MAX_STRING]; char c; char cQuote = '\0'; int i, iPos = 0; int iCount = 0; while ( isspace( pList[iPos] ) ) iPos++; if ( pList[iPos] == c1 ) { iCount++; iPos++; } for ( i = 0; ; i++, iPos++ ) { if ( i >= MAX_STRING ) goto warning; c = pList[iPos]; if ( c == '\0' ) break; switch ( c ) { case '"' : if ( cQuote == '\0' ) cQuote = '"'; else if ( cQuote != '\'' ) cQuote = '\0'; break; case '\'': if ( cQuote == '\0' ) cQuote = '\''; else if ( cQuote != '"' ) cQuote = '\0'; break; case '\n': case '\r': case '\t': if ( cQuote != '\0' ) c = ' '; break; case '\\': if ( cQuote != '\0' ) { iPos++; switch ( ( c = pList[iPos] ) ) { case '\0': case '\\': case '"' : case '\'': break; default : c = '\\'; break; } } default : break; } if ( cQuote == '\0' ) { if ( c == c2 ) { if ( iCount != 0 ) { iCount--; if ( iCount == 0 ) break; } else break; } else if ( c == c1 ) iCount++; } pStr[i] = c; } pStr[i] = '\0'; for ( i = 0; ; i++, iPos++ ) { if ( i >= MAX_STRING ) goto warning; if ( pList[iPos] == '\0' ) break; cOutput[i] = pList[iPos]; } cOutput[i] = '\0'; return ( cOutput ); warning: pStr[0] = '\0'; wcwarning( "Parse string: String too long." ); return ( EMPTY_STRING ); } /* * Closely related to edit_str(). Copys pList into pStr from c1 to c2. * Will skip nested forms of c1 and c2. Example: * * char cBuf[100]; * char *pReturnStr; * char *pStr = "[Parse [nested] test] ... garbage ..."; * * pReturnStr = edit_str_plus( pStr, cBuf, '[', ']' ); * * The result would be that pReturnStr is equal to "... garbage ..." and * cBuf is equal to "[Parse [nested] test]". pStr would remain unchanged. */ char *edit_str_plus( char *pList, char *pStr, char c1, char c2 ) { char *pOutput = new_buffer( ); char c; char cQuote = '\0'; int i, iPos = 0; int iCount = 0; while ( isspace( pList[iPos] ) ) iPos++; if ( pList[iPos] == c1 ) { iCount++; iPos++; } for ( i = 0; ; i++, iPos++ ) { if ( i >= MAX_STRING ) goto warning; c = pList[iPos]; if ( c == '\0' ) break; switch ( c ) { case '"' : if ( cQuote == '\0' ) cQuote = '"'; else if ( cQuote != '\'' ) cQuote = '\0'; break; case '\'': if ( cQuote == '\0' ) cQuote = '\''; else if ( cQuote != '"' ) cQuote = '\0'; break; case '\n': case '\r': case '\t': if ( cQuote != '\0' ) c = ' '; break; case '\\': if ( cQuote != '\0' ) { iPos++; switch ( ( c = pList[iPos] ) ) { case '\0': case '\\': case '"' : case '\'': break; default : c = '\\'; break; } } default : break; } if ( cQuote == '\0' ) { if ( c == c2 ) { if ( iCount != 0 ) { iCount--; if ( iCount == 0 ) break; } else break; } else if ( c == c1 ) iCount++; } pStr[i] = c; } pStr[i] = '\0'; for ( i = 0; ; i++, iPos++ ) { if ( i >= MAX_STRING ) goto warning; if ( pList[iPos] == '\0' ) break; pOutput[i] = pList[iPos]; } pOutput[i] = '\0'; return ( pOutput ); warning: pStr[0] = '\0'; wcwarning( "Parse string: String too long." ); return ( EMPTY_STRING ); } char *edit_str_plus_2( char *pList, char *pStr, char c1, char c2 ) { char c; char cQuote = '\0'; int i, iPos = 0; int iCount = 0; while ( isspace( pList[iPos] ) ) iPos++; if ( pList[iPos] == c1 ) { iCount++; iPos++; } for ( i = 0; ; i++, iPos++ ) { if ( i >= MAX_STRING ) goto warning; c = pList[iPos]; if ( c == '\0' ) break; switch ( c ) { case '"' : if ( cQuote == '\0' ) cQuote = '"'; else if ( cQuote != '\'' ) cQuote = '\0'; break; case '\'': if ( cQuote == '\0' ) cQuote = '\''; else if ( cQuote != '"' ) cQuote = '\0'; break; case '\n': case '\r': case '\t': if ( cQuote != '\0' ) c = ' '; break; case '\\': if ( cQuote != '\0' ) { iPos++; switch ( ( c = pList[iPos] ) ) { case '\0': case '\\': case '"' : case '\'': break; default : c = '\\'; break; } } default : break; } if ( cQuote == '\0' ) { if ( c == c2 ) { if ( iCount != 0 ) { iCount--; if ( iCount == 0 ) break; } else break; } else if ( c == c1 ) iCount++; } pStr[i] = c; } pStr[i] = '\0'; return ( &pList[iPos] ); warning: pStr[0] = '\0'; wcwarning( "Parse string: String too long." ); return ( EMPTY_STRING ); } char *smake_string( char *pList, char *pStr ) { static char cOutput[MAX_STRING]; int i; while ( isspace( *pList ) ) pList++; if ( *pList != '"' ) { sap_warning( "Parse string: Symbol `\"' not found." ); return ( EMPTY_STRING ); } if ( *( ++pList ) == '"' ) return ( EMPTY_STRING ); for ( i = 0; ; i++, pList++ ) { if ( i >= MAX_STRING ) goto warning; if ( *pList == '\\' ) { switch ( *( ++pList ) ) { case '\\': pStr[i] = '\\'; break; case '"' : pStr[i] = '"'; break; case 'n' : pStr[i] = '\n'; break; case 'r' : pStr[i] = '\r'; break; case 't' : pStr[i] = '\t'; break; case 'a' : pStr[i] = '\a'; break; case '\0': sap_warning( "Parse string: Incomplete escape." ); break; default : sap_warning( "Parse string: Unknown escape '\\%c'.", *pList ); break; } } else if ( *pList != '\n' && *pList != '\r' && *pList != '\t' && *pList != '"' ) pStr[i] = *pList; else i--; if ( *pList == '\0' ) { sap_warning( "Parse string: Symbol `\"' not found." ); break; } if ( *pList == '"' ) break; } pStr[i + 1] = '\0'; for ( i = 0; *pList != '\0'; i++ ) { if ( i >= MAX_STRING ) goto warning; cOutput[i] = *pList++; } cOutput[i] = '\0'; return ( cOutput ); warning: pStr[0] = '\0'; sap_warning( "Parse string: String too long." ); return ( EMPTY_STRING ); } char *make_string( char *pList, char *pStr ) { char *pOutput = new_buffer( ); int i; while ( isspace( *pList ) ) pList++; if ( *pList != '"' ) { sap_warning( "Parse string: Symbol `\"' not found." ); return ( EMPTY_STRING ); } if ( *( ++pList ) == '"' ) return ( EMPTY_STRING ); for ( i = 0; ; i++, pList++ ) { if ( i >= MAX_STRING ) goto warning; if ( *pList == '\\' ) { switch ( *( ++pList ) ) { case '\\': pStr[i] = '\\'; break; case '"' : pStr[i] = '"'; break; case 'n' : pStr[i] = '\n'; break; case 'r' : pStr[i] = '\r'; break; case 't' : pStr[i] = '\t'; break; case 'a' : pStr[i] = '\a'; break; case '\0': sap_warning( "Parse string: Incomplete escape." ); break; default : sap_warning( "Parse string: Unknown escape '\\%c'.", *pList ); break; } } else if ( *pList != '\n' && *pList != '\r' && *pList != '\t' && *pList != '"' ) pStr[i] = *pList; else i--; if ( *pList == '\0' ) { sap_warning( "Parse string: Symbol `\"' not found." ); break; } if ( *pList == '"' ) break; } pStr[i + 1] = '\0'; for ( i = 0; *pList != '\0'; i++ ) { if ( i >= MAX_STRING ) goto warning; pOutput[i] = *pList++; } pOutput[i] = '\0'; return ( pOutput ); warning: pStr[0] = '\0'; sap_warning( "Parse string: String too long." ); return ( EMPTY_STRING ); } char *make_string_2( char *pList, char *pStr ) { int i; while ( isspace( *pList ) ) pList++; if ( *pList != '"' ) { sap_warning( "Parse string: Symbol `\"' not found." ); return ( EMPTY_STRING ); } if ( *( ++pList ) == '"' ) return ( EMPTY_STRING ); for ( i = 0; ; i++, pList++ ) { if ( i >= MAX_STRING ) goto warning; if ( *pList == '\\' ) { switch ( *( ++pList ) ) { case '\\': pStr[i] = '\\'; break; case '"' : pStr[i] = '"'; break; case 'n' : pStr[i] = '\n'; break; case 'r' : pStr[i] = '\r'; break; case 't' : pStr[i] = '\t'; break; case 'a' : pStr[i] = '\a'; break; case '\0': sap_warning( "Parse string: Incomplete escape." ); break; default : sap_warning( "Parse string: Unknown escape '\\%c'.", *pList ); break; } } else if ( *pList != '\n' && *pList != '\r' && *pList != '\t' && *pList != '"' ) pStr[i] = *pList; else i--; if ( *pList == '\0' ) { sap_warning( "Parse string: Symbol `\"' not found." ); break; } if ( *pList == '"' ) break; } pStr[i + 1] = '\0'; return ( pList ); warning: pStr[0] = '\0'; sap_warning( "Parse string: String too long." ); return ( EMPTY_STRING ); } /* * Flips a string. */ char *flip_string( char *pStr ) { char *pOutput = new_buffer( ); int i, iEnd = ( strlen( pStr ) - 1 ); for ( i = 0; iEnd < 0; i++, iEnd-- ) pOutput[i] = pStr[iEnd]; pOutput[i] = '\0'; return ( pOutput ); } /* * Returns the next character in a string. */ char next_char( char *pStr ) { int iPos = 0; while ( isspace( pStr[iPos] ) ) iPos++; return ( pStr[iPos] ); } /* * Removes the first character of a string and copys the rest into * a new buffer. */ char *remove_char( char *pStr ) { char *pOutput = new_buffer( ); int i, iPos = 0; while ( isspace( pStr[iPos] ) ) iPos++; if ( pStr[iPos] == '\0' ) return ( EMPTY_STRING ); for ( i = 0, iPos++; pStr[iPos] != '\0'; i++, iPos++ ) { if ( i >= MAX_STRING ) { wcwarning( "Parse string: String too long." ); return ( EMPTY_STRING ); } pOutput[i] = pStr[iPos]; } pOutput[i] = '\0'; return ( pOutput ); } char *remove_char_2( char *pStr ) { int i = 0; while ( isspace( pStr[i] ) ) i++; if ( pStr[i] == '\0' ) return ( &pStr[i] ); return ( &pStr[++i] ); } /* * Removes the spaces from the beginning and the end * of a string. */ char *remove_spaces( char *pStr ) { char *pOutput = new_buffer( ); char cBuf[MAX_STRING]; int i, i2, iPos = 0; while ( isspace( pStr[iPos] ) ) iPos++; for ( i = 0; pStr[iPos] != '\0'; i++, iPos++ ) { if ( i >= MAX_STRING ) goto warning; cBuf[i] = pStr[iPos]; } cBuf[i] = '\0'; for ( i2 = ( strlen( cBuf ) - 1 ); isspace( cBuf[i2] ); i2-- ); for ( i = 0; i <= i2; i++ ) { if ( i >= MAX_STRING ) goto warning; pOutput[i] = cBuf[i]; } pOutput[i] = '\0'; return ( pOutput ); warning: wcwarning( "Parse string: String too long." ); return ( EMPTY_STRING ); } /* * Removes all newlines/carriage returns from a string. */ char *remove_nls( char *pStr ) { char *pOutput = new_buffer( ); int i; for ( i = 0; pStr[i] != '\0'; i++ ) { if ( pStr[i] == '\n' || pStr[i] == '\r' ) pOutput[i] = ' '; else pOutput[i] = pStr[i]; } pOutput[i] = '\0'; return ( pOutput ); } char *capit( char *pStr ) { char *pOutput = new_buffer( ); int i; for ( i = 0; pStr[i] != '\0'; i++ ) pOutput[i] = LOWER( pStr[i] ); pOutput[i] = '\0'; pOutput[0] = UPPER( pOutput[0] ); return ( pOutput ); } char *uncapit( char *pStr ) { char *pOutput = new_buffer( ); int i; for ( i = 0; pStr[i] != '\0'; i++ ) pOutput[i] = LOWER( pStr[i] ); pOutput[i] = '\0'; return ( pOutput ); } char *cap_first( char *pStr ) { char *pOutput = new_buffer( ); int i; for ( i = 0; pStr[i] != '\0'; i++ ) pOutput[i] = pStr[i]; pOutput[i] = '\0'; pOutput[0] = UPPER( pOutput[0] ); return ( pOutput ); } /* * End of parse.c */