Analyser les chaînes de format printf Objective-C?

Je veux obtenir les plages de membres dans une NSSsortingng construite avec +[NSSsortingng ssortingngWithFormat:] . Quel est le meilleur moyen d’parsingr la chaîne de format objective-c? Je ne peux pas simplement utiliser un parsingur de chaînes au format C à cause de %@ . Je dois également m’assurer qu’il prend en charge les commandes de formats: %1$d , %2$@ , etc.

Par exemple, avec la chaîne construite avec [NSSsortingng ssortingngWithFormat:@"foo %2$@ bar %1$@", @"Heath", @"Borders"] , j’aimerais idéalement utiliser le NSArray suivant: @[NSMakeRange(15, 5), NSMakeRange(4, 6)] . Le premier object de tableau correspond au premier élément de données de la chaîne de format, le deuxième object de tableau au deuxième élément de données, etc.

Dans ce cas, l’API ressemblerait à quelque chose comme + (NSSsortingng *) ssortingngWithFormatRanges:(NSArray **)outFormatRanges withFormat:(NSSsortingng *)format, ... NS_FORMAT_FUNCTION(1,2); Il renverrait une NSSsortingng exactement comme +[NSSsortingng ssortingngWithFormat:] , mais renverrait également un NSArray avec NSRange s de chaque élément de données de format.

— MODIFIER —

Étant donné que cette question a 3 ans, je serais heureux avec une implémentation en C uniquement à ce stade.

J’ai examiné cela il y a quelques années. Si je comprends votre question, il n’existe aucun moyen simple d’obtenir l’AST d’une chaîne de formatage pour les chaînes de format C ou Cocoa.

J’ai écrit NSXMLElement + elementWithXMLFormat qui permettait l’insertion sans échappement de NSXMLElements dans une chaîne de format avec un code de format %%%@ spécial, ce qui nécessitait l’extension du format de Cocoa. Ma technique peut vous être utile:

https://github.com/rentzsch/nsxmlelement-elementwithxmlformat/blob/937b54b2a830a8fbbd72d6bc5e48bafd495ddcbd/NSXMLElement%2BelementWithX MLMLFormat.m#L

J’extrais et NUL-délimite seulement les codes de format, le parcours traditionnellement, puis le réassemble.

J’ai écrit un parsingur syntaxique pour ceux de Swift (afin de pouvoir détecter ces espaces réservés dans Localizable.ssortingngs et d’extraire les types attendus lors de l’appel de ssortingngWithFormat: avec ces chaînes) pour mon outil SwiftGen.

Vous pouvez voir la partie du code qui effectue l’parsing ici sur mon GitHub .

  • Bien sûr, il s’agit de Swift et non d’Objective-C, mais j’imagine qu’il est facilement traduisible en ObjC, tant que vous conservez la logique de l’algorithme.
  • Mon code ne renvoie pas non plus les plages en tant que sorties de ces fonctions – seulement les types – mais le code des fonctions typesFromFormatSsortingng a définitivement access aux plages de ces espaces réservés et peut les renvoyer totalement en plus du type détecté changer, je n’avais tout simplement pas besoin de ces gammes, donc je ne les ai pas incluses dans le type de retour)

(Une fois que vous avez les plages pour les espaces réservés comme %d ou %2$@ , il sera facile de déduire les plages pour les parameters de chaîne: la première plage aura la même .location que le 1er espace réservé, mais la longueur du valeur remplacée, la 2ème plage aura le .location du 2ème espace réservé + (firstValue.length-firstRange.length) pour prendre en compte le décalage, etc.)

HTH.