Kolibri package manager

git-svn-id: svn://kolibrios.org@5725 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2015-08-16 07:53:30 +00:00
parent 69d74aa6a7
commit 11387d6d18
14 changed files with 7034 additions and 0 deletions

View File

@ -0,0 +1,63 @@
NAME= kpm
FASM= fasm.exe
CC = kos32-gcc
AR = kos32-ar
LD = kos32-ld
CPP= kos32-g++
STRIP = kos32-strip
CFLAGS = -U_Win32 -U_WIN32 -U__MINGW32__ -c -Os -fno-ident -fomit-frame-pointer -mno-ms-bitfields
ARFLAG = crs
SDK_DIR:= $(abspath ../../sdk)
LIB_DIR:= $(SDK_DIR)/lib
INCLUDES= -I. -I$(SDK_DIR)/sources/newlib/libc/include
INCLUDES+=-I$(SDK_DIR)/sources/freetype/include
#DEFINES= -DDEBUG=1
DEFINES= -DNDEBUG
LIBS:= -lsupc++ -lgcc_eh -lc.dll -lapp -lgcc
LIBPATH:= -L$(LIB_DIR) -L/home/autobuild/tools/win32/mingw32/lib
LDFLAGS = -static -nostdlib --stack 0x30000 -Map kpm.map -T$(SDK_DIR)/sources/newlib/app.lds --image-base 0
SOURCES = http.asm \
kpm.c \
collection.cpp \
tinyxml/tinyxml.cpp \
tinyxml/tinystr.cpp \
tinyxml/tinyxmlparser.cpp \
tinyxml/tinyxmlerror.cpp \
$(NULL)
OBJECTS = $(patsubst %.asm, %.o, $(patsubst %.cpp, %.o, $(patsubst %.c, %.o, $(SOURCES))))
# targets
all:$(NAME)
$(NAME): $(OBJECTS) Makefile
$(LD) $(LDFLAGS) $(LIBPATH) -o $@ $(OBJECTS) $(LIBS)
kos32-objcopy $@ -O binary
%.o : %.c Makefile
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o $@ $<
%.o : %.cpp Makefile
$(CPP) $(CFLAGS) $(DEFINES) $(INCLUDES) -o $@ $<
%.o : %.asm Makefile
$(FASM) $< $@
clean:
-rm -f *.o

View File

@ -0,0 +1,101 @@
#include "tinyxml/tinyxml.h"
#include "collection.h"
const char *key_collection = "collection";
const char *key_package = "package";
const char *key_name = "name";
const char *key_version = "version";
const char *key_description = "description";
const char *key_title = "title";
const char *key_release = "release";
const char *key_file = "file";
int package_id;
void parse_group(pkg_group_t* gr, TiXmlElement *xmlgroup)
{
TiXmlElement *xmlpkg;
TiXmlElement *xmle;
xmlpkg = xmlgroup->FirstChildElement(key_package);
while (xmlpkg)
{
package_t *pkg;
pkg = (package_t*)malloc(sizeof(package_t));
pkg->id = package_id++;
pkg->name = strdup(xmlpkg->Attribute(key_name));
pkg->version = strdup(xmlpkg->Attribute(key_version));
xmle = xmlpkg->FirstChildElement(key_description);
pkg->description = strdup(xmle->Attribute(key_title));
xmle = xmlpkg->FirstChildElement(key_release);
pkg->filename = strdup(xmle->Attribute(key_file));
list_add_tail(&pkg->list, &gr->packages);
xmlpkg = xmlpkg->NextSiblingElement();
};
};
collection_t* load_collection_file(const char *name)
{
TiXmlDocument doc;
TiXmlElement *col;
collection_t *collection = NULL;
doc.LoadFile(name);
col = doc.FirstChildElement(key_collection);
if (col)
{
collection = (collection_t*)malloc(sizeof(collection_t));
INIT_LIST_HEAD(&collection->groups);
TiXmlElement* xmlgroup = col->FirstChildElement();
if (xmlgroup)
{
pkg_group_t *gr;
gr = (pkg_group_t*)malloc(sizeof(pkg_group_t));
INIT_LIST_HEAD(&gr->list);
INIT_LIST_HEAD(&gr->packages);
gr->name = strdup(xmlgroup->Value());
list_add_tail(&gr->list, &collection->groups);
parse_group(gr, xmlgroup);
};
};
return collection;
}
collection_t* load_collection_buffer(const char *buffer)
{
TiXmlDocument doc;
TiXmlElement *col;
collection_t *collection = NULL;
doc.Parse(buffer);
col = doc.FirstChildElement(key_collection);
if (col)
{
collection = (collection_t*)malloc(sizeof(collection_t));
INIT_LIST_HEAD(&collection->groups);
TiXmlElement* xmlgroup = col->FirstChildElement();
if (xmlgroup)
{
pkg_group_t *gr;
gr = (pkg_group_t*)malloc(sizeof(pkg_group_t));
INIT_LIST_HEAD(&gr->list);
INIT_LIST_HEAD(&gr->packages);
gr->name = strdup(xmlgroup->Value());
list_add_tail(&gr->list, &collection->groups);
parse_group(gr, xmlgroup);
};
};
return collection;
}

