Candidate release of source code.

This commit is contained in:
Dan 2019-03-26 13:45:32 -04:00
parent db81e6b3b0
commit 79d8f164f8
12449 changed files with 2800756 additions and 16 deletions

56
.gitattributes vendored Normal file
View File

@ -0,0 +1,56 @@
# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto
# Explicitly declare text files you want to always be normalized and converted
# to native line endings on checkout.
*.java text
*.gradle text
*.manifest text
*.css text
*.htm text
*.html text
*.js text
*.json text
*.jsp text
*.jspf text
*.jspx text
*.properties text
*.sh text
*.tld text
*.txt text
*.tag text
*.xml text
*.c text
*.h text
*.cpp text
*.hh text
*.cc text
# Declare files that will always have CRLF line endings on checkout.
*.sln text eol=crlf
*.vcproj text eol=crlf
*.vcxproj text eol=crlf
*.bat text eol=crlf
# Denote all files that are truly binary and should not be modified.
*.png binary
*.jpg binary
*.class binary
*.dll binary
*.ear binary
*.gif binary
*.ico binary
*.jar binary
*.jpeg binary
*.so binary
*.war binary
*.pdf binary
*.exe binary
*.lib binary
*.sa binary
*.gz binary
*.gzf binary
*.tgz binary
*.tar binary

67
.gitignore vendored
View File

@ -1,14 +1,63 @@
.gradle *.class
Thumbs.db
.DS_Store
.svn
excludedFiles.txt
.classpath
.project
ghidra.repos.config
/*/*/*/*/*/bin/
/*/*/*/*/*/build/
/*/*/*/*/bin/
/*/*/*/*/build/
/*/*/*/bin/
/*/*/*/build/
/*/*/bin/
/*/*/build/
/*/bin/
/*/build/
/build/ /build/
/bin/
# Ignore Gradle GUI config **/dist
gradle-app.setting repositories/
*.sla
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) # Misc files
!gradle-wrapper.jar *.setting
*.settings
*.directory
.gradle/
.settings/
# Cache of project # File locks
.gradletasknamecache *.ulock
*.lock
# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 # Gradle creates these per developer
# gradle/wrapper/gradle-wrapper.properties **/vs/
# Misc files produced while executing application
Ghidra/.ghidraSvrKeys
wrapper.log*
# Ignore object files
*.o
*.obj
# Ignore MS Visual Studio artifcats
Release
#Debug
*.ncb
*.suo
*.aps
*.vcproj.*
# Ignore UNIX backup files
*~
*.swp
# Ignore eclipse project files
.project
.classpath

275
DevGuide.md Normal file
View File

@ -0,0 +1,275 @@
# Developer's Guide: Getting Started
Install OpenJDK 11 and make sure it's the default java.
Install Eclipse, at least version 2018-12, and ensure it is launched using OpenJDK 11.
Technically, you can launch with any JRE/JDK, but it's up to you ensure OpenJDK 11 is properly configured in Eclipse.
Optionally install Gradle 5.0, and ensure it is launched using OpenJDK 11.
These instructions assume you are using the gradle wrapper, so adjust the commands accordingly if you choose to use your own Gradle installation.
## Setup Repositories
Of course, you may choose any directory for your working copy, but these instructions will assume you have cloned the repo to `~/git`.
Be sure to adjust the commands to match your chosen working directory if different than suggested:
```bash
cd ~/git
git clone git@github.com:NationalSecurityAgency/ghidra.git
```
Ghidra's build uses artifact named as available in Maven Central and Bintray JCenter, when possible.
Unfortunately, in some cases, the artifact or the particular version we desire is not available.
So, in addition to mavenCentral and jcenter, you must configure a flatDir-style repository for manually-downloaded dependencies.
Create `~/.gradle/init.d/repos.gradle` with the following contents:
```groovy
ext.HOME = System.getProperty('user.home')
allprojects {
repositories {
mavenCentral()
jcenter()
flatDir name:'flat', dirs:["$HOME/flatRepo"]
}
}
```
You should also create the `~/flatRepo` folder to hold the manually-downloaded dependencies:
```bash
mkdir ~/flatRepo
```
If you prefer not to modify your user-wide Gradle configuration, you may use
Gradle's other init script facilities, but you're on your own.
## Get Dependencies for FileFormats:
Download `dex-tools-2.0.zip` from the dex2jar project's releases page on GitHub.
Unpack the `dex-*.jar` files from the `lib` directory to `~/flatRepo`:
```bash
cd ~/Downloads # Or wherever
curl -OL https://github.com/pxb1988/dex2jar/releases/download/2.0/dex-tools-2.0.zip
unzip dex-tools-2.0.zip
cp dex2jar-2.0/lib/dex-*.jar ~/flatRepo/
```
Download `AXMLPrinter2.jar` from the "android4me" archive on code.google.com.
Place it in `~/flatRepo`:
```bash
cd ~/flatRepo
curl -OL https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/android4me/AXMLPrinter2.jar
```
## Get Dependencies for DMG:
Download `hfsexplorer-0_21-bin.zip` from www.catacombae.org.
Unpack the `lib` directory to `~/flatRepo.`:
```bash
cd ~/Downloads # Or wherever
curl -OL https://sourceforge.net/projects/catacombae/files/HFSExplorer/0.21/hfsexplorer-0_21-bin.zip
mkdir hfsx
cd hfsx
unzip ../hfsexplorer-0_21-bin.zip
cd lib
cp csframework.jar hfsx_dmglib.jar hfsx.jar iharder-base64.jar ~/flatRepo/
```
## Import Gradle Project
At this point, you may import Ghidra into Eclipse using the integrated BuildShip plugin.
If you prefer another IDE, there's no reason it shouldn't work, but you're on your own.
Note that the GhidraDevPlugin requires Eclipse PDE.
Close this project to clean up the errors, unless you are developing the GhidraDevPlugin.
You may see build path errors until the environment is properly prepared, as described below.
## Prepare the Environment
There are a few preparatory tasks you should execute before, or immediately after, importing the project.
These tasks will build and index the online help, and place it somewhere accessible to Ghidra when launched from Eclipse, among other things.
This task also attempts to unpack some SDKs and/or larger dependencies required by Ghidra.
We do not provide these packages out-of-the-box because of technical and legal constraints on our distributing them.
These include the Eclipse CDT, PyDev for Eclipse, and "Yet another Java service wrapper."
If you would like to build the dependent modules, please see the relevant sections below.
For now, we will exclude the affected unpack tasks.
From the project root, execute:
```bash
./gradlew prepDev -x yajswDevUnpack
```
Optionally, to pre-compile all the language modules, you may also execute:
```bash
./gradlew sleighCompile
```
Refresh the Gradle project in Eclipse.
You should not see any errors at this point, and you can accomplish many development tasks.
However, some features of Ghidra will not be functional until further steps are taken.
### Building the natives
Some of Ghidra's components are built for the native platform.
We currently support Linux, macOS, and Windows 64-bit x86 systems.
Others should be possible, but we do not support them.
#### decompile
Install bison and flex.
Now build using Gradle:
On Linux:
```bash
./gradlew decompileLinux64Executable
```
On macOS:
```bash
./gradlew decompileOsx64Executable
```
On Windows:
```cmd
gradlew decompileWin64Executable
```
#### demangler_gnu
Build using Gradle:
On Linux:
```bash
./gradlew demangler_gnuLinux64Executable
```
On macOS:
```bash
./gradlew demangler_gnuOsx64Executable
```
On Windows:
```cmd
gradlew demangler_gnuWin64Executable
```
#### sleigh
The sleigh compiler has been ported to Java, and Ghidra will automatically compile slaspec files that it finds are out of date.
The native sleigh compiler may still be useful for those who'd like quicker feedback by compiling from the command line. To build the native sleigh compiler, install bison and flex.
Now, use Gradle:
On Linux:
```bash
./gradlew sleighLinux64Executable
```
On macOS:
```bash
./gradlew sleighOsx64Executable
```
On Windows:
```cmd
gradlew sleighWin64Executable
```
### Get Dependencies for GhidraDev
Building the GhidraDev plugin for Eclipse requires the CDT and PyDev plugins for Eclipse.
Download `cdt-8.6.0.zip` from The Eclipse Foundation, and place it in a directory named:
`ghidra.bin/GhidraBuild/EclipsePlugins/GhidraDev/buildDependencies/`.
`ghidra.bin` must be a sibling of `ghidra`.
To respect the CDT project's resources, you will need to download the file using a browser, or at the very least, locate a suitable mirror on your own:
```bash
cd ~/Downloads # Or wherever
curl -OL http://$CHOOSE_YOUR_MIRROR/pub/eclipse/tools/cdt/releases/8.6/cdt-8.6.0.zip
mkdir -p ~/git/ghidra.bin/GhidraBuild/EclipsePlugins/GhidraDev/buildDependencies/
cp ~/Downloads/cdt-8.6.0.zip ~/git/ghidra.bin/GhidraBuild/EclipsePlugins/GhidraDev/buildDependencies/
```
Download `PyDev 6.3.1.zip` from www.pydev.org, and place it in the same directory:
```bash
cd ~/Downloads # Or wherever
curl -OL https://sourceforge.net/projects/pydev/files/pydev/PyDev%206.3.1/PyDev%206.3.1.zip
cp ~/Downloads/'PyDev 6.3.1.zip' ~/git/ghidra.bin/GhidraBuild/EclipsePlugins/GhidraDev/buildDependencies/
```
Use Gradle to unpack the dependencies for development and building.
First, you will need to uncomment the GhidraDev project in the ```settings.gradle``` file.
Then, from your clone:
```bash
./gradlew cdtUnpack pyDevUnpack
```
### Get Dependencies for GhidraServer
Building the GhidraServer requires "Yet another Java service wrapper" (yajsw) version 12.12.
Note that building the full Ghidra package requires building the GhidraServer.
Download `yajsw-stable-12.12.zip` from their project on www.sourceforge.net, and place it in a directory named:
`ghidra.bin/Ghidra/Features/GhidraSerer/`:
```bash
cd ~/Downloads # Or wherever
curl -OL https://sourceforge.net/projects/yajsw/files/yajsw/yajsw-stable-12.12/yajsw-stable-12.12.zip
mkdir -p ~/git/ghidra.bin/Ghidra/Features/GhidraServer/
cp ~/Downloads/yajsw-stable-12.12.zip ~/git/ghidra.bin/Ghidra/Features/GhidraServer/
```
Use Gradle to unpack the wrapper for development.
From your clone:
```bash
./gradlew yajswDevUnpack
```
# Build the full Ghidra package
If you've followed all of the steps above, except perhaps importing to Eclipse, you should be able to produce a build.
Before building, you may want to update the version and release name.
These properties are kept in `Ghidra/application.properties`.
If you want it included, you must also build the GhidraDevPlugin module first.
We do not yet have instructions for building the GhidraDevPlugin.
It should be relatively straightforward for anyone familiar with Eclipse PDE.
To build the full package, use Gradle:
```bash
./gradlew buildGhidra
```
The output will be placed in `build/dist/`.
It will be named according to the version, release name, build date, and platform.
To test it, unzip it where you like, and execute `./ghidraRun`.
# Building Supporting Data
Some features of Ghidra require the curation of rather extensive data bases.
These include the Data Type Archives and Function ID Databases, both of which require collecting header files and libraries for the relevant SDKs and platforms.
Much of this work is done by hand, and the results are simply copied into the build.
We intend to document these procedures as soon as we can.
In the meantime, those artifacts can always be extracted from our binary release.
## Building Data Type Archives
TODO
## Building FID Databases
TODO

View File

@ -0,0 +1,2 @@
MODULE FILE LICENSE: os/linux64/cabextract GPL 3
MODULE FILE LICENSE: os/osx64/cabextract GPL 3

View File

@ -0,0 +1,69 @@
apply plugin: 'eclipse'
eclipse.project.name = 'GPL CabExtract'
project.ext.cabextract = "cabextract-1.6"
/*********************************************************************************
* CabExtract extraction task
*
* Unpacks the cabextract tar file that's needed for the symbol server. This
* is only unpacked for building the tool; once it's built, this unzipped
* archive is removed.
*
* NOTE: Ant is used so that timestamps are properly preserved, failure to
* do so can cause the aclocal utility to be required which may be missing!
*********************************************************************************/
task unpackCabExtract (type: Copy) {
doFirst {
delete file("build/${cabextract}")
}
doLast {
// Force all unpacked files to have the same timestamp
ant.touch() {
fileset(dir: file("build/${cabextract}"))
}
}
from tarTree(file("data/${cabextract}.tar.gz"))
into 'build'
// Force the task to be executed every time by setting to false.
// This is done since configure changes the contents for a platform
outputs.upToDateWhen { false }
}
/*********************************************************************************
* CabExtract platform specific tasks
*
* The cabextract tool requires that its 'configure' script is called before make.
*********************************************************************************/
['linux64', 'osx64'].each { platform ->
def configureName = "${platform}CabExtractConfigure"
def makeName = "${platform}CabExtractMake" // native Make task found automatically
task (configureName, type: Exec) {
group "private"
workingDir "build/${cabextract}"
executable "./configure"
dependsOn unpackCabExtract
}
task (makeName, type: Exec) {
group "private"
workingDir "build/${cabextract}"
executable "make"
dependsOn configureName
doLast {
copy {
from "build/${cabextract}/cabextract"
into "build/os/${platform}"
}
}
}
}

View File

@ -0,0 +1,8 @@
##VERSION: 2.0
##MODULE IP: GPL 3
##MODULE IP: Public Domain
.classpath||Public Domain||||END|
.project||Public Domain||||END|
Module.manifest||Public Domain||||END|
build.gradle||Public Domain||||END|
data/cabextract-1.6.tar.gz||GPL 3||||END|

Binary file not shown.

2
GPL/DMG/Module.manifest Normal file
View File

@ -0,0 +1,2 @@
# GPL because we have linked to GPL hsfx.jar
MODULE FILE LICENSE: data/lib/dmg.jar GPL 3

54
GPL/DMG/build.gradle Normal file
View File

@ -0,0 +1,54 @@
apply plugin: 'eclipse'
eclipse.project.name = 'GPL DMG'
/*********************************************************************************
*
* Define a new source set for dmg source because it is not part of Ghidra, it is
* a standalone application that is executed and called from Ghidra.
*
* see DmgServerProcessManager
*
*********************************************************************************/
sourceSets {
dmg {
java {
srcDir 'src/dmg/java'
}
}
}
eclipse.classpath.plusConfigurations += [configurations.dmgCompile]
dependencies {
dmgCompile ':csframework@jar'
dmgCompile ':hfsx@jar'
dmgCompile ':hfsx_dmglib@jar'
}
/***************************************************************************************
*
* Task to create the dmg.jar file
*
***************************************************************************************/
task dmgJar(type: Jar) {
from sourceSets.dmg.output
destinationDir = file("build/data/lib")
baseName = 'dmg'
}
jar {
doLast {
File f = file("build/libs/DMG.jar")
delete "build/libs"
}
}
/***************************************************************************************
*
* plugin the jar task into global task for building and zipping contribs
*
***************************************************************************************/
assemble.dependsOn dmgJar

View File

@ -0,0 +1,20 @@
##VERSION: 2.0
##MODULE IP: GPL 3
##MODULE IP: LGPL 2.1
##MODULE IP: Public Domain
.classpath||Public Domain||||END|
.project||Public Domain||||END|
Module.manifest||Public Domain||||END|
build.gradle||Public Domain||||END|
data/lib/catacombae_csframework.jar||LGPL 2.1||||END|
data/lib/catacombae_hfsx.jar||GPL 3||||END|
data/lib/catacombae_hfsx_dmglib.jar||GPL 3||||END|
data/lib/catacombae_iharder-base64.jar||GPL 3||||END|
data/lib/hfsexplorer-0_21-src.zip||GPL 3||||END|
data/os/win32/llio_amd64.dll||GPL 3||||END|
data/os/win32/llio_i386.dll||GPL 3||||END|
data/os/win32/llio_ia64.dll||GPL 3||||END|
data/os/win64/llio_amd64.dll||GPL 3||||END|
data/os/win64/llio_i386.dll||GPL 3||||END|
data/os/win64/llio_ia64.dll||GPL 3||||END|
data/server_memory.cfg||Public Domain||||END|

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1 @@
2048

View File

@ -0,0 +1,116 @@
/* ###
* IP: Public Domain
*/
package mobiledevices.dmg.btree;
import java.io.IOException;
import mobiledevices.dmg.ghidra.GBinaryReader;
/**
* Represents a BTHeaderRec structure.
*
* @see <a href="https://opensource.apple.com/source/xnu/xnu-792/bsd/hfs/hfs_format.h.auto.html">hfs/hfs_format.h</a>
*/
public class BTreeHeaderRecord /*implements StructConverter*/ {
private short treeDepth;
private int rootNode;
private int leafRecords;
private int firstLeafNode;
private int lastLeafNode;
private short nodeSize;
private short maxKeyLength;
private int totalNodes;
private int freeNodes;
private short reserved1;
private int clumpSize;
private byte btreeType;
private byte keyCompareType;
private int attributes;
private int[] reserved;
BTreeHeaderRecord(GBinaryReader reader) throws IOException {
this.treeDepth = reader.readNextShort();
this.rootNode = reader.readNextInt();
this.leafRecords = reader.readNextInt();
this.firstLeafNode = reader.readNextInt();
this.lastLeafNode = reader.readNextInt();
this.nodeSize = reader.readNextShort();
this.maxKeyLength = reader.readNextShort();
this.totalNodes = reader.readNextInt();
this.freeNodes = reader.readNextInt();
this.reserved1 = reader.readNextShort();
this.clumpSize = reader.readNextInt();
this.btreeType = reader.readNextByte();
this.keyCompareType = reader.readNextByte();
this.attributes = reader.readNextInt();
this.reserved = reader.readNextIntArray(16);
}
public short getTreeDepth() {
return treeDepth;
}
public int getRootNode() {
return rootNode;
}
public int getLeafRecords() {
return leafRecords;
}
public int getFirstLeafNode() {
return firstLeafNode;
}
public int getLastLeafNode() {
return lastLeafNode;
}
public short getNodeSize() {
return nodeSize;
}
public short getMaxKeyLength() {
return maxKeyLength;
}
public int getTotalNodes() {
return totalNodes;
}
public int getFreeNodes() {
return freeNodes;
}
public short getReserved1() {
return reserved1;
}
public int getClumpSize() {
return clumpSize;
}
public byte getBtreeType() {
return btreeType;
}
public byte getKeyCompareType() {
return keyCompareType;
}
public int getAttributes() {
return attributes;
}
public int[] getReserved() {
return reserved;
}
// @Override
// public DataType toDataType() throws DuplicateNameException, IOException {
// return StructConverterUtil.toDataType( this );
// }
}

View File

@ -0,0 +1,17 @@
/* ###
* IP: Public Domain
*/
package mobiledevices.dmg.btree;
/**
* Represents a BTHeaderRec attributes.
*
* @see <a href="https://opensource.apple.com/source/xnu/xnu-792/bsd/hfs/hfs_format.h.auto.html">hfs/hfs_format.h</a>
*/
public final class BTreeHeaderRecordAttributes {
public final static int kBTBadCloseMask = 0x00000001;
public final static int kBTBigKeysMask = 0x00000002;
public final static int kBTVariableIndexKeysMask = 0x00000004;
}

View File

@ -0,0 +1,47 @@
/* ###
* IP: Public Domain
*/
package mobiledevices.dmg.btree;
import java.io.IOException;
import mobiledevices.dmg.ghidra.GBinaryReader;
/**
* Represents a Map Record.
*
* @see <a href="https://developer.apple.com/library/archive/technotes/tn/tn1150.html">Map Record</a>
*/
public class BTreeMapRecord /*implements StructConverter*/ {
private byte[] bitmap;
protected BTreeMapRecord(GBinaryReader reader, BTreeHeaderRecord headerRecord)
throws IOException {
this.bitmap = reader.readNextByteArray(headerRecord.getNodeSize() - 256);
}
/**
* Returns the map record node allocation bitmap.
* @return the map record node allocation bitmap
*/
public byte[] getBitmap() {
return bitmap;
}
/**
* Returns true if the specified node index is used.
* Returns false if the specified node index is free.
* @param nodeIndex the node index
* @return true if the specified node index is used, false if free
*/
public boolean isNodeUsed(int nodeIndex) {
int block = bitmap[nodeIndex / 8] & 0xff;
return (block & (1 << 7 - (nodeIndex % 8))) != 0;
}
// @Override
// public DataType toDataType() throws DuplicateNameException, IOException {
// return StructConverterUtil.toDataType( this );
// }
}

View File

@ -0,0 +1,128 @@
/* ###
* IP: Public Domain
*/
package mobiledevices.dmg.btree;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import mobiledevices.dmg.ghidra.GBinaryReader;
/**
* Represents a BTNodeDescriptor structure.
*
* @see <a href="https://opensource.apple.com/source/xnu/xnu-792/bsd/hfs/hfs_format.h.auto.html">hfs/hfs_format.h</a>
*/
public class BTreeNodeDescriptor /*implements StructConverter*/ {
private int fLink;
private int bLink;
private byte kind;
private byte height;
private short numRecords;
private short reserved;
private List<Short> _recordOffsets = new ArrayList<Short>();
private List<BTreeNodeRecord> _records = new ArrayList<BTreeNodeRecord>();
BTreeNodeDescriptor(GBinaryReader reader) throws IOException {
this.fLink = reader.readNextInt();
this.bLink = reader.readNextInt();
this.kind = reader.readNextByte();
this.height = reader.readNextByte();
this.numRecords = reader.readNextShort();
this.reserved = reader.readNextShort();
}
protected void readRecordOffsets(GBinaryReader reader, long nodeStartIndex,
BTreeHeaderRecord header) throws IOException {
long position = nodeStartIndex + header.getNodeSize() - 2;
while (true) {
short recordOffset = reader.readShort(position);
if (recordOffset == 0) {
break;
}
_recordOffsets.add(recordOffset);
position = position - 2;
}
}
protected void readRecords(GBinaryReader reader, long nodeStartIndex) throws IOException {
for (int i = 0; i < getNumRecords(); ++i) {
short offset = getRecordOffsets().get(i);
long recordIndex = (offset & 0xffff) + nodeStartIndex;
reader.setPointerIndex(recordIndex);
BTreeNodeRecord record = new BTreeNodeRecord(reader, this);
_records.add(record);
}
}
public List<Short> getRecordOffsets() {
return _recordOffsets;
}
public List<BTreeNodeRecord> getRecords() {
return _records;
}
/**
* The node number of the next node of this type.
* Or, zero ( 0 ) if this is the last node.
* @return node number of the next node of this type
*/
public int getFLink() {
return fLink;
}
/**
* The node number of the previous node of this type.
* Or, zero ( 0 ) if this is the first node.
* @return node number of the previous node of this type
*/
public int getBLink() {
return bLink;
}
/**
* Returns the key of this node.
* @return the key of this node
* @see BTreeNodeKinds
*/
public byte getKind() {
return kind;
}
/**
* Returns the level, or depth, of this node in the B-tree hierarchy.
* @return the level, or depth, of this node in the B-tree hierarchy
*/
public byte getHeight() {
return height;
}
/**
* Returns the number of records in this node.
* @return the number of records in this node
*/
public short getNumRecords() {
return numRecords;
}
/**
* This field is reserved.
* @return this field is reserved
*/
public short getReserved() {
return reserved;
}
// @Override
// public DataType toDataType() throws DuplicateNameException, IOException {
// return StructConverterUtil.toDataType( this );
// }
}

View File

@ -0,0 +1,19 @@
/* ###
* IP: Public Domain
*/
package mobiledevices.dmg.btree;
/**
* Represents kinds of BTNodeDescriptor.
*
* @see <a href="https://opensource.apple.com/source/xnu/xnu-792/bsd/hfs/hfs_format.h.auto.html">hfs/hfs_format.h</a>
* @see <a href="https://developer.apple.com/library/archive/technotes/tn/tn1150.html">B-Trees</a>
*/
public final class BTreeNodeKinds {
public final static byte kBTLeafNode = -1;
public final static byte kBTIndexNode = 0;
public final static byte kBTHeaderNode = 1;
public final static byte kBTMapNode = 2;
}

View File

@ -0,0 +1,140 @@
/* ###
* IP: Public Domain
*/
package mobiledevices.dmg.btree;
import java.io.IOException;
import mobiledevices.dmg.decmpfs.DecmpfsHeader;
import mobiledevices.dmg.ghidra.GBinaryReader;
import mobiledevices.dmg.xattr.XattrConstants;
public class BTreeNodeRecord /*implements StructConverter*/ {
private int unknown0;
private int fileID;
private int unknown2;
private String type;
private int unknown3;
private int unknown4;
private int unknown5;
private int recordLength;
private short _typeLength;
private BTreeNodeDescriptor _descriptor;
private DecmpfsHeader _decmpfsHeader;
private long _offset;
BTreeNodeRecord( GBinaryReader reader, BTreeNodeDescriptor descriptor ) throws IOException {
_offset = reader.getPointerIndex();
unknown0 = reader.readNextInt();
fileID = reader.readNextInt();
unknown2 = reader.readNextInt();
_typeLength = reader.readNextShort();
type = readType( reader );
unknown3 = reader.readNextInt();
switch ( descriptor.getKind() ) {
case BTreeNodeKinds.kBTHeaderNode: {
break;
}
case BTreeNodeKinds.kBTIndexNode: {
break;
}
case BTreeNodeKinds.kBTLeafNode: {
unknown4 = reader.readNextInt();
unknown5 = reader.readNextInt();
recordLength = reader.readNextInt();
break;
}
case BTreeNodeKinds.kBTMapNode: {
break;
}
}
_descriptor = descriptor;
if ( descriptor.getKind() == BTreeNodeKinds.kBTLeafNode ) {
if ( getType().equals( XattrConstants.DECMPFS_XATTR_NAME ) ) {
_decmpfsHeader = new DecmpfsHeader( reader, getRecordLength() );
}
else if ( getType().equals( XattrConstants.KAUTH_FILESEC_XATTR_NAME ) ) {
//TODO
}
}
else if ( descriptor.getKind() == BTreeNodeKinds.kBTIndexNode ) {
if ( getType().equals( XattrConstants.DECMPFS_XATTR_NAME ) ) {
//TODO
}
}
}
private String readType( GBinaryReader reader ) throws IOException {
StringBuffer buffer = new StringBuffer();
for ( int i = 0 ; i < _typeLength ; ++i ) {
reader.readNextByte();//skip it...
buffer.append( (char) reader.readNextByte() );
}
return buffer.toString();
}
public String getType() {
return type;
}
public int getRecordLength() {
return recordLength;
}
public BTreeNodeDescriptor getDescriptor() {
return _descriptor;
}
public int getUnknown0() {
return unknown0;
}
public int getUnknown2() {
return unknown2;
}
public int getUnknown3() {
return unknown3;
}
public int getUnknown4() {
return unknown4;
}
public int getUnknown5() {
return unknown5;
}
public int getFileID() {
return fileID;
}
public DecmpfsHeader getDecmpfsHeader() {
return _decmpfsHeader;
}
public long getRecordOffset() {
return _offset;
}
// @Override
// public DataType toDataType() throws DuplicateNameException, IOException {
// String name = StructConverterUtil.parseName( BTreeNodeRecord.class );
// Structure struct = new StructureDataType( name, 0 );
// struct.add( DWORD, "unknown0", null );
// struct.add( DWORD, "fileID", null );
// struct.add( DWORD, "unknown2", null );
// struct.add( WORD, "typeLength", null );
// struct.add( UNICODE, _typeLength * 2, "type", null );
// struct.add( DWORD, "unknown3", null );
// if ( _descriptor.getKind() == BTreeNodeKinds.kBTLeafNode ) {
// struct.add( DWORD, "unknown4", null );
// struct.add( DWORD, "unknown5", null );
// struct.add( DWORD, "recordLength", null );
// }
// try {
// struct.setName( name + '_' + struct.getLength() );
// }
// catch ( Exception e ) {
// }
// return struct;
// }
}

View File

@ -0,0 +1,72 @@
/* ###
* IP: Public Domain
*/
package mobiledevices.dmg.btree;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import mobiledevices.dmg.ghidra.GBinaryReader;
public class BTreeRootNodeDescriptor extends BTreeNodeDescriptor {
private BTreeHeaderRecord headerRecord;
private BTreeUserDataRecord userDataRecord;
private BTreeMapRecord mapRecord;
private List<BTreeNodeDescriptor> nodes = new ArrayList<BTreeNodeDescriptor>();
public BTreeRootNodeDescriptor( GBinaryReader reader ) throws IOException {
super( reader );
headerRecord = new BTreeHeaderRecord( reader );
userDataRecord = new BTreeUserDataRecord( reader );
mapRecord = new BTreeMapRecord( reader, headerRecord );
nodes.add( this );
int nodeSize = headerRecord.getNodeSize() & 0xffff;
for ( int i = nodeSize ; i < reader.length() ; i += nodeSize ) {
reader.setPointerIndex( i );
BTreeNodeDescriptor node = new BTreeNodeDescriptor( reader );
nodes.add( node );
node.readRecordOffsets( reader, i, headerRecord );
node.readRecords( reader, i );
}
this.readRecordOffsets( reader, 0, headerRecord );
}
public BTreeHeaderRecord getHeaderRecord() {
return headerRecord;
}
public BTreeUserDataRecord getUserDataRecord() {
return userDataRecord;
}
public BTreeMapRecord getMapRecord() {
return mapRecord;
}
public BTreeNodeDescriptor getNode( int index ) {
try {
return nodes.get( index );
}
catch (Exception e) {
return null;
}
}
public List<BTreeNodeDescriptor> getNodes() {
return nodes;
}
// @Override
// public DataType toDataType() throws DuplicateNameException, IOException {
// //we want to return the super class structure,
// //this class is synthetic
// return StructConverterUtil.toDataType( BTreeNodeDescriptor.class );
// }
}

View File

@ -0,0 +1,14 @@
/* ###
* IP: Public Domain
*/
package mobiledevices.dmg.btree;
public final class BTreeTypes {
/** Control file */
public final static byte kHFSBTreeType = (byte)0;
/** User bTree types start from 128 */
public final static byte kUserBTreeType = (byte)128;
/** */
public final static byte kReservedBTreeType = (byte)255;
}

View File

@ -0,0 +1,31 @@
/* ###
* IP: Public Domain
*/
package mobiledevices.dmg.btree;
import java.io.IOException;
import mobiledevices.dmg.ghidra.GBinaryReader;
/**
* Represents a User Data Record.
*
* @see <a href="https://developer.apple.com/library/archive/technotes/tn/tn1150.html">User Data Record</a>
*/
public class BTreeUserDataRecord /*implements StructConverter*/ {
private byte[] unused;
BTreeUserDataRecord(GBinaryReader reader) throws IOException {
this.unused = reader.readNextByteArray(128);
}
public byte[] getUnused() {
return unused;
}
// @Override
// public DataType toDataType() throws DuplicateNameException, IOException {
// return StructConverterUtil.toDataType( this );
// }
}

View File

@ -0,0 +1,22 @@
/* ###
* IP: Public Domain
*/
package mobiledevices.dmg.decmpfs;
public final class DecmpfsCompressionTypes {
/** Uncompressed data in xattr. */
public final static int CMP_Type1 = 1;
/** Data stored in-line. */
public final static int CMP_Type3 = 3;
/** Resource fork contains compressed data. */
public final static int CMP_Type4 = 4;
/** ???? */
public final static int CMP_Type10 = 10;
public final static int CMP_MAX = 255;
}

View File

@ -0,0 +1,13 @@
/* ###
* IP: Public Domain
*/
package mobiledevices.dmg.decmpfs;
public final class DecmpfsConstants {
public final static int MAX_DECMPFS_XATTR_SIZE = 3802;
public final static byte [] DECMPFS_MAGIC_BYTES = { 'f', 'p', 'm', 'c' };
public final static String DECMPFS_MAGIC = new String( DECMPFS_MAGIC_BYTES );
}

View File

@ -0,0 +1,79 @@
/* ###
* IP: Public Domain
*/
package mobiledevices.dmg.decmpfs;
import java.io.IOException;
import mobiledevices.dmg.ghidra.GBinaryReader;
import mobiledevices.dmg.ghidra.GStringUtilities;
public class DecmpfsHeader /*implements StructConverter*/ {
private int compression_magic;
private int compression_type;
private long uncompressed_size;
private byte [] attr_bytes;
public DecmpfsHeader(GBinaryReader reader, int size) throws IOException {
long index = reader.getPointerIndex();
this.compression_magic = reader.readNextInt();
boolean originalEndian = reader.isLittleEndian();
reader.setLittleEndian( true );
this.compression_type = reader.readNextInt();
this.uncompressed_size = reader.readNextLong();
reader.setLittleEndian( originalEndian );
long endIndex = index + size + 1; //TODO always add 1????
if ( ( endIndex % 2 ) != 0 ) {
endIndex = endIndex - 1;
}
long nElements = endIndex - reader.getPointerIndex();
if ( ( nElements % 2 ) != 0 ) {//TODO
++nElements;
}
else if ( nElements < 0 ) {//TODO
System.err.println( "here" );
}
this.attr_bytes = reader.readNextByteArray( (int)nElements );
}
public String getCompressionMagic() {
return GStringUtilities.toString( compression_magic );
}
public int getCompressionType() {
return compression_type;
}
public long getUncompressedSize() {
return uncompressed_size;
}
public byte [] getAttrBytes() {
return attr_bytes;
}
// @Override
// public DataType toDataType() throws DuplicateNameException, IOException {
// String name = StructConverterUtil.parseName( DecmpfsHeader.class );
// Structure struct = new StructureDataType( name + "_" + attr_bytes.length, 0 );
//
// struct.add( STRING, 4, "compression_magic", null );
// struct.add( DWORD, "compression_type", null );
// struct.add( QWORD, "uncompressed_size", null );
//
// if ( attr_bytes.length > 0 ) {
// ArrayDataType byteArrayDT = new ArrayDataType( BYTE , attr_bytes.length, BYTE.getLength() );
// struct.add( byteArrayDT, "attr_bytes", null );
// }
// return struct;
// }
}

View File

@ -0,0 +1,13 @@
/* ###
* IP: Public Domain
*/
package mobiledevices.dmg.decmpfs;
public final class DecmpfsStates {
public final static int FILE_TYPE_UNKNOWN = 0;
public final static int FILE_IS_NOT_COMPRESSED = 1;
public final static int FILE_IS_COMPRESSED = 2;
public final static int FILE_IS_CONVERTING = 3; //file is converting from compressed to decompressed...
}

View File

