Skip to content

Instantly share code, notes, and snippets.

@davidcoallier
Created November 12, 2009 14:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davidcoallier/232947 to your computer and use it in GitHub Desktop.
Save davidcoallier/232947 to your computer and use it in GitHub Desktop.
Index: php_spl.c
===================================================================
--- php_spl.c (revision 290576)
+++ php_spl.c (working copy)
@@ -359,6 +359,97 @@
}
}
+
+/* {{{ spl_strrpos_ascii: borrowed from the php ext/standard/string.c */
+int32_t spl_strrpos_ascii(unsigned char *haystack, int32_t haystack_len, unsigned char *needle, int32_t needle_len, int32_t offset)
+{
+ unsigned char *p, *e;
+
+ if (offset >= 0) {
+ p = haystack + offset;
+ e = haystack + haystack_len - needle_len;
+ } else {
+ p = haystack;
+ if (needle_len > -offset) {
+ e = haystack + haystack_len - needle_len;
+ } else {
+ e = haystack + haystack_len + offset;
+ }
+ }
+
+ if (needle_len == 1) {
+ /* Single character search can shortcut memcmps */
+ while (e >= p) {
+ if (*e == *needle) {
+ return (e - p + (offset > 0 ? offset : 0));
+ }
+ e--;
+ }
+ return -1;
+ }
+
+ while (e >= p) {
+ if (memcmp(e, needle, needle_len) == 0) {
+ return (e - p + (offset > 0 ? offset : 0));
+ }
+ e--;
+ }
+
+ return -1;
+} /* }}} */
+
+/* {{{ proto void spl_autoload_psr(string class_name) U
+ This is the method that is used to be load in the autoloader */
+PHP_FUNCTION(spl_autoload_psr)
+{
+ zval *class_name = NULL;
+ int class_name_len;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &class_name, &class_name_len) == FAILURE) {
+ return;
+ }
+
+
+ // Let's set the common items we'll be using
+ zval *namespace = NULL, *filename = NULL;
+
+ // Process the string stuff first
+ if (Z_TYPE_P(class_name) == IS_STRING) {
+ Z_TYPE_P(return_value) = IS_STRING;
+
+ if (strstr(Z_STRVAL_P(class_name), "\\\\") != NULL) {
+ MAKE_STD_ZVAL(namespace);
+ MAKE_STD_ZVAL(filename);
+
+ int32_t class_pos;
+
+ unsigned char *needle = "\\\\";
+ int32_t needle_len = 4;
+
+ class_pos = spl_strrpos_ascii((unsigned char *)class_name.str.val, (int32_t)class_name.str.len, needle, needle_len, 0);
+
+ // $namespace = substr($classname, 0, strrpos($classname, '\\'));
+ Z_STRVAL_P(namespace) = strndup(Z_STRVAL_P(class_name), class_pos);
+
+ // $classname = substr($classname, strrpos($classname, '\\') + 1);
+ // Something is wrong here as well....
+ Z_STRVAL_P(class_name) = strndup(Z_STRVAL_P(class_name), class_pos + 1);
+
+ // $filename = str_replace('\\', '/', $namespace) . '/';
+ // Am I missing some \0 there? I can't find an internal strncpy
+ Z_STRVAL_P(filename) = sprintf("%s%s", strncpy("\\\\", "/", Z_STRVAL_P(namespace)), "/");
+
+ MAKE_STD_ZVAL(return_value);
+ *return_value = filename;
+
+ zval_dtor(filename);
+ zval_dtor(classname);
+ zval_dtor(class_name);
+ }
+ }
+ // I'll care about unicode later when this compiles. Z_TYPE_P(class_name) == IS_UNICODE.
+} /* }}} */
+
/* {{{ proto void spl_autoload_call(string class_name) U
Try all registerd autoload function to load the requested class */
PHP_FUNCTION(spl_autoload_call)
@@ -870,6 +961,11 @@
ZEND_ARG_INFO(0, class_name)
ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_spl_autoload_psr, 0, 0, 0)
+ ZEND_ARG_INFO(0, class_name)
+ZEND_END_ARG_INFO()
+
ZEND_BEGIN_ARG_INFO_EX(arginfo_spl_autoload_register, 0, 0, 0)
ZEND_ARG_INFO(0, autoload_function)
ZEND_END_ARG_INFO()
@@ -893,6 +989,7 @@
PHP_FE(spl_autoload_unregister, arginfo_spl_autoload_unregister)
PHP_FE(spl_autoload_functions, arginfo_spl_autoload_functions)
PHP_FE(spl_autoload_call, arginfo_spl_autoload_call)
+ PHP_FE(spl_autoload_psr, arginfo_spl_autoload_psr)
PHP_FE(class_parents, arginfo_class_parents)
PHP_FE(class_implements, arginfo_class_implements)
PHP_FE(spl_object_hash, arginfo_spl_object_hash)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment