]> granicus.if.org Git - php/commitdiff
wordwrap function from Chris Russel <russel@yorku.ca>
authorDavid Croft <david@php.net>
Sat, 22 Jul 2000 01:12:24 +0000 (01:12 +0000)
committerDavid Croft <david@php.net>
Sat, 22 Jul 2000 01:12:24 +0000 (01:12 +0000)
differences from his patch:
 - wordwrap width and wrap-string now optional parameters
   (default to 75 and "\n" respectively)
 - wordwrap_byte is now just an automatic special case of wordwrap
 - Zend API compliant

@- Added new function "wordwrap" to wordwrap long strings from Chris
@  Russel <russel@yorku.ca> (David Croft)

ext/standard/basic_functions.c
ext/standard/php_string.h
ext/standard/string.c

index 6c0dafc4aa667e9ce0503c3c12e595504fb7e38c..29dbf82e263d9435867f721f39a06766e7e1ac85 100644 (file)
@@ -106,6 +106,7 @@ function_entry basic_functions[] = {
        
        PHP_FE(getimagesize,                                                    NULL)
        
+       PHP_FE(wordwrap,                                                                NULL)
        PHP_FE(htmlspecialchars,                                                NULL)
        PHP_FE(htmlentities,                                                    NULL)
        PHP_FE(get_html_translation_table,                              NULL)
index 88b70f22c17304543f230cc2ce0e59775474abd3..3046407d4c59ebd3a3f40fb91335ff9fd30f25a6 100644 (file)
@@ -46,6 +46,7 @@ PHP_FUNCTION(soundex);
 PHP_FUNCTION(levenshtein);
 
 PHP_FUNCTION(count_chars);
+PHP_FUNCTION(wordwrap);
 PHP_FUNCTION(explode);
 PHP_FUNCTION(implode);
 PHP_FUNCTION(strtok);
index c8217b8ace5a21d3aeb66d688ec203403664e5c2..cebd8411388e6a7e30caf904ade2026a8b8c167e 100644 (file)
@@ -226,6 +226,144 @@ PHP_FUNCTION(ltrim)
 }
 /* }}} */
 
+
+/* {{{ proto string wordwrap(string str[, int width[, string break]])
+ * wrap buffer to selected number of characters using string break char */
+PHP_FUNCTION(wordwrap)
+{
+       pval **ptext, **plinelength, **pbreakchar;
+       long i=0, l=0, pgr=0, linelength=0, last=0, breakcharlen;
+       char *text, *breakchar, *newtext;
+
+       if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 3 || zend_get_parameters_ex(ZEND_NUM_ARGS(), &ptext, &plinelength, &pbreakchar) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_string_ex(ptext);
+       text = (*ptext)->value.str.val;
+
+       if (ZEND_NUM_ARGS() > 1) {
+               convert_to_long_ex(plinelength);
+               linelength = (*plinelength)->value.lval;
+       }
+       else {
+               linelength = 75;
+       }
+
+       if (ZEND_NUM_ARGS() > 2) {
+               convert_to_string_ex(pbreakchar);
+               breakchar = (*pbreakchar)->value.str.val;
+               breakcharlen = (*pbreakchar)->value.str.len;
+       }
+       else {
+               breakchar = "\n";
+               breakcharlen = 1;
+       }
+
+       /* Special case for a single-character break as it needs no
+          additional storage space */
+
+       if (breakcharlen == 1) {
+
+               while (text[i] != '\0') {
+                       /* prescan line to see if it is greater than linelength */
+                       l = 0;
+                       while (text[i+l] != breakchar[0]) {
+                               if (text[i+l] == '\0') {
+                                       l --;
+                                       break;
+                               }
+                               l++;
+                       }
+                       if (l > linelength) {
+                               pgr = l;
+                               l = linelength;
+                               /* needs breaking; work backwards to find previous word */
+                               while (l >= 0) {
+                                       if (text[i+l] == ' ') {
+                                               text[i+l] = breakchar[0];
+                                               break;
+                                       }
+                                       l --;
+                               }
+                               if (l == -1) {
+                                       /* couldn't break is backwards, try looking forwards */
+                                       l = linelength;
+                                       while (l <= pgr) {
+                                               if(text[i+l] == ' ') {
+                                                       text[i+l] = breakchar[0];
+                                                       break;
+                                               }
+                                               l ++;
+                                       }
+                               }
+                       }
+                       i += l+1;
+               }
+               RETVAL_STRINGL(text, strlen(text), 1);
+       }
+       else {
+               /* Multiple character line break */
+
+               newtext = emalloc((*ptext)->value.str.len * (breakcharlen+1));
+               newtext[0] = '\0';
+
+               i = 0;
+               while (text[i] != '\0') {
+                       /* prescan line to see if it is greater than linelength */
+                       l = 0;
+                       while (text[i+l] != '\0') {
+                               if (text[i+l] == breakchar[0]) {
+                                       if (breakcharlen == 1 || strncmp(text+i+l, breakchar, breakcharlen)==0)
+                                               break;
+                               }
+                               l ++;
+                       }
+                       if (l > linelength) {
+                               pgr = l;
+                               l = linelength;
+
+                               /* needs breaking; work backwards to find previous word */
+                               while (l >= 0) {
+                                       if (text[i+l] == ' ') {
+                                               strncat(newtext, text+last, i+l-last);
+                                               strcat(newtext, breakchar);
+                                               last = i + l + 1;
+                                               break;
+                                       }
+                                       l --;
+                               }
+                               if (l == -1) {
+                                       /* couldn't break it backwards, try looking forwards */
+                                       l = linelength;
+                                       while (l <= pgr) {
+                                               if (text[i+l] == ' ') {
+                                                       strncat(newtext, text+last, i+l-last);
+                                                       strcat(newtext, breakchar);
+                                                       last = i + l + 1;
+                                                       break;
+                                               }
+                                               l ++;
+                                       }
+                               }
+                               i += l+1;
+                       }
+                       else {
+                               i += (l ? l : 1);
+                       }
+               }
+
+               if (i+l > last) {
+                       strcat(newtext, text+last);
+               }
+
+               RETVAL_STRINGL(newtext, strlen(newtext), 1);
+               efree(newtext);
+       }
+}
+/* }}} */
+
+
 PHPAPI void php_explode(zval *delim, zval *str, zval *return_value, int limit) 
 {
        char *p1, *p2, *endp;