@ -0,0 +1,957 @@
/* ###
* IP: Public Domain
*/
package mobiledevices.dmg.ghidra;
import java.io.IOException;
/**
* A class for reading data from a
* generic byte provider in either big-endian or little-endian.
*
*
*/
public class GBinaryReader {
/**
* The size of a BYTE in Java.
*/
public final static int SIZEOF_BYTE = 1;
/**
* The size of a SHORT in Java.
*/
public final static int SIZEOF_SHORT = 2;
/**
* The size of an INTEGER in Java.
*/
public final static int SIZEOF_INT = 4;
/**
* The size of a LONG in Java.
*/
public final static int SIZEOF_LONG = 8;
private GByteProvider provider;
private GDataConverter converter;
private long currentIndex;
/**
* Constructs a reader using the given
* file and endian-order.
*
* If isLittleEndian is true, then all values read
* from the file will be done so assuming
* little-endian order.
*
* Otherwise, if isLittleEndian
* is false, then all values will be read
* assuming big-endian order.
*
* @param provider the byte provider
* @param isLittleEndian the endian-order
*/
public GBinaryReader(GByteProvider provider, boolean isLittleEndian) {
this.provider = provider;
setLittleEndian(isLittleEndian);
}
/**
* Returns a clone of this reader positioned at the new index.
* @param newIndex the new index
* @return a clone of this reader positioned at the new index
*/
public GBinaryReader clone(int newIndex) {
GBinaryReader clone = new GBinaryReader(provider, isLittleEndian());
clone.converter = converter;
clone.currentIndex = newIndex;
return clone;
}
/**
* Returns true if this reader will extract values in little endian,
* otherwise in big endian.
* @return true is little endian, false is big endian
*/
public boolean isLittleEndian() {
return converter instanceof GDataConverterLE;
}
/**
* Sets the endian of this binary reader.
* @param isLittleEndian true for little-endian and false for big-endian
*/
public void setLittleEndian(boolean isLittleEndian) {
if (isLittleEndian) {
converter = new GDataConverterLE();
}
else {
converter = new GDataConverterBE();
}
}
/**
* Returns the length of the underlying file.
* @return returns the length of the underlying file
* @exception IOException if an I/O error occurs
*/
public long length() throws IOException {
return provider.length();
}
/**
* Returns true if the specified index into
* the underlying byte provider is valid.
* @param index the index in the byte provider
* @return returns true if the specified index is valid
* @exception IOException if an I/O error occurs
*/
public boolean isValidIndex(int index) throws IOException {
return provider.isValidIndex(index & GConv.INT_MASK);
}
/**
* Returns true if the specified index into
* the underlying byte provider is valid.
* @param index the index in the byte provider
* @return returns true if the specified index is valid
* @exception IOException if an I/O error occurs
*/
public boolean isValidIndex(long index) throws IOException {
return provider.isValidIndex(index);
}
/**
* Aligns the current index on the specified alignment value.
* For example, if current index was 123 and align value was
* 16, then current index would become 128.
* @param alignValue
* @return the number of bytes required to align
*/
public int align(int alignValue) {
long align = currentIndex % alignValue;
if (align == 0) {
return 0;
}
currentIndex = currentIndex + (alignValue - align);
return (int)(alignValue - align);
}
////////////////////////////////////////////////////////////////////
/**
* A convenience method for setting the index using
* an integer.
*/
public void setPointerIndex(int index) {
this.currentIndex = index & GConv.INT_MASK;
}
/**
* Sets the current index to the specified value.
* The pointer index will allow the reader
* to operate as a psuedo-iterator.
*
* @param index the byte provider index value
*/
public void setPointerIndex(long index) {
this.currentIndex = index;
}
/**
* Returns the current index value.
* @return the current index value
*/
public long getPointerIndex() {
return currentIndex;
}
/**
* Peeks at the next byte without incrementing
* the current index.
* @return the next byte
* @exception IOException if an I/O error occurs
*/
public byte peekNextByte() throws IOException {
return readByte(currentIndex);
}
/**
* Peeks at the next short without incrementing
* the current index.
* @return the next short
* @exception IOException if an I/O error occurs
*/
public short peekNextShort() throws IOException {
return readShort(currentIndex);
}
/**
* Peeks at the next integer without incrementing
* the current index.
* @return the next int
* @exception IOException if an I/O error occurs
*/
public int peekNextInt() throws IOException {
return readInt(currentIndex);
}
/**
* Peeks at the next long without incrementing
* the current index.
* @return the next long
* @exception IOException if an I/O error occurs
*/
public long peekNextLong() throws IOException {
return readLong(currentIndex);
}
/**
* Reads the byte at the current index and then increments the current
* index by <code>SIZEOF_BYTE</code>.
* @return the byte at the current index
* @exception IOException if an I/O error occurs
*/
public byte readNextByte() throws IOException {
byte b = readByte(currentIndex);
currentIndex += SIZEOF_BYTE;
return b;
}
/**
* Reads the byte at the current index and then increments the current
* index by <code>SIZEOF_BYTE</code>.
* @return the byte at the current index
* @exception IOException if an I/O error occurs
*/
public byte readNextByte(byte minClamp, byte maxClamp, Byte... exceptions) throws IOException {
byte b = readByte(currentIndex, minClamp, maxClamp, exceptions);
currentIndex += SIZEOF_BYTE;
return b;
}
/**
* Reads the short at the current index and then increments the current
* index by <code>SIZEOF_SHORT</code>.
* @return the short at the current index
* @exception IOException if an I/O error occurs
*/
public short readNextShort() throws IOException {
short s = readShort(currentIndex);
currentIndex+=SIZEOF_SHORT;
return s;
}
/**
* Reads the short at the current index and then increments the current
* index by <code>SIZEOF_SHORT</code>.
* @return the short at the current index
* @exception IOException if an I/O error occurs
*/
public short readNextShort(short minClamp, short maxClamp, Short... exceptions) throws IOException {
short s = readShort(currentIndex, minClamp, maxClamp, exceptions);
currentIndex+=SIZEOF_SHORT;
return s;
}
/**
* Reads the integer at the current index and then increments the current
* index by <code>SIZEOF_INT</code>.
* @return the integer at the current index
* @exception IOException if an I/O error occurs
*/
public int readNextInt() throws IOException {
int i = readInt(currentIndex);
currentIndex+=SIZEOF_INT;
return i;
}
/**
* Reads the integer at the current index and then increments the current
* index by <code>SIZEOF_INT</code>.
* @return the integer at the current index
* @exception IOException if an I/O error occurs
*/
public int readNextInt(int minClamp, int maxClamp, Integer... exceptions) throws IOException {
int i = readInt(currentIndex, minClamp, maxClamp, exceptions);
currentIndex+=SIZEOF_INT;
return i;
}
/**
* Reads the long at the current index and then increments the current
* index by <code>SIZEOF_LONG</code>.
* @return the long at the current index
* @exception IOException if an I/O error occurs
*/
public long readNextLong() throws IOException {
long l = readLong(currentIndex);
currentIndex+=SIZEOF_LONG;
return l;
}
/**
* Reads the long at the current index and then increments the current
* index by <code>SIZEOF_LONG</code>.
* @return the long at the current index
* @exception IOException if an I/O error occurs
*/
public long readNextLong(long minClamp, long maxClamp, Long... exceptions) throws IOException {
long l = readLong(currentIndex, minClamp, maxClamp, exceptions);
currentIndex+=SIZEOF_LONG;
return l;
}
/**
* Reads the Ascii string at the current index and then increments the current
* index by the length of the Ascii string that was found. This method
* expects the string to be null-terminated.
* @return the null-terminated Ascii string at the current index
* @exception IOException if an I/O error occurs
*/
public String readNextAsciiString() throws IOException {
String s = readAsciiString(currentIndex);
currentIndex+=(s.length()+1);
return s;
}
/**
* Reads an Ascii string of <code>length</code>
* characters starting at the current index and then increments the current
* index by <code>length</code>.
*
* @return the Ascii string at the current index
*/
public String readNextAsciiString(int length) throws IOException {
String s = readAsciiString(currentIndex, length);
currentIndex+=length;
return s;
}
/**
* Reads the Unicode string at the current index and then increments the current
* index by the length of the Unicode string that was found. This method
* expects the string to be double null-terminated ('\0\0').
* @return the null-terminated Ascii string at the current index
* @exception IOException if an I/O error occurs
*/
public String readNextUnicodeString() throws IOException {
String s = readUnicodeString(currentIndex);
currentIndex += ((s.length()+1)*2);
return s;
}
/**
* Reads the unicode string at the current index and then increments the current
* index by <code>length</code>.
* @return the unicode string at the current index
* @exception IOException if an I/O error occurs
*/
public String readNextUnicodeString(int length) throws IOException {
String s = readUnicodeString(currentIndex, length);
currentIndex+=(length*2);
return s;
}
/**
* Reads a byte array of <code>nElements</code>
* starting at the current index and then increments the current
* index by <code>SIZEOF_BYTE * nElements</code>.
* @return the byte array starting at the current index
* @exception IOException if an I/O error occurs
*/
public byte [] readNextByteArray(int nElements) throws IOException {
byte [] b = readByteArray(currentIndex, nElements);
currentIndex+=(SIZEOF_BYTE*nElements);
return b;
}
/**
* Reads a byte array of <code>nElements</code>
* starting at the current index and then increments the current
* index by <code>SIZEOF_BYTE * nElements</code>.
* @return the byte array starting at the current index
* @exception IOException if an I/O error occurs
*/
public byte [] readNextByteArray(int nElements, byte minClamp, byte maxClamp, Byte... exceptions) throws IOException {
byte [] b = readByteArray(currentIndex, nElements, minClamp, maxClamp, exceptions);
currentIndex+=(SIZEOF_BYTE*nElements);
return b;
}
/**
* Reads a short array of <code>nElements</code>
* starting at the current index and then increments the current
* index by <code>SIZEOF_SHORT * nElements</code>.
* @return the short array starting at the current index
* @exception IOException if an I/O error occurs
*/
public short [] readNextShortArray(int nElements) throws IOException {
short [] s = readShortArray(currentIndex, nElements);
currentIndex+=(SIZEOF_SHORT*nElements);
return s;
}
/**
* Reads a short array of <code>nElements</code>
* starting at the current index and then increments the current
* index by <code>SIZEOF_SHORT * nElements</code>.
* @return the short array starting at the current index
* @exception IOException if an I/O error occurs
*/
public short [] readNextShortArray(int nElements, short minClamp, short maxClamp, Short... exceptions) throws IOException {
short [] s = readShortArray(currentIndex, nElements, minClamp, maxClamp, exceptions);
currentIndex+=(SIZEOF_SHORT*nElements);
return s;
}
/**
* Reads an integer array of <code>nElements</code>
* starting at the current index and then increments the current
* index by <code>SIZEOF_INT * nElements</code>.
* @return the integer array starting at the current index
* @exception IOException if an I/O error occurs
*/
public int [] readNextIntArray(int nElements) throws IOException {
int [] i = readIntArray(currentIndex, nElements);
currentIndex+=(SIZEOF_INT*nElements);
return i;
}
/**
* Reads an integer array of <code>nElements</code>
* starting at the current index and then increments the current
* index by <code>SIZEOF_INT * nElements</code>.
* @return the integer array starting at the current index
* @exception IOException if an I/O error occurs
*/
public int [] readNextIntArray(int nElements, int minClamp, int maxClamp, Integer... exceptions) throws IOException {
int [] i = readIntArray(currentIndex, nElements, minClamp, maxClamp, exceptions);
currentIndex+=(SIZEOF_INT*nElements);
return i;
}
/**
* Reads a long array of <code>nElements</code>
* starting at the current index and then increments the current
* index by <code>SIZEOF_LONG * nElements</code>.
* @return the long array starting at the current index
* @exception IOException if an I/O error occurs
*/
public long [] readNextLongArray(int nElements) throws IOException {
long [] l = readLongArray(currentIndex, nElements);
currentIndex+=(SIZEOF_LONG*nElements);
return l;
}
/**
* Reads a long array of <code>nElements</code>
* starting at the current index and then increments the current
* index by <code>SIZEOF_LONG * nElements</code>.
* @return the long array starting at the current index
* @exception IOException if an I/O error occurs
*/
public long [] readNextLongArray(int nElements, long minClamp, long maxClamp, Long... exceptions) throws IOException {
long [] l = readLongArray(currentIndex, nElements, minClamp, maxClamp, exceptions);
currentIndex+=(SIZEOF_LONG*nElements);
return l;
}
////////////////////////////////////////////////////////////////////
/**
* Returns a null-terminated Ascii string starting
* at <code>index</code>. The end of the string
* is denoted by a <code>null</code> character.
*
* @param index the index where the Ascii string begins
* @return the Ascii string
* @exception IOException if an I/O error occurs
*/
public String readAsciiString(long index) throws IOException {
StringBuffer buffer = new StringBuffer();
while (true) {
byte b = provider.readByte(index++);
if ((b >= 32) && (b <= 126)) {
buffer.append((char)b);
}
else {
break;
}
}
return buffer.toString().trim();
}
/**
* Returns an Ascii string of <code>length</code> bytes
* starting at <code>index</code>. This method does not
* care about null-terminators.
* @param index the index where the Ascii string begins
* @param length the length of the Ascii string
* @return the Ascii string
* @exception IOException if an I/O error occurs
*/
public String readAsciiString(long index, int length) throws IOException {
StringBuffer buffer = new StringBuffer();
for (int i = 0 ; i < length ; ++i) {
byte b = provider.readByte(index++);
buffer.append((char) (b & 0x00FF));
}
return buffer.toString().trim();
}
/**
* Returns a null-terminated Unicode string starting
* at <code>index</code>. The end of the string
* is denoted by two-byte Unicode <code>null</code> character.
* @param index the index where the Unicode string begins
* @return the Unicode string
* @exception IOException if an I/O error occurs
*/
public String readUnicodeString(long index) throws IOException {
StringBuffer buffer = new StringBuffer();
char c = 0;
int i = 0;
while (i < length()) {
c = (char)((provider.readByte(index++) & 0xff));
c += (char)((provider.readByte(index++) & 0xff) << 8);
if (c == 0x0000) {
break;
}
buffer.append(c);
i += 2;
}
return buffer.toString().trim();
}
/**
* Returns a Unicode string of <code>length</code> bytes
* starting at <code>index</code>. This method does not
* care about null-terminators.
* @param index the index where the Unicode string begins
* @param length the length of the Unicode string
* @return the Unicode string
* @exception IOException if an I/O error occurs
*/
public String readUnicodeString(long index, int length) throws IOException {
StringBuffer buffer = new StringBuffer();
char c = 0;
for (int i = 0 ; i < length*2 ; i+=2) {
c = (char)((provider.readByte(index++) & 0xff));
c += (char)((provider.readByte(index++) & 0xff) << 8);
buffer.append(c);
}
return buffer.toString().trim();
}
/**
* Returns the BYTE at <code>index<code>.
* @param index the index where the BYTE begins
* @return the BYTE
* @exception IOException if an I/O error occurs
*/
public byte readByte(long index) throws IOException {
return provider.readByte(index);
}
/**
* Returns the BYTE at <code>index</code>.
* @param index the index where the BYTE begins
* @return the BYTE
* @exception IOException if an I/O error occurs
*/
public byte readByte(long index, byte minClamp, byte maxClamp, Byte... exceptions) throws IOException {
byte b = readByte(index);
return clampByte(b, minClamp, maxClamp, exceptions);
}
/**
* Returns the SHORT at <code>index</code>.
* @param index the index where the SHORT begins
* @return the SHORT
* @exception IOException if an I/O error occurs
*/
public short readShort(long index) throws IOException {
byte [] bytes = provider.readBytes(index, SIZEOF_SHORT);
return converter.getShort(bytes);
}
/**
* Returns the SHORT at <code>index</code>.
* @param index the index where the SHORT begins
* @return the SHORT
* @exception IOException if an I/O error occurs
*/
public short readShort(long index, short minClamp, short maxClamp, Short... exceptions) throws IOException {
short s = readShort(index);
return clampShort(s, minClamp, maxClamp, exceptions);
}
/**
* Returns the INTEGER at <code>index</code>.
* @param index the index where the INTEGER begins
* @return the INTEGER
* @exception IOException if an I/O error occurs
*/
public int readInt(long index) throws IOException {
byte [] bytes = provider.readBytes(index, SIZEOF_INT);
return converter.getInt(bytes);
}
/**
* Returns the INTEGER at <code>index</code>.
* @param index the index where the INTEGER begins
* @return the INTEGER
* @exception IOException if an I/O error occurs
*/
public int readInt(long index, int minClamp, int maxClamp, Integer... exceptions) throws IOException {
int i = readInt(index);
return clampInt(i, minClamp, maxClamp, exceptions);
}
/**
* Returns the LONG at <code>index</code>.
* @param index the index where the LONG begins
* @return the LONG
* @exception IOException if an I/O error occurs
*/
public long readLong(long index) throws IOException {
byte [] bytes = provider.readBytes(index, SIZEOF_LONG);
return converter.getLong(bytes);
}
/**
* Returns the LONG at <code>index</code>.
* @param index the index where the LONG begins
* @return the LONG
* @exception IOException if an I/O error occurs
*/
public long readLong(long index, long minClamp, long maxClamp, Long... exceptions) throws IOException {
long l = readLong(index);
return clampLong(l, minClamp, maxClamp, exceptions);
}
/**
* Returns the BYTE array of <code>nElements</code>
* starting at <code>index</code>.
* @param index the index where the BYTE begins
* @param nElements the number of array elements
* @return the BYTE array
* @exception IOException if an I/O error occurs
*/
public byte [] readByteArray(long index, int nElements) throws IOException {
if (nElements < 0) {
throw new IOException("Invalid number of elements specified: "+nElements);
}
return provider.readBytes(index, nElements);
}
/**
* Returns the BYTE array of <code>nElements</code>
* starting at <code>index</code>.
* @param index the index where the BYTE begins
* @param nElements the number of array elements
* @return the BYTE array
* @exception IOException if an I/O error occurs
*/
public byte [] readByteArray(long index, int nElements, byte minClamp, byte maxClamp, Byte... exceptions) throws IOException {
byte[] array = readByteArray(index, nElements);
for (int ii = 0; ii < array.length; ++ii) {
array[ii] = clampByte(array[ii], minClamp, maxClamp, exceptions);
}
return array;
}
/**
* Returns the SHORT array of <code>nElements</code>
* starting at <code>index</code>.
* @param index the index where the SHORT begins
* @param nElements the number of array elements
* @return the SHORT array
* @exception IOException if an I/O error occurs
*/
public short [] readShortArray(long index, int nElements) throws IOException {
if (nElements < 0) {
throw new IOException("Invalid number of elements specified: "+nElements);
}
short [] arr = new short[nElements];
for (int i = 0 ; i < nElements ; ++i) {
arr[i] = readShort(index);
index += SIZEOF_SHORT;
}
return arr;
}
/**
* Returns the SHORT array of <code>nElements</code>
* starting at <code>index</code>.
* @param index the index where the SHORT begins
* @param nElements the number of array elements
* @return the SHORT array
* @exception IOException if an I/O error occurs
*/
public short [] readShortArray(long index, int nElements, short minClamp, short maxClamp, Short... exceptions) throws IOException {
short[] array = readShortArray(index, nElements);
for (int ii = 0; ii < array.length; ++ii) {
array[ii] = clampShort(array[ii], minClamp, maxClamp, exceptions);
}
return array;
}
/**
* Returns the INTEGER array of <code>nElements</code>
* starting at <code>index</code>.
* @param index the index where the INTEGER begins
* @param nElements the number of array elements
* @return the INTEGER array
* @exception IOException if an I/O error occurs
*/
public int [] readIntArray(long index, int nElements) throws IOException {
if (nElements < 0) {
throw new IOException("Invalid number of elements specified: "+nElements);
}
int [] arr = new int[nElements];
for (int i = 0 ; i < nElements ; ++i) {
arr[i] = readInt(index);
index += SIZEOF_INT;
}
return arr;
}
/**
* Returns the INTEGER array of <code>nElements</code>
* starting at <code>index</code>.
* @param index the index where the INTEGER begins
* @param nElements the number of array elements
* @return the INTEGER array
* @exception IOException if an I/O error occurs
*/
public int [] readIntArray(long index, int nElements, int minClamp, int maxClamp, Integer... exceptions) throws IOException {
int[] array = readIntArray(index, nElements);
for (int ii = 0; ii < array.length; ++ii) {
array[ii] = clampInt(array[ii], minClamp, maxClamp, exceptions);
}
return array;
}
/**
* Returns the LONG array of <code>nElements</code>
* starting at <code>index</code>.
* @param index the index where the LONG begins
* @param nElements the number of array elements
* @return the LONG array
* @exception IOException if an I/O error occurs
*/
public long [] readLongArray(long index, int nElements) throws IOException {
if (nElements < 0) {
throw new IOException("Invalid number of elements specified: "+nElements);
}
long [] arr = new long[nElements];
for (int i = 0 ; i < nElements ; ++i) {
arr[i] = readLong(index);
index += SIZEOF_LONG;
}
return arr;
}
/**
* Returns the LONG array of <code>nElements</code>
* starting at <code>index</code>.
* @param index the index where the LONG begins
* @param nElements the number of array elements
* @return the LONG array
* @exception IOException if an I/O error occurs
*/
public long [] readLongArray(long index, int nElements, long minClamp, long maxClamp, Long... exceptions) throws IOException {
long[] array = readLongArray(index, nElements);
for (int ii = 0; ii < array.length; ++ii) {
array[ii] = clampLong(array[ii], minClamp, maxClamp, exceptions);
}
return array;
}
/**
* Returns the Ascii string array of <code>nElements</code>
* starting at <code>index</code>
* @param index the index where the Ascii Strings begin
* @param nElements the number of array elements
* @return the Ascii String array
* @exception IOException if an I/O error occurs
*/
public String [] readAsciiStringArray(long index, int nElements) throws IOException {
if (nElements < 0) {
throw new IOException("Invalid number of elements specified: "+nElements);
}
String [] arr = new String[nElements];
for (int i = 0 ; i < nElements ; ++i) {
String tmp = readAsciiString(index);
arr[i] = tmp;
index += (tmp == null ? 1 : tmp.length());
}
return arr;
}
/**
* Writes the specified byte at the specified index.
* @param index the index where the byte should be written
* @param value the byte value to be written
* @exception IOException if an I/O error occurs
*/
public void writeByte(long index, byte value) throws IOException {
provider.writeByte(index, value);
}
/**
* Writes the specified short at the specified index.
* @param index the index where the short should be written
* @param value the short value to be written
* @exception IOException if an I/O error occurs
*/
public void writeShort(long index, short value) throws IOException {
byte [] bytes = converter.getBytes(value);
provider.writeBytes(index, bytes);
}
/**
* Writes the specified int at the specified index.
* @param index the index where the int should be written
* @param value the int value to be written
* @exception IOException if an I/O error occurs
*/
public void writeInt(long index, int value) throws IOException {
byte [] bytes = converter.getBytes(value);
provider.writeBytes(index, bytes);
}
/**
* Writes the specified long at the specified index.
* @param index the index where the long should be written
* @param value the long value to be written
* @exception IOException if an I/O error occurs
*/
public void writeLong(long index, long value) throws IOException {
byte [] bytes = converter.getBytes(value);
provider.writeBytes(index, bytes);
}
/**
* Returns the underlying byte provider.
* @return the underlying byte provider
*/
public GByteProvider getByteProvider() {
return provider;
}
protected byte clampByte(byte b, byte minClamp, byte maxClamp, Byte... exceptions) {
if (maxClamp < minClamp) {
throw new IllegalArgumentException("maxClamp < minClamp not allowed");
}
if (exceptions != null) {
if (exceptions.length % 2 != 0) {
throw new IllegalArgumentException("exceptions must be pairs of (flag, replacement) bytes");
}
}
boolean clamp = true;
if (exceptions != null) {
for (int ii = 0; ii < exceptions.length; ii += 2) {
if (b == exceptions[ii]) {
b = exceptions[ii+1];
clamp = false;
break;
}
}
}
if (clamp) {
if (b < minClamp) {
b = minClamp;
} else if (b > maxClamp) {
b = maxClamp;
}
}
return b;
}
protected short clampShort(short s, short minClamp, short maxClamp, Short... exceptions) {
if (maxClamp < minClamp) {
throw new IllegalArgumentException("maxClamp < minClamp not allowed");
}
if (exceptions != null) {
if (exceptions.length % 2 != 0) {
throw new IllegalArgumentException("exceptions must be pairs of (flag, replacement) shorts");
}
}
boolean clamp = true;
if (exceptions != null) {
for (int ii = 0; ii < exceptions.length; ii += 2) {
if (s == exceptions[ii]) {
s = exceptions[ii+1];
clamp = false;
break;
}
}
}
if (clamp) {
if (s < minClamp) {
s = minClamp;
} else if (s > maxClamp) {
s = maxClamp;
}
}
return s;
}
protected int clampInt(int i, int minClamp, int maxClamp, Integer... exceptions) {
if (maxClamp < minClamp) {
throw new IllegalArgumentException("maxClamp < minClamp not allowed");
}
if (exceptions != null) {
if (exceptions.length % 2 != 0) {
throw new IllegalArgumentException("exceptions must be pairs of (flag, replacement) ints");
}
}
boolean clamp = true;
if (exceptions != null) {
for (int ii = 0; ii < exceptions.length; ii += 2) {
if (i == exceptions[ii]) {
i = exceptions[ii+1];
clamp = false;
break;
}
}
}
if (clamp) {
if (i < minClamp) {
i = minClamp;
} else if (i > maxClamp) {
i = maxClamp;
}
}
return i;
}
protected long clampLong(long l, long minClamp, long maxClamp, Long... exceptions) {
if (maxClamp < minClamp) {
throw new IllegalArgumentException("maxClamp < minClamp not allowed");
}
if (exceptions != null) {
if (exceptions.length % 2 != 0) {
throw new IllegalArgumentException("exceptions must be pairs of (flag, replacement) longs");
}
}
boolean clamp = true;
if (exceptions != null) {
for (int ii = 0; ii < exceptions.length; ii += 2) {
if (l == exceptions[ii]) {
l = exceptions[ii+1];
clamp = false;
break;
}
}
}
if (clamp) {
if (l < minClamp) {
l = minClamp;
} else if (l > maxClamp) {
l = maxClamp;
}
}
return l;
}
}

View File

@ -0,0 +1,126 @@
/* ###
* IP: Public Domain
*/
package mobiledevices.dmg.ghidra;
import java.io.*;
/**
* An implementation of ByteProvider where the underlying
* bytes are supplied by a random access file.
*/
public class GByteProvider implements Closeable {
private File file;
private GRandomAccessFile randomAccessFile;
/**
* Constructs a byte provider using the specified file
* @param file the file to open for random access
* @throws FileNotFoundException if the file does not exist
*/
public GByteProvider(File file) throws IOException {
this.file = file;
this.randomAccessFile = new GRandomAccessFile(file, "r");
}
/**
* Constructs a byte provider using the specified file and permissions string
* @param file the file to open for random access
* @param string indicating permissions used for open
* @throws FileNotFoundException if the file does not exist
*/
public GByteProvider(File file, String permissions) throws IOException {
this.file = file;
this.randomAccessFile = new GRandomAccessFile(file, permissions);
}
/**
* @see GByteProvider.app.util.bin.ByteProvider#getFile()
*/
public File getFile() {
return file;
}
/**
* @see GByteProvider.app.util.bin.ByteProvider#getName()
*/
public String getName() {
return file.getName();
}
public String getAbsolutePath() {
return file.getAbsolutePath();
}
/**
* @see GByteProvider.app.util.bin.ByteProvider#getInputStream(long)
*/
public InputStream getInputStream(long index) throws IOException {
FileInputStream is = new FileInputStream(file);
is.skip(index);
return is;
}
/**
* Closes the underlying random-access file.
* @throws IOException if an I/O error occurs
*/
@Override
public void close() throws IOException {
randomAccessFile.close();
}
/**
* @see GByteProvider.app.util.bin.ByteProvider#length()
*/
public long length() throws IOException {
return randomAccessFile.length();
}
public boolean isValidIndex(long index) {
try {
return index >= 0 && index < randomAccessFile.length();
}
catch (IOException e) {
}
return false;
}
/**
* @see GByteProvider.app.util.bin.ByteProvider#readByte(long)
*/
public byte readByte(long index) throws IOException {
randomAccessFile.seek(index);
return randomAccessFile.readByte();
}
/**
* @see GByteProvider.app.util.bin.ByteProvider#readBytes(long, long)
*/
public byte [] readBytes(long index, long length) throws IOException {
randomAccessFile.seek(index);
byte [] b = new byte[(int)length];
int nRead = randomAccessFile.read(b);
if (nRead != length) {
throw new IOException("Unable to read "+length+" bytes");
}
return b;
}
/**
* @see GByteProvider.app.util.bin.ByteProvider#writeByte(long, byte)
*/
public void writeByte(long index, byte value) throws IOException {
randomAccessFile.seek(index);
randomAccessFile.write(value);
}
/**
* @see GByteProvider.app.util.bin.ByteProvider#writeBytes(long, byte[])
*/
public void writeBytes(long index, byte [] values) throws IOException {
randomAccessFile.seek(index);
randomAccessFile.write(values);
}
}

View File

@ -0,0 +1,136 @@
/* ###
* IP: Public Domain
*/
package mobiledevices.dmg.ghidra;
/**
* Helper methods for converting between
* number data types without negative
* promotion.
*
*
*/
public class GConv {
private GConv() {
}
/**
* A byte mask.
*/
public static final int BYTE_MASK = 0xff;
/**
* A short mask.
*/
public static final int SHORT_MASK = 0xffff;
/**
* An integer mask.
*/
public static final long INT_MASK = 0x00000000ffffffffL;
/**
* Converts a byte to a short.
* @param b the byte
* @return the short equivalent of the byte
*/
public static short byteToShort(byte b) {
return (short)(b & BYTE_MASK);
}
/**
* Converts a byte to an integer.
* @param b the byte
* @return the integer equivalent of the byte
*/
public static int byteToInt(byte b) {
return (b & BYTE_MASK);
}
/**
* Converts a byte to a long.
* @param b the byte
* @return the long equivalent of the byte
*/
public static long byteToLong(byte b) {
return intToLong(b & BYTE_MASK);
}
/**
* Converts a short to an integer.
* @param s the short
* @return the integer equivalent of the short
*/
public static int shortToInt(short s) {
return (s & SHORT_MASK);
}
/**
* Converts a short to a long.
* @param s the short
* @return the long eqivalent of the short
*/
public static long shortToLong(short s) {
return intToLong(s & SHORT_MASK);
}
/**
* Converts an integer to a long.
* @param i the integer
* @return the long equivalent of the long
*/
public static long intToLong(int i) {
return (i & INT_MASK);
}
public static String toString(byte [] array) {
StringBuffer buffer = new StringBuffer();
for (byte b : array) {
buffer.append((char)b);
}
return buffer.toString();
}
/**
* Converts a byte into a padded hex string.
* @param b the byte
* @return the padded hex string
*/
public static String toHexString(byte b) {
return zeropad(Integer.toHexString(byteToInt(b)), 2);
}
/**
* Converts a short into a padded hex string.
* @param s the short
* @return the padded hex string
*/
public static String toHexString(short s) {
return zeropad(Integer.toHexString(shortToInt(s)), 4);
}
/**
* Converts an integer into a padded hex string.
* @param i the integer
* @return the padded hex string
*/
public static String toHexString(int i) {
return zeropad(Integer.toHexString(i), 8);
}
/**
* Converts a long into a padded hex string.
* @param l the long
* @return the padded hex string
*/
public static String toHexString(long l) {
return zeropad(Long.toHexString(l), 16);
}
/**
* Returns a string that is extended to
* length len with zeroes.
* @param s The string to pad
* @param len The length of the return string
* @return A string that has been padded to be of legnth len
*/
public static String zeropad(String s, int len) {
if (s == null) s = "";
StringBuffer buffer = new StringBuffer(s);
int zerosNeeded = len - s.length();
for (int i = 0 ; i < zerosNeeded ; ++i) {
buffer.insert(0, '0');
}
return buffer.toString();
}
}

View File

@ -0,0 +1,218 @@
/* ###
* IP: Public Domain
*/
package mobiledevices.dmg.ghidra;
import java.io.Serializable;
/**
*
* Defines methods to convert byte arrays to a specific primitive Java types,
* and to populate byte arrays from primitive Java types.
*
*
*/
public interface GDataConverter extends Serializable {
/**
* Get the short value from the given byte array.
* @param b array containing bytes
* @throws IndexOutOfBoundsException if byte array size is
* less than 2.
*/
public short getShort(byte[] b);
/**
* Get the short value from the given byte array.
* @param b array containing bytes
* @param offset offset into byte array for getting the short
* @throws IndexOutOfBoundsException if byte array size is
* less than offset+2.
*/
public short getShort(byte[] b, int offset);
/**
* Get the int value from the given byte array.
* @param b array containing bytes
* @throws IndexOutOfBoundsException if byte array size is
* less than 4.
*/
public int getInt(byte[] b);
/**
* Get the int value from the given byte array.
* @param b array containing bytes
* @param offset offset into byte array for getting the int
* @throws IndexOutOfBoundsException if byte array size is
* less than offset+4.
*/
public int getInt(byte[] b, int offset);
/**
* Get the long value from the given byte array.
* @param b array containing bytes
* @throws IndexOutOfBoundsException if byte array size is
* less than 8.
*/
public long getLong(byte[] b);
/**
* Get the long value from the given byte array.
* @param b array containing bytes
* @param offset offset into byte array for getting the long
* @throws IndexOutOfBoundsException if byte array size is
* less than offset+8.
*/
public long getLong(byte[] b, int offset);
/**
* Get the value from the given byte array using the specified size.
* @param b array containing bytes
* @param size number of bytes to use from array at offset 0
* @throws IndexOutOfBoundsException if byte array size is
* less than size.
*/
public long getValue(byte[] b, int size);
/**
* Get the value from the given byte array using the specified size.
* @param b array containing bytes
* @param size number of bytes to use from array
* @param offset offset into byte array for getting the long
* @throws IndexOutOfBoundsException if byte array size is
* less than offset+size or size is greater than 8 (sizeof long).
*/
public long getValue(byte[] b, int offset, int size);
/**
* Converts the given value to bytes.
* @param value value to convert to bytes
* @param b byte array to store bytes
* @throws IndexOutOfBoundsException if b.length is not at least
* 2.
*/
public void getBytes(short value, byte[] b);
/**
* Converts the given value to bytes.
* @param value value to convert to bytes
* @param b byte array to store bytes
* @param offset offset into byte array to put the bytes
* @throws IndexOutOfBoundsException if (offset+2)>b.length
*/
public void getBytes(short value, byte[] b, int offset);
/**
* Converts the given value to bytes.
* @param value value to convert to bytes
* @param b byte array to store bytes
* @throws IndexOutOfBoundsException if b.length is not at least
* 4.
*/
public void getBytes(int value, byte[] b);
/**
* Converts the given value to bytes.
* @param value value to convert to bytes
* @param b byte array to store bytes
* @param offset offset into byte array to put the bytes
* @throws IndexOutOfBoundsException if (offset+4)>b.length
*/
public void getBytes(int value, byte[] b, int offset);
/**
* Converts the given value to bytes.
* @param value value to convert to bytes
* @param b byte array to store bytes
* @throws IndexOutOfBoundsException if b.length is not at least
* 8.
*/
public void getBytes(long value, byte[] b);
/**
* Converts the given value to bytes.
* @param value value to convert to bytes
* @param b byte array to store bytes
* @param offset offset into byte array to put the bytes
* @throws IndexOutOfBoundsException if (offset+8)>b.length
*/
public void getBytes(long value, byte[] b, int offset);
/**
* Converts the given value to bytes using the number of least significant bytes
* specified by size.
* @param value value to convert to bytes
* @param size number of least significant bytes of value to be written to the byte array
* @param b byte array to store bytes
* @param offset offset into byte array to put the bytes
* @throws IndexOutOfBoundsException if (offset+size)>b.length.
*/
public void getBytes(long value, int size, byte[] b, int offset);
/**
* Converts the short value to an array of bytes.
* @param value short value to be converted
* @return array of bytes
*/
public byte[] getBytes(short value);
/**
* Converts the int value to an array of bytes.
* @param value int value to be converted
* @return array of bytes
*/
public byte[] getBytes(int value);
/**
* Converts the long value to an array of bytes.
* @param value long value to be converted
* @return array of bytes
*/
public byte[] getBytes(long value);
/**
* Writes a short value into a byte array.
* @param b array to contain the bytes;
* @param value the short value
*/
public void putShort(byte[] b, short value);
/**
* Writes a short value into the byte array at the given offset
* @param b array to contain the bytes;
* @param offset the offset into the byte array to store the value.
* @param value the short value
*/
public void putShort(byte[] b, int offset, short value);
/**
* Writes a int value into a byte array.
* @param b array to contain the bytes;
* @param value the int value
*/
public void putInt(byte[] b, int value);
/**
* Writes a int value into the byte array at the given offset
* @param b array to contain the bytes;
* @param offset the offset into the byte array to store the value.
* @param value the int value
*/
public void putInt(byte[] b, int offset, int value);
/**
* Writes a long value into a byte array.
* @param b array to contain the bytes;
* @param value the long value
*/
public void putLong(byte[] b, long value);
/**
* Writes a long value into the byte array at the given offset
* @param b array to contain the bytes;
* @param offset the offset into the byte array to store the value.
* @param value the long value
*/
public void putLong(byte[] b, int offset, long value);
}

View File

@ -0,0 +1,224 @@
/* ###
* IP: Public Domain
*/
package mobiledevices.dmg.ghidra;
/**
* Helper class to convert a byte array to Java primitives and primitives to a
* byte array in Big endian.
*
*
*
*/
public class GDataConverterBE implements GDataConverter {
public static final GDataConverterBE INSTANCE = new GDataConverterBE();
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* Constructor for BigEndianDataConverter.
*/
public GDataConverterBE() {
}
/**
* @see GDataConverter#getShort(byte[])
*/
public final short getShort(byte[] b) {
return getShort(b, 0);
}
/**
* @see GDataConverter#getShort(byte[], int)
*/
public short getShort(byte[] b, int offset) {
return (short) (((b[offset] & 0xff) << 8) | (b[offset + 1] & 0xff));
}
/**
* @see GDataConverter#getInt(byte[])
*/
public final int getInt(byte[] b) {
return getInt(b, 0);
}
/**
* @see GDataConverter#getInt(byte[], int)
*/
public int getInt(byte[] b, int offset) {
int v = b[offset];
for (int i = 1; i < 4; i++) {
v = (v << 8) | (b[offset + i] & 0xff);
}
return v;
}
/**
* @see GDataConverter#getLong(byte[])
*/
public final long getLong(byte[] b) {
return getLong(b, 0);
}
/**
* @see GDataConverter#getLong(byte[], int)
*/
public long getLong(byte[] b, int offset) {
long v = b[offset];
for (int i = 1; i < 8; i++) {
v = (v << 8) | (b[offset + i] & 0xff);
}
return v;
}
/**
* @see GDataConverter.util.DataConverter#getValue(byte[], int)
*/
public long getValue(byte[] b, int size) {
return getValue(b, 0, size);
}
/**
* @see GDataConverter.util.DataConverter#getValue(byte[], int, int)
*/
public long getValue(byte[] b, int offset, int size) {
if (size > 8) {
throw new IndexOutOfBoundsException("size exceeds sizeof long: " + size);
}
long val = 0;
for (int i = 0; i < size; i++) {
val = (val << 8) | (b[offset + i] & 0xff);
}
return val;
}
/**
* @see GDataConverter#getBytes(short, byte[])
*/
public final void getBytes(short value, byte[] b) {
getBytes(value, b, 0);
}
/**
* @see GDataConverter#getBytes(short, byte[], int)
*/
public void getBytes(short value, byte[] b, int offset) {
b[offset] = (byte) (value >> 8);
b[offset + 1] = (byte) (value & 0xff);
}
/**
* @see GDataConverter#getBytes(int, byte[])
*/
public final void getBytes(int value, byte[] b) {
getBytes(value, b, 0);
}
/**
* @see GDataConverter#getBytes(int, byte[], int)
*/
public void getBytes(int value, byte[] b, int offset) {
b[offset + 3] = (byte) (value);
for (int i = 2; i >= 0; i--) {
value >>= 8;
b[offset + i] = (byte) (value);
}
}
/**
* @see GDataConverter#getBytes(long, byte[])
*/
public final void getBytes(long value, byte[] b) {
getBytes(value, 8, b, 0);
}
/**
* @see GDataConverter#getBytes(long, byte[], int)
*/
public void getBytes(long value, byte[] b, int offset) {
getBytes(value, 8, b, offset);
}
/**
* @see GDataConverter.util.DataConverter#getBytes(long, int, byte[], int)
*/
public void getBytes(long value, int size, byte[] b, int offset) {
for (int i = size - 1; i >= 0; i--) {
b[offset + i] = (byte) value;
value >>= 8;
}
}
/**
* @see GDataConverter.util.DataConverter#putInt(byte[], int, int)
*/
public final void putInt(byte[] b, int offset, int value) {
getBytes(value, b, offset);
}
/**
* @see GDataConverter.util.DataConverter#putInt(byte[], int)
*/
public final void putInt(byte[] b, int value) {
getBytes(value, b);
}
/**
* @see GDataConverter.util.DataConverter#putLong(byte[], int, long)
*/
public final void putLong(byte[] b, int offset, long value) {
getBytes(value, b, offset);
}
/**
* @see GDataConverter.util.DataConverter#putLong(byte[], long)
*/
public final void putLong(byte[] b, long value) {
getBytes(value, b);
}
/**
* @see GDataConverter.util.DataConverter#putShort(byte[], int, short)
*/
public final void putShort(byte[] b, int offset, short value) {
getBytes(value, b, offset);
}
/**
* @see GDataConverter.util.DataConverter#putShort(byte[], short)
*/
public final void putShort(byte[] b, short value) {
getBytes(value, b);
}
/**
* @see GDataConverter.util.DataConverter#getBytes(int)
*/
public byte[] getBytes(int value) {
byte[] bytes = new byte[4];
getBytes(value, bytes);
return bytes;
}
/**
* @see GDataConverter.util.DataConverter#getBytes(long)
*/
public byte[] getBytes(long value) {
byte[] bytes = new byte[8];
getBytes(value, bytes);
return bytes;
}
/**
* @see GDataConverter.util.DataConverter#getBytes(short)
*/
public byte[] getBytes(short value) {
byte[] bytes = new byte[2];
getBytes(value, bytes);
return bytes;
}
}

View File

