Manuel de suivi dynamique Solaris

Chapitre 6 Chaînes de caractères

DTrace assure la prise en charge du suivi et de la manipulation des chaînes. Ce chapitre décrit toutes les fonctionnalités du langage D qui permettent de déclarer et de manipuler des chaînes. Contrairement au langage ANSI-C, les chaînes en langage D possèdent leur propre prise en charge des types et opérateurs. Vous pouvez donc aisément et sans ambiguïté les utiliser dans vos programmes de suivi.

Représentation de chaînes

Les chaînes sont représentées dans DTrace sous la forme d'un tableau de caractères terminé par un octet nul (c'est-à-dire, un octet dont la valeur est égale à zéro, généralement présenté sous la forme '\0'). La partie visible de la chaîne correspond à la longueur de la variable, en fonction de l'emplacement de l'octet nul, mais DTrace enregistre chaque chaîne dans un tableau à taille fixe de sorte que chaque sonde suive une quantité conséquente de données. Les chaînes ne peuvent pas excéder la longueur de cette limite prédéfinie. Par contre, il est possible de modifier cette dernière dans votre programme en D ou sur la ligne de commande dtrace en réglant l'option strsize. Pour plus d'informations sur les options DTrace de réglage, reportez-vous au Chapitre16Options et paramètres réglables. La limite de chaîne par défaut est de 256 octets.

Le langage en D offre un type string explicite au lieu d'utiliser le type char * pour faire référence aux chaînes. Le type string équivaut à char * en ce qu'il correspond à l'adresse d'une séquence de caractères, mais les capacités du compilateur D et des fonctions du langage D comme le fournisseur trace() sont optimisées pour les expressions de type string. Par exemple, le type de chaîne supprime l'ambiguïté du type char * lorsque vous devez suivre les octets réels d'une chaîne. Dans un énoncé en D :

trace(s);

Si s est de type char *, DTrace suit la valeur du pointeur s (il suit une valeur d'adresse entière). Dans un énoncé en D :

trace(*s);

En définissant l'opérateur *, le compilateur D déréférence le pointeur s et suit le caractère unique à cet emplacement. Ces comportements sont essentiels pour vous permettre de manipuler les pointeurs de caractère qui font référence, à dessein, à d'autres caractères uniques ou à des tableaux de nombres entiers de la taille d'un octet ne constituant pas des chaînes et ne se terminant pas par un octet nul. Dans un énoncé en D :

trace(s);

Si s est de type string, le type string indique au compilateur D que vous souhaitez que DTrace suive une chaîne de caractères terminée par un caractère nul dont l'adresse est enregistrée dans la variable s. Vous pouvez également procéder à une comparaison lexicale des expressions de type string, comme indiqué à la section Comparaison de chaînes.

Constantes de chaîne

Les constantes de chaîne figurent entre guillemets doubles ("). Le type string leur est automatiquement attribué par le compilateur D. Vous pouvez définir des constantes de chaîne de n'importe quelle longueur, la seule limite étant la qualité de mémoire que DTrace peut utiliser sur votre système. L'octet nul de terminaison ( \0) est automatiquement ajouté par le compilateur D à toutes les constantes de chaîne que vous déclarez. La taille d'un objet de constante de chaîne correspond au nombre d'octets associé à la chaîne auquel vient s'ajouter un octet supplémentaire pour l'octet nul de terminaison.

Une constante chaîne ne peut pas contenir de caractère littéral de retour à la ligne. Pour créer des chaînes contenant des retours à la ligne, utilisez la séquence d'échappement \n plutôt qu'un retour à la ligne littéral. Les constantes de chaîne peuvent également contenir l'une des séquences spéciales d'échappement de caractères définies pour les constantes de caractère dans le Tableau 2–5.

Assignation de chaîne

Contrairement à l'assignation des variables char *, les chaînes sont copiées par valeur et non par référence. L'assignation de chaîne est réalisée à l'aide de l'opérateur = et copie les octets réels de la chaîne de l'opérande source jusqu'à l'octet nul, ce dernier compris, dans la variable située à gauche qui doit être de type string. Vous pouvez créer une nouvelle variable de type string en lui assignant une expression de type string. Par exemple, l'énoncé en D

s = "hello";

doit créer une nouvelle variable s de type string et y copier les 6 octets de la chaîne "hello" (5 caractères imprimables, plus l'octet nul). L'assignation de chaîne est un processus similaire à la fonction de bibliothèque du langage C strcpy(3C), hormis le fait que si la chaîne source dépasse la limite de stockage de la chaîne de destination, la chaîne qui en résulte est automatiquement tronquée à cette limite.

Vous pouvez également assigner à une variable de chaîne une expression d'un type compatible avec les chaînes. Le cas échéant, le compilateur D promeut automatiquement l'expression source en type de chaîne et exécute une assignation de chaîne. Le compilateur D autorise la promotion de n'importe quelle expression de type char * ou char[n] (c'est-à-dire un tableau scalaire de char de n'importe quelle taille) en string.

Conversion de chaîne

Les expressions d'autres types peuvent être explicitement converties en type string à l'aide d'une expression de forçage de type ou en appliquant l'opérateur spécial stringof, ces deux solutions ayant une signification identique :

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

L'opérateur stringof est très étroitement lié à l'opérande de droite. En règle générale, l'expression est placée entre parenthèses pour plus de clarté, les parenthèses n'étant pas impérativement requises.

Toute expression de type scalaire comme un pointeur, un nombre entier ou une adresse de tableau scalaire est convertible en chaîne. Les expressions d'autres types comme void ne sont pas convertibles en string. Si vous convertissez par erreur une adresse invalide en chaîne, vous n'endommagerez ni le système ni DTrace grâce aux fonctions de sécurité de DTrace mais vous devrez interrompre le suivi de la séquence de caractères indéchiffrables.

Comparaison de chaînes

D surcharge les opérateurs relationnels binaires et autorise leur utilisation dans les comparaisons de chaînes et de nombres entiers. Les opérateurs relationnels comparent les chaînes chaque fois que les deux opérandes sont de type string ou lorsqu'un opérande est de type string tandis que l'autre peut être promu en string, comme indiqué à la section Assignation de chaîne. Vous pouvez utiliser tous les opérateurs relationnels pour comparer des chaînes :

Tableau 6–1 Opérateurs relationnels et chaînes en langage D

<

opérande gauche inférieur à l'opérande droit 

<=

opérande gauche inférieur ou égal à l'opérande droit 

>

opérande gauche supérieur à l'opérande droit 

>=

opérande gauche supérieur ou égal à l'opérande droit 

==

opérande gauche égal à l'opérande droit 

!=

opérande gauche différent de l'opérande droit 

De même qu'avec les nombres entiers, chaque opérateur évalue la valeur du type int qui est égale à 1 si la condition est vraie et à 0 si la condition est fausse.

Les opérateurs relationnels comparent les deux chaînes d'entrée octet par octet, de la même manière que la routine de bibliothèque strcmp(3C) en langage C. Chaque octet est comparé à l'aide de sa valeur correspondante dans le jeu de caractères ASCII, comme illustré dans ascii(5), jusqu'à ce qu'un octet nul soit lu ou que la longueur de chaîne maximale soit atteinte. Exemples de comparaison de chaînes en D et leurs résultats :

"coffee" < "espresso"

... renvoie 1 (vrai) 

"coffee" == "coffee"

... renvoie 1 (vrai) 

"coffee" >= "mocha"

... renvoie 0 (faux)