/******************************************************************************* * Copyright (c) 2008 Red Hat, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Elliott Baron <ebaron@redhat.com> - initial API and implementation *******************************************************************************/ package org.eclipse.linuxtools.valgrind.core; import java.io.IOException; import org.eclipse.linuxtools.internal.valgrind.core.Messages; import org.eclipse.osgi.util.NLS; /** * Class containing convenient methods common to Valgrind * parsers. */ public final class ValgrindParserUtils { private static final String DOT = "."; //$NON-NLS-1$ private static final String EMPTY_STRING = ""; //$NON-NLS-1$ /** * Retrieves ARGUMENT portion of [OPTION][DELIMITER][ARGUMENT] * where ARGUMENT is a Long * @param line - the line to parse * @param delim - the DELIMITER to separate on * @return Long value of ARGUMENT * @throws IOException If parsing failed. */ public static Long parseLongValue(String line, String delim) throws IOException { Long result = null; String[] parts = line.split(delim, 2); if (parts.length > 1 && isNumber(parts[1])) { result = Long.parseLong(parts[1]); } else { fail(line); } return result; } /** * Retrieves ARGUMENT portion of [OPTION][DELIMITER][ARGUMENT] * where ARGUMENT is a String * @param line - the line to parse * @param delim - the DELIMITER to separate fields * @return String value of ARGUMENT * @throws IOException If parsing failed. */ public static String parseStrValue(String line, String delim) throws IOException { String result = null; String[] parts = line.split(delim, 2); if (parts.length > 1) { result = parts[1]; } else { fail(line); } return result; } /** * Retrieves PID from filename with format [PREFIX][PID].[EXTENSION] * @param filename - the file name to parse * @param prefix - the prefix of the filename up to the PID * @return - the PID portion of the filename as an Integer * @throws IOException If PID can not be parsed. */ public static Integer parsePID(String filename, String prefix) throws IOException { String pidstr = filename.substring(prefix.length(), filename.lastIndexOf(DOT)); if (isNumber(pidstr)) { return Integer.valueOf(pidstr); } else { throw new IOException("Cannot parse PID from output file"); //$NON-NLS-1$ } } /** * Throws an IOException indicating parsing failed on a given line * @param line - line that parsing failed * @throws IOException If parsing failed. */ public static void fail(String line) throws IOException { throw new IOException(NLS.bind(Messages.getString("AbstractValgrindTextParser.Parsing_output_failed"), line)); //$NON-NLS-1$ } /** * Determines if argument is a number * @param string - argument to test * @return - true if argument is a number */ public static boolean isNumber(String string) { boolean result = true; char[] chars = string.toCharArray(); for (int i = 0; i < chars.length; i++) { if (!Character.isDigit(chars[i])) { result = false; } } return result; } /** * Parses string ending with format ([FILE]:[LINE MODULE]) * Assumes syntax is: "\(.*:[0-9]+(\s.+)?\)$" * @param line - String with the above criteria * @return a tuple of [String filename, Integer line] */ public static Object[] parseFilename(String line) { String filename = null; int lineNo = 0; int ix = line.lastIndexOf('('); if (ix >= 0) { String part = line.substring(ix, line.length()); part = part.substring(1, part.length() - 1); // remove leading and trailing parentheses if ((ix = part.lastIndexOf(':')) >= 0) { String strLineNo = part.substring(ix + 1); if (isNumber(strLineNo)) { lineNo = Integer.parseInt(strLineNo); filename = part.substring(0, ix); } else { // handle format: (FILE:LINE MODULE) int ix1 = strLineNo.indexOf(' '); if (ix1 > 0) { strLineNo = strLineNo.substring(0, ix1); if (isNumber(strLineNo)) { lineNo = Integer.parseInt(strLineNo); filename = part.substring(0, ix); } } } } else { // check for "in " token (lib, with symbol) part = part.replaceFirst("^in ", EMPTY_STRING); //$NON-NLS-1$ // check for "within " token (lib, without symbol) part = part.replaceFirst("^within ", EMPTY_STRING); //$NON-NLS-1$ filename = part; // library, no line number } } return new Object[] { filename, lineNo }; } }