@ -0,0 +1,222 @@
/* ###
* IP: Public Domain
*/
package mobiledevices.dmg.ghidra;
/**
*
* Helper class to convert a byte array to a Java primitive in Little endian
* order, and to convert a primitive to a byte array.
*/
public class GDataConverterLE implements GDataConverter {
public static GDataConverterLE INSTANCE = new GDataConverterLE();
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* Constructor for BigEndianDataConverter.
*/
public GDataConverterLE() {
}
/**
* @see GDataConverter#getShort(byte[])
*/
public final short getShort(byte[] b) {
return getShort(b, 0);
}
/**
* @see GDataConverter#getShort(byte[], int)
*/
public short getShort(byte[] b, int offset) {
return (short) (((b[offset + 1] & 0xff) << 8) | (b[offset] & 0xff));
}
/**
* @see GDataConverter#getInt(byte[])
*/
public final int getInt(byte[] b) {
return getInt(b, 0);
}
/**
* @see GDataConverter#getInt(byte[], int)
*/
public int getInt(byte[] b, int offset) {
int v = b[offset + 3];
for (int i = 2; i >= 0; i--) {
v = (v << 8) | (b[offset + i] & 0xff);
}
return v;
}
/**
* @see GDataConverter#getLong(byte[])
*/
public final long getLong(byte[] b) {
return getLong(b, 0);
}
/**
* @see GDataConverter#getLong(byte[], int)
*/
public long getLong(byte[] b, int offset) {
long v = b[offset + 7];
for (int i = 6; i >= 0; i--) {
v = (v << 8) | (b[offset + i] & 0xff);
}
return v;
}
/**
* @see ghidra.util.GDataConverter#getValue(byte[], int)
*/
public long getValue(byte[] b, int size) {
return getValue(b, 0, size);
}
/**
* @see ghidra.util.GDataConverter#getValue(byte[], int, int)
*/
public long getValue(byte[] b, int offset, int size) {
if (size > 8) {
throw new IndexOutOfBoundsException("size exceeds sizeof long: " + size);
}
long val = 0;
for (int i = size - 1; i >= 0; i--) {
val = (val << 8) | (b[offset + i] & 0xff);
}
return val;
}
/**
* @see GDataConverter#getBytes(short, byte[])
*/
public final void getBytes(short value, byte[] b) {
getBytes(value, b, 0);
}
/**
* @see GDataConverter#getBytes(short, byte[], int)
*/
public void getBytes(short value, byte[] b, int offset) {
b[offset + 1] = (byte) (value >> 8);
b[offset] = (byte) (value & 0xff);
}
/**
* @see GDataConverter#getBytes(int, byte[])
*/
public final void getBytes(int value, byte[] b) {
getBytes(value, b, 0);
}
/**
* @see GDataConverter#getBytes(int, byte[], int)
*/
public void getBytes(int value, byte[] b, int offset) {
b[offset] = (byte) (value);
for (int i = 1; i < 4; i++) {
value >>= 8;
b[offset + i] = (byte) (value);
}
}
/**
* @see GDataConverter#getBytes(long, byte[])
*/
public final void getBytes(long value, byte[] b) {
getBytes(value, 8, b, 0);
}
/**
* @see GDataConverter#getBytes(long, byte[], int)
*/
public void getBytes(long value, byte[] b, int offset) {
getBytes(value, 8, b, offset);
}
/**
* @see ghidra.util.GDataConverter#getBytes(long, int, byte[], int)
*/
public void getBytes(long value, int size, byte[] b, int offset) {
for (int i = 0; i < size; i++) {
b[offset + i] = (byte) value;
value >>= 8;
}
}
/**
* @see ghidra.util.GDataConverter#putInt(byte[], int, int)
*/
public final void putInt(byte[] b, int offset, int value) {
getBytes(value, b, offset);
}
/**
* @see ghidra.util.GDataConverter#putInt(byte[], int)
*/
public final void putInt(byte[] b, int value) {
getBytes(value, b);
}
/**
* @see ghidra.util.GDataConverter#putLong(byte[], int, long)
*/
public final void putLong(byte[] b, int offset, long value) {
getBytes(value, b, offset);
}
/**
* @see ghidra.util.GDataConverter#putLong(byte[], long)
*/
public final void putLong(byte[] b, long value) {
getBytes(value, b);
}
/**
* @see ghidra.util.GDataConverter#putShort(byte[], int, short)
*/
public final void putShort(byte[] b, int offset, short value) {
getBytes(value, b, offset);
}
/**
* @see ghidra.util.GDataConverter#putShort(byte[], short)
*/
public final void putShort(byte[] b, short value) {
getBytes(value, b);
}
/**
* @see ghidra.util.GDataConverter#getBytes(int)
*/
public byte[] getBytes(int value) {
byte[] bytes = new byte[4];
getBytes(value, bytes);
return bytes;
}
/**
* @see ghidra.util.GDataConverter#getBytes(long)
*/
public byte[] getBytes(long value) {
byte[] bytes = new byte[8];
getBytes(value, bytes);
return bytes;
}
/**
* @see ghidra.util.GDataConverter#getBytes(short)
*/
public byte[] getBytes(short value) {
byte[] bytes = new byte[2];
getBytes(value, bytes);
return bytes;
}
}

View File

@ -0,0 +1,63 @@
/* ###
* IP: Public Domain
*/
package mobiledevices.dmg.ghidra;
import java.io.*;
public final class GFileUtilityMethods {
private static final String GHIDRA_FILE_SYSTEM_PREFIX = "ghidra_file_system_";
private static final String GHIDRA_FILE_SYSTEM_SUFFIX = ".tmp";
public final static File writeTemporaryFile( InputStream inputStream ) throws IOException {
return writeTemporaryFile( inputStream , Integer.MAX_VALUE );
}
public final static File writeTemporaryFile( InputStream inputStream, int maxBytesToWrite ) throws IOException {
File tempOutputFile = File.createTempFile( GHIDRA_FILE_SYSTEM_PREFIX, GHIDRA_FILE_SYSTEM_SUFFIX );
tempOutputFile.deleteOnExit();
OutputStream outputStream = new FileOutputStream( tempOutputFile );
try {
int nWritten = 0;
byte [] buffer = new byte[ 8192 ];
while ( true ) {
int nRead = inputStream.read( buffer );
if ( nRead == -1 ) {
break;
}
outputStream.write( buffer, 0, nRead );
nWritten += nRead;
if ( nWritten >= maxBytesToWrite ) {
break;
}
}
}
finally {
outputStream.close();
}
return tempOutputFile;
}
public final static File writeTemporaryFile( byte [] bytes, String prefix ) throws IOException {
if ( prefix == null ) {
prefix = GHIDRA_FILE_SYSTEM_PREFIX;
}
if ( prefix.length() < 3 ) {//temp file prefix must be at least 3 chars in length
for ( int i = prefix.length() ; i < 3 ; ++i ) {
prefix = prefix + '_';
}
}
File tempFile = File.createTempFile( prefix , GHIDRA_FILE_SYSTEM_SUFFIX );
tempFile.deleteOnExit();
OutputStream tempFileOut = new FileOutputStream( tempFile );
try {
tempFileOut.write( bytes );
}
finally {
tempFileOut.close();
}
return tempFile;
}
}

View File

@ -0,0 +1,306 @@
/* ###
* IP: Public Domain
*/
package mobiledevices.dmg.ghidra;
import java.io.*;
/**
* Instances of this class support both reading and writing to a
* random access file. A random access file behaves like a large
* array of bytes stored in the file system. There is a kind of cursor,
* or index into the implied array, called the <em>file pointer</em>.
* This implementation relies on java.net.RandomAccessFile,
* but adds buffering to limit the amount.
*/
public class GRandomAccessFile {
private static final byte[] EMPTY = new byte[0];
private static final int BUFFER_SIZE = 0x100000;
private File file;
private RandomAccessFile randomAccessFile;
private byte[] buffer = EMPTY;
private long bufferOffset = 0;
private long bufferFileStartIndex = 0;
private byte[] lastbuffer = EMPTY;
private long lastbufferOffset = 0;
private long lastbufferFileStartIndex = 0;
private boolean open = false;
private void checkOpen() throws IOException {
if (!open) {
throw new IOException("GhidraRandomAccessFile is closed");
}
}
/**
* Creates a random access file stream to read from, and optionally to
* write to, the file specified by the {@link File} argument. A new {@link
* FileDescriptor} object is created to represent this file connection.
*
* <p>
* This implementation relies on java.net.RandomAccessFile,
* but adds buffering to limit the amount.
* <p>
*
* <a name="mode"><p> The <tt>mode</tt> argument specifies the access mode
* in which the file is to be opened. The permitted values and their
* meanings are:
*
* <blockquote><table summary="Access mode permitted values and meanings">
* <tr><th><p align="left">Value</p></th><th><p align="left">Meaning</p></th></tr>
* <tr><td valign="top"><tt>"r"</tt></td>
* <td> Open for reading only. Invoking any of the <tt>write</tt>
* methods of the resulting object will cause an {@link
* java.io.IOException} to be thrown. </td></tr>
* <tr><td valign="top"><tt>"rw"</tt></td>
* <td> Open for reading and writing. If the file does not already
* exist then an attempt will be made to create it. </td></tr>
* <tr><td valign="top"><tt>"rws"</tt></td>
* <td> Open for reading and writing, as with <tt>"rw"</tt>, and also
* require that every update to the file's content or metadata be
* written synchronously to the underlying storage device. </td></tr>
* <tr><td valign="top"><tt>"rwd"&nbsp;&nbsp;</tt></td>
* <td> Open for reading and writing, as with <tt>"rw"</tt>, and also
* require that every update to the file's content be written
* synchronously to the underlying storage device. </td></tr>
* </table></blockquote>
*
* @param file the file object
* @param mode the access mode, as described
* <a href="#mode">above</a>
* @exception IllegalArgumentException if the mode argument is not equal
* to one of <tt>"r"</tt>, <tt>"rw"</tt>, <tt>"rws"</tt>, or
* <tt>"rwd"</tt>
* @exception FileNotFoundException
* that name cannot be created, or if some other error occurs
* while opening or creating the file
*/
public GRandomAccessFile(File file, String mode) throws IOException {
this.file = file;
randomAccessFile = new RandomAccessFile(file, mode);
this.open = true;
}
@Override
protected void finalize() {
if (open) {
//TODO Msg.warn(this, "FAIL TO CLOSE " + file);
}
}
/**
* Closes this random access file stream and releases any system
* resources associated with the stream. A closed random access
* file cannot perform input or output operations and cannot be
* reopened.
* <p>
* If this file has an associated channel then the channel is closed as well.
* @exception IOException if an I/O error occurs.
*/
public void close() throws IOException {
checkOpen();
open = false;
randomAccessFile.close();
}
/**
* Returns the length of this file.
* @return the length of this file, measured in bytes.
* @exception IOException if an I/O error occurs.
*/
public long length() throws IOException {
checkOpen();
return randomAccessFile.length();
}
/**
* Sets the file-pointer offset, measured from the beginning of this
* file, at which the next read or write occurs. The offset may be
* set beyond the end of the file. Setting the offset beyond the end
* of the file does not change the file length. The file length will
* change only by writing after the offset has been set beyond the end
* of the file.
* @param pos the offset position, measured in bytes from the
* beginning of the file, at which to set the file
* pointer.
* @throws IOException
* @exception IOException if <code>pos</code> is less than
* <code>0</code> or if an I/O error occurs.
*/
public void seek(long pos) throws IOException {
checkOpen();
if (pos < 0) {
throw new IOException("pos cannot be less than zero");
}
if (pos < bufferFileStartIndex || pos >= bufferFileStartIndex + BUFFER_SIZE) {
// check if the last buffer contained it, and swap in if necessary
swapInLast();
if (pos < bufferFileStartIndex || pos >= bufferFileStartIndex + BUFFER_SIZE) {
// not in either, gotta get a new one
buffer = EMPTY;
bufferOffset = 0;
bufferFileStartIndex = pos;
}
}
bufferOffset = pos - bufferFileStartIndex;
}
/**
* This method reads a byte from the file, starting from the current file pointer.
* <p>
* This method blocks until the byte is read, the end of the stream
* is detected, or an exception is thrown.
*
* @return the next byte of this file as a signed eight-bit
* <code>byte</code>.
* @exception EOFException if this file has reached the end.
* @exception IOException if an I/O error occurs.
*/
public byte readByte() throws IOException {
checkOpen();
ensure(1);
return buffer[(int) bufferOffset];
}
/**
* Reads up to <code>b.length</code> bytes of data from this file
* into an array of bytes. This method blocks until at least one byte
* of input is available.
*
* @param b the buffer into which the data is read.
* @return the total number of bytes read into the buffer, or
* <code>-1</code> if there is no more data because the end of
* this file has been reached.
* @exception IOException if an I/O error occurs.
*/
public int read(byte[] b) throws IOException {
checkOpen();
return read(b, 0, b.length);
}
/**
* Reads up to <code>len</code> bytes of data from this file into an
* array of bytes. This method blocks until at least one byte of input
* is available.
*
* @param b the buffer into which the data is read.
* @param off the start offset of the data.
* @param len the maximum number of bytes read.
* @return the total number of bytes read into the buffer, or
* <code>-1</code> if there is no more data because the end of
* the file has been reached.
* @exception IOException if an I/O error occurs.
*/
public int read(byte[] b, int offset, int length) throws IOException {
checkOpen();
int readLen = length;
do {
int blocklength = readLen;
if (readLen > (BUFFER_SIZE - bufferOffset)) {
blocklength = (BUFFER_SIZE - (int) bufferOffset);
if (blocklength <= 0) {
blocklength = BUFFER_SIZE;
}
}
ensure(blocklength);
System.arraycopy(buffer, (int) bufferOffset, b, offset, blocklength);
readLen -= blocklength;
offset += blocklength;
if (readLen > 0) {
seek(this.bufferFileStartIndex + bufferOffset + blocklength);
}
}
while (readLen > 0);
return length;
}
/**
* Writes a byte to this file, starting at the current file pointer.
* @param b the data.
* @exception IOException if an I/O error occurs.
*/
public void write(byte b) throws IOException {
checkOpen();
write(new byte[] { b }, 0, 1);
}
/**
* Writes <code>b.length</code> bytes from the specified byte array
* to this file, starting at the current file pointer.
* @param b the data.
* @exception IOException if an I/O error occurs.
*/
public void write(byte[] b) throws IOException {
checkOpen();
write(b, 0, b.length);
}
/**
* Writes a sub array as a sequence of bytes.
* @param b the data to be written
* @param offset the start offset in the data
* @param length the number of bytes that are written
* @exception IOException If an I/O error has occurred.
*/
public void write(byte[] b, int offset, int length) throws IOException {
checkOpen();
randomAccessFile.write(b, offset, length);
buffer = EMPTY;
bufferOffset = 0;
lastbuffer = EMPTY;
lastbufferOffset = 0;
}
/**
* Ensures that enough bytes are cached to
* satisfy the next request to read.
*/
private void ensure(int bytesNeeded) throws IOException {
checkOpen();
long oldFileStartIndex = bufferFileStartIndex;
long oldBufferOffset = bufferOffset;
long oldSeekPos = oldFileStartIndex + oldBufferOffset;
if (bufferOffset + bytesNeeded > buffer.length) {
// check if the last buffer contained it, and swap in if necessary
swapInLast();
// must ensure that current read pos is in old buffer, and enough bytes
long newBufferOffset = (oldSeekPos - bufferFileStartIndex);
if (oldSeekPos < bufferFileStartIndex ||
oldSeekPos >= bufferFileStartIndex + BUFFER_SIZE ||
(newBufferOffset + bytesNeeded > buffer.length)) {
bufferFileStartIndex = oldFileStartIndex + oldBufferOffset;
buffer = new byte[BUFFER_SIZE];
randomAccessFile.seek(bufferFileStartIndex);
randomAccessFile.read(buffer);
bufferOffset = 0;
}
else {
bufferOffset = newBufferOffset;
}
}
}
private void swapInLast() throws IOException {
checkOpen();
if (buffer == EMPTY) {
return;
}
// swap em and return
byte[] swapbuffer = buffer;
long swapbufferOffset = bufferOffset;
long swapbufferFileStartIndex = bufferFileStartIndex;
buffer = lastbuffer;
bufferOffset = lastbufferOffset;
bufferFileStartIndex = lastbufferFileStartIndex;
lastbuffer = swapbuffer;
lastbufferOffset = swapbufferOffset;
lastbufferFileStartIndex = swapbufferFileStartIndex;
}
}

View File

@ -0,0 +1,58 @@
/* ###
* IP: Public Domain
*/
package mobiledevices.dmg.ghidra;
/**
* Class with static methods that deal with string manipulation.
*/
public class GStringUtilities {
/**
* Converts an integer into a string.
* For example, given an integer 0x41424344,
* the returned string would be "ABCD".
* @param value the integer value
* @return the converted string
*/
public static String toString(int value) {
byte[] bytes = new byte[4];
int byteIndex = bytes.length - 1;
while (value != 0) {
bytes[byteIndex] = (byte) value;
value = value >> 8;
--byteIndex;
}
return new String(bytes);
}
public static String convertBytesToString( byte [] bytes, int length ) {
StringBuffer buf = new StringBuffer( length * 2);
for ( int i = 0 ; i < length ; ++i ) {
String bs = Integer.toHexString( bytes[ i ] & 0xff );
if ( bs.length() == 1 ) {
buf.append( "0" );
}
buf.append( bs );
}
return buf.toString();
}
public static byte[] convertStringToBytes(String hexstr) {
try {
byte[] bytes = new byte[hexstr.length() / 2];
for (int i = 0; i < hexstr.length(); i += 2) {
String bs = hexstr.substring(i, i + 2);
bytes[i / 2] = (byte) Integer.parseInt(bs, 16);
}
return bytes;
}
catch (Exception e) {
// tried, but failed
}
return null;
}
}

View File

@ -0,0 +1,16 @@
/* ###
* IP: Public Domain
*/
package mobiledevices.dmg.ghidra;
public class GSystemUtilities {
public static boolean isEqual(Object o1, Object o2) {
if (o1 == null) {
return (o2 == null);
}
return o1.equals(o2);
}
}

View File

@ -0,0 +1,125 @@
/* ###
* IP: Public Domain
*/
package mobiledevices.dmg.hfsplus;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
import org.catacombae.hfsexplorer.fs.ImplHFSXFileSystemView;
import org.catacombae.hfsexplorer.fs.NullProgressMonitor;
import org.catacombae.hfsexplorer.types.hfscommon.CommonHFSCatalogFile;
import org.catacombae.hfsexplorer.types.hfscommon.CommonHFSForkData;
import org.catacombae.hfsexplorer.types.hfsplus.*;
import org.catacombae.jparted.lib.fs.FSFile;
import org.catacombae.jparted.lib.fs.hfscommon.HFSCommonFSFile;
import org.catacombae.jparted.lib.fs.hfsx.HFSXFileSystemHandler;
import mobiledevices.dmg.btree.*;
import mobiledevices.dmg.decmpfs.DecmpfsHeader;
import mobiledevices.dmg.ghidra.GBinaryReader;
import mobiledevices.dmg.ghidra.GByteProvider;
/**
* This code will extract the attributes file from the HFS+ file system,
* which contains the B-tree for traversing the DECOMPFS files.
*/
public class AttributesFileParser {
private Map<FSFile, DecmpfsHeader> map = new HashMap<FSFile, DecmpfsHeader>();
private GByteProvider provider;
private BTreeRootNodeDescriptor root;
public AttributesFileParser( HFSXFileSystemHandler handler, String prefix ) throws IOException {
ImplHFSXFileSystemView hfsxFileSystemView = (ImplHFSXFileSystemView) handler.getFSView();
HFSPlusVolumeHeader volumeHeader = hfsxFileSystemView.getHFSPlusVolumeHeader();
HFSPlusForkData attributes = volumeHeader.getAttributesFile();
File attributesFile = writeVolumeHeaderFile( hfsxFileSystemView, attributes, prefix + "_" + "attributesFile" );
provider = new GByteProvider( attributesFile );
if ( attributesFile.length() == 0 ) {
return;
}
GBinaryReader reader = new GBinaryReader( provider, false );
root = new BTreeRootNodeDescriptor( reader );
}
public void dispose() throws IOException {
map.clear();
provider.close();
}
private int getFileID(FSFile file) {
try {
HFSCommonFSFile hfsFile = (HFSCommonFSFile)file;
CommonHFSCatalogFile catalogFile = hfsFile.getInternalCatalogFile();
CommonHFSCatalogFile.HFSPlusImplementation hfsPlusCatalogFile = (CommonHFSCatalogFile.HFSPlusImplementation)catalogFile;
HFSPlusCatalogFile underlying = hfsPlusCatalogFile.getUnderlying();
HFSCatalogNodeID fileID = underlying.getFileID();
return fileID.toInt();
}
catch (Exception e) {
return -1;
}
}
private File writeVolumeHeaderFile( ImplHFSXFileSystemView hfsxFileSystemView,
HFSPlusForkData volumeHeaderFile,
String volumeHeaderFileName ) throws IOException {
if (volumeHeaderFile == null) {
return null;
}
File file = File.createTempFile( "Ghidra_" + volumeHeaderFileName + "_", ".tmp" );
file.deleteOnExit();
OutputStream out = new FileOutputStream( file );
try {
CommonHFSForkData fork = CommonHFSForkData.create( volumeHeaderFile );
hfsxFileSystemView.extractForkToStream( fork, fork.getBasicExtents(), out, new NullProgressMonitor() {} );
}
finally {
out.close();
}
return file;
}
public DecmpfsHeader getDecmpfsHeader(FSFile file) throws IOException {
if ( root == null ) {
return null;
}
if ( map.get( file ) != null ) {
return map.get( file );
}
int fileID = getFileID( file );
if ( fileID == -1 ) {
return null;
}
for ( BTreeNodeDescriptor node : root.getNodes() ) {
for ( BTreeNodeRecord record : node.getRecords() ) {
if ( record.getFileID() == fileID ) {
DecmpfsHeader header = record.getDecmpfsHeader();
if ( header != null ) {
map.put( file, header );
return header;
}
}
}
}
return null;
}
}

View File

@ -0,0 +1,344 @@
/* ###
* IP: Public Domain
*/
package mobiledevices.dmg.reader;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import org.catacombae.dmgextractor.encodings.encrypted.ReadableCEncryptedEncodingStream;
import org.catacombae.hfsexplorer.FileSystemRecognizer;
import org.catacombae.hfsexplorer.PartitionSystemRecognizer;
import org.catacombae.hfsexplorer.UDIFRecognizer;
import org.catacombae.hfsexplorer.partitioning.Partition;
import org.catacombae.hfsexplorer.partitioning.PartitionSystem;
import org.catacombae.hfsexplorer.win32.WindowsLowLevelIO;
import org.catacombae.io.*;
import org.catacombae.jparted.lib.DataLocator;
import org.catacombae.jparted.lib.ReadableStreamDataLocator;
import org.catacombae.jparted.lib.fs.*;
import org.catacombae.jparted.lib.fs.FileSystemHandlerFactory.StandardAttribute;
import org.catacombae.jparted.lib.fs.hfsx.HFSXFileSystemHandler;
import org.catacombae.udif.UDIFFile;
import org.catacombae.udif.UDIFRandomAccessStream;
import mobiledevices.dmg.decmpfs.DecmpfsCompressionTypes;
import mobiledevices.dmg.decmpfs.DecmpfsHeader;
import mobiledevices.dmg.ghidra.*;
import mobiledevices.dmg.hfsplus.AttributesFileParser;
import mobiledevices.dmg.zlib.ZLIB;
public class DmgFileReader implements Closeable {
private final static GDataConverter ledc = new GDataConverterLE();
private final static GDataConverter bedc = new GDataConverterBE();
private GByteProvider provider;
private AttributesFileParser parser;
private ReadableRandomAccessStream rras;
private List<FSFolder> rootFolders = new ArrayList<FSFolder>();
private List<FileSystemHandler> fileSystemHandlers = new ArrayList<FileSystemHandler>();
public DmgFileReader( GByteProvider provider ) {
this.provider = provider;
}
public void open() throws IOException {
File file = provider.getFile();
if (WindowsLowLevelIO.isSystemSupported()) {
rras = new WindowsLowLevelIO(file.getAbsolutePath());
}
else {
rras = new ReadableFileStream(file.getAbsolutePath());
}
if (ReadableCEncryptedEncodingStream.isCEncryptedEncoding(rras)) {
//TODO use our decryption instead??
}
System.err.println("Trying to detect UDIF structure...");
if (UDIFRecognizer.isUDIF(rras)) {
System.err.println("UDIF structure found! Creating filter stream...");
UDIFFile udifFile = new UDIFFile(new ReadableFileStream(file.getAbsolutePath()));
debug(udifFile.getView().getPlistData(), "dmg-xml");
UDIFRandomAccessStream stream = new UDIFRandomAccessStream(rras);
rras = stream;
}
else {
System.err.println("UDIF structure not found. Proceeding...");
}
PartitionSystemRecognizer partitionSystemRecognizer = new PartitionSystemRecognizer(rras);
PartitionSystem partitionSystem = partitionSystemRecognizer.getPartitionSystem();
if (partitionSystem == null) {
throw new IOException("No system partitions found. Perhaps the decryption failed?");
}
Partition[] partitions = partitionSystem.getUsedPartitionEntries();
for (Partition partition : partitions) {
openPartition(partition);
}
}
private void debug( byte [] plistData, String fileName ) {
// TODO Auto-generated method stub
}
private void openPartition( Partition selectedPartition ) throws IOException {
long fsOffset = selectedPartition.getStartOffset();//getPmPyPartStart()+selectedPartition.getPmLgDataStart())*blockSize;
long fsLength = selectedPartition.getLength();//getPmDataCnt()*blockSize;
FileSystemRecognizer fsr = new FileSystemRecognizer( rras, fsOffset );
FileSystemRecognizer.FileSystemType fsType = fsr.detectFileSystem();
if ( fsType == FileSystemRecognizer.FileSystemType.HFS_PLUS ||
fsType == FileSystemRecognizer.FileSystemType.HFSX ||
fsType == FileSystemRecognizer.FileSystemType.HFS ) {
final FileSystemMajorType fsMajorType;
switch ( fsType ) {
case HFS:
fsMajorType = FileSystemMajorType.APPLE_HFS;
break;
case HFS_PLUS:
fsMajorType = FileSystemMajorType.APPLE_HFS_PLUS;
break;
case HFSX:
fsMajorType = FileSystemMajorType.APPLE_HFSX;
break;
default:
fsMajorType = null;
break;
}
FileSystemHandlerFactory factory = fsMajorType.createDefaultHandlerFactory();
if ( factory.isSupported( StandardAttribute.CACHING_ENABLED ) ) {
factory.getCreateAttributes().
setBooleanAttribute(StandardAttribute.CACHING_ENABLED,
true);
}
ReadableRandomAccessStream stage1;
if (fsLength > 0) {
stage1 = new ReadableConcatenatedStream(rras, fsOffset, fsLength);
}
else {
stage1 = rras;
}
DataLocator dataLocator = new ReadableStreamDataLocator(stage1);
FileSystemHandler fileSystemHandler = factory.createHandler(dataLocator);
fileSystemHandlers.add( fileSystemHandler );
rootFolders.add( fileSystemHandler.getRoot() );
if ( fileSystemHandler instanceof HFSXFileSystemHandler ) {
parser = new AttributesFileParser( (HFSXFileSystemHandler)fileSystemHandler, fileSystemHandler.getRoot( ).getName( ) );
}
} else {
System.err.println("UNKNOWN file system type. Can't Open filesystem. Suspect this is an APFS.\n");
}
}
@Override
public void close() throws IOException {
try {
rras.close();
}
catch (Exception e) {
//ignore
}
if ( parser != null ) {
parser.dispose();
parser = null;
}
fileSystemHandlers.clear();
rootFolders.clear();
}
public InputStream getData( FSEntry entry ) throws IOException {
if ( entry != null && entry.isFile() ) {
FSFile fsFile = (FSFile)entry;
FSFork mainFork = fsFile.getMainFork();
if ( mainFork.getLength() > 0 ) {
ReadableRandomAccessStream mainForkStream = mainFork.getReadableRandomAccessStream();
if ( mainForkStream.length() != 0 ) {
return new DmgInputStream( mainForkStream );
}
}
else if ( mainFork.getLength() == 0 ) {
FSFork resourceFork = fsFile.getForkByType( FSForkType.MACOS_RESOURCE );
ReadableRandomAccessStream resourceForkStream = resourceFork.getReadableRandomAccessStream();
if ( parser == null ) {
return null;
}
DecmpfsHeader decmpfsHeader = parser.getDecmpfsHeader( fsFile );
if ( decmpfsHeader == null ) {
return null;
}
if ( decmpfsHeader.getCompressionType() == DecmpfsCompressionTypes.CMP_Type3 ) {
if ( decmpfsHeader.getAttrBytes()[ 0 ] == -1 ) {
return new ByteArrayInputStream( decmpfsHeader.getAttrBytes(), 1, decmpfsHeader.getAttrBytes().length - 1 );
}
ZLIB zlib = new ZLIB();
InputStream inputStream =
new ByteArrayInputStream(decmpfsHeader.getAttrBytes());
ByteArrayOutputStream uncompressedBytes =
zlib.decompress(inputStream, (int) decmpfsHeader.getUncompressedSize());
File tempDecompressedFile = GFileUtilityMethods.writeTemporaryFile(
uncompressedBytes.toByteArray(), entry.getName());
return new FileInputStream(tempDecompressedFile);
}
else if ( decmpfsHeader.getCompressionType() == DecmpfsCompressionTypes.CMP_Type4 ) {
return decompressResourceFork( entry, resourceForkStream, (int)decmpfsHeader.getUncompressedSize() );
}
}
}
return null;
}
private InputStream decompressResourceFork( FSEntry entry,
ReadableRandomAccessStream resourceForkStream,
int expectedLength ) throws IOException {
File tempFile = GFileUtilityMethods.writeTemporaryFile( new DmgInputStream( resourceForkStream ) );
System.err.println(
"dmg resource fork for " + entry.getName() + ": " + tempFile.getAbsolutePath());
InputStream input = new FileInputStream( tempFile );
for ( int i = 0 ; i < 0x100 ; ++i ) {
input.read();
}
byte [] sizeBytes = new byte[ 4 ];
input.read( sizeBytes );
int size = sizeBytes[ 0 ] == 0 ?
bedc.getInt( sizeBytes ) :
ledc.getInt( sizeBytes );
byte [] flagsBytes = new byte[ 4 ];
input.read( flagsBytes );
byte [] startDistanceBytes = new byte[ 4 ];
input.read( startDistanceBytes );
int startDistance = ledc.getInt( startDistanceBytes );
input.skip( startDistance - 8 );//skip to the start of the zlib compressed file
File tempCompressedFile = GFileUtilityMethods.writeTemporaryFile( input, size - startDistance );
InputStream inputStream = new FileInputStream( tempCompressedFile );
ZLIB zlib = new ZLIB( );
ByteArrayOutputStream uncompressedByteStream = zlib.decompress( inputStream, expectedLength );
return new ByteArrayInputStream( uncompressedByteStream.toByteArray() );
}
public List<String> getInfo( String path ) {
if ( path != null ) {
DmgInfoGenerator info = new DmgInfoGenerator( this, path, parser );
return info.getInformation( );
}
return null;
}
public List<FSEntry> getListing( String path ) {
List<FSEntry> list = new ArrayList<FSEntry>();
if ( path == null || path.equals( "/" ) ) {
for ( FileSystemHandler handler : fileSystemHandlers ) {
list.add( handler.getRoot() );
}
}
else {
FSEntry fileByPath = getFileByPath( path );
if ( fileByPath != null ) {
if ( fileByPath.isFolder() ) {
FSEntry [] listEntries = fileByPath.asFolder().listEntries();
for ( FSEntry entry : listEntries ) {
list.add( entry );
}
}
}
}
return list;
}
/**
* Returns the length of the given file system entry.
* If the entry is actually a directory, then -1 is returned.
*/
public long getLength( FSEntry entry ) {
if ( entry != null & entry.isFile() ) {
FSFork mainFork = entry.asFile().getMainFork();
if ( mainFork.getLength() > 0 ) {
return mainFork.getLength();
}
try {
if (parser != null) {
DecmpfsHeader header = parser.getDecmpfsHeader(entry.asFile());
if (header != null) {
return header.getUncompressedSize();
}
}
}
catch (IOException e) {
return 1;//TODO lookup valid length in DECMPFS
}
}
return -1;
}
/**
* Convert path to string array.
*
* For example, "/a/b/c.txt" will be converted to [ "a", "b", "c.txt" ].
*
* Note: the "a" will be stripped because it corresponds to the file system handler.
*/
public String [] convertPathToArrayAndStripFileSystemName( String path ) {
String [] splitPath = path.split( "/" );
if ( splitPath.length <= 2 ) {
return new String[ 0 ];
}
String [] temp = new String[ splitPath.length - 2 ];
System.arraycopy( splitPath, 2, temp, 0, splitPath.length - 2 );
return temp;
}
/**
* Returns the DMG file object for the corresponding path.
* Path should contain the file system handler name.
*/
public FSEntry getFileByPath( String path ) {
if ( path == null || path.equals( "/" ) ) {//ROOT
return null;
}
for ( FileSystemHandler handler : fileSystemHandlers ) {
FSEntry entry = handler.getEntry( convertPathToArrayAndStripFileSystemName( path ) );
if ( entry != null ) {
return entry;
}
}
return null;
}
}

View File

@ -0,0 +1,223 @@
/* ###
* IP: Public Domain
*/
package mobiledevices.dmg.reader;
import java.io.IOException;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.List;
import org.catacombae.hfsexplorer.ObjectContainer;
import org.catacombae.hfsexplorer.types.hfscommon.CommonHFSCatalogFile;
import org.catacombae.hfsexplorer.types.hfsplus.HFSCatalogNodeID;
import org.catacombae.hfsexplorer.types.hfsplus.HFSPlusCatalogFile;
import org.catacombae.jparted.lib.fs.*;
import org.catacombae.jparted.lib.fs.FSAttributes.POSIXFileAttributes;
import org.catacombae.jparted.lib.fs.hfscommon.HFSCommonFSFile;
import mobiledevices.dmg.decmpfs.DecmpfsHeader;
import mobiledevices.dmg.hfsplus.AttributesFileParser;
/**
*
* @see org.catacombae.hfsexplorer.gui.FSEntrySummaryPanel
*
*/
class DmgInfoGenerator {
private DmgFileReader fileSystem;
private String filePath;
private AttributesFileParser parser;
private FSEntry entry;
private DateFormat df = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM);
DmgInfoGenerator(DmgFileReader fileSystem, String filePath, AttributesFileParser parser) {
this.fileSystem = fileSystem;
this.filePath = filePath;
this.parser = parser;
this.entry = fileSystem.getFileByPath(filePath);
}
List<String> getInformation() {
List<String> infoList = new ArrayList<String>();
if (entry == null) {
infoList.add("<< no information available >>");
return infoList;
}
infoList.add("Name: " + entry.getName());
if (entry instanceof FSFile) {
FSFile file = (FSFile) entry;
infoList.add("Type: " + "File");
infoList.add("Total Size: " + getSizeString(file.getCombinedLength()));
FSFork[] allForks = file.getAllForks();
for (FSFork fork : allForks) {
infoList.add(
" " + fork.getForkIdentifier() + ": " + getSizeString(fork.getLength()));
}
appendFileID(infoList, file);
if (parser != null) {
try {
DecmpfsHeader decmpfsHeader = parser.getDecmpfsHeader(file);
if (decmpfsHeader != null) {
infoList.add(
"Decmpfs Size: " + getSizeString(decmpfsHeader.getUncompressedSize()));
}
}
catch (IOException e) {
}
}
}
else if (entry instanceof FSFolder) {
FSFolder folder = (FSFolder) entry;
infoList.add("Type: " + "Folder");
infoList.add("Size: " + startFolderSizeCalculation(folder));
}
else if (entry instanceof FSLink) {
FSLink link = (FSLink) entry;
FSEntry linkTarget =
link.getLinkTarget(fileSystem.convertPathToArrayAndStripFileSystemName(filePath));
if (linkTarget == null) {
infoList.add("Type: " + "Symbolic link (broken)");
infoList.add("Size: " + "- (broken link)");
}
else if (linkTarget instanceof FSFile) {
FSFile file = (FSFile) linkTarget;
infoList.add("Type: " + "Symbolic link (file)");
infoList.add("Size: " + getSizeString(file.getMainFork().getLength()));
FSFork[] allForks = file.getAllForks();
for (FSFork fork : allForks) {
infoList.add(
" " + fork.getForkIdentifier() + ": " + getSizeString(fork.getLength()));
}
}
else if (linkTarget instanceof FSFolder) {
FSFolder folder = (FSFolder) linkTarget;
infoList.add("Type: " + "Symbolic link (folder)");
infoList.add("Size: " + startFolderSizeCalculation(folder));
}
else {
infoList.add("Type: " + "Symbolic link (unknown [" + linkTarget.getClass() + "])");
infoList.add("Size: " + "- (unknown type)");
}
infoList.add("Link Target: " + link.getLinkTargetString());
}
else {
infoList.add("Type: " + "Unknown [" + entry.getClass() + "]");
infoList.add("Size: " + "- (unknown size)");
}
FSAttributes attrs = entry.getAttributes();
appendDateInformation(attrs, infoList);
appendPosixInformation(attrs, infoList);
appendWindowsInformation(attrs, infoList);
return infoList;
}
private void appendFileID(List<String> infoList, FSFile file) {
try {
HFSCommonFSFile hfsFile = (HFSCommonFSFile) file;
CommonHFSCatalogFile catalogFile = hfsFile.getInternalCatalogFile();
CommonHFSCatalogFile.HFSPlusImplementation hfsPlusCatalogFile =
(CommonHFSCatalogFile.HFSPlusImplementation) catalogFile;
HFSPlusCatalogFile underlying = hfsPlusCatalogFile.getUnderlying();
HFSCatalogNodeID fileID = underlying.getFileID();
infoList.add("File ID: 0x" + Integer.toHexString(fileID.toInt()));
}
catch (Exception e) {
infoList.add("Unable to obtain file ID. " + e.getMessage());
}
}
private void appendPosixInformation(FSAttributes attrs, List<String> infoList) {
if (attrs.hasPOSIXFileAttributes()) {
POSIXFileAttributes posixAttrs = attrs.getPOSIXFileAttributes();
infoList.add("Permissions: " + posixAttrs.getPermissionString());
infoList.add("User ID: " + posixAttrs.getUserID());
infoList.add("Group ID: " + posixAttrs.getGroupID());
}
}
private void appendWindowsInformation(FSAttributes attrs, List<String> infoList) {
if (attrs.hasWindowsFileAttributes()) {
WindowsFileAttributes windowsFileAttributes = attrs.getWindowsFileAttributes();
infoList.add("Archive: " + windowsFileAttributes.isArchive());
infoList.add("Compressed: " + windowsFileAttributes.isCompressed());
infoList.add("Directory: " + windowsFileAttributes.isDirectory());
infoList.add("Encrypted: " + windowsFileAttributes.isEncrypted());
infoList.add("Hidden: " + windowsFileAttributes.isHidden());
infoList.add("Normal: " + windowsFileAttributes.isNormal());
infoList.add("Off-line: " + windowsFileAttributes.isOffline());
infoList.add("Read-only: " + windowsFileAttributes.isReadOnly());
infoList.add("Reparse: " + windowsFileAttributes.isReparsePoint());
infoList.add("Sparse: " + windowsFileAttributes.isSparseFile());
infoList.add("System: " + windowsFileAttributes.isSystem());
infoList.add("Temp: " + windowsFileAttributes.isTemporary());
infoList.add("Virtual: " + windowsFileAttributes.isVirtual());
}
}
private void appendDateInformation(FSAttributes attributes, List<String> infoList) {
if (attributes.hasCreateDate()) {
infoList.add("Created: " + df.format(attributes.getCreateDate()));
}
if (attributes.hasModifyDate()) {
infoList.add("Contents Modified: " + df.format(attributes.getModifyDate()));
}
if (attributes.hasAttributeModifyDate()) {
infoList.add("Attributes Modified: " + df.format(attributes.getAttributeModifyDate()));
}
if (attributes.hasAccessDate()) {
infoList.add("Last Accessed: " + df.format(attributes.getAccessDate()));
}
if (attributes.hasBackupDate()) {
infoList.add("Last Backup: " + df.format(attributes.getBackupDate()));
}
}
private String getSizeString(long result) {
String baseString = Long.toString(result);
return baseString + " bytes";
}
private String startFolderSizeCalculation(FSFolder folder) {
String resultString;
try {
ObjectContainer<Long> result = new ObjectContainer<Long>((long) 0);
calculateFolderSize(folder, result);
resultString = getSizeString(result.o);
}
catch (Exception e) {
e.printStackTrace();
resultString = "Exception while calculating! See debug console for info...";
}
return resultString;
}
private void calculateFolderSize(FSFolder folder, ObjectContainer<Long> result) {
for (FSEntry entry : folder.listEntries()) {
if (entry instanceof FSFile) {
Long value = result.o;
value += ((FSFile) entry).getMainFork().getLength();
result.o = value;
}
else if (entry instanceof FSFolder) {
calculateFolderSize((FSFolder) entry, result);
}
else if (entry instanceof FSLink) {
/* Do nothing. Symbolic link targets aren't part of the folder. */
}
else {
System.err.println("FSEntrySummaryPanel.calculateFolderSize():" +
" unexpected type " + entry.getClass());
}
}
}
}

