diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index cc29c70e097d367d4b0870eb4b78e13c4df767e6..eb48e4785049cf76ab210f68af16f9d051aed637 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -11,6 +11,9 @@ When submitting merge requests to existing files, unless you have prior agreemen
 
 In general, if it's a large set of changes, your best bet of getting it accepted and merged into the repo would be to discuss the concept of the change with the developers in the [Synchronet Programming conference](http://web.synchro.net/?page=001-forum.ssjs&sub=syncprog) **first**.
 
-If you were intereseted in contributing money, not code, then paypal to rob at synchro dot net.
+When modifying the C/C++ source files:
+* Do not call functions from `ctype.h` (e.g. `isprint`, `isspace`, `isdigit`, etc.) - use the `gen_defs.h IS_*` macros instead.
+
+If you were interested in contributing money, not code, then paypal to rob at synchro dot net.
 
 Thank you for contributing!
\ No newline at end of file
diff --git a/src/sbbs3/addfiles.c b/src/sbbs3/addfiles.c
index 5dabc3ba37fd3d33ad653c5e483a955d496e421c..d087ae9f6b3c068cd1d6e53f07b60475d0ac6659 100644
--- a/src/sbbs3/addfiles.c
+++ b/src/sbbs3/addfiles.c
@@ -91,7 +91,7 @@ void prep_desc(char *str)
 			tmp[j++]=str[i];
 		else if(j && str[i]<=' ' && str[i] > 0&& tmp[j-1]==' ')
 			continue;
-		else if(i && !isalnum((uchar)str[i]) && str[i]==str[i-1])
+		else if(i && !IS_ALPHANUMERIC(str[i]) && str[i]==str[i-1])
 			continue;
 		else if(str[i]>=' ' || str[i]<0)
 			tmp[j++]=str[i];
@@ -248,7 +248,7 @@ bool get_file_diz(file_t* f, const char* filepath, char* ext)
 		sprintf(tmpext,"%.256s",ext);
 		prep_desc(tmpext);
 		for(i=0;tmpext[i];i++)
-			if(isalpha((uchar)tmpext[i]))
+			if(IS_ALPHA(tmpext[i]))
 				break;
 		sprintf(f->desc,"%.*s",LEN_FDESC,tmpext+i);
 		for(i=0;(f->desc[i]>=' ' || f->desc[i]<0) && i<LEN_FDESC;i++)
@@ -411,7 +411,7 @@ void addlist(char *inpath, file_t f, uint dskip, uint sskip)
 		else				   /* no space after filename? */
 			continue;
 #endif
