git » fp-git.git » commit 39bcd63

better abstraction library-console program

author ecalot
2005-03-22 11:20:19 UTC
committer ecalot
2005-03-22 11:20:19 UTC
parent 5edb0796efb3d592f492b0bc9f0481b7551541f5

better abstraction library-console program

PR/src/Makefile +16 -12
PR/src/console/filedir.c +341 -0
PR/src/console/main.c +97 -352
PR/src/include/autodetect.h +1 -9
PR/src/include/common.h +1 -1
PR/src/include/disk.h +1 -1
PR/src/include/en.lang.pr.h +1 -1
PR/src/include/filedir.h +20 -40
PR/src/include/idlist.h +1 -9
PR/src/include/parse.h +10 -0
PR/src/include/pr.h +1 -1
PR/src/include/search.h +0 -8
PR/src/include/tree.h +1 -9
PR/src/include/unknown.h +1 -9
PR/src/lib/layers/autodetect.c +3 -127
PR/src/lib/layers/dat.c +23 -12
PR/src/lib/layers/disk.c +18 -68
PR/src/lib/layers/idlist.c +3 -127
PR/src/lib/pr.c +2 -252
PR/src/lib/xml/parse.c +69 -0
PR/src/lib/xml/search.c +0 -48
PR/src/lib/xml/tree.c +3 -127
PR/src/lib/xml/unknown.c +3 -127

diff --git a/PR/src/Makefile b/PR/src/Makefile
index 29e5bb4..e0ec0b7 100644
--- a/PR/src/Makefile
+++ b/PR/src/Makefile
@@ -52,9 +52,9 @@ endif
 
 OBJFILES = compile.o compress.o extract.o resources.o tasks.o disk.o\
            xmlparse.o xmlsearch.o dat.o bmp.o mid.o pal.o wav.o plv.o\
-           memory.o $(SRC2) pr.o
+           memory.o $(SRC2) pr.o 
 
-SRC3     = prlib.o
+SRC3     = main.o filedir.o
 
 EXEFILE  = bin/pr
 XMLFILE  = bin/resources.xml
@@ -65,10 +65,10 @@ LINKEROPTIONS = $(LINKERRELEASE)
 
 #main file
 
-$(EXEFILE): $(OBJFILES) $(XMLFILE)
+$(EXEFILE): $(OBJFILES) $(XMLFILE) $(SRC3)
 	$(INFO) Linking files...
 	$(MAKEDIR) bin
-	$(CC) $(OPTIONS) -o bin/pr $(OBJFILES) 
+	$(CC) $(OPTIONS) -o bin/pr $(OBJFILES) $(SRC3) 
 	$(INFO) Program successfully compiled
 	$(INFO)
 	$(INFO) Please read readme.txt for syntax information
@@ -78,7 +78,7 @@ $(EXEFILE): $(OBJFILES) $(XMLFILE)
 
 clean:
 	$(INFO) Erasing temporary object files...
-	$(REMOVER) $(OBJFILES) $(SRC3) $(EXEFILE)
+	$(REMOVER) $(OBJFILES) $(EXEFILE) $(SRC3)
 
 cleanxml:
 	$(INFO) Erasing xml file...
@@ -88,10 +88,10 @@ build: clean bin/pr
 
 all: $(EXEFILE)
 
-lib: clean $(OBJFILES) $(SRC3)
+lib: $(OBJFILES) $(SRC3)
 	$(MAKEDIR) bin
 	$(INFO) Making dynamic library...
-	$(CC) $(OPTIONS) -o bin/pr.so $(OBJFILES) $(SRC3) -Llibc -shared -dynamic
+	$(CC) $(OPTIONS) -o bin/pr.so $(OBJFILES) -Llibc -shared -dynamic
 	$(INFO) Library successfully compiled
 	$(INFO)
 	$(INFO) Please read readme.coders.txt and pr.h for interfaces
@@ -120,13 +120,17 @@ compress.o: compress.c
 	$(INFO) Compiling compression module...
 	$(CC) -c compress.c $(OPTIONS)
 
+main.o: main.c
+	$(INFO) Compiling command parsing module for standard mode...
+	$(CC) -c main.c $(OPTIONS)
+
 pr.o: pr.c
-	$(INFO) Compiling main module in standard mode...
+	$(INFO) Compiling main library primitives for both modes...
 	$(CC) -c pr.c $(OPTIONS)
-
-prlib.o: pr.c
-	$(INFO) Compiling main module in library mode...
-	$(CC) -c pr.c $(OPTIONS) -DDLL -o prlib.o
+	
+filedir.o: filedir.c
+	$(INFO) Compiling directory and recursive file reading module for standard mode...
+	$(CC) -c filedir.c $(OPTIONS)
 
 resources.o: resources.c
 	$(INFO) Compiling resource manager module...
diff --git a/PR/src/console/filedir.c b/PR/src/console/filedir.c
new file mode 100644
index 0000000..168dd3e
--- /dev/null
+++ b/PR/src/console/filedir.c
@@ -0,0 +1,341 @@
+/*  Princed V3 - Prince of Persia Level Editor for PC Version
+    Copyright (C) 2003 Princed Development Team
+
+    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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    The authors of this program may be contacted at http://forum.princed.com.ar
+*/
+
+/*
+filedir.c: Princed Resources : read command line file arguments and generate a file list
+\xaf\xaf\xaf\xaf\xaf\xaf
+ Copyright 2005 Princed Development Team
+  Created: 19 Mar 2005
+
+  Author: Enrique Calot <ecalot.cod@princed.com.ar>
+  Version: 1.00 (2005-Mar-19)
+
+ Note:
+  DO NOT remove this copyright notice
+*/
+
+#include "xmlsearch.h" /* tTag */
+#include "memory.h" /* malloc, strallocandcopy */
+#include <string.h> /* strcat */
+#include "disk.h"
+
+/* Private Searching Structures */
+
+/* File List Structure */
+typedef struct tFileDir {
+	char* text;
+	struct tFileDir* next;
+}tFileDir;
+
+typedef struct {
+	tFileDir* filenames;
+	tFileDir* options;
+}tFileDir2;
+
+/* layer 1: stack implementation */
+
+int filedir_push(const char* text, tFileDir** list, int checkEquals) {
+	/*
+		Adds the file to the list only once
+	*/
+	tFileDir* node;
+
+	/* Verify if the file exists */
+	if (checkEquals) {
+		node=*list;
+		while (node) {
+			if (equalsIgnoreCase(node->text,text)) /* TODO: use defines If file was in the list, do nothing */
+			/*if (!strcmp(node->file,text)) * If file was in the list, do nothing */
+				return -1;
+			node=node->next;
+		}
+	}
+
+	/* Add new node */
+	node=(tFileDir*)malloc(sizeof(tFileDir));
+
+	/* Use LIFO because its more probable to get a file with the same name */
+	node->text=strallocandcopy(text);
+	node->next=*list;
+	*list=node;
+	return 0;
+}
+
+char* filedir_pop(tFileDir** list) {
+	/*
+		Returns and removes one random file from the list
+	*/
+	char* result;
+	tFileDir* aux;
+	if (*list) {
+		/* Remember node values */
+		aux=*list;
+		result=(*list)->text;
+		/* move one position */
+		*list=(*list)->next;
+		/* free node */
+		free(aux);
+
+		return result;
+	} else {
+		return NULL;
+	}
+}
+
+/* layer 2, module Import one directory */
+typedef struct {
+	const char* dir;
+	const char* opt;
+	tFileDir2*  list;
+}tPassListAndDir;
+
+void addFileToList(const char* file,void* pass2) {
+	register tPassListAndDir* pass=pass2;
+	char path[256];
+	char* dat;
+	if (pass->dir) {
+		strcpy(path,pass->dir);
+		strcat(path,"/");
+		strcat(path,file);
+	} else {
+		strcpy(path,file);
+	}
+	dat=strallocandcopy(getFileNameFromPath(path));
+	strcat(path,pass->opt);
+	if(!filedir_push(path,&(pass->list->filenames),1))
+		filedir_push(dat,&(pass->list->options),0);
+	free(dat);
+}
+
+void addFileToListTag(const tTag* t,void* pass2) {
+	addFileToList(t->file,pass2);
+}
+
+/* Search all files in the xml tree and returns them */
+int listAllDatFiles(const char* vResFile, const char* directory, const char* opt, tFileDir2* list) {
+	/* Declare error variable */
+	tPassListAndDir pass;
+	tTag* structure;
+	int error;
+	
+	pass.dir=directory;
+	pass.opt=opt;
+	pass.list=list;
+
+	/* Generate xml structure if doesn't exist */
+	if ((error=parseStructure(vResFile,&structure))) return error;
+
+	/* Use the xml structure to Generate the file list */
+	workTree(structure,&pass,addFileToListTag);
+
+	/* All done */
+	list=pass.list;
+	return 0;
+}
+
+/* layer 2, module check if a file is in the xml */
+typedef struct {
+	const char* file;
+	int result;
+}tPassFileAndResult;
+
+void checkIfFileExists(const tTag* t,void* pass2) {
+	register tPassFileAndResult* pass=pass2;
+	if (equalsIgnoreCase(pass->file,t->file)) pass->result=1;
+}
+
+int isADatFile(const char* vResFile, const char* file) {
+	/* Declare error variable */
+	tPassFileAndResult pass;
+	tTag* structure;
+	int error;
+	
+	pass.file=getFileNameFromPath(file);
+	pass.result=0;
+
+	/* TODO: directory must end with / */
+	
+	/* Generate xml structure if doesn't exist */
+	if ((error=parseStructure(vResFile,&structure))) return error;
+
+	/* Use the xml structure to Generate the file list */
+	workTree(structure,&pass,checkIfFileExists);
+
+	/* All done */
+	return pass.result;
+}
+
+/* layer 2, module check Import type */
+int fileDirGetFilesImport(tFileDir2* list1,tFileDir2* files,const char* resfile) {
+	char* file;
+	char* opt;
+	whatIs type;
+	int dirs=0;
+	int fils=0;
+	char output[255];
+	int parseError=0;
+
+	files->filenames=NULL;
+	files->options=NULL;
+	
+	while ((file=filedir_pop(&(list1->filenames)))) {
+		opt=filedir_pop(&(list1->options));
+		type=isDir(file);
+		
+		/* a not found file may become either a directory or a file depending on the res file */
+		if (type==eNotFound) {
+			int isdat=isADatFile(resfile,file);
+			if (isdat<0) parseError=isdat;
+
+			if (isdat) {
+				type=eFile;
+			} else {
+				type=eDirectory;
+			}
+		}
+		
+		if ((!dirs)&&type==eDirectory) {
+			parseError=listAllDatFiles(resfile, file, opt, files);
+		}
+		if (type==eDirectory) dirs++;
+		if (type==eFile) {
+			fils++;
+			strcpy(output,file);
+			filedir_push(getFileNameFromPath(output), &(files->options), 0);
+			strcat(output,opt);
+			filedir_push(output, &(files->filenames), 0);
+		}
+
+		free(opt);
+		free(file);
+	}
+	printf("fils=%d dirs=%d\n",fils,dirs);
+	if (dirs>1) {
+		while ((file=filedir_pop(&(files->filenames)))) free(file); /* empty list */
+		return -20;
+	}
+	if (!fils&&!dirs)
+		return -22; /* no files selected */
+
+	if (parseError) {
+		while ((file=filedir_pop(&(files->filenames)))) free(file); /* empty list */
+		return parseError;
+	}
+	return 0;
+}
+
+/* layer 2, module Export */
+int fileDirGetFilesExport(tFileDir2* list1,tFileDir2* files,int notHasRecursiveFlag) {
+	char* file;
+	char* opt;
+	tPassListAndDir pass;
+	whatIs type;
+	char output[255];
+
+	files->filenames=NULL;
+	files->options=NULL;
+
+	while ((file=filedir_pop(&(list1->filenames)))) {
+		opt=filedir_pop(&(list1->options));
+		type=isDir(file);
+		if (type==eDirectory) {
+			pass.dir=NULL;
+			pass.opt=opt;
+			pass.list=files;
+			recurseDirectory(file,!notHasRecursiveFlag,&pass,addFileToList);
+			files=pass.list;
+		} else {
+			strcpy(output,file);
+			filedir_push(getFileNameFromPath(output), &(files->options), 0);
+			strcat(output,opt);
+			filedir_push(output, &(files->filenames), 0);
+		}
+		free(opt);
+		free(file);
+	}
+	return 0;
+}
+
+
+
+
+/* layer 3, primitives */
+
+void fileDirClearOptions(tFileDir2* list1) {
+	list1->filenames=NULL;
+	list1->options=NULL;
+}
+
+void fileDirAddOption(tFileDir2* list1, const char* option) {
+	char fn[256];
+	char op[256];
+	enum {eop,efn} mode=efn;
+	const char* pOpt=option;
+	char* pFn=fn;
+	char* pOp=op;
+
+	do {
+		if (*pOpt=='@')
+			mode=eop;
+		if (mode==eop) {
+			*pOp=*pOpt;
+			pOp++;
+		} else {
+			if (pOpt[0]!='/'/*DIR_SEPARATOR*/ || (pOpt[1]!='\0' && pOpt[1]!='@')) { /* ignore last "/" */
+				*pFn=*pOpt;
+				pFn++;
+			}
+		}
+		pOpt++;
+	} while (*pOpt);
+
+	*pOp=0;
+	*pFn=0;
+
+	filedir_push(fn, &(list1->filenames),0);
+	filedir_push(op, &(list1->options),0);
+}
+
+
+
+int fileDirGetFiles(tFileDir2* list1,tFileDir2* files,int hasExportFlag,int notHasRecursiveFlag,const char* resfile) {
+/* case 1: * import from more than one directory */
+ 
+	if (!hasExportFlag&&!notHasRecursiveFlag) {
+		char* file;
+		while ((file=filedir_pop(&(list1->filenames)))) {
+			free(filedir_pop(&(list1->options)));
+			free(file);
+		}
+		return -21; /* import with recursive flag is now allowed */
+	}
+
+	if (hasExportFlag)
+		return fileDirGetFilesExport(list1,files,notHasRecursiveFlag);
+	else
+		return fileDirGetFilesImport(list1,files,resfile);
+	
+}
+
+char* fileDirGetFile(tFileDir2* files, char** datfile) {
+	*datfile=filedir_pop(&(files->options));
+	return filedir_pop(&(files->filenames));
+}
+
diff --git a/PR/src/console/main.c b/PR/src/console/main.c
index 9790925..194ce54 100644
--- a/PR/src/console/main.c
+++ b/PR/src/console/main.c
@@ -19,229 +19,29 @@
 */
 
 /*
-pr.c: Main source file for Princed Resources
+main.c: PR console program parsing routine
 \xaf\xaf\xaf\xaf
-	Princed Resources editor
-	(c) Copyright 2003, Princed Development Team
-
-	Authors
-	 Coding & main routines
-	  Enrique Calot
-	  Santiago Zamora
-
-	 Graphic compression algorithms
-	  Tammo Jan Dijkema
-	  Enrique Calot
-
-	 Graphic format development
-	  Tammo Jan Dijkema
-	  Anke Balderer
-
-	 MID Sound format development
-	  Christian Lundheim
-
-	 Resources.xml edition
-	  Steven Fayers
 
  Note:
   DO NOT remove this copyright notice
 */
 