View File

@ -0,0 +1,43 @@
/* ###
* IP: Public Domain
*/
package mobiledevices.dmg.reader;
import java.io.IOException;
import java.io.InputStream;
import org.catacombae.io.ReadableRandomAccessStream;
/**
* A class to wrap a ReadableRandomAccessStream
* so it may be used as a conventional
* input stream.
*/
public class DmgInputStream extends InputStream {
private ReadableRandomAccessStream stream;
DmgInputStream(ReadableRandomAccessStream stream) {
this.stream = stream;
}
public long getLength() {
return stream.length();
}
@Override
public int read() throws IOException {
return stream.read();
}
@Override
public int read(byte [] b) throws IOException {
return stream.read(b);
}
@Override
public int read(byte [] b, int off, int len) throws IOException {
return stream.read(b, off, len);
}
}

View File

@ -0,0 +1,193 @@
/* ###
* IP: Public Domain
*/
package mobiledevices.dmg.server;
import java.io.*;
import java.util.List;
import org.catacombae.jparted.lib.fs.*;
import mobiledevices.dmg.ghidra.GByteProvider;
import mobiledevices.dmg.ghidra.GFileUtilityMethods;
import mobiledevices.dmg.reader.DmgFileReader;
public class DmgServer {
private static void writeln(String s) {
StringBuilder encoded = new StringBuilder();
char[] charArray = s.toCharArray();
for (char c : charArray) {
if (c == 11) {
encoded.append(c);// tab
}
if (c <= 31 || c == 127) {
continue;// control characters
}
encoded.append(c);
}
System.out.println(encoded.toString());
}
public static void sendResponse(String s) {
System.out.println(s);
System.out.flush();
}
public static void sendResponses(String... responseStrs) {
for (String s : responseStrs) {
System.out.println(s);
}
System.out.flush();
}
public static void log(String... logstrs) {
for (String s : logstrs) {
System.err.println(s);
}
System.err.flush();
}
public static void main(String[] args) {
log("Waiting for client to connect to DMG server...");
BufferedReader inputReader = new BufferedReader(new InputStreamReader(System.in));
try {
String openLine = inputReader.readLine();
if (openLine == null) {
return;
}
if (!openLine.startsWith("open ")) {
return;//TODO handle invalid initial command???
}
String openPath = parseLine(openLine);
File openFile = new File(openPath);
if (!openFile.exists()) {//TODO handle files that do not exist
}
try (GByteProvider provider = new GByteProvider(openFile);
DmgFileReader dmgFileReader = new DmgFileReader(provider);) {
dmgFileReader.open();
while (true) {
String line = inputReader.readLine();
if (line == null) {
break;
}
String[] parts = line.split(" ", 2);
if (parts.length < 1)
continue;
String cmd = parts[0];
switch (cmd) {
case "close":
log("Exiting DMG server process: close cmd");
return;
case "get_listing": {
String path = parseLine(line);
List<FSEntry> listing = dmgFileReader.getListing(path);
sendResponse("" + listing.size());//write total number of children
for (FSEntry childEntry : listing) {
// send 3 responses: name, isfolder boolean, file length
writeln(childEntry.getName());//write name of each child
sendResponses("" + childEntry.isFolder(),
"" + dmgFileReader.getLength(childEntry));
}
}
break;
case "get_info": {
String path = parseLine(line);
List<String> infoList = dmgFileReader.getInfo(path);
sendResponse("" + infoList.size());//write total number of info lines
for (String info : infoList) {
sendResponse(info);//write each info line
}
}
break;
case "get_data": {
String path = parseLine(line);
FSFile dmgFile = toFile(dmgFileReader, path);
if (dmgFile == null) {//TODO not a valid file...
sendResponse("");
}
else {
long expectedFileLength = dmgFileReader.getLength(dmgFile);
try (InputStream inputStream = dmgFileReader.getData(dmgFile)) {
if (inputStream != null) {
File temporaryFile =
GFileUtilityMethods.writeTemporaryFile(inputStream);
sendResponse(temporaryFile.getAbsolutePath());
if (expectedFileLength != temporaryFile.length()) {
log("file sizes do not match!");
}
}
else {
sendResponse("");// TODO: is this correct way to respond when error cond?
log("No data stream for get_data for " + path);
}
}
}
}
break;
}
}
}
}
catch (IOException e) {
log("IOException error in DMGServer command processing: " + e.getMessage());
e.printStackTrace(System.err);
}
finally {
log("DMG server has terminated.");
}
}
private static FSFile toFile(DmgFileReader dmgFileReader, String path) {
FSEntry entry = dmgFileReader.getFileByPath(path);
if (entry == null) {
//System.err.println("Bad path for toFile: " + path);
return null;
}
if (entry.isFile()) {
return entry.asFile();
}
else if (entry instanceof FSLink) {
int limit = 0;
while (limit++ < 10) {
FSLink link = (FSLink) entry;
FSEntry linkTarget = link.getLinkTarget(
dmgFileReader.convertPathToArrayAndStripFileSystemName(path));
if (linkTarget instanceof FSFile) {
return linkTarget.asFile();
}
else if (linkTarget instanceof FSLink) {
entry = linkTarget;
}
else {//anything else just return
break;
}
}
}
return null;
}
private static String parseLine(String openLine) {
int space = openLine.indexOf(' ');
String path = openLine.substring(space + 1).trim();
return path;
}
}

View File

@ -0,0 +1,13 @@
/* ###
* IP: Public Domain
*/
package mobiledevices.dmg.xattr;
public final class XattrConstants {
public final static String RESOURCE_XATTR_NAME = "com.apple.ResourceFork";
public final static String DECMPFS_XATTR_NAME = "com.apple.decmpfs";
public final static String KAUTH_FILESEC_XATTR_NAME = "com.apple.system.Security";
public final static String KAUTH_SCOPE_PROCESS = "com.apple.kauth.process";
}

View File

@ -0,0 +1,120 @@
/* ###
* IP: Public Domain
*/
package mobiledevices.dmg.zlib;
import java.io.*;
import java.util.zip.*;
/**
*
* TODO make this more memory efficient!!
*
*/
public class ZLIB {
public ZLIB() {
}
public ByteArrayOutputStream decompress( InputStream compressedIn, int expectedDecompressedLength ) throws IOException {
return decompress( compressedIn, expectedDecompressedLength, false );
}
public ByteArrayOutputStream decompress( InputStream compressedIn, int expectedDecompressedLength, boolean noWrap ) throws IOException {
byte [] compressedBytes = convertInputStreamToByteArray( compressedIn );
ByteArrayOutputStream decompressedBOS = new ByteArrayOutputStream();
byte [] tempDecompressedBytes = new byte[ 0x10000 ];
int totalDecompressed = 0;
int offset = 0;
try {
while ( offset < compressedBytes.length && totalDecompressed < expectedDecompressedLength ) {
if ( !noWrap && compressedBytes [ offset ] != 0x78 ) {
break;
}
Inflater inflater = new Inflater( noWrap );
inflater.setInput( compressedBytes, offset, compressedBytes.length - offset );
int nDecompressed = inflater.inflate( tempDecompressedBytes );
if ( nDecompressed == 0 ) {
break;
}
totalDecompressed += nDecompressed;
decompressedBOS.write( tempDecompressedBytes, 0, nDecompressed );
offset += inflater.getTotalIn();//increment total compressed bytes consumed
}
}
catch ( DataFormatException e ) {
throw new IOException( e.getMessage() );
}
return decompressedBOS;
}
public ByteArrayOutputStream compress(byte[] decompressedBytes) {
return compress( false, decompressedBytes );
}
public ByteArrayOutputStream compress(boolean noWrap, byte[] decompressedBytes) {
ByteArrayOutputStream compressedBOS = new ByteArrayOutputStream();
byte [] tempBuffer = new byte[ 0x10000 ];
int offset = 0;
while ( offset < decompressedBytes.length ) {
Deflater deflater = new Deflater( 0, noWrap );
deflater.setInput( decompressedBytes, offset, decompressedBytes.length - offset );
deflater.finish();
if ( deflater.needsInput() ) {
System.err.println( "needs input??" );
}
int nDeflated = deflater.deflate( tempBuffer );
if ( nDeflated == 0 ) {
break;
}
compressedBOS.write( tempBuffer, 0, nDeflated );
offset += deflater.getTotalIn();
}
return compressedBOS;
}
/**
* Converts the contents of an input stream to a byte array
* @param compressedIn
* @return
* @throws IOException
*/
private byte [] convertInputStreamToByteArray( InputStream compressedIn ) throws IOException {
byte [] bytes = new byte[ 8096 ];
ByteArrayOutputStream compressedBOS = new ByteArrayOutputStream();
while ( true ) {
int nRead = compressedIn.read( bytes );
if ( nRead == -1 ) {
break;
}
compressedBOS.write( bytes, 0, nRead );
}
return compressedBOS.toByteArray();
}
}

View File

@ -0,0 +1,3 @@
MODULE FILE LICENSE: os/linux64/demangler_gnu GPL 3
MODULE FILE LICENSE: os/osx64/demangler_gnu GPL 3
MODULE FILE LICENSE: os/win64/demangler_gnu.exe GPL 3

View File

@ -0,0 +1,109 @@
apply plugin: 'eclipse'
eclipse.project.name = 'GPL DemanglerGnu'
apply from: "../nativeBuildProperties.gradle"
/****************************************************************************
* Defines the platforms we have to support in Ghidra. This model is used
* for all native builds and should be extended by each module as-needed.
****************************************************************************/
model {
// define the platforms that we support in ghidra
platforms {
win64 {
architecture 'x86_64'
operatingSystem 'windows'
}
linux64 {
architecture 'x86_64'
operatingSystem 'linux'
}
osx64 {
architecture 'x86_64'
operatingSystem 'osx'
}
}
}
/**
* This project has some native 'c' code we need to include in the zip for licensing
* and build reasons. So include them here, but we have to do something special: the
* source is divided up into folders for makefiles, headers and .c files:
* /headers
* /c
* /build
*
* The contents of all these need to be merged into the same folder for distribution.
* Hence the following 3 'from' clauses:
*/
task zipBuildableSource(type:Zip) {
group 'private'
description "Collects the source files needed to build this module."
baseName project.name + "-src-for-build"
extension 'zip'
from (project.projectDir.toString() + "/src/demangler_gnu/c") {
into "/src/demangler_gnu"
}
from (project.projectDir.toString() + "/src/demangler_gnu/headers") {
into "/src/demangler_gnu"
}
from (project.projectDir.toString() + "/src/demangler_gnu/build") {
into "/src/demangler_gnu"
}
from (project.projectDir.toString() + "/src/demangler_gnu/README.txt")
}
model {
components {
demangler_gnu(NativeExecutableSpec) {
targetPlatform "win64"
targetPlatform "linux64"
targetPlatform "osx64"
sources {
c {
source {
srcDir "src/demangler_gnu/c"
}
exportedHeaders {
srcDir "src/demangler_gnu/headers"
}
}
}
}
}
}
model {
binaries {
all{ b ->
if (toolChain in Gcc) {
cCompiler.args "-DMAIN_CPLUS_DEM"
cCompiler.args "-DHAVE_STDLIB_H"
cCompiler.args "-DHAVE_STRING_H"
if (targetPlatform.operatingSystem.linux) {
// linker.args "-static"
}
}
else if (toolChain in VisualCpp) {
cCompiler.args "/D_CONSOLE"
cCompiler.args "/DMAIN_CPLUS_DEM"
cCompiler.args "-DHAVE_STDLIB_H"
cCompiler.args "-DHAVE_STRING_H"
}
else if (toolChain in Clang) {
cCompiler.args "-DMAIN_CPLUS_DEM"
cCompiler.args "-DHAVE_STDLIB_H"
cCompiler.args "-DHAVE_STRING_H"
if (targetPlatform.operatingSystem.linux) {
// linker.args "-static"
}
}
}
}
}

View File

@ -0,0 +1,11 @@
##VERSION: 2.0
##MODULE IP: GPL 3
##MODULE IP: GPL 3 Linking Permitted
##MODULE IP: LGPL 2.1
##MODULE IP: LGPL 3.0
##MODULE IP: Public Domain
.classpath||GHIDRA||||END|
.project||Public Domain||||END|
Module.manifest||Public Domain||||END|
build.gradle||Public Domain||||END|
src/demangler_gnu/README.txt||Public Domain||||END|

View File

@ -0,0 +1,94 @@
PURPOSE
This is a readme file to note the changes made to the binutils-2.24 source
code in order for Ghidra to build its GNU demangler.
COPIED SOURCE CODE / BUILDING RESTRICTIONS
Most of the files used to build the Ghidra GNU demangler are copied from binutils and have
not been changed. Further, the files in this directory are a small subset of the files used to
build the binutils suite. By copying specific files we are able to use Make and Visual Studio
to build a stand alone demangler without having to perform the more complicated build needed
to build binutils. Specifically, we do not have to run the configure utility that is
provided by binutils. This is critical, as we are using Visual Studio to build on Windows,
which does not have the configure utility support. If we ever wished to build the entire
binutils suite on Windows, then we would most likely need to use a GNU environment made for
Windows, such as MinGW.
CHANGES TO BINUTILS SOURCE
cplus-dem.c
To this file was added about 400 lines of source code. Previously, this file contained a
main method that we used to build our stand alone demangler. The current version of
binutils does not have this main method. Instead, binutils has only a main method in
cp-demangle.c for building the stand alone demangler. The c++filt utility is created using
a main method inside of cxxfilt.c. We could not build that utility without using the
more complicated build system mentioned above.
In order to gain full functionality contained in the c++filt utility, we copied the main
method from cxxfilt.c and placed it, along with supporting methods, into cplus-dem.c. This
allows us to perform a simple build of the stand alone demangler, with less source files
required.
cp-demangle.c *
This file contains a small, two-line change to send a newline character ('\n') along with
a flush to the output stream. Without this change, the program, when called repeatedly from
Ghidra would eventually hang. This is due to the nature of how Ghidra reads results in a
line-oriented fashion.
*This change is no longer used, as we do not use the main method inside of this file, but have
switched to the main method we made and placed into cplus-dem.c.
UPDATING
If we ever wish to update to a newer version of binutils, then we will need to re-copy the files
in this directory and then rebuild the main method we created inside of cplus-dem.c. That is,
unless at least one of the following changes happens:
1) the stand alone demangler in cp-demangle has full c++filt support, or
2) binutils has put the main method back inside cplus-dem.c, or
3) building a stand alone c++filt is simple enough that we can do it on each platform, or
4) we decide to build the entire binutils suite and use the full c++filt binary.
SOURCE FILES NEEDED BY OS
*nix / Mac
ansidecl.h
argv.c
cp-demangle.c
cp-demangle.h
cplus-dem.c
demangle.h
dyn-string.c
dyn-string.h
getopt.c
getopt.h
libiberty.h
safe-ctype.c
safe-ctype.h
xexit.c
xstrdup.c
WINDOWS
alloca.c
getopt1.c

View File

@ -0,0 +1,488 @@
/* ###
* IP: LGPL 2.1
* REVIEWED: YES
* NOTE: license is not in file, but in the directory from whence it came: binutils-2.24/libiberty/COPYING.LIB
*/
/* alloca.c -- allocate automatically reclaimed memory
(Mostly) portable public-domain implementation -- D A Gwyn
This implementation of the PWB library alloca function,
which is used to allocate space off the run-time stack so
that it is automatically reclaimed upon procedure exit,
was inspired by discussions with J. Q. Johnson of Cornell.
J.Otto Tennant <jot@cray.com> contributed the Cray support.
There are some preprocessor constants that can
be defined when compiling for your specific system, for
improved efficiency; however, the defaults should be okay.
The general concept of this implementation is to keep
track of all alloca-allocated blocks, and reclaim any
that are found to be deeper in the stack than the current
invocation. This heuristic does not reclaim storage as
soon as it becomes invalid, but it will do so eventually.
As a special case, alloca(0) reclaims storage without
allocating any. It is a good idea to use alloca(0) in
your main control loop, etc. to force garbage collection. */
/*
@deftypefn Replacement void* alloca (size_t @var{size})
This function allocates memory which will be automatically reclaimed
after the procedure exits. The @libib{} implementation does not free
the memory immediately but will do so eventually during subsequent
calls to this function. Memory is allocated using @code{xmalloc} under
normal circumstances.
The header file @file{alloca-conf.h} can be used in conjunction with the
GNU Autoconf test @code{AC_FUNC_ALLOCA} to test for and properly make
available this function. The @code{AC_FUNC_ALLOCA} test requires that
client code use a block of preprocessor code to be safe (see the Autoconf
manual for more); this header incorporates that logic and more, including
the possibility of a GCC built-in function.
@end deftypefn
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <libiberty.h>
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
/* These variables are used by the ASTRDUP implementation that relies
on C_alloca. */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
const char *libiberty_optr;
char *libiberty_nptr;
unsigned long libiberty_len;
#ifdef __cplusplus
}
#endif /* __cplusplus */
/* If your stack is a linked list of frames, you have to
provide an "address metric" ADDRESS_FUNCTION macro. */
#if defined (CRAY) && defined (CRAY_STACKSEG_END)
static long i00afunc ();
#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
#else
#define ADDRESS_FUNCTION(arg) &(arg)
#endif
#ifndef NULL
#define NULL 0
#endif
/* Define STACK_DIRECTION if you know the direction of stack
growth for your system; otherwise it will be automatically
deduced at run-time.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown */
#ifndef STACK_DIRECTION
#define STACK_DIRECTION 0 /* Direction unknown. */
#endif
#if STACK_DIRECTION != 0
#define STACK_DIR STACK_DIRECTION /* Known at compile-time. */
#else /* STACK_DIRECTION == 0; need run-time code. */
static int stack_dir; /* 1 or -1 once known. */
#define STACK_DIR stack_dir
static void
find_stack_direction (void)
{
static char *addr = NULL; /* Address of first `dummy', once known. */
auto char dummy; /* To get stack address. */
if (addr == NULL)
{ /* Initial entry. */
addr = ADDRESS_FUNCTION (dummy);
find_stack_direction (); /* Recurse once. */
}
else
{
/* Second entry. */
if (ADDRESS_FUNCTION (dummy) > addr)
stack_dir = 1; /* Stack grew upward. */
else
stack_dir = -1; /* Stack grew downward. */
}
}
#endif /* STACK_DIRECTION == 0 */
/* An "alloca header" is used to:
(a) chain together all alloca'ed blocks;
(b) keep track of stack depth.
It is very important that sizeof(header) agree with malloc
alignment chunk size. The following default should work okay. */
#ifndef ALIGN_SIZE
#define ALIGN_SIZE sizeof(double)
#endif
typedef union hdr
{
char align[ALIGN_SIZE]; /* To force sizeof(header). */
struct
{
union hdr *next; /* For chaining headers. */
char *deep; /* For stack depth measure. */
} h;
} header;
static header *last_alloca_header = NULL; /* -> last alloca header. */
/* Return a pointer to at least SIZE bytes of storage,
which will be automatically reclaimed upon exit from
the procedure that called alloca. Originally, this space
was supposed to be taken from the current stack frame of the
caller, but that method cannot be made to work for some
implementations of C, for example under Gould's UTX/32. */
/* @undocumented C_alloca */
PTR
C_alloca (size_t size)
{
auto char probe; /* Probes stack depth: */
register char *depth = ADDRESS_FUNCTION (probe);
#if STACK_DIRECTION == 0
if (STACK_DIR == 0) /* Unknown growth direction. */
find_stack_direction ();
#endif
/* Reclaim garbage, defined as all alloca'd storage that
was allocated from deeper in the stack than currently. */
{
register header *hp; /* Traverses linked list. */
for (hp = last_alloca_header; hp != NULL;)
if ((STACK_DIR > 0 && hp->h.deep > depth)
|| (STACK_DIR < 0 && hp->h.deep < depth))
{
register header *np = hp->h.next;
free ((PTR) hp); /* Collect garbage. */
hp = np; /* -> next header. */
}
else
break; /* Rest are not deeper. */
last_alloca_header = hp; /* -> last valid storage. */
}
if (size == 0)
return NULL; /* No allocation required. */
/* Allocate combined header + user data storage. */
{
register void *new_storage = XNEWVEC (char, sizeof (header) + size);
/* Address of header. */
if (new_storage == 0)
abort();
((header *) new_storage)->h.next = last_alloca_header;
((header *) new_storage)->h.deep = depth;
last_alloca_header = (header *) new_storage;
/* User storage begins just after header. */
return (PTR) ((char *) new_storage + sizeof (header));
}
}
#if defined (CRAY) && defined (CRAY_STACKSEG_END)
#ifdef DEBUG_I00AFUNC
#include <stdio.h>
#endif
#ifndef CRAY_STACK
#define CRAY_STACK
#ifndef CRAY2
/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
struct stack_control_header
{
long shgrow:32; /* Number of times stack has grown. */
long shaseg:32; /* Size of increments to stack. */
long shhwm:32; /* High water mark of stack. */
long shsize:32; /* Current size of stack (all segments). */
};
/* The stack segment linkage control information occurs at
the high-address end of a stack segment. (The stack
grows from low addresses to high addresses.) The initial
part of the stack segment linkage control information is
0200 (octal) words. This provides for register storage
for the routine which overflows the stack. */
struct stack_segment_linkage
{
long ss[0200]; /* 0200 overflow words. */
long sssize:32; /* Number of words in this segment. */
long ssbase:32; /* Offset to stack base. */
long:32;
long sspseg:32; /* Offset to linkage control of previous
segment of stack. */
long:32;
long sstcpt:32; /* Pointer to task common address block. */
long sscsnm; /* Private control structure number for
microtasking. */
long ssusr1; /* Reserved for user. */
long ssusr2; /* Reserved for user. */
long sstpid; /* Process ID for pid based multi-tasking. */
long ssgvup; /* Pointer to multitasking thread giveup. */
long sscray[7]; /* Reserved for Cray Research. */
long ssa0;
long ssa1;
long ssa2;
long ssa3;
long ssa4;
long ssa5;
long ssa6;
long ssa7;
long sss0;
long sss1;
long sss2;
long sss3;
long sss4;
long sss5;
long sss6;
long sss7;
};
#else /* CRAY2 */
/* The following structure defines the vector of words
returned by the STKSTAT library routine. */
struct stk_stat
{
long now; /* Current total stack size. */
long maxc; /* Amount of contiguous space which would
be required to satisfy the maximum
stack demand to date. */
long high_water; /* Stack high-water mark. */
long overflows; /* Number of stack overflow ($STKOFEN) calls. */
long hits; /* Number of internal buffer hits. */
long extends; /* Number of block extensions. */
long stko_mallocs; /* Block allocations by $STKOFEN. */
long underflows; /* Number of stack underflow calls ($STKRETN). */
long stko_free; /* Number of deallocations by $STKRETN. */
long stkm_free; /* Number of deallocations by $STKMRET. */
long segments; /* Current number of stack segments. */
long maxs; /* Maximum number of stack segments so far. */
long pad_size; /* Stack pad size. */
long current_address; /* Current stack segment address. */
long current_size; /* Current stack segment size. This
number is actually corrupted by STKSTAT to
include the fifteen word trailer area. */
long initial_address; /* Address of initial segment. */
long initial_size; /* Size of initial segment. */
};
/* The following structure describes the data structure which trails
any stack segment. I think that the description in 'asdef' is
out of date. I only describe the parts that I am sure about. */
struct stk_trailer
{
long this_address; /* Address of this block. */
long this_size; /* Size of this block (does not include
this trailer). */
long unknown2;
long unknown3;
long link; /* Address of trailer block of previous
segment. */
long unknown5;
long unknown6;
long unknown7;
long unknown8;
long unknown9;
long unknown10;
long unknown11;
long unknown12;
long unknown13;
long unknown14;
};
#endif /* CRAY2 */
#endif /* not CRAY_STACK */
#ifdef CRAY2
/* Determine a "stack measure" for an arbitrary ADDRESS.
I doubt that "lint" will like this much. */
static long
i00afunc (long *address)
{
struct stk_stat status;
struct stk_trailer *trailer;
long *block, size;
long result = 0;
/* We want to iterate through all of the segments. The first
step is to get the stack status structure. We could do this
more quickly and more directly, perhaps, by referencing the
$LM00 common block, but I know that this works. */
STKSTAT (&status);
/* Set up the iteration. */
trailer = (struct stk_trailer *) (status.current_address
+ status.current_size
- 15);
/* There must be at least one stack segment. Therefore it is
a fatal error if "trailer" is null. */
if (trailer == 0)
abort ();
/* Discard segments that do not contain our argument address. */
while (trailer != 0)
{
block = (long *) trailer->this_address;
size = trailer->this_size;
if (block == 0 || size == 0)
abort ();
trailer = (struct stk_trailer *) trailer->link;
if ((block <= address) && (address < (block + size)))
break;
}
/* Set the result to the offset in this segment and add the sizes
of all predecessor segments. */
result = address - block;
if (trailer == 0)
{
return result;
}
do
{
if (trailer->this_size <= 0)
abort ();
result += trailer->this_size;
trailer = (struct stk_trailer *) trailer->link;
}
while (trailer != 0);
/* We are done. Note that if you present a bogus address (one
not in any segment), you will get a different number back, formed
from subtracting the address of the first block. This is probably
not what you want. */
return (result);
}
#else /* not CRAY2 */
/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
Determine the number of the cell within the stack,
given the address of the cell. The purpose of this
routine is to linearize, in some sense, stack addresses
for alloca. */
static long
i00afunc (long address)
{
long stkl = 0;
long size, pseg, this_segment, stack;
long result = 0;
struct stack_segment_linkage *ssptr;
/* Register B67 contains the address of the end of the
current stack segment. If you (as a subprogram) store
your registers on the stack and find that you are past
the contents of B67, you have overflowed the segment.
B67 also points to the stack segment linkage control
area, which is what we are really interested in. */
stkl = CRAY_STACKSEG_END ();
ssptr = (struct stack_segment_linkage *) stkl;
/* If one subtracts 'size' from the end of the segment,
one has the address of the first word of the segment.
If this is not the first segment, 'pseg' will be
nonzero. */
pseg = ssptr->sspseg;
size = ssptr->sssize;
this_segment = stkl - size;
/* It is possible that calling this routine itself caused
a stack overflow. Discard stack segments which do not
contain the target address. */
while (!(this_segment <= address && address <= stkl))
{
#ifdef DEBUG_I00AFUNC
fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
#endif
if (pseg == 0)
break;
stkl = stkl - pseg;
ssptr = (struct stack_segment_linkage *) stkl;
size = ssptr->sssize;
pseg = ssptr->sspseg;
this_segment = stkl - size;
}
result = address - this_segment;
/* If you subtract pseg from the current end of the stack,
you get the address of the previous stack segment's end.
This seems a little convoluted to me, but I'll bet you save
a cycle somewhere. */
while (pseg != 0)
{
#ifdef DEBUG_I00AFUNC
fprintf (stderr, "%011o %011o\n", pseg, size);
#endif
stkl = stkl - pseg;
ssptr = (struct stack_segment_linkage *) stkl;
size = ssptr->sssize;
pseg = ssptr->sspseg;
result += size;
}
return (result);
}
#endif /* not CRAY2 */
#endif /* CRAY */

View File

