public List<FormatArgument> analyzeFormatStringWithParameters(String formatString) {

		FormatParsingData data = new FormatParsingData();
		Map<Integer, FormatArgument> formatArgumentMap = new HashMap<>();
		for (int i = 0; i < formatString.length(); i++) {
			char c = formatString.charAt(i);
			if (c == ' ') {
				continue;
			}
			if (c == '%') {
				if (emitPercent(formatString, i)) {
					++i;
				}
				else {
					data.setInConversion(true);
					data.clearData();
					data.setParameterIndex(locateParameterIndex(formatString, i));
					if (data.getParameterIndex() == 0) {
						return null; // $ operand number is required
					}
					i += Integer.toString(data.getParameterIndex()).length() + 1; // i should be at $
					if (isFlag(formatString.charAt(i + 1))) {
						i = skipFlags(formatString, i + 1);
					}
					continue;
				}
			}
			if (data.isInConversion()) {
				if (data.getLengthModifier() != null) {
					data.setConversionSpecifier(detectConversionSpecifier(c));
					if (data.getConversionSpecifier() == null) {
						return null; // Problem with format string
					}
					formatArgumentMap.put(data.getParameterIndex(), new FormatArgument(
						data.getLengthModifier(), data.getConversionSpecifier()));
					data.setInConversion(false);
					continue;
				}
				data.setLengthModifier(detectLengthModifier(c));
				if (data.getLengthModifier() == null) {
					i = searchWithNullModifier(formatString, i, data, formatArgumentMap);
					if (i == -1) {
						return null;
					}
				}
			}
		}
		return convertMapToList(formatArgumentMap);
	}
Handles format Strings with parameters. In this parser, we define a format
String parameter to be an integer n provided in the form: "%n$" or "*n$", where n is
the index of the referred argument. If a placeholder uses a format
argument parameter, all other placeholders must also have a parameter. Also,
all gaps between format argument indices are not supported. For instance, if
the first and third arguments are used, there must also be a parameter for a
second argument. Any parameter pattern beginning with % or * and ending with
$ must have integer in between. Failing to adhere by the format string
parameter requirements returns null.

@param formatString format String
@return List of FormatArgument


        TODO: What if multiple conversion specs refer to the same placeholder
        with different types? Ex: "%1$*1$x" (uses unsigned int and int)
        Currently just overwrites previous type
Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/plugin/core/string/variadic/FormatStringParser.java