-/* Headers */
-#include <stdio.h>
-#include <string.h>
-
-#include "pr.h"
-
-#include "compress.h"
-
-#include "extract.h"
-#include "compile.h"
-#include "tasks.h"
-
-#include "memory.h"    /* getMemory, free */
-#include "disk.h"      /* getFileNameFromPath */
-
-#ifndef DLL
- #ifdef UNIX
-  #include <unistd.h>
-  #ifndef LINUX
-   #include "getopt.h"
-  #endif
- #else
+#ifdef UNIX
+ #include <unistd.h>
+ #ifndef LINUX
   #include "getopt.h"
  #endif
+#else
+ #include "getopt.h"
 #endif
 
-/***************************************************************\
-|                      Main working functions                   |
-\***************************************************************/
-
-FILE* outputStream=NULL;
-
-#ifdef DLL
-void prSetOutput(FILE* output) {
-	outputStream=output;
-}
-#endif
-
-#ifdef DLL
-int prExportDat(const char* vDatFile, const char* vDirName, const char* vResFile) {
-	outputStream=stdout;
-	return prExportDatOpt(vDatFile,vDirName,vResFile,export_flag,NULL,NULL,NULL);
-}
-#endif
-
-int prExportDatOpt(const char* vDatFile, const char* vDirName, const char* vResFile,int opt,const char* vDatFileName,const char* datAuthor, const char* backupExtension) {
-	/*
-		Arguments:
-			char* vDatFile        - full Path to the dat file;
-			                        if file use it, if directory, perform it for
-			                        all files
-			char* vDirName        - full Path to the extracting folder
-			                        (doesn't need to exist)
-			char* vResFile        - full Path to the resources XML file
-			                        NULL is the default file resources.xml
-			char opt              - program options, see below
-			char* vDatFileName    - name of the file to be extracted
-			                        NULL means predict it from vDatFile
-			const char* datAuthor - Author's name when extracting PLV's,
-			                        NULL is default
-			const char* backupExtension
-			                      - If backup_flag is set, the string to attach
-			                        to the backup files
-
-		Options:
-			unknown_flag   - generate the unknown file without performing
-                       any extraction
-			raw_flag       - uses raw format
-			verbose_flag   - explain what is being done
-			recursive_flag - searches for all dat files (only if vDatFile
-			                 is not a dat file and vDatFileName is NULL)
-			force_flag     - default option, you cannot disable it,
-			                 so please make a backup of your files
-			backup_flag    - backup your files
-
-
-		Return values:
-			00 Ok
-			-1 Error accessing the file DAT
-			-2 Memory error in extraction
-			-3 Invalid DAT file
-			-4 XML Parse error
-			-5 Memory error in parsing
-			-6 XML Attribute not recognized
-			-7 XML File not found
-	*/
-
-	/* Declare variables */
-	tResource* r[MAX_RES_COUNT];
-	int a;
-	const char* aux;
-	char* currentDatFileName;
-	char* currentDatFile;
-
-	currentDatFile=strallocandcopy(vDatFileName);
-
-	parseGivenPath(currentDatFile);
-
-	if (vDatFileName==NULL) { /* if no special dat file was specified, a path parsed will be used */
-		aux=getFileNameFromPath(vDatFile);
-	} else {
-		aux=currentDatFile;
-	}
-	currentDatFileName=strallocandcopy(aux);
-
-	/* Parse XML and export the file */
-	a=parseFile(vResFile,currentDatFileName,r);
-	if (a<0) {
-		/* parsing errors */
-		a-=3;
-	} else {
-		/* exporting errors/no errors */
-		a=extract(vDatFile,vDirName,r,opt,currentDatFileName,datAuthor,backupExtension);
-	}
-	free(currentDatFileName);
-	free(currentDatFile);
-	freePartialList();
-
-	return a;
-}
-
-#ifdef DLL
-int prImportDat(const char* vDatFile, const char* vDirName, const char* vResFile) {
-	outputStream=stdout;
-	return prImportDatOpt(vDatFile,vDirName,vResFile,0,NULL,NULL);
-}
-#endif
-
-int prImportDatOpt(const char* vDatFile, const char* vDirName, const char* vResFile,int opt,const char* vDatFileName, const char* backupExtension) {
-	/*
-		Arguments:
-			char* vDatFile        - full Path to the dat file;
-			                        if file use it, if directory, perform it for
-			                        all files
-			char* vDirName        - full Path to the extracting folder
-			                        (doesn't need to exist)
-			char* vResFile        - full Path to the resources XML file
-			                        (resources.xml by default)
-			char opt              - program options, see below
-			char *vDatFileName    - name of the file to be extracted
-			                        NULL means predict it from vDatFile
-			const char* backupExtension
-			                      - If backup_flag is set, the string to attach
-			                        to the backup files
-
-		Options:
-			raw_flag       - uses raw format
-			verbose_flag   - explain what is being done
-			recursive_flag - searches for all dat files (only if vDatFile
-			                 is not a dat file and vDatFileName is NULL)
-			force_flag     - If not set and the file exists it will prompt
-			                 for action
-			backup_flag    - backup your files
-
-
-		Return values:
-			-1 DAT File couldn't be open for writing
-			-2 DAT file not found or invalid in partial importation
-			-3 XML Parse error
-			-4 No memory
-			-5 XML Attribute not recognized
-			-6 XML File not found
-			00 File successfully imported
-			positive number: number of missing files
-	*/
-
-	/* Declare variables */
-	tResource* r[MAX_RES_COUNT];
-	int a;
-	const char* aux;
-	char* currentDatFileName;
-
-	if (vDatFileName==NULL) { /* if no special dat file was specified, a path parsed will be used */
-		aux=getFileNameFromPath(vDatFile);
-	} else {
-		aux=vDatFileName;
-	}
-	currentDatFileName=strallocandcopy(aux);
+#include "pr.h"
+#include <string.h>
+#include "memory.h"
+#include "filedir.h"
+#include "xmlparse.h" /* free parsed cache */
 
-	/* Parse XML and import files */
-	a=parseFile(vResFile,currentDatFileName,r);
-	if (a<0) {
-		/* parsing errors */
-		a-=2;
-	} else {
-		/* importing errors/no errors */
-		a=compile (vDatFile, vDirName,r,opt,currentDatFileName,backupExtension);
-	}
-	free(currentDatFileName);
-	return a;
-}
-
-/***************************************************************\
-|                     M A I N   P R O G R A M                   |
-\***************************************************************/
+FILE* outputStream;
 
 void syntax() {
 	fprintf(outputStream,PARSING_HELP_BEGIN);
@@ -250,118 +50,6 @@ void syntax() {
 	fprintf(outputStream,PARSING_HELP_PART3);
 }
 
-int prMain(int optionflag, const char* extension,const char* dirName,const char* resFile,const char* datfile, const char* datfilename,const char* datAuthor,FILE* output) {
-
-	/* declare variables */
-	int returnValue;
-
-	outputStream=output;
-
-	/* do selected tasks */
-	if (hasFlag(export_flag)) { /* Export file */
-		char* array[]=PR_TEXT_EXPORT_ARRAY;
-		fprintf(output,PR_TEXT_TASK_EXTRACT,datfile,dirName);
-		returnValue=prExportDatOpt(datfile,dirName,resFile,optionflag,datfilename,datAuthor,extension);
-		fprintf(output,PR_TEXT_RESULT,array[-returnValue],returnValue);
-	}	else if (hasFlag(classify_flag)) { /* Classify file */
-		char* array[]=PR_TEXT_CLASSIFY_ARRAY;
-		fprintf(output,PR_TEXT_TASK_CLASSIFY,datfile);
-		returnValue=prVerifyDatType(datfile);
-		if (hasFlag(cgi_flag)) {
-			fprintf(output,PR_CGI_TEXT2,returnValue);
-		} else {
-			fprintf(output,PR_TEXT_RESULT,array[2+returnValue],returnValue);
-		}
-	}	else if (hasFlag(import_flag)) { /* Import file */
-		char* array[]=PR_TEXT_IMPORT_ARRAY;
-		fprintf(output,PR_TEXT_TASK_COMPILE,datfile,dirName);
-		returnValue=prImportDatOpt(datfile,dirName,resFile,optionflag,datfilename,extension);
-		if (returnValue<=0) {
-			fprintf(output,PR_TEXT_RESULT,array[-returnValue],returnValue);
-		} else {
-			fprintf(output,PR_TEXT_RESULT_ERR,returnValue);
-		}
-	} else {
-		syntax();
-		returnValue=-1;
-	}
-
-	return returnValue;
-}
-
-#ifndef DLL
-
-/***************************************************************\
-|             Standard executable specific functions            |
-\***************************************************************/
-
-int prStart(int optionflag, const char* extension,const char* dirName,const char* resFile,const char* datfile, const char* datfilename,const char* datAuthor,FILE* output) {
-	int result=1;
-	whatIs selectedFile;
-	outputStream=output;
-
-	/* Show about or cgi stuff */
-	if (hasFlag(cgi_flag)) {
-		fprintf(output,PR_CGI_TEXT1);
-	} else {
-		fprintf(output,PR_ABOUT);
-	}
-
-	/* Show version screen if requested */
-	if (hasFlag(version_flag)) {
-		fprintf(output,PARSING_ABOUT);
-		return -1;
-	}
-
-	/* If bad syntax or help screen requested */
-	if (hasFlag(help_flag)) {
-		syntax();
-		return -1;
-	}
-
-	/* Perform tasks depending on the argument */
-	if (hasFlag(import_flag)) {
-		/* We have to import something, let's see what the parameters are */
-		if (datfile==NULL) {
-			/* no files? let's use the whole current directory */
-			fprintf(output,PR_TEXT_IMPORTING_CURRENT);
-			importDir(dirName,resFile,optionflag,extension,".",output);
-		} else if ((selectedFile=isDir(datfile))!=eFile) {
-			fprintf(output,PR_TEXT_IMPORTING_GIVEN);
-			if ((selectedFile==eDirectory)||(isntADatFile(getFileNameFromPath(datfile),resFile))) {
-				/* it's a directory or doesn't exist (but it's not a dat file) */
-				importDir(dirName,resFile,optionflag,extension,datfile,output);
-			} else {
-				/* it doesn't exist but it's a dat file */
-				result=prMain(optionflag,extension,dirName,resFile,datfile,datfilename,datAuthor,output);
-			}
-		} else { /* it's only one existent file */
-			result=prMain(optionflag,extension,dirName,resFile,datfile,datfilename,datAuthor,output);
-		}
-	} else {
-		/* We have to export/classify something, perhaps we'll need to use somerecursive functions */
-		if (datfile==NULL) {
-			/* If nothing, let's use the current dir and check for all the files there */
-			fprintf(output,PR_TEXT_SCANNING_CURRENT);
-			recurseDirectory(".",optionflag,extension,dirName,resFile,datfilename,datAuthor,output);
-		} else if ((selectedFile=isDir(datfile))==eDirectory) {
-			/* If it's a directory, let's check for all the files there */
-			fprintf(output,PR_TEXT_SCANNING_GIVEN);
-			recurseDirectory(datfile,optionflag,extension,dirName,resFile,datfilename,datAuthor,output);
-		} else if (selectedFile==eNotFound) {
-			/* If the file doesn't exist, print an error and exit */
-			fprintf(output,PR_TEXT_FILE_NOT_FOUND,datfile);
-			result=0;
-		} else {
-			/* If it is a file, just do the tasks for it */
-			result=prMain(optionflag,extension,dirName,resFile,datfile,datfilename,datAuthor,output);
-		}
-	}
-
-	freeParsedStructure();
-	return result;
-}
-
 /***************************************************************\
 |      Standard executable command line parsing function        |
 \***************************************************************/
@@ -369,12 +57,16 @@ int prStart(int optionflag, const char* extension,const char* dirName,const char
 int main (int argc, char **argv) {
 	/* declare variables */
 	char  dirName[MAX_FILENAME_SIZE]=".";
-	char* datAuthor  =NULL;
-	char* datFileName=NULL;
-	char* datFilePath=NULL;
-	char* extension  =NULL;
-	char* resFile    =NULL;
-	int   c;
+	char* datAuthor        =NULL;
+	char* datFileName      =NULL;
+	char* datfile          =NULL;
+	char* extension        =NULL;
+	char* resFile          =NULL;
+	char* file;
+	char* exportErrors[]   =PR_TEXT_EXPORT_ARRAY;
+	char* classifyErrors[] =PR_TEXT_CLASSIFY_ARRAY;
+	char* importErrors[]   =PR_TEXT_IMPORT_ARRAY;
+	int   c,result;
 	int   optionflag=0;
 
 	/* Parse command line options */
@@ -444,37 +136,90 @@ int main (int argc, char **argv) {
 		}
 	} while (c!=-1);
 
-	if (optind < argc) datFilePath=strallocandcopy(argv[optind]);
-
+	outputStream=stdout;
+	c=0;
+	
 	/* At least one of these options must be selected, if not, the user needs help! */
 	if (!(hasFlag(import_flag|export_flag|classify_flag))) setFlag(help_flag);
 
-	parseGivenPath(datFilePath);
+	/* Show about or cgi stuff */
+	if (hasFlag(cgi_flag)) {
+		fprintf(outputStream,PR_CGI_TEXT1);
+	} else {
+		fprintf(outputStream,PR_ABOUT);
+	}
 
-	/* Run main program */
-	prStart(optionflag,extension,dirName,resFile,datFilePath,datFileName,datAuthor,stdout);
+	/* Show version screen if requested */
+	if (hasFlag(version_flag)) {
+		fprintf(outputStream,PARSING_ABOUT);
+		return -1;
+	}
 
-	/* Free memory and exit */
-	freePartialList();
+	if (hasFlag(help_flag)) {
+		syntax();
+	} else {
+		tFileDir2 files;
+		tFileDir2 input;
+		
+		fileDirClearOptions(&input);
+		if (optind < argc) {
+			while (optind < argc)
+				fileDirAddOption(&input,argv[optind++]);
+    } else {
+				fileDirAddOption(&input,".");
+		}
+		c=fileDirGetFiles(&input,&files,!hasFlag(import_flag),!hasFlag(recursive_flag),resFile);
+
+		switch (c) {
+		case -20: /* import from more than one directory */
+			fprintf(stderr,"You may select one directory to export all dat files or specifiy dat files.\nBoth actions are not allowed.\n");
+			break;
+		case -21: /* import with recursive flag */
+			fprintf(stderr,"Recursive flag must not be set when you import files\n");
+			break;
+		case -22: /* no files selected */
+			fprintf(stderr,"No files selected\n");
+			break;
+		case 0:
+			while ((file=fileDirGetFile(&files,&datfile))) {
+				const char* dat;
+				if (datFileName)
+					dat=datFileName;
+				else
+					dat=datfile;
+				/* Call PR */
+
+				if (hasFlag(import_flag)) {
+					/* import */
+					result=prImportDatOpt(file,dirName,resFile,optionflag,dat,extension);
+				} else if (hasFlag(export_flag)) {
+					/* export */
+					result=prExportDatOpt(file,dirName,resFile,optionflag,dat,datAuthor,extension);
+				} else {
+					/* classify */
+					result=prVerifyDatType(file);
+				}
+				printf("file: %s '%s' result=%d\n",file,dat,result);
+				free(file);
+				free(datfile);
+			}
+			break;
+		default:
+			fprintf(stderr,"Error, check the xml file\n");
+			break;
+		}
+		/*parseGivenPath(datFilePath);*/
+
+		/* Run main program */
+		/*prStart(optionflag,extension,dirName,resFile,datFilePath,datFileName,datAuthor,stdout);*/
+	}
+	freeParsingCache();
 	freeAllocation(datAuthor);
 	freeAllocation(datFileName);
-	freeAllocation(datFilePath);
 	freeAllocation(extension);
 	freeAllocation(resFile);
-#ifdef MEM_CHECK
-	showStats();
-#endif
-	return 0;
-}
-
-#endif
 
-/***************************************************************\
-|              Main Library start dummy function                |
-\***************************************************************/
+	return c;
+}
 