@ -0,0 +1,545 @@
/* ###
* IP: LGPL 2.1
* REVIEWED: YES
* NOTE: from binutils 2.24
*/
/* Create and destroy argument vectors (argv's)
Copyright (C) 1992, 2001, 2010, 2012 Free Software Foundation, Inc.
Written by Fred Fish @ Cygnus Support
This file is part of the libiberty library.
Libiberty is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
Libiberty is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with libiberty; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
Boston, MA 02110-1301, USA. */
/* Create and destroy argument vectors. An argument vector is simply an
array of string pointers, terminated by a NULL pointer. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "ansidecl.h"
#include "libiberty.h"
#include "safe-ctype.h"
/* Routines imported from standard C runtime libraries. */
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#ifndef NULL
#define NULL 0
#endif
#ifndef EOS
#define EOS '\0'
#endif
#define INITIAL_MAXARGC 8 /* Number of args + NULL in initial argv */
/*
@deftypefn Extension char** dupargv (char **@var{vector})
Duplicate an argument vector. Simply scans through @var{vector},
duplicating each argument until the terminating @code{NULL} is found.
Returns a pointer to the argument vector if successful. Returns
@code{NULL} if there is insufficient memory to complete building the
argument vector.
@end deftypefn
*/
char **
dupargv (char **argv)
{
int argc;
char **copy;
if (argv == NULL)
return NULL;
/* the vector */
for (argc = 0; argv[argc] != NULL; argc++);
copy = (char **) xmalloc ((argc + 1) * sizeof (char *));
/* the strings */
for (argc = 0; argv[argc] != NULL; argc++)
{
int len = strlen (argv[argc]);
copy[argc] = (char *) xmalloc (len + 1);
strcpy (copy[argc], argv[argc]);
}
copy[argc] = NULL;
return copy;
}
/*
@deftypefn Extension void freeargv (char **@var{vector})
Free an argument vector that was built using @code{buildargv}. Simply
scans through @var{vector}, freeing the memory for each argument until
the terminating @code{NULL} is found, and then frees @var{vector}
itself.
@end deftypefn
*/
void freeargv (char **vector)
{
register char **scan;
if (vector != NULL)
{
for (scan = vector; *scan != NULL; scan++)
{
free (*scan);
}
free (vector);
}
}
static void
consume_whitespace (const char **input)
{
while (ISSPACE (**input))
{
(*input)++;
}
}
static int
only_whitespace (const char* input)
{
while (*input != EOS && ISSPACE (*input))
input++;
return (*input == EOS);
}
/*
@deftypefn Extension char** buildargv (char *@var{sp})
Given a pointer to a string, parse the string extracting fields
separated by whitespace and optionally enclosed within either single
or double quotes (which are stripped off), and build a vector of
pointers to copies of the string for each field. The input string
remains unchanged. The last element of the vector is followed by a
@code{NULL} element.
All of the memory for the pointer array and copies of the string
is obtained from @code{xmalloc}. All of the memory can be returned to the
system with the single function call @code{freeargv}, which takes the
returned result of @code{buildargv}, as it's argument.
Returns a pointer to the argument vector if successful. Returns
@code{NULL} if @var{sp} is @code{NULL} or if there is insufficient
memory to complete building the argument vector.
If the input is a null string (as opposed to a @code{NULL} pointer),
then buildarg returns an argument vector that has one arg, a null
string.
@end deftypefn
The memory for the argv array is dynamically expanded as necessary.
In order to provide a working buffer for extracting arguments into,
with appropriate stripping of quotes and translation of backslash
sequences, we allocate a working buffer at least as long as the input
string. This ensures that we always have enough space in which to
work, since the extracted arg is never larger than the input string.
The argument vector is always kept terminated with a @code{NULL} arg
pointer, so it can be passed to @code{freeargv} at any time, or
returned, as appropriate.
*/
char **buildargv (const char *input)
{
char *arg;
char *copybuf;
int squote = 0;
int dquote = 0;
int bsquote = 0;
int argc = 0;
int maxargc = 0;
char **argv = NULL;
char **nargv;
if (input != NULL)
{
copybuf = (char *) xmalloc (strlen (input) + 1);
/* Is a do{}while to always execute the loop once. Always return an
argv, even for null strings. See NOTES above, test case below. */
do
{
/* Pick off argv[argc] */
consume_whitespace (&input);
if ((maxargc == 0) || (argc >= (maxargc - 1)))
{
/* argv needs initialization, or expansion */
if (argv == NULL)
{
maxargc = INITIAL_MAXARGC;
nargv = (char **) xmalloc (maxargc * sizeof (char *));
}
else
{
maxargc *= 2;
nargv = (char **) xrealloc (argv, maxargc * sizeof (char *));
}
argv = nargv;
argv[argc] = NULL;
}
/* Begin scanning arg */
arg = copybuf;
while (*input != EOS)
{
if (ISSPACE (*input) && !squote && !dquote && !bsquote)
{
break;
}
else
{
if (bsquote)
{
bsquote = 0;
*arg++ = *input;
}
else if (*input == '\\')
{
bsquote = 1;
}
else if (squote)
{
if (*input == '\'')
{
squote = 0;
}
else
{
*arg++ = *input;
}
}
else if (dquote)
{
if (*input == '"')
{
dquote = 0;
}
else
{
*arg++ = *input;
}
}
else
{
if (*input == '\'')
{
squote = 1;
}
else if (*input == '"')
{
dquote = 1;
}
else
{
*arg++ = *input;
}
}
input++;
}
}
*arg = EOS;
argv[argc] = xstrdup (copybuf);
argc++;
argv[argc] = NULL;
consume_whitespace (&input);
}
while (*input != EOS);
free (copybuf);
}
return (argv);
}
/*
@deftypefn Extension int writeargv (const char **@var{argv}, FILE *@var{file})
Write each member of ARGV, handling all necessary quoting, to the file
named by FILE, separated by whitespace. Return 0 on success, non-zero
if an error occurred while writing to FILE.
@end deftypefn
*/
int
writeargv (char **argv, FILE *f)
{
int status = 0;
if (f == NULL)
return 1;
while (*argv != NULL)
{
const char *arg = *argv;
while (*arg != EOS)
{
char c = *arg;
if (ISSPACE(c) || c == '\\' || c == '\'' || c == '"')
if (EOF == fputc ('\\', f))
{
status = 1;
goto done;
}
if (EOF == fputc (c, f))
{
status = 1;
goto done;
}
arg++;
}
if (EOF == fputc ('\n', f))
{
status = 1;
goto done;
}
argv++;
}
done:
return status;
}
/*
@deftypefn Extension void expandargv (int *@var{argcp}, char ***@var{argvp})
The @var{argcp} and @code{argvp} arguments are pointers to the usual
@code{argc} and @code{argv} arguments to @code{main}. This function
looks for arguments that begin with the character @samp{@@}. Any such
arguments are interpreted as ``response files''. The contents of the
response file are interpreted as additional command line options. In
particular, the file is separated into whitespace-separated strings;
each such string is taken as a command-line option. The new options
are inserted in place of the option naming the response file, and
@code{*argcp} and @code{*argvp} will be updated. If the value of
@code{*argvp} is modified by this function, then the new value has
been dynamically allocated and can be deallocated by the caller with
@code{freeargv}. However, most callers will simply call
@code{expandargv} near the beginning of @code{main} and allow the
operating system to free the memory when the program exits.
@end deftypefn
*/
void
expandargv (int *argcp, char ***argvp)
{
/* The argument we are currently processing. */
int i = 0;
/* Non-zero if ***argvp has been dynamically allocated. */
int argv_dynamic = 0;
/* Limit the number of response files that we parse in order
to prevent infinite recursion. */
unsigned int iteration_limit = 2000;
/* Loop over the arguments, handling response files. We always skip
ARGVP[0], as that is the name of the program being run. */
while (++i < *argcp)
{
/* The name of the response file. */
const char *filename;
/* The response file. */
FILE *f;
/* An upper bound on the number of characters in the response
file. */
long pos;
/* The number of characters in the response file, when actually
read. */
size_t len;
/* A dynamically allocated buffer used to hold options read from a
response file. */
char *buffer;
/* Dynamically allocated storage for the options read from the
response file. */
char **file_argv;
/* The number of options read from the response file, if any. */
size_t file_argc;
/* We are only interested in options of the form "@file". */
filename = (*argvp)[i];
if (filename[0] != '@')
continue;
/* If we have iterated too many times then stop. */
if (-- iteration_limit == 0)
{
fprintf (stderr, "%s: error: too many @-files encountered\n", (*argvp)[0]);
xexit (1);
}
/* Read the contents of the file. */
f = fopen (++filename, "r");
if (!f)
continue;
if (fseek (f, 0L, SEEK_END) == -1)
goto error;
pos = ftell (f);
if (pos == -1)
goto error;
if (fseek (f, 0L, SEEK_SET) == -1)
goto error;
buffer = (char *) xmalloc (pos * sizeof (char) + 1);
len = fread (buffer, sizeof (char), pos, f);
if (len != (size_t) pos
/* On Windows, fread may return a value smaller than POS,
due to CR/LF->CR translation when reading text files.
That does not in-and-of itself indicate failure. */
&& ferror (f))
goto error;
/* Add a NUL terminator. */
buffer[len] = '\0';
/* If the file is empty or contains only whitespace, buildargv would
return a single empty argument. In this context we want no arguments,
instead. */
if (only_whitespace (buffer))
{
file_argv = (char **) xmalloc (sizeof (char *));
file_argv[0] = NULL;
}
else
/* Parse the string. */
file_argv = buildargv (buffer);
/* If *ARGVP is not already dynamically allocated, copy it. */
if (!argv_dynamic)
*argvp = dupargv (*argvp);
/* Count the number of arguments. */
file_argc = 0;
while (file_argv[file_argc])
++file_argc;
/* Now, insert FILE_ARGV into ARGV. The "+1" below handles the
NULL terminator at the end of ARGV. */
*argvp = ((char **)
xrealloc (*argvp,
(*argcp + file_argc + 1) * sizeof (char *)));
memmove (*argvp + i + file_argc, *argvp + i + 1,
(*argcp - i) * sizeof (char *));
memcpy (*argvp + i, file_argv, file_argc * sizeof (char *));
/* The original option has been replaced by all the new
options. */
*argcp += file_argc - 1;
/* Free up memory allocated to process the response file. We do
not use freeargv because the individual options in FILE_ARGV
are now in the main ARGV. */
free (file_argv);
free (buffer);
/* Rescan all of the arguments just read to support response
files that include other response files. */
--i;
error:
/* We're all done with the file now. */
fclose (f);
}
}
/*
@deftypefn Extension int countargv (char **@var{argv})
Return the number of elements in @var{argv}.
Returns zero if @var{argv} is NULL.
@end deftypefn
*/
int
countargv (char **argv)
{
int argc;
if (argv == NULL)
return 0;
for (argc = 0; argv[argc] != NULL; argc++)
continue;
return argc;
}
#ifdef MAIN
/* Simple little test driver. */
static const char *const tests[] =
{
"a simple command line",
"arg 'foo' is single quoted",
"arg \"bar\" is double quoted",
"arg \"foo bar\" has embedded whitespace",
"arg 'Jack said \\'hi\\'' has single quotes",
"arg 'Jack said \\\"hi\\\"' has double quotes",
"a b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9",
/* This should be expanded into only one argument. */
"trailing-whitespace ",
"",
NULL
};
int
main (void)
{
char **argv;
const char *const *test;
char **targs;
for (test = tests; *test != NULL; test++)
{
printf ("buildargv(\"%s\")\n", *test);
if ((argv = buildargv (*test)) == NULL)
{
printf ("failed!\n\n");
}
else
{
for (targs = argv; *targs != NULL; targs++)
{
printf ("\t\"%s\"\n", *targs);
}
printf ("\n");
}
freeargv (argv);
}
return 0;
}
#endif /* MAIN */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,401 @@
/* ###
* IP: GPL 3 Linking Permitted
* REVIEWED: YES
*/
/* An abstract string datatype.
Copyright (C) 1998, 1999, 2000, 2002, 2004 Free Software Foundation, Inc.
Contributed by Mark Mitchell (mark@markmitchell.com).
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
In addition to the permissions in the GNU General Public License, the
Free Software Foundation gives you unlimited permission to link the
compiled version of this file into combinations with other programs,
and to distribute those combinations without any restriction coming
from the use of this file. (The General Public License restrictions
do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combined
executable.)
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 51 Franklin Street - Fifth Floor,
Boston, MA 02110-1301, USA. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include "libiberty.h"
#include "dyn-string.h"
/* Performs in-place initialization of a dyn_string struct. This
function can be used with a dyn_string struct on the stack or
embedded in another object. The contents of of the string itself
are still dynamically allocated. The string initially is capable
of holding at least SPACE characeters, including the terminating
NUL. If SPACE is 0, it will silently be increated to 1.
If RETURN_ON_ALLOCATION_FAILURE is defined and memory allocation
fails, returns 0. Otherwise returns 1. */
int
dyn_string_init (struct dyn_string *ds_struct_ptr, int space)
{
/* We need at least one byte in which to store the terminating NUL. */
if (space == 0)
space = 1;
#ifdef RETURN_ON_ALLOCATION_FAILURE
ds_struct_ptr->s = (char *) malloc (space);
if (ds_struct_ptr->s == NULL)
return 0;
#else
ds_struct_ptr->s = XNEWVEC (char, space);
#endif
ds_struct_ptr->allocated = space;
ds_struct_ptr->length = 0;
ds_struct_ptr->s[0] = '\0';
return 1;
}
/* Create a new dynamic string capable of holding at least SPACE
characters, including the terminating NUL. If SPACE is 0, it will
be silently increased to 1. If RETURN_ON_ALLOCATION_FAILURE is
defined and memory allocation fails, returns NULL. Otherwise
returns the newly allocated string. */
dyn_string_t
dyn_string_new (int space)
{
dyn_string_t result;
#ifdef RETURN_ON_ALLOCATION_FAILURE
result = (dyn_string_t) malloc (sizeof (struct dyn_string));
if (result == NULL)
return NULL;
if (!dyn_string_init (result, space))
{
free (result);
return NULL;
}
#else
result = XNEW (struct dyn_string);
dyn_string_init (result, space);
#endif
return result;
}
/* Free the memory used by DS. */
void
dyn_string_delete (dyn_string_t ds)
{
free (ds->s);
free (ds);
}
/* Returns the contents of DS in a buffer allocated with malloc. It
is the caller's responsibility to deallocate the buffer using free.
DS is then set to the empty string. Deletes DS itself. */
char*
dyn_string_release (dyn_string_t ds)
{
/* Store the old buffer. */
char* result = ds->s;
/* The buffer is no longer owned by DS. */
ds->s = NULL;
/* Delete DS. */
free (ds);
/* Return the old buffer. */
return result;
}
/* Increase the capacity of DS so it can hold at least SPACE
characters, plus the terminating NUL. This function will not (at
present) reduce the capacity of DS. Returns DS on success.
If RETURN_ON_ALLOCATION_FAILURE is defined and a memory allocation
operation fails, deletes DS and returns NULL. */
dyn_string_t
dyn_string_resize (dyn_string_t ds, int space)
{
int new_allocated = ds->allocated;
/* Increase SPACE to hold the NUL termination. */
++space;
/* Increase allocation by factors of two. */
while (space > new_allocated)
new_allocated *= 2;
if (new_allocated != ds->allocated)
{
ds->allocated = new_allocated;
/* We actually need more space. */
#ifdef RETURN_ON_ALLOCATION_FAILURE
ds->s = (char *) realloc (ds->s, ds->allocated);
if (ds->s == NULL)
{
free (ds);
return NULL;
}
#else
ds->s = XRESIZEVEC (char, ds->s, ds->allocated);
#endif
}
return ds;
}
/* Sets the contents of DS to the empty string. */
void
dyn_string_clear (dyn_string_t ds)
{
/* A dyn_string always has room for at least the NUL terminator. */
ds->s[0] = '\0';
ds->length = 0;
}
/* Makes the contents of DEST the same as the contents of SRC. DEST
and SRC must be distinct. Returns 1 on success. On failure, if
RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0. */
int
dyn_string_copy (dyn_string_t dest, dyn_string_t src)
{
if (dest == src)
abort ();
/* Make room in DEST. */
if (dyn_string_resize (dest, src->length) == NULL)
return 0;
/* Copy DEST into SRC. */
strcpy (dest->s, src->s);
/* Update the size of DEST. */
dest->length = src->length;
return 1;
}
/* Copies SRC, a NUL-terminated string, into DEST. Returns 1 on
success. On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST
and returns 0. */
int
dyn_string_copy_cstr (dyn_string_t dest, const char *src)
{
int length = strlen (src);
/* Make room in DEST. */
if (dyn_string_resize (dest, length) == NULL)
return 0;
/* Copy DEST into SRC. */
strcpy (dest->s, src);
/* Update the size of DEST. */
dest->length = length;
return 1;
}
/* Inserts SRC at the beginning of DEST. DEST is expanded as
necessary. SRC and DEST must be distinct. Returns 1 on success.
On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and
returns 0. */
int
dyn_string_prepend (dyn_string_t dest, dyn_string_t src)
{
return dyn_string_insert (dest, 0, src);
}
/* Inserts SRC, a NUL-terminated string, at the beginning of DEST.
DEST is expanded as necessary. Returns 1 on success. On failure,
if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0. */
int
dyn_string_prepend_cstr (dyn_string_t dest, const char *src)
{
return dyn_string_insert_cstr (dest, 0, src);
}
/* Inserts SRC into DEST starting at position POS. DEST is expanded
as necessary. SRC and DEST must be distinct. Returns 1 on
success. On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST
and returns 0. */
int
dyn_string_insert (dyn_string_t dest, int pos, dyn_string_t src)
{
int i;
if (src == dest)
abort ();
if (dyn_string_resize (dest, dest->length + src->length) == NULL)
return 0;
/* Make room for the insertion. Be sure to copy the NUL. */
for (i = dest->length; i >= pos; --i)
dest->s[i + src->length] = dest->s[i];
/* Splice in the new stuff. */
strncpy (dest->s + pos, src->s, src->length);
/* Compute the new length. */
dest->length += src->length;
return 1;
}
/* Inserts SRC, a NUL-terminated string, into DEST starting at
position POS. DEST is expanded as necessary. Returns 1 on
success. On failure, RETURN_ON_ALLOCATION_FAILURE, deletes DEST
and returns 0. */
int
dyn_string_insert_cstr (dyn_string_t dest, int pos, const char *src)
{
int i;
int length = strlen (src);
if (dyn_string_resize (dest, dest->length + length) == NULL)
return 0;
/* Make room for the insertion. Be sure to copy the NUL. */
for (i = dest->length; i >= pos; --i)
dest->s[i + length] = dest->s[i];
/* Splice in the new stuff. */
strncpy (dest->s + pos, src, length);
/* Compute the new length. */
dest->length += length;
return 1;
}
/* Inserts character C into DEST starting at position POS. DEST is
expanded as necessary. Returns 1 on success. On failure,
RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0. */
int
dyn_string_insert_char (dyn_string_t dest, int pos, int c)
{
int i;
if (dyn_string_resize (dest, dest->length + 1) == NULL)
return 0;
/* Make room for the insertion. Be sure to copy the NUL. */
for (i = dest->length; i >= pos; --i)
dest->s[i + 1] = dest->s[i];
/* Add the new character. */
dest->s[pos] = c;
/* Compute the new length. */
++dest->length;
return 1;
}
/* Append S to DS, resizing DS if necessary. Returns 1 on success.
On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and
returns 0. */
int
dyn_string_append (dyn_string_t dest, dyn_string_t s)
{
if (dyn_string_resize (dest, dest->length + s->length) == 0)
return 0;
strcpy (dest->s + dest->length, s->s);
dest->length += s->length;
return 1;
}
/* Append the NUL-terminated string S to DS, resizing DS if necessary.
Returns 1 on success. On failure, if RETURN_ON_ALLOCATION_FAILURE,
deletes DEST and returns 0. */
int
dyn_string_append_cstr (dyn_string_t dest, const char *s)
{
int len = strlen (s);
/* The new length is the old length plus the size of our string, plus
one for the null at the end. */
if (dyn_string_resize (dest, dest->length + len) == NULL)
return 0;
strcpy (dest->s + dest->length, s);
dest->length += len;
return 1;
}
/* Appends C to the end of DEST. Returns 1 on success. On failure,
if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0. */
int
dyn_string_append_char (dyn_string_t dest, int c)
{
/* Make room for the extra character. */
if (dyn_string_resize (dest, dest->length + 1) == NULL)
return 0;
/* Append the character; it will overwrite the old NUL. */
dest->s[dest->length] = c;
/* Add a new NUL at the end. */
dest->s[dest->length + 1] = '\0';
/* Update the length. */
++(dest->length);
return 1;
}
/* Sets the contents of DEST to the substring of SRC starting at START
and ending before END. START must be less than or equal to END,
and both must be between zero and the length of SRC, inclusive.
Returns 1 on success. On failure, if RETURN_ON_ALLOCATION_FAILURE,
deletes DEST and returns 0. */
int
dyn_string_substring (dyn_string_t dest, dyn_string_t src,
int start, int end)
{
int i;
int length = end - start;
if (start > end || start > src->length || end > src->length)
abort ();
/* Make room for the substring. */
if (dyn_string_resize (dest, length) == NULL)
return 0;
/* Copy the characters in the substring, */
for (i = length; --i >= 0; )
dest->s[i] = src->s[start + i];
/* NUL-terimate the result. */
dest->s[length] = '\0';
/* Record the length of the substring. */
dest->length = length;
return 1;
}
/* Returns non-zero if DS1 and DS2 have the same contents. */
int
dyn_string_eq (dyn_string_t ds1, dyn_string_t ds2)
{
/* If DS1 and DS2 have different lengths, they must not be the same. */
if (ds1->length != ds2->length)
return 0;
else
return !strcmp (ds1->s, ds2->s);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,184 @@
/* ###
* IP: GPL 3
* REVIEWED: YES
*/
/* getopt_long and getopt_long_only entry points for GNU getopt.
Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98,2005
Free Software Foundation, Inc.
NOTE: This source is derived from an old version taken from the GNU C
Library (glibc).
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
USA. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#if !defined __STDC__ || !__STDC__
/* This is a separate conditional since some stdc systems
reject `defined (const)'. */
#ifndef const
#define const
#endif
#endif
#include <stdio.h>
#include "getopt.h"
/* Comment out all this code if we are using the GNU C Library, and are not
actually compiling the library itself. This code is part of the GNU C
Library, but also included in many other GNU distributions. Compiling
and linking in this code is a waste when using the GNU C library
(especially if it is a shared library). Rather than having every GNU
program understand `configure --with-gnu-libc' and omit the object files,
it is simpler to just do this in the source for each such file. */
#define GETOPT_INTERFACE_VERSION 2
#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
#include <gnu-versions.h>
#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
#define ELIDE_CODE
#endif
#endif
#ifndef ELIDE_CODE
/* This needs to come after some library #include
to get __GNU_LIBRARY__ defined. */
#ifdef __GNU_LIBRARY__
#include <stdlib.h>
#endif
#ifndef NULL
#define NULL 0
#endif
int
getopt_long (int argc, char *const *argv, const char *options,
const struct option *long_options, int *opt_index)
{
return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
}
/* Like getopt_long, but '-' as well as '--' can indicate a long option.
If an option that starts with '-' (not '--') doesn't match a long option,
but does match a short option, it is parsed as a short option
instead. */
int
getopt_long_only (int argc, char *const *argv, const char *options,
const struct option *long_options, int *opt_index)
{
return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
}
#endif /* Not ELIDE_CODE. */
#ifdef TEST
#include <stdio.h>
int
main (int argc, char **argv)
{
int c;
int digit_optind = 0;
while (1)
{
int this_option_optind = optind ? optind : 1;
int option_index = 0;
static struct option long_options[] =
{
{"add", 1, 0, 0},
{"append", 0, 0, 0},
{"delete", 1, 0, 0},
{"verbose", 0, 0, 0},
{"create", 0, 0, 0},
{"file", 1, 0, 0},
{0, 0, 0, 0}
};
c = getopt_long (argc, argv, "abc:d:0123456789",
long_options, &option_index);
if (c == -1)
break;
switch (c)
{
case 0:
printf ("option %s", long_options[option_index].name);
if (optarg)
printf (" with arg %s", optarg);
printf ("\n");
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (digit_optind != 0 && digit_optind != this_option_optind)
printf ("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf ("option %c\n", c);
break;
case 'a':
printf ("option a\n");
break;
case 'b':
printf ("option b\n");
break;
case 'c':
printf ("option c with value `%s'\n", optarg);
break;
case 'd':
printf ("option d with value `%s'\n", optarg);
break;
case '?':
break;
default:
printf ("?? getopt returned character code 0%o ??\n", c);
}
}
if (optind < argc)
{
printf ("non-option ARGV-elements: ");
while (optind < argc)
printf ("%s ", argv[optind++]);
printf ("\n");
}
exit (0);
}
#endif /* TEST */

View File

@ -0,0 +1,259 @@
/* ###
* IP: LGPL 2.1
* REVIEWED: YES
*/
/* <ctype.h> replacement macros.
Copyright (C) 2000, 2001, 2002, 2003, 2004,
2005 Free Software Foundation, Inc.
Contributed by Zack Weinberg <zackw@stanford.edu>.
This file is part of the libiberty library.
Libiberty is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
Libiberty is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with libiberty; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
Boston, MA 02110-1301, USA. */
/*
@defvr Extension HOST_CHARSET
This macro indicates the basic character set and encoding used by the
host: more precisely, the encoding used for character constants in
preprocessor @samp{#if} statements (the C "execution character set").
It is defined by @file{safe-ctype.h}, and will be an integer constant
with one of the following values:
@ftable @code
@item HOST_CHARSET_UNKNOWN
The host character set is unknown - that is, not one of the next two
possibilities.
@item HOST_CHARSET_ASCII
The host character set is ASCII.
@item HOST_CHARSET_EBCDIC
The host character set is some variant of EBCDIC. (Only one of the
nineteen EBCDIC varying characters is tested; exercise caution.)
@end ftable
@end defvr
@deffn Extension ISALPHA (@var{c})
@deffnx Extension ISALNUM (@var{c})
@deffnx Extension ISBLANK (@var{c})
@deffnx Extension ISCNTRL (@var{c})
@deffnx Extension ISDIGIT (@var{c})
@deffnx Extension ISGRAPH (@var{c})
@deffnx Extension ISLOWER (@var{c})
@deffnx Extension ISPRINT (@var{c})
@deffnx Extension ISPUNCT (@var{c})
@deffnx Extension ISSPACE (@var{c})
@deffnx Extension ISUPPER (@var{c})
@deffnx Extension ISXDIGIT (@var{c})
These twelve macros are defined by @file{safe-ctype.h}. Each has the
same meaning as the corresponding macro (with name in lowercase)
defined by the standard header @file{ctype.h}. For example,
@code{ISALPHA} returns true for alphabetic characters and false for
others. However, there are two differences between these macros and
those provided by @file{ctype.h}:
@itemize @bullet
@item These macros are guaranteed to have well-defined behavior for all
values representable by @code{signed char} and @code{unsigned char}, and
for @code{EOF}.
@item These macros ignore the current locale; they are true for these
fixed sets of characters:
@multitable {@code{XDIGIT}} {yada yada yada yada yada yada yada yada}
@item @code{ALPHA} @tab @kbd{A-Za-z}
@item @code{ALNUM} @tab @kbd{A-Za-z0-9}
@item @code{BLANK} @tab @kbd{space tab}
@item @code{CNTRL} @tab @code{!PRINT}
@item @code{DIGIT} @tab @kbd{0-9}
@item @code{GRAPH} @tab @code{ALNUM || PUNCT}
@item @code{LOWER} @tab @kbd{a-z}
@item @code{PRINT} @tab @code{GRAPH ||} @kbd{space}
@item @code{PUNCT} @tab @kbd{`~!@@#$%^&*()_-=+[@{]@}\|;:'",<.>/?}
@item @code{SPACE} @tab @kbd{space tab \n \r \f \v}
@item @code{UPPER} @tab @kbd{A-Z}
@item @code{XDIGIT} @tab @kbd{0-9A-Fa-f}
@end multitable
Note that, if the host character set is ASCII or a superset thereof,
all these macros will return false for all values of @code{char} outside
the range of 7-bit ASCII. In particular, both ISPRINT and ISCNTRL return
false for characters with numeric values from 128 to 255.
@end itemize
@end deffn
@deffn Extension ISIDNUM (@var{c})
@deffnx Extension ISIDST (@var{c})
@deffnx Extension IS_VSPACE (@var{c})
@deffnx Extension IS_NVSPACE (@var{c})
@deffnx Extension IS_SPACE_OR_NUL (@var{c})
@deffnx Extension IS_ISOBASIC (@var{c})
These six macros are defined by @file{safe-ctype.h} and provide
additional character classes which are useful when doing lexical
analysis of C or similar languages. They are true for the following
sets of characters:
@multitable {@code{SPACE_OR_NUL}} {yada yada yada yada yada yada yada yada}
@item @code{IDNUM} @tab @kbd{A-Za-z0-9_}
@item @code{IDST} @tab @kbd{A-Za-z_}
@item @code{VSPACE} @tab @kbd{\r \n}
@item @code{NVSPACE} @tab @kbd{space tab \f \v \0}
@item @code{SPACE_OR_NUL} @tab @code{VSPACE || NVSPACE}
@item @code{ISOBASIC} @tab @code{VSPACE || NVSPACE || PRINT}
@end multitable
@end deffn
*/
#include "ansidecl.h"
#include <safe-ctype.h>
#include <stdio.h> /* for EOF */
#if EOF != -1
#error "<safe-ctype.h> requires EOF == -1"
#endif
/* Shorthand */
#define bl _sch_isblank
#define cn _sch_iscntrl
#define di _sch_isdigit
#define is _sch_isidst
#define lo _sch_islower
#define nv _sch_isnvsp
#define pn _sch_ispunct
#define pr _sch_isprint
#define sp _sch_isspace
#define up _sch_isupper
#define vs _sch_isvsp
#define xd _sch_isxdigit
/* Masks. */
#define L (const unsigned short) (lo|is |pr) /* lower case letter */
#define XL (const unsigned short) (lo|is|xd|pr) /* lowercase hex digit */
#define U (const unsigned short) (up|is |pr) /* upper case letter */
#define XU (const unsigned short) (up|is|xd|pr) /* uppercase hex digit */
#define D (const unsigned short) (di |xd|pr) /* decimal digit */
#define P (const unsigned short) (pn |pr) /* punctuation */
#define _ (const unsigned short) (pn|is |pr) /* underscore */
#define C (const unsigned short) ( cn) /* control character */
#define Z (const unsigned short) (nv |cn) /* NUL */
#define M (const unsigned short) (nv|sp |cn) /* cursor movement: \f \v */
#define V (const unsigned short) (vs|sp |cn) /* vertical space: \r \n */
#define T (const unsigned short) (nv|sp|bl|cn) /* tab */
#define S (const unsigned short) (nv|sp|bl|pr) /* space */
/* Are we ASCII? */
#if HOST_CHARSET == HOST_CHARSET_ASCII
const unsigned short _sch_istable[256] =
{
Z, C, C, C, C, C, C, C, /* NUL SOH STX ETX EOT ENQ ACK BEL */
C, T, V, M, M, V, C, C, /* BS HT LF VT FF CR SO SI */
C, C, C, C, C, C, C, C, /* DLE DC1 DC2 DC3 DC4 NAK SYN ETB */
C, C, C, C, C, C, C, C, /* CAN EM SUB ESC FS GS RS US */
S, P, P, P, P, P, P, P, /* SP ! " # $ % & ' */
P, P, P, P, P, P, P, P, /* ( ) * + , - . / */
D, D, D, D, D, D, D, D, /* 0 1 2 3 4 5 6 7 */
D, D, P, P, P, P, P, P, /* 8 9 : ; < = > ? */
P, XU, XU, XU, XU, XU, XU, U, /* @ A B C D E F G */
U, U, U, U, U, U, U, U, /* H I J K L M N O */
U, U, U, U, U, U, U, U, /* P Q R S T U V W */
U, U, U, P, P, P, P, _, /* X Y Z [ \ ] ^ _ */
P, XL, XL, XL, XL, XL, XL, L, /* ` a b c d e f g */
L, L, L, L, L, L, L, L, /* h i j k l m n o */
L, L, L, L, L, L, L, L, /* p q r s t u v w */
L, L, L, P, P, P, P, C, /* x y z { | } ~ DEL */
/* high half of unsigned char is locale-specific, so all tests are
false in "C" locale */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
const unsigned char _sch_tolower[256] =
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64,
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
91, 92, 93, 94, 95, 96,
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
123,124,125,126,127,
128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159,
160,161,162,163, 164,165,166,167, 168,169,170,171, 172,173,174,175,
176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,190,191,
192,193,194,195, 196,197,198,199, 200,201,202,203, 204,205,206,207,
208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
240,241,242,243, 244,245,246,247, 248,249,250,251, 252,253,254,255,
};
const unsigned char _sch_toupper[256] =
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64,
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
91, 92, 93, 94, 95, 96,
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
123,124,125,126,127,
128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159,
160,161,162,163, 164,165,166,167, 168,169,170,171, 172,173,174,175,
176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,190,191,
192,193,194,195, 196,197,198,199, 200,201,202,203, 204,205,206,207,
208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
240,241,242,243, 244,245,246,247, 248,249,250,251, 252,253,254,255,
};
#else
# if HOST_CHARSET == HOST_CHARSET_EBCDIC
#error "FIXME: write tables for EBCDIC"
# else
#error "Unrecognized host character set"
# endif
#endif

View File

@ -0,0 +1,56 @@
/* ###
* IP: LGPL 2.1
* REVIEWED: YES
*/
/* xexit.c -- Run any exit handlers, then exit.
Copyright (C) 1994, 95, 1997 Free Software Foundation, Inc.
This file is part of the libiberty library.
Libiberty is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
Libiberty is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with libiberty; see the file COPYING.LIB. If not, write
to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
Boston, MA 02110-1301, USA. */
/*
@deftypefn Replacement void xexit (int @var{code})
Terminates the program. If any functions have been registered with
the @code{xatexit} replacement function, they will be called first.
Termination is handled via the system's normal @code{exit} call.
@end deftypefn
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include "libiberty.h"
/* This variable is set by xatexit if it is called. This way, xmalloc
doesn't drag xatexit into the link. */
void (*_xexit_cleanup) (void);
void
xexit (int code)
{
if (_xexit_cleanup != NULL)
(*_xexit_cleanup) ();
exit (code);
}

View File

@ -0,0 +1,41 @@
/* ###
* IP: LGPL 2.1
* REVIEWED: YES
* NOTE: license is not in file, but in the directory from whence it came: binutils-2.24/libiberty/COPYING.LIB
*/
/* xstrdup.c -- Duplicate a string in memory, using xmalloc.
This trivial function is in the public domain.
Ian Lance Taylor, Cygnus Support, December 1995. */
/*
@deftypefn Replacement char* xstrdup (const char *@var{s})
Duplicates a character string without fail, using @code{xmalloc} to
obtain memory.
@end deftypefn
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/types.h>
#ifdef HAVE_STRING_H
#include <string.h>
#else
# ifdef HAVE_STRINGS_H
# include <strings.h>
# endif
#endif
#include "ansidecl.h"
#include "libiberty.h"
char *
xstrdup (const char *s)
{
register size_t len = strlen (s) + 1;
register char *ret = XNEWVEC (char, len);
return (char *) memcpy (ret, s, len);
}

View File

@ -0,0 +1,445 @@
/* ###
* IP: GPL 3
* REVIEWED: YES
*/
/* ANSI and traditional C compatability macros
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010
Free Software Foundation, Inc.
This file is part of the GNU C Library.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
/* ANSI and traditional C compatibility macros
ANSI C is assumed if __STDC__ is #defined.
Macro ANSI C definition Traditional C definition
----- ---- - ---------- ----------- - ----------
ANSI_PROTOTYPES 1 not defined
PTR `void *' `char *'
PTRCONST `void *const' `char *'
LONG_DOUBLE `long double' `double'
const not defined `'
volatile not defined `'
signed not defined `'
VA_START(ap, var) va_start(ap, var) va_start(ap)
Note that it is safe to write "void foo();" indicating a function
with no return value, in all K+R compilers we have been able to test.
For declaring functions with prototypes, we also provide these:
PARAMS ((prototype))
-- for functions which take a fixed number of arguments. Use this
when declaring the function. When defining the function, write a
K+R style argument list. For example:
char *strcpy PARAMS ((char *dest, char *source));
...
char *
strcpy (dest, source)
char *dest;
char *source;
{ ... }
VPARAMS ((prototype, ...))
-- for functions which take a variable number of arguments. Use
PARAMS to declare the function, VPARAMS to define it. For example:
int printf PARAMS ((const char *format, ...));
...
int
printf VPARAMS ((const char *format, ...))
{
...
}
For writing functions which take variable numbers of arguments, we
also provide the VA_OPEN, VA_CLOSE, and VA_FIXEDARG macros. These
hide the differences between K+R <varargs.h> and C89 <stdarg.h> more
thoroughly than the simple VA_START() macro mentioned above.
VA_OPEN and VA_CLOSE are used *instead of* va_start and va_end.
Immediately after VA_OPEN, put a sequence of VA_FIXEDARG calls
corresponding to the list of fixed arguments. Then use va_arg
normally to get the variable arguments, or pass your va_list object
around. You do not declare the va_list yourself; VA_OPEN does it
for you.
Here is a complete example:
int
printf VPARAMS ((const char *format, ...))
{
int result;
VA_OPEN (ap, format);
VA_FIXEDARG (ap, const char *, format);
result = vfprintf (stdout, format, ap);
VA_CLOSE (ap);
return result;
}
You can declare variables either before or after the VA_OPEN,
VA_FIXEDARG sequence. Also, VA_OPEN and VA_CLOSE are the beginning
and end of a block. They must appear at the same nesting level,
and any variables declared after VA_OPEN go out of scope at
VA_CLOSE. Unfortunately, with a K+R compiler, that includes the
argument list. You can have multiple instances of VA_OPEN/VA_CLOSE
pairs in a single function in case you need to traverse the
argument list more than once.
For ease of writing code which uses GCC extensions but needs to be
portable to other compilers, we provide the GCC_VERSION macro that
simplifies testing __GNUC__ and __GNUC_MINOR__ together, and various
wrappers around __attribute__. Also, __extension__ will be #defined
to nothing if it doesn't work. See below.
This header also defines a lot of obsolete macros:
CONST, VOLATILE, SIGNED, PROTO, EXFUN, DEFUN, DEFUN_VOID,
AND, DOTS, NOARGS. Don't use them. */
#ifndef _ANSIDECL_H
#define _ANSIDECL_H 1
#ifdef __cplusplus
extern "C" {
#endif
/* Every source file includes this file,
so they will all get the switch for lint. */
/* LINTLIBRARY */
/* Using MACRO(x,y) in cpp #if conditionals does not work with some
older preprocessors. Thus we can't define something like this:
#define HAVE_GCC_VERSION(MAJOR, MINOR) \
(__GNUC__ > (MAJOR) || (__GNUC__ == (MAJOR) && __GNUC_MINOR__ >= (MINOR)))
and then test "#if HAVE_GCC_VERSION(2,7)".
So instead we use the macro below and test it against specific values. */
/* This macro simplifies testing whether we are using gcc, and if it
is of a particular minimum version. (Both major & minor numbers are
significant.) This macro will evaluate to 0 if we are not using
gcc at all. */
#ifndef GCC_VERSION
#define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
#endif /* GCC_VERSION */
#if defined (__STDC__) || defined(__cplusplus) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(_WIN32)
/* All known AIX compilers implement these things (but don't always
define __STDC__). The RISC/OS MIPS compiler defines these things
in SVR4 mode, but does not define __STDC__. */
/* eraxxon@alumni.rice.edu: The Compaq C++ compiler, unlike many other
C++ compilers, does not define __STDC__, though it acts as if this
was so. (Verified versions: 5.7, 6.2, 6.3, 6.5) */
#define ANSI_PROTOTYPES 1
#define PTR void *
#define PTRCONST void *const
#define LONG_DOUBLE long double
/* PARAMS is often defined elsewhere (e.g. by libintl.h), so wrap it in
a #ifndef. */
#ifndef PARAMS
#define PARAMS(ARGS) ARGS
#endif
#define VPARAMS(ARGS) ARGS
#define VA_START(VA_LIST, VAR) va_start(VA_LIST, VAR)
/* variadic function helper macros */
/* "struct Qdmy" swallows the semicolon after VA_OPEN/VA_FIXEDARG's
use without inhibiting further decls and without declaring an
actual variable. */
#define VA_OPEN(AP, VAR) { va_list AP; va_start(AP, VAR); { struct Qdmy
#define VA_CLOSE(AP) } va_end(AP); }
#define VA_FIXEDARG(AP, T, N) struct Qdmy
#undef const
#undef volatile
#undef signed
/* inline requires special treatment; it's in C99, and GCC >=2.7 supports
it too, but it's not in C89. */
#undef inline
#if __STDC_VERSION__ >= 199901L || defined(__cplusplus) || (defined(__SUNPRO_C) && defined(__C99FEATURES__))
/* it's a keyword */
#else
# if GCC_VERSION >= 2007
# define inline __inline__ /* __inline__ prevents -pedantic warnings */
# else
# define inline /* nothing */
# endif
#endif
/* These are obsolete. Do not use. */
#ifndef IN_GCC
#define CONST const
#define VOLATILE volatile
#define SIGNED signed
#define PROTO(type, name, arglist) type name arglist
#define EXFUN(name, proto) name proto
#define DEFUN(name, arglist, args) name(args)
#define DEFUN_VOID(name) name(void)
#define AND ,
#define DOTS , ...
#define NOARGS void
#endif /* ! IN_GCC */
#else /* Not ANSI C. */
#undef ANSI_PROTOTYPES
#define PTR char *
#define PTRCONST PTR
#define LONG_DOUBLE double
#define PARAMS(args) ()
#define VPARAMS(args) (va_alist) va_dcl
#define VA_START(va_list, var) va_start(va_list)
#define VA_OPEN(AP, VAR) { va_list AP; va_start(AP); { struct Qdmy
#define VA_CLOSE(AP) } va_end(AP); }
#define VA_FIXEDARG(AP, TYPE, NAME) TYPE NAME = va_arg(AP, TYPE)
/* some systems define these in header files for non-ansi mode */
#undef const
#undef volatile
#undef signed
#undef inline
#define const
#define volatile
#define signed
#define inline
#ifndef IN_GCC
#define CONST
#define VOLATILE
#define SIGNED
#define PROTO(type, name, arglist) type name ()
#define EXFUN(name, proto) name()
#define DEFUN(name, arglist, args) name arglist args;
#define DEFUN_VOID(name) name()
#define AND ;
#define DOTS
#define NOARGS
#endif /* ! IN_GCC */
#endif /* ANSI C. */
/* Define macros for some gcc attributes. This permits us to use the
macros freely, and know that they will come into play for the
version of gcc in which they are supported. */
#if (GCC_VERSION < 2007)
# define __attribute__(x)
#endif
/* Attribute __malloc__ on functions was valid as of gcc 2.96. */
#ifndef ATTRIBUTE_MALLOC
# if (GCC_VERSION >= 2096)
# define ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
# else
# define ATTRIBUTE_MALLOC
# endif /* GNUC >= 2.96 */
#endif /* ATTRIBUTE_MALLOC */
/* Attributes on labels were valid as of gcc 2.93 and g++ 4.5. For
g++ an attribute on a label must be followed by a semicolon. */
#ifndef ATTRIBUTE_UNUSED_LABEL
# ifndef __cplusplus
# if GCC_VERSION >= 2093
# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED
# else
# define ATTRIBUTE_UNUSED_LABEL
# endif
# else
# if GCC_VERSION >= 4005
# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED ;
# else
# define ATTRIBUTE_UNUSED_LABEL
# endif
# endif
#endif
/* Similarly to ARG_UNUSED below. Prior to GCC 3.4, the C++ frontend
couldn't parse attributes placed after the identifier name, and now
the entire compiler is built with C++. */
#ifndef ATTRIBUTE_UNUSED
#if GCC_VERSION >= 3004
# define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
#else
#define ATTRIBUTE_UNUSED
#endif
#endif /* ATTRIBUTE_UNUSED */
/* Before GCC 3.4, the C++ frontend couldn't parse attributes placed after the
identifier name. */
#if ! defined(__cplusplus) || (GCC_VERSION >= 3004)
# define ARG_UNUSED(NAME) NAME ATTRIBUTE_UNUSED
#else /* !__cplusplus || GNUC >= 3.4 */
# define ARG_UNUSED(NAME) NAME
#endif /* !__cplusplus || GNUC >= 3.4 */
#ifndef ATTRIBUTE_NORETURN
#define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
#endif /* ATTRIBUTE_NORETURN */
/* Attribute `nonnull' was valid as of gcc 3.3. */
#ifndef ATTRIBUTE_NONNULL
# if (GCC_VERSION >= 3003)
# define ATTRIBUTE_NONNULL(m) __attribute__ ((__nonnull__ (m)))
# else
# define ATTRIBUTE_NONNULL(m)
# endif /* GNUC >= 3.3 */
#endif /* ATTRIBUTE_NONNULL */
/* Attribute `pure' was valid as of gcc 3.0. */
#ifndef ATTRIBUTE_PURE
# if (GCC_VERSION >= 3000)
# define ATTRIBUTE_PURE __attribute__ ((__pure__))
# else
# define ATTRIBUTE_PURE
# endif /* GNUC >= 3.0 */
#endif /* ATTRIBUTE_PURE */
/* Use ATTRIBUTE_PRINTF when the format specifier must not be NULL.
This was the case for the `printf' format attribute by itself
before GCC 3.3, but as of 3.3 we need to add the `nonnull'
attribute to retain this behavior. */
#ifndef ATTRIBUTE_PRINTF
#define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) ATTRIBUTE_NONNULL(m)
#define ATTRIBUTE_PRINTF_1 ATTRIBUTE_PRINTF(1, 2)
#define ATTRIBUTE_PRINTF_2 ATTRIBUTE_PRINTF(2, 3)
#define ATTRIBUTE_PRINTF_3 ATTRIBUTE_PRINTF(3, 4)
#define ATTRIBUTE_PRINTF_4 ATTRIBUTE_PRINTF(4, 5)
#define ATTRIBUTE_PRINTF_5 ATTRIBUTE_PRINTF(5, 6)
#endif /* ATTRIBUTE_PRINTF */
/* Use ATTRIBUTE_FPTR_PRINTF when the format attribute is to be set on
a function pointer. Format attributes were allowed on function
pointers as of gcc 3.1. */
#ifndef ATTRIBUTE_FPTR_PRINTF
# if (GCC_VERSION >= 3001)
# define ATTRIBUTE_FPTR_PRINTF(m, n) ATTRIBUTE_PRINTF(m, n)
# else
# define ATTRIBUTE_FPTR_PRINTF(m, n)
# endif /* GNUC >= 3.1 */
# define ATTRIBUTE_FPTR_PRINTF_1 ATTRIBUTE_FPTR_PRINTF(1, 2)
# define ATTRIBUTE_FPTR_PRINTF_2 ATTRIBUTE_FPTR_PRINTF(2, 3)
# define ATTRIBUTE_FPTR_PRINTF_3 ATTRIBUTE_FPTR_PRINTF(3, 4)
# define ATTRIBUTE_FPTR_PRINTF_4 ATTRIBUTE_FPTR_PRINTF(4, 5)
# define ATTRIBUTE_FPTR_PRINTF_5 ATTRIBUTE_FPTR_PRINTF(5, 6)
#endif /* ATTRIBUTE_FPTR_PRINTF */
/* Use ATTRIBUTE_NULL_PRINTF when the format specifier may be NULL. A
NULL format specifier was allowed as of gcc 3.3. */
#ifndef ATTRIBUTE_NULL_PRINTF
# if (GCC_VERSION >= 3003)
# define ATTRIBUTE_NULL_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n)))
# else
# define ATTRIBUTE_NULL_PRINTF(m, n)
# endif /* GNUC >= 3.3 */
# define ATTRIBUTE_NULL_PRINTF_1 ATTRIBUTE_NULL_PRINTF(1, 2)
# define ATTRIBUTE_NULL_PRINTF_2 ATTRIBUTE_NULL_PRINTF(2, 3)
# define ATTRIBUTE_NULL_PRINTF_3 ATTRIBUTE_NULL_PRINTF(3, 4)
# define ATTRIBUTE_NULL_PRINTF_4 ATTRIBUTE_NULL_PRINTF(4, 5)
# define ATTRIBUTE_NULL_PRINTF_5 ATTRIBUTE_NULL_PRINTF(5, 6)
#endif /* ATTRIBUTE_NULL_PRINTF */
/* Attribute `sentinel' was valid as of gcc 3.5. */
#ifndef ATTRIBUTE_SENTINEL
# if (GCC_VERSION >= 3005)
# define ATTRIBUTE_SENTINEL __attribute__ ((__sentinel__))
# else
# define ATTRIBUTE_SENTINEL
# endif /* GNUC >= 3.5 */
#endif /* ATTRIBUTE_SENTINEL */
#ifndef ATTRIBUTE_ALIGNED_ALIGNOF
# if (GCC_VERSION >= 3000)
# define ATTRIBUTE_ALIGNED_ALIGNOF(m) __attribute__ ((__aligned__ (__alignof__ (m))))
# else
# define ATTRIBUTE_ALIGNED_ALIGNOF(m)
# endif /* GNUC >= 3.0 */
#endif /* ATTRIBUTE_ALIGNED_ALIGNOF */
/* Useful for structures whose layout must much some binary specification
regardless of the alignment and padding qualities of the compiler. */
#ifndef ATTRIBUTE_PACKED
# define ATTRIBUTE_PACKED __attribute__ ((packed))
#endif
/* Attribute `hot' and `cold' was valid as of gcc 4.3. */
#ifndef ATTRIBUTE_COLD
# if (GCC_VERSION >= 4003)
# define ATTRIBUTE_COLD __attribute__ ((__cold__))
# else
# define ATTRIBUTE_COLD
# endif /* GNUC >= 4.3 */
#endif /* ATTRIBUTE_COLD */
#ifndef ATTRIBUTE_HOT
# if (GCC_VERSION >= 4003)
# define ATTRIBUTE_HOT __attribute__ ((__hot__))
# else
# define ATTRIBUTE_HOT
# endif /* GNUC >= 4.3 */
#endif /* ATTRIBUTE_HOT */
/* We use __extension__ in some places to suppress -pedantic warnings
about GCC extensions. This feature didn't work properly before
gcc 2.8. */
#if GCC_VERSION < 2008
#define __extension__
#endif
/* This is used to declare a const variable which should be visible
outside of the current compilation unit. Use it as
EXPORTED_CONST int i = 1;
This is because the semantics of const are different in C and C++.
"extern const" is permitted in C but it looks strange, and gcc
warns about it when -Wc++-compat is not used. */
#ifdef __cplusplus
#define EXPORTED_CONST extern const
#else
#define EXPORTED_CONST const
#endif
/* Be conservative and only use enum bitfields with C++ or GCC.
FIXME: provide a complete autoconf test for buggy enum bitfields. */
#ifdef __cplusplus
#define ENUM_BITFIELD(TYPE) enum TYPE
#elif (GCC_VERSION > 2000)
#define ENUM_BITFIELD(TYPE) __extension__ enum TYPE
#else
#define ENUM_BITFIELD(TYPE) unsigned int
#endif
#ifdef __cplusplus
}
#endif
#endif /* ansidecl.h */

View File

@ -0,0 +1,173 @@
/* ###
* IP: GPL 3 Linking Permitted
* REVIEWED: YES
*/
/* Internal demangler interface for g++ V3 ABI.
Copyright (C) 2003, 2004, 2005, 2006, 2007, 2010
Free Software Foundation, Inc.
Written by Ian Lance Taylor <ian@wasabisystems.com>.
This file is part of the libiberty library, which is part of GCC.
This file is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
In addition to the permissions in the GNU General Public License, the
Free Software Foundation gives you unlimited permission to link the
compiled version of this file into combinations with other programs,
and to distribute those combinations without any restriction coming
from the use of this file. (The General Public License restrictions
do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combined
executable.)
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
/* This file provides some definitions shared by cp-demangle.c and
cp-demint.c. It should not be included by any other files. */
/* Information we keep for operators. */
struct demangle_operator_info
{
/* Mangled name. */
const char *code;
/* Real name. */
const char *name;
/* Length of real name. */
int len;
/* Number of arguments. */
int args;
};
/* How to print the value of a builtin type. */
enum d_builtin_type_print
{
/* Print as (type)val. */
D_PRINT_DEFAULT,
/* Print as integer. */
D_PRINT_INT,
/* Print as unsigned integer, with trailing "u". */
D_PRINT_UNSIGNED,
/* Print as long, with trailing "l". */
D_PRINT_LONG,
/* Print as unsigned long, with trailing "ul". */
D_PRINT_UNSIGNED_LONG,
/* Print as long long, with trailing "ll". */
D_PRINT_LONG_LONG,
/* Print as unsigned long long, with trailing "ull". */
D_PRINT_UNSIGNED_LONG_LONG,
/* Print as bool. */
D_PRINT_BOOL,
/* Print as float--put value in square brackets. */
D_PRINT_FLOAT,
/* Print in usual way, but here to detect void. */
D_PRINT_VOID
};
/* Information we keep for a builtin type. */
struct demangle_builtin_type_info
{
/* Type name. */
const char *name;
/* Length of type name. */
int len;
/* Type name when using Java. */
const char *java_name;
/* Length of java name. */
int java_len;
/* How to print a value of this type. */
enum d_builtin_type_print print;
};
/* The information structure we pass around. */
struct d_info
{
/* The string we are demangling. */
const char *s;
/* The end of the string we are demangling. */
const char *send;
/* The options passed to the demangler. */
int options;
/* The next character in the string to consider. */
const char *n;
/* The array of components. */
struct demangle_component *comps;
/* The index of the next available component. */
int next_comp;
/* The number of available component structures. */
int num_comps;
/* The array of substitutions. */
struct demangle_component **subs;
/* The index of the next substitution. */
int next_sub;
/* The number of available entries in the subs array. */
int num_subs;
/* The number of substitutions which we actually made from the subs
array, plus the number of template parameter references we
saw. */
int did_subs;
/* The last name we saw, for constructors and destructors. */
struct demangle_component *last_name;
/* A running total of the length of large expansions from the
mangled name to the demangled name, such as standard
substitutions and builtin types. */
int expansion;
};
/* To avoid running past the ending '\0', don't:
- call d_peek_next_char if d_peek_char returned '\0'
- call d_advance with an 'i' that is too large
- call d_check_char(di, '\0')
Everything else is safe. */
#define d_peek_char(di) (*((di)->n))
#define d_peek_next_char(di) ((di)->n[1])
#define d_advance(di, i) ((di)->n += (i))
#define d_check_char(di, c) (d_peek_char(di) == c ? ((di)->n++, 1) : 0)
#define d_next_char(di) (d_peek_char(di) == '\0' ? '\0' : *((di)->n++))
#define d_str(di) ((di)->n)
/* Functions and arrays in cp-demangle.c which are referenced by
functions in cp-demint.c. */
#ifdef IN_GLIBCPP_V3
#define CP_STATIC_IF_GLIBCPP_V3 static
#else
#define CP_STATIC_IF_GLIBCPP_V3 extern
#endif
#ifndef IN_GLIBCPP_V3
extern const struct demangle_operator_info cplus_demangle_operators[];
#endif
#define D_BUILTIN_TYPE_COUNT (33)
CP_STATIC_IF_GLIBCPP_V3
const struct demangle_builtin_type_info
cplus_demangle_builtin_types[D_BUILTIN_TYPE_COUNT];
CP_STATIC_IF_GLIBCPP_V3
struct demangle_component *
cplus_demangle_mangled_name (struct d_info *, int);
CP_STATIC_IF_GLIBCPP_V3
struct demangle_component *
cplus_demangle_type (struct d_info *);
extern void
cplus_demangle_init_info (const char *, int, size_t, struct d_info *);
/* cp-demangle.c needs to define this a little differently */
#undef CP_STATIC_IF_GLIBCPP_V3

View File

@ -0,0 +1,675 @@
/* ###
* IP: LGPL 3.0
* REVIEWED: YES
*/
/* Defs for interface to demanglers.
Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002,
2003, 2004, 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License
as published by the Free Software Foundation; either version 2, or
(at your option) any later version.
In addition to the permissions in the GNU Library General Public
License, the Free Software Foundation gives you unlimited
permission to link the compiled version of this file into
combinations with other programs, and to distribute those
combinations without any restriction coming from the use of this
file. (The Library Public License restrictions do apply in other
respects; for example, they cover modification of the file, and
distribution when not linked into a combined executable.)
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
02110-1301, USA. */
#if !defined (DEMANGLE_H)
#define DEMANGLE_H
#include "libiberty.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* Options passed to cplus_demangle (in 2nd parameter). */
#define DMGL_NO_OPTS 0 /* For readability... */
#define DMGL_PARAMS (1 << 0) /* Include function args */
#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
#define DMGL_JAVA (1 << 2) /* Demangle as Java rather than C++. */
#define DMGL_VERBOSE (1 << 3) /* Include implementation details. */
#define DMGL_TYPES (1 << 4) /* Also try to demangle type encodings. */
#define DMGL_RET_POSTFIX (1 << 5) /* Print function return types (when
present) after function signature.
It applies only to the toplevel
function type. */
#define DMGL_RET_DROP (1 << 6) /* Suppress printing function return
types, even if present. It applies
only to the toplevel function type.
*/
#define DMGL_AUTO (1 << 8)
#define DMGL_GNU (1 << 9)
#define DMGL_LUCID (1 << 10)
#define DMGL_ARM (1 << 11)
#define DMGL_HP (1 << 12) /* For the HP aCC compiler;
same as ARM except for
template arguments, etc. */
#define DMGL_EDG (1 << 13)
#define DMGL_GNU_V3 (1 << 14)
#define DMGL_GNAT (1 << 15)
/* If none of these are set, use 'current_demangling_style' as the default. */
#define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU|DMGL_LUCID|DMGL_ARM|DMGL_HP|DMGL_EDG|DMGL_GNU_V3|DMGL_JAVA|DMGL_GNAT)
/* Enumeration of possible demangling styles.
Lucid and ARM styles are still kept logically distinct, even though
they now both behave identically. The resulting style is actual the
union of both. I.E. either style recognizes both "__pt__" and "__rf__"
for operator "->", even though the first is lucid style and the second
is ARM style. (FIXME?) */
extern enum demangling_styles
{
no_demangling = -1,
unknown_demangling = 0,
auto_demangling = DMGL_AUTO,
gnu_demangling = DMGL_GNU,
lucid_demangling = DMGL_LUCID,
arm_demangling = DMGL_ARM,
hp_demangling = DMGL_HP,
edg_demangling = DMGL_EDG,
gnu_v3_demangling = DMGL_GNU_V3,
java_demangling = DMGL_JAVA,
gnat_demangling = DMGL_GNAT
} current_demangling_style;
/* Define string names for the various demangling styles. */
#define NO_DEMANGLING_STYLE_STRING "none"
#define AUTO_DEMANGLING_STYLE_STRING "auto"
#define GNU_DEMANGLING_STYLE_STRING "gnu"
#define LUCID_DEMANGLING_STYLE_STRING "lucid"
#define ARM_DEMANGLING_STYLE_STRING "arm"
#define HP_DEMANGLING_STYLE_STRING "hp"
#define EDG_DEMANGLING_STYLE_STRING "edg"
#define GNU_V3_DEMANGLING_STYLE_STRING "gnu-v3"
#define JAVA_DEMANGLING_STYLE_STRING "java"
#define GNAT_DEMANGLING_STYLE_STRING "gnat"
/* Some macros to test what demangling style is active. */
#define CURRENT_DEMANGLING_STYLE current_demangling_style
#define AUTO_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_AUTO)
#define GNU_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNU)
#define LUCID_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_LUCID)
#define ARM_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_ARM)
#define HP_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_HP)
#define EDG_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_EDG)
#define GNU_V3_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNU_V3)
#define JAVA_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_JAVA)
#define GNAT_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNAT)
/* Provide information about the available demangle styles. This code is
pulled from gdb into libiberty because it is useful to binutils also. */
extern const struct demangler_engine
{
const char *const demangling_style_name;
const enum demangling_styles demangling_style;
const char *const demangling_style_doc;
} libiberty_demanglers[];
extern char *
cplus_demangle (const char *mangled, int options);
extern int
cplus_demangle_opname (const char *opname, char *result, int options);
extern const char *
cplus_mangle_opname (const char *opname, int options);
/* Note: This sets global state. FIXME if you care about multi-threading. */
extern void
set_cplus_marker_for_demangling (int ch);
extern enum demangling_styles
cplus_demangle_set_style (enum demangling_styles style);
extern enum demangling_styles
cplus_demangle_name_to_style (const char *name);
/* Callback typedef for allocation-less demangler interfaces. */
typedef void (*demangle_callbackref) (const char *, size_t, void *);
/* V3 ABI demangling entry points, defined in cp-demangle.c. Callback
variants return non-zero on success, zero on error. char* variants
return a string allocated by malloc on success, NULL on error. */
extern int
cplus_demangle_v3_callback (const char *mangled, int options,
demangle_callbackref callback, void *opaque);
extern char*
cplus_demangle_v3 (const char *mangled, int options);
extern int
java_demangle_v3_callback (const char *mangled,
demangle_callbackref callback, void *opaque);
extern char*
java_demangle_v3 (const char *mangled);
char *
ada_demangle (const char *mangled, int options);
enum gnu_v3_ctor_kinds {
gnu_v3_complete_object_ctor = 1,
gnu_v3_base_object_ctor,
gnu_v3_complete_object_allocating_ctor,
gnu_v3_object_ctor_group
};
/* Return non-zero iff NAME is the mangled form of a constructor name
in the G++ V3 ABI demangling style. Specifically, return an `enum
gnu_v3_ctor_kinds' value indicating what kind of constructor
it is. */
extern enum gnu_v3_ctor_kinds
is_gnu_v3_mangled_ctor (const char *name);
enum gnu_v3_dtor_kinds {
gnu_v3_deleting_dtor = 1,
gnu_v3_complete_object_dtor,
gnu_v3_base_object_dtor,
gnu_v3_object_dtor_group
};
/* Return non-zero iff NAME is the mangled form of a destructor name
in the G++ V3 ABI demangling style. Specifically, return an `enum
gnu_v3_dtor_kinds' value, indicating what kind of destructor
it is. */
extern enum gnu_v3_dtor_kinds
is_gnu_v3_mangled_dtor (const char *name);
/* The V3 demangler works in two passes. The first pass builds a tree
representation of the mangled name, and the second pass turns the
tree representation into a demangled string. Here we define an
interface to permit a caller to build their own tree
representation, which they can pass to the demangler to get a
demangled string. This can be used to canonicalize user input into
something which the demangler might output. It could also be used
by other demanglers in the future. */
/* These are the component types which may be found in the tree. Many
component types have one or two subtrees, referred to as left and
right (a component type with only one subtree puts it in the left
subtree). */
enum demangle_component_type
{
/* A name, with a length and a pointer to a string. */
DEMANGLE_COMPONENT_NAME,
/* A qualified name. The left subtree is a class or namespace or
some such thing, and the right subtree is a name qualified by
that class. */
DEMANGLE_COMPONENT_QUAL_NAME,
/* A local name. The left subtree describes a function, and the
right subtree is a name which is local to that function. */
DEMANGLE_COMPONENT_LOCAL_NAME,
/* A typed name. The left subtree is a name, and the right subtree
describes that name as a function. */
DEMANGLE_COMPONENT_TYPED_NAME,
/* A template. The left subtree is a template name, and the right
subtree is a template argument list. */
DEMANGLE_COMPONENT_TEMPLATE,
/* A template parameter. This holds a number, which is the template
parameter index. */
DEMANGLE_COMPONENT_TEMPLATE_PARAM,
/* A function parameter. This holds a number, which is the index. */
DEMANGLE_COMPONENT_FUNCTION_PARAM,
/* A constructor. This holds a name and the kind of
constructor. */
DEMANGLE_COMPONENT_CTOR,
/* A destructor. This holds a name and the kind of destructor. */
DEMANGLE_COMPONENT_DTOR,
/* A vtable. This has one subtree, the type for which this is a
vtable. */
DEMANGLE_COMPONENT_VTABLE,
/* A VTT structure. This has one subtree, the type for which this
is a VTT. */
DEMANGLE_COMPONENT_VTT,
/* A construction vtable. The left subtree is the type for which
this is a vtable, and the right subtree is the derived type for
which this vtable is built. */
DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE,
/* A typeinfo structure. This has one subtree, the type for which
this is the tpeinfo structure. */
DEMANGLE_COMPONENT_TYPEINFO,
/* A typeinfo name. This has one subtree, the type for which this
is the typeinfo name. */
DEMANGLE_COMPONENT_TYPEINFO_NAME,
/* A typeinfo function. This has one subtree, the type for which
this is the tpyeinfo function. */
DEMANGLE_COMPONENT_TYPEINFO_FN,
/* A thunk. This has one subtree, the name for which this is a
thunk. */
DEMANGLE_COMPONENT_THUNK,
/* A virtual thunk. This has one subtree, the name for which this
is a virtual thunk. */
DEMANGLE_COMPONENT_VIRTUAL_THUNK,
/* A covariant thunk. This has one subtree, the name for which this
is a covariant thunk. */
DEMANGLE_COMPONENT_COVARIANT_THUNK,
/* A Java class. This has one subtree, the type. */
DEMANGLE_COMPONENT_JAVA_CLASS,
/* A guard variable. This has one subtree, the name for which this
is a guard variable. */
DEMANGLE_COMPONENT_GUARD,
/* The init and wrapper functions for C++11 thread_local variables. */
DEMANGLE_COMPONENT_TLS_INIT,
DEMANGLE_COMPONENT_TLS_WRAPPER,
/* A reference temporary. This has one subtree, the name for which
this is a temporary. */
DEMANGLE_COMPONENT_REFTEMP,
/* A hidden alias. This has one subtree, the encoding for which it
is providing alternative linkage. */
DEMANGLE_COMPONENT_HIDDEN_ALIAS,
/* A standard substitution. This holds the name of the
substitution. */
DEMANGLE_COMPONENT_SUB_STD,
/* The restrict qualifier. The one subtree is the type which is
being qualified. */
DEMANGLE_COMPONENT_RESTRICT,
/* The volatile qualifier. The one subtree is the type which is
being qualified. */
DEMANGLE_COMPONENT_VOLATILE,
/* The const qualifier. The one subtree is the type which is being
qualified. */
DEMANGLE_COMPONENT_CONST,
/* The restrict qualifier modifying a member function. The one
subtree is the type which is being qualified. */
DEMANGLE_COMPONENT_RESTRICT_THIS,
/* The volatile qualifier modifying a member function. The one
subtree is the type which is being qualified. */
DEMANGLE_COMPONENT_VOLATILE_THIS,
/* The const qualifier modifying a member function. The one subtree
is the type which is being qualified. */
DEMANGLE_COMPONENT_CONST_THIS,
/* C++11 A reference modifying a member function. The one subtree is the
type which is being referenced. */
DEMANGLE_COMPONENT_REFERENCE_THIS,
/* C++11: An rvalue reference modifying a member function. The one
subtree is the type which is being referenced. */
DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS,
/* A vendor qualifier. The left subtree is the type which is being
qualified, and the right subtree is the name of the
qualifier. */
DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL,
/* A pointer. The one subtree is the type which is being pointed
to. */
DEMANGLE_COMPONENT_POINTER,
/* A reference. The one subtree is the type which is being
referenced. */
DEMANGLE_COMPONENT_REFERENCE,
/* C++0x: An rvalue reference. The one subtree is the type which is
being referenced. */
DEMANGLE_COMPONENT_RVALUE_REFERENCE,
/* A complex type. The one subtree is the base type. */
DEMANGLE_COMPONENT_COMPLEX,
/* An imaginary type. The one subtree is the base type. */
DEMANGLE_COMPONENT_IMAGINARY,
/* A builtin type. This holds the builtin type information. */
DEMANGLE_COMPONENT_BUILTIN_TYPE,
/* A vendor's builtin type. This holds the name of the type. */
DEMANGLE_COMPONENT_VENDOR_TYPE,
/* A function type. The left subtree is the return type. The right
subtree is a list of ARGLIST nodes. Either or both may be
NULL. */
DEMANGLE_COMPONENT_FUNCTION_TYPE,
/* An array type. The left subtree is the dimension, which may be
NULL, or a string (represented as DEMANGLE_COMPONENT_NAME), or an
expression. The right subtree is the element type. */
DEMANGLE_COMPONENT_ARRAY_TYPE,
/* A pointer to member type. The left subtree is the class type,
and the right subtree is the member type. CV-qualifiers appear
on the latter. */
DEMANGLE_COMPONENT_PTRMEM_TYPE,
/* A fixed-point type. */
DEMANGLE_COMPONENT_FIXED_TYPE,
/* A vector type. The left subtree is the number of elements,
the right subtree is the element type. */
DEMANGLE_COMPONENT_VECTOR_TYPE,
/* An argument list. The left subtree is the current argument, and
the right subtree is either NULL or another ARGLIST node. */
DEMANGLE_COMPONENT_ARGLIST,
/* A template argument list. The left subtree is the current
template argument, and the right subtree is either NULL or
another TEMPLATE_ARGLIST node. */
DEMANGLE_COMPONENT_TEMPLATE_ARGLIST,
/* An initializer list. The left subtree is either an explicit type or
NULL, and the right subtree is a DEMANGLE_COMPONENT_ARGLIST. */
DEMANGLE_COMPONENT_INITIALIZER_LIST,
/* An operator. This holds information about a standard
operator. */
DEMANGLE_COMPONENT_OPERATOR,
/* An extended operator. This holds the number of arguments, and
the name of the extended operator. */
DEMANGLE_COMPONENT_EXTENDED_OPERATOR,
/* A typecast, represented as a unary operator. The one subtree is
the type to which the argument should be cast. */
DEMANGLE_COMPONENT_CAST,
/* A nullary expression. The left subtree is the operator. */
DEMANGLE_COMPONENT_NULLARY,
/* A unary expression. The left subtree is the operator, and the
right subtree is the single argument. */
DEMANGLE_COMPONENT_UNARY,
/* A binary expression. The left subtree is the operator, and the
right subtree is a BINARY_ARGS. */
DEMANGLE_COMPONENT_BINARY,
/* Arguments to a binary expression. The left subtree is the first
argument, and the right subtree is the second argument. */
DEMANGLE_COMPONENT_BINARY_ARGS,
/* A trinary expression. The left subtree is the operator, and the
right subtree is a TRINARY_ARG1. */
DEMANGLE_COMPONENT_TRINARY,
/* Arguments to a trinary expression. The left subtree is the first
argument, and the right subtree is a TRINARY_ARG2. */
DEMANGLE_COMPONENT_TRINARY_ARG1,
/* More arguments to a trinary expression. The left subtree is the
second argument, and the right subtree is the third argument. */
DEMANGLE_COMPONENT_TRINARY_ARG2,
/* A literal. The left subtree is the type, and the right subtree
is the value, represented as a DEMANGLE_COMPONENT_NAME. */
DEMANGLE_COMPONENT_LITERAL,
/* A negative literal. Like LITERAL, but the value is negated.
This is a minor hack: the NAME used for LITERAL points directly
to the mangled string, but since negative numbers are mangled
using 'n' instead of '-', we want a way to indicate a negative
number which involves neither modifying the mangled string nor
allocating a new copy of the literal in memory. */
DEMANGLE_COMPONENT_LITERAL_NEG,
/* A libgcj compiled resource. The left subtree is the name of the
resource. */
DEMANGLE_COMPONENT_JAVA_RESOURCE,
/* A name formed by the concatenation of two parts. The left
subtree is the first part and the right subtree the second. */
DEMANGLE_COMPONENT_COMPOUND_NAME,
/* A name formed by a single character. */
DEMANGLE_COMPONENT_CHARACTER,
/* A number. */
DEMANGLE_COMPONENT_NUMBER,
/* A decltype type. */
DEMANGLE_COMPONENT_DECLTYPE,
/* Global constructors keyed to name. */
DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS,
/* Global destructors keyed to name. */
DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS,
/* A lambda closure type. */
DEMANGLE_COMPONENT_LAMBDA,
/* A default argument scope. */
DEMANGLE_COMPONENT_DEFAULT_ARG,
/* An unnamed type. */
DEMANGLE_COMPONENT_UNNAMED_TYPE,
/* A transactional clone. This has one subtree, the encoding for
which it is providing alternative linkage. */
DEMANGLE_COMPONENT_TRANSACTION_CLONE,
/* A non-transactional clone entry point. In the i386/x86_64 abi,
the unmangled symbol of a tm_callable becomes a thunk and the
non-transactional function version is mangled thus. */
DEMANGLE_COMPONENT_NONTRANSACTION_CLONE,
/* A pack expansion. */
DEMANGLE_COMPONENT_PACK_EXPANSION,
/* A name with an ABI tag. */
DEMANGLE_COMPONENT_TAGGED_NAME,
/* A cloned function. */
DEMANGLE_COMPONENT_CLONE
};
/* Types which are only used internally. */
struct demangle_operator_info;
struct demangle_builtin_type_info;
/* A node in the tree representation is an instance of a struct
demangle_component. Note that the field names of the struct are
not well protected against macros defined by the file including
this one. We can fix this if it ever becomes a problem. */
struct demangle_component
{
/* The type of this component. */
enum demangle_component_type type;
union
{
/* For DEMANGLE_COMPONENT_NAME. */
struct
{
/* A pointer to the name (which need not NULL terminated) and
its length. */
const char *s;
int len;
} s_name;
/* For DEMANGLE_COMPONENT_OPERATOR. */
struct
{
/* Operator. */
const struct demangle_operator_info *op;
} s_operator;
/* For DEMANGLE_COMPONENT_EXTENDED_OPERATOR. */
struct
{
/* Number of arguments. */
int args;
/* Name. */
struct demangle_component *name;
} s_extended_operator;
/* For DEMANGLE_COMPONENT_FIXED_TYPE. */
struct
{
/* The length, indicated by a C integer type name. */
struct demangle_component *length;
/* _Accum or _Fract? */
short accum;
/* Saturating or not? */
short sat;
} s_fixed;
/* For DEMANGLE_COMPONENT_CTOR. */
struct
{
/* Kind of constructor. */
enum gnu_v3_ctor_kinds kind;
/* Name. */
struct demangle_component *name;
} s_ctor;
/* For DEMANGLE_COMPONENT_DTOR. */
struct
{
/* Kind of destructor. */
enum gnu_v3_dtor_kinds kind;
/* Name. */
struct demangle_component *name;
} s_dtor;
/* For DEMANGLE_COMPONENT_BUILTIN_TYPE. */
struct
{
/* Builtin type. */
const struct demangle_builtin_type_info *type;
} s_builtin;
/* For DEMANGLE_COMPONENT_SUB_STD. */
struct
{
/* Standard substitution string. */
const char* string;
/* Length of string. */
int len;
} s_string;
/* For DEMANGLE_COMPONENT_*_PARAM. */
struct
{
/* Parameter index. */
long number;
} s_number;
/* For DEMANGLE_COMPONENT_CHARACTER. */
struct
{
int character;
} s_character;
/* For other types. */
struct
{
/* Left (or only) subtree. */
struct demangle_component *left;
/* Right subtree. */
struct demangle_component *right;
} s_binary;
struct
{
/* subtree, same place as d_left. */
struct demangle_component *sub;
/* integer. */
int num;
} s_unary_num;
} u;
};
/* People building mangled trees are expected to allocate instances of
struct demangle_component themselves. They can then call one of
the following functions to fill them in. */
/* Fill in most component types with a left subtree and a right
subtree. Returns non-zero on success, zero on failure, such as an
unrecognized or inappropriate component type. */
extern int
cplus_demangle_fill_component (struct demangle_component *fill,
enum demangle_component_type,
struct demangle_component *left,
struct demangle_component *right);
/* Fill in a DEMANGLE_COMPONENT_NAME. Returns non-zero on success,
zero for bad arguments. */
extern int
cplus_demangle_fill_name (struct demangle_component *fill,
const char *, int);
/* Fill in a DEMANGLE_COMPONENT_BUILTIN_TYPE, using the name of the
builtin type (e.g., "int", etc.). Returns non-zero on success,
zero if the type is not recognized. */
extern int
cplus_demangle_fill_builtin_type (struct demangle_component *fill,
const char *type_name);
/* Fill in a DEMANGLE_COMPONENT_OPERATOR, using the name of the
operator and the number of arguments which it takes (the latter is
used to disambiguate operators which can be both binary and unary,
such as '-'). Returns non-zero on success, zero if the operator is
not recognized. */
extern int
cplus_demangle_fill_operator (struct demangle_component *fill,
const char *opname, int args);
/* Fill in a DEMANGLE_COMPONENT_EXTENDED_OPERATOR, providing the
number of arguments and the name. Returns non-zero on success,
zero for bad arguments. */
extern int
cplus_demangle_fill_extended_operator (struct demangle_component *fill,
int numargs,
struct demangle_component *nm);
/* Fill in a DEMANGLE_COMPONENT_CTOR. Returns non-zero on success,
zero for bad arguments. */
extern int
cplus_demangle_fill_ctor (struct demangle_component *fill,
enum gnu_v3_ctor_kinds kind,
struct demangle_component *name);
/* Fill in a DEMANGLE_COMPONENT_DTOR. Returns non-zero on success,
zero for bad arguments. */
extern int
cplus_demangle_fill_dtor (struct demangle_component *fill,
enum gnu_v3_dtor_kinds kind,
struct demangle_component *name);
/* This function translates a mangled name into a struct
demangle_component tree. The first argument is the mangled name.
The second argument is DMGL_* options. This returns a pointer to a
tree on success, or NULL on failure. On success, the third
argument is set to a block of memory allocated by malloc. This
block should be passed to free when the tree is no longer
needed. */
extern struct demangle_component *
cplus_demangle_v3_components (const char *mangled, int options, void **mem);
/* This function takes a struct demangle_component tree and returns
the corresponding demangled string. The first argument is DMGL_*
options. The second is the tree to demangle. The third is a guess
at the length of the demangled string, used to initially allocate
the return buffer. The fourth is a pointer to a size_t. On
success, this function returns a buffer allocated by malloc(), and
sets the size_t pointed to by the fourth argument to the size of
the allocated buffer (not the length of the returned string). On
failure, this function returns NULL, and sets the size_t pointed to
by the fourth argument to 0 for an invalid tree, or to 1 for a
memory allocation error. */
extern char *
cplus_demangle_print (int options,
const struct demangle_component *tree,
int estimated_length,
size_t *p_allocated_size);
/* This function takes a struct demangle_component tree and passes back
a demangled string in one or more calls to a callback function.
The first argument is DMGL_* options. The second is the tree to
demangle. The third is a pointer to a callback function; on each call
this receives an element of the demangled string, its length, and an
opaque value. The fourth is the opaque value passed to the callback.
The callback is called once or more to return the full demangled
string. The demangled element string is always nul-terminated, though
its length is also provided for convenience. In contrast to
cplus_demangle_print(), this function does not allocate heap memory
to grow output strings (except perhaps where alloca() is implemented
by malloc()), and so is normally safe for use where the heap has been
corrupted. On success, this function returns 1; on failure, 0. */
extern int
cplus_demangle_print_callback (int options,
const struct demangle_component *tree,
demangle_callbackref callback, void *opaque);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* DEMANGLE_H */

