/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: TextUtils.java * * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. * * Electric(tm) is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Electric(tm) is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Electric(tm); see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, Mass 02111-1307, USA. */ package com.sun.electric.tool.simulation.test; import java.text.NumberFormat; import java.text.DecimalFormat; import java.util.Locale; /** * This class is a collection of text utilities. */ public class TextUtils { /** * Determines if the specified character is a ISO-LATIN-1 digit * (<code>'0'</code> through <code>'9'</code>). * <p> * This can be method instead of Character, if we are not ready * to handle Arabi-Indic, Devanagaru and other digits. * * @param ch the character to be tested. * @return <code>true</code> if the character is a ISO-LATIN-1 digit; * <code>false</code> otherwise. * @see java.lang.Character#isDigit(char) */ public static boolean isDigit(char ch) { return '0' <= ch && ch <= '9'; } /** * Determines if the specified character is a letter or digit. * <p> * A character is considered to be a letter or digit if either * <code>Character.isLetter(char ch)</code> or * <code>TextUtils.isDigit(char ch)</code> returns * <code>true</code> for the character. * * @param ch the character to be tested. * @return <code>true</code> if the character is a letter or digit; * <code>false</code> otherwise. * @see TextUtils#isDigit(char) * @see java.lang.Character#isJavaLetterOrDigit(char) * @see java.lang.Character#isLetter(char) */ public static boolean isLetterOrDigit(char ch) { return isDigit(ch) || Character.isLetter(ch); } /** * Method to determine if one string is a subset of another, but case-insensitive. * @param main the main string. * @param with the substring. * @return true if the main string starts with the substring, ignoring case. */ public static boolean startsWithIgnoreCase(String main, String with) { int mainLen = main.length(); int withLen = with.length(); if (withLen > mainLen) return false; for(int i=0; i<withLen; i++) { char mainChr = Character.toLowerCase(main.charAt(i)); char withChr = Character.toLowerCase(with.charAt(i)); if (mainChr != withChr) return false; } return true; } /** * Method to parse the number in a string. * <P> * There are many reasons to use this method instead of Integer.parseInt... * <UL> * <LI>This method can handle any radix. * If the number begins with "0", presume base 8. * If the number begins with "0b", presume base 2. * If the number begins with "0x", presume base 16. * Otherwise presume base 10. * <LI>This method can handle numbers that affect the sign bit. * If you give 0xFFFFFFFF to Integer.parseInt, you get a numberFormatPostFix exception. * This method properly returns -1. * <LI>This method does not require that the entire string be part of the number. * If there is extra text after the end, Integer.parseInt fails (for example "123xx"). * <LI>This method does not throw an exception if the number is invalid (or blank). * </UL> * @param s the string with a number in it. * @return the numeric value. */ public static int atoi(String s) { return atoi(s, 0, 0); } /** * Method to parse the number in a string. * See the comments for "atoi(String s)" for reasons why this method exists. * @param s the string with a number in it. * @param pos the starting position in the string to find the number. * @return the numeric value. */ public static int atoi(String s, int pos) { return atoi(s, pos, 0); } /** * Method to parse the number in a string. * See the comments for "atoi(String s)" for reasons why this method exists. * @param s the string with a number in it. * @param pos the starting position in the string to find the number. * @param base the forced base of the number (0 to determine it automatically). * @return the numeric value. */ public static int atoi(String s, int pos, int base) { int num = 0; int sign = 1; int len = s.length(); if (pos < len && s.charAt(pos) == '-') { pos++; sign = -1; } if (base == 0) { base = 10; if (pos < len && s.charAt(pos) == '0') { pos++; base = 8; if (pos < len && (s.charAt(pos) == 'x' || s.charAt(pos) == 'X')) { pos++; base = 16; } else if (pos < len && (s.charAt(pos) == 'b' || s.charAt(pos) == 'B')) { pos++; base = 2; } } } for(; pos < len; pos++) { char cat = s.charAt(pos); int digit = Character.digit(cat, base); if (digit < 0) break; num = num * base + digit; // if ((cat >= 'a' && cat <= 'f') || (cat >= 'A' && cat <= 'F')) // { // if (base != 16) break; // num = num * 16; // if (cat >= 'a' && cat <= 'f') num += cat - 'a' + 10; else // num += cat - 'A' + 10; // continue; // } // if (!TextUtils.isDigit(cat)) break; // if (cat >= '8' && base == 8) break; // num = num * base + cat - '0'; } return(num * sign); } private static NumberFormat numberFormatSpecific = null; /** * Method to convert a double to a string. * If the double has no precision past the decimal, none will be shown. * @param v the double value to format. * @return the string representation of the number. */ public static String formatDouble(double v) { return formatDouble(v, 3); } /** * Method to convert a double to a string. * It will show up to 'numFractions' digits past the decimal point if numFractions is greater * than zero. If numFractions is 0, it will show infinite (as far as doubles go) precision. * If the double has no precision past the decimal, none will be shown. * This method is now thread safe. * @param v the double value to format. * @param numFractions the number of digits to the right of the decimal point. * @return the string representation of the number. */ public static synchronized String formatDouble(double v, int numFractions) { if (numberFormatSpecific == null) { numberFormatSpecific = NumberFormat.getInstance(Locale.US); if (numberFormatSpecific != null) numberFormatSpecific.setGroupingUsed(false); try { DecimalFormat d = (DecimalFormat)numberFormatSpecific; d.setDecimalSeparatorAlwaysShown(false); } catch (Exception e) {} } if (numFractions == 0) { numberFormatSpecific.setMaximumFractionDigits(340); } else { numberFormatSpecific.setMaximumFractionDigits(numFractions); } return numberFormatSpecific.format(v); } }