Guía de seguimiento dinámico de Solaris

printf()

La función printf() combina la capacidad de realizar un seguimiento de los datos, al igual que la función trace(), con la capacidad de generar los datos y otro texto con el formato específico que describa. La función printf() indica a DTrace que debe realizar un seguimiento de los datos asociados a cada argumento ubicado detrás del primer argumento y, a continuación, debe aplicar un formato a los resultados mediante las reglas descritas en el primer argumento printf(), conocido como cadena de formato.

La cadena de formato es una cadena normal que contiene una serie de conversiones de formato; cada una de ellas comienza con el carácter % y describe el formato que debe aplicarse al argumento correspondiente. La primera conversión de la cadena de formato se corresponde con el segundo argumento printf(), la segunda conversión con el tercer argumento, y así sucesivamente. Todo el texto que se encuentra entre una conversión y otra se imprime de forma literal. El carácter que se incluye después del carácter de conversión % describe el formato que se utilizará para el argumento correspondiente.

A diferencia de printf(3C), DTrace printf() es una función incorporada que reconoce el compilador del lenguaje D. Este compilador proporciona varios servicios de utilidad para la función printf() de DTrace que no se encuentran en la función printf() de la biblioteca de C:

Para implementar estas funciones, la cadena de formato de la función printf() debe especificarse como constante de cadena en el programa D. Las cadenas de formato no pueden ser variables dinámicas del tipo string.

Especificaciones de conversión

Cada especificación de conversión presenta al principio un carácter %, tras el que se incluye la siguiente información en el siguiente orden:

La función printf(3C) también admite las especificaciones de conversión con el formato % n$, donde n es un entero decimal; la función printf() de DTrace no admite este tipo de especificación de conversión.

Especificadores de indicadores

Para habilitar los indicadores de conversión de printf(), debe especificar uno o varios de los siguientes caracteres, que pueden aparecer en cualquier orden:

'

A la parte de un entero del resultado de una conversión decimal (%i, %d, %u, %f , %g o %G) se le a un formato con miles de caracteres de agrupación mediante un carácter de agrupación no monetario. Algunas configuraciones regionales, incluida la configuración regional de C POSIX, no proporcionan caracteres de agrupación no monetarios para su uso con este indicador.

-

El resultado de la conversión se justifica a la izquierda en el campo. La conversión se justifica a la derecha si no se ha especificado este indicador.

+

El resultado de la conversión con signo siempre comienza por un signo (+ o -). Si no se especifica este indicador, la conversión comienza por un signo sólo cuando se convierta un valor negativo.

space

Si el primer carácter de una conversión con signo no es un signo o si la conversión con signo no ofrece como resultado ningún carácter, se incluye un espacio antes del resultado. Si aparece tanto el indicador space como +, se omitirá el indicador de espacio.

#

El valor se convierte a un formato alternativo si se define éste para la conversión seleccionada. Los formatos alternativos para las conversiones se describen junto con la conversión correspondiente.

0

Para las conversiones d, i, o, u, x, X, e, E, f, g y G, se utilizan ceros iniciales (después de cualquier indicación de signo o base) para incluirlos en el ancho de campo. No se incluye ningún espacio adicional. Si aparece tanto el indicador 0 como -, se omitirá el indicador 0. En las conversiones d, i, o, u, x y X, si se especifica la precisión, se omite el indicador 0. Si aparece tanto el indicador 0 como ', los caracteres de agrupamiento se insertan antes de los ceros adicionales.

Especificadores de precisión y anchura

El ancho mínimo de campo puede especificarse en forma de cadena de dígitos decimales después de cualquier especificador de indicador, en cuyo caso el ancho de campo se establecerá en el número especificado de columnas. El ancho de campo también puede especificarse en forma de asterisco (*), en cuyo caso se accede al argumento adicional del tipo int para determinar el ancho de campo. Por ejemplo, para imprimir un entero x en un ancho de campo determinado por el valor de la variable int w, debe escribir la siguiente instrucción de D:

printf("%*d", w, x);

El ancho de campo también puede especificarse mediante el carácter ? para indicar que el ancho debe establecerse en función del número de caracteres necesarios para dar formato a una dirección con valores hexadecimales en el modelo de datos del núcleo del sistema operativo. El ancho se establece en 8 si el núcleo está utilizando un modelo de datos de 32 bits o en 16 si está utilizando un modelo de datos de 64 bits.