View File

@ -0,0 +1,77 @@
/* ###
* IP: GPL 3
* REVIEWED: YES
*/
/* An abstract string datatype.
Copyright (C) 1998, 1999, 2000, 2002, 2004, 2005, 2009
Free Software Foundation, Inc.
Contributed by Mark Mitchell (mark@markmitchell.com).
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 51 Franklin Street - Fifth Floor,
Boston, MA 02110-1301, USA. */
#ifndef DYN_STRING_H
#define DYN_STRING_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct dyn_string
{
int allocated; /* The amount of space allocated for the string. */
int length; /* The actual length of the string. */
char *s; /* The string itself, NUL-terminated. */
}* dyn_string_t;
/* The length STR, in bytes, not including the terminating NUL. */
#define dyn_string_length(STR) \
((STR)->length)
/* The NTBS in which the contents of STR are stored. */
#define dyn_string_buf(STR) \
((STR)->s)
/* Compare DS1 to DS2 with strcmp. */
#define dyn_string_compare(DS1, DS2) \
(strcmp ((DS1)->s, (DS2)->s))
extern int dyn_string_init (struct dyn_string *, int);
extern dyn_string_t dyn_string_new (int);
extern void dyn_string_delete (dyn_string_t);
extern char *dyn_string_release (dyn_string_t);
extern dyn_string_t dyn_string_resize (dyn_string_t, int);
extern void dyn_string_clear (dyn_string_t);
extern int dyn_string_copy (dyn_string_t, dyn_string_t);
extern int dyn_string_copy_cstr (dyn_string_t, const char *);
extern int dyn_string_prepend (dyn_string_t, dyn_string_t);
extern int dyn_string_prepend_cstr (dyn_string_t, const char *);
extern int dyn_string_insert (dyn_string_t, int, dyn_string_t);
extern int dyn_string_insert_cstr (dyn_string_t, int, const char *);
extern int dyn_string_insert_char (dyn_string_t, int, int);
extern int dyn_string_append (dyn_string_t, dyn_string_t);
extern int dyn_string_append_cstr (dyn_string_t, const char *);
extern int dyn_string_append_char (dyn_string_t, int);
extern int dyn_string_substring (dyn_string_t, dyn_string_t, int, int);
extern int dyn_string_eq (dyn_string_t, dyn_string_t);
#ifdef __cplusplus
}
#endif
#endif /* !defined (DYN_STRING_H) */

View File

@ -0,0 +1,148 @@
/* ###
* IP: GPL 3
* REVIEWED: YES
*/
/* Declarations for getopt.
Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 2000,
2002 Free Software Foundation, Inc.
NOTE: The canonical source of this file is maintained with the GNU C Library.
Bugs can be reported to bug-glibc@gnu.org.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
USA. */
#ifndef _GETOPT_H
#define _GETOPT_H 1
#ifdef __cplusplus
extern "C" {
#endif
/* For communication from `getopt' to the caller.
When `getopt' finds an option that takes an argument,
the argument value is returned here.
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
extern char *optarg;
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
and for communication between successive calls to `getopt'.
On entry to `getopt', zero means this is the first call; initialize.
When `getopt' returns -1, this is the index of the first of the
non-option elements that the caller should itself scan.
Otherwise, `optind' communicates from one call to the next
how much of ARGV has been scanned so far. */
extern int optind;
/* Callers store zero here to inhibit the error message `getopt' prints
for unrecognized options. */
extern int opterr;
/* Set to an option character which was unrecognized. */
extern int optopt;
/* Describe the long-named options requested by the application.
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
of `struct option' terminated by an element containing a name which is
zero.
The field `has_arg' is:
no_argument (or 0) if the option does not take an argument,
required_argument (or 1) if the option requires an argument,
optional_argument (or 2) if the option takes an optional argument.
If the field `flag' is not NULL, it points to a variable that is set
to the value given in the field `val' when the option is found, but
left unchanged if the option is not found.
To have a long-named option do something other than set an `int' to
a compiled-in constant, such as set a value from `optarg', set the
option's `flag' field to zero and its `val' field to a nonzero
value (the equivalent single-letter option character, if there is
one). For long options that have a zero `flag' field, `getopt'
returns the contents of the `val' field. */
struct option
{
#if defined (__STDC__) && __STDC__
const char *name;
#else
char *name;
#endif
/* has_arg can't be an enum because some compilers complain about
type mismatches in all the code that assumes it is an int. */
int has_arg;
int *flag;
int val;
};
/* Names for the values of the `has_arg' field of `struct option'. */
#define no_argument 0
#define required_argument 1
#define optional_argument 2
#if defined (__STDC__) && __STDC__
/* HAVE_DECL_* is a three-state macro: undefined, 0 or 1. If it is
undefined, we haven't run the autoconf check so provide the
declaration without arguments. If it is 0, we checked and failed
to find the declaration so provide a fully prototyped one. If it
is 1, we found it so don't provide any declaration at all. */
#if !HAVE_DECL_GETOPT
#if defined (__GNU_LIBRARY__) || defined (HAVE_DECL_GETOPT)
/* Many other libraries have conflicting prototypes for getopt, with
differences in the consts, in unistd.h. To avoid compilation
errors, only prototype getopt for the GNU C library. */
extern int getopt (int argc, char *const *argv, const char *shortopts);
#else
#ifndef __cplusplus
extern int getopt ();
#endif /* __cplusplus */
#endif
#endif /* !HAVE_DECL_GETOPT */
extern int getopt_long (int argc, char *const *argv, const char *shortopts,
const struct option *longopts, int *longind);
extern int getopt_long_only (int argc, char *const *argv,
const char *shortopts,
const struct option *longopts, int *longind);
/* Internal only. Users should not call this directly. */
extern int _getopt_internal (int argc, char *const *argv,
const char *shortopts,
const struct option *longopts, int *longind,
int long_only);
#else /* not __STDC__ */
extern int getopt ();
extern int getopt_long ();
extern int getopt_long_only ();
extern int _getopt_internal ();
#endif /* __STDC__ */
#ifdef __cplusplus
}
#endif
#endif /* getopt.h */

View File

