]> granicus.if.org Git - php/commitdiff
one can now use callbacks for custom completion functions (still work-in-progress)
authorThies C. Arntzen <thies@php.net>
Sat, 23 Oct 1999 17:36:45 +0000 (17:36 +0000)
committerThies C. Arntzen <thies@php.net>
Sat, 23 Oct 1999 17:36:45 +0000 (17:36 +0000)
ext/readline/readline.c

index 0fae8d1b31cad28a0d33da03c4539d5e5eb7b6dc..b9601dd934f7e8a9f9a5d3bd01d8220c2862cb67 100644 (file)
 #include <readline/history.h>
 
 PHP_FUNCTION(readline);
-PHP_FUNCTION(readline_version);
-
 PHP_FUNCTION(readline_add_history);
+PHP_FUNCTION(readline_info);
+PHP_FUNCTION(readline_clear_history);
 PHP_FUNCTION(readline_list_history);
 PHP_FUNCTION(readline_read_history);
 PHP_FUNCTION(readline_write_history);
+PHP_FUNCTION(readline_completion_function);
+
+static char *_readline_completion = NULL;
+static zval _readline_array;
 
 PHP_MINIT_FUNCTION(readline);
+PHP_RSHUTDOWN_FUNCTION(readline);
 
 /* }}} */
 /* {{{ module stuff */
 
 static zend_function_entry php_readline_functions[] = {
        PHP_FE(readline,                                NULL)
-       PHP_FE(readline_version,                NULL)
+       PHP_FE(readline_info,               NULL)
        PHP_FE(readline_add_history,            NULL)
+       PHP_FE(readline_clear_history,          NULL)
        PHP_FE(readline_list_history,           NULL)
        PHP_FE(readline_read_history,           NULL)
        PHP_FE(readline_write_history,          NULL)
+       PHP_FE(readline_completion_function,NULL)
        {NULL, NULL, NULL}
 };
 
@@ -55,15 +62,24 @@ zend_module_entry readline_module_entry = {
        "PHP-Readline", 
        php_readline_functions, 
        PHP_MINIT(readline), 
-       NULL, 
-       NULL, 
-       NULL, 
+       NULL,
+       NULL,
+       PHP_RSHUTDOWN(readline),
        NULL, 
        STANDARD_MODULE_PROPERTIES
 };
 
 PHP_MINIT_FUNCTION(readline)
 {
+    using_history();
+       return SUCCESS;
+}
+
+PHP_RSHUTDOWN_FUNCTION(readline)
+{
+       if (_readline_completion) 
+               efree(_readline_completion);
+
        return SUCCESS;
 }
 
@@ -86,22 +102,34 @@ PHP_FUNCTION(readline)
        if (! result) {
                RETURN_FALSE;
        } else {
-               RETURN_STRING(result,1);
+               RETVAL_STRING(result,1);
+               free(result);
        }
 }
 
 /* }}} */
-/* {{{ proto string readline_version() */
+/* {{{ proto array|long|string readline_info([string varname][, string newvalue ]) 
+ gets/sets various internal readline variables. */
+
+#define SAFE_STRING(s) ((s)?(s):"")
 
-PHP_FUNCTION(readline_version)
+PHP_FUNCTION(readline_info)
 {
        int ac = ARG_COUNT(ht);
 
        if (ac) {
                WRONG_PARAM_COUNT;
        }
-
-       RETURN_STRING(rl_library_version?rl_library_version:"unknown",1);
+       
+       array_init(return_value);
+       add_assoc_string(return_value,"line_buffer",SAFE_STRING(rl_line_buffer),1);
+       add_assoc_long(return_value,"point",rl_point);
+       add_assoc_long(return_value,"end",rl_end);
+       add_assoc_long(return_value,"mark",rl_mark);
+       add_assoc_string(return_value,"prompt",SAFE_STRING(rl_prompt),1);
+       add_assoc_string(return_value,"library_version",SAFE_STRING(rl_library_version),1);
+       add_assoc_string(return_value,"terminal_name",SAFE_STRING(rl_terminal_name),1);
+       add_assoc_string(return_value,"readline_name",SAFE_STRING(rl_readline_name),1);
 }
 
 /* }}} */
