using System;
using System.Collections.Generic;
namespace CppSharp.AST
{
public enum ArchType
{
UnknownArch,
x86, // X86: i[3-9]86
x86_64 // X86-64: amd64, x86_64
}
///
/// Represents a shared library or a static library archive.
///
public class NativeLibrary
{
public NativeLibrary(string file)
: this()
{
FileName = file;
}
public NativeLibrary()
{
Symbols = new List();
Dependencies = new List();
}
///
/// File name of the library.
///
public string FileName;
public ArchType ArchType { get; set; }
///
/// Symbols gathered from the library.
///
public IList Symbols;
public IList Dependencies { get; private set; }
}
public class SymbolContext
{
///
/// List of native libraries.
///
public List Libraries;
///
/// Index of all symbols to their respective libraries.
///
public Dictionary Symbols;
public SymbolContext()
{
Libraries = new List();
Symbols = new Dictionary();
}
public NativeLibrary FindOrCreateLibrary(string file)
{
var library = Libraries.Find(m => m.FileName.Equals(file));
if (library == null)
{
library = new NativeLibrary(file);
Libraries.Add(library);
}
return library;
}
public void IndexSymbols()
{
foreach (var library in Libraries)
{
foreach (var symbol in library.Symbols)
{
if (!Symbols.ContainsKey(symbol))
Symbols[symbol] = library;
if (symbol.StartsWith("__", StringComparison.Ordinal))
{
string stripped = symbol.Substring(1);
if (!Symbols.ContainsKey(stripped))
Symbols[stripped] = library;
}
}
}
}
public bool FindSymbol(ref string symbol)
{
NativeLibrary lib;
if (FindLibraryBySymbol(symbol, out lib))
return true;
string alternativeSymbol;
// Check for C symbols with a leading underscore.
alternativeSymbol = "_" + symbol;
if (FindLibraryBySymbol(alternativeSymbol, out lib))
{
symbol = alternativeSymbol;
return true;
}
alternativeSymbol = symbol.TrimStart('_');
if (FindLibraryBySymbol(alternativeSymbol, out lib))
{
symbol = alternativeSymbol;
return true;
}
alternativeSymbol = "_imp_" + symbol;
if (FindLibraryBySymbol(alternativeSymbol, out lib))
{
symbol = alternativeSymbol;
return true;
}
alternativeSymbol = "__imp_" + symbol;
if (FindLibraryBySymbol("__imp_" + symbol, out lib))
{
symbol = alternativeSymbol;
return true;
}
return false;
}
public bool FindLibraryBySymbol(string symbol, out NativeLibrary library)
{
return Symbols.TryGetValue(symbol, out library);
}
}
}