@ -0,0 +1,690 @@
/* ###
* IP: GPL 3
* REVIEWED: YES
*/
/* Function declarations for libiberty.
Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
Note - certain prototypes declared in this header file are for
functions whoes implementation copyright does not belong to the
FSF. Those prototypes are present in this file for reference
purposes only and their presence in this file should not construed
as an indication of ownership by the FSF of the implementation of
those functions in any way or form whatsoever.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor,
Boston, MA 02110-1301, USA.
Written by Cygnus Support, 1994.
The libiberty library provides a number of functions which are
missing on some operating systems. We do not declare those here,
to avoid conflicts with the system header files on operating
systems that do support those functions. In this file we only
declare those functions which are specific to libiberty. */
#ifndef LIBIBERTY_H
#define LIBIBERTY_H
#ifdef __cplusplus
extern "C" {
#endif
#include "ansidecl.h"
/* Get a definition for size_t. */
#include <stddef.h>
/* Get a definition for va_list. */
#include <stdarg.h>
#include <stdio.h>
/* If the OS supports it, ensure that the supplied stream is setup to
avoid any multi-threaded locking. Otherwise leave the FILE pointer
unchanged. If the stream is NULL do nothing. */
extern void unlock_stream (FILE *);
/* If the OS supports it, ensure that the standard I/O streams, stdin,
stdout and stderr are setup to avoid any multi-threaded locking.
Otherwise do nothing. */
extern void unlock_std_streams (void);
/* Open and return a FILE pointer. If the OS supports it, ensure that
the stream is setup to avoid any multi-threaded locking. Otherwise
return the FILE pointer unchanged. */
extern FILE *fopen_unlocked (const char *, const char *);
extern FILE *fdopen_unlocked (int, const char *);
extern FILE *freopen_unlocked (const char *, const char *, FILE *);
/* Build an argument vector from a string. Allocates memory using
malloc. Use freeargv to free the vector. */
extern char **buildargv (const char *) ATTRIBUTE_MALLOC;
/* Free a vector returned by buildargv. */
extern void freeargv (char **);
/* Duplicate an argument vector. Allocates memory using malloc. Use
freeargv to free the vector. */
extern char **dupargv (char **) ATTRIBUTE_MALLOC;
/* Expand "@file" arguments in argv. */
extern void expandargv PARAMS ((int *, char ***));
/* Write argv to an @-file, inserting necessary quoting. */
extern int writeargv PARAMS ((char **, FILE *));
/* Return the number of elements in argv. */
extern int countargv (char**);
/* Return the last component of a path name. Note that we can't use a
prototype here because the parameter is declared inconsistently
across different systems, sometimes as "char *" and sometimes as
"const char *" */
/* HAVE_DECL_* is a three-state macro: undefined, 0 or 1. If it is
undefined, we haven't run the autoconf check so provide the
declaration without arguments. If it is 0, we checked and failed
to find the declaration so provide a fully prototyped one. If it
is 1, we found it so don't provide any declaration at all. */
#if !HAVE_DECL_BASENAME
#if defined (__GNU_LIBRARY__ ) || defined (__linux__) || defined (__FreeBSD__) || defined (__OpenBSD__) || defined(__NetBSD__) || defined (__CYGWIN__) || defined (__CYGWIN32__) || defined (__MINGW32__) || defined (HAVE_DECL_BASENAME)
extern char *basename (const char *);
#else
/* Do not allow basename to be used if there is no prototype seen. We
either need to use the above prototype or have one from
autoconf which would result in HAVE_DECL_BASENAME being set. */
#define basename basename_cannot_be_used_without_a_prototype
#endif
#endif
/* A well-defined basename () that is always compiled in. */
extern const char *lbasename (const char *);
/* Same, but assumes DOS semantics (drive name, backslash is also a
dir separator) regardless of host. */
extern const char *dos_lbasename (const char *);
/* Same, but assumes Unix semantics (absolute paths always start with
a slash, only forward slash is accepted as dir separator)
regardless of host. */
extern const char *unix_lbasename (const char *);
/* A well-defined realpath () that is always compiled in. */
extern char *lrealpath (const char *);
/* Concatenate an arbitrary number of strings. You must pass NULL as
the last argument of this function, to terminate the list of
strings. Allocates memory using xmalloc. */
extern char *concat (const char *, ...) ATTRIBUTE_MALLOC ATTRIBUTE_SENTINEL;
/* Concatenate an arbitrary number of strings. You must pass NULL as
the last argument of this function, to terminate the list of
strings. Allocates memory using xmalloc. The first argument is
not one of the strings to be concatenated, but if not NULL is a
pointer to be freed after the new string is created, similar to the
way xrealloc works. */
extern char *reconcat (char *, const char *, ...) ATTRIBUTE_MALLOC ATTRIBUTE_SENTINEL;
/* Determine the length of concatenating an arbitrary number of
strings. You must pass NULL as the last argument of this function,
to terminate the list of strings. */
extern unsigned long concat_length (const char *, ...) ATTRIBUTE_SENTINEL;
/* Concatenate an arbitrary number of strings into a SUPPLIED area of
memory. You must pass NULL as the last argument of this function,
to terminate the list of strings. The supplied memory is assumed
to be large enough. */
extern char *concat_copy (char *, const char *, ...) ATTRIBUTE_SENTINEL;
/* Concatenate an arbitrary number of strings into a GLOBAL area of
memory. You must pass NULL as the last argument of this function,
to terminate the list of strings. The supplied memory is assumed
to be large enough. */
extern char *concat_copy2 (const char *, ...) ATTRIBUTE_SENTINEL;
/* This is the global area used by concat_copy2. */
extern char *libiberty_concat_ptr;
/* Concatenate an arbitrary number of strings. You must pass NULL as
the last argument of this function, to terminate the list of
strings. Allocates memory using alloca. The arguments are
evaluated twice! */
#define ACONCAT(ACONCAT_PARAMS) \
(libiberty_concat_ptr = (char *) alloca (concat_length ACONCAT_PARAMS + 1), \
concat_copy2 ACONCAT_PARAMS)
/* Check whether two file descriptors refer to the same file. */
extern int fdmatch (int fd1, int fd2);
/* Return the position of the first bit set in the argument. */
/* Prototypes vary from system to system, so we only provide a
prototype on systems where we know that we need it. */
#if defined (HAVE_DECL_FFS) && !HAVE_DECL_FFS
extern int ffs(int);
#endif
/* Get the working directory. The result is cached, so don't call
chdir() between calls to getpwd(). */
extern char * getpwd (void);
/* Get the current time. */
/* Prototypes vary from system to system, so we only provide a
prototype on systems where we know that we need it. */
#ifdef __MINGW32__
/* Forward declaration to avoid #include <sys/time.h>. */
struct timeval;
extern int gettimeofday (struct timeval *, void *);
#endif
/* Get the amount of time the process has run, in microseconds. */
extern long get_run_time (void);
/* Generate a relocated path to some installation directory. Allocates
return value using malloc. */
extern char *make_relative_prefix (const char *, const char *,
const char *) ATTRIBUTE_MALLOC;
/* Generate a relocated path to some installation directory without
attempting to follow any soft links. Allocates
return value using malloc. */
extern char *make_relative_prefix_ignore_links (const char *, const char *,
const char *) ATTRIBUTE_MALLOC;
/* Choose a temporary directory to use for scratch files. */
extern char *choose_temp_base (void) ATTRIBUTE_MALLOC;
/* Return a temporary file name or NULL if unable to create one. */
extern char *make_temp_file (const char *) ATTRIBUTE_MALLOC;
/* Remove a link to a file unless it is special. */
extern int unlink_if_ordinary (const char *);
/* Allocate memory filled with spaces. Allocates using malloc. */
extern const char *spaces (int count);
/* Return the maximum error number for which strerror will return a
string. */
extern int errno_max (void);
/* Return the name of an errno value (e.g., strerrno (EINVAL) returns
"EINVAL"). */
extern const char *strerrno (int);
/* Given the name of an errno value, return the value. */
extern int strtoerrno (const char *);
/* ANSI's strerror(), but more robust. */
extern char *xstrerror (int);
/* Return the maximum signal number for which strsignal will return a
string. */
extern int signo_max (void);
/* Return a signal message string for a signal number
(e.g., strsignal (SIGHUP) returns something like "Hangup"). */
/* This is commented out as it can conflict with one in system headers.
We still document its existence though. */
/*extern const char *strsignal (int);*/
/* Return the name of a signal number (e.g., strsigno (SIGHUP) returns
"SIGHUP"). */
extern const char *strsigno (int);
/* Given the name of a signal, return its number. */
extern int strtosigno (const char *);
/* Register a function to be run by xexit. Returns 0 on success. */
extern int xatexit (void (*fn) (void));
/* Exit, calling all the functions registered with xatexit. */
extern void xexit (int status) ATTRIBUTE_NORETURN;
/* Set the program name used by xmalloc. */
extern void xmalloc_set_program_name (const char *);
/* Report an allocation failure. */
extern void xmalloc_failed (size_t) ATTRIBUTE_NORETURN;
/* Allocate memory without fail. If malloc fails, this will print a
message to stderr (using the name set by xmalloc_set_program_name,
if any) and then call xexit. */
extern void *xmalloc (size_t) ATTRIBUTE_MALLOC;
/* Reallocate memory without fail. This works like xmalloc. Note,
realloc type functions are not suitable for attribute malloc since
they may return the same address across multiple calls. */
extern void *xrealloc (void *, size_t);
/* Allocate memory without fail and set it to zero. This works like
xmalloc. */
extern void *xcalloc (size_t, size_t) ATTRIBUTE_MALLOC;
/* Copy a string into a memory buffer without fail. */
extern char *xstrdup (const char *) ATTRIBUTE_MALLOC;
/* Copy at most N characters from string into a buffer without fail. */
extern char *xstrndup (const char *, size_t) ATTRIBUTE_MALLOC;
/* Copy an existing memory buffer to a new memory buffer without fail. */
extern void *xmemdup (const void *, size_t, size_t) ATTRIBUTE_MALLOC;
/* Physical memory routines. Return values are in BYTES. */
extern double physmem_total (void);
extern double physmem_available (void);
/* Compute the 32-bit CRC of a block of memory. */
extern unsigned int xcrc32 (const unsigned char *, int, unsigned int);
/* These macros provide a K&R/C89/C++-friendly way of allocating structures
with nice encapsulation. The XDELETE*() macros are technically
superfluous, but provided here for symmetry. Using them consistently
makes it easier to update client code to use different allocators such
as new/delete and new[]/delete[]. */
/* Scalar allocators. */
#define XALLOCA(T) ((T *) alloca (sizeof (T)))
#define XNEW(T) ((T *) xmalloc (sizeof (T)))
#define XCNEW(T) ((T *) xcalloc (1, sizeof (T)))
#define XDUP(T, P) ((T *) xmemdup ((P), sizeof (T), sizeof (T)))
#define XDELETE(P) free ((void*) (P))
/* Array allocators. */
#define XALLOCAVEC(T, N) ((T *) alloca (sizeof (T) * (N)))
#define XNEWVEC(T, N) ((T *) xmalloc (sizeof (T) * (N)))
#define XCNEWVEC(T, N) ((T *) xcalloc ((N), sizeof (T)))
#define XDUPVEC(T, P, N) ((T *) xmemdup ((P), sizeof (T) * (N), sizeof (T) * (N)))
#define XRESIZEVEC(T, P, N) ((T *) xrealloc ((void *) (P), sizeof (T) * (N)))
#define XDELETEVEC(P) free ((void*) (P))
/* Allocators for variable-sized structures and raw buffers. */
#define XALLOCAVAR(T, S) ((T *) alloca ((S)))
#define XNEWVAR(T, S) ((T *) xmalloc ((S)))
#define XCNEWVAR(T, S) ((T *) xcalloc (1, (S)))
#define XDUPVAR(T, P, S1, S2) ((T *) xmemdup ((P), (S1), (S2)))
#define XRESIZEVAR(T, P, S) ((T *) xrealloc ((P), (S)))
/* Type-safe obstack allocator. */
#define XOBNEW(O, T) ((T *) obstack_alloc ((O), sizeof (T)))
#define XOBNEWVEC(O, T, N) ((T *) obstack_alloc ((O), sizeof (T) * (N)))
#define XOBNEWVAR(O, T, S) ((T *) obstack_alloc ((O), (S)))
#define XOBFINISH(O, T) ((T) obstack_finish ((O)))
/* hex character manipulation routines */
#define _hex_array_size 256
#define _hex_bad 99
extern const unsigned char _hex_value[_hex_array_size];
extern void hex_init (void);
#define hex_p(c) (hex_value (c) != _hex_bad)
/* If you change this, note well: Some code relies on side effects in
the argument being performed exactly once. */
#define hex_value(c) ((unsigned int) _hex_value[(unsigned char) (c)])
/* Flags for pex_init. These are bits to be or'ed together. */
/* Record subprocess times, if possible. */
#define PEX_RECORD_TIMES 0x1
/* Use pipes for communication between processes, if possible. */
#define PEX_USE_PIPES 0x2
/* Save files used for communication between processes. */
#define PEX_SAVE_TEMPS 0x4
/* Prepare to execute one or more programs, with standard output of
each program fed to standard input of the next.
FLAGS As above.
PNAME The name of the program to report in error messages.
TEMPBASE A base name to use for temporary files; may be NULL to
use a random name.
Returns NULL on error. */
extern struct pex_obj *pex_init (int flags, const char *pname,
const char *tempbase);
/* Flags for pex_run. These are bits to be or'ed together. */
/* Last program in pipeline. Standard output of program goes to
OUTNAME, or, if OUTNAME is NULL, to standard output of caller. Do
not set this if you want to call pex_read_output. After this is
set, pex_run may no longer be called with the same struct
pex_obj. */
#define PEX_LAST 0x1
/* Search for program in executable search path. */
#define PEX_SEARCH 0x2
/* OUTNAME is a suffix. */
#define PEX_SUFFIX 0x4
/* Send program's standard error to standard output. */
#define PEX_STDERR_TO_STDOUT 0x8
/* Input file should be opened in binary mode. This flag is ignored
on Unix. */
#define PEX_BINARY_INPUT 0x10
/* Output file should be opened in binary mode. This flag is ignored
on Unix. For proper behaviour PEX_BINARY_INPUT and
PEX_BINARY_OUTPUT have to match appropriately--i.e., a call using
PEX_BINARY_OUTPUT should be followed by a call using
PEX_BINARY_INPUT. */
#define PEX_BINARY_OUTPUT 0x20
/* Capture stderr to a pipe. The output can be read by
calling pex_read_err and reading from the returned
FILE object. This flag may be specified only for
the last program in a pipeline.
This flag is supported only on Unix and Windows. */
#define PEX_STDERR_TO_PIPE 0x40
/* Capture stderr in binary mode. This flag is ignored
on Unix. */
#define PEX_BINARY_ERROR 0x80
/* Execute one program. Returns NULL on success. On error returns an
error string (typically just the name of a system call); the error
string is statically allocated.
OBJ Returned by pex_init.
FLAGS As above.
EXECUTABLE The program to execute.
ARGV NULL terminated array of arguments to pass to the program.
OUTNAME Sets the output file name as follows:
PEX_SUFFIX set (OUTNAME may not be NULL):
TEMPBASE parameter to pex_init not NULL:
Output file name is the concatenation of TEMPBASE
and OUTNAME.
TEMPBASE is NULL:
Output file name is a random file name ending in
OUTNAME.
PEX_SUFFIX not set:
OUTNAME not NULL:
Output file name is OUTNAME.
OUTNAME NULL, TEMPBASE not NULL:
Output file name is randomly chosen using
TEMPBASE.
OUTNAME NULL, TEMPBASE NULL:
Output file name is randomly chosen.
If PEX_LAST is not set, the output file name is the
name to use for a temporary file holding stdout, if
any (there will not be a file if PEX_USE_PIPES is set
and the system supports pipes). If a file is used, it
will be removed when no longer needed unless
PEX_SAVE_TEMPS is set.
If PEX_LAST is set, and OUTNAME is not NULL, standard
output is written to the output file name. The file
will not be removed. If PEX_LAST and PEX_SUFFIX are
both set, TEMPBASE may not be NULL.
ERRNAME If not NULL, this is the name of a file to which
standard error is written. If NULL, standard error of
the program is standard error of the caller.
ERR On an error return, *ERR is set to an errno value, or
to 0 if there is no relevant errno.
*/
extern const char *pex_run (struct pex_obj *obj, int flags,
const char *executable, char * const *argv,
const char *outname, const char *errname,
int *err);
/* As for pex_run (), but takes an extra parameter to enable the
environment for the child process to be specified.
ENV The environment for the child process, specified as
an array of character pointers. Each element of the
array should point to a string of the form VAR=VALUE,
with the exception of the last element which must be
a null pointer.
*/
extern const char *pex_run_in_environment (struct pex_obj *obj, int flags,
const char *executable,
char * const *argv,
char * const *env,
const char *outname,
const char *errname, int *err);
/* Return a stream for a temporary file to pass to the first program
in the pipeline as input. The file name is chosen as for pex_run.
pex_run closes the file automatically; don't close it yourself. */
extern FILE *pex_input_file (struct pex_obj *obj, int flags,
const char *in_name);
/* Return a stream for a pipe connected to the standard input of the
first program in the pipeline. You must have passed
`PEX_USE_PIPES' to `pex_init'. Close the returned stream
yourself. */
extern FILE *pex_input_pipe (struct pex_obj *obj, int binary);
/* Read the standard output of the last program to be executed.
pex_run can not be called after this. BINARY should be non-zero if
the file should be opened in binary mode; this is ignored on Unix.
Returns NULL on error. Don't call fclose on the returned FILE; it
will be closed by pex_free. */
extern FILE *pex_read_output (struct pex_obj *, int binary);
/* Read the standard error of the last program to be executed.
pex_run can not be called after this. BINARY should be non-zero if
the file should be opened in binary mode; this is ignored on Unix.
Returns NULL on error. Don't call fclose on the returned FILE; it
will be closed by pex_free. */
extern FILE *pex_read_err (struct pex_obj *, int binary);
/* Return exit status of all programs in VECTOR. COUNT indicates the
size of VECTOR. The status codes in the vector are in the order of
the calls to pex_run. Returns 0 on error, 1 on success. */
extern int pex_get_status (struct pex_obj *, int count, int *vector);
/* Return times of all programs in VECTOR. COUNT indicates the size
of VECTOR. struct pex_time is really just struct timeval, but that
is not portable to all systems. Returns 0 on error, 1 on
success. */
struct pex_time
{
unsigned long user_seconds;
unsigned long user_microseconds;
unsigned long system_seconds;
unsigned long system_microseconds;
};
extern int pex_get_times (struct pex_obj *, int count,
struct pex_time *vector);
/* Clean up a pex_obj. If you have not called pex_get_times or
pex_get_status, this will try to kill the subprocesses. */
extern void pex_free (struct pex_obj *);
/* Just execute one program. Return value is as for pex_run.
FLAGS Combination of PEX_SEARCH and PEX_STDERR_TO_STDOUT.
EXECUTABLE As for pex_run.
ARGV As for pex_run.
PNAME As for pex_init.
OUTNAME As for pex_run when PEX_LAST is set.
ERRNAME As for pex_run.
STATUS Set to exit status on success.
ERR As for pex_run.
*/
extern const char *pex_one (int flags, const char *executable,
char * const *argv, const char *pname,
const char *outname, const char *errname,
int *status, int *err);
/* pexecute and pwait are the old pexecute interface, still here for
backward compatibility. Don't use these for new code. Instead,
use pex_init/pex_run/pex_get_status/pex_free, or pex_one. */
/* Definitions used by the pexecute routine. */
#define PEXECUTE_FIRST 1
#define PEXECUTE_LAST 2
#define PEXECUTE_ONE (PEXECUTE_FIRST + PEXECUTE_LAST)
#define PEXECUTE_SEARCH 4
#define PEXECUTE_VERBOSE 8
/* Execute a program. */
extern int pexecute (const char *, char * const *, const char *,
const char *, char **, char **, int);
/* Wait for pexecute to finish. */
extern int pwait (int, int *, int);
#if !HAVE_DECL_ASPRINTF
/* Like sprintf but provides a pointer to malloc'd storage, which must
be freed by the caller. */
extern int asprintf (char **, const char *, ...) ATTRIBUTE_PRINTF_2;
#endif
#if !HAVE_DECL_VASPRINTF
/* Like vsprintf but provides a pointer to malloc'd storage, which
must be freed by the caller. */
extern int vasprintf (char **, const char *, va_list) ATTRIBUTE_PRINTF(2,0);
#endif
#if defined(HAVE_DECL_SNPRINTF) && !HAVE_DECL_SNPRINTF
/* Like sprintf but prints at most N characters. */
extern int snprintf (char *, size_t, const char *, ...) ATTRIBUTE_PRINTF_3;
#endif
#if defined(HAVE_DECL_VSNPRINTF) && !HAVE_DECL_VSNPRINTF
/* Like vsprintf but prints at most N characters. */
extern int vsnprintf (char *, size_t, const char *, va_list) ATTRIBUTE_PRINTF(3,0);
#endif
#if defined(HAVE_DECL_STRVERSCMP) && !HAVE_DECL_STRVERSCMP
/* Compare version strings. */
extern int strverscmp (const char *, const char *);
#endif
/* Set the title of a process */
extern void setproctitle (const char *name, ...);
/* Increase stack limit if possible. */
extern void stack_limit_increase (unsigned long);
#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
/* Drastically simplified alloca configurator. If we're using GCC,
we use __builtin_alloca; otherwise we use the C alloca. The C
alloca is always available. You can override GCC by defining
USE_C_ALLOCA yourself. The canonical autoconf macro C_ALLOCA is
also set/unset as it is often used to indicate whether code needs
to call alloca(0). */
extern void *C_alloca (size_t) ATTRIBUTE_MALLOC;
#undef alloca
#if GCC_VERSION >= 2000 && !defined USE_C_ALLOCA
# define alloca(x) __builtin_alloca(x)
# undef C_ALLOCA
# define ASTRDUP(X) \
(__extension__ ({ const char *const libiberty_optr = (X); \
const unsigned long libiberty_len = strlen (libiberty_optr) + 1; \
char *const libiberty_nptr = (char *const) alloca (libiberty_len); \
(char *) memcpy (libiberty_nptr, libiberty_optr, libiberty_len); }))
#else
# define alloca(x) C_alloca(x)
# undef USE_C_ALLOCA
# define USE_C_ALLOCA 1
# undef C_ALLOCA
# define C_ALLOCA 1
extern const char *libiberty_optr;
extern char *libiberty_nptr;
extern unsigned long libiberty_len;
# define ASTRDUP(X) \
(libiberty_optr = (X), \
libiberty_len = strlen (libiberty_optr) + 1, \
libiberty_nptr = (char *) alloca (libiberty_len), \
(char *) memcpy (libiberty_nptr, libiberty_optr, libiberty_len))
#endif
#ifdef __cplusplus
}
#endif
#endif /* ! defined (LIBIBERTY_H) */

View File

@ -0,0 +1,154 @@
/* ###
* IP: LGPL 3.0
* REVIEWED: YES
*/
/* <ctype.h> replacement macros.
Copyright (C) 2000, 2001 Free Software Foundation, Inc.
Contributed by Zack Weinberg <zackw@stanford.edu>.
This file is part of the libiberty library.
Libiberty is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
Libiberty is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with libiberty; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
Boston, MA 02110-1301, USA. */
/* This is a compatible replacement of the standard C library's <ctype.h>
with the following properties:
- Implements all isxxx() macros required by C99.
- Also implements some character classes useful when
parsing C-like languages.
- Does not change behavior depending on the current locale.
- Behaves properly for all values in the range of a signed or
unsigned char.
To avoid conflicts, this header defines the isxxx functions in upper
case, e.g. ISALPHA not isalpha. */
#ifndef SAFE_CTYPE_H
#define SAFE_CTYPE_H
/* Determine host character set. */
#define HOST_CHARSET_UNKNOWN 0
#define HOST_CHARSET_ASCII 1
#define HOST_CHARSET_EBCDIC 2
#if '\n' == 0x0A && ' ' == 0x20 && '0' == 0x30 \
&& 'A' == 0x41 && 'a' == 0x61 && '!' == 0x21
# define HOST_CHARSET HOST_CHARSET_ASCII
#else
# if '\n' == 0x15 && ' ' == 0x40 && '0' == 0xF0 \
&& 'A' == 0xC1 && 'a' == 0x81 && '!' == 0x5A
# define HOST_CHARSET HOST_CHARSET_EBCDIC
# else
# define HOST_CHARSET HOST_CHARSET_UNKNOWN
# endif
#endif
/* Categories. */
enum {
/* In C99 */
_sch_isblank = 0x0001, /* space \t */
_sch_iscntrl = 0x0002, /* nonprinting characters */
_sch_isdigit = 0x0004, /* 0-9 */
_sch_islower = 0x0008, /* a-z */
_sch_isprint = 0x0010, /* any printing character including ' ' */
_sch_ispunct = 0x0020, /* all punctuation */
_sch_isspace = 0x0040, /* space \t \n \r \f \v */
_sch_isupper = 0x0080, /* A-Z */
_sch_isxdigit = 0x0100, /* 0-9A-Fa-f */
/* Extra categories useful to cpplib. */
_sch_isidst = 0x0200, /* A-Za-z_ */
_sch_isvsp = 0x0400, /* \n \r */
_sch_isnvsp = 0x0800, /* space \t \f \v \0 */
/* Combinations of the above. */
_sch_isalpha = _sch_isupper|_sch_islower, /* A-Za-z */
_sch_isalnum = _sch_isalpha|_sch_isdigit, /* A-Za-z0-9 */
_sch_isidnum = _sch_isidst|_sch_isdigit, /* A-Za-z0-9_ */
_sch_isgraph = _sch_isalnum|_sch_ispunct, /* isprint and not space */
_sch_iscppsp = _sch_isvsp|_sch_isnvsp, /* isspace + \0 */
_sch_isbasic = _sch_isprint|_sch_iscppsp /* basic charset of ISO C
(plus ` and @) */
};
/* Character classification. */
extern const unsigned short _sch_istable[256];
#define _sch_test(c, bit) (_sch_istable[(c) & 0xff] & (unsigned short)(bit))
#define ISALPHA(c) _sch_test(c, _sch_isalpha)
#define ISALNUM(c) _sch_test(c, _sch_isalnum)
#define ISBLANK(c) _sch_test(c, _sch_isblank)
#define ISCNTRL(c) _sch_test(c, _sch_iscntrl)
#define ISDIGIT(c) _sch_test(c, _sch_isdigit)
#define ISGRAPH(c) _sch_test(c, _sch_isgraph)
#define ISLOWER(c) _sch_test(c, _sch_islower)
#define ISPRINT(c) _sch_test(c, _sch_isprint)
#define ISPUNCT(c) _sch_test(c, _sch_ispunct)
#define ISSPACE(c) _sch_test(c, _sch_isspace)
#define ISUPPER(c) _sch_test(c, _sch_isupper)
#define ISXDIGIT(c) _sch_test(c, _sch_isxdigit)
#define ISIDNUM(c) _sch_test(c, _sch_isidnum)
#define ISIDST(c) _sch_test(c, _sch_isidst)
#define IS_ISOBASIC(c) _sch_test(c, _sch_isbasic)
#define IS_VSPACE(c) _sch_test(c, _sch_isvsp)
#define IS_NVSPACE(c) _sch_test(c, _sch_isnvsp)
#define IS_SPACE_OR_NUL(c) _sch_test(c, _sch_iscppsp)
/* Character transformation. */
extern const unsigned char _sch_toupper[256];
extern const unsigned char _sch_tolower[256];
#define TOUPPER(c) _sch_toupper[(c) & 0xff]
#define TOLOWER(c) _sch_tolower[(c) & 0xff]
/* Prevent the users of safe-ctype.h from accidently using the routines
from ctype.h. Initially, the approach was to produce an error when
detecting that ctype.h has been included. But this was causing
trouble as ctype.h might get indirectly included as a result of
including another system header (for instance gnulib's stdint.h).
So we include ctype.h here and then immediately redefine its macros. */
#include <ctype.h>
#undef isalpha
#define isalpha(c) do_not_use_isalpha_with_safe_ctype
#undef isalnum
#define isalnum(c) do_not_use_isalnum_with_safe_ctype
#undef iscntrl
#define iscntrl(c) do_not_use_iscntrl_with_safe_ctype
#undef isdigit
#define isdigit(c) do_not_use_isdigit_with_safe_ctype
#undef isgraph
#define isgraph(c) do_not_use_isgraph_with_safe_ctype
#undef islower
#define islower(c) do_not_use_islower_with_safe_ctype
#undef isprint
#define isprint(c) do_not_use_isprint_with_safe_ctype
#undef ispunct
#define ispunct(c) do_not_use_ispunct_with_safe_ctype
#undef isspace
#define isspace(c) do_not_use_isspace_with_safe_ctype
#undef isupper
#define isupper(c) do_not_use_isupper_with_safe_ctype
#undef isxdigit
#define isxdigit(c) do_not_use_isxdigit_with_safe_ctype
#undef toupper
#define toupper(c) do_not_use_toupper_with_safe_ctype
#undef tolower
#define tolower(c) do_not_use_tolower_with_safe_ctype
#endif /* SAFE_CTYPE_H */

View File

