mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-24 09:25:31 +02:00
Changed the way Strings are stored in the PDOM to support strings larger than the Chunk size. Added support for Macros and the use of them when skipping over header files (i.e. don't skip the macros). Upversioned the PDOM to kick off reindexing.
This commit is contained in:
parent
9d6cdda5a6
commit
1be823b03c
18 changed files with 758 additions and 306 deletions
|
@ -6,10 +6,10 @@ import junit.framework.TestCase;
|
|||
|
||||
import org.eclipse.cdt.core.testplugin.CTestPlugin;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.BTree;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.DBString;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.Database;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.IBTreeComparator;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.IString;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
|
||||
|
@ -84,7 +84,7 @@ public class DBTest extends TestCase {
|
|||
}
|
||||
|
||||
public int compare(int record) throws CoreException {
|
||||
return db.stringCompare(record + 4, key);
|
||||
return db.getString(db.getInt(record + 4)).compare(key);
|
||||
}
|
||||
|
||||
public boolean visit(int record) throws CoreException {
|
||||
|
@ -92,8 +92,7 @@ public class DBTest extends TestCase {
|
|||
return false;
|
||||
}
|
||||
|
||||
public int findIn(BTree btree) throws CoreException {
|
||||
btree.accept(this);
|
||||
public int getRecord() {
|
||||
return record;
|
||||
}
|
||||
|
||||
|
@ -134,23 +133,28 @@ public class DBTest extends TestCase {
|
|||
BTree btree = new BTree(db, Database.DATA_AREA);
|
||||
for (int i = 0; i < names.length; ++i) {
|
||||
String name = names[i];
|
||||
int record = db.malloc((name.length() + 1) * Database.CHAR_SIZE + Database.INT_SIZE);
|
||||
db.putInt(record, i);
|
||||
db.putString(record + Database.INT_SIZE, name);
|
||||
int record = db.malloc(8);
|
||||
db.putInt(record + 0, i);
|
||||
IString string = db.newString(name);
|
||||
db.putInt(record + 4, string.getRecord());
|
||||
btree.insert(record, new IBTreeComparator() {
|
||||
public int compare(int record1, int record2) throws CoreException {
|
||||
return db.stringCompare(record1 + 4, record2 + 4);
|
||||
IString string1 = db.getString(db.getInt(record1 + 4));
|
||||
IString string2 = db.getString(db.getInt(record2 + 4));
|
||||
return string1.compare(string2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
for (int i = 0; i < names.length; ++i) {
|
||||
String name = names[i];
|
||||
int record = new FindVisitor(db, name).findIn(btree);
|
||||
FindVisitor finder = new FindVisitor(db, name);
|
||||
btree.accept(finder);
|
||||
int record = finder.getRecord();
|
||||
assertTrue(record != 0);
|
||||
assertEquals(i, db.getInt(record));
|
||||
DBString rname = db.getString(record + Database.INT_SIZE);
|
||||
assertEquals(name, rname);
|
||||
IString rname = db.getString(db.getInt(record + 4));
|
||||
assertTrue(rname.equals(name));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,8 +26,10 @@ import org.eclipse.cdt.core.dom.IPDOMResolver;
|
|||
import org.eclipse.cdt.core.dom.IPDOMVisitor;
|
||||
import org.eclipse.cdt.core.dom.IPDOMWriter;
|
||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.model.ICProject;
|
||||
|
@ -65,10 +67,11 @@ public class PDOM extends PlatformObject
|
|||
private final IPath dbPath;
|
||||
private Database db;
|
||||
|
||||
public static final int VERSION = 2;
|
||||
public static final int VERSION = 3;
|
||||
// 0 - the beginning of it all
|
||||
// 1 - first change to kick off upgrades
|
||||
// 2 - added file inclusions
|
||||
// 3 - added macros and change string implementation
|
||||
|
||||
public static final int LINKAGES = Database.DATA_AREA;
|
||||
public static final int FILE_INDEX = Database.DATA_AREA + 4;
|
||||
|
@ -213,13 +216,32 @@ public class PDOM extends PlatformObject
|
|||
for (int i = 0; i < includes.length; ++i) {
|
||||
IASTPreprocessorIncludeStatement include = includes[i];
|
||||
|
||||
String sourcePath = include.getFileLocation().getFileName();
|
||||
IASTFileLocation sourceLoc = include.getFileLocation();
|
||||
String sourcePath
|
||||
= sourceLoc != null
|
||||
? sourceLoc.getFileName()
|
||||
: ast.getFilePath(); // command-line includes
|
||||
|
||||
PDOMFile sourceFile = addFile(sourcePath);
|
||||
String destPath = include.getPath();
|
||||
PDOMFile destFile = addFile(destPath);
|
||||
sourceFile.addIncludeTo(destFile);
|
||||
}
|
||||
|
||||
// Add in the macros
|
||||
IASTPreprocessorMacroDefinition[] macros = ast.getMacroDefinitions();
|
||||
for (int i = 0; i < macros.length; ++i) {
|
||||
IASTPreprocessorMacroDefinition macro = macros[i];
|
||||
|
||||
IASTFileLocation sourceLoc = macro.getFileLocation();
|
||||
if (sourceLoc == null)
|
||||
continue; // skip built-ins and command line macros
|
||||
|
||||
PDOMFile sourceFile = getFile(sourceLoc.getFileName());
|
||||
if (sourceFile != null) // not sure why this would be null
|
||||
sourceFile.addMacro(macro);
|
||||
}
|
||||
|
||||
// Add in the names
|
||||
ast.accept(new ASTVisitor() {
|
||||
{
|
||||
|
|
|
@ -13,7 +13,9 @@ package org.eclipse.cdt.internal.core.pdom;
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.dom.ICodeReaderFactory;
|
||||
|
@ -22,7 +24,10 @@ import org.eclipse.cdt.core.model.IWorkingCopy;
|
|||
import org.eclipse.cdt.core.parser.CodeReader;
|
||||
import org.eclipse.cdt.core.parser.ICodeReaderCache;
|
||||
import org.eclipse.cdt.core.parser.ParserUtil;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.IString;
|
||||
import org.eclipse.cdt.internal.core.pdom.dom.PDOMFile;
|
||||
import org.eclipse.cdt.internal.core.pdom.dom.PDOMInclude;
|
||||
import org.eclipse.cdt.internal.core.pdom.dom.PDOMMacro;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
|
@ -59,10 +64,28 @@ public class PDOMCodeReaderFactory implements ICodeReaderFactory {
|
|||
return new CodeReader(tu.getResource().getLocation().toOSString(), tu.getContents());
|
||||
}
|
||||
|
||||
private static class SkippedInclusion extends CodeReader {
|
||||
private static char[] buffer = "".toCharArray();
|
||||
public SkippedInclusion(String filename) {
|
||||
super(filename, buffer);
|
||||
private void fillMacros(PDOMFile file, StringBuffer buffer, Set visited) throws CoreException {
|
||||
IString filename = file.getFileName();
|
||||
if (visited.contains(filename))
|
||||
return;
|
||||
visited.add(filename);
|
||||
|
||||
// Follow the includes
|
||||
PDOMInclude include = file.getFirstInclude();
|
||||
while (include != null) {
|
||||
fillMacros(include.getIncludes(), buffer, visited);
|
||||
include = include.getNextInIncludes();
|
||||
}
|
||||
|
||||
// Add in my macros now
|
||||
PDOMMacro macro = file.getFirstMacro();
|
||||
while (macro != null) {
|
||||
buffer.append("#define "); //$NON-NLS-1$
|
||||
buffer.append(macro.getName().getChars());
|
||||
buffer.append(' ');
|
||||
buffer.append(macro.getExpansion().getChars());
|
||||
buffer.append('\n');
|
||||
macro = macro.getNextMacro();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,9 +98,16 @@ public class PDOMCodeReaderFactory implements ICodeReaderFactory {
|
|||
// ignore and use the path we were passed in
|
||||
}
|
||||
PDOMFile file = pdom.getFile(path);
|
||||
if (file != null && file.getFirstName() != null)
|
||||
// Already got things from here
|
||||
return new SkippedInclusion(path);
|
||||
if (file != null) {
|
||||
// Already got things from here, pass in a magic
|
||||
// buffer with the macros in it
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
fillMacros(file, buffer, new HashSet());
|
||||
int length = buffer.length();
|
||||
char[] chars = new char[length];
|
||||
buffer.getChars(0, length, chars, 0);
|
||||
return new CodeReader(path, chars);
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
CCorePlugin.log(new CoreException(new Status(IStatus.ERROR,
|
||||
CCorePlugin.PLUGIN_ID, 0, "PDOM Exception", e)));
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
|
||||
package org.eclipse.cdt.internal.core.pdom;
|
||||
|
||||
import org.eclipse.cdt.internal.core.pdom.db.DBString;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.Database;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.IString;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
/**
|
||||
|
@ -28,6 +28,8 @@ public class PDOMLanguage {
|
|||
private static final int ID = 4; // char
|
||||
private static final int NAME = 6; // string
|
||||
|
||||
private static int RECORD_SIZE = 10;
|
||||
|
||||
public PDOMLanguage(PDOM pdom, int record) {
|
||||
this.pdom = pdom;
|
||||
this.record = record;
|
||||
|
@ -36,10 +38,10 @@ public class PDOMLanguage {
|
|||
public PDOMLanguage(PDOM pdom, String name, int id, int next) throws CoreException {
|
||||
this.pdom = pdom;
|
||||
Database db = pdom.getDB();
|
||||
record = db.malloc(6 + (name.length() + 1) * 2);
|
||||
record = db.malloc(RECORD_SIZE);
|
||||
db.putInt(record + NEXT, next);
|
||||
db.putChar(record + ID, (char)id);
|
||||
db.putString(record + NAME, name);
|
||||
db.putInt(record + NAME, db.newString(name).getRecord());
|
||||
}
|
||||
|
||||
public int getRecord() {
|
||||
|
@ -50,8 +52,10 @@ public class PDOMLanguage {
|
|||
return pdom.getDB().getChar(record + ID);
|
||||
}
|
||||
|
||||
public DBString getName() throws CoreException {
|
||||
return pdom.getDB().getString(record + NAME);
|
||||
public IString getName() throws CoreException {
|
||||
Database db = pdom.getDB();
|
||||
int rec = db.getInt(record + NAME);
|
||||
return db.getString(rec);
|
||||
}
|
||||
|
||||
public PDOMLanguage getNext() throws CoreException {
|
||||
|
@ -60,6 +64,7 @@ public class PDOMLanguage {
|
|||
}
|
||||
|
||||
public boolean equals(String id) throws CoreException {
|
||||
return pdom.getDB().stringCompare(record + NAME, id) == 0;
|
||||
return getName().equals(id);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -64,32 +64,6 @@ public class Chunk {
|
|||
return buffer.getChar(offset % Database.CHUNK_SIZE);
|
||||
}
|
||||
|
||||
// Strings have a 16 bit length followed by the chars
|
||||
|
||||
public void putChars(int offset, char[] value) {
|
||||
buffer.position(offset % Database.CHUNK_SIZE);
|
||||
buffer.putChar((char)value.length);
|
||||
for (int i = 0; i < value.length; ++i)
|
||||
buffer.putChar(value[i]);
|
||||
}
|
||||
|
||||
public char[] getChars(int offset) {
|
||||
buffer.position(offset % Database.CHUNK_SIZE);
|
||||
int n = buffer.getChar();
|
||||
char[] chars = new char[n];
|
||||
for (int i = 0; i < n; ++i)
|
||||
chars[i] = buffer.getChar();
|
||||
return chars;
|
||||
}
|
||||
|
||||
public void putString(int offset, String value) {
|
||||
buffer.position(offset % Database.CHUNK_SIZE);
|
||||
int n = value.length();
|
||||
buffer.putChar((char)n);
|
||||
for (int i = 0; i < n; ++i)
|
||||
buffer.putChar(value.charAt(i));
|
||||
}
|
||||
|
||||
Chunk getNextChunk() {
|
||||
return nextChunk;
|
||||
}
|
||||
|
|
|
@ -1,90 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006 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 - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.internal.core.pdom.db;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
/**
|
||||
* A String class for strings stored in the database. The idea
|
||||
* is to minimize how often we extract the string.
|
||||
*
|
||||
* @author Doug Schaefer
|
||||
*/
|
||||
public class DBString {
|
||||
|
||||
private final Database db;
|
||||
private final int offset;
|
||||
|
||||
DBString(Database db, int offset) {
|
||||
this.db = db;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this)
|
||||
return true;
|
||||
|
||||
try {
|
||||
if (obj instanceof DBString) {
|
||||
DBString string = (DBString)obj;
|
||||
if (db == string.db && offset == string.offset)
|
||||
return true;
|
||||
|
||||
Chunk chunk1 = db.getChunk(offset);
|
||||
Chunk chunk2 = string.db.getChunk(string.offset);
|
||||
|
||||
int n1 = chunk1.getChar(offset);
|
||||
int n2 = chunk2.getChar(string.offset);
|
||||
if (n1 != n2)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < n1; ++i) {
|
||||
int coffset1 = offset + 2 + i * 2;
|
||||
int coffset2 = string.offset + 2 + i * 2;
|
||||
if (chunk1.getChar(coffset1) != chunk2.getChar(coffset2))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} else if (obj instanceof String) {
|
||||
String string = (String)obj;
|
||||
Chunk chunk = db.getChunk(offset);
|
||||
|
||||
// Make sure size is the same
|
||||
int n = chunk.getChar(offset);
|
||||
if (n != string.length())
|
||||
return false;
|
||||
|
||||
// Check each character
|
||||
for (int i = 0; i < n; ++i) {
|
||||
int coffset = offset + 2 + i * 2;
|
||||
if (chunk.getChar(coffset) != string.charAt(i))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
CCorePlugin.log(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
// Custom hash code function to allow DBStrings in hashmaps.
|
||||
return offset;
|
||||
}
|
||||
|
||||
public String getString() throws CoreException {
|
||||
return new String(db.getChars(offset));
|
||||
}
|
||||
}
|
|
@ -42,6 +42,8 @@ public class Database {
|
|||
public static final int NEXT_OFFSET = INT_SIZE * 2;
|
||||
public static final int DATA_AREA = CHUNK_SIZE / MIN_SIZE * INT_SIZE + INT_SIZE;
|
||||
|
||||
public static final int MAX_SIZE = CHUNK_SIZE - 4; // Room for overhead
|
||||
|
||||
public Database(String filename) throws CoreException {
|
||||
try {
|
||||
file = new RandomAccessFile(filename, "rw"); //$NON-NLS-1$
|
||||
|
@ -136,6 +138,11 @@ public class Database {
|
|||
* @return
|
||||
*/
|
||||
public int malloc(int size) throws CoreException {
|
||||
if (size > MAX_SIZE)
|
||||
// Too Big
|
||||
throw new CoreException(new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, 0,
|
||||
CCorePlugin.getResourceString("pdom.requestTooLarge"), new IllegalArgumentException())); //$NON-NLS-1$
|
||||
|
||||
// Which block size
|
||||
int freeblock = 0;
|
||||
int blocksize;
|
||||
|
@ -270,127 +277,30 @@ public class Database {
|
|||
return chunk.getChar(offset);
|
||||
}
|
||||
|
||||
public void putChars(int offset, char[] value) throws CoreException {
|
||||
Chunk chunk = getChunk(offset);
|
||||
chunk.putChars(offset, value);
|
||||
}
|
||||
|
||||
public int putChars(char[] value) throws CoreException {
|
||||
int record = malloc((value.length + 1) * 2);
|
||||
putChars(record, value);
|
||||
return record;
|
||||
}
|
||||
|
||||
public char[] getChars(int offset) throws CoreException {
|
||||
Chunk chunk = getChunk(offset);
|
||||
return chunk.getChars(offset);
|
||||
public IString newString(String string) throws CoreException {
|
||||
if (string.length() > ShortString.MAX_LENGTH)
|
||||
return new LongString(this, string);
|
||||
else
|
||||
return new ShortString(this, string);
|
||||
}
|
||||
|
||||
public void putString(int offset, String value) throws CoreException {
|
||||
Chunk chunk = getChunk(offset);
|
||||
chunk.putString(offset, value);
|
||||
public IString newString(char[] chars) throws CoreException {
|
||||
if (chars.length > ShortString.MAX_LENGTH)
|
||||
return new LongString(this, chars);
|
||||
else
|
||||
return new ShortString(this, chars);
|
||||
}
|
||||
|
||||
public int putString(String value) throws CoreException {
|
||||
int record = malloc((value.length() + 1) * 2);
|
||||
putString(record, value);
|
||||
return record;
|
||||
}
|
||||
|
||||
public DBString getString(int offset) throws CoreException {
|
||||
return new DBString(this, offset);
|
||||
|
||||
public IString getString(int offset) throws CoreException {
|
||||
int length = getInt(offset);
|
||||
if (length > ShortString.MAX_LENGTH)
|
||||
return new LongString(this, offset);
|
||||
else
|
||||
return new ShortString(this, offset);
|
||||
}
|
||||
|
||||
public int getNumChunks() {
|
||||
return toc.length;
|
||||
}
|
||||
|
||||
public int stringCompare(int record1, int record2) throws CoreException {
|
||||
Chunk chunk1 = getChunk(record1);
|
||||
Chunk chunk2 = getChunk(record2);
|
||||
|
||||
int i1 = record1 + 2;
|
||||
int i2 = record2 + 2;
|
||||
int n1 = i1 + chunk1.getChar(record1) * 2;
|
||||
int n2 = i2 + chunk2.getChar(record2) * 2;
|
||||
|
||||
while (i1 < n1 && i2 < n2) {
|
||||
char c1 = chunk1.getChar(i1);
|
||||
char c2 = chunk2.getChar(i2);
|
||||
|
||||
if (c1 < c2)
|
||||
return -1;
|
||||
if (c1 > c2)
|
||||
return 1;
|
||||
|
||||
i1 += 2;
|
||||
i2 += 2;
|
||||
}
|
||||
|
||||
if (i1 == n1 && i2 != n2)
|
||||
return -1;
|
||||
else if (i2 == n2 && i1 != n1)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int stringCompare(int record1, char[] record2) throws CoreException {
|
||||
Chunk chunk1 = getChunk(record1);
|
||||
|
||||
int i1 = record1 + 2;
|
||||
int i2 = 0;
|
||||
int n1 = i1 + chunk1.getChar(record1) * 2;
|
||||
int n2 = record2.length;
|
||||
|
||||
while (i1 < n1 && i2 < n2) {
|
||||
char c1 = chunk1.getChar(i1);
|
||||
char c2 = record2[i2];
|
||||
|
||||
if (c1 < c2)
|
||||
return -1;
|
||||
if (c1 > c2)
|
||||
return 1;
|
||||
|
||||
i1 += 2;
|
||||
++i2;
|
||||
}
|
||||
|
||||
if (i1 == n1 && i2 != n2)
|
||||
return -1;
|
||||
else if (i2 == n2 && i1 != n1)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int stringCompare(int record1, String record2) throws CoreException {
|
||||
Chunk chunk1 = getChunk(record1);
|
||||
|
||||
int i1 = record1 + 2;
|
||||
int i2 = 0;
|
||||
int n1 = i1 + chunk1.getChar(record1) * 2;
|
||||
int n2 = record2.length();
|
||||
|
||||
while (i1 < n1 && i2 < n2) {
|
||||
char c1 = chunk1.getChar(i1);
|
||||
char c2 = record2.charAt(i2);
|
||||
|
||||
if (c1 < c2)
|
||||
return -1;
|
||||
if (c1 > c2)
|
||||
return 1;
|
||||
|
||||
i1 += 2;
|
||||
++i2;
|
||||
}
|
||||
|
||||
if (i1 == n1 && i2 != n2)
|
||||
return -1;
|
||||
else if (i2 == n2 && i1 != n1)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006 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 - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.internal.core.pdom.db;
|
||||
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
/**
|
||||
* Interface for strings stored in the database. There is more than one string
|
||||
* format. This interface hides that fact.
|
||||
*
|
||||
* @author Doug Schaefer
|
||||
*/
|
||||
public interface IString {
|
||||
|
||||
public int getRecord();
|
||||
|
||||
// strcmp equivalents
|
||||
public int compare(IString string) throws CoreException;
|
||||
public int compare(String string) throws CoreException;
|
||||
public int compare(char[] chars) throws CoreException;
|
||||
|
||||
// use sparingly, these can be expensive
|
||||
public char[] getChars() throws CoreException;
|
||||
public String getString() throws CoreException;
|
||||
|
||||
}
|
|
@ -0,0 +1,195 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006 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 - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.internal.core.pdom.db;
|
||||
|
||||
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNotImplementedError;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
/**
|
||||
* This is for strings that take up more than on chunk.
|
||||
* The string will need to be broken up into sections and then
|
||||
* reassembled when necessary.
|
||||
*
|
||||
* @author Doug Schaefer
|
||||
*/
|
||||
public class LongString implements IString {
|
||||
|
||||
private final Database db;
|
||||
private final int record1;
|
||||
|
||||
// Additional fields of first record
|
||||
private static final int LENGTH = 0; // must be first to match ShortString
|
||||
private static final int NEXT1 = 4;
|
||||
private static final int CHARS1 = 8;
|
||||
|
||||
private static final int NUM_CHARS1 = (Database.MAX_SIZE - CHARS1) / 2;
|
||||
|
||||
// Additional fields of subsequent records
|
||||
private static final int NEXTN = 0;
|
||||
private static final int CHARSN = 4;
|
||||
|
||||
private static final int NUM_CHARSN = (Database.MAX_SIZE - CHARSN) / 2;
|
||||
|
||||
public LongString(Database db, int record1) {
|
||||
this.db = db;
|
||||
this.record1 = record1;
|
||||
}
|
||||
|
||||
private interface IWriter {
|
||||
public void writeChars(int start, int length, int p) throws CoreException;
|
||||
}
|
||||
|
||||
private int createString(int length, IWriter writer) throws CoreException {
|
||||
// write the first record
|
||||
int firstRecord = db.malloc(Database.MAX_SIZE);
|
||||
int start = 0;
|
||||
db.putInt(firstRecord, length);
|
||||
writer.writeChars(start, NUM_CHARS1, firstRecord + CHARS1);
|
||||
|
||||
// write the subsequent records
|
||||
int lastNext = firstRecord + NEXT1;
|
||||
start += NUM_CHARS1;
|
||||
while (length - start > NUM_CHARSN) {
|
||||
int nextRecord = db.malloc(Database.MAX_SIZE);
|
||||
db.putInt(lastNext, nextRecord);
|
||||
writer.writeChars(start, NUM_CHARSN, nextRecord + CHARSN);
|
||||
start += NUM_CHARSN;
|
||||
lastNext = nextRecord + NEXTN;
|
||||
}
|
||||
|
||||
// Write the final record
|
||||
length -= start;
|
||||
int finalRecord = db.malloc(CHARSN + (length) * 2);
|
||||
db.putInt(lastNext, finalRecord);
|
||||
writer.writeChars(start, length, finalRecord + CHARSN);
|
||||
|
||||
return firstRecord;
|
||||
}
|
||||
|
||||
public LongString(Database db, final String string) throws CoreException {
|
||||
this.db = db;
|
||||
this.record1 = createString(string.length(), new IWriter() {
|
||||
public void writeChars(int start, int length, int p) throws CoreException {
|
||||
for (int i = start; i < start + length; ++i) {
|
||||
LongString.this.db.putChar(p, string.charAt(i));
|
||||
p += 2;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public LongString(Database db, final char[] chars) throws CoreException {
|
||||
this.db = db;
|
||||
this.record1 = createString(chars.length, new IWriter() {
|
||||
public void writeChars(int start, int length, int p) throws CoreException {
|
||||
for (int i = start; i < start + length; ++i) {
|
||||
LongString.this.db.putChar(p, chars[i]);
|
||||
p += 2;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public int getRecord() {
|
||||
return record1;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return record1;
|
||||
}
|
||||
|
||||
public int compare(IString string) throws CoreException {
|
||||
if (string instanceof LongString)
|
||||
return compare((LongString)string);
|
||||
else if (string instanceof ShortString)
|
||||
return compare((ShortString)string);
|
||||
else
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
public int compare(LongString string) throws CoreException {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public int compare(ShortString string) throws CoreException {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public int compare(String string) throws CoreException {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public int compare(char[] chars) throws CoreException {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
private interface IReader {
|
||||
public void appendChar(char c);
|
||||
}
|
||||
|
||||
private void readChars(int length, IReader reader) throws CoreException {
|
||||
// First record
|
||||
int p = record1 + CHARS1;
|
||||
for (int i = 0; i < NUM_CHARS1; ++i) {
|
||||
reader.appendChar(db.getChar(p));
|
||||
p += 2;
|
||||
}
|
||||
length -= NUM_CHARS1;
|
||||
int nextRecord = db.getInt(record1 + NEXT1);
|
||||
|
||||
// Middle records
|
||||
while (length > NUM_CHARSN) {
|
||||
p = nextRecord + CHARSN;
|
||||
for (int i = 0; i < NUM_CHARSN; ++i) {
|
||||
reader.appendChar(db.getChar(p));
|
||||
p += 2;
|
||||
}
|
||||
length -= NUM_CHARSN;
|
||||
nextRecord = db.getInt(nextRecord + NEXTN);
|
||||
}
|
||||
|
||||
// Last record
|
||||
p = nextRecord + CHARSN;
|
||||
for (int i = 0; i < length; ++i) {
|
||||
reader.appendChar(db.getChar(p));
|
||||
p += 2;
|
||||
}
|
||||
}
|
||||
|
||||
public char[] getChars() throws CoreException {
|
||||
int length = db.getInt(record1 + LENGTH);
|
||||
final char[] chars = new char[length];
|
||||
readChars(length, new IReader() {
|
||||
int cp = 0;
|
||||
public void appendChar(char c) {
|
||||
chars[cp++] = c;
|
||||
}
|
||||
});
|
||||
return chars;
|
||||
}
|
||||
|
||||
public String getString() throws CoreException {
|
||||
int length = db.getInt(record1 + LENGTH);
|
||||
final StringBuffer buffer = new StringBuffer(length);
|
||||
readChars(length, new IReader() {
|
||||
public void appendChar(char c) {
|
||||
buffer.append(c);
|
||||
}
|
||||
});
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,255 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006 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 - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.internal.core.pdom.db;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
/**
|
||||
* This is for strings that fit inside a single chunk.
|
||||
*
|
||||
* @author Doug Schaefer
|
||||
*/
|
||||
public class ShortString implements IString {
|
||||
|
||||
private final Database db;
|
||||
private final int record;
|
||||
|
||||
private static final int LENGTH = 0;
|
||||
private static final int CHARS = 4;
|
||||
|
||||
public static final int MAX_LENGTH = (Database.MAX_SIZE - CHARS) / 2;
|
||||
|
||||
public ShortString(Database db, int offset) {
|
||||
this.db = db;
|
||||
this.record = offset;
|
||||
}
|
||||
|
||||
public ShortString(Database db, char[] chars) throws CoreException {
|
||||
this.db = db;
|
||||
this.record = db.malloc(CHARS + chars.length * 2);
|
||||
|
||||
Chunk chunk = db.getChunk(record);
|
||||
chunk.putInt(record + LENGTH, (char)chars.length);
|
||||
int n = chars.length;
|
||||
int p = record + CHARS;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
chunk.putChar(p, chars[i]);
|
||||
p += 2;
|
||||
}
|
||||
}
|
||||
|
||||
public ShortString(Database db, String string) throws CoreException {
|
||||
this.db = db;
|
||||
this.record = db.malloc(CHARS + string.length() * 2);
|
||||
|
||||
Chunk chunk = db.getChunk(record);
|
||||
chunk.putInt(record + LENGTH, (char)string.length());
|
||||
int n = string.length();
|
||||
int p = record + CHARS;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
chunk.putChar(p, string.charAt(i));
|
||||
p += 2;
|
||||
}
|
||||
}
|
||||
|
||||
public int getRecord() {
|
||||
return record;
|
||||
}
|
||||
|
||||
public char[] getChars() throws CoreException {
|
||||
Chunk chunk = db.getChunk(record);
|
||||
int length = chunk.getInt(record + LENGTH);
|
||||
char[] chars = new char[length];
|
||||
int p = record + CHARS;
|
||||
for (int i = 0; i < length; ++i) {
|
||||
chars[i] = chunk.getChar(p);
|
||||
p += 2;
|
||||
}
|
||||
return chars;
|
||||
}
|
||||
|
||||
public String getString() throws CoreException {
|
||||
return new String(getChars());
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this)
|
||||
return true;
|
||||
|
||||
try {
|
||||
if (obj instanceof ShortString) {
|
||||
ShortString string = (ShortString)obj;
|
||||
if (db == string.db && record == string.record)
|
||||
return true;
|
||||
|
||||
Chunk chunk1 = db.getChunk(record);
|
||||
Chunk chunk2 = string.db.getChunk(string.record);
|
||||
|
||||
int n1 = chunk1.getInt(record);
|
||||
int n2 = chunk2.getInt(string.record);
|
||||
if (n1 != n2)
|
||||
return false;
|
||||
|
||||
int p1 = record + CHARS;
|
||||
int p2 = string.record + CHARS;
|
||||
for (int i = 0; i < n1; ++i) {
|
||||
if (chunk1.getChar(p1) != chunk2.getChar(p2))
|
||||
return false;
|
||||
p1 += 2;
|
||||
p2 += 2;
|
||||
}
|
||||
return true;
|
||||
} else if (obj instanceof char[]) {
|
||||
char[] chars = (char[])obj;
|
||||
Chunk chunk = db.getChunk(record);
|
||||
|
||||
// Make sure size is the same
|
||||
int n = chunk.getInt(record);
|
||||
if (n != chars.length)
|
||||
return false;
|
||||
|
||||
// Check each character
|
||||
int p = record + CHARS;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
if (chunk.getChar(p) != chars[i])
|
||||
return false;
|
||||
p += 2;
|
||||
}
|
||||
return true;
|
||||
} else if (obj instanceof String) {
|
||||
String string = (String)obj;
|
||||
Chunk chunk = db.getChunk(record);
|
||||
|
||||
// Make sure size is the same
|
||||
int n = chunk.getInt(record);
|
||||
if (n != string.length())
|
||||
return false;
|
||||
|
||||
// Check each character
|
||||
int p = record + CHARS;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
if (chunk.getChar(p) != string.charAt(i))
|
||||
return false;
|
||||
p += 2;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
CCorePlugin.log(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
// Custom hash code function to allow DBStrings in hashmaps.
|
||||
return record;
|
||||
}
|
||||
|
||||
public int compare(IString string) throws CoreException {
|
||||
if (string instanceof ShortString)
|
||||
return compare((ShortString)string);
|
||||
else if (string instanceof LongString)
|
||||
return - ((LongString)string).compare(this);
|
||||
else
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
public int compare(ShortString other) throws CoreException {
|
||||
Chunk chunk1 = db.getChunk(record);
|
||||
Chunk chunk2 = other.db.getChunk(other.record);
|
||||
|
||||
int i1 = record + CHARS;
|
||||
int i2 = other.record + CHARS;
|
||||
int n1 = i1 + chunk1.getInt(record + LENGTH) * 2;
|
||||
int n2 = i2 + chunk2.getInt(other.record + LENGTH) * 2;
|
||||
|
||||
while (i1 < n1 && i2 < n2) {
|
||||
char c1 = chunk1.getChar(i1);
|
||||
char c2 = chunk2.getChar(i2);
|
||||
|
||||
if (c1 < c2)
|
||||
return -1;
|
||||
if (c1 > c2)
|
||||
return 1;
|
||||
|
||||
i1 += 2;
|
||||
i2 += 2;
|
||||
}
|
||||
|
||||
if (i1 == n1 && i2 != n2)
|
||||
return -1;
|
||||
else if (i2 == n2 && i1 != n1)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int compare(char[] other) throws CoreException {
|
||||
Chunk chunk = db.getChunk(record);
|
||||
|
||||
int i1 = record + CHARS;
|
||||
int i2 = 0;
|
||||
int n1 = i1 + chunk.getInt(record + LENGTH) * 2;
|
||||
int n2 = other.length;
|
||||
|
||||
while (i1 < n1 && i2 < n2) {
|
||||
char c1 = chunk.getChar(i1);
|
||||
char c2 = other[i2];
|
||||
|
||||
if (c1 < c2)
|
||||
return -1;
|
||||
if (c1 > c2)
|
||||
return 1;
|
||||
|
||||
i1 += 2;
|
||||
++i2;
|
||||
}
|
||||
|
||||
if (i1 == n1 && i2 != n2)
|
||||
return -1;
|
||||
else if (i2 == n2 && i1 != n1)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int compare(String other) throws CoreException {
|
||||
Chunk chunk = db.getChunk(record);
|
||||
|
||||
int i1 = record + CHARS;
|
||||
int i2 = 0;
|
||||
int n1 = i1 + chunk.getInt(record + LENGTH) * 2;
|
||||
int n2 = other.length();
|
||||
|
||||
while (i1 < n1 && i2 < n2) {
|
||||
char c1 = chunk.getChar(i1);
|
||||
char c2 = other.charAt(i2);
|
||||
|
||||
if (c1 < c2)
|
||||
return -1;
|
||||
if (c1 > c2)
|
||||
return 1;
|
||||
|
||||
i1 += 2;
|
||||
++i2;
|
||||
}
|
||||
|
||||
if (i1 == n1 && i2 != n2)
|
||||
return -1;
|
||||
else if (i2 == n2 && i1 != n1)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
|
@ -160,10 +160,6 @@ public abstract class PDOMBinding extends PDOMNode implements IBinding {
|
|||
return new char[0];
|
||||
}
|
||||
|
||||
public boolean hasName(char[] name) throws CoreException {
|
||||
return pdom.getDB().stringCompare(getNameRecord(), name) == 0;
|
||||
}
|
||||
|
||||
public IScope getScope() throws DOMException {
|
||||
// TODO implement this
|
||||
return null;
|
||||
|
|
|
@ -15,11 +15,12 @@ import java.util.HashMap;
|
|||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
|
||||
import org.eclipse.cdt.internal.core.pdom.PDOM;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.DBString;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.Database;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.IBTreeComparator;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.IString;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
/**
|
||||
|
@ -36,9 +37,10 @@ public class PDOMFile {
|
|||
private static final int FIRST_NAME = 0;
|
||||
private static final int FIRST_INCLUDE = 4;
|
||||
private static final int FIRST_INCLUDED_BY = 8;
|
||||
private static final int FILE_NAME = 12;
|
||||
private static final int FIRST_MACRO = 12;
|
||||
private static final int FILE_NAME = 16;
|
||||
|
||||
private static final int RECORD_SIZE = 12; // + length of string
|
||||
private static final int RECORD_SIZE = 20;
|
||||
|
||||
public static class Comparator implements IBTreeComparator {
|
||||
private Database db;
|
||||
|
@ -48,7 +50,9 @@ public class PDOMFile {
|
|||
}
|
||||
|
||||
public int compare(int record1, int record2) throws CoreException {
|
||||
return db.stringCompare(record1 + FILE_NAME, record2 + FILE_NAME);
|
||||
IString name1 = db.getString(db.getInt(record1 + FILE_NAME));
|
||||
IString name2 = db.getString(db.getInt(record2 + FILE_NAME));
|
||||
return name1.compare(name2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,7 +67,8 @@ public class PDOMFile {
|
|||
}
|
||||
|
||||
public int compare(int record) throws CoreException {
|
||||
return db.stringCompare(record + FILE_NAME, key);
|
||||
IString name = db.getString(db.getInt(record + FILE_NAME));
|
||||
return name.compare(key);
|
||||
}
|
||||
|
||||
public boolean visit(int record) throws CoreException {
|
||||
|
@ -84,8 +89,8 @@ public class PDOMFile {
|
|||
public PDOMFile(PDOM pdom, String filename) throws CoreException {
|
||||
this.pdom = pdom;
|
||||
Database db = pdom.getDB();
|
||||
record = db.malloc(RECORD_SIZE + (filename.length() + 1) * 2);
|
||||
db.putString(record + FILE_NAME, filename);
|
||||
record = db.malloc(RECORD_SIZE);
|
||||
db.putInt(record + FILE_NAME, db.newString(filename).getRecord());
|
||||
setFirstName(null);
|
||||
setFirstInclude(null);
|
||||
setFirstIncludedBy(null);
|
||||
|
@ -95,8 +100,9 @@ public class PDOMFile {
|
|||
return record;
|
||||
}
|
||||
|
||||
public DBString getFileName() throws CoreException {
|
||||
return pdom.getDB().getString(record + FILE_NAME);
|
||||
public IString getFileName() throws CoreException {
|
||||
Database db = pdom.getDB();
|
||||
return db.getString(db.getInt(record + FILE_NAME));
|
||||
}
|
||||
|
||||
public PDOMName getFirstName() throws CoreException {
|
||||
|
@ -129,6 +135,34 @@ public class PDOMFile {
|
|||
pdom.getDB().putInt(record + FIRST_INCLUDED_BY, rec);
|
||||
}
|
||||
|
||||
public PDOMMacro getFirstMacro() throws CoreException {
|
||||
int rec = pdom.getDB().getInt(record + FIRST_MACRO);
|
||||
return rec != 0 ? new PDOMMacro(pdom, rec) : null;
|
||||
}
|
||||
|
||||
public void setFirstMacro(PDOMMacro macro) throws CoreException {
|
||||
int rec = macro != null ? macro.getRecord() : 0;
|
||||
pdom.getDB().putInt(record + FIRST_MACRO, rec);
|
||||
}
|
||||
|
||||
public void addMacro(IASTPreprocessorMacroDefinition macro) throws CoreException {
|
||||
PDOMMacro firstMacro = getFirstMacro();
|
||||
|
||||
// Make sure we don't already have one
|
||||
char[] name = macro.getName().toCharArray();
|
||||
PDOMMacro pdomMacro = firstMacro;
|
||||
while (pdomMacro != null) {
|
||||
if (pdomMacro.getName().equals(name))
|
||||
return;
|
||||
pdomMacro = pdomMacro.getNextMacro();
|
||||
}
|
||||
|
||||
// Nope, add it in
|
||||
pdomMacro = new PDOMMacro(pdom, macro);
|
||||
pdomMacro.setNextMacro(getFirstMacro());
|
||||
setFirstMacro(pdomMacro);
|
||||
}
|
||||
|
||||
public void clear() throws CoreException {
|
||||
// Remove the includes
|
||||
PDOMInclude include = getFirstInclude();
|
||||
|
@ -139,6 +173,15 @@ public class PDOMFile {
|
|||
}
|
||||
setFirstInclude(include);
|
||||
|
||||
// Delete all the macros in this file
|
||||
PDOMMacro macro = getFirstMacro();
|
||||
while (macro != null) {
|
||||
PDOMMacro nextMacro = macro.getNextMacro();
|
||||
macro.delete();
|
||||
macro = nextMacro;
|
||||
}
|
||||
setFirstMacro(null);
|
||||
|
||||
// Delete all the names in this file
|
||||
PDOMName name = getFirstName();
|
||||
while (name != null) {
|
||||
|
@ -146,7 +189,6 @@ public class PDOMFile {
|
|||
name.delete();
|
||||
name = nextName;
|
||||
}
|
||||
|
||||
setFirstName(null);
|
||||
}
|
||||
|
||||
|
@ -179,16 +221,16 @@ public class PDOMFile {
|
|||
LinkedList todo = new LinkedList();
|
||||
|
||||
// Add me in to make sure we don't get caught in a circular include
|
||||
DBString myFileName = getFileName();
|
||||
IString myFileName = getFileName();
|
||||
files.put(myFileName, this);
|
||||
|
||||
todo.addLast(this);
|
||||
while (todo.size() > 0) {
|
||||
PDOMFile file = (PDOMFile)todo.removeFirst();
|
||||
PDOMInclude includedBy = getFirstIncludedBy();
|
||||
PDOMInclude includedBy = file.getFirstIncludedBy();
|
||||
while (includedBy != null) {
|
||||
PDOMFile incFile = includedBy.getIncludedBy();
|
||||
DBString incFileName = incFile.getFileName();
|
||||
IString incFileName = incFile.getFileName();
|
||||
if (files.get(incFileName) == null) {
|
||||
files.put(incFileName, incFile);
|
||||
todo.addLast(incFile);
|
||||
|
|
|
@ -21,9 +21,9 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
|
|||
import org.eclipse.cdt.core.model.ILanguage;
|
||||
import org.eclipse.cdt.internal.core.pdom.PDOM;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.BTree;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.DBString;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.Database;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.IString;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
/**
|
||||
|
@ -78,8 +78,7 @@ public abstract class PDOMLinkage extends PDOMNode {
|
|||
Database db = pdom.getDB();
|
||||
|
||||
// id
|
||||
int idrec = db.putString(languageId);
|
||||
db.putInt(record + ID_OFFSET, idrec);
|
||||
db.putInt(record + ID_OFFSET, db.newString(languageId).getRecord());
|
||||
|
||||
pdom.insertLinkage(this);
|
||||
}
|
||||
|
@ -88,7 +87,7 @@ public abstract class PDOMLinkage extends PDOMNode {
|
|||
return RECORD_SIZE;
|
||||
}
|
||||
|
||||
public static DBString getId(PDOM pdom, int record) throws CoreException {
|
||||
public static IString getId(PDOM pdom, int record) throws CoreException {
|
||||
Database db = pdom.getDB();
|
||||
int namerec = db.getInt(record + ID_OFFSET);
|
||||
return db.getString(namerec);
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006 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 - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.internal.core.pdom.dom;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
|
||||
import org.eclipse.cdt.internal.core.pdom.PDOM;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.Database;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.IString;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
/**
|
||||
* Represents macros.
|
||||
*
|
||||
* @author Doug Schaefer
|
||||
*/
|
||||
public class PDOMMacro {
|
||||
|
||||
private final PDOM pdom;
|
||||
private final int record;
|
||||
|
||||
private static final int NAME = 0;
|
||||
private static final int EXPANSION = 4;
|
||||
private static final int NEXT_MACRO = 8;
|
||||
|
||||
private static final int RECORD_SIZE = 12;
|
||||
|
||||
public PDOMMacro(PDOM pdom, int record) {
|
||||
this.pdom = pdom;
|
||||
this.record = record;
|
||||
}
|
||||
|
||||
public PDOMMacro(PDOM pdom, IASTPreprocessorMacroDefinition macro) throws CoreException {
|
||||
this.pdom = pdom;
|
||||
|
||||
Database db = pdom.getDB();
|
||||
this.record = db.malloc(RECORD_SIZE);
|
||||
db.putInt(record + NAME, db.newString(macro.getName().toCharArray()).getRecord());
|
||||
db.putInt(record + EXPANSION, db.newString(macro.getExpansion()).getRecord());
|
||||
setNextMacro(0);
|
||||
}
|
||||
|
||||
public int getRecord() {
|
||||
return record;
|
||||
}
|
||||
|
||||
public void delete() throws CoreException {
|
||||
pdom.getDB().free(record);
|
||||
}
|
||||
|
||||
public IString getName() throws CoreException {
|
||||
Database db = pdom.getDB();
|
||||
int rec = db.getInt(record + NAME);
|
||||
return db.getString(rec);
|
||||
}
|
||||
|
||||
public IString getExpansion() throws CoreException {
|
||||
Database db = pdom.getDB();
|
||||
int rec = db.getInt(record + EXPANSION);
|
||||
return db.getString(rec);
|
||||
}
|
||||
|
||||
public PDOMMacro getNextMacro() throws CoreException {
|
||||
int rec = pdom.getDB().getInt(record + NEXT_MACRO);
|
||||
return rec != 0 ? new PDOMMacro(pdom, rec) : null;
|
||||
}
|
||||
|
||||
public void setNextMacro(PDOMMacro macro) throws CoreException {
|
||||
setNextMacro(macro != null ? macro.getRecord() : 0);
|
||||
}
|
||||
|
||||
public void setNextMacro(int rec) throws CoreException {
|
||||
pdom.getDB().putInt(record + NEXT_MACRO, rec);
|
||||
}
|
||||
}
|
|
@ -20,7 +20,6 @@ import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.internal.core.pdom.PDOM;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.DBString;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.Database;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
|
|
|
@ -14,10 +14,10 @@ package org.eclipse.cdt.internal.core.pdom.dom;
|
|||
import org.eclipse.cdt.core.dom.IPDOMNode;
|
||||
import org.eclipse.cdt.core.dom.IPDOMVisitor;
|
||||
import org.eclipse.cdt.internal.core.pdom.PDOM;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.DBString;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.Database;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.IBTreeComparator;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.IString;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
/**
|
||||
|
@ -29,8 +29,8 @@ import org.eclipse.core.runtime.CoreException;
|
|||
*/
|
||||
public abstract class PDOMNode implements IPDOMNode{
|
||||
|
||||
private static final int PARENT_OFFSET = 0;
|
||||
private static final int NAME_OFFSET = 4;
|
||||
private static final int PARENT = 0;
|
||||
private static final int NAME = 4;
|
||||
|
||||
protected static final int RECORD_SIZE = 8;
|
||||
|
||||
|
@ -49,12 +49,11 @@ public abstract class PDOMNode implements IPDOMNode{
|
|||
record = db.malloc(getRecordSize());
|
||||
|
||||
// name - must be before parent
|
||||
int namerec = db.putChars(name);
|
||||
db.putInt(record + NAME_OFFSET, namerec);
|
||||
db.putInt(record + NAME, db.newString(name).getRecord());
|
||||
|
||||
// parent
|
||||
if (parent != null) {
|
||||
pdom.getDB().putInt(record + PARENT_OFFSET, parent.getRecord());
|
||||
pdom.getDB().putInt(record + PARENT, parent.getRecord());
|
||||
parent.addChild(this);
|
||||
}
|
||||
|
||||
|
@ -81,29 +80,23 @@ public abstract class PDOMNode implements IPDOMNode{
|
|||
public static PDOMLinkage getLinkage(PDOM pdom, int record) throws CoreException {
|
||||
Database db = pdom.getDB();
|
||||
int linkagerec = record;
|
||||
int parentrec = db.getInt(linkagerec + PARENT_OFFSET);
|
||||
int parentrec = db.getInt(linkagerec + PARENT);
|
||||
while (parentrec != 0) {
|
||||
linkagerec = parentrec;
|
||||
parentrec = db.getInt(linkagerec + PARENT_OFFSET);
|
||||
parentrec = db.getInt(linkagerec + PARENT);
|
||||
}
|
||||
|
||||
return pdom.getLinkage(linkagerec);
|
||||
}
|
||||
|
||||
public DBString getDBName() throws CoreException {
|
||||
public IString getDBName() throws CoreException {
|
||||
Database db = pdom.getDB();
|
||||
int namerec = db.getInt(record + NAME_OFFSET);
|
||||
int namerec = db.getInt(record + NAME);
|
||||
return db.getString(namerec);
|
||||
}
|
||||
|
||||
public char[] getNameCharArray() throws CoreException {
|
||||
Database db = pdom.getDB();
|
||||
int namerec = db.getInt(record + NAME_OFFSET);
|
||||
return db.getChars(namerec);
|
||||
}
|
||||
|
||||
protected int getNameRecord() throws CoreException {
|
||||
return pdom.getDB().getInt(record + NAME_OFFSET);
|
||||
return getDBName().getChars();
|
||||
}
|
||||
|
||||
protected void addChild(PDOMNode child) throws CoreException {
|
||||
|
@ -111,18 +104,16 @@ public abstract class PDOMNode implements IPDOMNode{
|
|||
}
|
||||
|
||||
public boolean hasName(char[] name) throws CoreException {
|
||||
Database db = pdom.getDB();
|
||||
int namerec = db.getInt(record + NAME_OFFSET);
|
||||
return pdom.getDB().stringCompare(namerec, name) == 0;
|
||||
return getDBName().equals(name);
|
||||
}
|
||||
|
||||
public IBTreeComparator getIndexComparator() {
|
||||
return new IBTreeComparator() {
|
||||
public int compare(int record1, int record2) throws CoreException {
|
||||
Database db = pdom.getDB();
|
||||
int string1 = db.getInt(record1 + NAME_OFFSET);
|
||||
int string2 = db.getInt(record2 + NAME_OFFSET);
|
||||
return db.stringCompare(string1, string2);
|
||||
int string1 = db.getInt(record1 + NAME);
|
||||
int string2 = db.getInt(record2 + NAME);
|
||||
return db.getString(string1).compare(db.getString(string2));
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -136,8 +127,8 @@ public abstract class PDOMNode implements IPDOMNode{
|
|||
}
|
||||
public int compare(int record) throws CoreException {
|
||||
Database db = pdom.getDB();
|
||||
int namerec = db.getInt(record + NAME_OFFSET);
|
||||
return db.stringCompare(namerec, name);
|
||||
int namerec = db.getInt(record + NAME);
|
||||
return db.getString(namerec).compare(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,4 +70,6 @@ CTagsIndexMarker.CTagsMissing=CTags not installed or not in path
|
|||
DOMIndexerMarker.EmptyScannerInfo=File not indexed because it was not built
|
||||
|
||||
dom.languageError=Language not found
|
||||
indexer.notFound = Indexer not found
|
||||
indexer.notFound = Indexer not found
|
||||
|
||||
pdom.requestTooLarge=Request too large
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
package org.eclipse.cdt.internal.ui.indexview;
|
||||
|
||||
import org.eclipse.cdt.internal.core.pdom.PDOM;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.DBString;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.IString;
|
||||
import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
|
||||
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
@ -83,7 +83,7 @@ public class LinkageCache {
|
|||
return pdom.getBinding(cache[index]);
|
||||
}
|
||||
|
||||
public DBString getName() throws CoreException {
|
||||
public IString getName() throws CoreException {
|
||||
return linkage.getDBName();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue