[klibc] Provide out-of-line versions of the ctype functions

Some programs need to be able to call the ctype functions indirectly.
Accordingly, we need to make them available in the library.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
diff --git a/include/ctype.h b/include/ctype.h
index daa6a8e..8da9a5f 100644
--- a/include/ctype.h
+++ b/include/ctype.h
@@ -7,12 +7,6 @@
 #ifndef _CTYPE_H
 #define _CTYPE_H
 
-#ifndef __CTYPE_NO_INLINE
-# define __ctype_inline extern __inline__
-#else
-# define __ctype_inline
-#endif
-
 /*
  * This relies on the following definitions:
  *
@@ -34,70 +28,70 @@
 
 extern const unsigned char __ctypes[];
 
-__ctype_inline int isalnum(int __c)
+static inline int __ctype_isalnum(int __c)
 {
   return __ctypes[__c+1] &
     (__ctype_upper|__ctype_lower|__ctype_digit);
 }
 
-__ctype_inline int isalpha(int __c)
+static inline int __ctype_isalpha(int __c)
 {
   return __ctypes[__c+1] &
     (__ctype_upper|__ctype_lower);
 }
 
-__ctype_inline int isascii(int __c)
+static inline int __ctype_isascii(int __c)
 {
   return !(__c & ~0x7f);
 }
 
-__ctype_inline int isblank(int __c)
+static inline int __ctype_isblank(int __c)
 {
   return (__c == '\t') || (__c == ' ');
 }
 
-__ctype_inline int iscntrl(int __c)
+static inline int __ctype_iscntrl(int __c)
 {
   return __ctypes[__c+1] & __ctype_cntrl;
 }
 
-__ctype_inline int isdigit(int __c)
+static inline int __ctype_isdigit(int __c)
 {
   return ((unsigned)__c - '0') <= 9;
 }
 
-__ctype_inline int isgraph(int __c)
+static inline int __ctype_isgraph(int __c)
 {
   return __ctypes[__c+1] &
     (__ctype_upper|__ctype_lower|__ctype_digit|__ctype_punct);
 }
 
-__ctype_inline int islower(int __c)
+static inline int __ctype_islower(int __c)
 {
   return __ctypes[__c+1] & __ctype_lower;
 }
 
-__ctype_inline int isprint(int __c)
+static inline int __ctype_isprint(int __c)
 {
   return __ctypes[__c+1] & __ctype_print;
 }
 
-__ctype_inline int ispunct(int __c)
+static inline int __ctype_ispunct(int __c)
 {
   return __ctypes[__c+1] & __ctype_punct;
 }
 
-__ctype_inline int isspace(int __c)
+static inline int __ctype_isspace(int __c)
 {
   return __ctypes[__c+1] & __ctype_space;
 }
 
-__ctype_inline int isupper(int __c)
+static inline int __ctype_isupper(int __c)
 {
   return __ctypes[__c+1] & __ctype_upper;
 }
 
-__ctype_inline int isxdigit(int __c)
+static inline int __ctype_isxdigit(int __c)
 {
   return __ctypes[__c+1] & __ctype_xdigit;
 }
@@ -106,14 +100,37 @@
 #define _toupper(__c) ((__c) & ~32)
 #define _tolower(__c) ((__c) | 32)
 
-__ctype_inline int toupper(int __c)
+static inline int __ctype_toupper(int __c)
 {
-  return islower(__c) ? _toupper(__c) : __c;
+  return __ctype_islower(__c) ? _toupper(__c) : __c;
 }
 
-__ctype_inline int tolower(int __c)
+static inline int __ctype_tolower(int __c)
 {
-  return isupper(__c) ? _tolower(__c) : __c;
+  return __ctype_isupper(__c) ? _tolower(__c) : __c;
 }
 
+#ifndef __CTYPE_NO_INLINE
+#define __CTYPEFUNC(X) \
+  extern inline int X(int __c)			\
+  {						\
+    return __ctype_##X(__c); 			\
+  }
+__CTYPEFUNC(isalnum)
+__CTYPEFUNC(isalpha)
+__CTYPEFUNC(isascii)
+__CTYPEFUNC(isblank)
+__CTYPEFUNC(iscntrl)
+__CTYPEFUNC(isdigit)
+__CTYPEFUNC(isgraph)
+__CTYPEFUNC(islower)
+__CTYPEFUNC(isprint)
+__CTYPEFUNC(ispunct)
+__CTYPEFUNC(isspace)
+__CTYPEFUNC(isupper)
+__CTYPEFUNC(isxdigit)
+__CTYPEFUNC(toupper)
+__CTYPEFUNC(tolower)
+#endif /* __CTYPE_NO_INLINE */
+
 #endif /* _CTYPE_H */
diff --git a/klibc/Kbuild b/klibc/Kbuild
index 6741a1c..9e651d0 100644
--- a/klibc/Kbuild
+++ b/klibc/Kbuild
@@ -45,7 +45,12 @@
 	  lrand48.o jrand48.o mrand48.o nrand48.o srand48.o seed48.o \
 	  inet/inet_ntoa.o inet/inet_aton.o inet/inet_addr.o \
 	  inet/inet_ntop.o inet/inet_pton.o inet/bindresvport.o \
-	  send.o recv.o
+	  send.o recv.o \
+	  ctype/isalnum.o ctype/isalpha.o ctype/isascii.o \
+	  ctype/isblank.o ctype/iscntrl.o ctype/isdigit.o \
+	  ctype/isgraph.o ctype/islower.o ctype/isprint.o \
+	  ctype/ispunct.o ctype/isspace.o ctype/isupper.o \
+	  ctype/isxdigit.o ctype/tolower.o ctype/toupper.o
 
 libc-$(CONFIG_KLIBC_ERRLIST) += errlist.o
 