-		if(!isalnum(*fname)) {	// filename doesn't begin with an alpha-numeric char?
+		if(!IS_ALPHANUMERIC(*fname)) {	// filename doesn't begin with an alpha-numeric char?
 			continue;
 		}
 		SAFEPRINTF2(filepath,"%s%s",cur_altpath ? scfg.altpath[cur_altpath-1]
@@ -756,7 +756,7 @@ int main(int argc, char **argv)
 		mode|=AUTO_ADD;
 		i=0;
 	} else {
-		if(!isalnum((uchar)argv[1][0]) && argc==2) {
+		if(!IS_ALPHANUMERIC(argv[1][0]) && argc==2) {
 			puts(usage);
 			return(1);
 		}
@@ -862,7 +862,7 @@ int main(int argc, char **argv)
 						return(1);
 			}
 		}
-		else if(isdigit((uchar)argv[j][0])) {
+		else if(IS_DIGIT(argv[j][0])) {
 			if(desc_offset==0)
 				desc_offset=atoi(argv[j]);
 			else
@@ -872,9 +872,9 @@ int main(int argc, char **argv)
 		else if(argv[j][0]=='+') {      /* filelist - FILES.BBS */
 			listgiven=1;
 			if(argc > j+1
-				&& isdigit((uchar)argv[j+1][0])) { /* skip x characters before description */
+				&& IS_DIGIT(argv[j+1][0])) { /* skip x characters before description */
 				if(argc > j+2
-					&& isdigit((uchar)argv[j+2][0])) { /* skip x characters before size */
+					&& IS_DIGIT(argv[j+2][0])) { /* skip x characters before size */
 					addlist(argv[j]+1,f,atoi(argv[j+1]),atoi(argv[j+2]));
 					j+=2;
 				}
diff --git a/src/sbbs3/allusers.c b/src/sbbs3/allusers.c
index 4d5ea513c7fdeaa837321149bf0ae6949b7dae62..ef8d3525f15357d3303a9ceac27d4f5848b220dd 100644
--- a/src/sbbs3/allusers.c
+++ b/src/sbbs3/allusers.c
@@ -182,22 +182,22 @@ int main(int argc, char **argv)
 				case 'F':                       /* Set required flags */
 					j=3;
 					set=1;
-					if(isdigit(argv[i][2]))
+					if(IS_DIGIT(argv[i][2]))
 						set=argv[i][2]&0xf;
 					else
 						j=2;
 					for(;argv[i][j];j++)
-						if(isalpha(argv[i][j]))
+						if(IS_ALPHA(argv[i][j]))
 							reqflags[set-1]|=FLAG(toupper(argv[i][j]));
 					break;
 				case 'R':                       /* Set required restrictions */
 					for(j=2;argv[i][j];j++)
-						if(isalpha(argv[i][j]))
+						if(IS_ALPHA(argv[i][j]))
 							reqrest|=FLAG(toupper(argv[i][j]));
 					break;
 				case 'E':                       /* Set required exemptions */
 					for(j=2;argv[i][j];j++)
-						if(isalpha(argv[i][j]))
+						if(IS_ALPHA(argv[i][j]))
 							reqexempt|=FLAG(toupper(argv[i][j]));
 					break;
 				default:						/* Unrecognized include */
@@ -210,7 +210,7 @@ int main(int argc, char **argv)
 				case 'F':   /* flags */
 					j=3;
 					set=1;
-					if(isdigit(argv[i][2]))
+					if(IS_DIGIT(argv[i][2]))
 						set=argv[i][2]&0xf;
 					else
 						j=2;
@@ -221,7 +221,7 @@ int main(int argc, char **argv)
 						sub=1; 
 					}
 					for(;argv[i][j];j++)
-						if(isalpha(argv[i][j]))
+						if(IS_ALPHA(argv[i][j]))
 							flags|=FLAG(toupper(argv[i][j]));
 					SAFEPRINTF(str,"%suser.dat",dir);
 					if(!fexistcase(str) || (file=sopen(str,O_RDWR|O_BINARY,SH_DENYNO))==-1) {
@@ -285,7 +285,7 @@ int main(int argc, char **argv)
 						sub=1; 
 					}
 					for(;argv[i][j];j++)
-						if(isalpha(argv[i][j]))
+						if(IS_ALPHA(argv[i][j]))
 							flags|=FLAG(toupper(argv[i][j]));
 					SAFEPRINTF(str,"%suser.dat",dir);
 					if(!fexistcase(str) || (file=sopen(str,O_RDWR|O_BINARY,SH_DENYNO))==-1) {
diff --git a/src/sbbs3/ansiterm.cpp b/src/sbbs3/ansiterm.cpp
index c64acc19e2332e0482fa0f7d9b1a4e5e87ec2414..d130acb177e9198cf99a35fc23ff5bfea2ea4f56 100644
--- a/src/sbbs3/ansiterm.cpp
+++ b/src/sbbs3/ansiterm.cpp
@@ -243,7 +243,7 @@ bool sbbs_t::ansi_getxy(int* x, int* y)
             	rsp++;
 				start=time(NULL);
 			}
-            else if(isdigit(ch) && rsp==2) {
+            else if(IS_DIGIT(ch) && rsp==2) {
 				if(y!=NULL) {
                		(*y)*=10;
 					(*y)+=(ch&0xf);
@@ -254,7 +254,7 @@ bool sbbs_t::ansi_getxy(int* x, int* y)
             	rsp++;
 				start=time(NULL);
 			}
-            else if(isdigit(ch) && rsp==3) {
+            else if(IS_DIGIT(ch) && rsp==3) {
 				if(x!=NULL) {
             		(*x)*=10;
 					(*x)+=(ch&0xf);
diff --git a/src/sbbs3/ars.c b/src/sbbs3/ars.c
index 8eb049dfbcbb6047f178b02fec6d1d119368e509..d03edddd557f28ffbce19795e5e698cc238ca55f 100644
--- a/src/sbbs3/ars.c
+++ b/src/sbbs3/ars.c
@@ -102,7 +102,7 @@ uchar* arstr(ushort* count, const char* str, scfg_t* cfg, uchar* ar_buf)
 		if(str[i]=='&')
 			continue;
 
-		if(isalpha(str[i])) {
+		if(IS_ALPHA(str[i])) {
 			p=np=str+i;
 			SKIP_ALPHA(np);
 			n=np-p;
@@ -248,7 +248,7 @@ uchar* arstr(ushort* count, const char* str, scfg_t* cfg, uchar* ar_buf)
 			continue; 
 		}
 
-		if(!arg_expected && isalpha(str[i])) {
+		if(!arg_expected && IS_ALPHA(str[i])) {
 			n=i;
 			if(!strnicmp(str+i,"AGE",3)) {
 				artype=AR_AGE;
@@ -550,7 +550,7 @@ uchar* arstr(ushort* count, const char* str, scfg_t* cfg, uchar* ar_buf)
 			ar[j++]=AR_EQUAL;
 		not=equal=0;
 
-		if(artype==AR_FLAG1 && isdigit(str[i])) {   /* flag set specified */
+		if(artype==AR_FLAG1 && IS_DIGIT(str[i])) {   /* flag set specified */
 			switch(str[i]) {
 				case '2':
 					artype=AR_FLAG2;
@@ -567,15 +567,15 @@ uchar* arstr(ushort* count, const char* str, scfg_t* cfg, uchar* ar_buf)
 
 		arg_expected=FALSE;
 
-		if(artype==AR_SUB && !isdigit(str[i]))
+		if(artype==AR_SUB && !IS_DIGIT(str[i]))
 			artype=AR_SUBCODE;
-		if(artype==AR_DIR && !isdigit(str[i]))
+		if(artype==AR_DIR && !IS_DIGIT(str[i]))
 			artype=AR_DIRCODE;
 
 		if(artype==AR_INVALID)
 			artype=AR_LEVEL;
 		ar[j++]=artype;
-		if(isdigit(str[i]) && !ar_string_arg(artype)) {
+		if(IS_DIGIT(str[i]) && !ar_string_arg(artype)) {
 			if(artype==AR_TIME) {
 				n=atoi(str+i)*60;
 				p=strchr(str+i,':');
@@ -583,7 +583,7 @@ uchar* arstr(ushort* count, const char* str, scfg_t* cfg, uchar* ar_buf)
 					n+=atoi(p+1);
 				*((short *)(ar+j))=n;
 				j+=2;
-				while(isdigit(str[i+1]) || str[i+1]==':') i++;
+				while(IS_DIGIT(str[i+1]) || str[i+1]==':') i++;
 				continue; 
 			}
 			n=atoi(str+i);
@@ -635,7 +635,7 @@ uchar* arstr(ushort* count, const char* str, scfg_t* cfg, uchar* ar_buf)
 					j--;
 					break; 
 			}
-			while(isdigit(str[i+1])) i++;
+			while(IS_DIGIT(str[i+1])) i++;
 			continue; 
 		}
 		maxlen=128;
@@ -681,7 +681,7 @@ uchar* arstr(ushort* count, const char* str, scfg_t* cfg, uchar* ar_buf)
 				}
 				else        /* Unknown sub-board */
 					j--;
-				while(isalpha(str[i+1])) i++;
+				while(IS_ALPHA(str[i+1])) i++;
 				break;
 			case AR_DIR:
 				for(n=0;n<(uint)cfg->total_dirs;n++)
@@ -693,7 +693,7 @@ uchar* arstr(ushort* count, const char* str, scfg_t* cfg, uchar* ar_buf)
 				}
 				else        /* Unknown directory */
 					j--;
-				while(isalpha(str[i+1])) i++;
+				while(IS_ALPHA(str[i+1])) i++;
 				break;
 			case AR_DAY:
 				if(toupper(str[i])=='S' 
@@ -712,7 +712,7 @@ uchar* arstr(ushort* count, const char* str, scfg_t* cfg, uchar* ar_buf)
 				else if(toupper(str[i])=='F')               /* Friday */
 					ar[j++]=5;
 				else ar[j++]=6;                             /* Saturday */
-				while(isalpha(str[i+1])) i++;
+				while(IS_ALPHA(str[i+1])) i++;
 				break;
 			default:	/* Badly formed ARS, digit expected */
 				j--;
diff --git a/src/sbbs3/atcodes.cpp b/src/sbbs3/atcodes.cpp
index b1ed9e9cb8cc4a9fbe9ed0eee27a5d6c801bb457..a51b5aa9c72b0e3abccbd6b774f11041e38aa678 100644
--- a/src/sbbs3/atcodes.cpp
+++ b/src/sbbs3/atcodes.cpp
@@ -52,7 +52,7 @@ static char* separate_thousands(const char* src, char *dest, size_t maxlen, char
 	if(strlen(src) * 1.3 > maxlen)
 		return (char*)src;
 	const char* tail = src;
-	while(*tail && isdigit(*tail))
+	while(*tail && IS_DIGIT(*tail))
 		tail++;
 	if(tail == src)
 		return (char*)src;
@@ -174,13 +174,13 @@ int sbbs_t::show_atcode(const char *instr, JSObject* obj)
 	if(p!=NULL) {
 		char* lp = p;
 		lp++;	// skip the '|' or '-'
-		while(*lp == '>'|| isalpha((uchar)*lp))
+		while(*lp == '>'|| IS_ALPHA(*lp))
 			lp++;
 		if(*lp)
 			width_specified = true;
-		while(*lp && !isdigit((uchar)*lp))
+		while(*lp && !IS_DIGIT(*lp))
 			lp++;
-		if(*lp && isdigit((uchar)*lp)) {
+		if(*lp && IS_DIGIT(*lp)) {
 			disp_len=atoi(lp);
 			width_specified = true;
 		}
diff --git a/src/sbbs3/baja.c b/src/sbbs3/baja.c
index b572083c842022d1409e77c45b3a8c84d572faa1..654a4dc0ff114c9fdd97b10a29f43595a2de5928 100644
--- a/src/sbbs3/baja.c
+++ b/src/sbbs3/baja.c
@@ -148,7 +148,7 @@ int32_t val(char *src, char *p)
 	static int inside;
 	int32_t l;
 
-	if(isdigit((uchar)*p) || *p=='-')      /* Dec, Hex, or Oct */
+	if(IS_DIGIT(*p) || *p=='-')      /* Dec, Hex, or Oct */
 		l=strtol(p,&p,0);
 	else if(*p=='\'') {  /* Char */
 		p++;
@@ -230,11 +230,11 @@ void writecstr(char *p)
 			continue; }
 		if(*p=='\\')    { /* escape */
 			p++;
-			if(isdigit((uchar)*p)) {
+			if(IS_DIGIT(*p)) {
 				sprintf(tmp,"%.3s",p);
 				str[j]=atoi(tmp); 		/* decimal, NOT octal */
-				if(isdigit((uchar)*(++p))) 	/* skip up to 3 digits */
-					if(isdigit((uchar)*(++p)))
+				if(IS_DIGIT(*(++p))) 	/* skip up to 3 digits */
+					if(IS_DIGIT(*(++p)))
 						p++;
 				j++;
 				continue; }
@@ -311,7 +311,7 @@ void newvar(char* src, char *in)
 	char name[128];
 	int32_t i,l;
 
-	if(isdigit((uchar)*in)) {
+	if(IS_DIGIT(*in)) {
 		printf("!SYNTAX ERROR (illegal variable name):\n");
 		printf(linestr,src,line,(char*)in);
 		bail(1); 
@@ -377,7 +377,7 @@ int32_t isvar(char *arg)
 	char name[128],*p;
 	int32_t i,l;
 
-	if(!arg || !(*arg) || isdigit((uchar)*arg))
+	if(!arg || !(*arg) || IS_DIGIT(*arg))
 		return(0);
 
 	sprintf(name,"%.80s",arg);
@@ -426,7 +426,7 @@ void expdefs(char *line)
 			continue; }
 
 		for(sp=p;*sp;sp++)
-			if(!isalnum((uchar)*sp) && *sp!='_')
+			if(!IS_ALPHANUMERIC(*sp) && *sp!='_')
 				break;
 		sav[0]=*sp; 		/* Save delimiter */
 		sav[1]=0;
@@ -1185,7 +1185,7 @@ void compile(char *src)
 
 		if(!stricmp(p,"COMPARE_INT_VAR") ||
 			(!stricmp(p,"COMPARE")
-				&& (isdigit((uchar)*arg2) || atol(arg2) || *arg2=='\'' || *arg2=='.'))) {
+				&& (IS_DIGIT(*arg2) || atol(arg2) || *arg2=='\'' || *arg2=='.'))) {
 			if(!(*arg)) break;
 
 			fputc(CS_VAR_INSTRUCTION,out);
@@ -1290,7 +1290,7 @@ void compile(char *src)
 
 		if(!stricmp(p,"ADD_INT_VAR")
 			|| (!stricmp(p,"ADD")
-				&& (isdigit((uchar)*arg2) || atol(arg2) || *arg2=='\'' || *arg2=='.'))) {
+				&& (IS_DIGIT(*arg2) || atol(arg2) || *arg2=='\'' || *arg2=='.'))) {
 			if(!(*arg)) break;
 			fputc(CS_VAR_INSTRUCTION,out);
 			fputc(ADD_INT_VAR,out);
@@ -1318,7 +1318,7 @@ void compile(char *src)
 
 		if(!stricmp(p,"SUB_INT_VAR")
 			|| (!stricmp(p,"SUB")
-				&& (isdigit((uchar)*arg2) || atol(arg2) || *arg2=='\'' || *arg2=='.'))) {
+				&& (IS_DIGIT(*arg2) || atol(arg2) || *arg2=='\'' || *arg2=='.'))) {
 			if(!(*arg)) break;
 			fputc(CS_VAR_INSTRUCTION,out);
 			fputc(SUB_INT_VAR,out);
@@ -1346,7 +1346,7 @@ void compile(char *src)
 
 		if(!stricmp(p,"MUL_INT_VAR")
 			|| (!stricmp(p,"MUL")
-				&& (isdigit((uchar)*arg2) || atol(arg2) || *arg2=='\'' || *arg2=='.'))) {
+				&& (IS_DIGIT(*arg2) || atol(arg2) || *arg2=='\'' || *arg2=='.'))) {
 			if(!(*arg)) break;
 			fputc(CS_VAR_INSTRUCTION,out);
 			fputc(MUL_INT_VAR,out);
@@ -1374,7 +1374,7 @@ void compile(char *src)
 
 		if(!stricmp(p,"DIV_INT_VAR")
 			|| (!stricmp(p,"DIV")
-				&& (isdigit((uchar)*arg2) || atol(arg2) || *arg2=='\'' || *arg2=='.'))) {
+				&& (IS_DIGIT(*arg2) || atol(arg2) || *arg2=='\'' || *arg2=='.'))) {
 			if(!(*arg)) break;
 			fputc(CS_VAR_INSTRUCTION,out);
 			fputc(DIV_INT_VAR,out);
@@ -1402,7 +1402,7 @@ void compile(char *src)
 
 		if(!stricmp(p,"MOD_INT_VAR")
 			|| (!stricmp(p,"MOD")
-				&& (isdigit((uchar)*arg2) || atol(arg2) || *arg2=='\'' || *arg2=='.'))) {
+				&& (IS_DIGIT(*arg2) || atol(arg2) || *arg2=='\'' || *arg2=='.'))) {
 			if(!(*arg)) break;
 			fputc(CS_VAR_INSTRUCTION,out);
 			fputc(MOD_INT_VAR,out);
@@ -1430,7 +1430,7 @@ void compile(char *src)
 
 		if(!stricmp(p,"AND_INT_VAR")
 			|| (!stricmp(p,"AND")
-				&& (isdigit((uchar)*arg2) || atol(arg2) || *arg2=='\'' || *arg2=='.'))) {
+				&& (IS_DIGIT(*arg2) || atol(arg2) || *arg2=='\'' || *arg2=='.'))) {
 			if(!(*arg)) break;
 			fputc(CS_VAR_INSTRUCTION,out);
 			fputc(AND_INT_VAR,out);
@@ -1474,7 +1474,7 @@ void compile(char *src)
 
 		if(!stricmp(p,"OR_INT_VAR")
 			|| (!stricmp(p,"OR")
-				&& (isdigit((uchar)*arg2) || atol(arg2) || *arg2=='\'' || *arg2=='.'))) {
+				&& (IS_DIGIT(*arg2) || atol(arg2) || *arg2=='\'' || *arg2=='.'))) {
 			if(!(*arg)) break;
 			fputc(CS_VAR_INSTRUCTION,out);
 			fputc(OR_INT_VAR,out);
@@ -1500,7 +1500,7 @@ void compile(char *src)
 
 		if(!stricmp(p,"NOT_INT_VAR")
 			|| (!stricmp(p,"NOT")
-				&& (isdigit((uchar)*arg2) || atol(arg2) || *arg2=='\'' || *arg2=='.'))) {
+				&& (IS_DIGIT(*arg2) || atol(arg2) || *arg2=='\'' || *arg2=='.'))) {
 			if(!(*arg)) break;
 			fputc(CS_VAR_INSTRUCTION,out);
 			fputc(NOT_INT_VAR,out);
@@ -1526,7 +1526,7 @@ void compile(char *src)
 
 		if(!stricmp(p,"XOR_INT_VAR")
 			|| (!stricmp(p,"XOR")
-				&& (isdigit((uchar)*arg2) || atol(arg2) || *arg2=='\'' || *arg2=='.'))) {
+				&& (IS_DIGIT(*arg2) || atol(arg2) || *arg2=='\'' || *arg2=='.'))) {
 			if(!(*arg)) break;
 			fputc(CS_VAR_INSTRUCTION,out);
 			fputc(XOR_INT_VAR,out);
@@ -1678,7 +1678,7 @@ void compile(char *src)
 			if(!(*arg)) break;
 
 			fputc(CS_FIO_FUNCTION,out);
-			if(!(*arg3) || isdigit((uchar)*arg3) || atoi(arg3))
+			if(!(*arg3) || IS_DIGIT(*arg3) || atoi(arg3))
 				fputc(FIO_READ,out);
 			else
 				fputc(FIO_READ_VAR,out);
@@ -1691,7 +1691,7 @@ void compile(char *src)
 			if(p)
 				*p=0;
 			writecrc(src,arg2); 		/* Variable */
-			if(isdigit((uchar)*arg3))
+			if(IS_DIGIT(*arg3))
 				i=val(src,arg3);	 /* Length */
 			else
 				i=0;
@@ -1703,7 +1703,7 @@ void compile(char *src)
 		if(!stricmp(p,"FWRITE")) {
 			if(!(*arg)) break;
 			fputc(CS_FIO_FUNCTION,out);
-			if(!(*arg3) || isdigit((uchar)*arg3) || atoi(arg3))
+			if(!(*arg3) || IS_DIGIT(*arg3) || atoi(arg3))
 				fputc(FIO_WRITE,out);
 			else
 				fputc(FIO_WRITE_VAR,out);
@@ -1716,7 +1716,7 @@ void compile(char *src)
 			if(p)
 				*p=0;
 			writecrc(src,arg2); 		/* Variable */
-			if(isdigit((uchar)*arg3))
+			if(IS_DIGIT(*arg3))
 				i=val(src,arg3);	 /* Length */
 			else
 				i=0;
@@ -1769,7 +1769,7 @@ void compile(char *src)
 		if(!stricmp(p,"FSET_POS") || !stricmp(p,"FSEEK")) {
 			if(!(*arg)) break;
 			fputc(CS_FIO_FUNCTION,out);
-			if(isdigit((uchar)*arg2) || atol(arg2))
+			if(IS_DIGIT(*arg2) || atol(arg2))
 				fputc(FIO_SEEK,out);
 			else
 				fputc(FIO_SEEK_VAR,out);
@@ -1781,7 +1781,7 @@ void compile(char *src)
 			p=strchr(arg2,' ');
 			if(p)
 				*p=0;
-			if(atol(arg2) || isdigit((uchar)*arg2)) {
+			if(atol(arg2) || IS_DIGIT(*arg2)) {
 				l=val(src,arg2);
 				fwrite(&l,4,1,out); }
 			else
@@ -1800,7 +1800,7 @@ void compile(char *src)
 		if(!stricmp(p,"FLOCK")) {
 			if(!(*arg)) break;
 			fputc(CS_FIO_FUNCTION,out);
-			if(isdigit((uchar)*arg2) || atol(arg2))
+			if(IS_DIGIT(*arg2) || atol(arg2))
 				fputc(FIO_LOCK,out);
 			else
 				fputc(FIO_LOCK_VAR,out);
@@ -1809,7 +1809,7 @@ void compile(char *src)
 				break;
 			*p=0;
 			writecrc(src,arg);			/* File handle */
-			if(atol(arg2) || isdigit((uchar)*arg2)) {
+			if(atol(arg2) || IS_DIGIT(*arg2)) {
 				l=val(src,arg2);
 				if(!l)
 					break;
@@ -1820,7 +1820,7 @@ void compile(char *src)
 		if(!stricmp(p,"FUNLOCK")) {
 			if(!(*arg)) break;
 			fputc(CS_FIO_FUNCTION,out);
-			if(isdigit((uchar)*arg2) || atol(arg2))
+			if(IS_DIGIT(*arg2) || atol(arg2))
 				fputc(FIO_UNLOCK,out);
 			else
 				fputc(FIO_UNLOCK_VAR,out);
@@ -1829,7 +1829,7 @@ void compile(char *src)
 				break;
 			*p=0;
 			writecrc(src,arg);			/* File handle */
-			if(atol(arg2) || isdigit((uchar)*arg2)) {
+			if(atol(arg2) || IS_DIGIT(*arg2)) {
 				l=val(src,arg2);
 				if(!l)
 					break;
@@ -1840,7 +1840,7 @@ void compile(char *src)
 		if(!stricmp(p,"FSET_LENGTH")) {
 			if(!(*arg)) break;
 			fputc(CS_FIO_FUNCTION,out);
-			if(isdigit((uchar)*arg2) || atol(arg2))
+			if(IS_DIGIT(*arg2) || atol(arg2))
 				fputc(FIO_SET_LENGTH,out);
 			else
 				fputc(FIO_SET_LENGTH_VAR,out);
@@ -1849,7 +1849,7 @@ void compile(char *src)
 				break;
 			*p=0;
 			writecrc(src,arg);			/* File handle */
-			if(atol(arg2) || isdigit((uchar)*arg2)) {
+			if(atol(arg2) || IS_DIGIT(*arg2)) {
 				l=val(src,arg2);
 				fwrite(&l,4,1,out); }
 			else
@@ -2548,7 +2548,7 @@ void compile(char *src)
 		if(!stricmp(p,"GETSTR")) {
 			p=strchr(arg,' ');
 			if(p) *p=0;
-			if((!(*arg) || isdigit((uchar)*arg) || !stricmp(arg,"STR")) && !(*arg3))
+			if((!(*arg) || IS_DIGIT(*arg) || !stricmp(arg,"STR")) && !(*arg3))
 				fprintf(out,"%c%c",CS_GETSTR,atoi(arg) ? atoi(arg)
 					: *arg2 ? atoi(arg2) : 128);
 			else {
@@ -2577,7 +2577,7 @@ void compile(char *src)
 			if(!(*arg)) break;
 			p=strchr(arg,' ');
 			if(p) *p=0;
-			if(isdigit((uchar)*arg)) {
+			if(IS_DIGIT(*arg)) {
 				i=val(src,arg);
 				fprintf(out,"%c",CS_GETNUM);
 				fwrite(&i,2,1,out); }
@@ -2612,7 +2612,7 @@ void compile(char *src)
 		if(!stricmp(p,"GETLINE")) {
 			p=strchr(arg,' ');
 			if(p) *p=0;
-			if(!(*arg) || isdigit((uchar)*arg))
+			if(!(*arg) || IS_DIGIT(*arg))
 				fprintf(out,"%c%c",CS_GETLINE,*arg ? atoi(arg) :128);
 			else {
 				if((l=isvar(arg2))!=0) {
@@ -2632,7 +2632,7 @@ void compile(char *src)
 		if(!stricmp(p,"GETSTRUPR")) {
 			p=strchr(arg,' ');
 			if(p) *p=0;
-			if(!(*arg) || isdigit((uchar)*arg))
+			if(!(*arg) || IS_DIGIT(*arg))
 				fprintf(out,"%c%c",CS_GETSTRUPR,*arg ? atoi(arg) :128);
 			else {
 				if((l=isvar(arg2))!=0) {
@@ -2652,7 +2652,7 @@ void compile(char *src)
 		if(!stricmp(p,"GETNAME")) {
 			p=strchr(arg,' ');
 			if(p) *p=0;
-			if(!(*arg) || isdigit((uchar)*arg))
+			if(!(*arg) || IS_DIGIT(*arg))
 				fprintf(out,"%c%c",CS_GETNAME,*arg ? atoi(arg) :25);
 			else {
 				if((l=isvar(arg2))!=0) {
@@ -2673,7 +2673,7 @@ void compile(char *src)
 			if(!(*arg)) break;
 			p=strchr(arg,' ');
 			if(p) *p=0;
-			if(isdigit((uchar)*arg))
+			if(IS_DIGIT(*arg))
 				fprintf(out,"%c%c",CS_SHIFT_STR,atoi(arg));
 			else {
 				if((l=isvar(arg2))!=0) {
diff --git a/src/sbbs3/chat.cpp b/src/sbbs3/chat.cpp
index 1d68f5209226aa858c2fbfce1ac8bc275adffa17..321c907bd00b5c7822e40a09cd5a56d5ab15c67a 100644
--- a/src/sbbs3/chat.cpp
+++ b/src/sbbs3/chat.cpp
@@ -1571,7 +1571,7 @@ void sbbs_t::guruchat(char* line, char* gurubuf, int gurunum, char* last_answer)
 	j=strlen(line);
 	k=0;
 	for(i=0;i<j;i++) {
-		if(line[i]<0 || !isalnum((uchar)line[i])) {
+		if(line[i]<0 || !IS_ALPHANUMERIC(line[i])) {
 			if(!k)	/* beginning non-alphanumeric */
 				continue;
 			if(line[i]==line[i+1])	/* redundant non-alnum */
@@ -1584,7 +1584,7 @@ void sbbs_t::guruchat(char* line, char* gurubuf, int gurunum, char* last_answer)
 	cstr[k]=0;
 	while(k) {
 		k--;
-		if(!isalnum((uchar)cstr[k]))
+		if(!IS_ALPHANUMERIC(cstr[k]))
 			continue;
 		break; 
 	}
@@ -1786,8 +1786,8 @@ void sbbs_t::guruchat(char* line, char* gurubuf, int gurunum, char* last_answer)
 			if(action!=NODE_MCHT) {
 				for(i=0;i<k;i++) {
 					if(i && mistakes && theanswer[i]!=theanswer[i-1] &&
-						((!isalnum((uchar)theanswer[i]) && !sbbs_random(100))
-						|| (isalnum((uchar)theanswer[i]) && !sbbs_random(30)))) {
+						((!IS_ALPHANUMERIC(theanswer[i]) && !sbbs_random(100))
+						|| (IS_ALPHANUMERIC(theanswer[i]) && !sbbs_random(30)))) {
 						c=j=((uint)sbbs_random(3)+1);	/* 1 to 3 chars */
 						if(c<strcspn(theanswer+(i+1),"\0., "))
 							c=j=1;
@@ -1909,7 +1909,7 @@ bool sbbs_t::guruexp(char **ptrptr, char *line)
 		if((**ptrptr)==')')
 			break;
 		c=0;
-		while((**ptrptr) && isspace(**ptrptr))
+		while((**ptrptr) && IS_WHITESPACE(**ptrptr))
 			(*ptrptr)++;
 		while((**ptrptr)!='|' && (**ptrptr)!='&' && (**ptrptr)!=')' &&(**ptrptr)) {
 			str[c++]=(**ptrptr);
@@ -1948,13 +1948,13 @@ bool sbbs_t::guruexp(char **ptrptr, char *line)
 		else {
 			cp=strstr(line,str);
 			if(cp && c) {
-				if(cp!=line || isalnum((uchar)*(cp+strlen(str))))
+				if(cp!=line || IS_ALPHANUMERIC(*(cp+strlen(str))))
 					cp=0; 
 			}
 			else {	/* must be isolated word */
 				while(cp)
-					if((cp!=line && isalnum((uchar)*(cp-1)))
-						|| isalnum((uchar)*(cp+strlen(str))))
+					if((cp!=line && IS_ALPHANUMERIC(*(cp-1)))
+						|| IS_ALPHANUMERIC(*(cp+strlen(str))))
 						cp=strstr(cp+strlen(str),str);
 					else
 						break; 
diff --git a/src/sbbs3/con_out.cpp b/src/sbbs3/con_out.cpp
index 1c2ed232e850608ca3a279e2f4d66d0bc1280434..04db4b9869cbf9407bc4ab2424f96c7785bcf40b 100644
--- a/src/sbbs3/con_out.cpp
+++ b/src/sbbs3/con_out.cpp
@@ -178,7 +178,7 @@ size_t sbbs_t::bstrlen(const char *str, long mode)
 /* Perform PETSCII terminal output translation (from ASCII/CP437) */
 unsigned char cp437_to_petscii(unsigned char ch)
 {
-	if(isalpha(ch))
+	if(IS_ALPHA(ch))
 		return ch ^ 0x20;	/* swap upper/lower case */
 	switch(ch) {
 		case '\1':		return '@';
@@ -260,7 +260,7 @@ int sbbs_t::petscii_to_ansibbs(unsigned char ch)
 {
 	if((ch&0xe0) == 0xc0)	/* "Codes $60-$7F are, actually, copies of codes $C0-$DF" */
 		ch = 0x60 | (ch&0x1f);
-	if(isalpha(ch))
+	if(IS_ALPHA(ch))
 		return outchar(ch ^ 0x20);	/* swap upper/lower case */
 	switch(ch) {
 		case '\r':					newline();		break;
@@ -1038,7 +1038,7 @@ void sbbs_t::ctrl_a(char x)
 		cursor_right((uchar)x-0x7f);
 		return;
 	}
-	if(isdigit(x)) {	/* background color */
+	if(IS_DIGIT(x)) {	/* background color */
 		atr &= (BG_BRIGHT|BLINK|0x0f);
 	}
 	switch(toupper(x)) {
diff --git a/src/sbbs3/date_str.c b/src/sbbs3/date_str.c
index 310aff910194e4a4e1c8ce95c249824e6869505e..c2f2b4d38422e8678c18ce410ad51858017c8049 100644
--- a/src/sbbs3/date_str.c
+++ b/src/sbbs3/date_str.c
@@ -54,18 +54,18 @@ time32_t DLLCALL dstrtounix(scfg_t* cfg, const char *instr)
 	if(!instr[0] || !strncmp(instr,"00/00/00",8))
 		return(0);
 
-	if(isdigit(instr[0]) && isdigit(instr[1])
-		&& isdigit(instr[3]) && isdigit(instr[4])
-		&& isdigit(instr[6]) && isdigit(instr[7]))
+	if(IS_DIGIT(instr[0]) && IS_DIGIT(instr[1])
+		&& IS_DIGIT(instr[3]) && IS_DIGIT(instr[4])
+		&& IS_DIGIT(instr[6]) && IS_DIGIT(instr[7]))
 		p=instr;	/* correctly formatted */
 	else {
 		p=instr;	/* incorrectly formatted */
-		while(*p && isdigit(*p)) p++;
+		while(*p && IS_DIGIT(*p)) p++;
 		if(*p==0)
 			return(0);
 		p++;
 		day=p;
-		while(*p && isdigit(*p)) p++;
+		while(*p && IS_DIGIT(*p)) p++;
 		if(*p==0)
 			return(0);
 		p++;
diff --git a/src/sbbs3/exec.cpp b/src/sbbs3/exec.cpp
index ed123167456b785da1d4c1566276676a42d62f8f..f864952c7177a32fe42d350b3c1402ee063478d6 100644
--- a/src/sbbs3/exec.cpp
+++ b/src/sbbs3/exec.cpp
@@ -1521,9 +1521,9 @@ int sbbs_t::exec(csi_t *csi)
 				csi->logic=*csi->ip++;
 				return(0);
 			case CS_CMDKEY:
-				if( ((*csi->ip)==CS_DIGIT && isdigit(csi->cmd))
+				if( ((*csi->ip)==CS_DIGIT && IS_DIGIT(csi->cmd))
 					|| ((*csi->ip)==CS_EDIGIT && csi->cmd&0x80
-					&& isdigit(csi->cmd&0x7f))) {
+					&& IS_DIGIT(csi->cmd&0x7f))) {
 					csi->ip++;
 					return(0); 
 				}
@@ -1597,9 +1597,9 @@ int sbbs_t::exec(csi_t *csi)
 					memmove(csi->str,csi->str+i,j+1);
 				return(0);
 			case CS_COMPARE_KEY:
-				if( ((*csi->ip)==CS_DIGIT && isdigit(csi->cmd))
+				if( ((*csi->ip)==CS_DIGIT && IS_DIGIT(csi->cmd))
 					|| ((*csi->ip)==CS_EDIGIT && csi->cmd&0x80
-					&& isdigit(csi->cmd&0x7f))) {
+					&& IS_DIGIT(csi->cmd&0x7f))) {
 					csi->ip++;
 					csi->logic=LOGIC_TRUE; 
 				}
@@ -1628,7 +1628,7 @@ int sbbs_t::exec(csi_t *csi)
 				}
 				switch(*(csi->ip++)) {
 					case USER_STRING_ALIAS:
-						if(!isalpha(csi->str[0]) || trashcan(csi->str,"name"))
+						if(!IS_ALPHA(csi->str[0]) || trashcan(csi->str,"name"))
 							break;
 						i=matchuser(&cfg,csi->str,TRUE /*sysop_alias*/);
 						if(i && i!=useron.number)
diff --git a/src/sbbs3/execfile.cpp b/src/sbbs3/execfile.cpp
index 061bd073f236442017f0b22499eabba0a32a22a6..a27f220ea66a2db584613c5ba9e1755d598fdab4 100644
--- a/src/sbbs3/execfile.cpp
+++ b/src/sbbs3/execfile.cpp
@@ -127,7 +127,7 @@ int sbbs_t::exec_file(csi_t *csi)
 			if((ch&0xf)*10U<=usrdirs[curlib] && (ch&0xf) && usrlibs) {
 				i=(ch&0xf)*10;
 				ch=getkey(K_UPPER);
-				if(!isdigit(ch) && ch!=CR) {
+				if(!IS_DIGIT(ch) && ch!=CR) {
 					ungetkey(ch);
 					curdir[curlib]=(i/10)-1;
 					return(0); 
@@ -142,7 +142,7 @@ int sbbs_t::exec_file(csi_t *csi)
 				if(i*10<=usrdirs[curlib]) { 	/* 100+ dirs */
 					i*=10;
 					ch=getkey(K_UPPER);
-					if(!isdigit(ch) && ch!=CR) {
+					if(!IS_DIGIT(ch) && ch!=CR) {
 						ungetkey(ch);
 						curdir[curlib]=(i/10)-1;
 						return(0); 
@@ -179,7 +179,7 @@ int sbbs_t::exec_file(csi_t *csi)
 			if((ch&0xf)*10U<=usrlibs && (ch&0xf)) {
 				i=(ch&0xf)*10;
 				ch=getkey(K_UPPER);
-				if(!isdigit(ch) && ch!=CR) {
+				if(!IS_DIGIT(ch) && ch!=CR) {
 					ungetkey(ch);
 					curlib=(i/10)-1;
 					return(0); 
diff --git a/src/sbbs3/execmsg.cpp b/src/sbbs3/execmsg.cpp
index e5952d8600d9210c825eeb721672a585d9278377..ce327dd3b912816637699c05ded2f851cf0c9f17 100644
--- a/src/sbbs3/execmsg.cpp
+++ b/src/sbbs3/execmsg.cpp
@@ -123,7 +123,7 @@ int sbbs_t::exec_msg(csi_t *csi)
 			if(usrgrps && (ch&0xf)*10U<=usrsubs[curgrp] && (ch&0xf)) {
 				i=(ch&0xf)*10;
 				ch=getkey(K_UPPER);
-				if(!isdigit((uchar)ch) && ch!=CR) {
+				if(!IS_DIGIT(ch) && ch!=CR) {
 					ungetkey(ch);
 					cursub[curgrp]=(i/10)-1;
 					return(0); 
@@ -138,7 +138,7 @@ int sbbs_t::exec_msg(csi_t *csi)
 				if(i*10<=usrsubs[curgrp]) { 	/* 100+ subs */
 					i*=10;
 					ch=getkey(K_UPPER);
-					if(!isdigit((uchar)ch) && ch!=CR) {
+					if(!IS_DIGIT(ch) && ch!=CR) {
 						ungetkey(ch);
 						cursub[curgrp]=(i/10)-1;
 						return(0); 
@@ -175,7 +175,7 @@ int sbbs_t::exec_msg(csi_t *csi)
 			if((ch&0xf)*10U<=usrgrps && (ch&0xf)) {
 				i=(ch&0xf)*10;
 				ch=getkey(K_UPPER);
-				if(!isdigit((uchar)ch) && ch!=CR) {
+				if(!IS_DIGIT(ch) && ch!=CR) {
 					ungetkey(ch);
 					curgrp=(i/10)-1;
 					return(0); 
diff --git a/src/sbbs3/ftpsrvr.c b/src/sbbs3/ftpsrvr.c
index 26bb5dac45d86b785dc453a0c0b66b826d63f848..ba9d9b77362899efee793113af5a5716def3a117 100644
--- a/src/sbbs3/ftpsrvr.c
+++ b/src/sbbs3/ftpsrvr.c
@@ -1887,8 +1887,8 @@ static void receive_thread(void* arg)
 							SAFECOPY(desc,ext);
 							strip_exascii(desc, desc);	/* strip extended ASCII chars */
 							prep_file_desc(desc, desc);	/* strip control chars and dupe chars */
-							for(i=0;desc[i];i++)	/* find approprate first char */
-								if(isalnum(desc[i]))
+							for(i=0;desc[i];i++)	/* find appropriate first char */
+								if(IS_ALPHANUMERIC(desc[i]))
 									break;
 							SAFECOPY(f.desc,desc+i); 
 						}
diff --git a/src/sbbs3/getkey.cpp b/src/sbbs3/getkey.cpp
index 20d9d59b3c9aca381db9f61bfbaced67ec28c505..b7c1a3e56ee3ef21adeb9b5c115cbbef29b773c0 100644
--- a/src/sbbs3/getkey.cpp
+++ b/src/sbbs3/getkey.cpp
@@ -91,9 +91,9 @@ char sbbs_t::getkey(long mode)
 			return(0);
 		now=time(NULL);
 		if(ch) {
-			if(mode&K_NUMBER && isprint(ch) && !isdigit(ch))
+			if(mode&K_NUMBER && IS_PRINTABLE(ch) && !IS_DIGIT(ch))
 				continue;
-			if(mode&K_ALPHA && isprint(ch) && !isalpha(ch))
+			if(mode&K_ALPHA && IS_PRINTABLE(ch) && !IS_ALPHA(ch))
 				continue;
 			if(mode&K_NOEXASC && ch&0x80)
 				continue;
@@ -365,7 +365,7 @@ long sbbs_t::getkeys(const char *keys, ulong max, long mode)
 			lncntr=0;
 			return(-1); 
 		}
-		if(ch && !n && ((keys == NULL && !isdigit(ch)) || (strchr(str,ch)))) {  /* return character if in string */
+		if(ch && !n && ((keys == NULL && !IS_DIGIT(ch)) || (strchr(str,ch)))) {  /* return character if in string */
 			if(ch > ' ') {
 				if(!(mode&K_NOECHO))
 					outchar(ch);
@@ -411,7 +411,7 @@ long sbbs_t::getkeys(const char *keys, ulong max, long mode)
 			i/=10;
 			n--; 
 		}
-		else if(max && isdigit(ch) && (i*10)+(ch&0xf)<=max && (ch!='0' || n)) {
+		else if(max && IS_DIGIT(ch) && (i*10)+(ch&0xf)<=max && (ch!='0' || n)) {
 			i*=10;
 			n++;
 			i+=ch&0xf;
diff --git a/src/sbbs3/getstr.cpp b/src/sbbs3/getstr.cpp
index bee868bdac1ff61465c5f4be5a0456cd762bde52..92308498de39dea168df3553ccf20afb2142d456 100644
--- a/src/sbbs3/getstr.cpp
+++ b/src/sbbs3/getstr.cpp
@@ -99,7 +99,7 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode, const str_list_t h
 	if(mode&K_AUTODEL && str1[0] && !(mode&K_NOECHO)) {
 		ch=getkey(mode|K_GETSTR);
 		attr(atr);
-		if(isprint(ch) || ch==DEL) {
+		if(IS_PRINTABLE(ch) || ch==DEL) {
 			for(i=0;i<l;i++)
 				backspace();
 			i=l=0; 
@@ -689,7 +689,7 @@ long sbbs_t::getnum(ulong max, ulong dflt)
 			i/=10;
 			n--; 
 		}
-		else if(isdigit(ch) && (i*10UL)+(ch&0xf)<=max && (dflt || ch!='0' || n)) {
+		else if(IS_DIGIT(ch) && (i*10UL)+(ch&0xf)<=max && (dflt || ch!='0' || n)) {
 			i*=10L;
 			n++;
 			i+=ch&0xf;
diff --git a/src/sbbs3/inkey.cpp b/src/sbbs3/inkey.cpp
index 05b6f3c6d94a0d52bc9fac5a4d7f163e30b544d2..eacf9560cdcd9791ef7636951c34b546f1463c47 100644
--- a/src/sbbs3/inkey.cpp
+++ b/src/sbbs3/inkey.cpp
@@ -74,7 +74,7 @@ int kbincom(sbbs_t* sbbs, unsigned long timeout)
 			}
 			if((ch&0xe0) == 0xc0)	/* "Codes $60-$7F are, actually, copies of codes $C0-$DF" */
 				ch = 0x60 | (ch&0x1f);
-			if(isalpha((unsigned char)ch))
+			if(IS_ALPHA(ch))
 				ch ^= 0x20;	/* Swap upper/lower case */
 		}
 
@@ -416,7 +416,7 @@ char sbbs_t::handle_ctrlkey(char ch, long mode)
 							return 0;
 						}
 						str[i++] = byte;
-						if(isalpha(byte))
+						if(IS_ALPHA(byte))
 							break;
 					}
 					str[i] = 0;
@@ -487,7 +487,7 @@ char sbbs_t::handle_ctrlkey(char ch, long mode)
 	#endif
 					return 0;
 				}
-				if(ch!=';' && !isdigit((uchar)ch) && ch!='R') {    /* other ANSI */
+				if(ch!=';' && !IS_DIGIT(ch) && ch!='R') {    /* other ANSI */
 					str[i]=0;
 					switch(ch) {
 						case 'A':
diff --git a/src/sbbs3/js_bbs.cpp b/src/sbbs3/js_bbs.cpp
index 0e1121e74bd12c466f4ce5a0e2f5088953c1d762..e21ddaf9b2da36364a9da629bae103f4bdc0f252 100644
--- a/src/sbbs3/js_bbs.cpp
+++ b/src/sbbs3/js_bbs.cpp
@@ -1662,7 +1662,7 @@ js_atcode(JSContext *cx, uintN argc, jsval *arglist)
 	else if((p=strstr(instr,"-R"))!=NULL)
 		padded_right=true;
 	if(p!=NULL) {
-		if(*(p+2) && isdigit(*(p+2)))
+		if(*(p+2) && IS_DIGIT(*(p+2)))
 			disp_len=atoi(p+2);
 		*p=0;
 	}
diff --git a/src/sbbs3/js_file.c b/src/sbbs3/js_file.c
index b6d6ab25947f464b2b93f92c4ed7866568a648f2..646d48ef058a814f88f74bf196ebed9e8199777d 100644
--- a/src/sbbs3/js_file.c
+++ b/src/sbbs3/js_file.c
@@ -714,7 +714,7 @@ static jsval get_value(JSContext *cx, char* value)
 	for(p=value;*p;p++) {
 		if(*p=='.' && !f)
 			f=TRUE;
-		else if(!isdigit((uchar)*p))
+		else if(!IS_DIGIT(*p))
 			break;
 	}
 	if(*p==0) {
diff --git a/src/sbbs3/js_global.c b/src/sbbs3/js_global.c
index d98f9316068614ba5f4860dba1772a4a6170255d..9ee3956cce5062efc38592d7cb2b0e916cc9974e 100644
--- a/src/sbbs3/js_global.c
+++ b/src/sbbs3/js_global.c
@@ -1886,7 +1886,7 @@ js_html_encode(JSContext *cx, uintN argc, jsval *arglist)
 				ansi_seq[MAX_ANSI_SEQ]=0;
 				for(lastparam=ansi_seq;*lastparam;lastparam++)
 				{
-					if(isalpha(*lastparam))
+					if(IS_ALPHA(*lastparam))
 					{
 						*(++lastparam)=0;
 						break;
@@ -1896,16 +1896,16 @@ js_html_encode(JSContext *cx, uintN argc, jsval *arglist)
 				param=ansi_seq;
 				if(*param=='?')		/* This is to fix ESC[?7 whatever that is */
 					param++;
-				if(isdigit(*param))
+				if(IS_DIGIT(*param))
 					ansi_param[k++]=atoi(ansi_seq);
-				while(isspace(*param) || isdigit(*param))
+				while(IS_WHITESPACE(*param) || IS_DIGIT(*param))
 					param++;
 				lastparam=param;
 				while((param=strchr(param,';'))!=NULL)
 				{
 					param++;
 					ansi_param[k++]=atoi(param);
-					while(isspace(*param) || isdigit(*param))
+					while(IS_WHITESPACE(*param) || IS_DIGIT(*param))
 						param++;
 					lastparam=param;
 				}
diff --git a/src/sbbs3/js_server.c b/src/sbbs3/js_server.c
index 55ddba7d5f023238b6d2ceffbac0155a64a79f9d..de81d138afac15b16f6b857780a24185077b7a86 100644
--- a/src/sbbs3/js_server.c
+++ b/src/sbbs3/js_server.c
@@ -150,7 +150,7 @@ static void remove_port_part(char *host)
 {
 	char *p=strchr(host, 0)-1;
 
-	if (isdigit(*p)) {
+	if (IS_DIGIT(*p)) {
 		/*
 		 * If the first and last : are not the same, and it doesn't
 		 * start with '[', there's no port part.
@@ -164,7 +164,7 @@ static void remove_port_part(char *host)
 				*p = 0;
 				break;
 			}
-			if (!isdigit(*p))
+			if (!IS_DIGIT(*p))
 				break;
 		}
 	}
diff --git a/src/sbbs3/js_socket.c b/src/sbbs3/js_socket.c
index a987cf41f1b7a94efe419ca28c1085b3c95fff7d..e47b0335b5b491a0f263205d9e4d340122ab49bd 100644
--- a/src/sbbs3/js_socket.c
+++ b/src/sbbs3/js_socket.c
@@ -458,7 +458,7 @@ static ushort js_port(JSContext* cx, jsval val, int type)
 	if(JSVAL_IS_STRING(val)) {
 		str = JS_ValueToString(cx,val);
 		JSSTRING_TO_ASTRING(cx, str, cp, 16, NULL);
-		if(isdigit(*cp))
+		if(IS_DIGIT(*cp))
 			return((ushort)strtol(cp,NULL,0));
 		rc=JS_SUSPENDREQUEST(cx);
 		serv = getservbyname(cp,type==SOCK_STREAM ? "tcp":"udp");
diff --git a/src/sbbs3/jsexec.c b/src/sbbs3/jsexec.c
index 636887a47f9b5caf65ef0b31246eca86e18093dc..cfe931314da8c44d638b72f64231739e3875c4e9 100644
--- a/src/sbbs3/jsexec.c
+++ b/src/sbbs3/jsexec.c
@@ -1111,7 +1111,7 @@ int parseLogLevel(const char* p)
 	str_list_t logLevelStringList=iniLogLevelStringList();
 	int i;
 
-	if(isdigit(*p))
+	if(IS_DIGIT(*p))
 		return strtol(p,NULL,0);
 
 	/* Exact match */
diff --git a/src/sbbs3/load_cfg.c b/src/sbbs3/load_cfg.c
index ee0ecb55f86c5b35c9528dff1c344e4e17a96b55..1c6ced9ba6200d84b9f8d6cd373c89dd6e6a8cc1 100644
--- a/src/sbbs3/load_cfg.c
+++ b/src/sbbs3/load_cfg.c
@@ -474,7 +474,7 @@ char* prep_code(char *str, const char* prefix)
 	strcpy(str,tmp);
 	if(j>LEN_CODE) {	/* Extra chars? Strip symbolic chars */
 		for(i=j=0;str[i];i++)
-			if(isalnum(str[i]))
+			if(IS_ALPHANUMERIC(str[i]))
 				tmp[j++]=str[i];
 		tmp[j]=0;
 		strcpy(str,tmp);
diff --git a/src/sbbs3/login.cpp b/src/sbbs3/login.cpp
index d5ee19f77ef314db9d4c135d89b83b5a4868db17..7432b23b30cd2b59b555f41f62c5108429263e75 100644
--- a/src/sbbs3/login.cpp
+++ b/src/sbbs3/login.cpp
@@ -61,7 +61,7 @@ int sbbs_t::login(char *username, char *pw_prompt, const char* user_pw, const ch
 	useron.number=0;
 	username = parse_login(username);
 
-	if(!(cfg.node_misc&NM_NO_NUM) && isdigit((uchar)username[0])) {
+	if(!(cfg.node_misc&NM_NO_NUM) && IS_DIGIT(username[0])) {
 		useron.number=atoi(username);
 		getuserdat(&cfg,&useron);
 		if(useron.number && useron.misc&(DELETED|INACTIVE))
@@ -71,7 +71,7 @@ int sbbs_t::login(char *username, char *pw_prompt, const char* user_pw, const ch
 	if(!useron.number) {
 		useron.number=matchuser(&cfg,username,FALSE);
 		if(!useron.number && (uchar)username[0]<0x7f && username[1]
-			&& isalpha(username[0]) && strchr(username,' ') && cfg.node_misc&NM_LOGON_R)
+			&& IS_ALPHA(username[0]) && strchr(username,' ') && cfg.node_misc&NM_LOGON_R)
 			useron.number=userdatdupe(0,U_NAME,LEN_NAME,username);
 		if(useron.number) {
 			getuserdat(&cfg,&useron);
diff --git a/src/sbbs3/logon.cpp b/src/sbbs3/logon.cpp
index 4b516a512ecf091a47d396c54b4d221398b05b65..c5df0609e2512571f4e0d60ee98c5782290c6eb4 100644
--- a/src/sbbs3/logon.cpp
+++ b/src/sbbs3/logon.cpp
@@ -243,7 +243,7 @@ bool sbbs_t::logon()
 			c=0;
 			while(c < RAND_PASS_LEN) { 				/* Create random password */
 				str[c]=sbbs_random(43)+'0';
-				if(isalnum(str[c]))
+				if(IS_ALPHANUMERIC(str[c]))
 					c++; 
 			}
 			str[c]=0;
diff --git a/src/sbbs3/mailsrvr.c b/src/sbbs3/mailsrvr.c
index 1ec0ed29eb73335f51d6b2f6382b62de94b229d6..85d164212eb781b3582b727329e3957a3d6a3b70 100644
--- a/src/sbbs3/mailsrvr.c
+++ b/src/sbbs3/mailsrvr.c
@@ -40,7 +40,6 @@
 #include <stdlib.h>			/* ltoa in GNU C lib */
 #include <stdarg.h>			/* va_list */
 #include <string.h>			/* strrchr */
-#include <ctype.h>			/* isdigit */
 #include <fcntl.h>			/* Open flags */
 #include <errno.h>			/* errno */
 
@@ -946,7 +945,7 @@ static u_long resolve_ip(const char *inaddr)
 		return((u_long)INADDR_NONE);
 
 	for(p=addr;*p;p++)
-		if(*p!='.' && !isdigit((uchar)*p))
+		if(*p!='.' && !IS_DIGIT(*p))
 			break;
 	if(!(*p))
 		return(inet_addr(addr));
@@ -1478,7 +1477,7 @@ static void pop3_thread(void* arg)
 			if(!strnicmp(buf, "LIST",4) || !strnicmp(buf,"UIDL",4)) {
 				p=buf+4;
 				SKIP_WHITESPACE(p);
-				if(isdigit((uchar)*p)) {
+				if(IS_DIGIT(*p)) {
 					msgnum=strtoul(p, NULL, 10);
 					if(msgnum<1 || msgnum>msgs) {
 						lprintf(LOG_NOTICE,"%04d %s <%s> !INVALID message #%" PRIu32
@@ -2428,7 +2427,7 @@ char* mimehdr_q_decode(char* buf)
 	for(;*p != 0; p++) {
 		if(*p == '=') {
 			p++;
-			if(isxdigit(*p) && isxdigit(*(p + 1))) {
+			if(IS_HEXDIGIT(*p) && IS_HEXDIGIT(*(p + 1))) {
 				uchar ch = HEX_CHAR_TO_INT(*p) << 4;
 				p++;
 				ch |= HEX_CHAR_TO_INT(*p);
@@ -2655,7 +2654,7 @@ static int chk_received_hdr(SOCKET socket,const char* prot,const char *buf,IN_AD
 		if(*p==0)
 			break;
 		p2=host_name;
-		for(;*p && !isspace((unsigned char)*p) && p2<host_name+126;p++)  {
+		for(;*p && !IS_WHITESPACE(*p) && p2<host_name+126;p++)  {
 			*p2++=*p;
 		}
 		*p2=0;
@@ -2754,7 +2753,7 @@ static char* qp_decode(char* buf)
 			p++;
 			if(*p==0) 	/* soft link break */
 				break;
-			if(isxdigit(*p) && isxdigit(*(p+1))) {
+			if(IS_HEXDIGIT(*p) && IS_HEXDIGIT(*(p+1))) {
 				char hex[3];
 				hex[0]=*p;
 				hex[1]=*(p+1);
@@ -4836,7 +4835,7 @@ static void smtp_thread(void* arg)
 			}
 
 			if((p==alias_buf || p==name_alias_buf || startup->options&MAIL_OPT_ALLOW_RX_BY_NUMBER)
-				&& isdigit((uchar)*p)) {
+				&& IS_DIGIT(*p)) {
 				usernum=atoi(p);			/* RX by user number */
 				/* verify usernum */
 				username(&scfg,usernum,str);
@@ -5247,7 +5246,7 @@ void get_dns_server(char* dns_server, size_t len)
 	size_t		count;
 
 	sprintf(dns_server,"%.*s",(int)len-1,startup->dns_server);
-	if(!isalnum(dns_server[0])) {
+	if(!IS_ALPHANUMERIC(dns_server[0])) {
 		if((list=getNameServerList())!=NULL) {
 			if((count=strListCount(list))>0) {
 				sprintf(dns_server,"%.*s",(int)len,list[xp_random(count)]);
diff --git a/src/sbbs3/main.cpp b/src/sbbs3/main.cpp
index e7e8d4df09e082fb78faff7da8e3eaa59bc38219..0aee306206e43e90589a556ac09a3daea6c3a1af 100644
--- a/src/sbbs3/main.cpp
+++ b/src/sbbs3/main.cpp
@@ -370,7 +370,7 @@ u_long resolve_ip(char *addr)
 		return((u_long)INADDR_NONE);
 
 	for(p=addr;*p;p++)
-		if(*p!='.' && !isdigit((uchar)*p))
+		if(*p!='.' && !IS_DIGIT(*p))
 			break;
 	if(!(*p))
 		return(inet_addr(addr));
diff --git a/src/sbbs3/msgdate.c b/src/sbbs3/msgdate.c
index d5c564e3fa4e1f0921ee1d516173df5b96e10e6c..34a2028455d0d3c8b9718260e22679ad973328c2 100644
--- a/src/sbbs3/msgdate.c
+++ b/src/sbbs3/msgdate.c
@@ -86,10 +86,10 @@ when_t DLLCALL rfc822date(char* date)
 	memset(&when,0,sizeof(when));
 
 	while(*p && *p<=' ') p++;
-	while(*p && !isdigit(*p)) p++;
+	while(*p && !IS_DIGIT(*p)) p++;
 	/* DAY */
 	tm.tm_mday=atoi(p);
-	while(*p && isdigit(*p)) p++;
+	while(*p && IS_DIGIT(*p)) p++;
 	/* MONTH */
 	while(*p && *p<=' ') p++;
 	sprintf(month,"%3.3s",p);
@@ -125,23 +125,23 @@ when_t DLLCALL rfc822date(char* date)
 	else if(tm.tm_year>1900)
 		tm.tm_year-=1900;
 
-	while(*p && isdigit(*p)) p++;
+	while(*p && IS_DIGIT(*p)) p++;
 	/* HOUR */
 	while(*p && *p<=' ') p++;
 	tm.tm_hour=atoi(p);
-	while(*p && isdigit(*p)) p++;
+	while(*p && IS_DIGIT(*p)) p++;
 	/* MINUTE */
 	if(*p) p++;
 	tm.tm_min=atoi(p);
-	while(*p && isdigit(*p)) p++;
+	while(*p && IS_DIGIT(*p)) p++;
 	/* SECONDS */
 	if(*p) p++;
 	tm.tm_sec=atoi(p);
-	while(*p && isdigit(*p)) p++;
+	while(*p && IS_DIGIT(*p)) p++;
 	/* TIME ZONE */
 	while(*p && *p<=' ') p++;
 	if(*p) {
-		if(isdigit(*p) || *p=='-' || *p=='+') { /* [+|-]HHMM format */
+		if(IS_DIGIT(*p) || *p=='-' || *p=='+') { /* [+|-]HHMM format */
 			if(*p=='+') p++;
 			sprintf(str,"%.*s",*p=='-'? 3:2,p);
 			when.zone=atoi(str)*60;
diff --git a/src/sbbs3/netmail.cpp b/src/sbbs3/netmail.cpp
index 5e6f206c2c18d3f81bd46fb9d68bed507d565a52..eab9d211cddb2a309b1e3123f133de1841ad7a84 100644
--- a/src/sbbs3/netmail.cpp
+++ b/src/sbbs3/netmail.cpp
@@ -428,11 +428,11 @@ void sbbs_t::qwktonetmail(FILE *rep, char *block, char *into, uchar fromhub)
 
 
 	p=strrchr(to,'@');       /* Find '@' in name@addr */
-	if(p && !isdigit(*(p+1)) && !strchr(p,'.') && !strchr(p,':')) { /* QWKnet */
+	if(p && !IS_DIGIT(*(p+1)) && !strchr(p,'.') && !strchr(p,':')) { /* QWKnet */
 		qnet=1;
 		*p=0; 
 	}
-	else if(p==NULL || !isdigit(*(p+1)) || !cfg.total_faddrs) {
+	else if(p==NULL || !IS_DIGIT(*(p+1)) || !cfg.total_faddrs) {
 		if(cfg.inetmail_misc&NMAIL_ALLOW) {	/* Internet */
 			inet=1;
 		} else {
diff --git a/src/sbbs3/newuser.cpp b/src/sbbs3/newuser.cpp
index c496793372bcdcd2b22a410f2c108b9af96d3902..f462e72fe84bdd4fcde64c2b7f75c062cc94bb3a 100644
--- a/src/sbbs3/newuser.cpp
+++ b/src/sbbs3/newuser.cpp
@@ -383,7 +383,7 @@ BOOL sbbs_t::newuser()
 		c=0;
 		while(c < RAND_PASS_LEN) { 				/* Create random password */
 			useron.pass[c]=sbbs_random(43)+'0';
-			if(isalnum(useron.pass[c]))
+			if(IS_ALPHANUMERIC(useron.pass[c]))
 				c++; 
 		}
 		useron.pass[c]=0;
diff --git a/src/sbbs3/pack_qwk.cpp b/src/sbbs3/pack_qwk.cpp
index 110cbf3ebfe2abc5392ac6d6d4e0b8dd317252d8..1645895e470dc86b5cc22e256132a72331f295e9 100644
--- a/src/sbbs3/pack_qwk.cpp
+++ b/src/sbbs3/pack_qwk.cpp
@@ -712,7 +712,7 @@ bool sbbs_t::pack_qwk(char *packet, ulong *msgcnt, bool prepack)
 		for(i=0;i<(uint)g.gl_pathc;i++) { 			/* Copy BLT-*.* files */
 			fname=getfname(g.gl_pathv[i]);
 			padfname(fname,str);
-			if(isdigit(str[4]) && isdigit(str[9])) {
+			if(IS_DIGIT(str[4]) && IS_DIGIT(str[9])) {
 				SAFEPRINTF2(str,"%sQWK/%s",cfg.text_dir,fname);
 				SAFEPRINTF2(tmp2,"%s%s",cfg.temp_dir,fname);
 				mv(str,tmp2,/* copy: */TRUE); 
diff --git a/src/sbbs3/putmsg.cpp b/src/sbbs3/putmsg.cpp
index 6e12701a7138c7dd065f5db64a471e83799bad65..a18df8a2eb4fa57737fee43f29c75543d553b4fa 100644
--- a/src/sbbs3/putmsg.cpp
+++ b/src/sbbs3/putmsg.cpp
@@ -165,8 +165,8 @@ char sbbs_t::putmsgfrag(const char* buf, long* mode, long org_cols, JSObject* ob
 				if(mark == 0)
 					next = strchr(str + l + 1, str[l]);
 				char *blank = strstr(str + l + 1, "\n\r");
-				if(((l < 1 || isspace(str[l - 1]) || ispunct(str[l - 1]))
-						&& isalnum(str[l + 1]) && mark == 0 && next != NULL	&& (*(next + 1) == '\0' || isspace(*(next + 1)) || ispunct(*(next+1)))
+				if(((l < 1 || IS_WHITESPACE(str[l - 1]) || IS_PUNCTUATION(str[l - 1]))
+						&& IS_ALPHANUMERIC(str[l + 1]) && mark == 0 && next != NULL	&& (*(next + 1) == '\0' || IS_WHITESPACE(*(next + 1)) || IS_PUNCTUATION(*(next+1)))
 						&& (blank == NULL || next < blank))
 					|| str[l] == mark) {
 					if(mark == 0)
@@ -201,7 +201,7 @@ char sbbs_t::putmsgfrag(const char* buf, long* mode, long org_cols, JSObject* ob
 			if(str[l+1]=='"' && !(sys_status&SS_NEST_PF) && !((*mode)&P_NOATCODES)) {  /* Quote a file */
 				l+=2;
 				i=0;
-				while(i<(int)sizeof(tmp2)-1 && isprint((unsigned char)str[l]) && str[l]!='\\' && str[l]!='/')
+				while(i<(int)sizeof(tmp2)-1 && IS_PRINTABLE(str[l]) && str[l]!='\\' && str[l]!='/')
 					tmp2[i++]=str[l++];
 				if(i > 0) {
 					tmp2[i]=0;
@@ -234,7 +234,7 @@ char sbbs_t::putmsgfrag(const char* buf, long* mode, long org_cols, JSObject* ob
 		}
 		else if(!((*mode)&P_NOXATTRS)
 			&& (cfg.sys_misc&SM_PCBOARD) && str[l]=='@' && str[l+1]=='X'
-			&& isxdigit((unsigned char)str[l+2]) && isxdigit((unsigned char)str[l+3])) {
+			&& IS_HEXDIGIT(str[l+2]) && IS_HEXDIGIT(str[l+3])) {
 			sprintf(tmp2,"%.2s",str+l+2);
 			ulong val = ahtoul(tmp2);
 			// @X00 saves the current color and @XFF restores that saved color
@@ -255,15 +255,15 @@ char sbbs_t::putmsgfrag(const char* buf, long* mode, long org_cols, JSObject* ob
 		}
 		else if(!((*mode)&P_NOXATTRS)
 			&& (cfg.sys_misc&SM_WILDCAT) && str[l]=='@' && str[l+3]=='@'
-			&& isxdigit((unsigned char)str[l+1]) && isxdigit((unsigned char)str[l+2])) {
+			&& IS_HEXDIGIT(str[l+1]) && IS_HEXDIGIT(str[l+2])) {
 			sprintf(tmp2,"%.2s",str+l+1);
 			attr(ahtoul(tmp2));
 			// exatr=1;
 			l+=4;
 		}
 		else if(!((*mode)&P_NOXATTRS)
-			&& (cfg.sys_misc&SM_RENEGADE) && str[l]=='|' && isdigit((unsigned char)str[l+1])
-			&& isdigit((unsigned char)str[l+2]) && !(useron.misc&RIP)) {
+			&& (cfg.sys_misc&SM_RENEGADE) && str[l]=='|' && IS_DIGIT(str[l+1])
+			&& IS_DIGIT(str[l+2]) && !(useron.misc&RIP)) {
 			sprintf(tmp2,"%.2s",str+l+1);
 			i=atoi(tmp2);
 			if(i>=16) { 				/* setting background */
@@ -278,7 +278,7 @@ char sbbs_t::putmsgfrag(const char* buf, long* mode, long org_cols, JSObject* ob
 			l+=3;	/* Skip |xx */
 		}
 		else if(!((*mode)&P_NOXATTRS)
-			&& (cfg.sys_misc&SM_CELERITY) && str[l]=='|' && isalpha((unsigned char)str[l+1])
+			&& (cfg.sys_misc&SM_CELERITY) && str[l]=='|' && IS_ALPHA(str[l+1])
 			&& !(useron.misc&RIP)) {
 			switch(str[l+1]) {
 				case 'k':
@@ -337,7 +337,7 @@ char sbbs_t::putmsgfrag(const char* buf, long* mode, long org_cols, JSObject* ob
 			l+=2;	/* Skip |x */
 		}  /* Skip second digit if it exists */
 		else if(!((*mode)&P_NOXATTRS)
-			&& (cfg.sys_misc&SM_WWIV) && str[l]==CTRL_C && isdigit((unsigned char)str[l+1])) {
+			&& (cfg.sys_misc&SM_WWIV) && str[l]==CTRL_C && IS_DIGIT(str[l+1])) {
 			exatr=1;
 			switch(str[l+1]) {
 				default:
diff --git a/src/sbbs3/readmsgs.cpp b/src/sbbs3/readmsgs.cpp
index 4fcf265ec2a1267c733f6deb354161f2d2768f9d..1cb29d9ec21a95c8027f83557aa57aa01d0a13ae 100644
--- a/src/sbbs3/readmsgs.cpp
+++ b/src/sbbs3/readmsgs.cpp
@@ -802,7 +802,7 @@ int sbbs_t::scanposts(uint subnum, long mode, const char *find)
 			domsg = true;
 			continue; 
 		}
-		if(thread_mode && (isalpha(l) || l=='?')) {
+		if(thread_mode && (IS_ALPHA(l) || l=='?')) {
 			thread_mode = false;
 			domsg = true;
 		}
diff --git a/src/sbbs3/readtext.c b/src/sbbs3/readtext.c
index 3454b53e2464334f9292ebe9696c9c66cb4dc47a..e92c1e962a3c5e0f5be27e4eac6bc81f8c43df3f 100644
--- a/src/sbbs3/readtext.c
+++ b/src/sbbs3/readtext.c
@@ -50,10 +50,10 @@ char *readtext(long *line,FILE *stream,long dflt)
 	for(i=1,j=0;i<k && j<sizeof(str)-1;j++) {
 		if(buf[i]=='\\')	{ /* escape */
 			i++;
-			if(isdigit(buf[i])) {
+			if(IS_DIGIT(buf[i])) {
 				str[j]=atoi(buf+i); 	/* decimal, NOT octal */
-				if(isdigit(buf[++i]))	/* skip up to 3 digits */
-					if(isdigit(buf[++i]))
+				if(IS_DIGIT(buf[++i]))	/* skip up to 3 digits */
+					if(IS_DIGIT(buf[++i]))
 						i++;
 				continue; 
 			}
diff --git a/src/sbbs3/sbbscon.c b/src/sbbs3/sbbscon.c
index c603e9f9331dbaad4c37f82342695a75ad972700..205c69dff3798fc8693abc811bbd73fffc0914c6 100644
--- a/src/sbbs3/sbbscon.c
+++ b/src/sbbs3/sbbscon.c
@@ -1723,7 +1723,7 @@ int main(int argc, char** argv)
 						mail_startup.options=strtoul(arg,NULL,0);
 						break;
 					case 'S':	/* SMTP/SendMail */
-						if(isdigit(*arg)) {
+						if(IS_DIGIT(*arg)) {
 							mail_startup.smtp_port=atoi(arg);
 							break;
 						}
@@ -1737,7 +1737,7 @@ int main(int argc, char** argv)
 						}
 						break;
 					case 'P':	/* POP3 */
-						if(isdigit(*arg)) {
+						if(IS_DIGIT(*arg)) {
 							mail_startup.pop3_port=atoi(arg);
 							break;
 						}
diff --git a/src/sbbs3/sbbsecho.c b/src/sbbs3/sbbsecho.c
index af4a0be2b9080c3ba0518935d54d6fc25e3f4f66..09f3d24afba10e14281eda524ff029095dde628f 100644
--- a/src/sbbs3/sbbsecho.c
+++ b/src/sbbs3/sbbsecho.c
@@ -849,7 +849,7 @@ int write_flofile(const char *infile, fidoaddr_t dest, bool bundle, bool use_out
 		infile++;
 
 #ifdef __unix__
-	if(isalpha(infile[0]) && infile[1] == ':')	// Ignore "C:" prefix
+	if(IS_ALPHA(infile[0]) && infile[1] == ':')	// Ignore "C:" prefix
 		infile += 2;
 #endif
 	SAFECOPY(attachment, infile);
@@ -2317,7 +2317,7 @@ char* process_areafix(fidoaddr_t addr, char* inbuf, const char* password, const
 	add_area=strListInit();
 	del_area=strListInit();
 	for(l=0;l<m;l++) {
-		while(*(p+l) && isspace((uchar)*(p+l))) l++;
+		while(*(p+l) && IS_WHITESPACE(*(p+l))) l++;
 		while(*(p+l)==CTRL_A) {				/* Ignore kludge lines June-13-2004 */
 			while(*(p+l) && *(p+l)!='\r') l++;
 			continue;
@@ -3107,7 +3107,7 @@ time32_t fmsgtime(const char *str)
 	memset(&tm,0,sizeof(tm));
 	tm.tm_isdst=-1;	/* Do not adjust for DST */
 
-	if(isdigit((uchar)str[1])) {	/* Regular format: "01 Jan 86  02:34:56" */
+	if(IS_DIGIT(str[1])) {	/* Regular format: "01 Jan 86  02:34:56" */
 		tm.tm_mday=atoi(str);
 		sprintf(month,"%3.3s",str+3);
 		if(!stricmp(month,"jan"))
@@ -6208,7 +6208,7 @@ int main(int argc, char **argv)
 		else {
 			if(strchr(argv[i],'.')!=NULL && fexist(argv[i]))
 				SAFECOPY(cfg.cfgfile,argv[i]);
-			else if(isdigit((uchar)argv[i][0]))
+			else if(IS_DIGIT(argv[i][0]))
 				nodeaddr = atofaddr(argv[i]);
 			else
 				sub_code = argv[i];
@@ -6400,7 +6400,7 @@ int main(int argc, char **argv)
 			SKIP_WHITESPACE(p);		/* Skip white space */
 
 			while(*p && *p!=';') {
-				if(!isdigit(*p)) {
+				if(!IS_DIGIT(*p)) {
 					printf("\n");
 					lprintf(LOG_WARNING, "Invalid Area File line, expected link address(es) after echo-tag: '%s'", str);
 					break;
diff --git a/src/sbbs3/scfg/scfg.c b/src/sbbs3/scfg/scfg.c
index e6ca0748c3290e09d048e67303918d8cf3043910..9b43ad3bf3d3a7c14a08f78cae988f2a6c2c329c 100644
--- a/src/sbbs3/scfg/scfg.c
+++ b/src/sbbs3/scfg/scfg.c
@@ -233,7 +233,7 @@ int main(int argc, char **argv)
 					umask(strtoul(argv[i]+2,NULL,8));
 					break;
 				case 'G':
-					if(isalpha(argv[i][2]))
+					if(IS_ALPHA(argv[i][2]))
 						grpname = argv[i]+2;
 					else
 						grpnum = atoi(argv[i]+2);
diff --git a/src/sbbs3/scfg/scfgnet.c b/src/sbbs3/scfg/scfgnet.c
index eb3ac852c194c6450a033e6fbc0252a56dbdf207..d2305c2e6eb69a0f059d6999c6d9e2784da3507b 100644
--- a/src/sbbs3/scfg/scfgnet.c
+++ b/src/sbbs3/scfg/scfgnet.c
@@ -980,7 +980,7 @@ void qhub_edit(int num)
 				;
 				if(uifc.input(WIN_MID|WIN_SAV,0,0
 					,"Node to Perform Call-out",str,3,K_EDIT) > 0) {
-					if(isdigit(*str))
+					if(IS_DIGIT(*str))
 						cfg.qhub[num]->node=atoi(str);
 					else
 						cfg.qhub[num]->node = NODE_ANY;
diff --git a/src/sbbs3/scfg/scfgxtrn.c b/src/sbbs3/scfg/scfgxtrn.c
index 98a3a31df30180cca2d5bee1b5ca7290c1468e08..3155544035ca03dff2784a5af4e8063a38429d56 100644
--- a/src/sbbs3/scfg/scfgxtrn.c
+++ b/src/sbbs3/scfg/scfgxtrn.c
@@ -623,7 +623,7 @@ void tevents_cfg()
 						SAFEPRINTF(str, "%u", cfg.event[i]->node);
 					if(uifc.input(WIN_MID|WIN_SAV,0,0,"Execution Node Number (or Any)"
 						,str,3,K_EDIT) > 0) {
-						if(isdigit(*str))
+						if(IS_DIGIT(*str))
 							cfg.event[i]->node=atoi(str);
 						else
 							cfg.event[i]->node = NODE_ANY;
@@ -643,7 +643,7 @@ void tevents_cfg()
 					for(p=str;*p;p++) {
 						if(atoi(p)) {
 							cfg.event[i]->months|=(1<<(atoi(p)-1));
-							while(*p && isdigit(*p))
+							while(*p && IS_DIGIT(*p))
 								p++;
 						} else {
 							for(j=0;j<12;j++)
@@ -672,7 +672,7 @@ void tevents_cfg()
 						if(!isdigit(*p))
 							continue;
 						cfg.event[i]->mdays|=(1<<atoi(p));
-						while(*p && isdigit(*p))
+						while(*p && IS_DIGIT(*p))
 							p++;
 					}
 					break;
diff --git a/src/sbbs3/services.c b/src/sbbs3/services.c
index 14aa6c479235a0cbb8b7ea81d62cd86ca4091bb4..cbb6372c9806b91ea21ec1e88eabc5f46afc8042 100644
--- a/src/sbbs3/services.c
+++ b/src/sbbs3/services.c
@@ -44,7 +44,6 @@
 #include <stdlib.h>			/* ltoa in GNU C lib */
 #include <stdarg.h>			/* va_list */
 #include <string.h>			/* strrchr */
-#include <ctype.h>			/* isdigit */
 #include <fcntl.h>			/* Open flags */
 #include <errno.h>			/* errno */
 
@@ -386,7 +385,7 @@ js_login(JSContext *cx, uintN argc, jsval *arglist)
 			putmsgptrs(&scfg, &client->user, client->subscan);
 	}
 
-	if(isdigit(*user))
+	if(IS_DIGIT(*user))
 		client->user.number=atoi(user);
 	else if(*user)
 		client->user.number=matchuser(&scfg,user,FALSE);
@@ -1575,7 +1574,7 @@ static service_t* read_services_ini(const char* services_ini, service_t* service
 		SAFECOPY(serv.cmd,iniGetString(list,sec_list[i],"Command","",cmd));
 
 		p=iniGetString(list,sec_list[i],"Port",serv.protocol,portstr);
-		if(isdigit(*p))
+		if(IS_DIGIT(*p))
 			serv.port=(ushort)strtol(p,NULL,0);
 		else {
 			struct servent* servent = getservbyname(p,serv.options&SERVICE_OPT_UDP ? "udp":"tcp");
diff --git a/src/sbbs3/sexyz.c b/src/sbbs3/sexyz.c
index dd9ff75f429ff4d3e8e31f4ecc23230587ed76b1..ee1c77a52da226f9ec9af51367ec1ea855a98737 100644
--- a/src/sbbs3/sexyz.c
+++ b/src/sbbs3/sexyz.c
@@ -1656,7 +1656,7 @@ int main(int argc, char **argv)
 
 	for(i=1;i<argc;i++) {
 
-		if(sock==INVALID_SOCKET && isdigit(argv[i][0])) {
+		if(sock==INVALID_SOCKET && IS_DIGIT(argv[i][0])) {
 			sock=atoi(argv[i]);
 			continue;
 		}
diff --git a/src/sbbs3/smbutil.c b/src/sbbs3/smbutil.c
index 3b17537b46f45bf79d34ec7b2ba7be9827e936e9..f651220e6bf503d400ab76a8e60715fe230d83ac 100644
--- a/src/sbbs3/smbutil.c
+++ b/src/sbbs3/smbutil.c
@@ -53,7 +53,6 @@ const char *mon[]={"Jan","Feb","Mar","Apr","May","Jun"
 #endif
 
 #if defined(_WIN32)
-	#include <ctype.h>	/* isdigit() */
 	#include <conio.h>	/* getch() */
 #endif
 
@@ -447,7 +446,7 @@ void config(void)
 	printf("Last Message  =%-6"PRIu32" New Value (CR=No Change): "
 		,smb.status.last_msg);
 	gets(str);
-	if(isdigit(str[0]))
+	if(IS_DIGIT(str[0]))
 		last_msg = atol(str);
 	printf("Header offset =%-5"PRIu32"  New value (CR=No Change): "
 		,smb.status.header_offset);
@@ -479,15 +478,15 @@ void config(void)
 	}
 	if(last_msg != 0)
 		smb.status.last_msg = last_msg;
-	if(isdigit(max_msgs[0]))
+	if(IS_DIGIT(max_msgs[0]))
 		smb.status.max_msgs=atol(max_msgs);
-	if(isdigit(max_crcs[0]))
+	if(IS_DIGIT(max_crcs[0]))
 		smb.status.max_crcs=atol(max_crcs);
-	if(isdigit(max_age[0]))
+	if(IS_DIGIT(max_age[0]))
 		smb.status.max_age=atoi(max_age);
-	if(isdigit(header_offset[0]))
+	if(IS_DIGIT(header_offset[0]))
 		smb.status.header_offset=atol(header_offset);
-	if(isdigit(attr[0]))
+	if(IS_DIGIT(attr[0]))
 		smb.status.attr=atoi(attr);
 	i=smb_putstatus(&smb);
 	smb_unlocksmbhdr(&smb);
@@ -1511,7 +1510,7 @@ short str2tzone(const char* str)
 	char tmp[32];
 	short zone;
 
-	if(isdigit(*str) || *str=='-' || *str=='+') { /* [+|-]HHMM format */
+	if(IS_DIGIT(*str) || *str=='-' || *str=='+') { /* [+|-]HHMM format */
 		if(*str=='+') str++;
 		sprintf(tmp,"%.*s",*str=='-'? 3:2,str);
 		zone=atoi(tmp)*60;
@@ -1626,7 +1625,7 @@ int main(int argc, char **argv)
 			argv[x][0]=='/' ||		/* for backwards compatibilty */
 #endif
 			argv[x][0]=='-') {
-			if(isdigit(argv[x][1])) {
+			if(IS_DIGIT(argv[x][1])) {
 				count=strtol(argv[x]+1,NULL,10);
 				continue;
 			}
diff --git a/src/sbbs3/str.cpp b/src/sbbs3/str.cpp
index 2694a61dc2ee96c9a034f1da2e5f72ce1845cb20..d5286bf4b9552119d7be21dc89a92457d6429c99 100644
--- a/src/sbbs3/str.cpp
+++ b/src/sbbs3/str.cpp
@@ -255,15 +255,15 @@ void sbbs_t::sif(char *fname, char *answers, long len)
 				cr=1;
 				m++; 
 			}
-			if(isdigit((uchar)buf[m+1])) {
+			if(IS_DIGIT(buf[m+1])) {
 				max=buf[++m]&0xf;
-				if(isdigit((uchar)buf[m+1]))
+				if(IS_DIGIT(buf[m+1]))
 					max=max*10+(buf[++m]&0xf); 
 			}
-			if(buf[m+1]=='.' && isdigit((uchar)buf[m+2])) {
+			if(buf[m+1]=='.' && IS_DIGIT(buf[m+2])) {
 				m++;
 				min=buf[++m]&0xf;
-				if(isdigit((uchar)buf[m+1]))
+				if(IS_DIGIT(buf[m+1]))
 					min=min*10+(buf[++m]&0xf); 
 			}
 			if(buf[m+1]=='"') {
@@ -402,15 +402,15 @@ void sbbs_t::sof(char *fname, char *answers, long len)
 				cr=1;
 				m++; 
 			}
-			if(isdigit((uchar)buf[m+1])) {
+			if(IS_DIGIT(buf[m+1])) {
 				max=buf[++m]&0xf;
-				if(isdigit((uchar)buf[m+1]))
+				if(IS_DIGIT(buf[m+1]))
 					max=max*10+(buf[++m]&0xf); 
 			}
-			if(buf[m+1]=='.' && isdigit((uchar)buf[m+2])) {
+			if(buf[m+1]=='.' && IS_DIGIT(buf[m+2])) {
 				m++;
 				min=buf[++m]&0xf;
-				if(isdigit((uchar)buf[m+1]))
+				if(IS_DIGIT(buf[m+1]))
 					min=min*10+(buf[++m]&0xf); 
 			}
 			if(buf[m+1]=='"') {
@@ -542,9 +542,9 @@ size_t sbbs_t::gettmplt(char *strout, const char *templt, long mode)
 			}
 		}
 		else if(c<t) {
-			if(tmplt[c]=='N' && !isdigit((uchar)ch))
+			if(tmplt[c]=='N' && !IS_DIGIT(ch))
 				continue;
-			if(tmplt[c]=='A' && !isalpha((uchar)ch))
+			if(tmplt[c]=='A' && !IS_ALPHA(ch))
 				continue;
 			outchar(ch);
 			str[c++]=ch;
diff --git a/src/sbbs3/str_util.c b/src/sbbs3/str_util.c
index 065678a101d0332f90c76c55d22a2b11aa2ce578..e64133be0ea701cc35a4c71e3e4d14708eb74948 100644
--- a/src/sbbs3/str_util.c
+++ b/src/sbbs3/str_util.c
@@ -128,7 +128,7 @@ char* strip_space(const char *str, char* dest)
 	if(dest==NULL && (dest=strdup(str))==NULL)
 		return NULL;
 	for(i=j=0;str[i];i++)
-		if(!isspace((unsigned char)str[i]))
+		if(!IS_WHITESPACE(str[i]))
 			dest[j++]=str[i];
 	dest[j]=0;
 	return dest;
@@ -167,7 +167,7 @@ char* prep_file_desc(const char *str, char* dest)
 		}
 		else if(j && str[i]<=' ' && dest[j-1]==' ')
 			continue;
-		else if(i && !isalnum((unsigned char)str[i]) && str[i]==str[i-1])
+		else if(i && !IS_ALPHANUMERIC(str[i]) && str[i]==str[i-1])
 			continue;
 		else if((uchar)str[i]>=' ')
 			dest[j++]=str[i];
@@ -671,7 +671,7 @@ char* condense_whitespace(char* str)
 	char* s = str;
 	char* d = str;
 	while(*s != '\0') {
-		if(isspace((unsigned char)*s)) {
+		if(IS_WHITESPACE(*s)) {
 			*(d++) = ' ';
 			SKIP_WHITESPACE(s);
 		} else {
diff --git a/src/sbbs3/textgen.c b/src/sbbs3/textgen.c
index d8318d7b36a8a0165e330604c601e44897d710ad..476d0c60e124032a5f2f77d8ec30f7f8d4babc2b 100644
--- a/src/sbbs3/textgen.c
+++ b/src/sbbs3/textgen.c
@@ -27,7 +27,7 @@ char *readtext(FILE *stream, char **comment_ret)
 	}
 	comment[0]=0;
 	if(*(p+1)=='\\') {	/* merge multiple lines */
-		for(cp=p+2; *cp && isspace(*cp); cp++);
+		for(cp=p+2; *cp && IS_WHITESPACE(*cp); cp++);
 		truncsp(cp);
 		strcat(comment, cp);
 		while(strlen(buf)<2000) {
@@ -39,7 +39,7 @@ char *readtext(FILE *stream, char **comment_ret)
 			strcpy(p,p2+1);
 			p=strrchr(p,'"');
 			if(p && *(p+1)=='\\') {
-				for(cp=p+2; *cp && isspace(*cp); cp++);
+				for(cp=p+2; *cp && IS_WHITESPACE(*cp); cp++);
 				truncsp(cp);
 				strcat(comment, cp);
 				continue;
@@ -48,7 +48,7 @@ char *readtext(FILE *stream, char **comment_ret)
 		}
 	}
 	else {
-		for(cp=p+2; *cp && isspace(*cp); cp++);
+		for(cp=p+2; *cp && IS_WHITESPACE(*cp); cp++);
 		strcat(comment, cp);
 		truncsp(comment);
 	}
@@ -57,10 +57,10 @@ char *readtext(FILE *stream, char **comment_ret)
 	for(i=1,j=0;i<k;j++) {
 		if(buf[i]=='\\')	{ /* escape */
 			i++;
-			if(isdigit(buf[i])) {
+			if(IS_DIGIT(buf[i])) {
 				str[j]=atoi(buf+i); 	/* decimal, NOT octal */
-				if(isdigit(buf[++i]))	/* skip up to 3 digits */
-					if(isdigit(buf[++i]))
+				if(IS_DIGIT(buf[++i]))	/* skip up to 3 digits */
+					if(IS_DIGIT(buf[++i]))
 						i++;
 				continue; 
 			}
@@ -227,7 +227,7 @@ int main(int argc, char **argv)
 				fprintf(stderr,"Error creating C string! for %d\n", i+1);
 			}
 			lno=strtoul(comment, &macro, 10);
-			while(isspace(*macro))
+			while(IS_WHITESPACE(*macro))
 				macro++;
 			if((int)lno != i) {
 				fprintf(stderr,"Mismatch! %s has %ld... should be %d\n", comment, lno, i);
diff --git a/src/sbbs3/upload.cpp b/src/sbbs3/upload.cpp
index 4733ad1cabb11c9298b033bb6089e9c731805568..13e6c2a9f50023695e82f72b8cb3819aabf0dc08 100644
--- a/src/sbbs3/upload.cpp
+++ b/src/sbbs3/upload.cpp
@@ -174,7 +174,7 @@ bool sbbs_t::uploadfile(file_t *f)
 					strip_exascii(desc, desc);
 					prep_file_desc(desc, desc);
 					for(i=0;desc[i];i++)
-						if(isalnum(desc[i]))
+						if(IS_ALPHANUMERIC(desc[i]))
 							break;
 					sprintf(f->desc,"%.*s",LEN_FDESC,desc+i); 
 				}
@@ -412,7 +412,7 @@ bool sbbs_t::upload(uint dirnum)
 		SYNC;
 		bputs(text[RateThisFile]);
 		ch=getkey(K_ALPHA);
-		if(!isalpha(ch) || sys_status&SS_ABORT)
+		if(!IS_ALPHA(ch) || sys_status&SS_ABORT)
 			return(false);
 		CRLF;
 		sprintf(descbeg,text[Rated],toupper(ch)); 
diff --git a/src/sbbs3/userdat.c b/src/sbbs3/userdat.c
index 16710240be927f81d78e36f0e4660da8110d2025..c90ad560b1d7657d437f8dfc86f286977bcf08d5 100644
--- a/src/sbbs3/userdat.c
+++ b/src/sbbs3/userdat.c
@@ -745,7 +745,7 @@ int putusername(scfg_t* cfg, int number, char *name)
 
 int getbirthyear(const char* birth)
 {
-	if(isdigit(birth[2]))				// CCYYMMYY format
+	if(IS_DIGIT(birth[2]))				// CCYYMMYY format
 		return DECVAL(birth[0], 1000)
 				+ DECVAL(birth[1], 100)
 				+ DECVAL(birth[2], 10)
@@ -764,7 +764,7 @@ int getbirthyear(const char* birth)
 
 int getbirthmonth(scfg_t* cfg, const char* birth)
 {
-	if(isdigit(birth[5]))				// CCYYMMYY format
+	if(IS_DIGIT(birth[5]))				// CCYYMMYY format
 		return DECVAL(birth[4], 10)	+ DECVAL(birth[5], 1);
 	if(cfg->sys_misc & SM_EURODATE) {	// DD/MM/YY format
 		return DECVAL(birth[3], 10) + DECVAL(birth[4], 1);
@@ -775,7 +775,7 @@ int getbirthmonth(scfg_t* cfg, const char* birth)
 
 int getbirthday(scfg_t* cfg, const char* birth)
 {
-	if(isdigit(birth[5]))				// CCYYMMYY format
+	if(IS_DIGIT(birth[5]))				// CCYYMMYY format
 		return DECVAL(birth[6], 10)	+ DECVAL(birth[7], 1);
 	if(cfg->sys_misc & SM_EURODATE) {	// DD/MM/YY format
 		return DECVAL(birth[0], 10) + DECVAL(birth[1], 1);
@@ -3128,7 +3128,7 @@ BOOL check_name(scfg_t* cfg, const char* name)
 		return FALSE;
 	if (   name[0] <= ' '			/* begins with white-space? */
 		|| name[len-1] <= ' '		/* ends with white-space */
-		|| !isalpha(name[0])
+		|| !IS_ALPHA(name[0])
 		|| !stricmp(name,cfg->sys_id)
 		|| strchr(name,0xff)
 		|| matchuser(cfg,name,TRUE /* sysop_alias */)
diff --git a/src/sbbs3/useredit.cpp b/src/sbbs3/useredit.cpp
index a24199d918a2bdb897da0844024c9d96b2e0e7af..97042c495595824bec22c6f335ebdc0c286508b6 100644
--- a/src/sbbs3/useredit.cpp
+++ b/src/sbbs3/useredit.cpp
@@ -293,7 +293,7 @@ void sbbs_t::useredit(int usernumber)
 						menu(str);
 						continue; 
 					}
-					if(isdigit(c)) {
+					if(IS_DIGIT(c)) {
 						i=c&0xf;
 						continue; 
 					}
@@ -343,7 +343,7 @@ void sbbs_t::useredit(int usernumber)
 			case 'G':
 				bputs(text[GoToUser]);
 				if(getstr(str,LEN_ALIAS,K_UPPER|K_LINE)) {
-					if(isdigit(str[0])) {
+					if(IS_DIGIT(str[0])) {
 						i=atoi(str);
 						if(i>lastuser(&cfg))
 							break;
@@ -503,7 +503,7 @@ void sbbs_t::useredit(int usernumber)
 				ASYNC;
 				bputs(text[QuickValidatePrompt]);
 				c=getkey(0);
-				if(!isdigit(c))
+				if(!IS_DIGIT(c))
 					break;
 				i=c&0xf;
 				user.level=cfg.val_level[i];
diff --git a/src/sbbs3/websrvr.c b/src/sbbs3/websrvr.c
index c6330ecd897fe33a6b813a8a72f400f43bc293a5..92062d890e9d8548836b1c385682a5074243e65d 100644
--- a/src/sbbs3/websrvr.c
+++ b/src/sbbs3/websrvr.c
@@ -2279,7 +2279,7 @@ static void unescape(char *p)
 
 	dst=p;
 	for(;*p;p++) {
-		if(*p=='%' && isxdigit((uchar)*(p+1)) && isxdigit((uchar)*(p+2))) {
+		if(*p=='%' && IS_HEXDIGIT(*(p+1)) && IS_HEXDIGIT(*(p+2))) {
 			sprintf(code,"%.2s",p+1);
 			*(dst++)=(char)strtol(code,NULL,16);
 			p+=2;
@@ -2528,7 +2528,7 @@ static char *get_token_value(char **p)
 		}
 	}
 end_of_text:
-	while(*pos==',' || isspace(*pos))
+	while(*pos==',' || IS_WHITESPACE(*pos))
 		pos++;
 	*out=0;
 	*p=pos;
@@ -2602,7 +2602,7 @@ static BOOL parse_headers(http_session_t * session)
 								session->req.auth.type=AUTHENTICATION_DIGEST;
 								/* Parse out values one at a time and store */
 								while(p != NULL && *p) {
-									while(isspace(*p))
+									while(IS_WHITESPACE(*p))
 										p++;
 									if(strnicmp(p,"username=",9)==0) {
 										p+=9;
@@ -2865,7 +2865,7 @@ static BOOL parse_js_headers(http_session_t * session)
 
 						p=value;
 						while((key=strtok_r(p,"=",&last))!=NULL) {
-							while(isspace(*key))
+							while(IS_WHITESPACE(*key))
 								key++;
 							p=NULL;
 							if((val=strtok_r(p,";\t\n\v\f\r ",&last))!=NULL) {	/* Whitespace */
@@ -2954,7 +2954,7 @@ static char * split_port_part(char *host)
 	char *ret = NULL;
 	char *p=strchr(host, 0)-1;
 
-	if (isdigit(*p)) {
+	if (IS_DIGIT(*p)) {
 		/*
 		 * If the first and last : are not the same, and it doesn't
 		 * start with '[', there's no port part.
@@ -2969,7 +2969,7 @@ static char * split_port_part(char *host)
 				ret = p+1;
 				break;
 			}
-			if (!isdigit(*p))
+			if (!IS_DIGIT(*p))
 				break;
 		}
 	}
@@ -5460,7 +5460,7 @@ js_login(JSContext *cx, uintN argc, jsval *arglist)
 
 	memset(&user,0,sizeof(user));
 
-	if(isdigit((uchar)*username))
+	if(IS_DIGIT(*username))
 		user.number=atoi(username);
 	else if(*username)
 		user.number=matchuser(&scfg,username,FALSE);
diff --git a/src/sbbs3/wordwrap.c b/src/sbbs3/wordwrap.c
index 8b6a4f7b90f633d6315b633a8335e8351e0228be..1885a7fbe72527899cd554657cbf543a4de771ee 100644
--- a/src/sbbs3/wordwrap.c
+++ b/src/sbbs3/wordwrap.c
@@ -214,7 +214,7 @@ static struct section_len get_ws_len(char *buf, int col)
 	for(ret.bytes=0; ; ret.bytes++) {
 		if (!buf[ret.bytes])
 			break;
-		if (!isspace((unsigned char)buf[ret.bytes]))
+		if (!IS_WHITESPACE(buf[ret.bytes]))
 			break;
 		if(buf[ret.bytes] == '\t') {
 			ret.len++;
@@ -246,7 +246,7 @@ static struct section_len get_word_len(char *buf, int maxlen, BOOL is_utf8)
 		len = 1;
 		if (!buf[ret.bytes])
 			break;
-		else if (isspace((unsigned char)buf[ret.bytes]))
+		else if (IS_WHITESPACE(buf[ret.bytes]))
 			break;
 		else if (buf[ret.bytes]==DEL)
 			continue;
diff --git a/src/sbbs3/writemsg.cpp b/src/sbbs3/writemsg.cpp
index b049f91013b73fa104f16b87ccbfbe4211b73997..5c77a025671b1018ae5a7b46f92ee1273c38b814 100644
--- a/src/sbbs3/writemsg.cpp
+++ b/src/sbbs3/writemsg.cpp
@@ -422,7 +422,7 @@ bool sbbs_t::writemsg(const char *fname, const char *top, char *subj, long mode,
 					continue; 
 				}
 
-				if(!isdigit(quote[0]))
+				if(!IS_DIGIT(quote[0]))
 					break;
 				p=quote;
 				while(p) {
diff --git a/src/sbbs3/xtrn.cpp b/src/sbbs3/xtrn.cpp
index 1b00fe322b8188b34beaea90588f2c24b5fafead..9c8b6dee3cd574deb3d865016d92b508396a6f6f 100644
--- a/src/sbbs3/xtrn.cpp
+++ b/src/sbbs3/xtrn.cpp
@@ -1842,7 +1842,7 @@ const char* quoted_string(const char* str, char* buf, size_t maxlen)
 }
 
 #define QUOTED_STRING(ch, str, buf, maxlen) \
-	((isalpha(ch) && isupper(ch)) ? str : quoted_string(str,buf,maxlen))
+	((IS_ALPHA(ch) && IS_UPPERCASE(ch)) ? str : quoted_string(str,buf,maxlen))
 
 /*****************************************************************************/
 /* Returns command line generated from instr with %c replacements            */
@@ -1864,7 +1864,7 @@ char* sbbs_t::cmdstr(const char *instr, const char *fpath, const char *fspec, ch
             cmd[j]=0;
 			int avail = maxlen - j;
 			char ch=instr[i];
-			if(isalpha(ch))
+			if(IS_ALPHA(ch))
 				ch=toupper(ch);
             switch(ch) {
                 case 'A':   /* User alias */
@@ -2000,7 +2000,7 @@ char* sbbs_t::cmdstr(const char *instr, const char *fpath, const char *fspec, ch
 					strncat(cmd, ARCHITECTURE_DESC, avail);
 					break;
                 default:    /* unknown specification */
-                    if(isdigit(instr[i])) {
+                    if(IS_DIGIT(instr[i])) {
                         sprintf(str,"%0*d",instr[i]&0xf,useron.number);
                         strncat(cmd,str, avail); }
                     break; }
@@ -2033,7 +2033,7 @@ char* DLLCALL cmdstr(scfg_t* cfg, user_t* user, const char* instr, const char* f
             cmd[j]=0;
 			int avail = maxlen - j;
 			char ch=instr[i];
-			if(isalpha(ch))
+			if(IS_ALPHA(ch))
 				ch=toupper(ch);
             switch(ch) {
                 case 'A':   /* User alias */
@@ -2168,7 +2168,7 @@ char* DLLCALL cmdstr(scfg_t* cfg, user_t* user, const char* instr, const char* f
 					strncat(cmd, ARCHITECTURE_DESC, avail);
 					break;
                 default:    /* unknown specification */
-                    if(isdigit(instr[i]) && user!=NULL) {
+                    if(IS_DIGIT(instr[i]) && user!=NULL) {
                         sprintf(str,"%0*d",instr[i]&0xf,user->number);
                         strncat(cmd,str, avail);
 					}
diff --git a/src/sbbs3/xtrn_sec.cpp b/src/sbbs3/xtrn_sec.cpp
index e96940768b6f07942b108706204228afbee15bfa..d6654bcb95c6e47f5c2135571e4ab4ed279f189e 100644
--- a/src/sbbs3/xtrn_sec.cpp
+++ b/src/sbbs3/xtrn_sec.cpp
@@ -1246,7 +1246,7 @@ void sbbs_t::moduserdat(uint xtrnnum)
 			for(i=0;i<15;i++)			/* skip first 14 lines */
 				if(!fgets(str,128,stream))
 					break;
-			if(i==15 && isdigit(str[0])) {
+			if(i==15 && IS_DIGIT(str[0])) {
 				mod=atoi(str);
 				if(mod<SYSOP_LEVEL) {
 					useron.level=(char)mod;
@@ -1265,11 +1265,11 @@ void sbbs_t::moduserdat(uint xtrnnum)
 			for(;i<25;i++)
 				if(!fgets(str,128,stream))
 					break;
-			if(i==25 && isdigit(str[0]) && isdigit(str[1])
+			if(i==25 && IS_DIGIT(str[0]) && IS_DIGIT(str[1])
 				&& (str[2]=='/' || str[2]=='-') /* xx/xx/xx or xx-xx-xx */
-				&& isdigit(str[3]) && isdigit(str[4])
+				&& IS_DIGIT(str[3]) && IS_DIGIT(str[4])
 				&& (str[5]=='/' || str[5]=='-')
-				&& isdigit(str[6]) && isdigit(str[7])) { /* valid expire date */
+				&& IS_DIGIT(str[6]) && IS_DIGIT(str[7])) { /* valid expire date */
 				useron.expire=(ulong)dstrtounix(&cfg,str);
 				putuserrec(&cfg,useron.number,U_EXPIRE,8,ultoa((ulong)useron.expire,tmp,16)); 
 			}
@@ -1296,7 +1296,7 @@ void sbbs_t::moduserdat(uint xtrnnum)
 			for(;i<42;i++)
 				if(!fgets(str,128,stream))
 					break;
-			if(i==42 && isdigit(str[0])) {	/* Time Credits in Minutes */
+			if(i==42 && IS_DIGIT(str[0])) {	/* Time Credits in Minutes */
 				useron.min=atol(str);
 				putuserrec(&cfg,useron.number,U_MIN,10,ultoa(useron.min,tmp,10)); 
 			}
@@ -1351,7 +1351,7 @@ void sbbs_t::moduserdat(uint xtrnnum)
 		}
 		if(fgets(str,81,stream)) {		/* main level */
 			mod=atoi(str);
-			if(isdigit(str[0]) && mod<SYSOP_LEVEL) {
+			if(IS_DIGIT(str[0]) && mod<SYSOP_LEVEL) {
 				useron.level=(uchar)mod;
 				putuserrec(&cfg,useron.number,U_LEVEL,2,ultoa(useron.level,tmp,10)); 
 			} 
diff --git a/src/smblib/smbstr.c b/src/smblib/smbstr.c
index 47c7a02da5b38e578b4961f00c18fa2b71e05f91..d73662d411cc6a0b121ac39bdde2ce4c93d0d3f8 100644
--- a/src/smblib/smbstr.c
+++ b/src/smblib/smbstr.c
@@ -131,7 +131,7 @@ uint16_t SMBCALL smb_hfieldtypelookup(const char* str)
 {
 	uint16_t type;
 
-	if(isdigit(*str))
+	if(IS_DIGIT(*str))
 		return((uint16_t)strtol(str,NULL,0));
 
 	for(type=0;type<=UNUSED;type++)
@@ -395,13 +395,13 @@ enum smb_net_type SMBCALL smb_get_net_type_by_addr(const char* addr)
 	char* colon = strchr(p,':');
 	char* slash = strchr(p,'/');
 
-	if(at == NULL && isalpha(*p) && dot == NULL && colon == NULL)
+	if(at == NULL && IS_ALPHA(*p) && dot == NULL && colon == NULL)
 		return NET_QWK;
 
 	char last = 0;
 	for(tp = p; *tp != '\0'; tp++) {
 		last = *tp;
-		if(isdigit(*tp))
+		if(IS_DIGIT(*tp))
 			continue;
 		if(*tp == ':') {
 			if(tp != colon)
@@ -426,7 +426,7 @@ enum smb_net_type SMBCALL smb_get_net_type_by_addr(const char* addr)
 		}
 		break;
 	}
-	if(at == NULL && isdigit(*p) && *tp == '\0' && isdigit(last))
+	if(at == NULL && IS_DIGIT(*p) && *tp == '\0' && IS_DIGIT(last))
 		return NET_FIDO;
 	if(slash == NULL && (isalnum(*p) || p == colon))
 		return NET_INTERNET;
diff --git a/src/smblib/smbtxt.c b/src/smblib/smbtxt.c
index 84a4aab9d59b76c86b3e690e7ace56a769493e7c..1f1219c004bd16db6a68b9a64a4824be8a74ad04 100644
--- a/src/smblib/smbtxt.c
+++ b/src/smblib/smbtxt.c
@@ -234,7 +234,7 @@ char* qp_decode(char* buf)
 				break;
 			if(*p == '\n')
 				continue;
-			if(isxdigit(*p) && isxdigit(*(p+1))) {
+			if(IS_HEXDIGIT(*p) && IS_HEXDIGIT(*(p+1))) {
 				uchar ch = HEX_CHAR_TO_INT(*p) << 4;
 				p++;
 				ch |= HEX_CHAR_TO_INT(*p);
diff --git a/src/xpdev/dirwrap.c b/src/xpdev/dirwrap.c
index 2882ddaadf80f9809df2996a6ebe1922a82e8b50..49006c6a5a21dd05503b6fa4293938b0e03d7ba7 100644
--- a/src/xpdev/dirwrap.c
+++ b/src/xpdev/dirwrap.c
@@ -612,7 +612,7 @@ BOOL DLLCALL fexistcase(char *path)
 	SAFECOPY(fname,p);
 	*p=0;
 	for(i=0;fname[i];i++)  {
-		if(isalpha(fname[i]))
+		if(IS_ALPHA(fname[i]))
 			sprintf(tmp,"[%c%c]",toupper(fname[i]),tolower(fname[i]));
 		else
 			sprintf(tmp,"%c",fname[i]);
@@ -733,7 +733,7 @@ int removecase(const char *path)
 	p=getfname(inpath);
 	fname[0]=0;
 	for(i=0;p[i];i++)  {
-		if(isalpha(p[i]))
+		if(IS_ALPHA(p[i]))
 			sprintf(tmp,"[%c%c]",toupper(p[i]),tolower(p[i]));
 		else
 			sprintf(tmp,"%c",p[i]);
@@ -1099,7 +1099,7 @@ BOOL DLLCALL isfullpath(const char* filename)
 {
 	return(filename[0]=='/'
 #ifdef WIN32
-		|| filename[0]=='\\' || (isalpha(filename[0]) && filename[1]==':')
+		|| filename[0]=='\\' || (IS_ALPHA(filename[0]) && filename[1]==':')
 #endif
 		);
 }
diff --git a/src/xpdev/gen_defs.h b/src/xpdev/gen_defs.h
index c38856ac7518e23653aa6f64ca6e501abfac2bb7..68decddfa2bc1589fac5773d09c08e5a44835f04 100644
--- a/src/xpdev/gen_defs.h
+++ b/src/xpdev/gen_defs.h
@@ -416,33 +416,42 @@ typedef struct {
 #define SAFEPRINTF4(dst,fmt,a1,a2,a3,a4)	snprintf(dst,sizeof(dst),fmt,a1,a2,a3,a4), TERMINATE(dst)
 #endif
 
-/* Replace every occurance of c1 in str with c2, using p as a temporary char pointer */
+/* Replace every occurrence of c1 in str with c2, using p as a temporary char pointer */
 #define REPLACE_CHARS(str,c1,c2,p)      for((p)=(str);*(p);(p)++) if(*(p)==(c1)) *(p)=(c2);
 
 /* ASCIIZ char* parsing helper macros */
-#define SKIP_WHITESPACE(p)              while(*(p) && isspace((unsigned char)*(p)))             (p)++;
-#define FIND_WHITESPACE(p)              while(*(p) && !isspace((unsigned char)*(p)))            (p)++;
-#define SKIP_CHAR(p,c)                  while(*(p)==c)                                          (p)++;
-#define FIND_CHAR(p,c)                  while(*(p) && *(p)!=c)                                  (p)++;
-#define SKIP_CHARSET(p,s)               while(*(p) && strchr(s,*(p))!=NULL)                     (p)++;
-#define FIND_CHARSET(p,s)               while(*(p) && strchr(s,*(p))==NULL)                     (p)++;
+/* These (unsigned char) typecasts defeat MSVC debug assertion when passed a negative value */
+#define IS_WHITESPACE(c)				isspace((unsigned char)(c))
+#define IS_CONTROL(c)					iscntrl((unsigned char)(c))
+#define IS_ALPHA(c)						isalpha((unsigned char)(c))
+#define IS_ALPHANUMERIC(c)				isalnum((unsigned char)(c))
+#define IS_UPPERCASE(c)					isupper((unsigned char)(c))
+#define IS_LOWERCASE(c)					islower((unsigned char)(c))
+#define IS_PUNCTUATION(c)				ispunct((unsigned char)(c))
+#define IS_PRINTABLE(c)					isprint((unsigned char)(c))
+#define IS_DIGIT(c)						isdigit((unsigned char)(c))
+#define IS_HEXDIGIT(c)					isxdigit((unsigned char)(c))
+#define IS_OCTDIGIT(c)					((c) >= '0' && (c) <= '7')
+#define SKIP_WHITESPACE(p)              while(*(p) && IS_WHITESPACE(*(p)))        (p)++;
+#define FIND_WHITESPACE(p)              while(*(p) && !IS_WHITESPACE(*(p)))       (p)++;
+#define SKIP_CHAR(p,c)                  while(*(p)==c)                            (p)++;
+#define FIND_CHAR(p,c)                  while(*(p) && *(p)!=c)                    (p)++;
+#define SKIP_CHARSET(p,s)               while(*(p) && strchr(s,*(p))!=NULL)       (p)++;
+#define FIND_CHARSET(p,s)               while(*(p) && strchr(s,*(p))==NULL)       (p)++;
 #define SKIP_CRLF(p)					SKIP_CHARSET(p, "\r\n")
 #define FIND_CRLF(p)					FIND_CHARSET(p, "\r\n")
-#define SKIP_ALPHA(p)                   while(*(p) && isalpha((unsigned char)*(p)))             (p)++;
-#define FIND_ALPHA(p)                   while(*(p) && !isalpha((unsigned char)*(p)))            (p)++;
-#define SKIP_ALPHANUMERIC(p)            while(*(p) && isalnum((unsigned char)*(p)))             (p)++;
-#define FIND_ALPHANUMERIC(p)            while(*(p) && !isalnum((unsigned char)*(p)))            (p)++;
-#define SKIP_DIGIT(p)                   while(*(p) && isdigit((unsigned char)*(p)))             (p)++;
-#define FIND_DIGIT(p)                   while(*(p) && !isdigit((unsigned char)*(p)))            (p)++;
-#define SKIP_HEXDIGIT(p)                while(*(p) && isxdigit((unsigned char)*(p)))            (p)++;
-#define FIND_HEXDIGIT(p)                while(*(p) && !isxdigit((unsigned char)*(p)))           (p)++;
+#define SKIP_ALPHA(p)                   while(*(p) && IS_ALPHA(*(p)))             (p)++;
+#define FIND_ALPHA(p)                   while(*(p) && !IS_ALPHA(*(p)))            (p)++;
+#define SKIP_ALPHANUMERIC(p)            while(*(p) && IS_ALPHANUMERIC(*(p)))      (p)++;
+#define FIND_ALPHANUMERIC(p)            while(*(p) && !IS_ALPHANUMERIC(*(p)))     (p)++;
+#define SKIP_DIGIT(p)                   while(*(p) && IS_DIGIT(*(p)))             (p)++;
+#define FIND_DIGIT(p)                   while(*(p) && !IS_DIGIT(*(p)))            (p)++;
+#define SKIP_HEXDIGIT(p)                while(*(p) && IS_HEXDIGIT(*(p)))          (p)++;
+#define FIND_HEXDIGIT(p)                while(*(p) && !IS_HEXDIGIT(*(p)))         (p)++;
 
 #define HEX_CHAR_TO_INT(ch) 			(((ch)&0xf)+(((ch)>>6)&1)*9)
 #define DEC_CHAR_TO_INT(ch)				((ch)&0xf)
 #define OCT_CHAR_TO_INT(ch)				((ch)&0x7)
-#ifndef isodigit
-#define isodigit(ch)					((ch) >= '0' && (ch) <= '7')
-#endif
 
 /* Variable/buffer initialization (with zeros) */
 #define ZERO_VAR(var)                           memset(&(var),0,sizeof(var))
diff --git a/src/xpdev/genwrap.c b/src/xpdev/genwrap.c
index a9b0b31320ab4bb3c2d984f56874cd1cc979f577..5a72fee45c3f57c0f7f06b9ede47977157eee0ad 100644
--- a/src/xpdev/genwrap.c
+++ b/src/xpdev/genwrap.c
@@ -157,27 +157,27 @@ char DLLCALL c_unescape_char_ptr(const char* str, char** endptr)
 		int digits = 0;		// \x## for hexadecimal character literals (only 2 digits supported)
 		++str;
 		ch = 0;
-		while(digits < 2 && isxdigit(*str)) {
+		while(digits < 2 && IS_HEXDIGIT(*str)) {
 			ch *= 0x10;	
 			ch += HEX_CHAR_TO_INT(*str);
 			str++;
 			digits++;
 		}
 #ifdef C_UNESCAPE_OCTAL_SUPPORT
-	} else if(isodigit(*str)) {
+	} else if(IS_OCTDIGIT(*str)) {
 		int digits = 0;		// \### for octal character literals (only 3 digits supported)
 		ch = 0;
-		while(digits < 3 && isodigit(*str)) {
+		while(digits < 3 && IS_OCTDIGIT(*str)) {
 			ch *= 8;
 			ch += OCT_CHAR_TO_INT(*str);
 			str++;
 			digits++;
 		}
 #else
-	} else if(isdigit(*str)) {
-		int digits = 0;		// \### for decimal charater literals (only 3 digits supported)
+	} else if(IS_DIGIT(*str)) {
+		int digits = 0;		// \### for decimal character literals (only 3 digits supported)
 		ch = 0;
-		while(digits < 3 && isdigit(*str)) {
+		while(digits < 3 && IS_DIGIT(*str)) {
 			ch *= 10;
 			ch += DEC_CHAR_TO_INT(*str);
 			str++;
@@ -725,7 +725,7 @@ char* DLLCALL truncsp(char* str)
 
 	if(str!=NULL) {
 		i=len=strlen(str);
-		while(i && isspace((unsigned char)str[i-1]))
+		while(i && IS_WHITESPACE(str[i-1]))
 			i--;
 		if(i!=len)
 			str[i]=0;	/* truncate */
diff --git a/src/xpdev/ini_file.c b/src/xpdev/ini_file.c
index 074be46920fe0ee1a9347c13327ba1b484762daf..b096a82450e8092b456ebec83aa5069f54bbd335 100644
--- a/src/xpdev/ini_file.c
+++ b/src/xpdev/ini_file.c
@@ -1358,7 +1358,7 @@ static BOOL isTrue(const char* value)
 	char*	p;
 	BOOL	is_true;
 
-	if(!isalpha(*value))
+	if(!IS_ALPHA(*value))
 		return FALSE;
 
 	if((str=strdup(value)) == NULL)
@@ -1933,7 +1933,7 @@ static unsigned parseEnum(const char* value, str_list_t names, unsigned deflt)
 			return(i);
 
     i=strtoul(val, &endptr, 0);
-	if(*endptr != 0 && !isspace(*endptr))
+	if(*endptr != 0 && !IS_WHITESPACE(*endptr))
 		return deflt;
 	if(i>=count)
 		i=count-1;
diff --git a/src/xpdev/netwrap.c b/src/xpdev/netwrap.c
index b212c986b92b4cfd76262d79ce2f6ad7ca7a2a70..e4f13a637de09abc962618ab6945b551d7066837 100644
--- a/src/xpdev/netwrap.c
+++ b/src/xpdev/netwrap.c
@@ -40,7 +40,6 @@
 #include "netwrap.h"	/* verify prototypes */
 
 #include <stdlib.h>		/* malloc() */
-#include <ctype.h>		/* isspace() */
 
 #if defined(_WIN32)
 	#include <iphlpapi.h>	/* GetNetworkParams */