View File

@ -0,0 +1,39 @@
#ifndef __COLLECTION_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "list.h"
typedef struct
{
list_t groups;
char *issue;
}collection_t;
typedef struct
{
list_t list;
list_t packages;
char *name;
}pkg_group_t;
typedef struct package
{
list_t list;
int id;
char *name;
char *version;
char *filename;
char *description;
}package_t;
collection_t* load_collection_file(const char *name);
collection_t* load_collection_buffer(const char *buffer);
#ifdef __cplusplus
}
#endif
#endif /* __COLLECTION_H__ */

236
contrib/other/kpm/http.asm Normal file
View File

@ -0,0 +1,236 @@
include 'proc32.inc'
format MS COFF
public _http_init
public _http_get@16
public _http_receive@4
public _http_free@4
section '.text' align 16
;void* __fastcall getprocaddr(export, name)
align 4
getprocaddress:
push esi
push edi
xor eax, eax
test ecx, ecx ; If hlib = 0 then goto .end
jz .end
.next:
cmp [ecx], dword 0 ; If end of export table then goto .end
jz .end
xor eax, eax
mov esi, [ecx]
mov edi, edx ; name
.next_:
lodsb
scasb
jne .fail
or al, al
jnz .next_
jmp .ok
.fail:
add ecx, 8
jmp .next
.ok:
mov eax, [ecx + 4] ; return address
.end:
pop edi
pop esi
ret
;void fastcall dll_link(export, import)
align 4
dll_link:
push esi
push ecx
mov esi, edx
test esi, esi
jz .done
.next:
mov edx, [esi]
test edx, edx
jz .done
mov ecx, [esp]
call getprocaddress
test eax, eax
jz .done
mov [esi], eax
add esi, 4
jmp .next
.done:
pop ecx
pop esi
ret
align 4
dll_load:
push ebp
push esi
push edi
mov ebp, [esp+16]
.next_lib:
mov edx, [ebp]
test edx, edx
jz .exit
mov esi, [ebp+4]
mov edi, s_libdir.fname
@@:
lodsb
stosb
test al, al
jnz @b
mov eax, 68
mov ebx, 19
mov ecx, s_libdir
int 0x40
test eax, eax
jz .fail
mov ecx, eax
call dll_link
mov eax, [ecx]
cmp dword[eax], 'lib_'
jnz @f
mov esi, [ecx+4]
pushad
mov eax, mem.Alloc
mov ebx, mem.Free
mov ecx, mem.ReAlloc
mov edx, dll_load
call esi
popad
@@:
add ebp, 8
jmp .next_lib
.exit:
pop edi
pop esi
pop ebp
xor eax, eax
ret 4
.fail:
pop edi
pop esi
pop ebx
inc eax
ret 4
align 4
_http_init:
push @IMPORT
call dll_load
ret
align 4
_http_get@16:
jmp [HTTP_get]
align 4
_http_receive@4:
jmp [HTTP_receive]
align 4
_http_free@4:
jmp [HTTP_free]
proc mem.Alloc, size
push ebx ecx
mov ecx, [size]
mov eax, 68
mov ebx, 12
int 0x40
pop ecx ebx
ret
endp
;-----------------------------------------------------------------------------
proc mem.ReAlloc, mptr, size
push ebx ecx edx
mov ecx, [size]
test ecx, ecx
jz @f
@@:
mov edx, [mptr]
test edx, edx
jz @f
@@:
mov eax, 68
mov ebx, 20
int 0x40
test eax, eax
jz @f
@@:
pop edx ecx ebx
ret
endp
;-----------------------------------------------------------------------------
proc mem.Free, mptr
push ebx ecx
mov ecx,[mptr]
test ecx,ecx
jz @f
@@:
mov eax, 68
mov ebx, 13
int 0x40
pop ecx ebx
ret
endp
section '.data' align 16
; -------------------------
macro library [lname,fname]
{
forward
dd __#lname#_library_table__,__#lname#_library_name__
common
dd 0
forward
align 4
__#lname#_library_name__ db fname,0
}
macro import lname,[name,sname]
{
common
align 4
__#lname#_library_table__:
forward
if used name
name dd __#name#_import_name__
end if
common
dd 0
forward
if used name
align 4
__#name#_import_name__ db sname,0
end if
}
align 4
@IMPORT:
library lib_http, 'http.obj'
import lib_http, \
HTTP_get, 'get', \
HTTP_receive, 'receive', \
HTTP_free, 'free'
s_libdir:
db '/sys/lib/'
.fname rb 32

47
contrib/other/kpm/http.h Normal file
View File

