2011-12-24 7 views
5

PHP tiene una función donde puede usar increment operators en cadenas. Se comporta de manera similar a un cuentakilómetros, donde una vez que alcanzas el final de un rango, "gira".¿Dónde en la fuente PHP está el código para incrementar las cadenas?

<?php 
$str = 'zy'; 
$str++; 
echo "$str\n"; // zz 
$str++; 
echo "$str\n"; // aaa 

Solo curiosidad por el código fuente de PHP. A menudo miro en el código fuente en funciones/extensiones, pero algo así no tengo idea de dónde buscar.

Un enlace al archivo usando su web based SVN sería increíble.

+0

Hace poco [enteré de esto] (http://stackoverflow.com/questions/ 3567180/increment-letters-like-numbers) y lo usó para rellenar celdas en una hoja de cálculo de Excel. Una característica extraña si me preguntas pero seguro que puede ser útil. –

+0

¿Has encontrado la fuente donde incrementa los números? – emaillenin

+2

https://github.com/php/php-src/blob/master/Zend/zend_operators.c#L1706 – mario

Respuesta

10

La implementación de este operador está convenientemente ubicado en zend_operators.c, en una función que se llama aún más convenientemente increment_string():

static void increment_string(zval *str) /* {{{ */ 
{ 
    int carry=0; 
    int pos=Z_STRLEN_P(str)-1; 
    char *s=Z_STRVAL_P(str); 
    char *t; 
    int last=0; /* Shut up the compiler warning */ 
    int ch; 

    if (Z_STRLEN_P(str) == 0) { 
     STR_FREE(Z_STRVAL_P(str)); 
     Z_STRVAL_P(str) = estrndup("1", sizeof("1")-1); 
     Z_STRLEN_P(str) = 1; 
     return; 
    } 

    if (IS_INTERNED(s)) { 
     s = (char*) emalloc(Z_STRLEN_P(str) + 1); 
     memcpy(s, Z_STRVAL_P(str), Z_STRLEN_P(str) + 1); 
     Z_STRVAL_P(str) = s; 
    } 

    while (pos >= 0) { 
     ch = s[pos]; 
     if (ch >= 'a' && ch <= 'z') { 
      if (ch == 'z') { 
       s[pos] = 'a'; 
       carry=1; 
      } else { 
       s[pos]++; 
       carry=0; 
      } 
      last=LOWER_CASE; 
     } else if (ch >= 'A' && ch <= 'Z') { 
      if (ch == 'Z') { 
       s[pos] = 'A'; 
       carry=1; 
      } else { 
       s[pos]++; 
       carry=0; 
      } 
      last=UPPER_CASE; 
     } else if (ch >= '0' && ch <= '9') { 
      if (ch == '9') { 
       s[pos] = '0'; 
       carry=1; 
      } else { 
       s[pos]++; 
       carry=0; 
      } 
      last = NUMERIC; 
     } else { 
      carry=0; 
      break; 
     } 
     if (carry == 0) { 
      break; 
     } 
     pos--; 
    } 

    if (carry) { 
     t = (char *) emalloc(Z_STRLEN_P(str)+1+1); 
     memcpy(t+1, Z_STRVAL_P(str), Z_STRLEN_P(str)); 
     Z_STRLEN_P(str)++; 
     t[Z_STRLEN_P(str)] = '\0'; 
     switch (last) { 
      case NUMERIC: 
       t[0] = '1'; 
       break; 
      case UPPER_CASE: 
       t[0] = 'A'; 
       break; 
      case LOWER_CASE: 
       t[0] = 'a'; 
       break; 
     } 
     STR_FREE(Z_STRVAL_P(str)); 
     Z_STRVAL_P(str) = t; 
    } 
} 
/* }}} */ 
+3

Y esto se llama desde [increment_function()] (http://svn.php.net/viewvc/php/php-src/trunk/Zend/zend_operators.c?view=markup#l1790), que supongo que es el operador de incremento –

+0

@ Álvaro G. Vicario: Eso es correcto. – BoltClock

Cuestiones relacionadas