I wrote a simply getopt function for PHP (based on the system's
getopt() call).  This is not meant to compete with the getopt PEAR
class but rather to provide simple command line parsing capabilities
to CLI-based PHP scripts.

If there are no objections, I'd like to commit this over the weekend
(at which point I'll also write the associated documentation).

Comments are, of course, welcome.

-- 
Jon Parise ([EMAIL PROTECTED]) :: The PHP Project (http://www.php.net/)
Index: basic_functions.c
===================================================================
RCS file: /repository/php4/ext/standard/basic_functions.c,v
retrieving revision 1.514
diff -u -r1.514 basic_functions.c
--- basic_functions.c   27 Sep 2002 23:42:38 -0000      1.514
+++ basic_functions.c   28 Sep 2002 02:25:20 -0000
@@ -498,6 +498,10 @@
        PHP_FE(putenv,                                                                 
                                                 NULL)
 #endif
 
+#ifdef HAVE_GETOPT
+       PHP_FE(getopt,                                                                 
+                                                 NULL)
+#endif
+
        PHP_FE(microtime,                                                              
                                                 NULL)
        PHP_FE(gettimeofday,                                                           
                                         NULL)
 
@@ -1334,6 +1338,92 @@
                        efree(pe.key);
                        RETURN_FALSE;
                }
+       }
+}
+/* }}} */
+#endif
+
+#ifdef HAVE_GETOPT
+/* {{{ proto array getopt(string options)
+   Get options from the command line argument list */
+PHP_FUNCTION(getopt)
+{
+       char *options = NULL, **argv = NULL;
+       char opt[1] = { '\0' };
+       int ch, argc, options_len = 0, pos = 0;
+       zval *val, **args;
+       
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",
+                                                         &options, &options_len) == 
+FAILURE) {
+               return;
+       }
+
+       /*
+        * Get argv from the global symbol table.  We calculate argc ourselves
+        * in order to be on the safe side, even though it is also available
+        * from the symbol table.
+        */
+       if (zend_hash_find(&EG(symbol_table), "argv", sizeof("argv"),
+                                          (void **) &args) != FAILURE) {
+               zval **arg;
+
+               argc = zend_hash_num_elements(Z_ARRVAL_PP(args));
+
+               /* Attempt to allocate enough memory to hold all of the arguments. */
+               if ((argv = (char **) malloc(argc * sizeof(char *))) == NULL) {
+                       RETURN_FALSE;
+               }
+
+               /* Reset the array indexes. */
+               pos = 0;
+               zend_hash_internal_pointer_reset(Z_ARRVAL_PP(args));
+
+               /* Iterate over the hash to construct the argv array. */
+               while (zend_hash_get_current_data(Z_ARRVAL_PP(args),
+                                                                                 
+(void **)&arg) == SUCCESS) {
+                       argv[pos++] = strdup(Z_STRVAL_PP(arg));
+                       zend_hash_move_forward(Z_ARRVAL_PP(args));
+               }
+       }
+
+       /* Initialize the return value as an array. */
+       if (array_init(return_value)) {
+               RETURN_FALSE;
+       }
+
+       /* Create a standard zval to hold the argument string. */
+       MAKE_STD_ZVAL(val);
+
+       /* Disable getopt()'s error messages. */
+       opterr = 0;
+
+       while ((ch = getopt(argc, argv, options)) != -1) {
+
+               /* Skip unknown arguments. */
+               if (ch == '?') {
+                       continue;
+               }
+
+               /* Prepare the option character and the argument string. */
+               opt[0] = ch;
+               ZVAL_STRING(val, optarg, 1);
+
+               /* Add this option / argument pair to the result hash. */
+               if (zend_hash_update(HASH_OF(return_value), opt, 1, (void *)&val,
+                                                        sizeof(zval *), NULL) == 
+FAILURE) {
+                       /* TODO: Raise error and free argv */
+                       RETURN_FALSE;
+               }
+       }
+
+       /* Free the memory allocated to the argv array. */
+       if (argv) {
+               for (pos = 0; pos < argc; pos++) {
+                       if (argv[pos]) {
+                               free(argv[pos]);
+                       }
+               }
+               free(argv);
        }
 }
 /* }}} */
Index: basic_functions.h
===================================================================
RCS file: /repository/php4/ext/standard/basic_functions.h,v
retrieving revision 1.107
diff -u -r1.107 basic_functions.h
--- basic_functions.h   23 Sep 2002 18:12:38 -0000      1.107
+++ basic_functions.h   28 Sep 2002 02:25:20 -0000
@@ -50,6 +50,8 @@
 PHP_FUNCTION(getenv);
 PHP_FUNCTION(putenv);
 
+PHP_FUNCTION(getopt);
+
 PHP_FUNCTION(get_current_user);
 PHP_FUNCTION(set_time_limit);
 

-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to