@ -0,0 +1,47 @@
#ifndef __HTTP_H__
#define __HTTP_H__
#define FLAG_GOT_ALL_DATA (1 << 2)
#define FLAG_STREAM (1 << 9)
#define FLAG_REUSE_BUFFER (1 << 10)
typedef struct
{
int socket; // socket on which the actual transfer happens
int flags; // flags, reflects status of the transfer using bitflags
int write_ptr; // internal use only (where to write new data in buffer)
int buffer_length; // internal use only (number of available bytes in buffer)
int chunk_ptr; // internal use only (where the next chunk begins)
int timestamp; // internal use only (when last data was received)
int status; // HTTP status
int header_length; // length of HTTP header
void *content_ptr; // ptr to content
int content_length; // total length of HTTP content
int content_received; // number of currently received content bytes
}http_t;
int http_init();
int http_load(char *buf, const char *path);
http_t* __attribute__ ((stdcall)) http_get(const char *url, http_t *conn, int flags, const char *header);
int __attribute__ ((stdcall)) http_receive(http_t *conn);
void __attribute__ ((stdcall)) http_free(http_t *conn);
static inline int http_receive_with_retry(http_t *http, int retry_count)
{
int err;
do
{
if(err = http_receive(http))
delay(1);
}while(err && --retry_count);
return err;
}
#endif /* __HTTP_H__ */

179
contrib/other/kpm/kpm.c Normal file
View File

@ -0,0 +1,179 @@
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/unistd.h>
#include <fcntl.h>
#include <kos32sys.h>
#include "collection.h"
#include "http.h"
#define BUFFSIZE (64*1024)
int http_load_mem(char *buf, const char *url)
{
http_t *http;
int offset = 0;
int count;
// asm volatile("int3");
http = http_get(url, NULL,FLAG_STREAM|FLAG_REUSE_BUFFER, NULL);
if(http == NULL)
goto err_get;
do
{
// delay(100);
if(http_receive_with_retry(http, 500)==0)
{
if(http->flags & 0xffff0000)
goto err_http;
count = http->content_received - offset;
if(count == 0)
continue;
memcpy(buf+offset, http->content_ptr, count);
offset = http->content_received;
}
else goto err_http;
}while( (http->flags & FLAG_GOT_ALL_DATA) == 0);
if(http->content_ptr)
user_free(http->content_ptr);
http_free(http);
return offset;
err_http:
if(http->content_ptr)
user_free(http->content_ptr);
http_free(http);
printf("HTTP receive failed\n");
return offset;
err_get:
printf("HTTP GET failed\n");
return offset;
}
int http_load_file(const char *path, const char *url)
{
http_t *http;
int received = 0;
int offset = 0;
int tail;
char *buf;
int fd;
int i;
buf = user_alloc(BUFFSIZE);
for(i = 0; i < 16; i++)
buf[i*4096] = 0;
fd = open(path, O_CREAT|O_WRONLY);
if(fd == -1)
{
user_free(buf);
return 0;
};
http = http_get(url, NULL,FLAG_STREAM|FLAG_REUSE_BUFFER, NULL);
if(http == NULL)
goto err_get;
do
{
if(http_receive_with_retry(http, 500) == 0)
{
int count;
if(http->flags & 0xffff0000)
break;
count = http->content_received - received;
if(count+offset <= BUFFSIZE)
{
memcpy(buf+offset, http->content_ptr, count);
offset+= count;
}
else
{
tail = count+offset-BUFFSIZE;
count = BUFFSIZE - offset;
if(count)
{
memcpy(buf+offset, http->content_ptr, count);
offset = 0;
};
write(fd, buf, BUFFSIZE);
if(tail)
{
memcpy(buf, http->content_ptr+count, tail);
offset = tail;
}
}
received = http->content_received;
}
else break;
}while( (http->flags & FLAG_GOT_ALL_DATA) == 0);
if(offset)
{
write(fd, buf, offset);
}
// ftruncate(fd, received);
close(fd);
if(http->content_ptr)
user_free(http->content_ptr);
http_free(http);
user_free(buf);
return received;
err_get:
printf("HTTP GET failed\n");
return received;
}
int main(int argc, char *argv[])
{
int count;
if(http_init())
goto err_init;
count = http_load_file("/tmp0/1/packages.xml", "http://ftp.kolibrios.org/users/Serge/new/OS/packages.xml");
if(count)
{
collection_t *collection;
pkg_group_t *gr;
collection = load_collection_file("/tmp0/1/packages.xml");
list_for_each_entry(gr, &collection->groups, list)
{
package_t *pkg;
list_for_each_entry(pkg, &gr->packages, list)
{
printf("package %s-%s\n", pkg->name, pkg->version);
}
};
}
return 0;
err_init:
printf("HTTP library initialization failed\n");
return -1;
}

253
contrib/other/kpm/list.h Normal file
View File

