blob: ffe717f62efac4742631a093813635cd4db00b2d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009 STMicroelectronics.
* 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:
* Xavier Raynaud <xavier.raynaud@st.com> - initial API and implementation
*******************************************************************************/
package org.eclipse.linuxtools.binutils.utils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.core.resources.IProject;
import org.eclipse.linuxtools.tools.launch.core.factory.CdtSpawnerProcessFactory;
/**
* This class launches NM and parses output.
*/
public class STNM {
private static Pattern undef_pattern = null;
private static Pattern normal_pattern = null;
private final STNMSymbolsHandler handler;
/**
* Constructor
*
* @param command
* the nm to call
* @param params
* nm params
* @param file
* file to parse
* @param handler The symbol handler.
* @param project
* the project to get the path to use to run nm
* @throws IOException If an IOException occured.
*/
public STNM(String command, String[] params, String file, STNMSymbolsHandler handler, IProject project)
throws IOException {
this.handler = handler;
if (handler != null) {
init(command, params, file, project);
}
}
private void init(String command, String[] params, String file, IProject project) throws IOException {
String[] args = null;
if (params == null || params.length == 0) {
args = new String[] { command, file };
} else {
args = new String[params.length + 2];
args[0] = command;
args[params.length + 1] = file;
System.arraycopy(params, 0, args, 1, params.length);
}
Process process = CdtSpawnerProcessFactory.getFactory().exec(args, project);
parseOutput(process.getInputStream());
process.destroy();
}
private void parseOutput(InputStream stream) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
String line;
// See matcher.java for regular expression string data definitions.
if (undef_pattern == null) {
undef_pattern = Pattern.compile("^\\s+U\\s+(\\S+)"); //$NON-NLS-1$
}
if (normal_pattern == null) {
normal_pattern = Pattern.compile("^(\\S+)\\s+([AaTtBbDd])\\s+(\\S+)"); //$NON-NLS-1$
}
while ((line = reader.readLine()) != null) {
Matcher undef_matcher = undef_pattern.matcher(line);
Matcher normal_matcher = normal_pattern.matcher(line);
try {
if (undef_matcher.matches()) {
handler.foundUndefSymbol(undef_matcher.group(1));
} else if (normal_matcher.matches()) {
char type = normal_matcher.group(2).charAt(0);
String name = normal_matcher.group(3);
String address = normal_matcher.group(1);
switch (type) {
case 'T':
case 't':
handler.foundTextSymbol(name, address);
break;
case 'B':
case 'b':
handler.foundBssSymbol(name, address);
break;
case 'D':
case 'd':
handler.foundDataSymbol(name, address);
break;
}
}
} catch (NumberFormatException|IndexOutOfBoundsException e) {
// ignore
}
}
}
}