-#ifdef SO
-/* When compiling in Unix SO libraries */
-void start() {}
-#endif
 
diff --git a/PR/src/include/autodetect.h b/PR/src/include/autodetect.h
index 6a579a3..e41de4c 100644
--- a/PR/src/include/autodetect.h
+++ b/PR/src/include/autodetect.h
@@ -128,16 +128,8 @@ void getUpperFolder(char* aux, char* vFiledat);
 
 const char* getExtDesc(int type);
 
-/* parse file and free parsed structure */
+/* parse xml file */
 int parseFile(const char* vFile, const char* datFile, tResource* r[]);
-void freeParsedStructure();
-#ifdef DLL
-int parseStructure(const char* vFile);
-tTag* resourceTreeGetChild(tTag* whereAmI);
-tTag* resourceTreeGetNext (tTag* whereAmI);
-tTag* resourceTreeGetRoot ();
-int   resourceTreeGetInfo (tTag* whereAmI, char** tag, char** desc, char** path, char** file, char** itemtype, char** name, char** palette, char** type, char** value, char** version, char** number);
-#endif
 
 /* In case there are unknown resources it closes the unknown XML output */
 void endUnknownXml();
diff --git a/PR/src/include/common.h b/PR/src/include/common.h
index 5c5ea29..86e9b03 100644
--- a/PR/src/include/common.h
+++ b/PR/src/include/common.h
@@ -97,7 +97,7 @@ void prSetOutput(FILE* output);
 
 #define PR_URL                    "http://www.princed.com.ar"
 #define PR_VERSION                "v1.0-dev2"
-#define PR_COPY                   "(c) Copyright 2003, 2004 - Princed Development Team"
+#define PR_COPY                   "(c) Copyright 2003 - 2005 Princed Development Team"
 
 /***************************************************************\
 |                         Other defines                         |
diff --git a/PR/src/include/disk.h b/PR/src/include/disk.h
index 60f15aa..d774f32 100644
--- a/PR/src/include/disk.h
+++ b/PR/src/include/disk.h
@@ -69,7 +69,7 @@ int  mLoadFileArray(const char* vFile,unsigned char** array);
 int  makebase      (const char* p);
 const char* repairFolders(const char* a);
 const char* getFileNameFromPath(const char* path);
-int recurseDirectory(const char* path,int optionflag, const char* extension,const char* dirName,const char* resFile, const char* datfilename,const char* datAuthor,FILE* output);
+int recurseDirectory(const char* path,int recursive, void* pass, void (*function)(const char*,void*));
 whatIs isDir(const char *nombre);
 int mCopy(const char* strSource, const char* strTarget);
 #define mRemoveFile(a) remove(repairFolders(a))
diff --git a/PR/src/include/en.lang.pr.h b/PR/src/include/en.lang.pr.h
index e0c6906..7fa4523 100644
--- a/PR/src/include/en.lang.pr.h
+++ b/PR/src/include/en.lang.pr.h
@@ -96,7 +96,7 @@ pr.h: Princed Resources : English language strings
 "Valid DAT file with undefined content",\
 "Graphic DAT file",\
 "Internal PC Speaker dat file",\
-"","","",\
+NULL,NULL,NULL,\
 "Pop2 dat file"}
 
 #define PR_TEXT_IMPORT_ARRAY {\
diff --git a/PR/src/include/filedir.h b/PR/src/include/filedir.h
index e537976..28f29b7 100644
--- a/PR/src/include/filedir.h
+++ b/PR/src/include/filedir.h
@@ -35,46 +35,26 @@ xmlparse.h: Princed Resources : xml handling functions header file
 |                  I M P L E M E N T A T I O N                  |
 \***************************************************************/
 