@ -0,0 +1,253 @@
#ifndef __LIST_H__
#define __LIST_H__
typedef struct _list list_t;
struct _list
{
list_t *next, *prev;
};
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
list_t name = LIST_HEAD_INIT(name)
static inline void INIT_LIST_HEAD(list_t *list)
{
list->next = list;
list->prev = list;
}
/*
* Insert a new entry between two known consecutive entries.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_add(list_t *lnew, list_t *prev, list_t *next)
{
next->prev = lnew;
lnew->next = next;
lnew->prev = prev;
prev->next = lnew;
}
/**
* list_add - add a new entry
* @new: new entry to be added
* @head: list head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
static inline void list_add(list_t *lnew, list_t *head)
{
__list_add(lnew, head, head->next);
}
/**
* list_add_tail - add a new entry
* @new: new entry to be added
* @head: list head to add it before
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
static inline void list_add_tail(list_t *lnew, list_t *head)
{
__list_add(lnew, head->prev, head);
}
/*
* Delete a list entry by making the prev/next entries
* point to each other.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_del(list_t * prev, list_t * next)
{
next->prev = prev;
prev->next = next;
}
/**
* list_del - deletes entry from list.
* @entry: the element to delete from the list.
* Note: list_empty() on entry does not return true after this, the entry is
* in an undefined state.
*/
static inline void __list_del_entry(list_t *entry)
{
__list_del(entry->prev, entry->next);
}
static inline void list_del(list_t *entry)
{
__list_del(entry->prev, entry->next);
entry->next = NULL;
entry->prev = NULL;
}
/**
* list_replace - replace old entry by new one
* @old : the element to be replaced
* @new : the new element to insert
*
* If @old was empty, it will be overwritten.
*/
static inline void list_replace(list_t *old, list_t *lnew)
{
lnew->next = old->next;
lnew->next->prev = lnew;
lnew->prev = old->prev;
lnew->prev->next = lnew;
}
static inline void list_replace_init(list_t *old, list_t *lnew)
{
list_replace(old, lnew);
INIT_LIST_HEAD(old);
}
/**
* list_del_init - deletes entry from list and reinitialize it.
* @entry: the element to delete from the list.
*/
static inline void list_del_init(list_t *entry)
{
__list_del_entry(entry);
INIT_LIST_HEAD(entry);
}
/**
* list_move - delete from one list and add as another's head
* @list: the entry to move
* @head: the head that will precede our entry
*/
static inline void list_move(list_t *list, list_t *head)
{
__list_del_entry(list);
list_add(list, head);
}
/**
* list_move_tail - delete from one list and add as another's tail
* @list: the entry to move
* @head: the head that will follow our entry
*/
static inline void list_move_tail(list_t *list, list_t *head)
{
__list_del_entry(list);
list_add_tail(list, head);
}
/**
* list_is_last - tests whether @list is the last entry in list @head
* @list: the entry to test
* @head: the head of the list
*/
static inline int list_is_last(const list_t *list, const list_t *head)
{
return list->next == head;
}
/**
* list_empty - tests whether a list is empty
* @head: the list to test.
*/
static inline int list_empty(const list_t *head)
{
return head->next == head;
}
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - __builtin_offsetof(type,member) );})
/**
* list_entry - get the struct for this entry
* @ptr: the &struct list_head pointer.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*/
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
/**
* list_first_entry - get the first element from a list
* @ptr: the list head to take the element from.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*
* Note, that list is expected to be not empty.
*/
#define list_first_entry(ptr, type, member) \
list_entry((ptr)->next, type, member)
/**
* list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop cursor.
* @head: the head for your list.
*/
#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
/**
* list_for_each_prev - iterate over a list backwards
* @pos: the &struct list_head to use as a loop cursor.
* @head: the head for your list.
*/
#define list_for_each_prev(pos, head) \
for (pos = (head)->prev; pos != (head); pos = pos->prev)
/**
* list_for_each_safe - iterate over a list safe against removal of list entry
* @pos: the &struct list_head to use as a loop cursor.
* @n: another &struct list_head to use as temporary storage
* @head: the head for your list.
*/
#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
/**
* list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
* @pos: the &struct list_head to use as a loop cursor.
* @n: another &struct list_head to use as temporary storage
* @head: the head for your list.
*/
#define list_for_each_prev_safe(pos, n, head) \
for (pos = (head)->prev, n = pos->prev; \
pos != (head); \
pos = n, n = pos->prev)
/**
* list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); \
&pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
/**
* list_for_each_entry_reverse - iterate backwards over list of given type.
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_reverse(pos, head, member) \
for (pos = list_entry((head)->prev, typeof(*pos), member); \
&pos->member != (head); \
pos = list_entry(pos->member.prev, typeof(*pos), member))
#endif

View File

@ -0,0 +1,301 @@
; Macroinstructions for defining and calling procedures
macro stdcall proc,[arg] ; directly call STDCALL procedure
{ common
if ~ arg eq
reverse
pushd arg
common
end if
call proc }
macro invoke proc,[arg] ; indirectly call STDCALL procedure
{ common
if ~ arg eq
reverse
pushd arg
common
end if
call [proc] }
macro ccall proc,[arg] ; directly call CDECL procedure
{ common
size@ccall = 0
if ~ arg eq
reverse
pushd arg
size@ccall = size@ccall+4
common
end if
call proc
if size@ccall
add esp,size@ccall
end if }
macro cinvoke proc,[arg] ; indirectly call CDECL procedure
{ common
size@ccall = 0
if ~ arg eq
reverse
pushd arg
size@ccall = size@ccall+4
common
end if
call [proc]
if size@ccall
add esp,size@ccall
end if }
macro proc [args] ; define procedure
{ common
match name params, args>
\{ define@proc name,<params \} }
prologue@proc equ prologuedef
macro prologuedef procname,flag,parmbytes,localbytes,reglist
{ local loc
loc = (localbytes+3) and (not 3)
parmbase@proc equ ebp+8
localbase@proc equ ebp-loc
if parmbytes | localbytes
push ebp
mov ebp,esp
if localbytes
sub esp,loc
end if
end if
irps reg, reglist \{ push reg \} }
epilogue@proc equ epiloguedef
macro epiloguedef procname,flag,parmbytes,localbytes,reglist
{ irps reg, reglist \{ reverse pop reg \}
if parmbytes | localbytes
leave
end if
if flag and 10000b
retn
else
retn parmbytes
end if }
close@proc equ
macro define@proc name,statement
{ local params,flag,regs,parmbytes,localbytes,current
if used name
name:
match =stdcall args, statement \{ params equ args
flag = 11b \}
match =stdcall, statement \{ params equ
flag = 11b \}
match =c args, statement \{ params equ args
flag = 10001b \}
match =c, statement \{ params equ
flag = 10001b \}
match =params, params \{ params equ statement
flag = 0 \}
match =uses reglist=,args, params \{ regs equ reglist
params equ args \}
match =regs =uses reglist, regs params \{ regs equ reglist
params equ \}
match =regs, regs \{ regs equ \}
match prologue:reglist, prologue@proc:<regs> \{ prologue name,flag,parmbytes,localbytes,reglist \}
virtual at parmbase@proc
match =,args, params \{ defargs@proc args \}
match =args@proc args, args@proc params \{ defargs@proc args \}
parmbytes = $-(parmbase@proc)
end virtual
name # % = parmbytes/4
all@vars equ
current = 0
macro locals
\{ virtual at localbase@proc+current
macro label def \\{ match . type,def> \\\{ deflocal@proc .,label,<type \\\} \\}
struc db [val] \\{ \common deflocal@proc .,db,val \\}
struc du [val] \\{ \common deflocal@proc .,du,val \\}
struc dw [val] \\{ \common deflocal@proc .,dw,val \\}
struc dp [val] \\{ \common deflocal@proc .,dp,val \\}
struc dd [val] \\{ \common deflocal@proc .,dd,val \\}
struc dt [val] \\{ \common deflocal@proc .,dt,val \\}
struc dq [val] \\{ \common deflocal@proc .,dq,val \\}
struc rb cnt \\{ deflocal@proc .,rb cnt, \\}
struc rw cnt \\{ deflocal@proc .,rw cnt, \\}
struc rp cnt \\{ deflocal@proc .,rp cnt, \\}
struc rd cnt \\{ deflocal@proc .,rd cnt, \\}
struc rt cnt \\{ deflocal@proc .,rt cnt, \\}
struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \}
macro endl
\{ purge label
restruc db,du,dw,dp,dd,dt,dq
restruc rb,rw,rp,rd,rt,rq
current = $-(localbase@proc)
end virtual \}
macro ret operand
\{ match any, operand \\{ retn operand \\}
match , operand \\{ match epilogue:reglist, epilogue@proc:<regs> \\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \}
macro finish@proc
\{ localbytes = current
match close:reglist, close@proc:<regs> \\{ close name,flag,parmbytes,localbytes,reglist \\}
end if \} }
macro defargs@proc [arg]
{ common
if ~ arg eq
forward
local ..arg,current@arg
match argname:type, arg
\{ current@arg equ argname
label ..arg type
argname equ ..arg
if qqword eq type
dd ?,?,?,?,?,?,?,?
else if dqword eq type
dd ?,?,?,?
else if tbyte eq type
dd ?,?,?
else if qword eq type | pword eq type
dd ?,?
else
dd ?
end if \}
match =current@arg,current@arg
\{ current@arg equ arg
arg equ ..arg
..arg dd ? \}
common
args@proc equ current@arg
forward
restore current@arg
common
end if }
macro deflocal@proc name,def,[val] { name def val }
macro deflocal@proc name,def,[val]
{ common
match vars, all@vars \{ all@vars equ all@vars, \}
all@vars equ all@vars name
forward
local ..var,..tmp
..var def val
match =?, val \{ ..tmp equ \}
match any =?, val \{ ..tmp equ \}
match any (=?), val \{ ..tmp equ \}
match =label, def \{ ..tmp equ \}
match tmp : value, ..tmp : val
\{ tmp: end virtual
initlocal@proc ..var,def value
virtual at tmp\}
common
match first rest, ..var, \{ name equ first \} }
struc label type { label . type }
macro initlocal@proc name,def
{ virtual at name
def
size@initlocal = $ - name
end virtual
position@initlocal = 0
while size@initlocal > position@initlocal
virtual at name
def
if size@initlocal - position@initlocal < 2
current@initlocal = 1
load byte@initlocal byte from name+position@initlocal
else if size@initlocal - position@initlocal < 4
current@initlocal = 2
load word@initlocal word from name+position@initlocal
else
current@initlocal = 4
load dword@initlocal dword from name+position@initlocal
end if
end virtual
if current@initlocal = 1
mov byte [name+position@initlocal],byte@initlocal
else if current@initlocal = 2
mov word [name+position@initlocal],word@initlocal
else
mov dword [name+position@initlocal],dword@initlocal
end if
position@initlocal = position@initlocal + current@initlocal
end while }
macro endp
{ purge ret,locals,endl
finish@proc
purge finish@proc
restore regs@proc
match all,args@proc \{ restore all \}
restore args@proc
match all,all@vars \{ restore all \} }
macro local [var]
{ common
locals
forward done@local equ
match varname[count]:vartype, var
\{ match =BYTE, vartype \\{ varname rb count
restore done@local \\}
match =WORD, vartype \\{ varname rw count
restore done@local \\}
match =DWORD, vartype \\{ varname rd count
restore done@local \\}
match =PWORD, vartype \\{ varname rp count
restore done@local \\}
match =QWORD, vartype \\{ varname rq count
restore done@local \\}
match =TBYTE, vartype \\{ varname rt count
restore done@local \\}
match =DQWORD, vartype \\{ label varname dqword
rq count*2
restore done@local \\}
match =QQWORD, vartype \\{ label varname qqword
rq count*4
restore done@local \\}
match =XWORD, vartype \\{ label varname xword
rq count*2
restore done@local \\}
match =YWORD, vartype \\{ label varname yword
rq count*4
restore done@local \\}
match , done@local \\{ virtual
varname vartype
end virtual
rb count*sizeof.\#vartype
restore done@local \\} \}
match :varname:vartype, done@local:var
\{ match =BYTE, vartype \\{ varname db ?
restore done@local \\}
match =WORD, vartype \\{ varname dw ?
restore done@local \\}
match =DWORD, vartype \\{ varname dd ?
restore done@local \\}
match =PWORD, vartype \\{ varname dp ?
restore done@local \\}
match =QWORD, vartype \\{ varname dq ?
restore done@local \\}
match =TBYTE, vartype \\{ varname dt ?
restore done@local \\}
match =DQWORD, vartype \\{ label varname dqword
dq ?,?
restore done@local \\}
match =QQWORD, vartype \\{ label varname qqword
dq ?,?,?,?
restore done@local \\}
match =XWORD, vartype \\{ label varname xword
dq ?,?
restore done@local \\}
match =YWORD, vartype \\{ label varname yword
dq ?,?,?,?
restore done@local \\}
match , done@local \\{ varname vartype
restore done@local \\} \}
match ,done@local
\{ var
restore done@local \}
common
endl }

View File

@ -0,0 +1,115 @@
/*
www.sourceforge.net/projects/tinyxml
Original file by Yves Berquin.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
/*
* THIS FILE WAS ALTERED BY Tyge Løvset, 7. April 2005.
*/
#ifndef TIXML_USE_STL
#include "tinystr.h"
// Error value for find primitive
const TiXmlString::size_type TiXmlString::npos = static_cast< TiXmlString::size_type >(-1);
// Null rep.
TiXmlString::Rep TiXmlString::nullrep_ = { 0, 0, { '\0' } };
void TiXmlString::reserve (size_type cap)
{
if (cap > capacity())
{
TiXmlString tmp;
tmp.init(length(), cap);
memcpy(tmp.start(), data(), length());
swap(tmp);
}
}
TiXmlString& TiXmlString::assign(const char* str, size_type len)
{
size_type cap = capacity();
if (len > cap || cap > 3*(len + 8))
{
TiXmlString tmp;
tmp.init(len);
memcpy(tmp.start(), str, len);
swap(tmp);
}
else
{
memmove(start(), str, len);
set_size(len);
}
return *this;
}
TiXmlString& TiXmlString::append(const char* str, size_type len)
{
size_type newsize = length() + len;
if (newsize > capacity())
{
reserve (newsize + capacity());
}
memmove(finish(), str, len);
set_size(newsize);
return *this;
}
TiXmlString operator + (const TiXmlString & a, const TiXmlString & b)
{
TiXmlString tmp;
tmp.reserve(a.length() + b.length());
tmp += a;
tmp += b;
return tmp;
}
TiXmlString operator + (const TiXmlString & a, const char* b)
{
TiXmlString tmp;
TiXmlString::size_type b_len = static_cast<TiXmlString::size_type>( strlen(b) );
tmp.reserve(a.length() + b_len);
tmp += a;
tmp.append(b, b_len);
return tmp;
}
TiXmlString operator + (const char* a, const TiXmlString & b)
{
TiXmlString tmp;
TiXmlString::size_type a_len = static_cast<TiXmlString::size_type>( strlen(a) );
tmp.reserve(a_len + b.length());
tmp.append(a, a_len);
tmp += b;
return tmp;
}
#endif // TIXML_USE_STL