@@ -122,6 +150,22 @@ PHP_FUNCTION(readline_add_history)
        RETURN_TRUE;
 }
 
+/* }}} */
+/* {{{ proto void readline_clear_history() */
+
+PHP_FUNCTION(readline_clear_history)
+{
+       int ac = ARG_COUNT(ht);
+
+       if (ac < 0 || ac > 0) {
+               WRONG_PARAM_COUNT;
+       }
+
+       clear_history();
+
+       RETURN_TRUE;
+}
+
 /* }}} */
 /* {{{ proto array readline_list_history() */
 
@@ -198,6 +242,106 @@ PHP_FUNCTION(readline_write_history)
        }
 }
 
+/* }}} */
+/* {{{ proto void readline_completion_function(string funcname) */
+
+char *test[] = { "bleibt", "da", "helfen", "keine", "pillen", "und" , "heissen", "umsclaege","hallo", "pallo", "thies", "ist", "doof", "tubu", "tata",0 };
+
+static char *_readline_command_generator(char *text,int state)
+{
+       HashTable  *myht = _readline_array.value.ht;
+       zval **entry;
+       
+       /*
+       printf("\n_readline_command_generator(\"%s\",%d)\n",text,state);
+       */
+       
+       if (! state)    {
+               zend_hash_internal_pointer_reset(myht);
+       }
+       
+       while (zend_hash_get_current_data(myht, (void **)&entry) == SUCCESS) {
+               zend_hash_move_forward(myht);
+
+               convert_to_string_ex(entry);
+               if (strncmp ((*entry)->value.str.val, text, strlen(text)) == 0) {
+                       return (strdup((*entry)->value.str.val));
+               }
+       }
+
+       return NULL;
+}
+
+static zval *_readline_string_zval(const char *str)
+{
+       zval *ret;
+       int len = strlen(str);
+       MAKE_STD_ZVAL(ret);
+
+       ret->type = IS_STRING;
+       ret->value.str.len = len;
+       ret->value.str.val = estrndup(str, len);
+       return ret;
+}
+
+static zval *_readline_long_zval(long l)
+{
+       zval *ret;
+       MAKE_STD_ZVAL(ret);
+
+       ret->type = IS_LONG;
+       ret->value.lval = l;
+       return ret;
+}
+
+static char **_readline_completion_cb(char *text, int start, int end)
+{ 
+       zval *params[4];
+       int i;
+       char **matches = NULL;
+       ELS_FETCH();
+
+       params[0]=_readline_string_zval(_readline_completion);
+       params[1]=_readline_string_zval(text);
+       params[2]=_readline_long_zval(start);
+       params[3]=_readline_long_zval(end);
+
+       if (call_user_function(CG(function_table), NULL, params[0], &_readline_array, 3, params+1) == SUCCESS) {
+               if (_readline_array.type == IS_ARRAY) {
+                       matches = completion_matches(text,_readline_command_generator);
+               }
+       }
+       
+       for (i = 0; i < 4; i++) {
+               zval_del_ref(&params[i]);
+       }
+       zval_dtor(&_readline_array);
+       
+       return matches; 
+}
+
+PHP_FUNCTION(readline_completion_function)
+{
+       pval **arg;
+       int ac = ARG_COUNT(ht);
+
+       if (ac < 0 || ac > 1 || getParametersEx(ac, &arg) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       if (ac == 1) {
+               convert_to_string_ex(arg);
+
+               if (_readline_completion)
+                       efree(_readline_completion);
+
+               _readline_completion = estrdup((*arg)->value.str.val);
+               rl_attempted_completion_function = _readline_completion_cb;
+       }
+
+       RETURN_TRUE;
+}
+
 /* }}} */
 
 #endif /* HAVE_LIBREADLINE */