-#ifndef _XMLSEARCH_H_
-#define _XMLSEARCH_H_
-
-/* Includes */
-#include "xmlparse.h"
-#include "resources.h"
-
-/****************************************************************\
-|                   Tag Tree Searching Functions                 |
-\****************************************************************/
-
-const tTag* searchTree(const tTag* t,const char* datFile, const char* id);
-void workTag(const tTag* t,void* pass);
-
-/* Abstract function that runs all the tree and executes "function(tag,pass)" for each tag */
-void workTree(const tTag* t,void* pass, void (*function)(const tTag*,void*));
-
-void compareXmlFile(tTag* modified,tTag* original);
-
-/* Searching Structures */
-
-/* File List Structure */
-typedef struct tListNode {
- char* file;
- struct tListNode* next;
-}tListNode;
-
-/* File List Functions */
-void addFileToList(const tTag* t,void* junk);
-char* getFileFromList();
-
-/* Abstract passing structures */
-typedef struct tPassWork {
-	const char* datFile;
-	tResource** r;
-}tPassWork;
-
-typedef struct tPassCompare {
-	const tTag* tag;
-}tPassCompare;
+#ifndef _FILEDIR_H_
+#define _FILEDIR_H_
+
+/* types */
+typedef struct tFileDir {
+        char* file;
+        struct tFileDir* next;
+}tFileDir;
+
+typedef struct {
+        tFileDir filenames;
+        tFileDir options;
+}tFileDir2;
+
+/* prototypes */
+
+void  fileDirClearOptions(tFileDir2* list1);
+void  fileDirAddOption(tFileDir2* list1, const char* option);
+int   fileDirGetFiles(tFileDir2* list1,tFileDir2* files,int hasExportFlag,int notHasRecursiveFlag,const char* vResFile);
+char* fileDirGetFile(tFileDir2* files,char** datfile);
 
 #endif
 
diff --git a/PR/src/include/idlist.h b/PR/src/include/idlist.h
index 6a579a3..e41de4c 100644
--- a/PR/src/include/idlist.h
+++ b/PR/src/include/idlist.h
@@ -128,16 +128,8 @@ void getUpperFolder(char* aux, char* vFiledat);
 
 const char* getExtDesc(int type);
 
-/* parse file and free parsed structure */
+/* parse xml file */
 int parseFile(const char* vFile, const char* datFile, tResource* r[]);
-void freeParsedStructure();
-#ifdef DLL
-int parseStructure(const char* vFile);
-tTag* resourceTreeGetChild(tTag* whereAmI);
-tTag* resourceTreeGetNext (tTag* whereAmI);
-tTag* resourceTreeGetRoot ();
-int   resourceTreeGetInfo (tTag* whereAmI, char** tag, char** desc, char** path, char** file, char** itemtype, char** name, char** palette, char** type, char** value, char** version, char** number);
-#endif
 
 /* In case there are unknown resources it closes the unknown XML output */
 void endUnknownXml();
diff --git a/PR/src/include/parse.h b/PR/src/include/parse.h
index 9035800..3dc4b22 100644
--- a/PR/src/include/parse.h
+++ b/PR/src/include/parse.h
@@ -59,4 +59,14 @@ typedef struct tTag {
 void  freeTagStructure (tTag* structure);
 tTag* parseXmlFile     (const char* vFile,int* error);
 
+int parseStructure(const char* vFile, tTag** structure);
+void freeParsedStructure(tTag** structure);
+void freeParsingCache();
+
+#ifdef DLL
+tTag* resourceTreeGetChild(tTag* whereAmI);
+tTag* resourceTreeGetNext (tTag* whereAmI);
+int   resourceTreeGetInfo (tTag* whereAmI, char** tag, char** desc, char** path, char** file, char** itemtype, char** name, char** palette, char** type, char** value, char** version, char** number);
+#endif
+
 #endif
diff --git a/PR/src/include/pr.h b/PR/src/include/pr.h
index 5c5ea29..86e9b03 100644
--- a/PR/src/include/pr.h
+++ b/PR/src/include/pr.h
@@ -97,7 +97,7 @@ void prSetOutput(FILE* output);
 
 #define PR_URL                    "http://www.princed.com.ar"
 #define PR_VERSION                "v1.0-dev2"
-#define PR_COPY                   "(c) Copyright 2003, 2004 - Princed Development Team"
+#define PR_COPY                   "(c) Copyright 2003 - 2005 Princed Development Team"
 
 /***************************************************************\
 |                         Other defines                         |
diff --git a/PR/src/include/search.h b/PR/src/include/search.h
index e537976..be33d05 100644
--- a/PR/src/include/search.h
+++ b/PR/src/include/search.h
@@ -54,16 +54,8 @@ void workTree(const tTag* t,void* pass, void (*function)(const tTag*,void*));
 
 void compareXmlFile(tTag* modified,tTag* original);
 
-/* Searching Structures */
-
-/* File List Structure */
-typedef struct tListNode {
- char* file;
- struct tListNode* next;
-}tListNode;
 
 /* File List Functions */
-void addFileToList(const tTag* t,void* junk);
 char* getFileFromList();
 
 /* Abstract passing structures */
diff --git a/PR/src/include/tree.h b/PR/src/include/tree.h
index 6a579a3..e41de4c 100644
--- a/PR/src/include/tree.h
+++ b/PR/src/include/tree.h
@@ -128,16 +128,8 @@ void getUpperFolder(char* aux, char* vFiledat);
 
 const char* getExtDesc(int type);
 
-/* parse file and free parsed structure */
+/* parse xml file */
 int parseFile(const char* vFile, const char* datFile, tResource* r[]);
-void freeParsedStructure();
-#ifdef DLL
-int parseStructure(const char* vFile);
-tTag* resourceTreeGetChild(tTag* whereAmI);
-tTag* resourceTreeGetNext (tTag* whereAmI);
-tTag* resourceTreeGetRoot ();
-int   resourceTreeGetInfo (tTag* whereAmI, char** tag, char** desc, char** path, char** file, char** itemtype, char** name, char** palette, char** type, char** value, char** version, char** number);
-#endif
 
 /* In case there are unknown resources it closes the unknown XML output */
 void endUnknownXml();
diff --git a/PR/src/include/unknown.h b/PR/src/include/unknown.h
index 6a579a3..e41de4c 100644
--- a/PR/src/include/unknown.h
+++ b/PR/src/include/unknown.h
@@ -128,16 +128,8 @@ void getUpperFolder(char* aux, char* vFiledat);
 
 const char* getExtDesc(int type);
 
-/* parse file and free parsed structure */
+/* parse xml file */
 int parseFile(const char* vFile, const char* datFile, tResource* r[]);
-void freeParsedStructure();
-#ifdef DLL
-int parseStructure(const char* vFile);
-tTag* resourceTreeGetChild(tTag* whereAmI);
-tTag* resourceTreeGetNext (tTag* whereAmI);
-tTag* resourceTreeGetRoot ();
-int   resourceTreeGetInfo (tTag* whereAmI, char** tag, char** desc, char** path, char** file, char** itemtype, char** name, char** palette, char** type, char** value, char** version, char** number);
-#endif
 
 /* In case there are unknown resources it closes the unknown XML output */
 void endUnknownXml();
diff --git a/PR/src/lib/layers/autodetect.c b/PR/src/lib/layers/autodetect.c
index 280a430..74c6291 100644
--- a/PR/src/lib/layers/autodetect.c
+++ b/PR/src/lib/layers/autodetect.c
@@ -244,49 +244,28 @@ void emptyTable(tResource* r[]) {
 	while (i--) *(r++)=NULL;
 }
 
-/* Resources input xml tree. Private+abstract variable */
-static tTag* xmlStructure=NULL; /* Keeping the parsed file structure in memory will save a lot of time */
 
-int parseStructure(const char* vFile) {
-	static const char defaultXmlFile[]=RES_XML_RESOURC_XML;
-	int error=0;
-
-	/* Generate xml structure if doesn't exist */
-	if (xmlStructure==NULL)	{
-		/* Set default values */
-		if (vFile==NULL) vFile=defaultXmlFile;
-		xmlStructure=parseXmlFile(vFile,&error);
-	}
-	if (error) xmlStructure=NULL;
-	return error;
-}
 
 /* parse file */
 int parseFile(const char* vFile, const char* datFile, tResource* r[]) {
 	/* Declare error variable */
 	int error;
 	tPassWork pass;
+	tTag* structure;
 
 	/* Generate xml structure if doesn't exist */
-	if ((error=(parseStructure(vFile)))) return error;
+	if ((error=parseStructure(vFile,&structure))) return error;
 
 	/* Use the xml structure to Generate the resource structure of the file */
 	emptyTable(r);
 	pass.datFile=datFile;
 	pass.r=r;
-	workTree(xmlStructure,&pass,workTag);
+	workTree(structure,&pass,workTag);
 
 	/* All done */
 	return 0;
 }
 
-void freeParsedStructure() {
-	/* Free if exist */
-	if (xmlStructure!=NULL) freeTagStructure(xmlStructure);
-	/* Reinitializes the variable */
-	xmlStructure=NULL;
-}
-
 /***************************************************************\
 |                     Unknown.xml primitives                    |
 \***************************************************************/
@@ -348,106 +327,3 @@ void getFileName(char* vFileext,const char* vDirExt,tResource* r,unsigned short
 		sprintf(vFileext,"%s/%s",vDirExt,r->path);
 	}
 }
