
// a, b, p, q & r should be of "char [{near|far}] *" form

	// the following are boolean in nature

#define IsStrNULL(p)	(!(p))		// NULL?
#define IsStrNull(p)	(!*(p)) 	// Null ("" or "\0")?

#define IsStrEqual(a,b) (!strcmp(a,b))	// equal?
#define IsStrEquiv(a,b) (!stricmp(a,b)) // equivalent?

#define IsStrOnly	!StrVerify	// verifies chars are in string

	// the following are of "p = StrFunction(q, r)" form

#define StrNull(q)	strchr(q,'\0')
			// find string-end Null;  p -> null terminator

#define StrCrop(q,r)	(StrTrunc(q,r),StrLeft(q,r))
			// crop both ends, copy;  p==q:  first non-"r"-char

#define StrLeft(q,r)	strcpy(q,StrSkip(q,r))
			// crop left side, copy;  p==q:  first non-"r"-char
#define StrLeftTo(q,r)	strcpy(q,StrSkipTo(q,r))
			// crop left side, copy;  p==q:  first "r"-char

#define StrSkip(q,r)	(&(q)[strspn(q,r)])
			// skip chars in "r";     p -> first non-"r"-char
#define StrSkipTo(q,r)	(&(q)[strcspn(q,r)])
			// skip to char in "r";   p -> first "r"-char

#define StrPlural(n,s,p) ((n)==1?(s):(p))
			// if singular: "", "y"; if plural: "s", "es", "ies"

	// BEWARE OF SIDE EFFECTS IN THE FOLLOWING

#define SubStrCL(to,from,col,len)	SubStr(to,from,(col)-1,len)
#define SubStrCC(to,from,col1,col2)	SubStr(to,from,(col1)-1,(col2)-(col1)+1)
#define SubStrOO(to,from,off1,off2)	SubStr(to,from,off1,(off2)-(off1)+1)
#define SubStrOL			SubStr	// (to,from,off,len)

	// the following are of "p = StrFunction(q, r)" form

#define TABSTOPS	8	// columns per tab in StrDetab and StrEntab

extern	char	*StrDetab(char *);		// remove tabs, expanding
extern	char	*StrEntab(char *);		// insert tabs, contracting
extern	char	*StrIndex(char *, char *);	// same as MS-C "strstr"
extern	char	*StrTrunc(char *, char *);	// truncates chars from end
extern	char	*StrUcLc(char *);		// makes upper/lower case
extern	char	*StrVerify(char *, char *);	// verifies chars are in string
extern	char	*SubStr(char *, char *, int, int);	// PL/I "substr"