La precisión de la conversión puede especificarse en forma de cadena de dígitos decimales después de un punto (.) o en forma de asterisco ( *) después de un punto. Si se utiliza un asterisco para especificar la precisión, se accede a un argumento adicional del tipo int antes del argumento de conversión para determinar la precisión. Si se especifica tanto el ancho como la precisión en forma de asteriscos, los argumentos de printf() para la conversión deberían aparecer en el siguiente orden: ancho, precisión y valor.

Prefijos de tamaño

Los prefijos de tamaño son necesarios en los programas ANSI-C que utilizan printf(3C) para indicar el tamaño y el tipo del argumento de conversión. El compilador del lenguaje D realiza automáticamente este procesamiento para las llamadas a printf(), por lo que no es necesario utilizar prefijos. Aunque los prefijos de tamaño se proporcionan para la compatibilidad con C, se desaconseja explícitamente su uso en programas D, ya que enlazan el código a un modelo de datos específico al utilizar tipos derivados. Por ejemplo, si typedef se vuelve a definir con tipos de enteros diferentes en función del modelo de datos, no se puede utilizar una única conversión de C que funcione en ambos modelos de datos sin conocer de forma explícita los dos tipos subyacentes, y sin incluir una expresión de conversión de tipo o definir varias cadenas de formato. El compilador de D resuelve este problema automáticamente permitiendo omitir los prefijos de tamaño y determinando automáticamente el tamaño del argumento.

Los prefijos de tamaño pueden insertarse justo antes del nombre de la conversión de formato, y detrás de los especificadores de indicadores, ancho y precisión. Los prefijos de tamaño son los siguientes:

Formatos de conversión

Cada secuencia de caracteres de conversión permite obtener cero o más argumentos. Si se proporciona un número insuficiente de argumentos para la cadena de formato o si se ha agotado la cadena de formato, pero aún quedan argumentos, el compilador de D emite el mensaje de error correspondiente. Si se especifica un formato de conversión no definido, el compilador de D emite el mensaje de error correspondiente. Las secuencias de caracteres de conversión son:

a