-
-/* Search files for the Import feature */
-int importDir(const char* directory, const char* vResFile, int pOption, const char* backupExtension,const char* vDatDirectory, FILE* output) {
-	/* Declare error variable */
-	int error=0;
-	char* datfile;
-	char* recursive;
-	int sizeOfPath;
-	int sizeOfFile;
-	int result;
-
-	/* Generate xml structure if doesn't exist */
-	if ((error=(parseStructure(vResFile)))) return error;
-
-	/* Use the xml structure to Generate the file list */
-	workTree(xmlStructure,NULL,addFileToList);
-
-	while((datfile=getFileFromList())) {
-		sizeOfPath=strlen(vDatDirectory);
-		sizeOfFile=strlen(datfile);
-
-		/* Generate full vDatDirectory/datfile path */
-		recursive=(char*)malloc(sizeOfPath+sizeOfFile+2);
-		memcpy(recursive,vDatDirectory,sizeOfPath);
-		recursive[sizeOfPath]=DIR_SEPARATOR;
-		memcpy(recursive+sizeOfPath+1,datfile,sizeOfFile+1);
-
-		/* Run program */
-		result=prMain(pOption, backupExtension,directory,vResFile,recursive,datfile,NULL,output);
-		/* Free memory */
-		free(datfile);
-		free(recursive);
-	}
-
-	/* All done */
-	return result;
-}
-
-int isntADatFile(const char* testFile, const char* vResFile) {
-	/*
-		Results:
-			0  Is a dat file
-			1  It isn't a dat file
-			-1 Parse error
-			-2 No memory
-			-3 Attribute not recognized
-			-4 File not found
-	*/
-
-	/* Declare result variable */
-	int result;
-	char* gottenFile;
-
-	/* Generate xml structure if doesn't exist */
-	if ((result=(parseStructure(vResFile)))) return result;
-
-	/* Use the xml structure to Generate the file list */
-	workTree(xmlStructure,NULL,addFileToList);
-	while((gottenFile=(getFileFromList()))) {
-		result=result||equalsIgnoreCase(gottenFile,testFile);
-		free(gottenFile);
-	}
-
-	/* All done */
-	return !result;
-}
-
-/***************************************************************\
-|                Resource tree browsing for DLL                 |
-\***************************************************************/
-
-#ifdef DLL
-
-tTag* resourceTreeGetRoot () {
-	return xmlStructure;
-}
-
-tTag* resourceTreeGetNext (tTag* whereAmI) {
-	return whereAmI->next;
-}
-
-tTag* resourceTreeGetChild(tTag* whereAmI) {
-	return whereAmI->child;
-}
-
-int   resourceTreeGetInfo (tTag* whereAmI,	char** tag, char** desc, char** path, char** file, char** itemtype, char** name, char** palette, char** type, char** value, char** version, char** number) {
-	if (whereAmI==NULL) return 0;
-	*tag=whereAmI->tag;
-	*desc=whereAmI->desc;
-	*path=whereAmI->path;
-	*file=whereAmI->file;
-	*itemtype=whereAmI->itemtype;
-	*name=whereAmI->name;
-	*palette=whereAmI->palette;
-	*type=whereAmI->type;
-	*value=whereAmI->value;
-	*version=whereAmI->version;
-	*number=whereAmI->number;
-	return 1;
-}
-
-#endif
-
diff --git a/PR/src/lib/layers/dat.c b/PR/src/lib/layers/dat.c
index 15273e1..50f513d 100644
--- a/PR/src/lib/layers/dat.c
+++ b/PR/src/lib/layers/dat.c
@@ -34,10 +34,10 @@ dat.c: Princed Resources : DAT library
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include "pr.h"
 
 #include "disk.h"
 #include "dat.h"
+#include "pr.h"
 
 /***************************************************************\
 |                     DAT reading primitives                    |
@@ -70,8 +70,17 @@ int mReadBeginDatFile(unsigned short int *numberOfItems,const char* vFiledat){
 
 	/* Open file */
 	readDatFileSize=mLoadFileArray(vFiledat,&readDatFile);
-	if (!readDatFileSize) return 0;
-	if (readDatFileSize<=6) {free(readDatFile);return 0;}
+	if (!readDatFileSize) 
+	{
+		fprintf(stderr, "mReadBeginDatFile: %s not found\n", vFiledat);
+		return 0;
+	}
+	if (readDatFileSize<=6)
+	{
+		fprintf(stderr, "mReadBeginDatFile: File too short\n");
+		free(readDatFile);
+		return 0;
+	}
 
 	readDatFilePoint=readDatFile;
 
