Guía de seguimiento dinámico de Solaris

Capítulo 6 Cadenas

DTrace admite el seguimiento y la manipulación de cadenas. Este capítulo describe el conjunto completo de las funciones del lenguaje D para declarar y manipular cadenas. A diferencia de ANSI-C, las cadenas en D tienen su propia compatibilidad de tipo y operador incorporada, por lo que puede utilizarlas fácilmente y sin ambigüedades en los programas de seguimiento.

Representación de las cadenas

Las cadenas se representan en DTrace como una matriz de caracteres con un byte nulo como terminación (es decir, un byte cuyo valor es cero, normalmente escrito como '\0'). La parte visible de la cadena es de longitud variable, en función de la ubicación del byte nulo; sin embargo, DTrace guarda cada cadena en una matriz de tamaño fijo de forma que cada sondeo supervisa una cantidad homogénea de datos. Las cadenas no pueden superar la longitud de este límite de cadena predefinido, sin embargo, el límite se puede modificar en el programa D o en la línea de comandos de dtrace mediante el ajuste de la opción strsize. Consulte el Capítulo 16Opciones y optimizables, para obtener más información sobre las opciones ajustables de DTrace. El límite predeterminado de la cadena es 256 bytes.

El lenguaje D proporciona un tipo string explícito en vez de utilizar el tipo char * para hacer referencia a las cadenas. El tipo string es equivalente a char *, en el sentido de que hace referencia a una secuencia de caracteres, pero el compilador de D y las funciones de D como trace() proporcionan mejores capacidades cuando se aplican a expresiones del tipo string. Por ejemplo, el tipo string elimina la ambigüedad del tipo char * cuando necesita realizar un seguimiento de los bytes de una cadena. En la instrucción de D:

trace(s);

Si s es del tipo char *, DTrace realizará un seguimiento del valor del puntero s (es decir, realizará un seguimiento de un valor de dirección de número entero). En la instrucción de D:

trace(*s);

por definición del operador *, el compilador de D anulará la referencia al puntero s y realizará un seguimiento del carácter único en dicha ubicación. Estos comportamientos son esenciales para que pueda manipular los punteros de caracteres que, por diseño, hacen referencia a caracteres únicos o a matrices de enteros de tamaño de byte que no son cadenas y no terminan con un byte nulo. En la instrucción de D:

trace(s);

Si s es del tipo string, el tipo string indica al compilador de D que desea que DTrace realice un seguimiento de una cadena de caracteres con una terminación de byte nulo cuya dirección está guardada en la variable s. También puede realizar comparaciones léxicas de expresiones del tipo string, como se describe en Comparación de cadenas.

Constantes de cadena

Las constantes de cadenas están incluidas entre comillas dobles (") y el compilador de D les asigna automáticamente el tipo string. Puede definir constantes de cadena de cualquier longitud, aspecto limitado únicamente por la cantidad de memoria que se permite a DTrace utilizar en el sistema. El compilador de D agrega automáticamente el byte nulo final ( \0) a cualquier constante de cadena que declare. El tamaño de un objeto de constante de cadena es el número de bytes asociados a la cadena más un byte adicional para el byte nulo final.

Es posible que una constante de cadena no contenga un carácter de nueva línea literal. Para crear cadenas que contengan líneas nuevas, use la secuencia de escape \n en vez de una línea nueva literal. Las constantes de cadenas también pueden contener cualquier secuencia de escape de caracteres especial definida para las constantes de caracteres en la Tabla 2–5.

Asignación de cadenas

A diferencia de la asignación de las variables char *, las cadenas se copian por valor, no por referencia. La asignación de cadenas se realiza utilizando el operador = y copia los bytes reales de la cadena desde el operando de origen hasta el byte nulo, incluido, a la variable del lado izquierdo, que debe ser del tipo string. Puede crear una nueva variable de tipo string asignándole una expresión de tipo string. Por ejemplo, la instrucción D:

s = "hello";

crearía una variable nueva s del tipo string y copiaría los 6 bytes de la cadena "hello" en ella (5 caracteres imprimibles más el byte nulo). La asignación de cadena es parecida a la función de biblioteca de strcpy(3C), excepto que si la cadena de origen supera el límite de almacenamiento de la cadena de destino, la cadena resultante se trunca automáticamente en este límite.

También puede asignar a una variable de cadena una expresión de tipo compatible con cadenas. En este caso, el compilador de D envía automáticamente la expresión de origen al tipo string y realiza una asignación de cadena. El compilador de D permite que una expresión de tipo char * o de tipo char[n] (es decir, una matriz escalar de char de cualquier tamaño), se envíe a un tipo string.

Conversión de cadenas

Las expresiones de otros tipos se pueden convertir explícitamente al tipo string utilizando una expresión de conversión de tipos o aplicando el operador especial stringof, que tiene un significado equivalente:

s = (string) expression				s = stringof ( expression )

El operador stringof está enlazado de una forma muy estrecha al operando que se encuentra a su derecha. Normalmente, se utilizan paréntesis para cerrar la expresión para una mayor claridad, aunque no son estrictamente necesarios.

Cualquier expresión del tipo escalar como un puntero o número entero, o una dirección de matriz escalar puede convertirse a cadena. Es posible que expresiones de otros tipos como void no se conviertan a string. Si convierte por error una dirección no válida a cadena, las funciones de seguridad de DTrace evitarán que dañe el sistema y DTrace, pero es posible que termine realizando un seguimiento de una secuencia de caracteres no descifrables.

Comparación de cadenas

D sobrecarga los operadores relacionales binarios y permite utilizarlos para las comparaciones de cadenas, así como para comparaciones de números enteros. Los operadores relacionales realizan la comparación de cadenas siempre que ambos operandos sean del tipo string, o cuando un operando es del tipo string y el otro operando se pueda promocionar al tipo string, como se describe en Asignación de cadenas. Todos los operadores relacionales se pueden utilizar para comparar cadenas:

Tabla 6–1 Operadores relacionales de D para cadenas

<

el operando de la izquierda es menor que el de la derecha 

<=

el operando de la izquierda es menor o igual que el de la derecha 

>

el operando de la izquierda es mayor que el de la derecha 

>=

el operando de la izquierda es mayor o igual que el de la derecha 

==

el operando de la izquierda es igual que el de la derecha 

!=

el operando de la izquierda es distinto que el de la derecha 

Al igual que con los números enteros, cada operador evalúa el valor del tipo int,que es igual a uno si la condición es true, o cero si es false.

Los operadores relacionales comparan las dos cadenas de entrada byte a byte, igual que la rutina de la biblioteca C strcmp(3C). Cada byte se compara utilizando su valor de entero correspondiente en el conjunto de caracteres ASCII, como se muestra en ascii(5), hasta que se lea un byte nulo o se alcance la longitud máxima de la cadena. Algunos ejemplos de comparaciones de cadenas D y sus resultados son:

"coffee" < "espresso"

... devuelve 1 (true) 

"coffee" == "coffee"

... devuelve 1 (true) 

"coffee" >= "mocha"

... devuelve 0 (false)