| /******************************************************************************* |
| * Copyright (c) 2000, 2009 QNX Software Systems and others. |
| * 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: |
| * QNX Software Systems - Initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.cdt.utils; |
| |
| import java.io.BufferedReader; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.InputStreamReader; |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| |
| import org.eclipse.cdt.utils.spawner.ProcessFactory; |
| |
| /** |
| */ |
| public class NM { |
| |
| public class AddressNamePair { |
| public String name; |
| |
| public long address; |
| |
| public AddressNamePair(String n, long a) { |
| name = n; |
| address = a; |
| } |
| |
| @Override |
| public String toString() { |
| return (name + "@" + Long.toHexString(address)); //$NON-NLS-1$ |
| } |
| |
| } |
| |
| private static Pattern undef_pattern = null; |
| private static Pattern normal_pattern = null; |
| |
| /** |
| * @since 5.1 |
| */ |
| protected List<String> undef_symbols; |
| /** |
| * @since 5.1 |
| */ |
| protected List<AddressNamePair> text_symbols; |
| /** |
| * @since 5.1 |
| */ |
| protected List<AddressNamePair> bss_symbols; |
| /** |
| * @since 5.1 |
| */ |
| protected List<AddressNamePair> data_symbols; |
| |
| 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()) { |
| undef_symbols.add(undef_matcher.group(1)); |
| } else if (normal_matcher.matches()) { |
| char type = normal_matcher.group(2).charAt(0); |
| String name = normal_matcher.group(3); |
| long address = Long.parseLong(normal_matcher.group(1), 16); |
| AddressNamePair val = new AddressNamePair(name, address); |
| |
| switch (type) { |
| case 'T': |
| case 't': |
| text_symbols.add(val); |
| break; |
| case 'B': |
| case 'b': |
| bss_symbols.add(val); |
| break; |
| case 'D': |
| case 'd': |
| data_symbols.add(val); |
| break; |
| } |
| } |
| } catch (NumberFormatException e) { |
| // ignore. |
| } catch (IndexOutOfBoundsException e) { |
| // ignore |
| } |
| } |
| |
| } |
| |
| public NM(String file, boolean dynamic_only) throws IOException { |
| this ("nm", file, dynamic_only); //$NON-NLS-1$ |
| } |
| |
| public NM(String command, String file, boolean dynamic_only) throws IOException { |
| this(command, (dynamic_only) ? new String[] {"-C", "-D"}: null, file); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| public NM(String command, String param, String file) throws IOException { |
| String[] params; |
| if (param == null || param.length() == 0) { |
| params = new String[0]; |
| } else { |
| // FIXME: This is wrong we have to check for quoted strings. |
| params = param.split("\\s"); //$NON-NLS-1$ |
| } |
| init(command, params, file); |
| } |
| |
| public NM(String command, String[] params, String file) throws IOException { |
| init(command, params, file); |
| } |
| |
| protected void init(String command, String[] params, String file) throws IOException { |
| String[] args = null; |
| if (params == null || params.length == 0) { |
| args = new String[] {command, "-C", file}; //$NON-NLS-1$ |
| } else { |
| args = new String[params.length + 2]; |
| args[0] = command; |
| System.arraycopy(params, 0, args, 1, params.length); |
| args[params.length+1] = file; |
| } |
| |
| undef_symbols = new ArrayList<String>(); |
| text_symbols = new ArrayList<AddressNamePair>(); |
| data_symbols = new ArrayList<AddressNamePair>(); |
| bss_symbols = new ArrayList<AddressNamePair>(); |
| Process process = ProcessFactory.getFactory().exec(args); |
| parseOutput(process.getInputStream()); |
| process.destroy(); |
| } |
| |
| public String[] getUndefSymbols() { |
| return undef_symbols.toArray(new String[0]); |
| } |
| |
| public AddressNamePair[] getTextSymbols() { |
| return text_symbols.toArray(new AddressNamePair[0]); |
| } |
| |
| public AddressNamePair[] getDataSymbols() { |
| return data_symbols.toArray(new AddressNamePair[0]); |
| } |
| |
| public AddressNamePair[] getBSSSymbols() { |
| return bss_symbols.toArray(new AddressNamePair[0]); |
| } |
| |
| } |