El puntero o el argumento uintptr_t se imprime como nombre del símbolo del núcleo con el formato módulo `nombre_símbolo más un desplazamiento de bytes hexadecimal opcional. Si el valor no se encuentra dentro del intervalo definido por un símbolo del núcleo conocido, se imprimirá el valor en forma de entero hexadecimal.

c

El argumento char, short o int se imprime como carácter ASCII.

C

El argumento char, short o int se imprime como carácter ACSCII si el carácter presenta un formato ASCII imprimible. Si el carácter no es imprimible, se imprimirá mediante la secuencia de escape correspondiente, como se muestra en la Tabla 2–5.

d

El argumento char, short, int, long o long long se imprime en forma de entero decimal (base 10). Si el argumento tiene signo (signed), se imprimirá como valor con signo. Si, por el contrario, no tiene signo (unsigned), se imprimirá como valor sin signo. Esta conversión tiene el mismo significado que i.

e, E

El argumento float, double o long double se convierte al estilo [-] d.ddddd, donde hay un dígito antes del carácter de base y el número de dígitos posteriores al mismo es igual a la precisión. El carácter de base tiene un valor distinto a cero si el argumento es también distinto a cero. Si no se especifica la precisión, el valor predeterminado es 6. Si la precisión es 0 y no se ha especificado el indicador #, no aparece ningún carácter de base. El formato de conversión E genera un número con E en lugar de e antes del exponente. El exponente siempre contiene, al menos, dos dígitos. El valor se redondea para obtener el número adecuado de dígitos.

f

El argumento float, double o long double se convierte al estilo [-] ddd.ddd, donde el número de dígitos detrás del carácter de base es igual a la especificación de precisión. Si no se especifica la precisión, el valor predeterminado es 6. Si la precisión es 0 y no se ha especificado el indicador #, no aparece ningún carácter de base. Si aparece un carácter de base, al menos, uno de los dígitos debe aparecer delante de él. El valor se redondea para obtener el número adecuado de dígitos.

g, G

El argumento float, double o long double se imprime con el estilo f o e (o el estilo E si se utiliza un carácter de conversión G), con la precisión que especifica el número de dígitos significativos. Si la precisión explícita es 0, se establece como 1. El estilo utilizado depende del valor convertido: el estilo e (o E) sólo se utiliza si el exponente procedente de la conversión es inferior a -4 o superior o igual a la precisión. Los ceros finales se eliminan de la parte fraccional del resultado. Sólo aparece un carácter de base si incluye a continuación un dígito. Si se especifica el indicador #, los ceros finales no se eliminan del resultado.

i

El argumento char, short, int, long o long long se imprime en forma de entero decimal (base 10). Si el argumento tiene signo (signed), se imprimirá como valor con signo. Si, por el contrario, no tiene signo (unsigned), se imprimirá como valor sin signo. Esta conversión tiene el mismo significado que d.

o

El argumento char, short, int, long o long long se imprime en forma de entero octal (base 8) sin signo. Los argumentos con signo (signed) o sin signo (unsigned) pueden utilizarse con esta conversión. Si se especifica el indicador #, se aumentará la precisión del resultado, si es necesario, para hacer que el primer dígito del resultado sea cero.

p

El puntero o el argumento uintptr_t se imprime en forma de entero hexadecimal (base 16). El lenguaje D acepta argumentos de puntero de cualquier tipo. Si se especifica el indicador #, se incluirá 0x delante de un resultado distinto a cero.

s

El argumento debe ser una matriz de char o una cadena, string. Los bytes de la matriz o la cadena, string, se leen hasta un carácter nulo final o hasta el final de los datos, y se interpretan e imprimen como caracteres ASCII. Si no se especifica la precisión, se establece como infinita, por lo que se imprimen todos los caracteres hasta el primer carácter nulo. Si, por el contrario, se especifica la precisión, sólo se imprimirá la parte de la matriz de caracteres que se mostrará en el número correspondiente de columnas de la pantalla. Si se da un formato a un argumento del tipo char *, debería convertirse en una cadena, string, o incluir como prefijo un indicador stringof del lenguaje D para indicar que DTrace debe realizar un seguimiento de los bytes de la cadena y darles un formato.

S

El argumento debe ser una matriz de char o una cadena, string. El argumento se procesa del mismo modo que la conversión %s, pero todos los caracteres ASCII no imprimibles se sustituyen por la secuencia de escape correspondiente, que se describe en la Tabla 2–5.

u

El argumento char, short, int, long o long long se imprime en forma de entero decimal (base 10) sin signo. Los argumentos con signo (signed) o sin signo (unsigned) pueden utilizarse con esta conversión, aunque al resultado siempre se le da un formato sin signo (unsigned).

wc

El argumento int se convierte en un carácter ancho (wchar_t) y se imprime el carácter ancho resultante.

ws

El argumento debe ser una matriz de wchar_t. Los bytes de la matriz se leen hasta un carácter nulo final o el final de los datos, y se interpretan e imprimen como caracteres anchos. Si no se especifica la precisión, se establece como infinita,por lo que se imprimen todos los caracteres anchos hasta el primer carácter nulo. Si, por el contrario, se especifica la precisión, sólo se imprimirá la parte de la matriz de caracteres anchos que se mostrará en el número correspondiente de columnas de la pantalla.

x, X

El argumento char, short, int, long o long long se imprime en forma de entero hexadecimal (base 16) sin signo. Los argumentos con signo (signed) o sin signo (unsigned) pueden utilizarse con esta conversión. Si se utiliza el formato x de la conversión, se utilizarán las letras abcdef. Si se utiliza el formato X de la conversión, se utilizarán las letras ABCDEF. Si se especifica el indicador #, se incluirá 0x (para %x) o 0X (para %X) delante de un resultado distinto de cero.

Y

Se interpreta que el argumento uint64_t es el número de nanosegundos transcurridos desde las 00:00 horas (Horario universal coordinado) del 1 de enero de 1970, y se imprime con el siguiente formato cftime(3C): "%Y %a %b %e %T %Z". El número de nanosegundos transcurridos desde las 00:00 horas UTC del 1 de enero de 1970 está disponible en la variable walltimestamp.

%

Permite imprimir un carácter % literal. No se convierte ningún argumento. La especificación de conversión completa debe ser %%.