summaryrefslogtreecommitdiff
path: root/ext/ctype
diff options
context:
space:
mode:
authorHartmut Holzgraefe <hholzgra@php.net>2000-11-22 01:00:44 +0000
committerHartmut Holzgraefe <hholzgra@php.net>2000-11-22 01:00:44 +0000
commit9d468a33c4e8894d40b42d3bda61ac2e7630491d (patch)
tree10658b9e036e7e35b0aa7bd51bf9a8f784d144fd /ext/ctype
parentf8dabac6d506b94f8f94d1ee175ade17d1a63021 (diff)
downloadphp-git-9d468a33c4e8894d40b42d3bda61ac2e7630491d.tar.gz
an experimental extension providing the C ctype function family
Diffstat (limited to 'ext/ctype')
-rw-r--r--ext/ctype/Makefile.in8
-rw-r--r--ext/ctype/config.m426
-rw-r--r--ext/ctype/ctype.c385
-rw-r--r--ext/ctype/ctype.xml245
-rw-r--r--ext/ctype/php_ctype.h94
-rw-r--r--ext/ctype/tests/001.phpt41
-rw-r--r--ext/ctype/tests/002.phpt43
7 files changed, 842 insertions, 0 deletions
diff --git a/ext/ctype/Makefile.in b/ext/ctype/Makefile.in
new file mode 100644
index 0000000000..940398455b
--- /dev/null
+++ b/ext/ctype/Makefile.in
@@ -0,0 +1,8 @@
+# $Id$
+
+LTLIBRARY_NAME = libctype.la
+LTLIBRARY_SOURCES = ctype.c
+LTLIBRARY_SHARED_NAME = ctype.la
+LTLIBRARY_SHARED_LIBADD = $(CTYPE_SHARED_LIBADD)
+
+include $(top_srcdir)/build/dynlib.mk
diff --git a/ext/ctype/config.m4 b/ext/ctype/config.m4
new file mode 100644
index 0000000000..9bcdcdb2c6
--- /dev/null
+++ b/ext/ctype/config.m4
@@ -0,0 +1,26 @@
+dnl $Id$
+dnl config.m4 for extension ctype
+dnl don't forget to call PHP_EXTENSION(ctype)
+
+dnl Comments in this file start with the string 'dnl'.
+dnl Remove where necessary. This file will not work
+dnl without editing.
+
+dnl If your extension references something external, use with:
+
+dnl PHP_ARG_WITH(ctype, for ctype support,
+dnl Make sure that the comment is aligned:
+dnl [ --with-ctype Include ctype support])
+
+dnl Otherwise use enable:
+
+PHP_ARG_ENABLE(ctype, whether to enable ctype support,[ --enable-ctype Enable ctype support])
+
+if test "$PHP_CTYPE" != "no"; then
+ dnl If you will not be testing anything external, like existence of
+ dnl headers, libraries or functions in them, just uncomment the
+ dnl following line and you are ready to go.
+ AC_DEFINE(HAVE_CTYPE, 1, [ ])
+ dnl Write more examples of tests here...
+ PHP_EXTENSION(ctype, $ext_shared)
+fi
diff --git a/ext/ctype/ctype.c b/ext/ctype/ctype.c
new file mode 100644
index 0000000000..32e04eaed8
--- /dev/null
+++ b/ext/ctype/ctype.c
@@ -0,0 +1,385 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP version 4.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997, 1998, 1999, 2000 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 2.02 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available at through the world-wide-web at |
+ | http://www.php.net/license/2_02.txt. |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Hartmut Holzgraefe <hartmut@six.de> |
+ | |
+ +----------------------------------------------------------------------+
+ */
+
+#include "php.h"
+#include "php_ini.h"
+#include "php_ctype.h"
+#include "SAPI.h"
+#include "ext/standard/info.h"
+
+#include <ctype.h>
+
+/* You should tweak config.m4 so this symbol (or some else suitable)
+ gets defined.
+*/
+#if HAVE_CTYPE
+
+/* If you declare any globals in php_ctype.h uncomment this:
+ZEND_DECLARE_MODULE_GLOBALS(ctype)
+*/
+
+/* True global resources - no need for thread safety here */
+static int le_ctype;
+
+/* Every user visible function must have an entry in ctype_functions[].
+*/
+function_entry ctype_functions[] = {
+ PHP_FE(confirm_ctype_compiled, NULL) /* For testing, remove later. */
+ PHP_FE(isalnum, NULL)
+ PHP_FE(isalpha, NULL)
+ PHP_FE(iscntrl, NULL)
+ PHP_FE(isdigit, NULL)
+ PHP_FE(islower, NULL)
+ PHP_FE(isgraph, NULL)
+ PHP_FE(isprint, NULL)
+ PHP_FE(ispunct, NULL)
+ PHP_FE(isspace, NULL)
+ PHP_FE(isupper, NULL)
+ PHP_FE(isxdigit, NULL)
+ {NULL, NULL, NULL} /* Must be the last line in ctype_functions[] */
+};
+
+zend_module_entry ctype_module_entry = {
+ "ctype",
+ ctype_functions,
+ PHP_MINIT(ctype),
+ PHP_MSHUTDOWN(ctype),
+ PHP_RINIT(ctype), /* Replace with NULL if there's nothing to do at request start */
+ PHP_RSHUTDOWN(ctype), /* Replace with NULL if there's nothing to do at request end */
+ PHP_MINFO(ctype),
+ STANDARD_MODULE_PROPERTIES
+};
+
+#ifdef COMPILE_DL_CTYPE
+ZEND_GET_MODULE(ctype)
+#endif
+
+/* Remove comments and fill if you need to have entries in php.ini
+PHP_INI_BEGIN()
+PHP_INI_END()
+*/
+
+#ifndef PHP_EXPERIMENTAL
+#define PHP_EXPERIMENTAL(x,y)
+#endif
+
+
+PHP_MINIT_FUNCTION(ctype)
+{
+/* Remove comments if you have entries in php.ini
+ REGISTER_INI_ENTRIES();
+*/
+
+ return SUCCESS;
+}
+
+PHP_MSHUTDOWN_FUNCTION(ctype)
+{
+/* Remove comments if you have entries in php.ini
+ UNREGISTER_INI_ENTRIES();
+*/
+ return SUCCESS;
+}
+
+/* Remove if there's nothing to do at request start */
+PHP_RINIT_FUNCTION(ctype)
+{
+ return SUCCESS;
+}
+
+/* Remove if there's nothing to do at request end */
+PHP_RSHUTDOWN_FUNCTION(ctype)
+{
+ return SUCCESS;
+}
+
+PHP_MINFO_FUNCTION(ctype)
+{
+ ELS_FETCH();
+ SLS_FETCH();
+
+ php_info_print_table_start();
+ php_info_print_table_row(2, "ctype functions", "enabled (experimental)");
+ php_info_print_table_end();
+
+ /* Remove comments if you have entries in php.ini
+ DISPLAY_INI_ENTRIES();
+ */
+}
+
+/* Remove the following function when you have succesfully modified config.m4
+ so that your module can be compiled into PHP, it exists only for testing
+ purposes. */
+
+/* Every user-visible function in PHP should document itself in the source */
+/* {{{ proto string confirm_ctype_compiled(string arg)
+ Return a string to confirm that the module is compiled in */
+PHP_FUNCTION(confirm_ctype_compiled)
+{
+ zval **arg;
+ int len;
+ char string[256];
+
+ if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_string_ex(arg);
+
+ len = sprintf(string, "Congratulations, you have successfully modified ext/ctype/config.m4, module %s is compiled into PHP", Z_STRVAL_PP(arg));
+ RETURN_STRINGL(string, len, 1);
+}
+/* }}} */
+/* The previous line is meant for emacs, so it can correctly fold and unfold
+ functions in source code. See the corresponding marks just before function
+ definition, where the functions purpose is also documented. Please follow
+ this convention for the convenience of others editing your code.
+*/
+
+static int ctype(int (*iswhat)(int),zval **c)
+{
+ switch ((*c)->type) {
+ case IS_LONG:
+ return iswhat((*c)->value.lval);
+ case IS_STRING:
+ {
+ char *p;
+ int n,len;
+ convert_to_string_ex(c);
+ p=(*c)->value.str.val;
+ len = (*c)->value.str.len;
+ for(n=0;n<len;n++) {
+ if(!iswhat(*p++)) return 0;
+ }
+ return 1;
+ }
+ default:
+ break;
+ }
+ return 0;
+}
+
+/* {{{ proto bool isalnum(mixed c)
+ Check for alphanumeric character(s) */
+PHP_FUNCTION(isalnum)
+{
+ PHP_EXPERIMENTAL("4.0.4dev",NULL)
+ zval **c;
+ if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &c) == FAILURE){
+ WRONG_PARAM_COUNT;
+ }
+
+ if(ctype(isalnum,c)) {
+ RETURN_TRUE;
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto bool isalpha(mixed c)
+ Check for alphabetic character(s) */
+PHP_FUNCTION(isalpha)
+{
+ PHP_EXPERIMENTAL("4.0.4dev",NULL)
+ zval **c;
+ if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &c) == FAILURE){
+ WRONG_PARAM_COUNT;
+ }
+
+ if(ctype(isalpha,c)) {
+ RETURN_TRUE;
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto bool iscntrl(mixed c)
+ Check for control character(s) */
+PHP_FUNCTION(iscntrl)
+{
+ PHP_EXPERIMENTAL("4.0.4dev",NULL)
+ zval **c;
+ if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &c) == FAILURE){
+ WRONG_PARAM_COUNT;
+ }
+
+ if(ctype(iscntrl,c)) {
+ RETURN_TRUE;
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto bool isdigit(mixed c)
+ Check for numeric character(s) */
+PHP_FUNCTION(isdigit)
+{
+ PHP_EXPERIMENTAL("4.0.4dev",NULL)
+ zval **c;
+ if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &c) == FAILURE){
+ WRONG_PARAM_COUNT;
+ }
+
+ if(ctype(isdigit,c)) {
+ RETURN_TRUE;
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto bool islower(mixed c)
+ Check for lowercase character(s) */
+PHP_FUNCTION(islower)
+{
+ PHP_EXPERIMENTAL("4.0.4dev",NULL)
+ zval **c;
+ if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &c) == FAILURE){
+ WRONG_PARAM_COUNT;
+ }
+
+ if(ctype(islower,c)) {
+ RETURN_TRUE;
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto bool isgraph(mixed c)
+ Check for any printable character(s) except space */
+PHP_FUNCTION(isgraph)
+{
+ PHP_EXPERIMENTAL("4.0.4dev",NULL)
+ zval **c;
+ if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &c) == FAILURE){
+ WRONG_PARAM_COUNT;
+ }
+
+ if(ctype(isgraph,c)) {
+ RETURN_TRUE;
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto bool isprint(mixed c)
+ Check for printable character(s) */
+PHP_FUNCTION(isprint)
+{
+ PHP_EXPERIMENTAL("4.0.4dev",NULL)
+ zval **c;
+ if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &c) == FAILURE){
+ WRONG_PARAM_COUNT;
+ }
+
+ if(ctype(isprint,c)) {
+ RETURN_TRUE;
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto bool ispunct(mixed c)
+ Check for any printable character which is not a space or an alphanumeric character */
+PHP_FUNCTION(ispunct)
+{
+ PHP_EXPERIMENTAL("4.0.4dev",NULL)
+ zval **c;
+ if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &c) == FAILURE){
+ WRONG_PARAM_COUNT;
+ }
+
+ if(ctype(ispunct,c)) {
+ RETURN_TRUE;
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto bool isspace(mixed c)
+ Check for whitespace character(s)*/
+PHP_FUNCTION(isspace)
+{
+ PHP_EXPERIMENTAL("4.0.4dev",NULL)
+ zval **c;
+ if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &c) == FAILURE){
+ WRONG_PARAM_COUNT;
+ }
+
+ if(ctype(isspace,c)) {
+ RETURN_TRUE;
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto bool isupper(mixed c)
+ Check for uppercase character(s) */
+PHP_FUNCTION(isupper)
+{
+ PHP_EXPERIMENTAL("4.0.4dev",NULL)
+ zval **c;
+ if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &c) == FAILURE){
+ WRONG_PARAM_COUNT;
+ }
+
+ if(ctype(isupper,c)) {
+ RETURN_TRUE;
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto bool isxdigit(mixed c)
+ Check for character(s) representing a hexadecimal digit */
+PHP_FUNCTION(isxdigit)
+{
+ PHP_EXPERIMENTAL("4.0.4dev",NULL)
+ zval **c;
+ if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &c) == FAILURE){
+ WRONG_PARAM_COUNT;
+ }
+
+ if(ctype(isxdigit,c)) {
+ RETURN_TRUE;
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+
+#endif /* HAVE_CTYPE */
+
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/ext/ctype/ctype.xml b/ext/ctype/ctype.xml
new file mode 100644
index 0000000000..5837b9b5d0
--- /dev/null
+++ b/ext/ctype/ctype.xml
@@ -0,0 +1,245 @@
+ <reference id="ref.ctype">
+ <title>Character type functions</title>
+ <titleabbrev>ctype</titleabbrev>
+
+ <partintro>
+ <para>
+ These functions check whether a character or string
+ falls into a certain character class according to the i
+ current locale.
+ </para>
+ <para>
+ When called with an integer argument theese functions
+ behave exactly like their C counterparts.
+ </para>
+ <para>
+ When called with a string argument they will check
+ every character in the string and will only return
+ true if every character in the string matches the
+ requested criteria.
+ </para>
+ <para>
+ Passing anything else but a string or integer will
+ return false immediately.
+ </para>
+ </partintro>
+
+
+ <refentry id="function.isalnum">
+ <refnamediv>
+ <refname>isalnum</refname>
+ <refpurpose>Check for alphanumeric character(s)</refpurpose>
+ </refnamediv>
+ <refsect1>
+ <title>Description</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>bool <function>isalnum</function></funcdef>
+ <paramdef>string <parameter>c</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <para>
+ See also <function>setlocale</function>.
+ </para>
+ </refsect1>
+ </refentry>
+
+ <refentry id="function.isalpha">
+ <refnamediv>
+ <refname>isalpha</refname>
+ <refpurpose></refpurpose>
+ </refnamediv>
+ <refsect1>
+ <title>Description</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>bool <function>isalpha</function></funcdef>
+ <paramdef>string <parameter>c</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <para>
+ </para>
+ </refsect1>
+ </refentry>
+
+ <refentry id="function.iscntrl">
+ <refnamediv>
+ <refname>iscntrl</refname>
+ <refpurpose></refpurpose>
+ </refnamediv>
+ <refsect1>
+ <title>Description</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>bool <function>iscntrl</function></funcdef>
+ <paramdef>string <parameter>c</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <para>
+ </para>
+ </refsect1>
+ </refentry>
+
+ <refentry id="function.isdigit">
+ <refnamediv>
+ <refname>isdigit</refname>
+ <refpurpose></refpurpose>
+ </refnamediv>
+ <refsect1>
+ <title>Description</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>bool <function>isdigit</function></funcdef>
+ <paramdef>string <parameter>c</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <para>
+ </para>
+ </refsect1>
+ </refentry>
+
+ <refentry id="function.islower">
+ <refnamediv>
+ <refname>islower</refname>
+ <refpurpose></refpurpose>
+ </refnamediv>
+ <refsect1>
+ <title>Description</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>bool <function>islower</function></funcdef>
+ <paramdef>string <parameter>c</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <para>
+ </para>
+ </refsect1>
+ </refentry>
+
+ <refentry id="function.isgraph">
+ <refnamediv>
+ <refname>isgraph</refname>
+ <refpurpose></refpurpose>
+ </refnamediv>
+ <refsect1>
+ <title>Description</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>bool <function>isgraph</function></funcdef>
+ <paramdef>string <parameter>c</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <para>
+ </para>
+ </refsect1>
+ </refentry>
+
+ <refentry id="function.isprint">
+ <refnamediv>
+ <refname>isprint</refname>
+ <refpurpose></refpurpose>
+ </refnamediv>
+ <refsect1>
+ <title>Description</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>bool <function>isprint</function></funcdef>
+ <paramdef>string <parameter>c</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <para>
+ </para>
+ </refsect1>
+ </refentry>
+
+ <refentry id="function.ispunct">
+ <refnamediv>
+ <refname>ispunct</refname>
+ <refpurpose></refpurpose>
+ </refnamediv>
+ <refsect1>
+ <title>Description</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>bool <function>ispunct</function></funcdef>
+ <paramdef>string <parameter>c</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <para>
+ </para>
+ </refsect1>
+ </refentry>
+
+ <refentry id="function.isspace">
+ <refnamediv>
+ <refname>isspace</refname>
+ <refpurpose></refpurpose>
+ </refnamediv>
+ <refsect1>
+ <title>Description</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>bool <function>isspace</function></funcdef>
+ <paramdef>string <parameter>c</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <para>
+ </para>
+ </refsect1>
+ </refentry>
+
+ <refentry id="function.isupper">
+ <refnamediv>
+ <refname>isupper</refname>
+ <refpurpose></refpurpose>
+ </refnamediv>
+ <refsect1>
+ <title>Description</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>bool <function>isupper</function></funcdef>
+ <paramdef>string <parameter>c</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <para>
+ </para>
+ </refsect1>
+ </refentry>
+
+ <refentry id="function.isxdigit">
+ <refnamediv>
+ <refname>isxdigit</refname>
+ <refpurpose></refpurpose>
+ </refnamediv>
+ <refsect1>
+ <title>Description</title>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>bool <function>isxdigit</function></funcdef>
+ <paramdef>string <parameter>c</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <para>
+ </para>
+ </refsect1>
+ </refentry>
+
+ </reference>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:t
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-default-dtd-file:"../../manual.ced"
+sgml-exposed-tags:nil
+sgml-local-catalogs:nil
+sgml-local-ecat-files:nil
+End:
+-->
+
diff --git a/ext/ctype/php_ctype.h b/ext/ctype/php_ctype.h
new file mode 100644
index 0000000000..2702dd021d
--- /dev/null
+++ b/ext/ctype/php_ctype.h
@@ -0,0 +1,94 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP version 4.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997, 1998, 1999, 2000 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 2.02 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available at through the world-wide-web at |
+ | http://www.php.net/license/2_02.txt. |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: |
+ | |
+ +----------------------------------------------------------------------+
+ */
+
+#ifndef PHP_CTYPE_H
+#define PHP_CTYPE_H
+
+/* You should tweak config.m4 so this symbol (or some else suitable)
+ gets defined.
+*/
+#if HAVE_CTYPE
+
+extern zend_module_entry ctype_module_entry;
+#define phpext_ctype_ptr &ctype_module_entry
+
+#ifdef PHP_WIN32
+#define PHP_CTYPE_API __declspec(dllexport)
+#else
+#define PHP_CTYPE_API
+#endif
+
+PHP_MINIT_FUNCTION(ctype);
+PHP_MSHUTDOWN_FUNCTION(ctype);
+PHP_RINIT_FUNCTION(ctype);
+PHP_RSHUTDOWN_FUNCTION(ctype);
+PHP_MINFO_FUNCTION(ctype);
+
+PHP_FUNCTION(confirm_ctype_compiled); /* For testing, remove later. */
+PHP_FUNCTION(isalnum);
+PHP_FUNCTION(isalpha);
+PHP_FUNCTION(iscntrl);
+PHP_FUNCTION(isdigit);
+PHP_FUNCTION(islower);
+PHP_FUNCTION(isgraph);
+PHP_FUNCTION(isprint);
+PHP_FUNCTION(ispunct);
+PHP_FUNCTION(isspace);
+PHP_FUNCTION(isupper);
+PHP_FUNCTION(isxdigit);
+
+/*
+ Declare any global variables you may need between the BEGIN
+ and END macros here:
+
+ZEND_BEGIN_MODULE_GLOBALS(ctype)
+ int global_variable;
+ZEND_END_MODULE_GLOBALS(ctype)
+*/
+
+/* In every function that needs to use variables in php_ctype_globals,
+ do call CTYPELS_FETCH(); after declaring other variables used by
+ that function, and always refer to them as CTYPEG(variable).
+ You are encouraged to rename these macros something shorter, see
+ examples in any other php module directory.
+*/
+
+#ifdef ZTS
+#define CTYPEG(v) (ctype_globals->v)
+#define CTYPELS_FETCH() php_ctype_globals *ctype_globals = ts_resource(ctype_globals_id)
+#else
+#define CTYPEG(v) (ctype_globals.v)
+#define CTYPELS_FETCH()
+#endif
+
+#else
+
+#define phpext_ctype_ptr NULL
+
+#endif
+
+#endif /* PHP_CTYPE_H */
+
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/ext/ctype/tests/001.phpt b/ext/ctype/tests/001.phpt
new file mode 100644
index 0000000000..53ae99b56a
--- /dev/null
+++ b/ext/ctype/tests/001.phpt
@@ -0,0 +1,41 @@
+--TEST--
+ctype on integers
+--SKIPIF--
+<?php if (!extension_loaded("ctype")) print "skip"; ?>
+--POST--
+--GET--
+--FILE--
+<?php
+ setlocale("LC_ALL","C");
+
+ function ctype_test_001($function) {
+ $n=0;
+ for($a=0;$a<256;$a++) {
+ if($function($a)) $n++;
+ }
+ echo "$function $n\n";
+ }
+ctype_test_001("islower");
+ctype_test_001("isupper");
+ctype_test_001("isalpha");
+ctype_test_001("isdigit");
+ctype_test_001("isalnum");
+ctype_test_001("iscntrl");
+ctype_test_001("isgraph");
+ctype_test_001("isprint");
+ctype_test_001("ispunct");
+ctype_test_001("isspace");
+ctype_test_001("isxdigit");
+?>
+--EXPECT--
+islower 26
+isupper 26
+isalpha 52
+isdigit 10
+isalnum 62
+iscntrl 33
+isgraph 94
+isprint 95
+ispunct 32
+isspace 6
+isxdigit 22
diff --git a/ext/ctype/tests/002.phpt b/ext/ctype/tests/002.phpt
new file mode 100644
index 0000000000..e5a6062d11
--- /dev/null
+++ b/ext/ctype/tests/002.phpt
@@ -0,0 +1,43 @@
+--TEST--
+ctype on strings
+--SKIPIF--
+<?php if (!extension_loaded("ctype")) print "skip"; ?>
+--POST--
+--GET--
+--FILE--
+<?php
+ setlocale("LC_ALL","C");
+
+ function ctype_test_002($function) {
+ $n=0; $m=0;
+ for($a=0;$a<256;$a++) {
+ $c = chr($a);
+ if($function("$c$c$c")) $n++;
+ if($function("1-$c$c$c-x")) $m++;
+ }
+ echo "$function $n $m\n";
+ }
+ctype_test_002("islower");
+ctype_test_002("isupper");
+ctype_test_002("isalpha");
+ctype_test_002("isdigit");
+ctype_test_002("isalnum");
+ctype_test_002("iscntrl");
+ctype_test_002("isgraph");
+ctype_test_002("isprint");
+ctype_test_002("ispunct");
+ctype_test_002("isspace");
+ctype_test_002("isxdigit");
+?>
+--EXPECT--
+islower 26 0
+isupper 26 0
+isalpha 52 0
+isdigit 10 0
+isalnum 62 0
+iscntrl 33 0
+isgraph 94 94
+isprint 95 95
+ispunct 32 0
+isspace 6 0
+isxdigit 22 0