diff --git a/tools/VerifyTranslatedStringFormatting.java b/tools/VerifyTranslatedStringFormatting.java new file mode 100644 index 00000000..2aeb22d1 --- /dev/null +++ b/tools/VerifyTranslatedStringFormatting.java @@ -0,0 +1,116 @@ +// run: java tools/VerifyTranslatedStringFormatting.java +// Reads all localized strings and makes sure they contain valid formatting placeholders matching the original English strings to avoid crashes. + +import org.w3c.dom.*; +import javax.xml.parsers.*; +import java.io.*; +import java.util.*; +import java.util.regex.*; + +public class VerifyTranslatedStringFormatting{ + // %[argument_index$][flags][width][.precision][t]conversion + private static final String formatSpecifier="%(\\d+\\$)?([-#+ 0,(\\<]*)?(\\d+)?(\\.\\d+)?([tT])?([a-zA-Z%])"; + private static final Pattern fsPattern=Pattern.compile(formatSpecifier); + + private static HashMap> placeholdersInStrings=new HashMap<>(); + private static int errorCount=0; + + public static void main(String[] args) throws Exception{ + DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(false); + DocumentBuilder builder=factory.newDocumentBuilder(); + Document doc; + try(FileInputStream in=new FileInputStream("mastodon/src/main/res/values/strings.xml")){ + doc=builder.parse(in); + } + NodeList list=doc.getDocumentElement().getChildNodes(); // why does this stupid NodeList thing exist at all? + for(int i=0;i placeholders=new ArrayList<>(); + Matcher matcher=fsPattern.matcher(value); + while(matcher.find()){ + placeholders.add(matcher.group()); + } + placeholdersInStrings.put(name, placeholders); + } + } + for(File file:new File("mastodon/src/main/res").listFiles()){ + if(file.getName().startsWith("values-")){ + File stringsXml=new File(file, "strings.xml"); + if(stringsXml.exists()){ + processFile(stringsXml); + } + } + } + if(errorCount>0){ + System.err.println("Found "+errorCount+" problems in localized strings"); + System.exit(1); + } + } + + private static void processFile(File file) throws Exception{ + DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(false); + DocumentBuilder builder=factory.newDocumentBuilder(); + Document doc; + try(FileInputStream in=new FileInputStream(file)){ + doc=builder.parse(in); + } + NodeList list=doc.getDocumentElement().getChildNodes(); + for(int i=0;i placeholders){ + for(String placeholder:placeholders){ + if(placeholder.equals("%,d")){ + // %,d and %d are interchangeable but %,d provides nicer formatting + if(!str.contains(placeholder) && !str.contains("%d")) + return false; + }else if(!str.contains(placeholder)){ + return false; + } + } + return true; + } +} \ No newline at end of file