/*@z39.c:String Handler:AsciiToFull(), StringEqual(), etc.@*******************/
/* */
/* THE LOUT DOCUMENT FORMATTING SYSTEM (VERSION 3.41) */
/* COPYRIGHT (C) 1991, 2023 Jeffrey H. Kingston */
/* */
/* Jeffrey H. Kingston (jeff@it.usyd.edu.au) */
/* School of Information Technologies */
/* The University of Sydney 2006 */
/* AUSTRALIA */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either Version 3, or (at your option) */
/* any later version. */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program; if not, write to the Free Software */
/* Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307 USA */
/* */
/* FILE: z39.c */
/* MODULE: String Handler */
/* EXTERNS: AsciiToFull(), StringEqual(), */
/* StringCat(), StringCopy(), StringLength(), */
/* StringFOpen(), StringFPuts(), StringRemove(), */
/* StringRename(), StringBeginsWith(), StringContains(), */
/* StringInt(), StringFiveInt(), StringQuotedWord() */
/* */
/*****************************************************************************/
#include "externs.h"
/*****************************************************************************/
/* */
/* AsciiToFull(str) Returns ASCII string as FULL_CHARs. */
/* BOOLEAN StringEqual(a, b) TRUE if strings a and b are equal */
/* StringCat(a, b) Catenate string b onto end of a */
/* StringCopy(a, b) Overwrite string a with string b */
/* StringLength(a) Length of string a */
/* StringFOpen(str, mode) Equivalent to fopen(str, mode) */
/* StringFPuts(str, fp) Equivalent to fputs(str, fp) */
/* StringRemove(a) Equivalent to remove(a) */
/* StringRename(a, b) Equivalent to rename(a, b) */
/* */
/* These procedures are defined as macros in file externs. */
/* */
/*****************************************************************************/
/*****************************************************************************/
/* */
/* int strcollcmp(char *a, char *b) */
/* */
/* Written by Valery Ushakov (uwe). */
/* */
/* Like strcoll, but returns 0 only iff strcmp returns 0. */
/* This allow to test for equality using only strcmp. --uwe */
/* */
/* The new version of strcollcmp analyses a and b into three fields */
/* separated by \t, then does the comparison field by field. This is */
/* to ensure that the collation order of \t has no effect on the result. */
/* */
/*****************************************************************************/
/* *** old version
int strcollcmp(char *a, char *b)
{
int order = strcoll (a, b);
if( order == 0 ) / * then disambiguate with strcmp * /
order = strcmp (a, b);
return order;
}
*** */
int strcollcmp(char *a, char *b)
{ char a1[MAX_BUFF], a2[MAX_BUFF], a3[MAX_BUFF];
char b1[MAX_BUFF], b2[MAX_BUFF], b3[MAX_BUFF];
int order;
a1[0] = a2[0] = a3[0] = '\0';
sscanf(a, "%[^\t]\t%[^\t]\t%[^\t]", a1, a2, a3);
b1[0] = b2[0] = b3[0] = '\0';
sscanf(b, "%[^\t]\t%[^\t]\t%[^\t]", b1, b2, b3);
order = strcoll(a1, b1);
if( order == 0 )
{
order = strcoll(a2, b2);
if( order == 0 )
{
order = strcoll(a3, b3);
if( order == 0 )
order = strcmp(a, b); /* disambiguate with strcmp */
}
}
debug7(DBS, D, "strcollcmp(\"%s<tab>%s<tab>%s\", \"%s<tab>%s<tab>%s\") = %d",
a1, a2, a3, b1, b2, b3, order);
return order;
}
/*@::StringBeginsWith(), StringContains(), StringInt(), StringFiveInt()@******/
/* */
/* BOOLEAN StringBeginsWith(str, pattern) */
/* BOOLEAN StringBeginsWithWord(str, pattern) */
/* BOOLEAN StringEndsWith(str, pattern) */
/* */
/* Check whether str begins with or ends with pattern; in the case of */
/* StringBeginsWithWord there may not be a letter after the pattern. */
/* */
/*****************************************************************************/
BOOLEAN StringBeginsWith(FULL_CHAR *str, FULL_CHAR *pattern)
{ FULL_CHAR *sp, *pp;
sp = str; pp = pattern;
while( *sp != '\0' && *pp != '\0' )
{ if( *sp++ != *pp++ ) return FALSE;
}
return (*pp == '\0');
} /* end StringBeginsWith */
#define is_letter(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z'))
BOOLEAN StringBeginsWithWord(FULL_CHAR *str, FULL_CHAR *pattern)
{ FULL_CHAR *sp, *pp;
sp = str; pp = pattern;
while( *sp != '\0' && *pp != '\0' )
{ if( *sp++ != *pp++ ) return FALSE;
}
return (*pp == '\0' && !is_letter(*sp));
} /* end StringBeginsWithWord */
BOOLEAN StringEndsWith(FULL_CHAR *str, FULL_CHAR *pattern)
{ FULL_CHAR *sp, *pp; int slen, plen;
slen = StringLength(str);
plen = StringLength(pattern);
if( slen < plen ) return FALSE;
sp = &str[slen - plen]; pp = pattern;
while( *sp != '\0' && *pp != '\0' )
{ if( *sp++ != *pp++ ) return FALSE;
}
return (*pp == '\0');
} /* end StringBeginsWith */
/*****************************************************************************/
/* */
/* BOOLEAN StringContains(str, pattern) */
/* */
/* Check whether str contains pattern. */
/* */
/*****************************************************************************/
BOOLEAN StringContains(FULL_CHAR *str, FULL_CHAR *pattern)
{ FULL_CHAR *sp;
for( sp = str; *sp != '\0'; sp++ )
{ if( StringBeginsWith(sp, pattern) ) return TRUE;
}
return FALSE;
} /* end StringContains */
/*****************************************************************************/
/* */
/* FULL_CHAR *StringInt(i) */
/* FULL_CHAR *StringFiveInt(i) */
/* */
/* Returns a string version of integer i. */
/* */
/*****************************************************************************/
FULL_CHAR *StringInt(int i)
{ static FULL_CHAR buff[20];
sprintf( (char *) buff, "%d", i);
return buff;
} /* end StringInt */
FULL_CHAR *StringFiveInt(int i)
{ static FULL_CHAR buff[20];
sprintf( (char *) buff, "%.5d", i);
return buff;
} /* end StringInt */
/*@::StringQuotedWord()@******************************************************/
/* */
/* static char *quoted_string[] */
/* */
/* quoted_string[ch] is a string containing the representation of the */
/* 8-bit character ch within a quoted string in a Lout source file. */
/* */
/*****************************************************************************/
static char *quoted_string[] = {
"\\000", "\\001", "\\002", "\\003", "\\004", "\\005", "\\006", "\\007",
"\\010", "\\011", "\\012", "\\013", "\\014", "\\015", "\\016", "\\017",
"\\020", "\\021", "\\022", "\\023", "\\024", "\\025", "\\026", "\\027",
"\\030", "\\031", "\\032", "\\033", "\\034", "\\035", "\\036", "\\037",
" ", "!", "\\\"", "#", "$", "%", "&", "'",
"(", ")", "*", "+", ",", "-", ".", "/",
"0", "1", "2", "3", "4", "5", "6", "7",
"8", "9", ":", ";", "<", "=", ">", "?",
"@", "A", "B", "C", "D", "E", "F", "G",
"H", "I", "J", "K", "L", "M", "N", "O",
"P", "Q", "R", "S", "T", "U", "V", "W",
"X", "Y", "Z", "[", "\\\\", "]", "^", "_",
"`", "a", "b", "c", "d", "e", "f", "g",
"h", "i", "j", "k", "l", "m", "n", "o",
"p", "q", "r", "s", "t", "u", "v", "w",
"x", "y", "z", "{", "|", "}", "~", "\\177",
"\\200", "\\201", "\\202", "\\203", "\\204", "\\205", "\\206", "\\207",
"\\210", "\\211", "\\212", "\\213", "\\214", "\\215", "\\216", "\\217",
"\\220", "\\221", "\\222", "\\223", "\\224", "\\225", "\\226", "\\227",
"\\230", "\\231", "\\232", "\\233", "\\234", "\\235", "\\236", "\\237",
"\\240", "\\241", "\\242", "\\243", "\\244", "\\245", "\\246", "\\247",
"\\250", "\\251", "\\252", "\\253", "\\254", "\\255", "\\256", "\\257",
"\\260", "\\261", "\\262", "\\263", "\\264", "\\265", "\\266", "\\267",
"\\270", "\\271", "\\272", "\\273", "\\274", "\\275", "\\276", "\\277",
"\\300", "\\301", "\\302", "\\303", "\\304", "\\305", "\\306", "\\307",
"\\310", "\\311", "\\312", "\\313", "\\314", "\\315", "\\316", "\\317",
"\\320", "\\321", "\\322", "\\323", "\\324", "\\325", "\\326", "\\327",
"\\330", "\\331", "\\332", "\\333", "\\334", "\\335", "\\336", "\\337",
"\\340", "\\341", "\\342", "\\343", "\\344", "\\345", "\\346", "\\347",
"\\350", "\\351", "\\352", "\\353", "\\354", "\\355", "\\356", "\\357",
"\\360", "\\361", "\\362", "\\363", "\\364", "\\365", "\\366", "\\367",
"\\370", "\\371", "\\372", "\\373", "\\374", "\\375", "\\376", "\\377",
};
/*****************************************************************************/
/* */
/* FULL_CHAR *StringQuotedWord(x) */
/* */
/* Returns the string in QWORD x in the form it would need to take if it */
/* was a quoted word in a Lout source file. Note that the result is */
/* returned in a static variable so it needs to be copied before a */
/* subsequent call to StringQuotedWord is made. */
/* */
/*****************************************************************************/
FULL_CHAR *StringQuotedWord(OBJECT x)
{ FULL_CHAR *p, *q, *r;
static FULL_CHAR buff[MAX_BUFF];
assert( type(x) == QWORD, "StringQuotedWord: type(x) != QWORD!" );
q = buff;
*q++ = CH_QUOTE;
for( p = string(x); *p != '\0'; p++ )
{
for( r = (FULL_CHAR *) quoted_string[*p]; *r != '\0'; *q++ = *r++ );
}
*q++ = CH_QUOTE;
*q++ = '\0';
return buff;
} /* StringQuotedWord */