'Kay. This ought to do it. Patch included at the bottom of the post. 
(I have no idea why, but qmail daemon for the newsgroup keeps 
bouncing back my posts if I include attachments -- something 
about the message being < 2 bytes long.)

Anyways, I don't have a CVS account, so whoever wants to apply 
this little patch should go ahead. It's nothing serious -- basically, 
take what was done in substr() and jam it into strtoupper/lower(). 

J

Stig Sæther Bakken wrote:

> [J Smith <[EMAIL PROTECTED]>]
>> string strtoupper(string string [, int start [, int length]])
>> string strtolower(string string [, int start [, int length]])
>> 
>> The additional parameters would work in much the same fashion as
>> substr().  I've implemented it in the latest cvs just for the hell
>> of it.
>> 
>> Am I the only one who thinks this is even remotely useful? It isn't
>> a big thing, but it's a lot easier to have this available than to
>> chop up a string with substr() and then capitalize what you want.
>> 
>> A pretty useless feature, I guess. Obviously, I'm pretty bored right
>> now.
> 
> If it's useful to you, it will be useful to others.  Go for it.
> 
>  - Stig
> 


Index: string.c
===================================================================
RCS file: /repository/php4/ext/standard/string.c,v
retrieving revision 1.224
diff -u -r1.224 string.c
--- string.c    11 Aug 2001 17:03:37 -0000      1.224
+++ stringnew.c 14 Aug 2001 15:22:11 -0000
@@ -995,20 +995,74 @@
 }
 /* }}} */
 
-/* {{{ proto string strtoupper(string str)
-   Make a string uppercase */
+/* {{{ proto string strtoupper(string str [, int from [, int length]])
+   Make a string (or part of a string) uppercase */
 PHP_FUNCTION(strtoupper)
 {
-       zval **arg;
-       
-       if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg)) {
+       zval **str, **from, **len;
+       int argc = ZEND_NUM_ARGS(), f, l, i;
+
+       if ((argc == 1 && zend_get_parameters_ex(1, &str) == FAILURE) ||
+               (argc == 2 && zend_get_parameters_ex(2, &str, &from) == FAILURE) ||
+               (argc == 3 && zend_get_parameters_ex(3, &str, &from, &len) == 
+FAILURE)) {
                WRONG_PARAM_COUNT;
        }
-       convert_to_string_ex(arg);
+       convert_to_string_ex(str);
+       
+       /* if there's only one argument, this function will work exactly like it did 
+before. */
+
+       if (argc == 1) {
+               *return_value = **str;
+               zval_copy_ctor(return_value);
+               php_strtoupper(return_value->value.str.val, 
+return_value->value.str.len);
+    }
+
+       /* otherwise, it acts a lot like PHP's substr() function */
+
+       else {
+               convert_to_long_ex(from);
+               f = (*from)->value.lval;
+       
+               if (argc == 2) {
+                       l = (*str)->value.str.len;
+               }
+               else if (argc == 3) {
+                       convert_to_long_ex(len);
+                       l = (*len)->value.lval;
+               }
 
-       *return_value = **arg;
-       zval_copy_ctor(return_value);
-       php_strtoupper(return_value->value.str.val, return_value->value.str.len);
+               /* if the "from" position is negative, then count back from the end of 
+the string */
+
+               if (f < 0) {
+                       f = (*str)->value.str.len + f;
+                       if (f < 0) {
+                               f = 0;
+                       }
+               }
+
+               /* if the "length" position is negative, set it to the length needed 
+to stop
+                * X many characters from the end of the string */
+
+               if (l < 0) {
+                       l = ((*str)->value.str.len - f) + l;
+                       if (l < 0) {
+                               l = 0;
+                       }
+               }
+
+               if (f >= (int)(*str)->value.str.len) {
+                       RETURN_FALSE;
+               }
+
+               if ((f + 1) > (int)(*str)->value.str.len) {
+                       l = (int)(*str)->value.str.len - f;
+               }
+
+               for (i = f; i < (f + l); i++) {
+                       (*str)->value.str.val[i] = toupper((*str)->value.str.val[i]);
+               }
+               RETVAL_STRINGL((*str)->value.str.val, (*str)->value.str.len, 1);
+       }
 }
 /* }}} */
 
@@ -1029,21 +1083,74 @@
 }
 /* }}} */
 
-/* {{{ proto string strtolower(string str)
-   Make a string lowercase */
+/* {{{ proto string strtolower(string str [, int from [, int length]])
+   Make a string (or part of a string) lowercase */
 PHP_FUNCTION(strtolower)
 {
-       zval **str;
-       char *ret;
-       
-       if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str)) {
+       zval **str, **from, **len;
+       int argc = ZEND_NUM_ARGS(), f, l, i;
+
+       if ((argc == 1 && zend_get_parameters_ex(1, &str) == FAILURE) ||
+               (argc == 2 && zend_get_parameters_ex(2, &str, &from) == FAILURE) ||
+               (argc == 3 && zend_get_parameters_ex(3, &str, &from, &len) == 
+FAILURE)) {
                WRONG_PARAM_COUNT;
        }
        convert_to_string_ex(str);
+       
+       /* if there's only one argument, this function will work exactly like it did 
+before */
+
+       if (argc == 1) {
+               *return_value = **str;
+               zval_copy_ctor(return_value);
+               php_strtolower(return_value->value.str.val, 
+return_value->value.str.len);
+       }
+
+    /* otherwise, it acts a lot like PHP's substr() function */
+
+       else {
+               convert_to_long_ex(from);
+               f = (*from)->value.lval;
+
+               if (argc == 2) {
+                       l = (*str)->value.str.len;
+               }
+               else if (argc == 3) {
+                       convert_to_long_ex(len);
+                       l = (*len)->value.lval;
+               }
 
-       *return_value = **str;
-       zval_copy_ctor(return_value);
-       ret = php_strtolower(return_value->value.str.val, return_value->value.str.len);
+               /* if the "from" position is negative, then count back from the end of 
+the string */
+
+               if (f < 0) {
+                       f = (*str)->value.str.len + f;
+                       if (f < 0) {
+                               f = 0;
+                       }
+               }
+
+               /* if the "length" position is negative, set it to the length needed 
+to stop
+                * X many characters from the end of the string. */
+
+               if (l < 0) {
+                       l = ((*str)->value.str.len - f) + l;
+                       if (l < 0) {
+                               l = 0;
+                       }
+               }
+
+               if (f >= (int)(*str)->value.str.len) {
+                       RETURN_FALSE;
+               }
+
+               if ((f + 1) > (int)(*str)->value.str.len) {
+                       l = (int)(*str)->value.str.len - f;
+               }
+
+               for (i = f; i < (f + l); i++) {
+                       (*str)->value.str.val[i] = tolower((*str)->value.str.val[i]);
+               }
+               RETVAL_STRINGL((*str)->value.str.val, (*str)->value.str.len, 1);
+       }
 }
 /* }}} */
 


-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]

Reply via email to