package org.python.core.stringlib; /** * Parser for PEP-3101 field format specifications. */ public class InternalFormatSpecParser { private String spec; private int index; public InternalFormatSpecParser(String spec) { this.spec = spec; this.index = 0; } private static boolean isAlign(char c) { switch(c) { case '<': case '>': case '=': case '^': return true; default: return false; } } public InternalFormatSpec parse() { InternalFormatSpec result = new InternalFormatSpec(); if (spec.length() >= 1 && isAlign(spec.charAt(0))) { result.align = spec.charAt(index); index++; } else if (spec.length() >= 2 && isAlign(spec.charAt(1))) { result.fill_char = spec.charAt(0); result.align = spec.charAt(1); index += 2; } if (isAt("+- ")) { result.sign = spec.charAt(index); index++; } if (isAt("#")) { result.alternate = true; index++; } if (isAt("0")) { result.align = '='; result.fill_char = '0'; index++; } result.width = getInteger(); if (isAt(".")) { index++; result.precision = getInteger(); if (result.precision == -1) { throw new IllegalArgumentException("Format specifier missing precision"); } } if (index < spec.length()) { result.type = spec.charAt(index); if (index + 1 != spec.length()) { throw new IllegalArgumentException("Invalid conversion specification"); } } return result; } private int getInteger() { int value = 0; boolean empty = true; while (index < spec.length() && spec.charAt(index) >= '0' && spec.charAt(index) <= '9') { value = value * 10 + spec.charAt(index) - '0'; index++; empty = false; } if (empty) { return -1; } return value; } private boolean isAt(String chars) { return index < spec.length() && chars.indexOf(spec.charAt(index)) >= 0; } }