@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1"
width="25"
height="17"
id="svg2">
<defs
id="defs4">
<linearGradient
x1="1.3965347"
y1="2.8009901"
x2="7.6133666"
y2="6.9455447"
id="linearGradient4260"
xlink:href="#linearGradient4254"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="2.6579208"
y1="2.260396"
x2="6.6222773"
y2="3.2934308"
id="linearGradient4239"
xlink:href="#linearGradient4233"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="9.6405945"
y1="1.4495049"
x2="5.4509902"
y2="9.19802"
id="linearGradient4228"
xlink:href="#linearGradient4222"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient4222">
<stop
id="stop4224"
style="stop-color:#a38300;stop-opacity:1"
offset="0" />
<stop
id="stop4226"
style="stop-color:#6c5600;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4233">
<stop
id="stop4235"
style="stop-color:#32ac00;stop-opacity:1"
offset="0" />
<stop
id="stop4237"
style="stop-color:#116200;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4254">
<stop
id="stop4256"
style="stop-color:#166500;stop-opacity:1"
offset="0" />
<stop
id="stop4258"
style="stop-color:#3a3000;stop-opacity:1"
offset="1" />
</linearGradient>
</defs>
<g
transform="translate(0,-1035.3622)"
id="layer1">
<image
xlink:href="../nuvola/16x16/folder_yellow.png"
x="1"
y="1036.3622"
width="16"
height="16"
id="image2998" />
<g
transform="translate(14.000269,1038.3624)"
id="layer2">
<path
d="M 9.34375,0 C 9.331893,0.02007096 9.321443,0.04097223 9.3125,0.0625 9.291694,0.0611972 9.270806,0.0611972 9.25,0.0625 9.239262,0.0619942 9.229468,0.06294871 9.21875,0.0625 7.428818,-0.01243524 5.9102713,0.70487297 4.4375,1.40625 2.9559097,2.1118269 1.9397871,2.7910082 0.35734465,2.84375 -0.05907529,2.8522791 -0.26232937,3.5072089 0.07609465,3.75 2.0160738,5.1266314 3.5432986,6.2464747 5.59375,6.5 L 4.0625,9.25 C 3.9616756,9.4398454 4.0018376,9.6942052 4.15625,9.84375 l 1,1 C 5.3695576,11.057374 5.7807905,11.008026 5.9375,10.75 l 5,-9 C 11.038324,1.5601546 10.99816,1.3057948 10.84375,1.15625 l -1,-1 C 9.7346028,0.03783212 9.5657191,-0.02248351 9.40625,0 9.3854438,-0.0013028 9.3645562,-0.0013028 9.34375,0 z m -1.0625,1.1875 -2.5,4.25 C 4.3246653,5.2701854 2.8452361,4.5502621 1.3125,3.5625 2.5816669,3.2796931 3.7528393,2.8007738 4.84375,2.28125 6.0013234,1.7299795 7.1322792,1.3413489 8.28125,1.1875 z m 1.34375,0.125 0.25,0.25 -4.5,8.125 -0.25,-0.25 4.5,-8.125 z"
id="path4241"
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:url(#linearGradient4260);fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" />
<path
d="m 9.5,0.5 1,1 -5,9 -1,-1 5,-9 z"
id="rect3709"
style="fill:url(#linearGradient4228);fill-opacity:1;stroke:none" />
<path
d="M 0.50737752,3.3857784 C 3.9389568,3.2714061 5.9236512,0.39252559 9.2351487,0.54851491 L 6.0366336,6.0445543 C 3.9943893,5.9091062 2.5496218,4.8349783 0.50737752,3.3857784 z"
id="rect4230"
style="fill:url(#linearGradient4239);fill-opacity:1;stroke:none" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -0,0 +1,150 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1"
width="25"
height="17"
id="svg2">
<defs
id="defs4">
<linearGradient
x1="1.3965347"
y1="2.8009901"
x2="7.6133666"
y2="6.9455447"
id="linearGradient4260"
xlink:href="#linearGradient4254"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="2.6579208"
y1="2.260396"
x2="6.6222773"
y2="3.2934308"
id="linearGradient4239"
xlink:href="#linearGradient4233"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="9.6405945"
y1="1.4495049"
x2="5.4509902"
y2="9.19802"
id="linearGradient4228"
xlink:href="#linearGradient4222"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient4222">
<stop
id="stop4224"
style="stop-color:#a38300;stop-opacity:1"
offset="0" />
<stop
id="stop4226"
style="stop-color:#6c5600;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4233">
<stop
id="stop4235"
style="stop-color:#32ac00;stop-opacity:1"
offset="0" />
<stop
id="stop4237"
style="stop-color:#116200;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4254">
<stop
id="stop4256"
style="stop-color:#166500;stop-opacity:1"
offset="0" />
<stop
id="stop4258"
style="stop-color:#3a3000;stop-opacity:1"
offset="1" />
</linearGradient>
<clipPath
id="clipPath4146">
<rect
width="8"
height="7"
x="-0.0004619"
y="9"
id="rect4148"
style="opacity:0.55979644;fill:#0060c0;fill-opacity:1;stroke:none" />
</clipPath>
<linearGradient
x1="4"
y1="1045.5497"
x2="-6.0625"
y2="1026.2684"
id="linearGradient3693"
xlink:href="#linearGradient3613"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(2,2)" />
<linearGradient
x1="-5.095274"
y1="1033.3518"
x2="13.163674"
y2="1058.4865"
id="linearGradient3647"
xlink:href="#linearGradient3639"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(1.96875,2)" />
<linearGradient
x1="-5.095274"
y1="1033.3518"
x2="13.163674"
y2="1058.4865"
id="linearGradient3633"
xlink:href="#linearGradient3639"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-0.03124999,0)" />
<linearGradient
x1="4"
y1="1045.5497"
x2="-6.0625"
y2="1026.2684"
id="linearGradient3619"
xlink:href="#linearGradient3613"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient3613">
<stop
id="stop3615"
style="stop-color:#ffffff;stop-opacity:1"
offset="0" />
<stop
id="stop3617"
style="stop-color:#000000;stop-opacity:0.72944295"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient3639">
<stop
id="stop3641"
style="stop-color:#000000;stop-opacity:1"
offset="0" />
<stop
id="stop3643"
style="stop-color:#ffffff;stop-opacity:1"
offset="1" />
</linearGradient>
</defs>
<g
transform="translate(0,-1035.3622)"
id="layer1">
<image
xlink:href="../nuvola/16x16/folder_yellow.png"
x="1"
y="1036.3622"
width="16"
height="16"
id="image2998" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -0,0 +1,151 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1"
width="25"
height="17"
id="svg2">
<defs
id="defs4">
<linearGradient
x1="1.3965347"
y1="2.8009901"
x2="7.6133666"
y2="6.9455447"
id="linearGradient4260"
xlink:href="#linearGradient4254"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="2.6579208"
y1="2.260396"
x2="6.6222773"
y2="3.2934308"
id="linearGradient4239"
xlink:href="#linearGradient4233"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="9.6405945"
y1="1.4495049"
x2="5.4509902"
y2="9.19802"
id="linearGradient4228"
xlink:href="#linearGradient4222"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient4222">
<stop
id="stop4224"
style="stop-color:#a38300;stop-opacity:1"
offset="0" />
<stop
id="stop4226"
style="stop-color:#6c5600;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4233">
<stop
id="stop4235"
style="stop-color:#32ac00;stop-opacity:1"
offset="0" />
<stop
id="stop4237"
style="stop-color:#116200;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4254">
<stop
id="stop4256"
style="stop-color:#166500;stop-opacity:1"
offset="0" />
<stop
id="stop4258"
style="stop-color:#3a3000;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
x1="8.5"
y1="11.630198"
x2="2.567822"
y2="0.54801965"
id="linearGradient4886"
xlink:href="#linearGradient4880"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="6.8984327"
y1="7.0056653"
x2="-0.66759026"
y2="0.26749697"
id="linearGradient4878"
xlink:href="#linearGradient4872"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient4872">
<stop
id="stop4874"
style="stop-color:#009c31;stop-opacity:1"
offset="0" />
<stop
id="stop4876"
style="stop-color:#009c31;stop-opacity:0.28498727"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4880">
<stop
id="stop4882"
style="stop-color:#006331;stop-opacity:1"
offset="0" />
<stop
id="stop4884"
style="stop-color:#006331;stop-opacity:0"
offset="1" />
</linearGradient>
</defs>
<g
transform="translate(0,-1035.3622)"
id="layer1">
<image
xlink:href="../nuvola/16x16/folder_yellow.png"
x="1"
y="1036.3622"
width="16"
height="16"
id="image2998" />
<g
transform="translate(16,1036.3622)"
id="layer1-8">
<path
d="M 3.5,-0.50000049 0.5,2.4999995 0.5,10.5 l 5,5 3,-3 0,-8.0000005 -5,-4.99999999 z"
id="path4840"
style="fill:#ffffff;fill-opacity:1;stroke:#004d00;stroke-linejoin:round;stroke-opacity:1" />
<path
d="M 5.7629584,2.9216062 13.995756,1.3810437 9.0560775,8.3053812 0.82327977,9.8459437 5.7629584,2.9216062 z"
transform="matrix(0.60732696,0.79445199,0,1,0,0)"
id="path4870"
style="fill:#eaeaea;fill-opacity:1;stroke:none" />
<path
d="M 3.5,-0.49999991 8.5,4.5000002 8.5,12.5 3.5,7.5000001 3.5,-0.49999991 z"
id="path4834"
style="fill:#cecece;fill-opacity:1;stroke:none" />
<path
d="M 3.5,-0.49999991 0.5,2.5 l 0,8 3,-2.9999999 0,-8.00000001 z"
id="path4836"
style="fill:#9c9c9c;fill-opacity:1;stroke:none" />
<path
d="m 0.82327977,1.8459437 8.23279773,-1.54056247 0,7.99999997 -8.23279773,1.5405625 0,-8 z"
transform="matrix(0.60732696,0.79445199,0,1,0,0)"
id="rect4321"
style="fill:url(#linearGradient4878);fill-opacity:1;stroke:none" />
<path
d="m 8.5,4.5000002 -3,2.9999999 0,7.9999999 3,-3 0,-7.9999998 z"
id="path4838"
style="fill:url(#linearGradient4886);fill-opacity:1;stroke:none" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@ -0,0 +1,189 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1"
width="25"
height="17"
id="svg2">
<defs
id="defs4">
<linearGradient
x1="1.3965347"
y1="2.8009901"
x2="7.6133666"
y2="6.9455447"
id="linearGradient4260"
xlink:href="#linearGradient4254"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="2.6579208"
y1="2.260396"
x2="6.6222773"
y2="3.2934308"
id="linearGradient4239"
xlink:href="#linearGradient4233"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="9.6405945"
y1="1.4495049"
x2="5.4509902"
y2="9.19802"
id="linearGradient4228"
xlink:href="#linearGradient4222"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient4222">
<stop
id="stop4224"
style="stop-color:#a38300;stop-opacity:1"
offset="0" />
<stop
id="stop4226"
style="stop-color:#6c5600;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4233">
<stop
id="stop4235"
style="stop-color:#32ac00;stop-opacity:1"
offset="0" />
<stop
id="stop4237"
style="stop-color:#116200;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4254">
<stop
id="stop4256"
style="stop-color:#166500;stop-opacity:1"
offset="0" />
<stop
id="stop4258"
style="stop-color:#3a3000;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
x1="8.5"
y1="11.630198"
x2="2.567822"
y2="0.54801965"
id="linearGradient4886"
xlink:href="#linearGradient4880"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="6.8984327"
y1="7.0056653"
x2="-0.66759026"
y2="0.26749697"
id="linearGradient4878"
xlink:href="#linearGradient4872"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient4872">
<stop
id="stop4874"
style="stop-color:#009c31;stop-opacity:1"
offset="0" />
<stop
id="stop4876"
style="stop-color:#009c31;stop-opacity:0.28498727"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4880">
<stop
id="stop4882"
style="stop-color:#006331;stop-opacity:1"
offset="0" />
<stop
id="stop4884"
style="stop-color:#006331;stop-opacity:0"
offset="1" />
</linearGradient>
<linearGradient
x1="8.5"
y1="11.630198"
x2="2.567822"
y2="0.54801965"
id="linearGradient4886-0"
xlink:href="#linearGradient4880-9"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="6.8984327"
y1="7.0056653"
x2="-0.66759026"
y2="0.26749697"
id="linearGradient4878-7"
xlink:href="#linearGradient4872-0"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient4872-0">
<stop
id="stop4874-0"
style="stop-color:#f71000;stop-opacity:1"
offset="0" />
<stop
id="stop4876-2"
style="stop-color:#f71000;stop-opacity:0.4427481"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4880-9">
<stop
id="stop4882-0"
style="stop-color:#7d201b;stop-opacity:1"
offset="0" />
<stop
id="stop4884-8"
style="stop-color:#bd3129;stop-opacity:0.22900763"
offset="1" />
</linearGradient>
</defs>
<g
transform="translate(0,-1035.3622)"
id="layer1">
<image
xlink:href="../nuvola/16x16/folder_yellow.png"
x="1"
y="1036.3622"
width="16"
height="16"
id="image2998" />
<g
transform="translate(16,1036.3622)"
id="layer1-7">
<path
d="M 3.5,-0.50000049 0.5,2.4999995 0.5,10.5 l 5,5 3,-3 0,-8.0000005 -5,-4.99999999 z"
id="path4840"
style="fill:#ffffff;fill-opacity:1;stroke:#4d0000;stroke-linejoin:round;stroke-opacity:1" />
<path
d="M 5.7629584,2.9216062 13.995756,1.3810437 9.0560775,8.3053812 0.82327977,9.8459437 5.7629584,2.9216062 z"
transform="matrix(0.60732696,0.79445199,0,1,0,0)"
id="path4870"
style="fill:#eaeaea;fill-opacity:1;stroke:none" />
<path
d="M 3.5,-0.49999991 8.5,4.5000002 8.5,12.5 3.5,7.5000001 3.5,-0.49999991 z"
id="path4834"
style="fill:#cecece;fill-opacity:1;stroke:none" />
<path
d="M 3.5,-0.49999991 0.5,2.5 l 0,8 3,-2.9999999 0,-8.00000001 z"
id="path4836"
style="fill:#9c9c9c;fill-opacity:1;stroke:none" />
<path
d="m 8.5,4.5000002 -3,2.9999999 0,7.9999999 3,-3 0,-7.9999998 z"
id="path4838"
style="fill:url(#linearGradient4886-0);fill-opacity:1;stroke:none" />
<path
d="m 0.82327977,1.8459437 8.23279773,-1.54056247 0,7.99999997 -8.23279773,1.5405625 0,-8 z"
transform="matrix(0.60732696,0.79445199,0,1,0,0)"
id="rect4321"
style="fill:url(#linearGradient4878-7);fill-opacity:1;stroke:none" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@ -0,0 +1,158 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1"
width="25"
height="17"
id="svg2">
<defs
id="defs4">
<linearGradient
x1="1.3965347"
y1="2.8009901"
x2="7.6133666"
y2="6.9455447"
id="linearGradient4260"
xlink:href="#linearGradient4254"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="2.6579208"
y1="2.260396"
x2="6.6222773"
y2="3.2934308"
id="linearGradient4239"
xlink:href="#linearGradient4233"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="9.6405945"
y1="1.4495049"
x2="5.4509902"
y2="9.19802"
id="linearGradient4228"
xlink:href="#linearGradient4222"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient4222">
<stop
id="stop4224"
style="stop-color:#a38300;stop-opacity:1"
offset="0" />
<stop
id="stop4226"
style="stop-color:#6c5600;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4233">
<stop
id="stop4235"
style="stop-color:#32ac00;stop-opacity:1"
offset="0" />
<stop
id="stop4237"
style="stop-color:#116200;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4254">
<stop
id="stop4256"
style="stop-color:#166500;stop-opacity:1"
offset="0" />
<stop
id="stop4258"
style="stop-color:#3a3000;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
x1="8.5"
y1="11.630198"
x2="2.567822"
y2="0.54801965"
id="linearGradient4886-0"
xlink:href="#linearGradient4880-9"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="6.8984327"
y1="7.0056653"
x2="-0.66759026"
y2="0.26749697"
id="linearGradient4878-7"
xlink:href="#linearGradient4872-0"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient4872-0">
<stop
id="stop4874-0"
style="stop-color:#f71000;stop-opacity:1"
offset="0" />
<stop
id="stop4876-2"
style="stop-color:#f71000;stop-opacity:0.4427481"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4880-9">
<stop
id="stop4882-0"
style="stop-color:#7d201b;stop-opacity:1"
offset="0" />
<stop
id="stop4884-8"
style="stop-color:#bd3129;stop-opacity:0.22900763"
offset="1" />
</linearGradient>
<linearGradient
x1="13"
y1="13"
x2="0"
y2="0"
id="linearGradient3598"
xlink:href="#linearGradient3592"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient3592">
<stop
id="stop3594"
style="stop-color:#008000;stop-opacity:1"
offset="0" />
<stop
id="stop3596"
style="stop-color:#ffffff;stop-opacity:1"
offset="1" />
</linearGradient>
</defs>
<g
transform="translate(0,-1035.3622)"
id="layer1">
<image
xlink:href="../nuvola/16x16/folder_yellow.png"
x="1"
y="1036.3622"
width="16"
height="16"
id="image2998" />
<g
transform="translate(11,-1.99995)"
id="layer1-5">
<path
d="m 15,7.5 a 7.5,7.5 0 1 1 -15,0 7.5,7.5 0 1 1 15,0 z"
transform="matrix(0.8125,0,0,0.8125,0.40624999,1039.7684)"
id="path2818"
style="fill:url(#linearGradient3598);fill-opacity:1;stroke:#006a00;stroke-opacity:1" />
<g
transform="matrix(1.0062656,0,0,0.96251684,-0.04659213,39.20481)"
id="text3600"
style="font-size:9.615345px;font-style:normal;font-weight:normal;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans">
<path
d="m 8.9902632,1048.9746 c -0.3317856,0.1722 -0.6776497,0.3021 -1.0375934,0.3897 -0.3599545,0.088 -0.7355535,0.1315 -1.1267982,0.1315 -1.1674913,0 -2.092404,-0.3255 -2.7747407,-0.9766 -0.6823398,-0.6542 -1.0235089,-1.5399 -1.0235084,-2.6574 -5e-7,-1.1205 0.3411686,-2.0063 1.0235084,-2.6573 0.6823367,-0.6542 1.6072494,-0.9813 2.7747407,-0.9813 0.3912447,0 0.7668437,0.044 1.1267982,0.1315 0.3599437,0.088 0.7058078,0.2175 1.0375934,0.3897 l 0,1.4507 c -0.3349156,-0.2285 -0.6651298,-0.3959 -0.9906435,-0.5023 -0.3255246,-0.1065 -0.6682587,-0.1597 -1.0282034,-0.1597 -0.6447827,0 -1.1518414,0.2066 -1.5211776,0.6198 -0.3693419,0.4131 -0.5540115,0.9828 -0.5540091,1.7089 -2.4e-6,0.7231 0.1846672,1.2912 0.5540091,1.7043 0.3693362,0.4132 0.8763949,0.6198 1.5211776,0.6198 0.3599447,0 0.7026788,-0.053 1.0282034,-0.1597 0.3255137,-0.1064 0.6557279,-0.2738 0.9906435,-0.5023 l 0,1.4507"
id="path3661"
style="font-weight:bold;fill:#ffffff" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@ -0,0 +1,201 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1"
width="25"
height="17"
id="svg2">
<defs
id="defs4">
<linearGradient
x1="1.3965347"
y1="2.8009901"
x2="7.6133666"
y2="6.9455447"
id="linearGradient4260"
xlink:href="#linearGradient4254"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="2.6579208"
y1="2.260396"
x2="6.6222773"
y2="3.2934308"
id="linearGradient4239"
xlink:href="#linearGradient4233"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="9.6405945"
y1="1.4495049"
x2="5.4509902"
y2="9.19802"
id="linearGradient4228"
xlink:href="#linearGradient4222"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient4222">
<stop
id="stop4224"
style="stop-color:#a38300;stop-opacity:1"
offset="0" />
<stop
id="stop4226"
style="stop-color:#6c5600;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4233">
<stop
id="stop4235"
style="stop-color:#32ac00;stop-opacity:1"
offset="0" />
<stop
id="stop4237"
style="stop-color:#116200;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4254">
<stop
id="stop4256"
style="stop-color:#166500;stop-opacity:1"
offset="0" />
<stop
id="stop4258"
style="stop-color:#3a3000;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
x1="13"
y1="13"
x2="0"
y2="0"
id="linearGradient3598"
xlink:href="#linearGradient3592"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient3592">
<stop
id="stop3594"
style="stop-color:#008000;stop-opacity:1"
offset="0" />
<stop
id="stop3596"
style="stop-color:#ffffff;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
x1="3.2851486"
y1="11.444585"
x2="7.125"
y2="15"
id="linearGradient5517"
xlink:href="#linearGradient5442"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="-1.8334223"
y1="6.6957436"
x2="7.8287196"
y2="16.000019"
id="linearGradient5509"
xlink:href="#linearGradient5450"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="1.6893564"
y1="5.3683167"
x2="14.504462"
y2="21.180693"
id="linearGradient5456"
xlink:href="#linearGradient5450"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(0.57338659,-17.647565)" />
<linearGradient
x1="2.7254951"
y1="6.4945545"
x2="13.09375"
y2="16.765842"
id="linearGradient5448"
xlink:href="#linearGradient5442"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(0.57338659,-17.647565)" />
<linearGradient
id="linearGradient5442">
<stop
id="stop5444"
style="stop-color:#3bb265;stop-opacity:1"
offset="0" />
<stop
id="stop5446"
style="stop-color:#246c32;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient5450">
<stop
id="stop5452"
style="stop-color:#62dd90;stop-opacity:1"
offset="0" />
<stop
id="stop5454"
style="stop-color:#041308;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
x1="-1.8334223"
y1="6.6957436"
x2="7.8287196"
y2="16.000019"
id="linearGradient3368"
xlink:href="#linearGradient5450"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="3.2851486"
y1="11.444585"
x2="7.125"
y2="15"
id="linearGradient3370"
xlink:href="#linearGradient5442"
gradientUnits="userSpaceOnUse" />
<clipPath
id="clipPath4146">
<rect
width="8"
height="7"
x="-0.0004619"
y="9"
id="rect4148"
style="opacity:0.55979644;fill:#0060c0;fill-opacity:1;stroke:none" />
</clipPath>
</defs>
<g
transform="translate(0,-1035.3622)"
id="layer1">
<image
xlink:href="../nuvola/16x16/folder_yellow.png"
x="1"
y="1036.3622"
width="16"
height="16"
id="image2998" />
<g
transform="translate(22.426613,1043.041)"
id="layer1-7">
<g
transform="translate(-6.4261511,-8.6788)"
clip-path="url(#clipPath4146)"
id="g3364">
<path
d="m 3.90625,8.28125 a 0.50005,0.50005 0 0 0 -0.34375,0.25 l -4,6.71875 A 0.50005,0.50005 0 0 0 0,16 l 8,0 a 0.50005,0.50005 0 0 0 0.4375,-0.75 l -4,-6.71875 a 0.50005,0.50005 0 0 0 -0.53125,-0.25 z"
id="path5501"
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:url(#linearGradient3368);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" />
<path
d="M 4,9.78125 7.125,15 0.875,15 4,9.78125 z"
id="path5432"
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:url(#linearGradient3370);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

@ -0,0 +1,223 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1"
width="25"
height="17"
id="svg2">
<defs
id="defs4">
<linearGradient
x1="1.3965347"
y1="2.8009901"
x2="7.6133666"
y2="6.9455447"
id="linearGradient4260"
xlink:href="#linearGradient4254"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="2.6579208"
y1="2.260396"
x2="6.6222773"
y2="3.2934308"
id="linearGradient4239"
xlink:href="#linearGradient4233"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="9.6405945"
y1="1.4495049"
x2="5.4509902"
y2="9.19802"
id="linearGradient4228"
xlink:href="#linearGradient4222"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient4222">
<stop
id="stop4224"
style="stop-color:#a38300;stop-opacity:1"
offset="0" />
<stop
id="stop4226"
style="stop-color:#6c5600;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4233">
<stop
id="stop4235"
style="stop-color:#32ac00;stop-opacity:1"
offset="0" />
<stop
id="stop4237"
style="stop-color:#116200;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4254">
<stop
id="stop4256"
style="stop-color:#166500;stop-opacity:1"
offset="0" />
<stop
id="stop4258"
style="stop-color:#3a3000;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient5442">
<stop
id="stop5444"
style="stop-color:#3bb265;stop-opacity:1"
offset="0" />
<stop
id="stop5446"
style="stop-color:#246c32;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient5450">
<stop
id="stop5452"
style="stop-color:#62dd90;stop-opacity:1"
offset="0" />
<stop
id="stop5454"
style="stop-color:#041308;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
x1="-1.8334223"
y1="6.6957436"
x2="7.8287196"
y2="16.000019"
id="linearGradient3368"
xlink:href="#linearGradient5450"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="3.2851486"
y1="11.444585"
x2="7.125"
y2="15"
id="linearGradient3370"
xlink:href="#linearGradient5442"
gradientUnits="userSpaceOnUse" />
<clipPath
id="clipPath4146">
<rect
width="8"
height="7"
x="-0.0004619"
y="9"
id="rect4148"
style="opacity:0.55979644;fill:#0060c0;fill-opacity:1;stroke:none" />
</clipPath>
<linearGradient
x1="4"
y1="1045.5497"
x2="-6.0625"
y2="1026.2684"
id="linearGradient3693"
xlink:href="#linearGradient3613"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(2,2)" />
<linearGradient
x1="-5.095274"
y1="1033.3518"
x2="13.163674"
y2="1058.4865"
id="linearGradient3647"
xlink:href="#linearGradient3639"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(1.96875,2)" />
<linearGradient
x1="-5.095274"
y1="1033.3518"
x2="13.163674"
y2="1058.4865"
id="linearGradient3633"
xlink:href="#linearGradient3639"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-0.03124999,0)" />
<linearGradient
x1="4"
y1="1045.5497"
x2="-6.0625"
y2="1026.2684"
id="linearGradient3619"
xlink:href="#linearGradient3613"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient3613">
<stop
id="stop3615"
style="stop-color:#ffffff;stop-opacity:1"
offset="0" />
<stop
id="stop3617"
style="stop-color:#000000;stop-opacity:0.72944295"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient3639">
<stop
id="stop3641"
style="stop-color:#000000;stop-opacity:1"
offset="0" />
<stop
id="stop3643"
style="stop-color:#ffffff;stop-opacity:1"
offset="1" />
</linearGradient>
</defs>
<g
transform="translate(0,-1035.3622)"
id="layer1">
<image
xlink:href="../nuvola/16x16/folder_yellow.png"
x="1"
y="1036.3622"
width="16"
height="16"
id="image2998" />
<g
transform="translate(14,-2)"
id="layer1-3">
<rect
width="7"
height="10"
x="2.5"
y="1041.8622"
id="rect3691"
style="fill:url(#linearGradient3693);fill-opacity:1;stroke:none" />
<path
d="m 2,1041.3622 0,0.5 0,10 0,0.5 0.5,0 7,0 0.5,0 0,-0.5 0,-10 0,-0.5 -0.5,0 -7,0 -0.5,0 z m 1,1 6,0 0,9 -6,0 0,-9 z"
id="path3645"
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:url(#linearGradient3647);fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" />
<rect
width="7"
height="10"
x="0.5"
y="1039.8622"
id="rect2830"
style="fill:url(#linearGradient3619);fill-opacity:1;stroke:none" />
<g
transform="matrix(0.95890403,0,0,1.0370725,0.10376718,1039.1783)"
id="text3606"
style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans">
<path
d="m 5.1060718,5.9628425 0,-0.9642527 -1.0428572,0 C 4.0306249,3.7121191 4.083755,3.053575 4.7443307,3.0573877 5.1497912,3.0597279 4.9463843,3.3728736 5.1060718,4.034337 l 1.0428572,0 C 6.018572,3.997887 6.5367413,2.1133648 4.8909824,2.1058316 4.4999161,2.1040415 3.9247097,2.1079872 3.4880137,2.5817867 3.123014,2.9754047 3.1686383,3.7283135 3.0203573,4.9985898 l -1.0428572,0 0,0.9642527 1.0428572,0 C 2.9557912,7.3713527 2.9381392,7.5511525 2.6260642,7.7473342 2.4279358,7.871885 2.1534821,7.920488 1.9775001,7.891348 l 0,0.9642527 c 0.1433927,0.021865 0.2150895,-1.04e-5 0.3193751,-1.04e-5 C 2.8110412,8.8432983 3.2847948,8.6547561 3.5358927,8.3834973 4.040844,7.8380029 4.0632146,5.9628425 4.0632146,5.9628425"
id="path3611"
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;fill:#ff0000;font-family:URW Chancery L;-inkscape-font-specification:URW Chancery L Bold Italic" />
</g>
<path
d="m 0,1039.3622 0,0.5 0,10 0,0.5 0.5,0 7,0 0.5,0 0,-0.5 0,-10 0,-0.5 -0.5,0 -7,0 -0.5,0 z m 1,1 6,0 0,9 -6,0 0,-9 z"
id="rect3621"
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:url(#linearGradient3633);fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.9 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 28 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 33 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 33 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 32 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 34 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 35 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 31 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 34 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 31 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -0,0 +1,150 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1"
width="25"
height="17"
id="svg2">
<defs
id="defs4">
<linearGradient
x1="1.3965347"
y1="2.8009901"
x2="7.6133666"
y2="6.9455447"
id="linearGradient4260"
xlink:href="#linearGradient4254"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="2.6579208"
y1="2.260396"
x2="6.6222773"
y2="3.2934308"
id="linearGradient4239"
xlink:href="#linearGradient4233"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="9.6405945"
y1="1.4495049"
x2="5.4509902"
y2="9.19802"
id="linearGradient4228"
xlink:href="#linearGradient4222"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient4222">
<stop
id="stop4224"
style="stop-color:#a38300;stop-opacity:1"
offset="0" />
<stop
id="stop4226"
style="stop-color:#6c5600;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4233">
<stop
id="stop4235"
style="stop-color:#32ac00;stop-opacity:1"
offset="0" />
<stop
id="stop4237"
style="stop-color:#116200;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4254">
<stop
id="stop4256"
style="stop-color:#166500;stop-opacity:1"
offset="0" />
<stop
id="stop4258"
style="stop-color:#3a3000;stop-opacity:1"
offset="1" />
</linearGradient>
<clipPath
id="clipPath4146">
<rect
width="8"
height="7"
x="-0.0004619"
y="9"
id="rect4148"
style="opacity:0.55979644;fill:#0060c0;fill-opacity:1;stroke:none" />
</clipPath>
<linearGradient
x1="4"
y1="1045.5497"
x2="-6.0625"
y2="1026.2684"
id="linearGradient3693"
xlink:href="#linearGradient3613"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(2,2)" />
<linearGradient
x1="-5.095274"
y1="1033.3518"
x2="13.163674"
y2="1058.4865"
id="linearGradient3647"
xlink:href="#linearGradient3639"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(1.96875,2)" />
<linearGradient
x1="-5.095274"
y1="1033.3518"
x2="13.163674"
y2="1058.4865"
id="linearGradient3633"
xlink:href="#linearGradient3639"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-0.03124999,0)" />
<linearGradient
x1="4"
y1="1045.5497"
x2="-6.0625"
y2="1026.2684"
id="linearGradient3619"
xlink:href="#linearGradient3613"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient3613">
<stop
id="stop3615"
style="stop-color:#ffffff;stop-opacity:1"
offset="0" />
<stop
id="stop3617"
style="stop-color:#000000;stop-opacity:0.72944295"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient3639">
<stop
id="stop3641"
style="stop-color:#000000;stop-opacity:1"
offset="0" />
<stop
id="stop3643"
style="stop-color:#ffffff;stop-opacity:1"
offset="1" />
</linearGradient>
</defs>
<g
transform="translate(0,-1035.3622)"
id="layer1">
<image
xlink:href="../nuvola/16x16/folder_yellow_open.png"
x="1"
y="1036.3622"
width="16"
height="16"
id="image2998" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -0,0 +1,151 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1"
width="25"
height="17"
id="svg2">
<defs
id="defs4">
<linearGradient
x1="1.3965347"
y1="2.8009901"
x2="7.6133666"
y2="6.9455447"
id="linearGradient4260"
xlink:href="#linearGradient4254"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="2.6579208"
y1="2.260396"
x2="6.6222773"
y2="3.2934308"
id="linearGradient4239"
xlink:href="#linearGradient4233"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="9.6405945"
y1="1.4495049"
x2="5.4509902"
y2="9.19802"
id="linearGradient4228"
xlink:href="#linearGradient4222"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient4222">
<stop
id="stop4224"
style="stop-color:#a38300;stop-opacity:1"
offset="0" />
<stop
id="stop4226"
style="stop-color:#6c5600;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4233">
<stop
id="stop4235"
style="stop-color:#32ac00;stop-opacity:1"
offset="0" />
<stop
id="stop4237"
style="stop-color:#116200;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4254">
<stop
id="stop4256"
style="stop-color:#166500;stop-opacity:1"
offset="0" />
<stop
id="stop4258"
style="stop-color:#3a3000;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
x1="8.5"
y1="11.630198"
x2="2.567822"
y2="0.54801965"
id="linearGradient4886"
xlink:href="#linearGradient4880"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="6.8984327"
y1="7.0056653"
x2="-0.66759026"
y2="0.26749697"
id="linearGradient4878"
xlink:href="#linearGradient4872"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient4872">
<stop
id="stop4874"
style="stop-color:#009c31;stop-opacity:1"
offset="0" />
<stop
id="stop4876"
style="stop-color:#009c31;stop-opacity:0.28498727"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4880">
<stop
id="stop4882"
style="stop-color:#006331;stop-opacity:1"
offset="0" />
<stop
id="stop4884"
style="stop-color:#006331;stop-opacity:0"
offset="1" />
</linearGradient>
</defs>
<g
transform="translate(0,-1035.3622)"
id="layer1">
<image
xlink:href="../nuvola/16x16/folder_yellow_open.png"
x="1"
y="1036.3622"
width="16"
height="16"
id="image2998" />
<g
transform="translate(16,1036.3622)"
id="layer1-8">
<path
d="M 3.5,-0.50000049 0.5,2.4999995 0.5,10.5 l 5,5 3,-3 0,-8.0000005 -5,-4.99999999 z"
id="path4840"
style="fill:#ffffff;fill-opacity:1;stroke:#004d00;stroke-linejoin:round;stroke-opacity:1" />
<path
d="M 5.7629584,2.9216062 13.995756,1.3810437 9.0560775,8.3053812 0.82327977,9.8459437 5.7629584,2.9216062 z"
transform="matrix(0.60732696,0.79445199,0,1,0,0)"
id="path4870"
style="fill:#eaeaea;fill-opacity:1;stroke:none" />
<path
d="M 3.5,-0.49999991 8.5,4.5000002 8.5,12.5 3.5,7.5000001 3.5,-0.49999991 z"
id="path4834"
style="fill:#cecece;fill-opacity:1;stroke:none" />
<path
d="M 3.5,-0.49999991 0.5,2.5 l 0,8 3,-2.9999999 0,-8.00000001 z"
id="path4836"
style="fill:#9c9c9c;fill-opacity:1;stroke:none" />
<path
d="m 0.82327977,1.8459437 8.23279773,-1.54056247 0,7.99999997 -8.23279773,1.5405625 0,-8 z"
transform="matrix(0.60732696,0.79445199,0,1,0,0)"
id="rect4321"
style="fill:url(#linearGradient4878);fill-opacity:1;stroke:none" />
<path
d="m 8.5,4.5000002 -3,2.9999999 0,7.9999999 3,-3 0,-7.9999998 z"
id="path4838"
style="fill:url(#linearGradient4886);fill-opacity:1;stroke:none" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@ -0,0 +1,189 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1"
width="25"
height="17"
id="svg2">
<defs
id="defs4">
<linearGradient
x1="1.3965347"
y1="2.8009901"
x2="7.6133666"
y2="6.9455447"
id="linearGradient4260"
xlink:href="#linearGradient4254"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="2.6579208"
y1="2.260396"
x2="6.6222773"
y2="3.2934308"
id="linearGradient4239"
xlink:href="#linearGradient4233"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="9.6405945"
y1="1.4495049"
x2="5.4509902"
y2="9.19802"
id="linearGradient4228"
xlink:href="#linearGradient4222"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient4222">
<stop
id="stop4224"
style="stop-color:#a38300;stop-opacity:1"
offset="0" />
<stop
id="stop4226"
style="stop-color:#6c5600;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4233">
<stop
id="stop4235"
style="stop-color:#32ac00;stop-opacity:1"
offset="0" />
<stop
id="stop4237"
style="stop-color:#116200;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4254">
<stop
id="stop4256"
style="stop-color:#166500;stop-opacity:1"
offset="0" />
<stop
id="stop4258"
style="stop-color:#3a3000;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
x1="8.5"
y1="11.630198"
x2="2.567822"
y2="0.54801965"
id="linearGradient4886"
xlink:href="#linearGradient4880"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="6.8984327"
y1="7.0056653"
x2="-0.66759026"
y2="0.26749697"
id="linearGradient4878"
xlink:href="#linearGradient4872"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient4872">
<stop
id="stop4874"
style="stop-color:#009c31;stop-opacity:1"
offset="0" />
<stop
id="stop4876"
style="stop-color:#009c31;stop-opacity:0.28498727"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4880">
<stop
id="stop4882"
style="stop-color:#006331;stop-opacity:1"
offset="0" />
<stop
id="stop4884"
style="stop-color:#006331;stop-opacity:0"
offset="1" />
</linearGradient>
<linearGradient
x1="8.5"
y1="11.630198"
x2="2.567822"
y2="0.54801965"
id="linearGradient4886-0"
xlink:href="#linearGradient4880-9"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="6.8984327"
y1="7.0056653"
x2="-0.66759026"
y2="0.26749697"
id="linearGradient4878-7"
xlink:href="#linearGradient4872-0"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient4872-0">
<stop
id="stop4874-0"
style="stop-color:#f71000;stop-opacity:1"
offset="0" />
<stop
id="stop4876-2"
style="stop-color:#f71000;stop-opacity:0.4427481"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4880-9">
<stop
id="stop4882-0"
style="stop-color:#7d201b;stop-opacity:1"
offset="0" />
<stop
id="stop4884-8"
style="stop-color:#bd3129;stop-opacity:0.22900763"
offset="1" />
</linearGradient>
</defs>
<g
transform="translate(0,-1035.3622)"
id="layer1">
<image
xlink:href="../nuvola/16x16/folder_yellow_open.png"
x="1"
y="1036.3622"
width="16"
height="16"
id="image2998" />
<g
transform="translate(16,1036.3622)"
id="layer1-7">
<path
d="M 3.5,-0.50000049 0.5,2.4999995 0.5,10.5 l 5,5 3,-3 0,-8.0000005 -5,-4.99999999 z"
id="path4840"
style="fill:#ffffff;fill-opacity:1;stroke:#4d0000;stroke-linejoin:round;stroke-opacity:1" />
<path
d="M 5.7629584,2.9216062 13.995756,1.3810437 9.0560775,8.3053812 0.82327977,9.8459437 5.7629584,2.9216062 z"
transform="matrix(0.60732696,0.79445199,0,1,0,0)"
id="path4870"
style="fill:#eaeaea;fill-opacity:1;stroke:none" />
<path
d="M 3.5,-0.49999991 8.5,4.5000002 8.5,12.5 3.5,7.5000001 3.5,-0.49999991 z"
id="path4834"
style="fill:#cecece;fill-opacity:1;stroke:none" />
<path
d="M 3.5,-0.49999991 0.5,2.5 l 0,8 3,-2.9999999 0,-8.00000001 z"
id="path4836"
style="fill:#9c9c9c;fill-opacity:1;stroke:none" />
<path
d="m 8.5,4.5000002 -3,2.9999999 0,7.9999999 3,-3 0,-7.9999998 z"
id="path4838"
style="fill:url(#linearGradient4886-0);fill-opacity:1;stroke:none" />
<path
d="m 0.82327977,1.8459437 8.23279773,-1.54056247 0,7.99999997 -8.23279773,1.5405625 0,-8 z"
transform="matrix(0.60732696,0.79445199,0,1,0,0)"
id="rect4321"
style="fill:url(#linearGradient4878-7);fill-opacity:1;stroke:none" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@ -0,0 +1,158 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1"
width="25"
height="17"
id="svg2">
<defs
id="defs4">
<linearGradient
x1="1.3965347"
y1="2.8009901"
x2="7.6133666"
y2="6.9455447"
id="linearGradient4260"
xlink:href="#linearGradient4254"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="2.6579208"
y1="2.260396"
x2="6.6222773"
y2="3.2934308"
id="linearGradient4239"
xlink:href="#linearGradient4233"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="9.6405945"
y1="1.4495049"
x2="5.4509902"
y2="9.19802"
id="linearGradient4228"
xlink:href="#linearGradient4222"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient4222">
<stop
id="stop4224"
style="stop-color:#a38300;stop-opacity:1"
offset="0" />
<stop
id="stop4226"
style="stop-color:#6c5600;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4233">
<stop
id="stop4235"
style="stop-color:#32ac00;stop-opacity:1"
offset="0" />
<stop
id="stop4237"
style="stop-color:#116200;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4254">
<stop
id="stop4256"
style="stop-color:#166500;stop-opacity:1"
offset="0" />
<stop
id="stop4258"
style="stop-color:#3a3000;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
x1="8.5"
y1="11.630198"
x2="2.567822"
y2="0.54801965"
id="linearGradient4886-0"
xlink:href="#linearGradient4880-9"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="6.8984327"
y1="7.0056653"
x2="-0.66759026"
y2="0.26749697"
id="linearGradient4878-7"
xlink:href="#linearGradient4872-0"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient4872-0">
<stop
id="stop4874-0"
style="stop-color:#f71000;stop-opacity:1"
offset="0" />
<stop
id="stop4876-2"
style="stop-color:#f71000;stop-opacity:0.4427481"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4880-9">
<stop
id="stop4882-0"
style="stop-color:#7d201b;stop-opacity:1"
offset="0" />
<stop
id="stop4884-8"
style="stop-color:#bd3129;stop-opacity:0.22900763"
offset="1" />
</linearGradient>
<linearGradient
x1="13"
y1="13"
x2="0"
y2="0"
id="linearGradient3598"
xlink:href="#linearGradient3592"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient3592">
<stop
id="stop3594"
style="stop-color:#008000;stop-opacity:1"
offset="0" />
<stop
id="stop3596"
style="stop-color:#ffffff;stop-opacity:1"
offset="1" />
</linearGradient>
</defs>
<g
transform="translate(0,-1035.3622)"
id="layer1">
<image
xlink:href="../nuvola/16x16/folder_yellow_open.png"
x="1"
y="1036.3622"
width="16"
height="16"
id="image2998" />
<g
transform="translate(11,-1.99995)"
id="layer1-5">
<path
d="m 15,7.5 a 7.5,7.5 0 1 1 -15,0 7.5,7.5 0 1 1 15,0 z"
transform="matrix(0.8125,0,0,0.8125,0.40624999,1039.7684)"
id="path2818"
style="fill:url(#linearGradient3598);fill-opacity:1;stroke:#006a00;stroke-opacity:1" />
<g
transform="matrix(1.0062656,0,0,0.96251684,-0.04659213,39.20481)"
id="text3600"
style="font-size:9.615345px;font-style:normal;font-weight:normal;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans">
<path
d="m 8.9902632,1048.9746 c -0.3317856,0.1722 -0.6776497,0.3021 -1.0375934,0.3897 -0.3599545,0.088 -0.7355535,0.1315 -1.1267982,0.1315 -1.1674913,0 -2.092404,-0.3255 -2.7747407,-0.9766 -0.6823398,-0.6542 -1.0235089,-1.5399 -1.0235084,-2.6574 -5e-7,-1.1205 0.3411686,-2.0063 1.0235084,-2.6573 0.6823367,-0.6542 1.6072494,-0.9813 2.7747407,-0.9813 0.3912447,0 0.7668437,0.044 1.1267982,0.1315 0.3599437,0.088 0.7058078,0.2175 1.0375934,0.3897 l 0,1.4507 c -0.3349156,-0.2285 -0.6651298,-0.3959 -0.9906435,-0.5023 -0.3255246,-0.1065 -0.6682587,-0.1597 -1.0282034,-0.1597 -0.6447827,0 -1.1518414,0.2066 -1.5211776,0.6198 -0.3693419,0.4131 -0.5540115,0.9828 -0.5540091,1.7089 -2.4e-6,0.7231 0.1846672,1.2912 0.5540091,1.7043 0.3693362,0.4132 0.8763949,0.6198 1.5211776,0.6198 0.3599447,0 0.7026788,-0.053 1.0282034,-0.1597 0.3255137,-0.1064 0.6557279,-0.2738 0.9906435,-0.5023 l 0,1.4507"
id="path3661"
style="font-weight:bold;fill:#ffffff" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@ -0,0 +1,201 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1"
width="25"
height="17"
id="svg2">
<defs
id="defs4">
<linearGradient
x1="1.3965347"
y1="2.8009901"
x2="7.6133666"
y2="6.9455447"
id="linearGradient4260"
xlink:href="#linearGradient4254"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="2.6579208"
y1="2.260396"
x2="6.6222773"
y2="3.2934308"
id="linearGradient4239"
xlink:href="#linearGradient4233"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="9.6405945"
y1="1.4495049"
x2="5.4509902"
y2="9.19802"
id="linearGradient4228"
xlink:href="#linearGradient4222"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient4222">
<stop
id="stop4224"
style="stop-color:#a38300;stop-opacity:1"
offset="0" />
<stop
id="stop4226"
style="stop-color:#6c5600;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4233">
<stop
id="stop4235"
style="stop-color:#32ac00;stop-opacity:1"
offset="0" />
<stop
id="stop4237"
style="stop-color:#116200;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4254">
<stop
id="stop4256"
style="stop-color:#166500;stop-opacity:1"
offset="0" />
<stop
id="stop4258"
style="stop-color:#3a3000;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
x1="13"
y1="13"
x2="0"
y2="0"
id="linearGradient3598"
xlink:href="#linearGradient3592"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient3592">
<stop
id="stop3594"
style="stop-color:#008000;stop-opacity:1"
offset="0" />
<stop
id="stop3596"
style="stop-color:#ffffff;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
x1="3.2851486"
y1="11.444585"
x2="7.125"
y2="15"
id="linearGradient5517"
xlink:href="#linearGradient5442"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="-1.8334223"
y1="6.6957436"
x2="7.8287196"
y2="16.000019"
id="linearGradient5509"
xlink:href="#linearGradient5450"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="1.6893564"
y1="5.3683167"
x2="14.504462"
y2="21.180693"
id="linearGradient5456"
xlink:href="#linearGradient5450"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(0.57338659,-17.647565)" />
<linearGradient
x1="2.7254951"
y1="6.4945545"
x2="13.09375"
y2="16.765842"
id="linearGradient5448"
xlink:href="#linearGradient5442"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(0.57338659,-17.647565)" />
<linearGradient
id="linearGradient5442">
<stop
id="stop5444"
style="stop-color:#3bb265;stop-opacity:1"
offset="0" />
<stop
id="stop5446"
style="stop-color:#246c32;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient5450">
<stop
id="stop5452"
style="stop-color:#62dd90;stop-opacity:1"
offset="0" />
<stop
id="stop5454"
style="stop-color:#041308;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
x1="-1.8334223"
y1="6.6957436"
x2="7.8287196"
y2="16.000019"
id="linearGradient3368"
xlink:href="#linearGradient5450"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="3.2851486"
y1="11.444585"
x2="7.125"
y2="15"
id="linearGradient3370"
xlink:href="#linearGradient5442"
gradientUnits="userSpaceOnUse" />
<clipPath
id="clipPath4146">
<rect
width="8"
height="7"
x="-0.0004619"
y="9"
id="rect4148"
style="opacity:0.55979644;fill:#0060c0;fill-opacity:1;stroke:none" />
</clipPath>
</defs>
<g
transform="translate(0,-1035.3622)"
id="layer1">
<image
xlink:href="../nuvola/16x16/folder_yellow_open.png"
x="1"
y="1036.3622"
width="16"
height="16"
id="image2998" />
<g
transform="translate(22.426613,1043.041)"
id="layer1-7">
<g
transform="translate(-6.4261511,-8.6788)"
clip-path="url(#clipPath4146)"
id="g3364">
<path
d="m 3.90625,8.28125 a 0.50005,0.50005 0 0 0 -0.34375,0.25 l -4,6.71875 A 0.50005,0.50005 0 0 0 0,16 l 8,0 a 0.50005,0.50005 0 0 0 0.4375,-0.75 l -4,-6.71875 a 0.50005,0.50005 0 0 0 -0.53125,-0.25 z"
id="path5501"
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:url(#linearGradient3368);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" />
<path
d="M 4,9.78125 7.125,15 0.875,15 4,9.78125 z"
id="path5432"
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:url(#linearGradient3370);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

@ -0,0 +1,223 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1"
width="25"
height="17"
id="svg2">
<defs
id="defs4">
<linearGradient
x1="1.3965347"
y1="2.8009901"
x2="7.6133666"
y2="6.9455447"
id="linearGradient4260"
xlink:href="#linearGradient4254"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="2.6579208"
y1="2.260396"
x2="6.6222773"
y2="3.2934308"
id="linearGradient4239"
xlink:href="#linearGradient4233"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="9.6405945"
y1="1.4495049"
x2="5.4509902"
y2="9.19802"
id="linearGradient4228"
xlink:href="#linearGradient4222"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient4222">
<stop
id="stop4224"
style="stop-color:#a38300;stop-opacity:1"
offset="0" />
<stop
id="stop4226"
style="stop-color:#6c5600;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4233">
<stop
id="stop4235"
style="stop-color:#32ac00;stop-opacity:1"
offset="0" />
<stop
id="stop4237"
style="stop-color:#116200;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4254">
<stop
id="stop4256"
style="stop-color:#166500;stop-opacity:1"
offset="0" />
<stop
id="stop4258"
style="stop-color:#3a3000;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient5442">
<stop
id="stop5444"
style="stop-color:#3bb265;stop-opacity:1"
offset="0" />
<stop
id="stop5446"
style="stop-color:#246c32;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient5450">
<stop
id="stop5452"
style="stop-color:#62dd90;stop-opacity:1"
offset="0" />
<stop
id="stop5454"
style="stop-color:#041308;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
x1="-1.8334223"
y1="6.6957436"
x2="7.8287196"
y2="16.000019"
id="linearGradient3368"
xlink:href="#linearGradient5450"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="3.2851486"
y1="11.444585"
x2="7.125"
y2="15"
id="linearGradient3370"
xlink:href="#linearGradient5442"
gradientUnits="userSpaceOnUse" />
<clipPath
id="clipPath4146">
<rect
width="8"
height="7"
x="-0.0004619"
y="9"
id="rect4148"
style="opacity:0.55979644;fill:#0060c0;fill-opacity:1;stroke:none" />
</clipPath>
<linearGradient
x1="4"
y1="1045.5497"
x2="-6.0625"
y2="1026.2684"
id="linearGradient3693"
xlink:href="#linearGradient3613"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(2,2)" />
<linearGradient
x1="-5.095274"
y1="1033.3518"
x2="13.163674"
y2="1058.4865"
id="linearGradient3647"
xlink:href="#linearGradient3639"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(1.96875,2)" />
<linearGradient
x1="-5.095274"
y1="1033.3518"
x2="13.163674"
y2="1058.4865"
id="linearGradient3633"
xlink:href="#linearGradient3639"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-0.03124999,0)" />
<linearGradient
x1="4"
y1="1045.5497"
x2="-6.0625"
y2="1026.2684"
id="linearGradient3619"
xlink:href="#linearGradient3613"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient3613">
<stop
id="stop3615"
style="stop-color:#ffffff;stop-opacity:1"
offset="0" />
<stop
id="stop3617"
style="stop-color:#000000;stop-opacity:0.72944295"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient3639">
<stop
id="stop3641"
style="stop-color:#000000;stop-opacity:1"
offset="0" />
<stop
id="stop3643"
style="stop-color:#ffffff;stop-opacity:1"
offset="1" />
</linearGradient>
</defs>
<g
transform="translate(0,-1035.3622)"
id="layer1">
<image
xlink:href="../nuvola/16x16/folder_yellow_open.png"
x="1"
y="1036.3622"
width="16"
height="16"
id="image2998" />
<g
transform="translate(14,-2)"
id="layer1-3">
<rect
width="7"
height="10"
x="2.5"
y="1041.8622"
id="rect3691"
style="fill:url(#linearGradient3693);fill-opacity:1;stroke:none" />
<path
d="m 2,1041.3622 0,0.5 0,10 0,0.5 0.5,0 7,0 0.5,0 0,-0.5 0,-10 0,-0.5 -0.5,0 -7,0 -0.5,0 z m 1,1 6,0 0,9 -6,0 0,-9 z"
id="path3645"
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:url(#linearGradient3647);fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" />
<rect
width="7"
height="10"
x="0.5"
y="1039.8622"
id="rect2830"
style="fill:url(#linearGradient3619);fill-opacity:1;stroke:none" />
<g
transform="matrix(0.95890403,0,0,1.0370725,0.10376718,1039.1783)"
id="text3606"
style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans">
<path
d="m 5.1060718,5.9628425 0,-0.9642527 -1.0428572,0 C 4.0306249,3.7121191 4.083755,3.053575 4.7443307,3.0573877 5.1497912,3.0597279 4.9463843,3.3728736 5.1060718,4.034337 l 1.0428572,0 C 6.018572,3.997887 6.5367413,2.1133648 4.8909824,2.1058316 4.4999161,2.1040415 3.9247097,2.1079872 3.4880137,2.5817867 3.123014,2.9754047 3.1686383,3.7283135 3.0203573,4.9985898 l -1.0428572,0 0,0.9642527 1.0428572,0 C 2.9557912,7.3713527 2.9381392,7.5511525 2.6260642,7.7473342 2.4279358,7.871885 2.1534821,7.920488 1.9775001,7.891348 l 0,0.9642527 c 0.1433927,0.021865 0.2150895,-1.04e-5 0.3193751,-1.04e-5 C 2.8110412,8.8432983 3.2847948,8.6547561 3.5358927,8.3834973 4.040844,7.8380029 4.0632146,5.9628425 4.0632146,5.9628425"
id="path3611"
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;fill:#ff0000;font-family:URW Chancery L;-inkscape-font-specification:URW Chancery L Bold Italic" />
</g>
<path
d="m 0,1039.3622 0,0.5 0,10 0,0.5 0.5,0 7,0 0.5,0 0,-0.5 0,-10 0,-0.5 -0.5,0 -7,0 -0.5,0 z m 1,1 6,0 0,9 -6,0 0,-9 z"
id="rect3621"
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:url(#linearGradient3633);fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.9 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 28 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 33 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 32 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 34 KiB

Some files were not shown because too many files have changed in this diff Show More