mirror of
https://github.com/KolibriOS/kolibrios.git
synced 2024-12-22 14:52:39 +03:00
Kolibri package manager
git-svn-id: svn://kolibrios.org@5725 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
69d74aa6a7
commit
11387d6d18
63
contrib/other/kpm/Makefile
Normal file
63
contrib/other/kpm/Makefile
Normal 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
|
||||
|
||||
|
||||
|
||||
|
101
contrib/other/kpm/collection.cpp
Normal file
101
contrib/other/kpm/collection.cpp
Normal 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;
|
||||
}
|
39
contrib/other/kpm/collection.h
Normal file
39
contrib/other/kpm/collection.h
Normal 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
236
contrib/other/kpm/http.asm
Normal 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
47
contrib/other/kpm/http.h
Normal 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
179
contrib/other/kpm/kpm.c
Normal 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
253
contrib/other/kpm/list.h
Normal 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
|
301
contrib/other/kpm/proc32.inc
Normal file
301
contrib/other/kpm/proc32.inc
Normal 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 }
|
115
contrib/other/kpm/tinyxml/tinystr.cpp
Normal file
115
contrib/other/kpm/tinyxml/tinystr.cpp
Normal 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
|
319
contrib/other/kpm/tinyxml/tinystr.h
Normal file
319
contrib/other/kpm/tinyxml/tinystr.h
Normal 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
|
1886
contrib/other/kpm/tinyxml/tinyxml.cpp
Normal file
1886
contrib/other/kpm/tinyxml/tinyxml.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1807
contrib/other/kpm/tinyxml/tinyxml.h
Normal file
1807
contrib/other/kpm/tinyxml/tinyxml.h
Normal file
File diff suppressed because it is too large
Load Diff
53
contrib/other/kpm/tinyxml/tinyxmlerror.cpp
Normal file
53
contrib/other/kpm/tinyxml/tinyxmlerror.cpp
Normal 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.",
|
||||
};
|
1635
contrib/other/kpm/tinyxml/tinyxmlparser.cpp
Normal file
1635
contrib/other/kpm/tinyxml/tinyxmlparser.cpp
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user