@@ -81,6 +90,7 @@ int mReadBeginDatFile(unsigned short int *numberOfItems,const char* vFiledat){
 	indexSize=array2short(readDatFilePoint);
 
 	if ((indexOffset>readDatFileSize)&&((indexOffset+indexSize)!=readDatFileSize)) {
+		fprintf(stderr, "mReadBeginDatFile: Invalid format\n");
 		free(readDatFile);
 		return 0; /* this is not a valid prince dat file */
 	}
@@ -102,13 +112,14 @@ int mReadBeginDatFile(unsigned short int *numberOfItems,const char* vFiledat){
 }
 
 int mReadFileInDatFile(int k,unsigned char* *data,unsigned long  int *size) {
-	int ok=1;
+	int ok=1; /* TODO: rename mRead* for mRead* and mWrite for mWrite */
 	unsigned short int id;
 
 	/* for each archived file the index is read */
-	id=    array2short(indexPointer+ofk+k*recordSize);/*(indexPointer[ofk+k*recordSize])+(indexPointer[ofk+k*recordSize+1]<<8);*/
-	offset=array2long(indexPointer+ofk+k*recordSize+2);/*indexPointer[ofk+k*recordSize+2])+(indexPointer[ofk+k*recordSize+3]<<8)+(indexPointer[ofk+k*recordSize+4]<<16)+(indexPointer[ofk+k*recordSize+5]<<24);*/
-	*size= array2short(indexPointer+ofk+k*recordSize+6)+1;/*indexPointer[ofk+k*recordSize+6])+(indexPointer[ofk+k*recordSize+7]<<8)+1;*/
+	id=array2short(indexPointer+ofk+k*recordSize);
+	
+	offset=array2long(indexPointer+ofk+k*recordSize+2);
+	*size= array2short(indexPointer+ofk+k*recordSize+6);
 	if ((!pop1)&&(!(indexPointer[ofk+k*recordSize+8]==0x40)&&(!indexPointer[ofk+k*recordSize+9])&&(!indexPointer[ofk+k*recordSize+10]))) return -1;
 	if (offset+indexSize>readDatFileSize) return -1;
 	*data=readDatFile+offset;
@@ -126,10 +137,10 @@ int mReadInitResource(tResource** res,const unsigned char* data,long size) {
 		(*res)->palette=0;
 		(*res)->number=0;
 		(*res)->size=(unsigned short int)size;
-		/* (*res)->offset=(unsigned short)offset; TODO delete this line */
-		(*res)->type=verifyHeader(data,(unsigned short int)size);
+		(*res)->offset=(unsigned short)offset; /* TODO delete this line */
+		/* (*res)->type=verifyHeader(data,(unsigned short int)size); */
 	} else { /* If resource type is invalid or 0, the type will be decided by PR */
-		if (!((*res)->type)) (*res)->type=verifyHeader(data,(unsigned short int)size);
+		if (!((*res)->type)) (*res)->type=0; /*verifyHeader(data,(unsigned short int)size);*/
 	}
 	return 0;
 }
@@ -152,7 +163,7 @@ int mWriteBeginDatFile(const char* vFile, int optionflag) {
 			 0 File couldn't be open
 
 	*/
-	if (writeOpen(vFile,&writeDatFile,optionflag|backup_flag)) {
+	if (writeOpen(vFile,&writeDatFile,optionflag)) {
 		fseek(writeDatFile,6,SEEK_SET);
 		return 1;
 	} else {
@@ -174,7 +185,7 @@ void mWriteInitResource(tResource** res) {
 void mWriteFileInDatFile(const unsigned char* data, int size) {
 	/*
 		Adds a data resource to a dat file keeping
-		abstractly the checksum verifications
+		abstractly the checksum ver	ifications
 	*/
 
 	/* Declare variables */
diff --git a/PR/src/lib/layers/disk.c b/PR/src/lib/layers/disk.c
index 5331747..f1aa1ab 100644
--- a/PR/src/lib/layers/disk.c
+++ b/PR/src/lib/layers/disk.c
@@ -73,7 +73,7 @@ const char *repairFolders(const char* a) {
 	static char result[MAX_FILENAME_SIZE];
 
 
-	for (i=0,k=0;a[i]&&(k<MAX_FILENAME_SIZE);) {
+	for (i=0,k=0;(k<MAX_FILENAME_SIZE)&&a[i];) {
 		if (isDirSep(a,i)) {
 			result[k]=DIR_SEPARATOR;
 			i++;
@@ -197,6 +197,7 @@ int writeClose(FILE* fp,int dontSave,int optionflag,const char* backupExtension)
 				fp=fopen(fileName,"wb");
 				if (fp==NULL) return -1;
 				fwrite(content,1,size,fp);
+				fclose(fp);
 			} else {
 				remove(fileName);
 			}
@@ -213,6 +214,7 @@ int writeClose(FILE* fp,int dontSave,int optionflag,const char* backupExtension)
 				fp=fopen(aux,"wb");
 				if (fp==NULL) return -2;
 				fwrite(content,1,size,fp);
+				fclose(fp);
 			}
 		}
 
@@ -220,7 +222,7 @@ int writeClose(FILE* fp,int dontSave,int optionflag,const char* backupExtension)
 		if (size) free(content);
 	}
 
-	return fclose(fp);
+	return 0;
 }
 
 int writeOpen(const char* vFileext, FILE* *fp, int optionflag) {
@@ -365,39 +367,6 @@ int mLoadFileArray(const char* vFile,unsigned char** array) {
 	}
 }
 
-#ifdef PR_FUTURE_CODE
-int mDiskVealidateFileHeader(unsigned char* text, int size, FILE* fp) {
-	/*
-		Validates if the file contains the following text in the stream.
-		1 if it does
-		0 if error or doesn't
-
-		Moves the file pointer to the next position
-	*/
-
-	/* Declare variables */
-	int i;
-	unsigned char* readText;
-
-	/* Reserves memory to allocate the read bytes */
-	readText=getMemory(size);
-	if (readText==NULL) return 0; /* memory error, abort */
-
-	/* Read the file and move the file pointer */
-	if (!fread(readText,size,1,fp)) {
-		free(readText);
-		return 0;
-	}
-
-	/* Make the binary compare */
-	for (i=0;(i<size)&&(readText[i]==text[i]);i++);
-
-	/* Frees memory and returns the result */
-	free(readText);
-	return (i==size); /* 0 if the compare for was stopped before end reached */
-}
-#endif
-
 const char* getFileNameFromPath(const char* path) {
 	/*
 		If you give a path you get the filename,
@@ -426,9 +395,7 @@ whatIs isDir(const char *path) {
 	return (S_IFDIR&buf.st_mode)?eDirectory:eFile;
 }
 
-#ifndef IGNORERECURSIVEFUNCTIONS
-
-int recurseDirectory(const char* path,int optionflag, const char* extension,const char* dirName,const char* resFile, const char* datfilename,const char* datAuthor,FILE* output) {
+int recurseDirectory(const char* path,int recursive, void* pass, void (*function)(const char*,void*)) {
 	/*
 		Search for all .dat files in the directory
 		if recursive flag is set search over the subdirectories
@@ -437,18 +404,13 @@ int recurseDirectory(const char* path,int optionflag, const char* extension,cons
 	*/
 
 	/* Declare variables */
-	char*          recursive;
+	char*          recursivePath;
 	struct dirent* directoryStructure;
 	DIR*           dir;
 
 	/* Opens directory */
 	if ((dir = opendir(path))==NULL) {
-		return 0;
-	}
-
-	/* Shows some messages */
-	if ((hasFlag(recursive_flag))&&(hasFlag(verbose_flag))) { /* Only recourse if recursive and verbose flags are set */
-		fprintf(outputStream,PR_TEXT_DISK_PROCESSING,path);
+		return -1;
 	}
 
 	/* Main loop: while there are still more files left */
@@ -463,34 +425,23 @@ int recurseDirectory(const char* path,int optionflag, const char* extension,cons
 			int sizeOfFile=strlen(directoryStructure->d_name);
 
 			/* Generate recursive path */
-			recursive=(char*)malloc(sizeOfPath+2+sizeOfFile);
-			memcpy(recursive,path,sizeOfPath);
-			recursive[sizeOfPath]=DIR_SEPARATOR;
-			memcpy(recursive+sizeOfPath+1,directoryStructure->d_name,sizeOfFile+1);
-
-			/*
-				If recursive path is a directory and recursive flag is set recourse into it
-				if recursive path is a directory and recursive flag wasn't set, just ignore
-				if recursive path is not a directory and is a dat file, do prMain
-				if recursive path is not a directory and is not a dat file, ignore
-			*/
-			if (isDir(recursive)==eDirectory) {
-				if (hasFlag(recursive_flag)) { /* Only recurse if recursive flag is set */
-					recurseDirectory(recursive,optionflag,extension,dirName,resFile,datfilename,datAuthor,output);
-				}
+			recursivePath=(char*)malloc(sizeOfPath+2+sizeOfFile);
+			memcpy(recursivePath,path,sizeOfPath);
+			recursivePath[sizeOfPath]=DIR_SEPARATOR;
+			memcpy(recursivePath+sizeOfPath+1,directoryStructure->d_name,sizeOfFile+1);
+
+			if (isDir(recursivePath)==eDirectory&&recursive) {
+				/* Only recurse if we are in a directory and recursive is true */
+				recurseDirectory(recursivePath,recursive,pass,function);
 			} else {
-				if (sizeOfFile>4) {
-					if (equalsIgnoreCase(".dat",directoryStructure->d_name+sizeOfFile-4)) {
-						prMain(optionflag,extension,dirName,resFile,recursive,directoryStructure->d_name,datAuthor,output);
-					}
-				}
+				function(recursivePath,pass);
 			}
 			/* Free all allocated memory */
-			free(recursive);
+			free(recursivePath);
 		}
 	}
 	closedir(dir);
-	return 1;
+	return 0;
 }
 
 #ifdef MACOS
@@ -537,5 +488,4 @@ int macfwritel(const void* var,FILE* file) {
 }
 
 #endif
-#endif
 
diff --git a/PR/src/lib/layers/idlist.c b/PR/src/lib/layers/idlist.c
index 280a430..74c6291 100644
--- a/PR/src/lib/layers/idlist.c
+++ b/PR/src/lib/layers/idlist.c
@@ -244,49 +244,28 @@ void emptyTable(tResource* r[]) {
 	while (i--) *(r++)=NULL;
 }
 
-/* Resources input xml tree. Private+abstract variable */
-static tTag* xmlStructure=NULL; /* Keeping the parsed file structure in memory will save a lot of time */
 
-int parseStructure(const char* vFile) {
-	static const char defaultXmlFile[]=RES_XML_RESOURC_XML;
-	int error=0;
-
-	/* Generate xml structure if doesn't exist */
-	if (xmlStructure==NULL)	{
-		/* Set default values */
-		if (vFile==NULL) vFile=defaultXmlFile;
-		xmlStructure=parseXmlFile(vFile,&error);
-	}
-	if (error) xmlStructure=NULL;
-	return error;
-}
 
 /* parse file */
 int parseFile(const char* vFile, const char* datFile, tResource* r[]) {
 	/* Declare error variable */
 	int error;
 	tPassWork pass;
+	tTag* structure;
 
 	/* Generate xml structure if doesn't exist */
-	if ((error=(parseStructure(vFile)))) return error;
+	if ((error=parseStructure(vFile,&structure))) return error;
 
 	/* Use the xml structure to Generate the resource structure of the file */
 	emptyTable(r);
 	pass.datFile=datFile;
 	pass.r=r;
-	workTree(xmlStructure,&pass,workTag);
+	workTree(structure,&pass,workTag);
 
 	/* All done */
 	return 0;
 }
 
-void freeParsedStructure() {
-	/* Free if exist */
-	if (xmlStructure!=NULL) freeTagStructure(xmlStructure);
-	/* Reinitializes the variable */
-	xmlStructure=NULL;
-}
-
 /***************************************************************\
 |                     Unknown.xml primitives                    |
 \***************************************************************/
@@ -348,106 +327,3 @@ void getFileName(char* vFileext,const char* vDirExt,tResource* r,unsigned short
 		sprintf(vFileext,"%s/%s",vDirExt,r->path);
 	}
 }
-
-/* Search files for the Import feature */
-int importDir(const char* directory, const char* vResFile, int pOption, const char* backupExtension,const char* vDatDirectory, FILE* output) {
-	/* Declare error variable */
-	int error=0;
-	char* datfile;
-	char* recursive;
-	int sizeOfPath;
-	int sizeOfFile;
-	int result;
-
-	/* Generate xml structure if doesn't exist */
-	if ((error=(parseStructure(vResFile)))) return error;
-
-	/* Use the xml structure to Generate the file list */
-	workTree(xmlStructure,NULL,addFileToList);
-
-	while((datfile=getFileFromList())) {
-		sizeOfPath=strlen(vDatDirectory);
-		sizeOfFile=strlen(datfile);
-
-		/* Generate full vDatDirectory/datfile path */
-		recursive=(char*)malloc(sizeOfPath+sizeOfFile+2);
-		memcpy(recursive,vDatDirectory,sizeOfPath);
-		recursive[sizeOfPath]=DIR_SEPARATOR;
-		memcpy(recursive+sizeOfPath+1,datfile,sizeOfFile+1);
-
-		/* Run program */
-		result=prMain(pOption, backupExtension,directory,vResFile,recursive,datfile,NULL,output);
-		/* Free memory */
-		free(datfile);
-		free(recursive);
-	}
-
-	/* All done */
-	return result;
-}
-
-int isntADatFile(const char* testFile, const char* vResFile) {
-	/*
-		Results:
-			0  Is a dat file
-			1  It isn't a dat file
-			-1 Parse error
-			-2 No memory
-			-3 Attribute not recognized
-			-4 File not found
-	*/
-
-	/* Declare result variable */
-	int result;
-	char* gottenFile;
-
-	/* Generate xml structure if doesn't exist */
-	if ((result=(parseStructure(vResFile)))) return result;
-
-	/* Use the xml structure to Generate the file list */
-	workTree(xmlStructure,NULL,addFileToList);
-	while((gottenFile=(getFileFromList()))) {
-		result=result||equalsIgnoreCase(gottenFile,testFile);
-		free(gottenFile);
-	}
-
-	/* All done */
-	return !result;
-}
-
-/***************************************************************\
-|                Resource tree browsing for DLL                 |
-\***************************************************************/
-
-#ifdef DLL
-
-tTag* resourceTreeGetRoot () {
-	return xmlStructure;
-}
-
-tTag* resourceTreeGetNext (tTag* whereAmI) {
-	return whereAmI->next;
-}
-
-tTag* resourceTreeGetChild(tTag* whereAmI) {
-	return whereAmI->child;
-}
-
-int   resourceTreeGetInfo (tTag* whereAmI,	char** tag, char** desc, char** path, char** file, char** itemtype, char** name, char** palette, char** type, char** value, char** version, char** number) {
-	if (whereAmI==NULL) return 0;
-	*tag=whereAmI->tag;
-	*desc=whereAmI->desc;
-	*path=whereAmI->path;
-	*file=whereAmI->file;
-	*itemtype=whereAmI->itemtype;
-	*name=whereAmI->name;
-	*palette=whereAmI->palette;
-	*type=whereAmI->type;
-	*value=whereAmI->value;
-	*version=whereAmI->version;
-	*number=whereAmI->number;
-	return 1;
-}
-
-#endif
-
diff --git a/PR/src/lib/pr.c b/PR/src/lib/pr.c
index 9790925..61e886f 100644
--- a/PR/src/lib/pr.c
+++ b/PR/src/lib/pr.c
@@ -19,7 +19,7 @@
 */
 
 /*
-pr.c: Main source file for Princed Resources
+pr.c: Main source file for Princed Resources library
 \xaf\xaf\xaf\xaf
 	Princed Resources editor
 	(c) Copyright 2003, Princed Development Team
@@ -62,16 +62,6 @@ pr.c: Main source file for Princed Resources
 #include "memory.h"    /* getMemory, free */
 #include "disk.h"      /* getFileNameFromPath */
 
-#ifndef DLL
- #ifdef UNIX
-  #include <unistd.h>
-  #ifndef LINUX
-   #include "getopt.h"
-  #endif
- #else
-  #include "getopt.h"
- #endif
-#endif
 
 /***************************************************************\
 |                      Main working functions                   |
@@ -79,18 +69,14 @@ pr.c: Main source file for Princed Resources
 
 FILE* outputStream=NULL;
 
-#ifdef DLL
 void prSetOutput(FILE* output) {
 	outputStream=output;
 }
-#endif
 
-#ifdef DLL
 int prExportDat(const char* vDatFile, const char* vDirName, const char* vResFile) {
 	outputStream=stdout;
 	return prExportDatOpt(vDatFile,vDirName,vResFile,export_flag,NULL,NULL,NULL);
 }
-#endif
 
 int prExportDatOpt(const char* vDatFile, const char* vDirName, const char* vResFile,int opt,const char* vDatFileName,const char* datAuthor, const char* backupExtension) {
 	/*
@@ -168,12 +154,10 @@ int prExportDatOpt(const char* vDatFile, const char* vDirName, const char* vResF
 	return a;
 }
 
-#ifdef DLL
 int prImportDat(const char* vDatFile, const char* vDirName, const char* vResFile) {
 	outputStream=stdout;
 	return prImportDatOpt(vDatFile,vDirName,vResFile,0,NULL,NULL);
 }
-#endif
 
 int prImportDatOpt(const char* vDatFile, const char* vDirName, const char* vResFile,int opt,const char* vDatFileName, const char* backupExtension) {
 	/*
@@ -239,241 +223,7 @@ int prImportDatOpt(const char* vDatFile, const char* vDirName, const char* vResF
 	return a;
 }
 
-/***************************************************************\
-|                     M A I N   P R O G R A M                   |
-\***************************************************************/
-
-void syntax() {
-	fprintf(outputStream,PARSING_HELP_BEGIN);
-	fprintf(outputStream,PARSING_HELP_PART1);
-	fprintf(outputStream,PARSING_HELP_PART2);
-	fprintf(outputStream,PARSING_HELP_PART3);
-}
-
-int prMain(int optionflag, const char* extension,const char* dirName,const char* resFile,const char* datfile, const char* datfilename,const char* datAuthor,FILE* output) {
-
-	/* declare variables */
-	int returnValue;
-
-	outputStream=output;
-
-	/* do selected tasks */
-	if (hasFlag(export_flag)) { /* Export file */
-		char* array[]=PR_TEXT_EXPORT_ARRAY;
-		fprintf(output,PR_TEXT_TASK_EXTRACT,datfile,dirName);
-		returnValue=prExportDatOpt(datfile,dirName,resFile,optionflag,datfilename,datAuthor,extension);
-		fprintf(output,PR_TEXT_RESULT,array[-returnValue],returnValue);
-	}	else if (hasFlag(classify_flag)) { /* Classify file */
-		char* array[]=PR_TEXT_CLASSIFY_ARRAY;
-		fprintf(output,PR_TEXT_TASK_CLASSIFY,datfile);
-		returnValue=prVerifyDatType(datfile);
-		if (hasFlag(cgi_flag)) {
-			fprintf(output,PR_CGI_TEXT2,returnValue);
-		} else {
-			fprintf(output,PR_TEXT_RESULT,array[2+returnValue],returnValue);
-		}
-	}	else if (hasFlag(import_flag)) { /* Import file */
-		char* array[]=PR_TEXT_IMPORT_ARRAY;
-		fprintf(output,PR_TEXT_TASK_COMPILE,datfile,dirName);
-		returnValue=prImportDatOpt(datfile,dirName,resFile,optionflag,datfilename,extension);
-		if (returnValue<=0) {
-			fprintf(output,PR_TEXT_RESULT,array[-returnValue],returnValue);
-		} else {
-			fprintf(output,PR_TEXT_RESULT_ERR,returnValue);
-		}
-	} else {
-		syntax();
-		returnValue=-1;
-	}
-
-	return returnValue;
-}
-
-#ifndef DLL
-
-/***************************************************************\
-|             Standard executable specific functions            |
-\***************************************************************/
-
-int prStart(int optionflag, const char* extension,const char* dirName,const char* resFile,const char* datfile, const char* datfilename,const char* datAuthor,FILE* output) {
-	int result=1;
-	whatIs selectedFile;
-	outputStream=output;
-
-	/* Show about or cgi stuff */
-	if (hasFlag(cgi_flag)) {
-		fprintf(output,PR_CGI_TEXT1);
-	} else {
-		fprintf(output,PR_ABOUT);
-	}
-
-	/* Show version screen if requested */
-	if (hasFlag(version_flag)) {
-		fprintf(output,PARSING_ABOUT);
-		return -1;
-	}
-
-	/* If bad syntax or help screen requested */
-	if (hasFlag(help_flag)) {
-		syntax();
-		return -1;
-	}
-
-	/* Perform tasks depending on the argument */
-	if (hasFlag(import_flag)) {
-		/* We have to import something, let's see what the parameters are */
-		if (datfile==NULL) {
-			/* no files? let's use the whole current directory */
-			fprintf(output,PR_TEXT_IMPORTING_CURRENT);
-			importDir(dirName,resFile,optionflag,extension,".",output);
-		} else if ((selectedFile=isDir(datfile))!=eFile) {
-			fprintf(output,PR_TEXT_IMPORTING_GIVEN);
-			if ((selectedFile==eDirectory)||(isntADatFile(getFileNameFromPath(datfile),resFile))) {
-				/* it's a directory or doesn't exist (but it's not a dat file) */
-				importDir(dirName,resFile,optionflag,extension,datfile,output);
-			} else {
-				/* it doesn't exist but it's a dat file */
-				result=prMain(optionflag,extension,dirName,resFile,datfile,datfilename,datAuthor,output);
-			}
-		} else { /* it's only one existent file */
-			result=prMain(optionflag,extension,dirName,resFile,datfile,datfilename,datAuthor,output);
-		}
-	} else {
-		/* We have to export/classify something, perhaps we'll need to use somerecursive functions */
-		if (datfile==NULL) {
-			/* If nothing, let's use the current dir and check for all the files there */
-			fprintf(output,PR_TEXT_SCANNING_CURRENT);
-			recurseDirectory(".",optionflag,extension,dirName,resFile,datfilename,datAuthor,output);
-		} else if ((selectedFile=isDir(datfile))==eDirectory) {
-			/* If it's a directory, let's check for all the files there */
-			fprintf(output,PR_TEXT_SCANNING_GIVEN);
-			recurseDirectory(datfile,optionflag,extension,dirName,resFile,datfilename,datAuthor,output);
-		} else if (selectedFile==eNotFound) {
-			/* If the file doesn't exist, print an error and exit */
-			fprintf(output,PR_TEXT_FILE_NOT_FOUND,datfile);
-			result=0;
-		} else {
-			/* If it is a file, just do the tasks for it */
-			result=prMain(optionflag,extension,dirName,resFile,datfile,datfilename,datAuthor,output);
-		}
-	}
-
-	freeParsedStructure();
-	return result;
-}
-
-/***************************************************************\
-|      Standard executable command line parsing function        |
-\***************************************************************/
-
-int main (int argc, char **argv) {
-	/* declare variables */
-	char  dirName[MAX_FILENAME_SIZE]=".";
-	char* datAuthor  =NULL;
-	char* datFileName=NULL;
-	char* datFilePath=NULL;
-	char* extension  =NULL;
-	char* resFile    =NULL;
-	int   c;
-	int   optionflag=0;
-
-	/* Parse command line options */
-	do {
-		static struct option long_options[] = PARSING_OPTIONS;
-		int junk = 0;
-
-		c = getopt_long(argc,argv,PARSING_CHARS,long_options,&junk);
-		switch (c) {
-				case 'c':
-				case 'i':
-					if (hasFlag(classify_flag|export_flag)) setFlag(help_flag);
-					setFlag(import_flag);
-					if (optarg) strncpy(dirName,optarg,MAX_FILENAME_SIZE);
-					break;
-				case 'g':
-					setFlag(cgi_flag); /* if cgi, a classify must be performed */
-				case 'd':
-					if (hasFlag(import_flag|export_flag)) setFlag(help_flag);
-					setFlag(classify_flag);
-					break;
-				case 'x':
-				case 'e':
-					if (hasFlag(classify_flag|import_flag)) setFlag(help_flag);
-					setFlag(export_flag);
-					if (optarg) strncpy(dirName,optarg,MAX_FILENAME_SIZE);
-					break;
-				case 'b':
-					setFlag(backup_flag);
-					freeAllocation(extension);
-					extension=strallocandcopy(optarg);
-					break;
-				case 'f':
-					setFlag(force_flag);
-					break;
-				case 's':
-					freeAllocation(resFile);
-					resFile=strallocandcopy(optarg);
-					break;
-				case 'r':
-#ifndef PR_IGNORE_RAW_OPTION
-					setFlag(raw_flag);
-					break;
-#endif
-				case 'R':
-					setFlag(recursive_flag);
-					break;
-				case 't':
-					freeAllocation(datFileName);
-					datFileName=strallocandcopy(optarg);
-					break;
-				case 'a':
-					freeAllocation(datAuthor);
-					datAuthor=strallocandcopy(optarg);
-					break;
-				case 'v':
-					setFlag(verbose_flag);
-					break;
-				case 2:
-					setFlag(unknown_flag);
-				case -1:
-					break;
-				case 1:
-					setFlag(version_flag);
-				default:
-					setFlag(help_flag);
-		}
-	} while (c!=-1);
-
-	if (optind < argc) datFilePath=strallocandcopy(argv[optind]);
-
-	/* At least one of these options must be selected, if not, the user needs help! */
-	if (!(hasFlag(import_flag|export_flag|classify_flag))) setFlag(help_flag);
-
-	parseGivenPath(datFilePath);
-
-	/* Run main program */
-	prStart(optionflag,extension,dirName,resFile,datFilePath,datFileName,datAuthor,stdout);
-
-	/* Free memory and exit */
-	freePartialList();
-	freeAllocation(datAuthor);
-	freeAllocation(datFileName);
-	freeAllocation(datFilePath);
-	freeAllocation(extension);
-	freeAllocation(resFile);
-#ifdef MEM_CHECK
-	showStats();
-#endif
-	return 0;
-}
-
-#endif
-
-/***************************************************************\
-|              Main Library start dummy function                |
-\***************************************************************/
-
-#ifdef SO
+#ifdef UNIX
 /* When compiling in Unix SO libraries */
 void start() {}
 #endif
diff --git a/PR/src/lib/xml/parse.c b/PR/src/lib/xml/parse.c
index 4858622..07ebb64 100644
--- a/PR/src/lib/xml/parse.c
+++ b/PR/src/lib/xml/parse.c
@@ -503,3 +503,72 @@ tTag* parseXmlFile(const char* vFile,int* error) {
 		return NULL;
 	}
 }
+
+static tTag* xmlStructure=NULL; /* Keeping the parsed file structure in memory will save a lot of time */
+static char lastFile[256]="";
+
+/* cache parsed structure. If null is passed the default name will be used */
+int parseStructure(const char* vFile,tTag** structure) {
+	/* Resources input xml tree. Private+abstract variable */
+	static const char defaultXmlFile[]=RES_XML_RESOURC_XML;
+	int error=0;
+
+	if (vFile==NULL) vFile=defaultXmlFile;
+	
+	/* Generate xml structure if doesn't exist */
+	if (strcmp(lastFile,vFile)) {
+		/* if the file is different than the cached file */
+		freeParsedStructure(&xmlStructure);
+		xmlStructure=parseXmlFile(vFile,&error);
+		strncpy(lastFile,vFile,256); /* remember the new cached filename */
+	}
+
+	if (error) xmlStructure=NULL;
+	*structure=xmlStructure;
+	return error;
+}
+
+void freeParsingCache() {
+	freeParsedStructure(&xmlStructure);
+	lastFile[0]=0;
+}
+
+void freeParsedStructure(tTag** structure) {
+	/* Free it only if exists */
+	if (*structure!=NULL) freeTagStructure(*structure);
+	/* Reinitializes the variable */
+	*structure=NULL;
+}
+
+/***************************************************************\
+|                Resource tree browsing for DLL                 |
+\***************************************************************/
+
+#ifdef DLL
+
+tTag* resourceTreeGetNext (tTag* whereAmI) {
+	return whereAmI->next;
+}
+
+tTag* resourceTreeGetChild(tTag* whereAmI) {
+	return whereAmI->child;
+}
+
+int   resourceTreeGetInfo (tTag* whereAmI,	char** tag, char** desc, char** path, char** file, char** itemtype, char** name, char** palette, char** type, char** value, char** version, char** number) {
+	if (whereAmI==NULL) return 0;
+	*tag=whereAmI->tag;
+	*desc=whereAmI->desc;
+	*path=whereAmI->path;
+	*file=whereAmI->file;
+	*itemtype=whereAmI->itemtype;
+	*name=whereAmI->name;
+	*palette=whereAmI->palette;
+	*type=whereAmI->type;
+	*value=whereAmI->value;
+	*version=whereAmI->version;
+	*number=whereAmI->number;
+	return 1;
+}
+
+#endif
+
diff --git a/PR/src/lib/xml/search.c b/PR/src/lib/xml/search.c
index 2d378da..ce8dff5 100644
--- a/PR/src/lib/xml/search.c
+++ b/PR/src/lib/xml/search.c
@@ -111,54 +111,6 @@ void workTree(const tTag* t,void* pass, void (*function)(const tTag*,void*)) {
 	}
 }
 
-/****************************************************************\
-|                       File List Primitives                     |
-\****************************************************************/
-
-static tListNode* list=NULL;
-
-void addFileToList(const tTag* t,void* junk) {
-	/*
-		Adds the file to the list only once
-	*/
-	tListNode* node=list;
-
-	/* Verify if the file exists */
-	while (node) {
-		if (equalsIgnoreCase(node->file,t->file)) /* If file was in the list, do nothing */
-			return;
-		node=node->next;
-	}
-	/* Add new node */
-	node=(tListNode*)malloc(sizeof(tListNode));
-
-	/* Use LIFO because its more probable to get a file with the same name */
-	node->file=strallocandcopy(t->file);
-	node->next=list;
-	list=node;
-}
-
-char* getFileFromList() {
-	/*
-		Returns and removes one random file from the list
-	*/
-	char* result;
-	tListNode* aux;
-	if (list) {
-		/* Remember node values */
-		aux=list;
-		result=list->file;
-		/* move one position */
-		list=list->next;
-		/* free node */
-		free(aux);
-
-		return result;
-	} else {
-		return NULL;
-	}
-}
-
 /****************************************************************\
 |                       Compare two XML files                    |
 \****************************************************************/
diff --git a/PR/src/lib/xml/tree.c b/PR/src/lib/xml/tree.c
index 280a430..74c6291 100644
--- a/PR/src/lib/xml/tree.c
+++ b/PR/src/lib/xml/tree.c
@@ -244,49 +244,28 @@ void emptyTable(tResource* r[]) {
 	while (i--) *(r++)=NULL;
 }
 
-/* Resources input xml tree. Private+abstract variable */
-static tTag* xmlStructure=NULL; /* Keeping the parsed file structure in memory will save a lot of time */
 
-int parseStructure(const char* vFile) {
-	static const char defaultXmlFile[]=RES_XML_RESOURC_XML;
-	int error=0;
-
-	/* Generate xml structure if doesn't exist */
-	if (xmlStructure==NULL)	{
-		/* Set default values */
-		if (vFile==NULL) vFile=defaultXmlFile;
-		xmlStructure=parseXmlFile(vFile,&error);
-	}
-	if (error) xmlStructure=NULL;
-	return error;
-}
 
 /* parse file */
 int parseFile(const char* vFile, const char* datFile, tResource* r[]) {
 	/* Declare error variable */
 	int error;
 	tPassWork pass;
+	tTag* structure;
 
 	/* Generate xml structure if doesn't exist */
-	if ((error=(parseStructure(vFile)))) return error;
+	if ((error=parseStructure(vFile,&structure))) return error;
 
 	/* Use the xml structure to Generate the resource structure of the file */
 	emptyTable(r);
 	pass.datFile=datFile;
 	pass.r=r;
-	workTree(xmlStructure,&pass,workTag);
+	workTree(structure,&pass,workTag);
 
 	/* All done */
 	return 0;
 }
 
-void freeParsedStructure() {
-	/* Free if exist */
-	if (xmlStructure!=NULL) freeTagStructure(xmlStructure);
-	/* Reinitializes the variable */
-	xmlStructure=NULL;
-}
-
 /***************************************************************\
 |                     Unknown.xml primitives                    |
 \***************************************************************/
@@ -348,106 +327,3 @@ void getFileName(char* vFileext,const char* vDirExt,tResource* r,unsigned short
 		sprintf(vFileext,"%s/%s",vDirExt,r->path);
 	}
 }
-
-/* Search files for the Import feature */
-int importDir(const char* directory, const char* vResFile, int pOption, const char* backupExtension,const char* vDatDirectory, FILE* output) {
-	/* Declare error variable */
-	int error=0;
-	char* datfile;
-	char* recursive;
-	int sizeOfPath;
-	int sizeOfFile;
-	int result;
-
-	/* Generate xml structure if doesn't exist */
-	if ((error=(parseStructure(vResFile)))) return error;
-
-	/* Use the xml structure to Generate the file list */
-	workTree(xmlStructure,NULL,addFileToList);
-
-	while((datfile=getFileFromList())) {
-		sizeOfPath=strlen(vDatDirectory);
-		sizeOfFile=strlen(datfile);
-
-		/* Generate full vDatDirectory/datfile path */
-		recursive=(char*)malloc(sizeOfPath+sizeOfFile+2);
-		memcpy(recursive,vDatDirectory,sizeOfPath);
-		recursive[sizeOfPath]=DIR_SEPARATOR;
-		memcpy(recursive+sizeOfPath+1,datfile,sizeOfFile+1);
-
-		/* Run program */
-		result=prMain(pOption, backupExtension,directory,vResFile,recursive,datfile,NULL,output);
-		/* Free memory */
-		free(datfile);
-		free(recursive);
-	}
-
-	/* All done */
-	return result;
-}
-
-int isntADatFile(const char* testFile, const char* vResFile) {
-	/*
-		Results:
-			0  Is a dat file
-			1  It isn't a dat file
-			-1 Parse error
-			-2 No memory
-			-3 Attribute not recognized
-			-4 File not found
-	*/
-
-	/* Declare result variable */
-	int result;
-	char* gottenFile;
-
-	/* Generate xml structure if doesn't exist */
-	if ((result=(parseStructure(vResFile)))) return result;
-
-	/* Use the xml structure to Generate the file list */
-	workTree(xmlStructure,NULL,addFileToList);
-	while((gottenFile=(getFileFromList()))) {
-		result=result||equalsIgnoreCase(gottenFile,testFile);
-		free(gottenFile);
-	}
-
-	/* All done */
-	return !result;
-}
-
-/***************************************************************\
-|                Resource tree browsing for DLL                 |
-\***************************************************************/
-
-#ifdef DLL
-
-tTag* resourceTreeGetRoot () {
-	return xmlStructure;
-}
-
-tTag* resourceTreeGetNext (tTag* whereAmI) {
-	return whereAmI->next;
-}
-
-tTag* resourceTreeGetChild(tTag* whereAmI) {
-	return whereAmI->child;
-}
-
-int   resourceTreeGetInfo (tTag* whereAmI,	char** tag, char** desc, char** path, char** file, char** itemtype, char** name, char** palette, char** type, char** value, char** version, char** number) {
-	if (whereAmI==NULL) return 0;
-	*tag=whereAmI->tag;
-	*desc=whereAmI->desc;
-	*path=whereAmI->path;
-	*file=whereAmI->file;
-	*itemtype=whereAmI->itemtype;
-	*name=whereAmI->name;
-	*palette=whereAmI->palette;
-	*type=whereAmI->type;
-	*value=whereAmI->value;
-	*version=whereAmI->version;
-	*number=whereAmI->number;
-	return 1;
-}
-
-#endif
-
diff --git a/PR/src/lib/xml/unknown.c b/PR/src/lib/xml/unknown.c
index 280a430..74c6291 100644
--- a/PR/src/lib/xml/unknown.c
+++ b/PR/src/lib/xml/unknown.c
@@ -244,49 +244,28 @@ void emptyTable(tResource* r[]) {
 	while (i--) *(r++)=NULL;
 }
 
-/* Resources input xml tree. Private+abstract variable */
-static tTag* xmlStructure=NULL; /* Keeping the parsed file structure in memory will save a lot of time */
 
-int parseStructure(const char* vFile) {
-	static const char defaultXmlFile[]=RES_XML_RESOURC_XML;
-	int error=0;
-
-	/* Generate xml structure if doesn't exist */
-	if (xmlStructure==NULL)	{
-		/* Set default values */
-		if (vFile==NULL) vFile=defaultXmlFile;
-		xmlStructure=parseXmlFile(vFile,&error);
-	}
-	if (error) xmlStructure=NULL;
-	return error;
-}
 
 /* parse file */
 int parseFile(const char* vFile, const char* datFile, tResource* r[]) {
 	/* Declare error variable */
 	int error;
 	tPassWork pass;
+	tTag* structure;
 
 	/* Generate xml structure if doesn't exist */
-	if ((error=(parseStructure(vFile)))) return error;
+	if ((error=parseStructure(vFile,&structure))) return error;
 
 	/* Use the xml structure to Generate the resource structure of the file */
 	emptyTable(r);
 	pass.datFile=datFile;
 	pass.r=r;
-	workTree(xmlStructure,&pass,workTag);
+	workTree(structure,&pass,workTag);
 
 	/* All done */
 	return 0;
 }
 
-void freeParsedStructure() {
-	/* Free if exist */
-	if (xmlStructure!=NULL) freeTagStructure(xmlStructure);
-	/* Reinitializes the variable */
-	xmlStructure=NULL;
-}
-
 /***************************************************************\
 |                     Unknown.xml primitives                    |
 \***************************************************************/
@@ -348,106 +327,3 @@ void getFileName(char* vFileext,const char* vDirExt,tResource* r,unsigned short
 		sprintf(vFileext,"%s/%s",vDirExt,r->path);
 	}
 }