diff --git a/klibc/ctype/ctypefunc.h b/klibc/ctype/ctypefunc.h
new file mode 100644
index 0000000..f9e247d
--- /dev/null
+++ b/klibc/ctype/ctypefunc.h
@@ -0,0 +1,13 @@
+/*
+ * ctype/ctype.h
+ *
+ * Common header for out-of-line ctype functions
+ */
+
+#define __CTYPE_NO_INLINE
+#include <ctype.h>
+
+#define CTYPEFUNC(X)				\
+  int X(int c) {				\
+    return __ctype_##X(c);			\
+  }
diff --git a/klibc/ctype/isalnum.c b/klibc/ctype/isalnum.c
new file mode 100644
index 0000000..57af18b
--- /dev/null
+++ b/klibc/ctype/isalnum.c
@@ -0,0 +1,2 @@
+#include "ctypefunc.h"
+CTYPEFUNC(isalnum)
diff --git a/klibc/ctype/isalpha.c b/klibc/ctype/isalpha.c
new file mode 100644
index 0000000..8f2effe
--- /dev/null
+++ b/klibc/ctype/isalpha.c
@@ -0,0 +1,2 @@
+#include "ctypefunc.h"
+CTYPEFUNC(isalpha)
diff --git a/klibc/ctype/isascii.c b/klibc/ctype/isascii.c
new file mode 100644
index 0000000..6a974d5
--- /dev/null
+++ b/klibc/ctype/isascii.c
@@ -0,0 +1,2 @@
+#include "ctypefunc.h"
+CTYPEFUNC(isascii)
diff --git a/klibc/ctype/isblank.c b/klibc/ctype/isblank.c
new file mode 100644
index 0000000..7728550
--- /dev/null
+++ b/klibc/ctype/isblank.c
@@ -0,0 +1,2 @@
+#include "ctypefunc.h"
+CTYPEFUNC(isblank)
diff --git a/klibc/ctype/iscntrl.c b/klibc/ctype/iscntrl.c
new file mode 100644
index 0000000..81db804
--- /dev/null
+++ b/klibc/ctype/iscntrl.c
@@ -0,0 +1,2 @@
+#include "ctypefunc.h"
+CTYPEFUNC(iscntrl)
diff --git a/klibc/ctype/isdigit.c b/klibc/ctype/isdigit.c
new file mode 100644
index 0000000..41a39d9
--- /dev/null
+++ b/klibc/ctype/isdigit.c
@@ -0,0 +1,2 @@
+#include "ctypefunc.h"
+CTYPEFUNC(isdigit)
diff --git a/klibc/ctype/isgraph.c b/klibc/ctype/isgraph.c
new file mode 100644
index 0000000..e5b83d1
--- /dev/null
+++ b/klibc/ctype/isgraph.c
@@ -0,0 +1,2 @@
+#include "ctypefunc.h"
+CTYPEFUNC(isgraph)
diff --git a/klibc/ctype/islower.c b/klibc/ctype/islower.c
new file mode 100644
index 0000000..9e179ae
--- /dev/null
+++ b/klibc/ctype/islower.c
@@ -0,0 +1,2 @@
+#include "ctypefunc.h"
+CTYPEFUNC(islower)
diff --git a/klibc/ctype/isprint.c b/klibc/ctype/isprint.c
new file mode 100644
index 0000000..9c6a351
--- /dev/null
+++ b/klibc/ctype/isprint.c
@@ -0,0 +1,2 @@
+#include "ctypefunc.h"
+CTYPEFUNC(isprint)
diff --git a/klibc/ctype/ispunct.c b/klibc/ctype/ispunct.c
new file mode 100644
index 0000000..36b5258
--- /dev/null
+++ b/klibc/ctype/ispunct.c
@@ -0,0 +1,2 @@
+#include "ctypefunc.h"
+CTYPEFUNC(ispunct)
diff --git a/klibc/ctype/isspace.c b/klibc/ctype/isspace.c
new file mode 100644
index 0000000..aed06c8
--- /dev/null
+++ b/klibc/ctype/isspace.c
@@ -0,0 +1,2 @@
+#include "ctypefunc.h"
+CTYPEFUNC(isspace)
diff --git a/klibc/ctype/isupper.c b/klibc/ctype/isupper.c
new file mode 100644
index 0000000..70a139b
--- /dev/null
+++ b/klibc/ctype/isupper.c
@@ -0,0 +1,2 @@
+#include "ctypefunc.h"
+CTYPEFUNC(isupper)
diff --git a/klibc/ctype/isxdigit.c b/klibc/ctype/isxdigit.c
new file mode 100644
index 0000000..ab89c1f
--- /dev/null
+++ b/klibc/ctype/isxdigit.c
@@ -0,0 +1,2 @@
+#include "ctypefunc.h"
+CTYPEFUNC(isxdigit)
diff --git a/klibc/ctype/tolower.c b/klibc/ctype/tolower.c
new file mode 100644
index 0000000..24ca72b
--- /dev/null
+++ b/klibc/ctype/tolower.c
@@ -0,0 +1,2 @@
+#include "ctypefunc.h"
+CTYPEFUNC(tolower)
diff --git a/klibc/ctype/toupper.c b/klibc/ctype/toupper.c
new file mode 100644
index 0000000..15763f7
--- /dev/null
+++ b/klibc/ctype/toupper.c
@@ -0,0 +1,2 @@
+#include "ctypefunc.h"
+CTYPEFUNC(toupper)