View File

@ -0,0 +1,319 @@
/*
www.sourceforge.net/projects/tinyxml
Original file by Yves Berquin.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
/*
* THIS FILE WAS ALTERED BY Tyge Lovset, 7. April 2005.
*
* - completely rewritten. compact, clean, and fast implementation.
* - sizeof(TiXmlString) = pointer size (4 bytes on 32-bit systems)
* - fixed reserve() to work as per specification.
* - fixed buggy compares operator==(), operator<(), and operator>()
* - fixed operator+=() to take a const ref argument, following spec.
* - added "copy" constructor with length, and most compare operators.
* - added swap(), clear(), size(), capacity(), operator+().
*/
#ifndef TIXML_USE_STL
#ifndef TIXML_STRING_INCLUDED
#define TIXML_STRING_INCLUDED
#include <assert.h>
#include <string.h>
/* The support for explicit isn't that universal, and it isn't really
required - it is used to check that the TiXmlString class isn't incorrectly
used. Be nice to old compilers and macro it here:
*/
#if defined(_MSC_VER) && (_MSC_VER >= 1200 )
// Microsoft visual studio, version 6 and higher.
#define TIXML_EXPLICIT explicit
#elif defined(__GNUC__) && (__GNUC__ >= 3 )
// GCC version 3 and higher.s
#define TIXML_EXPLICIT explicit
#else
#define TIXML_EXPLICIT
#endif
/*
TiXmlString is an emulation of a subset of the std::string template.
Its purpose is to allow compiling TinyXML on compilers with no or poor STL support.
Only the member functions relevant to the TinyXML project have been implemented.
The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase
a string and there's no more room, we allocate a buffer twice as big as we need.
*/
class TiXmlString
{
public :
// The size type used
typedef size_t size_type;
// Error value for find primitive
static const size_type npos; // = -1;
// TiXmlString empty constructor
TiXmlString () : rep_(&nullrep_)
{
}
// TiXmlString copy constructor
TiXmlString ( const TiXmlString & copy) : rep_(0)
{
init(copy.length());
memcpy(start(), copy.data(), length());
}
// TiXmlString constructor, based on a string
TIXML_EXPLICIT TiXmlString ( const char * copy) : rep_(0)
{
init( static_cast<size_type>( strlen(copy) ));
memcpy(start(), copy, length());
}
// TiXmlString constructor, based on a string
TIXML_EXPLICIT TiXmlString ( const char * str, size_type len) : rep_(0)
{
init(len);
memcpy(start(), str, len);
}
// TiXmlString destructor
~TiXmlString ()
{
quit();
}
// = operator
TiXmlString& operator = (const char * copy)
{
return assign( copy, (size_type)strlen(copy));
}
// = operator
TiXmlString& operator = (const TiXmlString & copy)
{
return assign(copy.start(), copy.length());
}
// += operator. Maps to append
TiXmlString& operator += (const char * suffix)
{
return append(suffix, static_cast<size_type>( strlen(suffix) ));
}
// += operator. Maps to append
TiXmlString& operator += (char single)
{
return append(&single, 1);
}
// += operator. Maps to append
TiXmlString& operator += (const TiXmlString & suffix)
{
return append(suffix.data(), suffix.length());
}
// Convert a TiXmlString into a null-terminated char *
const char * c_str () const { return rep_->str; }
// Convert a TiXmlString into a char * (need not be null terminated).
const char * data () const { return rep_->str; }
// Return the length of a TiXmlString
size_type length () const { return rep_->size; }
// Alias for length()
size_type size () const { return rep_->size; }
// Checks if a TiXmlString is empty
bool empty () const { return rep_->size == 0; }
// Return capacity of string
size_type capacity () const { return rep_->capacity; }
// single char extraction
const char& at (size_type index) const
{
assert( index < length() );
return rep_->str[ index ];
}
// [] operator
char& operator [] (size_type index) const
{
assert( index < length() );
return rep_->str[ index ];
}
// find a char in a string. Return TiXmlString::npos if not found
size_type find (char lookup) const
{
return find(lookup, 0);
}
// find a char in a string from an offset. Return TiXmlString::npos if not found
size_type find (char tofind, size_type offset) const
{
if (offset >= length()) return npos;
for (const char* p = c_str() + offset; *p != '\0'; ++p)
{
if (*p == tofind) return static_cast< size_type >( p - c_str() );
}
return npos;
}
void clear ()
{
//Lee:
//The original was just too strange, though correct:
// TiXmlString().swap(*this);
//Instead use the quit & re-init:
quit();
init(0,0);
}
/* Function to reserve a big amount of data when we know we'll need it. Be aware that this
function DOES NOT clear the content of the TiXmlString if any exists.
*/
void reserve (size_type cap);
TiXmlString& assign (const char* str, size_type len);
TiXmlString& append (const char* str, size_type len);
void swap (TiXmlString& other)
{
Rep* r = rep_;
rep_ = other.rep_;
other.rep_ = r;
}
private:
void init(size_type sz) { init(sz, sz); }
void set_size(size_type sz) { rep_->str[ rep_->size = sz ] = '\0'; }
char* start() const { return rep_->str; }
char* finish() const { return rep_->str + rep_->size; }
struct Rep
{
size_type size, capacity;
char str[1];
};
void init(size_type sz, size_type cap)
{
if (cap)
{
// Lee: the original form:
// rep_ = static_cast<Rep*>(operator new(sizeof(Rep) + cap));
// doesn't work in some cases of new being overloaded. Switching
// to the normal allocation, although use an 'int' for systems
// that are overly picky about structure alignment.
const size_type bytesNeeded = sizeof(Rep) + cap;
const size_type intsNeeded = ( bytesNeeded + sizeof(int) - 1 ) / sizeof( int );
rep_ = reinterpret_cast<Rep*>( new int[ intsNeeded ] );
rep_->str[ rep_->size = sz ] = '\0';
rep_->capacity = cap;
}
else
{
rep_ = &nullrep_;
}
}
void quit()
{
if (rep_ != &nullrep_)
{
// The rep_ is really an array of ints. (see the allocator, above).
// Cast it back before delete, so the compiler won't incorrectly call destructors.
delete [] ( reinterpret_cast<int*>( rep_ ) );
}
}
Rep * rep_;
static Rep nullrep_;
} ;
inline bool operator == (const TiXmlString & a, const TiXmlString & b)
{
return ( a.length() == b.length() ) // optimization on some platforms
&& ( strcmp(a.c_str(), b.c_str()) == 0 ); // actual compare
}
inline bool operator < (const TiXmlString & a, const TiXmlString & b)
{
return strcmp(a.c_str(), b.c_str()) < 0;
}
inline bool operator != (const TiXmlString & a, const TiXmlString & b) { return !(a == b); }
inline bool operator > (const TiXmlString & a, const TiXmlString & b) { return b < a; }
inline bool operator <= (const TiXmlString & a, const TiXmlString & b) { return !(b < a); }
inline bool operator >= (const TiXmlString & a, const TiXmlString & b) { return !(a < b); }
inline bool operator == (const TiXmlString & a, const char* b) { return strcmp(a.c_str(), b) == 0; }
inline bool operator == (const char* a, const TiXmlString & b) { return b == a; }
inline bool operator != (const TiXmlString & a, const char* b) { return !(a == b); }
inline bool operator != (const char* a, const TiXmlString & b) { return !(b == a); }
TiXmlString operator + (const TiXmlString & a, const TiXmlString & b);
TiXmlString operator + (const TiXmlString & a, const char* b);
TiXmlString operator + (const char* a, const TiXmlString & b);
/*
TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString.
Only the operators that we need for TinyXML have been developped.
*/
class TiXmlOutStream : public TiXmlString
{
public :
// TiXmlOutStream << operator.
TiXmlOutStream & operator << (const TiXmlString & in)
{
*this += in;
return *this;
}
// TiXmlOutStream << operator.
TiXmlOutStream & operator << (const char * in)
{
*this += in;
return *this;
}
} ;
#endif // TIXML_STRING_INCLUDED
#endif // TIXML_USE_STL

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,53 @@
/*
www.sourceforge.net/projects/tinyxml
Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include "tinyxml.h"
// The goal of the seperate error file is to make the first
// step towards localization. tinyxml (currently) only supports
// english error messages, but the could now be translated.
//
// It also cleans up the code a bit.
//
const char* TiXmlBase::errorString[ TIXML_ERROR_STRING_COUNT ] =
{
"No error",
"Error",
"Failed to open file",
"Memory allocation failed.",
"Error parsing Element.",
"Failed to read Element name",
"Error reading Element value.",
"Error reading Attributes.",
"Error: empty tag.",
"Error reading end tag.",
"Error parsing Unknown.",
"Error parsing Comment.",
"Error parsing Declaration.",
"Error document empty.",
"Error null (0) or unexpected EOF found in input stream.",
"Error parsing CDATA.",
"Error when TiXmlDocument added to document, because TiXmlDocument can only be at the root.",
};

File diff suppressed because it is too large Load Diff