-
-/* Search files for the Import feature */
-int importDir(const char* directory, const char* vResFile, int pOption, const char* backupExtension,const char* vDatDirectory, FILE* output) {
-	/* Declare error variable */
-	int error=0;
-	char* datfile;
-	char* recursive;
-	int sizeOfPath;
-	int sizeOfFile;
-	int result;
-
-	/* Generate xml structure if doesn't exist */
-	if ((error=(parseStructure(vResFile)))) return error;
-
-	/* Use the xml structure to Generate the file list */
-	workTree(xmlStructure,NULL,addFileToList);
-
-	while((datfile=getFileFromList())) {
-		sizeOfPath=strlen(vDatDirectory);
-		sizeOfFile=strlen(datfile);
-
-		/* Generate full vDatDirectory/datfile path */
-		recursive=(char*)malloc(sizeOfPath+sizeOfFile+2);
-		memcpy(recursive,vDatDirectory,sizeOfPath);
-		recursive[sizeOfPath]=DIR_SEPARATOR;
-		memcpy(recursive+sizeOfPath+1,datfile,sizeOfFile+1);
-
-		/* Run program */
-		result=prMain(pOption, backupExtension,directory,vResFile,recursive,datfile,NULL,output);
-		/* Free memory */
-		free(datfile);
-		free(recursive);
-	}
-
-	/* All done */
-	return result;
-}
-
-int isntADatFile(const char* testFile, const char* vResFile) {
-	/*
-		Results:
-			0  Is a dat file
-			1  It isn't a dat file
-			-1 Parse error
-			-2 No memory
-			-3 Attribute not recognized
-			-4 File not found
-	*/
-
-	/* Declare result variable */
-	int result;
-	char* gottenFile;
-
-	/* Generate xml structure if doesn't exist */
-	if ((result=(parseStructure(vResFile)))) return result;
-
-	/* Use the xml structure to Generate the file list */
-	workTree(xmlStructure,NULL,addFileToList);
-	while((gottenFile=(getFileFromList()))) {
-		result=result||equalsIgnoreCase(gottenFile,testFile);
-		free(gottenFile);
-	}
-
-	/* All done */
-	return !result;
-}
-
-/***************************************************************\
-|                Resource tree browsing for DLL                 |
-\***************************************************************/
-
-#ifdef DLL
-
-tTag* resourceTreeGetRoot () {
-	return xmlStructure;
-}
-
-tTag* resourceTreeGetNext (tTag* whereAmI) {
-	return whereAmI->next;
-}
-
-tTag* resourceTreeGetChild(tTag* whereAmI) {
-	return whereAmI->child;
-}
-
-int   resourceTreeGetInfo (tTag* whereAmI,	char** tag, char** desc, char** path, char** file, char** itemtype, char** name, char** palette, char** type, char** value, char** version, char** number) {
-	if (whereAmI==NULL) return 0;
-	*tag=whereAmI->tag;
-	*desc=whereAmI->desc;
-	*path=whereAmI->path;
-	*file=whereAmI->file;
-	*itemtype=whereAmI->itemtype;
-	*name=whereAmI->name;
-	*palette=whereAmI->palette;
-	*type=whereAmI->type;
-	*value=whereAmI->value;
-	*version=whereAmI->version;
-	*number=whereAmI->number;
-	return 1;
-}
-
-#endif
-