From: <bh...@us...> - 2009-02-08 16:12:36
|
Revision: 11121 http://swig.svn.sourceforge.net/swig/?rev=11121&view=rev Author: bhy Date: 2009-02-08 16:12:32 +0000 (Sun, 08 Feb 2009) Log Message: ----------- Initial commit of DOH2 Added Paths: ----------- branches/swig-2.0/Source/DOH2/ branches/swig-2.0/Source/DOH2/Makefile branches/swig-2.0/Source/DOH2/doh.cxx branches/swig-2.0/Source/DOH2/doh.h branches/swig-2.0/Source/DOH2/file.cxx branches/swig-2.0/Source/DOH2/fio.cxx branches/swig-2.0/Source/DOH2/hash.cxx branches/swig-2.0/Source/DOH2/list.cxx branches/swig-2.0/Source/DOH2/string.cxx branches/swig-2.0/Source/DOH2/test.cxx Added: branches/swig-2.0/Source/DOH2/Makefile =================================================================== --- branches/swig-2.0/Source/DOH2/Makefile (rev 0) +++ branches/swig-2.0/Source/DOH2/Makefile 2009-02-08 16:12:32 UTC (rev 11121) @@ -0,0 +1,12 @@ +SRCS=doh.cpp string.cpp list.cpp hash.cpp file.cpp fio.cpp test.cpp +OBJS=doh.o string.o list.o hash.o file.o fio.o test.o + +CXXFLAGS=-ggdb3 -O0 + +run_test: test + ./test + +test: $(OBJS) + $(CXX) -ggdb3 -O0 -o test $(OBJS) + + Added: branches/swig-2.0/Source/DOH2/doh.cxx =================================================================== --- branches/swig-2.0/Source/DOH2/doh.cxx (rev 0) +++ branches/swig-2.0/Source/DOH2/doh.cxx 2009-02-08 16:12:32 UTC (rev 11121) @@ -0,0 +1,380 @@ +#include <string> +#include <list> +#include <iostream> +#include <cassert> +#include <exception> +#include "doh.h" + +namespace doh { + + /* class DOH */ + DOH::DOH() + : _line(0), _file(0), meta(0) + {} + + DOH::DOH(const DOH &x) + : _line(x._line), _file(x._file), + meta(x.meta->clone()) + {} + + DOH::~DOH() { + if (meta) + delete meta; + } + + void DOH::clear() { + if (meta) + delete meta; + meta = 0; + _line = 0; + _file = 0; + return; + } + + void DOH::line(int l) { + _line = l; + } + + int DOH::line() { + return _line; + } + + void DOH::file(DOH *f) { + _file = f; + } + + DOH *DOH::file() { + return _file; + } + + void DOH::setmeta(DOH *name, DOH *value) { + String &namestr = ref_cast<String>(name); + if (0==meta) + meta = new Hash; + Hash &ho = *doh_cast<Hash*>(meta); + ho[namestr] = value; + } + + DOH *DOH::getmeta(DOH *name) { + String &namestr = ref_cast<String>(name); + if (0==meta) + return 0; + Hash &ho = ref_cast<Hash>(meta); + if (ho.count(namestr) > 0) + return ho[namestr]; + else + return 0; + } + + /* class Filelike */ + Filelike::Filelike() + {} + + Filelike::Filelike(const Filelike& f) + :DOH(f) + {} + + + /* class Container */ + Container::Container() + {} + Container::Container(const Container &x) + :DOH(x) + {} + + /* class _Iterator */ + _Iterator::~_Iterator() { + } + + /* struct Iterator */ + Iterator::~Iterator() { + } + + /* class DOHCaster */ + + DOHCaster::DOHCaster(DOH *obj) + :content(obj) + {} + + DOHCaster::operator DOH* () { + return to_ptr<DOH>(); + } + + DOHCaster::operator const char* () { + return to_ptr<String>()->c_str(); + } + + DOHCaster::operator String* () { + return to_ptr<String>(); + } + + DOHCaster::operator List* () { + return to_ptr<List>(); + } + + template<class T> + T* DOHCaster::to_ptr() const { + return dynamic_cast<T*>(content); + } + + + /* class String_or_char_ptr */ + + String_or_char_ptr::String_or_char_ptr(const String_or_char_ptr& str) + :content_str(str.content_str), + content_charptr(str.content_charptr), + need_free(0) /* TODO: may potential memory leak/corrupt here */ + {} + + String_or_char_ptr::~String_or_char_ptr() { + if (need_free) { + delete content_str; + } + } + + // Casters + // from const char* + String_or_char_ptr::String_or_char_ptr(const char *s) + :content_str(0), content_charptr(s), + need_free(false) + {} + // from DOH* + String_or_char_ptr::String_or_char_ptr(const DOH* str) + :content_str(dynamic_cast<const String*>(str)), + content_charptr(0), + need_free(false) + {} + // to const char* + String_or_char_ptr::operator const char* () const { + return content_charptr ? content_charptr : content_str->c_str(); + } + // to const String* + String_or_char_ptr::operator const String* () const { + if (!content_str) { + content_str = new String(content_charptr); + need_free = true; + } + return content_str; + } + + /* wrapper of dynamic_cast with error detection */ + template<class T> + T doh_cast(DOH *obj) { + // TODO: raise exception + T result = dynamic_cast<T>(obj); + assert(result); + return result; + } + + template<class T> + T doh_cast(const DOH *obj) { + T result = dynamic_cast<T>(obj); + assert(result); + return result; + } + + /* shortcut which cast DOH object pointer to reference */ + template<class T> + T& ref_cast(DOH *obj) { + return *doh_cast<T*>(obj); + } + + + /* Basic object methods */ + int DohCheck(const DOH *ptr) { + if (ptr) + return true; + else + return false; + } + + int Len(const DOH* obj) { + return obj->size(); + } + + DOHCaster Copy(const DOH* obj) { + return obj->clone(); + } + + void Clear(DOH *obj) { + obj->clear(); + } + + void Delete(DOH *obj) { + delete obj; + return; + } + + /* Positional */ + + int Getline(DOH *obj) { + return obj->line(); + } + void Setline(DOH *obj, int line) { + obj->line(line); + } + + DOH *Getfile(DOH *obj) { + return obj->file(); + } + + void Setfile(DOH *obj, DOH *file) { + return obj->file(file); + } + + + + /* Common methods for List and String */ + int Dump(const DOH *obj, DOH *out) { + // XXX only support string dump + const String *so = doh_cast<const String*>(obj); + Write(out, so->data(), so->size()); + } + + + int Insertitem(DOH *obj, int index, DOH *value) { + int len = obj->size(); + if (DOH_END == index) { + index = len; + } + if (index < 0) { + index = 0; + } + if (index > len) { + index = len; + } + + if (dynamic_cast<List*>(obj)) { + /* is List */ + List *lo = doh_cast<List*>(obj); + lo->insert(index, value); + } else { + /* is String */ + String *so = doh_cast<String*>(obj); + String &str = ref_cast<String>(value); + so->insert(index,str); + } + return 0; + } + + int Append(DOH *x, DOH *item) { + if (!item) + return -1; + if (dynamic_cast<List*>(x)) { + /* the object is a list */ + List *lo = doh_cast<List*>(x); + lo->push_back(item); + } else { + /* otherwise it is string */ + String *so = doh_cast<String*>(x); + String &str = ref_cast<String>(item); + so->append(str); + } + return 0; + } + + int Delslice(DOH *obj, int sindex, int eindex) { + int len = obj->size(); + if (eindex == DOH_END) + eindex = len; + if (sindex == DOH_BEGIN) + sindex = 0; + + if (dynamic_cast<List*>(obj)) { + /* is List */ + List *lo = doh_cast<List*>(obj); + lo->erase(sindex, eindex - sindex); + } else { + /* is String */ + String *so = doh_cast<String*>(obj); + so->erase(sindex, eindex - sindex); + } + return 0; + } + + int Delitem(DOH *obj, int index) { + int len = obj->size(); + if (index == DOH_END) + index = len-1; + if (index == DOH_BEGIN) + index = 0; + if (len == 0) + return 0; + return Delslice(obj, index, index+1); + } + + /* Common methods for String and File */ + int Write(DOH * obj, const char *buffer, int length) { + Filelike *fo = doh_cast<Filelike*>(obj); + return fo->write(buffer, length); + } + + int Read(DOH * obj, char *buffer, int length) { + Filelike *fo = doh_cast<Filelike*>(obj); + return fo->read(buffer, length); + } + + int Seek(DOH * obj, long offset, int whence) { + Filelike *fo = doh_cast<Filelike*>(obj); + return fo->seek(offset, whence); + } + + long Tell(DOH * obj) { + Filelike *fo = doh_cast<Filelike*>(obj); + return fo->tell(); + } + + int Getc(DOH * obj) { + Filelike *fo = doh_cast<Filelike*>(obj); + return fo->getc(); + } + + int Putc(int ch, DOH * obj) { + Filelike *fo = doh_cast<Filelike*>(obj); + return fo->putc(ch); + } + + int Ungetc(int ch, DOH * obj) { + Filelike *fo = doh_cast<Filelike*>(obj); + return fo->ungetc(ch); + } + + + /* Iterator */ + Iterator First(DOH *obj) { + Container *cont = dynamic_cast<Container*>(obj); + assert(cont); + return cont->first(); + } + + Iterator& Next(Iterator& x) { + Container *cont = dynamic_cast<Container*>(x.object); + assert(cont); + return cont->next(x); + } + + /* Miscellaneous */ + + int DohIsMapping(const DOH *obj) { + const Hash* o = dynamic_cast<const Hash*>(obj); + return o ? true : false; + } + + int DohIsSequence(const DOH *obj) { + const List* o = dynamic_cast<const List*>(obj); + return o ? true : false; + } + + int DohIsString(const DOH *obj) { + const String* o = dynamic_cast<const String*>(obj); + return o ? true : false; + } + + int DohIsFile(const DOH *obj) { + const Filelike* o = dynamic_cast<const Filelike*>(obj); + return o ? true : false; + } + +} + + Added: branches/swig-2.0/Source/DOH2/doh.h =================================================================== --- branches/swig-2.0/Source/DOH2/doh.h (rev 0) +++ branches/swig-2.0/Source/DOH2/doh.h 2009-02-08 16:12:32 UTC (rev 11121) @@ -0,0 +1,513 @@ +/* + * This file is part of SWIG. + * + * SWIG 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 3 of the License, or + * (at your option) any later version. + * + * SWIG 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 SWIG. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _DOH_H +#define _DOH_H + +#include <string> +#include <list> +#include <map> +#include <fstream> + +/* Problems need to be solved: + * + * 1. String_or_char *: find a replacement so foo(String_or_char * c) works. + * + * 2. List and Hash require the ability to contain any DOH objects + * (No longer require things like boost::any!) + * All DOH types inherit from DOH + * + * 3. Auto cast return value to String* or List* etc. (for Getattr()) + * Casters. + * All casters storage content as DOH* + * StringCaster : cast from const char*, std::string, String* + * to const char*, std::string&, String* + * DohCaster : StringCaster adds caster for List* and Hash* + * + * 4. Extra data attached to each object (file, line, meta) + * In DOH + * + * 5. Keep the DOH iterator interface + * + * 6. Co-operating with STL + * + * 7. DOH String is file-like + * + * 8. varargs + * + * + * Core types: + * String, List, Mapping, File, Iterator + */ + +namespace doh { + /* Base class for DOH types */ + class DOH { + public: + DOH(); + DOH(const DOH &x); + virtual ~DOH(); + + virtual DOH *clone() const = 0; + virtual void clear(); + virtual int size() const = 0; + + void line(int l); + int line(); + void file(DOH *f); + DOH *file(); + void setmeta(DOH *name, DOH *value); + DOH *getmeta(DOH *name); + + protected: + DOH *meta; + int _line; + DOH *_file; + }; + + /* Interface for file-like objects (String and File) */ + class Filelike : public DOH { + public: + Filelike(); + Filelike(const Filelike& f); + + virtual int write(const char *buffer, size_t length) = 0; + virtual int read(char *buffer, size_t length) = 0; + virtual int seek(off_t offset, int whence) = 0; + virtual off_t tell() = 0; + virtual char getc() = 0; + virtual char putc(char c) = 0; + virtual char ungetc(char ch) = 0; + }; + + class String : public Filelike, public std::string { + public: + /* Constructors */ + String(); + String(const String& str); + String(const std::string& str); + String(const char *s); + String(const char *s, size_t n); + + virtual DOH *clone() const; + virtual void clear(); + virtual int size() const; + + virtual int write(const char *buffer, size_t length); + virtual int read(char *buffer, size_t length); + virtual int seek(off_t offset, int whence); + virtual off_t tell(); + virtual char getc(); + virtual char putc(char c); + virtual char ungetc(char ch); + + int doh_replace(const char *token, const char *rep, int flags); + + /*TODO: override all modifiers of std::string + * to keep sp always at correct position + */ + String& insert(size_t pos, const std::string &str); + String& erase(size_t pos, size_t n); + + private: + off_t sp; + }; + + /* XXX Now we uses cstdio for file I/O, may switch to fstream */ + //class File : public Filelike, public std::fstream { + class File : public Filelike { + public: + /* Constructors */ + File(); + File(const File &f); + File(const char *filename, const char *mode); + + virtual DOH *clone() const; + virtual void clear(); + virtual int size() const; + + virtual int write(const char *buffer, size_t length); + virtual int read(char *buffer, size_t length); + virtual int seek(off_t offset, int whence); + virtual off_t tell(); + virtual char getc(); + virtual char putc(char c); + virtual char ungetc(char ch); + private: + FILE *fp; + }; + + /* Iterator */ + + /* class _Iterator, internal use for containers */ + class _Iterator { + public: + virtual ~_Iterator(); + }; + + /* Public iterator */ + struct Iterator { + /* XXX key should be DOH*, but have to be + * const char * to prevent memory leak */ + const char * key; + DOH* item; + DOH* object; + _Iterator *_iter; + ~Iterator(); + }; + + class Container : public DOH { + public: + Container(); + Container(const Container &x); + virtual Iterator first() = 0; + virtual Iterator& next(Iterator& i) = 0; + }; + + /* TODO containers must have own copy of contained objects */ + + typedef std::list<DOH*> list_doh; + class List : public Container, public list_doh { + public: + /* Constructors */ + List(); + List(const List &x); + + virtual DOH *clone() const; + virtual void clear(); + virtual int size() const; + + virtual Iterator first(); + virtual Iterator& next(Iterator& i); + + void insert(size_t pos, DOH *x); + void erase(size_t pos, size_t n); + private: + //Internal iterator for List + class _iterator; + //Check and set state of iterator + void check_iter(Iterator &i); + }; + + typedef std::map<std::string, DOH*> map_doh; + class Hash : public Container, public map_doh { + public: + /* Constructors */ + Hash(); + /* Copy constructor */ + Hash(const Hash &x); + virtual DOH *clone() const; + virtual void clear(); + virtual int size() const; + + virtual Iterator first(); + virtual Iterator& next(Iterator& i); + private: + //Internal iterator for Hash + class _iterator; + //Check and set state of iterator + void check_iter(Iterator &i); + }; + + + /* Caster */ + class DOHCaster { + public: + // from DOH* + DOHCaster(DOH *obj); + // to DOH* + operator DOH* (); + // to const char* + operator const char* (); + // to String* + operator String* (); + // to List* + operator List* (); + // to Hash* + operator Hash* (); + + private: + template<class T> + T* to_ptr() const; + + DOH * const content; + }; + + /* wrapper of dynamic_cast with error detection */ + template<class T> + T doh_cast(DOH *obj); + + template<class T> + const T constdoh_cast(const DOH *obj); + + /* shortcut which cast DOH object pointer to reference */ + template<class T> + T& ref_cast(DOH *obj); + + /* This class should only be used as + * function input argument type. + * It is the equivalence of + * const String_or_char * + */ + class String_or_char_ptr { + public: + // Copy constructor + String_or_char_ptr(const String_or_char_ptr& str); + // Destructor + ~String_or_char_ptr(); + + /* Casters */ + // from const char* + String_or_char_ptr(const char *s); + // from DOH* + String_or_char_ptr(const DOH* str); + // to const char* + operator const char* () const; + // to const String* + operator const String* () const; + + private: + mutable bool need_free; + mutable const String *content_str; + const char *content_charptr; + }; + + /* ----------------------------------------------------------------------------- + * Our own varargs mechanism, so Printf and Stringf works. + * This varargs implementation convert any DOH object to POD, + * and then store it in a union. + * -----------------------------------------------------------------------------*/ + union vararg_item { + int _int; + double _double; + const char *_str; + void *_pointer; + + inline vararg_item(doh::DOH *obj) + : _str(doh::doh_cast<String*>(obj)->c_str()) + {} + inline vararg_item(const char *c) + : _str(c) + {} + inline vararg_item(int i) + : _int(i) + {} + + inline vararg_item(double d) + : _double(d) + {} + + inline vararg_item(void *p) + : _pointer(p) + {} + }; + +#define VA_DECL vararg_item varg_0 = 0, \ + vararg_item varg_1 = 0, \ + vararg_item varg_2 = 0, \ + vararg_item varg_3 = 0, \ + vararg_item varg_4 = 0 + +#define VA_DEF vararg_item varg_0, \ + vararg_item varg_1, \ + vararg_item varg_2, \ + vararg_item varg_3, \ + vararg_item varg_4 +#define VA_CALL varg_0, varg_1, varg_2, varg_3, varg_4 +#define VA_INIT int _varg_index = 0; \ + vararg_item _varg_items[] = {VA_CALL}; +#define VA_GET (_varg_items[_varg_index++]) + + + + /* Basic object methods. Common to most objects */ + int DohCheck(const DOH *ptr); /* Check if a DOH object */ + void Delete(DOH *obj); + DOHCaster Copy(const DOH* obj); /* Shallow copy. Copy meta, file, line */ + void Clear(DOH *obj); + String *Str(const DOH *obj); // Rare + void *Data(const DOH *obj); // Rare: only swig/typesys.c:1867 + int Dump(const DOH *obj, DOH *out); + int Len(const DOH* obj); + /* Cmp removed to string method section */ + int Hashval(const DOH *obj); // Never + void DohIncref(DOH *obj); //Rare. Is it really useful? + + /* Mapping methods */ + //XXX Removed all the const qulifier of 'DOH *value' argument + DOHCaster Getattr(DOH *obj, const String_or_char_ptr name); + int Setattr(DOH *obj, const String_or_char_ptr name, const char *value); // Overloaded + int Setattr(DOH *obj, const String_or_char_ptr name, DOH *value); + int Checkattr(DOH *obj, const String_or_char_ptr name, const String_or_char_ptr value); + DOHCaster Keys(DOH *obj); + int GetInt(DOH *obj, const String_or_char_ptr name); + void SetInt(DOH *obj, const String_or_char_ptr name, int value); + #define DohSetInt SetInt + double GetDouble(DOH *obj, const String_or_char_ptr name); // Never + double SetDouble(DOH *obj, const String_or_char_ptr name, double); // Never + char *GetChar(DOH *obj, const String_or_char_ptr name); // These are redundant + void SetChar(DOH *obj, const DOH *name, char *value); + DOHCaster GetFlagAttr(DOH *obj, const String_or_char_ptr name); + int GetFlag(DOH *obj, const String_or_char_ptr name); + void SetFlagAttr(DOH *obj, const String_or_char_ptr name, DOH *attr); // Rare + void SetFlag(DOH *obj, const String_or_char_ptr name); + void GetVoid(DOH *obj, const String_or_char_ptr name); // Rare, unable to support. Modules/allegrocl.cxx + void *SetVoid(DOH *obj, const String_or_char_ptr name, void *value); + #define UnsetFlag(o,n) SetFlagAttr(o,n,NULL) + + /* Sequence methods */ + DOHCaster Getitem(DOH *obj, int index); + int Setitem(DOH *obj, int index, DOH *value); // overloaded + int Setitem(DOH *obj, int index, const char *value); + int Delitem(DOH *obj, int index); + int Insertitem(DOH *obj, int index, DOH *value); // overloaded + int Insertitem(DOH *obj, int index, const char *value); + int Delslice(DOH *obj, int sindex, int eindex); + int Append(DOH *x, DOH *item); // was a macro + #define Insert DohInsertitem +// #define Append(s,x) DohInsertitem(s,DOH_END,x) + #define Push(s,x) DohInsertitem(s,DOH_BEGIN,x) + + /* Sequence position flags */ + #define DOH_BEGIN -1 + #define DOH_END -2 + #define DOH_CUR -3 + #define DOH_CURRENT -3 + + /* File methods */ + + int Write(DOH * obj, const char *buffer, int length); + int Read(DOH * obj, char *buffer, int length); + int Seek(DOH * obj, long offset, int whence); + long Tell(DOH * obj); + int Getc(DOH * obj); + int Putc(int ch, DOH * obj); + int Ungetc(int ch, DOH * obj); + + /* Iterator */ + Iterator First(DOH *obj); + Iterator& Next(Iterator& x); + + /* Positional */ + + int Getline(DOH *obj); + void Setline(DOH *obj, int line); + DOH *Getfile(DOH *obj); + void Setfile(DOH *obj, DOH *file); + + /* String Methods */ + int Cmp(String_or_char_ptr obj1, String_or_char_ptr obj2); + int Equal(const String_or_char_ptr obj1, const String_or_char_ptr obj2); + int Replace(DOH * src, const String_or_char_ptr token, const String_or_char_ptr rep, int flags); + void Chop(DOH * src); + + /* Meta-variables */ + DOH *Getmeta(DOH *obj, const DOH *name); + int Setmeta(DOH *obj, const DOH *name, const DOH *value); + int Delmeta(DOH *obj, const DOH *name); + + /* Utility functions */ + + void DohEncoding(char *name, DOH *(*fn) (DOH *s)); + int Printf(DOH * obj, const char *format, VA_DECL); + int Printf(FILE *obj, const char *format, VA_DECL); + int vPrintf(DOH * obj, const char *format, VA_DECL); + int Printv(DOH * obj, VA_DECL); + int Printv(FILE * obj, VA_DECL); + DOH *Readline(DOH * in); // Never + + /* Miscellaneous */ + + int DohIsMapping(const DOH *obj); + int DohIsSequence(const DOH *obj); + int DohIsString(const DOH *obj); + int DohIsFile(const DOH *obj); + + void DohSetmark(DOH *obj, int x); + int DohGetmark(DOH *obj); + + /* ----------------------------------------------------------------------------- + * Strings. + * ----------------------------------------------------------------------------- */ + + String *NewStringEmpty(void); + String *NewString(String_or_char_ptr c); + String *NewStringWithSize(const String_or_char_ptr c, int len); + String *NewStringf(const String_or_char_ptr fmt, VA_DECL); + + const char *Char(const String_or_char_ptr s); + + int Strcmp(const String_or_char_ptr s1, const String_or_char_ptr s2); + int Strncmp(const String_or_char_ptr s1, const String_or_char_ptr s2, int n); + const char *Strstr(const String_or_char_ptr s1, const String_or_char_ptr s2); + const char *Strchr(const String_or_char_ptr s1, int ch); + + /* String replacement flags */ + + #define DOH_REPLACE_ANY 0x01 + #define DOH_REPLACE_NOQUOTE 0x02 + #define DOH_REPLACE_ID 0x04 + #define DOH_REPLACE_FIRST 0x08 + #define DOH_REPLACE_ID_BEGIN 0x10 + #define DOH_REPLACE_ID_END 0x20 + + #define Replaceall(s,t,r) Replace(s,t,r,DOH_REPLACE_ANY) + #define Replaceid(s,t,r) Replace(s,t,r,DOH_REPLACE_ID) + + + /* ----------------------------------------------------------------------------- + * Files + * ----------------------------------------------------------------------------- */ + + DOH *NewFile(DOH *filename, const char *mode, DOH *outfiles); + DOH *NewFileFromFile(FILE *f); // Never + DOH *NewFileFromFd(int fd); // Never + void FileErrorDisplay(DOH *filename); + int Close(DOH *file); + int Copyto(DOH *input, DOH *output); // Never + + /* ----------------------------------------------------------------------------- + * List + * ----------------------------------------------------------------------------- */ + + List *NewList(); + //void SortList(DOH *lo, int (*cmp) (const DOH *, const DOH *)); + void SortList(DOH *lo, int (*cmp) + (const String_or_char_ptr, const String_or_char_ptr)); + + /* ----------------------------------------------------------------------------- + * Hash + * ----------------------------------------------------------------------------- */ + + Hash *NewHash(void); + + /* ----------------------------------------------------------------------------- + * Void + * ----------------------------------------------------------------------------- */ + + DOH *DohNewVoid(void *ptr, void (*del) (void *)); // Never + List *Split(DOH *input, char ch, int nsplits); + List *SplitLines(DOH *input); + #define DohSplitLines(x) SplitLines(x) + #define DohNone 0 + + extern void DohMemoryDebug(void); + + +} + +#endif /* DOH_H */ Added: branches/swig-2.0/Source/DOH2/file.cxx =================================================================== --- branches/swig-2.0/Source/DOH2/file.cxx (rev 0) +++ branches/swig-2.0/Source/DOH2/file.cxx 2009-02-08 16:12:32 UTC (rev 11121) @@ -0,0 +1,83 @@ +/* + * This file is part of SWIG. + * + * SWIG 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 3 of the License, or + * (at your option) any later version. + * + * SWIG 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 SWIG. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "doh.h" +#include <cstdarg> +#include <cstdio> +#include <cassert> +namespace doh { + + /* class File */ + + /* Constructors */ + File::File() + {} + + File::File(const File& f) + : Filelike(f), fp(f.fp) + {} + + File::File(const char * filename, const char *mode) + : fp(fopen(filename, mode)) + {} + + /* inherit from DOH */ + DOH* File::clone() const { + return new File(*this); + } + + void File::clear() { + /* XXX should we have clear()? */ + DOH::clear(); + return; + } + + int File::size() const { + /* XXX no size() operation */ + return 0; + } + + int File::write(const char *buffer, size_t length) { + return fwrite(buffer, 1, length, fp); + } + + int File::read(char *buffer, size_t length) { + return fread(buffer, 1, length, fp); + } + + int File::seek(off_t offset, int whence) { + return fseek(fp, offset, whence); + } + + off_t File::tell() { + return ftell(fp); + } + + char File::getc() { + return fgetc(fp); + } + + char File::putc(char c) { + return fputc(c, fp); + } + + char File::ungetc(char ch) { + return std::ungetc(ch, fp); + } + + +} Added: branches/swig-2.0/Source/DOH2/fio.cxx =================================================================== --- branches/swig-2.0/Source/DOH2/fio.cxx (rev 0) +++ branches/swig-2.0/Source/DOH2/fio.cxx 2009-02-08 16:12:32 UTC (rev 11121) @@ -0,0 +1,623 @@ +/* ----------------------------------------------------------------------------- + * fio.c + * + * This file implements a number of standard I/O operations included + * formatted output, readline, and splitting. + * + * Author(s) : David Beazley (be...@cs...) + * + * Copyright (C) 1999-2000. The University of Chicago + * See the file LICENSE for information on usage and redistribution. + * ----------------------------------------------------------------------------- */ + +#include "doh.h" +#include <map> +#include <string> +#include <cstring> +#include <cstdarg> +#include <cstdlib> +using namespace std; +namespace doh { +#define OBUFLEN 512 + +typedef DOH *(*encoding_fn) (DOH *s); +typedef map<std::string, encoding_fn> encoding_map; + +static encoding_map *encodings = 0; /* Encoding hash */ + +/* ----------------------------------------------------------------------------- + * Writen() + * + * Write's N characters of output and retries until all characters are + * written. This is useful should a write operation encounter a spurious signal. + * ----------------------------------------------------------------------------- */ + +static int Writen(DOH *out, void *buffer, int len) { + int nw = len, ret; + char *cb = (char *) buffer; + while (nw) { + ret = Write(out, cb, nw); + if (ret < 0) + return -1; + nw = nw - ret; + cb += ret; + } + return len; +} + +/* ----------------------------------------------------------------------------- + * DohEncoding() + * + * Registers a new printf encoding method. An encoder function should accept + * two file-like objects and operate as a filter. + * ----------------------------------------------------------------------------- */ + +void DohEncoding(char *name, DOH *(*fn) (DOH *s)) { + if (!encodings) + encodings = new encoding_map(); + (*encodings)[name] = fn; + //Setattr(encodings, (void *) name, NewVoid((void *) fn, 0)); +} + +/* internal function for processing an encoding */ +static DOH *encode(char *name, DOH *s) { + DOH *ns; + DOH *(*fn) (DOH *); + long pos; + char *cfmt = strchr(name, ':'); + DOH *tmp = 0; + if (cfmt) { + tmp = NewString(cfmt + 1); + Append(tmp, s); + Setfile(tmp, Getfile((DOH *) s)); + Setline(tmp, Getline((DOH *) s)); + *cfmt = '\0'; + } + //if (!encodings || !(handle = Getattr(encodings, name))) { + if (!encodings || encodings->count(name)) { + return Copy(s); + } else { + fn = (*encodings)[name]; + } + if (tmp) + s = tmp; + pos = Tell(s); + Seek(s, 0, SEEK_SET); + //fn = (DOH *(*)(DOH *)) Data(handle); + ns = (*fn) (s); + Seek(s, pos, SEEK_SET); + if (tmp) + Delete(tmp); + return ns; +} + +/* ----------------------------------------------------------------------------- + * DohvPrintf() + * + * DOH implementation of printf. Output can be directed to any file-like object + * including bare FILE * objects. The same formatting codes as printf are + * recognized with two extensions: + * + * %s - Prints a "char *" or the string representation of any + * DOH object. This will implicitly result in a call to + * Str(obj). + * + * %(encoder)* - Filters the output through an encoding function registered + * with DohEncoder(). + * + * Note: This function is not particularly memory efficient with large strings. + * It's better to use Dump() or some other method instead. + * ----------------------------------------------------------------------------- */ + +int vPrintf(DOH *so, const char *format, VA_DEF) { + static const char *fmt_codes = "dioxXucsSfeEgGpn"; + int state = 0; + const char *p = format; + char newformat[256]; + char obuffer[OBUFLEN]; + char *fmt = 0; + char temp[64]; + int widthval = 0; + int precval = 0; + int maxwidth; + char *w = 0; + int ivalue; + double dvalue; + void *pvalue; + char *stemp; + int nbytes = 0; + char encoder[128], *ec = 0; + int plevel = 0; + + VA_INIT; + + memset(newformat, 0, sizeof(newformat)); + + while (*p) { + switch (state) { + case 0: /* Ordinary text */ + if (*p != '%') { + Putc(*p, so); + nbytes++; + } else { + fmt = newformat; + widthval = 0; + precval = 0; + *(fmt++) = *p; + encoder[0] = 0; + state = 10; + } + break; + case 10: /* Look for a width and precision */ + if (isdigit((int) *p) && (*p != '0')) { + w = temp; + *(w++) = *p; + *(fmt++) = *p; + state = 20; + } else if (strchr(fmt_codes, *p)) { + /* Got one of the formatting codes */ + p--; + state = 100; + } else if (*p == '*') { + /* Width field is specified in the format list */ + widthval = VA_GET._int; + sprintf(temp, "%d", widthval); + for (w = temp; *w; w++) { + *(fmt++) = *w; + } + state = 30; + } else if (*p == '%') { + Putc(*p, so); + fmt = newformat; + nbytes++; + state = 0; + } else if (*p == '(') { + ++plevel; + ec = encoder; + state = 60; + } else { + *(fmt++) = *p; + } + break; + + case 20: /* Hmmm. At the start of a width field */ + if (isdigit((int) *p)) { + *(w++) = *p; + *(fmt++) = *p; + } else if (strchr(fmt_codes, *p)) { + /* Got one of the formatting codes */ + /* Figure out width */ + *w = 0; + widthval = atoi(temp); + p--; + state = 100; + } else if (*p == '.') { + *w = 0; + widthval = atoi(temp); + w = temp; + *(fmt++) = *p; + state = 40; + } else { + /* ??? */ + *w = 0; + widthval = atoi(temp); + state = 50; + } + break; + + case 30: /* Parsed a width from an argument. Look for a . */ + if (*p == '.') { + w = temp; + *(fmt++) = *p; + state = 40; + } else if (strchr(fmt_codes, *p)) { + /* Got one of the formatting codes */ + /* Figure out width */ + p--; + state = 100; + } else { + /* hmmm. Something else. */ + state = 50; + } + break; + + case 40: + /* Start of precision expected */ + if (isdigit((int) *p) && (*p != '0')) { + *(fmt++) = *p; + *(w++) = *p; + state = 41; + } else if (*p == '*') { + /* Precision field is specified in the format list */ + precval = VA_GET._int; + sprintf(temp, "%d", precval); + for (w = temp; *w; w++) { + *(fmt++) = *w; + } + state = 50; + } else if (strchr(fmt_codes, *p)) { + p--; + state = 100; + } else { + *(fmt++) = *p; + state = 50; + } + break; + case 41: + if (isdigit((int) *p)) { + *(fmt++) = *p; + *(w++) = *p; + } else if (strchr(fmt_codes, *p)) { + /* Got one of the formatting codes */ + /* Figure out width */ + *w = 0; + precval = atoi(temp); + p--; + state = 100; + } else { + *w = 0; + precval = atoi(temp); + *(fmt++) = *p; + state = 50; + } + break; + /* Hang out, wait for format specifier */ + case 50: + if (strchr(fmt_codes, *p)) { + p--; + state = 100; + } else { + *(fmt++) = *p; + } + break; + + /* Got an encoding header */ + case 60: + if (*p == '(') { + ++plevel; + *ec = *p; + ec++; + } else if (*p == ')') { + --plevel; + if (plevel <= 0) { + *ec = 0; + state = 10; + } else { + *ec = *p; + ec++; + } + } else { + *ec = *p; + ec++; + } + break; + case 100: + /* Got a formatting code */ + if (widthval < precval) + maxwidth = precval; + else + maxwidth = widthval; + if ((*p == 's') || (*p == 'S')) { /* Null-Terminated string */ + const char *str; + DOH *Sval; + DOH *enc = 0; + str = VA_GET._str; + /* if (DohCheck(doh)) { + // Is a DOH object. + if (DohIsString(doh)) { + Sval = doh; + } else { + Sval = Str(doh); + } + if (strlen(encoder)) { + enc = encode(encoder, Sval); + maxwidth = maxwidth + strlen(newformat) + Len(enc); + } else { + maxwidth = maxwidth + strlen(newformat) + Len(Sval); + } + *(fmt++) = 's'; + *fmt = 0; + if ((maxwidth + 1) < OBUFLEN) { + stemp = obuffer; + } else { + stemp = (char *) malloc(maxwidth + 1); + } + if (enc) { + nbytes += sprintf(stemp, newformat, Data(enc)); + } else { + nbytes += sprintf(stemp, newformat, Data(Sval)); + } + if (Writen(so, stemp, strlen(stemp)) < 0) + return -1; + if ((DOH *) Sval != doh) { + Delete(Sval); + } + if (enc) + Delete(enc); + if (*p == 'S') { + Delete(doh); + } + if (stemp != obuffer) { + free(stemp); + } + } else */ { + //if (!doh) + // doh = (char *) ""; + + if (strlen(encoder)) { + //DOH *s = NewString(doh); + DOH *s = NewString(str); + Seek(s, 0, SEEK_SET); + enc = encode(encoder, s); + Delete(s); + str = Char(enc); + } else { + enc = 0; + } + maxwidth = maxwidth + strlen(newformat) + strlen((char *) str); + *(fmt++) = 's'; + *fmt = 0; + if ((maxwidth + 1) < OBUFLEN) { + stemp = obuffer; + } else { + stemp = (char *) malloc(maxwidth + 1); + } + nbytes += sprintf(stemp, newformat, str); + if (Writen(so, stemp, strlen(stemp)) < 0) + return -1; + if (stemp != obuffer) { + free(stemp); + } + if (enc) + Delete(enc); + } + } else { + *(fmt++) = *p; + *fmt = 0; + maxwidth = maxwidth + strlen(newformat) + 64; + + /* Only allocate a buffer if it is too big to fit. Shouldn't have to do + this very often */ + + if (maxwidth < OBUFLEN) + stemp = obuffer; + else + stemp = (char *) malloc(maxwidth + 1); + switch (*p) { + case 'd': + case 'i': + case 'o': + case 'u': + case 'x': + case 'X': + case 'c': + ivalue = VA_GET._int; //va_arg(ap, int); + nbytes += sprintf(stemp, newformat, ivalue); + break; + case 'f': + case 'g': + case 'e': + case 'E': + case 'G': + dvalue = VA_GET._double; //va_arg(ap, double); + nbytes += sprintf(stemp, newformat, dvalue); + break; + case 'p': + pvalue = VA_GET._pointer; //va_arg(ap, void *); + nbytes += sprintf(stemp, newformat, pvalue); + break; + default: + break; + } + if (Writen(so, stemp, strlen(stemp)) < 0) + return -1; + if (stemp != obuffer) + free(stemp); + } + state = 0; + break; + } + p++; + } + if (state) { + int r; + *fmt = 0; + r = Writen(so, fmt, strlen(fmt)); + if (r < 0) + return -1; + nbytes += r; + } + return nbytes; +} + +/* ----------------------------------------------------------------------------- + * DohPrintf() + * + * Variable length argument entry point to Printf + * ----------------------------------------------------------------------------- */ + +int Printf(DOH *obj, const char *format, VA_DEF) { + int ret; + ret = vPrintf(obj, format, VA_CALL); + return ret; +} + +int Printf(FILE *f, const char *format, VA_DEF) { + int ret; + String *tmp = NewStringEmpty(); + ret = vPrintf(tmp, format, VA_CALL); + fprintf(f, tmp->c_str()); + Delete(tmp); + return ret; +} + +/* ----------------------------------------------------------------------------- + * DohPrintv() + * + * Print a null-terminated variable length list of DOH objects + * ----------------------------------------------------------------------------- */ + +int Printv(DOH * obj, VA_DEF) { + int ret = 0; + const char *str; + VA_INIT; + + while (1) { + /* Always assume const char* */ + str = VA_GET._str; + if ((!str) || (str == DohNone)) + break; + ret += Write(obj, str, strlen(str)); + } + return ret; +} + +int Printv(FILE * f, VA_DEF) { + int ret = 0; + const char *str; + VA_INIT; + + while (1) { + /* Always assume const char* */ + str = VA_GET._str; + if ((!str) || (str == DohNone)) + break; + ret += fwrite(str, 1, strlen(str), f); + } + return ret; + +} + +/* ----------------------------------------------------------------------------- + * DohCopyto() + * + * Copies all of the input from an input stream to an output stream. Returns the + * number of bytes copied. + * ----------------------------------------------------------------------------- */ + +int DohCopyto(DOH *in, DOH *out) { + int nbytes = 0, ret; + int nwrite = 0, wret; + char *cw; + char buffer[16384]; + + if ((!in) || (!out)) + return 0; + while (1) { + ret = Read(in, buffer, 16384); + if (ret > 0) { + nwrite = ret; + cw = buffer; + while (nwrite) { + wret = Write(out, cw, nwrite); + if (wret < 0) + return -1; + nwrite = nwrite - wret; + cw += wret; + } + nbytes += ret; + } else { + return nbytes; + } + } +} + + +/* ----------------------------------------------------------------------------- + * DohSplit() + * + * Split an input stream into a list of strings delimited by the specified + * character. Optionally accepts a maximum number of splits to perform. + * ----------------------------------------------------------------------------- */ + +List *Split(DOH *in, char ch, int nsplits) { + List *list; + DOH *str; + int c; + + list = NewList(); + + if (DohIsString(in)) { + Seek(in, 0, SEEK_SET); + } + + while (1) { + str = NewStringEmpty(); + do { + c = Getc(in); + } while ((c != EOF) && (c == ch)); + if (c != EOF) { + Putc(c, str); + while (1) { + c = Getc(in); + if ((c == EOF) || ((c == ch) && (nsplits != 0))) + break; + Putc(c, str); + } + nsplits--; + } + Append(list, str); + //Delete(str); + if (c == EOF) + break; + } + return list; +} + +/* ----------------------------------------------------------------------------- + * DohSplitLines() + * + * Split an input stream into a list of strings delimited by newline characters. + * ----------------------------------------------------------------------------- */ + +List *SplitLines(DOH *in) { + List *list; + DOH *str; + int c = 0; + + list = NewList(); + + if (DohIsString(in)) { + Seek(in, 0, SEEK_SET); + } + + while (c != EOF) { + str = NewStringEmpty(); + while ((c = Getc(in)) != '\n' && c != EOF) { + Putc(c, str); + } + Append(list, str); + //Delete(str); + } + return list; +} + + +/* ----------------------------------------------------------------------------- + * DohReadline() + * + * Read a single input line and return it as a string. + * ----------------------------------------------------------------------------- */ + +DOH *Readline(DOH *in) { + char c; + int n = 0; + DOH *s = NewStringEmpty(); + while (1) { + if (Read(in, &c, 1) < 0) { + if (n == 0) { + Delete(s); + return 0; + } + return s; + } + if (c == '\n') + return s; + if (c == '\r') + continue; + Putc(c, s); + n++; + } +} + +} /* namespace doh */ Added: branches/swig-2.0/Source/DOH2/hash.cxx =================================================================== --- branches/swig-2.0/Source/DOH2/hash.cxx (rev 0) +++ branches/swig-2.0/Source/DOH2/hash.cxx 2009-02-08 16:12:32 UTC (rev 11121) @@ -0,0 +1,174 @@ +/* + * This file is part of SWIG. + * + * SWIG 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 3 of the License, or + * (at your option) any later version. + * + * SWIG 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 SWIG. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "doh.h" +#include <cassert> +#include <cstdlib> +namespace doh { + /* class Hash */ + /* Constructors */ + Hash::Hash() { + } + + Hash::Hash(const Hash &x) + : Container(x), map_doh(x) + {} + + /* inherit from DOH */ + DOH *Hash::clone() const { + return new Hash(*this); + } + + void Hash::clear() { + map_doh::clear(); + DOH::clear(); + } + + int Hash::size() const { + return map_doh::size(); + } + + /* internal iterator for Hash */ + class Hash::_iterator + : public _Iterator, public map_doh::iterator { + public: + _iterator(const map_doh::iterator& i) + :map_doh::iterator(i) + {} + virtual ~_iterator() { + } + }; + + + /* inherit from Container */ + Iterator Hash::first() { + Iterator i; + /* XXX potential memory leak since we only + * delete i._iter when the iterator reached + * its end. */ + i._iter = new _iterator(begin()); + i.object = this; + check_iter(i); + return i; + } + Iterator& Hash::next(Iterator& i) { + _iterator* _i = dynamic_cast<_iterator*>(i._iter); + ++(*_i); + check_iter(i); + } + + // Check and set state of iterator + void Hash::check_iter(Iterator &i) { + _iterator* _i = dynamic_cast<_iterator*>(i._iter); + if (0==_i) + return; + if (end() != *_i) { + i.key = (**_i).first.c_str(); + i.item = (**_i).second; + } else { + i.key = 0; + i.item = 0; + delete i._iter; + i._iter = 0; + } + } + + Hash *NewHash(void) { + return new Hash(); + } + + DOHCaster Getattr(DOH *obj, const String_or_char_ptr name) { + Hash &ho = ref_cast<Hash>(obj); + std::string key(name); + if (ho.count(key) > 0) + return ho[key]; + else + return 0; + } + + int Setattr(DOH *obj, const String_or_char_ptr name, const char *value) { + Hash &ho = ref_cast<Hash>(obj); + std::string key(name); + DOH *so = new String(value); + int r = ho.count(key); + ho[key] = so; + return r; + } + + int Setattr(DOH *obj, const String_or_char_ptr name, DOH *value) { + Hash &ho = ref_cast<Hash>(obj); + std::string key(name); + int r = ho.count(key); + ho[key] = value; + return r; + } + + int Checkattr(DOH *obj, const String_or_char_ptr name, const String_or_char_ptr value) { + DOH *attr = Getattr(obj, name); + if (!attr) return 0; + return Equal(doh_cast<String*>(attr), value); + } + + DOHCaster Keys(DOH *obj) { + Hash &ho = ref_cast<Hash>(obj); + List *keys = new List(); + map_doh::iterator iter = ho.begin(); + for(;iter!=ho.end(); iter++) { + keys->push_back(new String(iter->first)); + } + return keys; + } + + int GetInt(DOH *obj, const String_or_char_ptr name) { + Hash &ho = ref_cast<Hash>(obj); + std::string key(name); + if (ho.count(key)>0) { + String *val = doh_cast<String*>(ho[key]); + return atoi(val->c_str()); + } else + return 0; + } + + void SetInt(DOH *obj, const String_or_char_ptr name, int value) { + String *val = NewStringEmpty(); + Printf(val, "%d", value); + Setattr(obj, name, val); + } + + DOHCaster GetFlagAttr(DOH *obj, const String_or_char_ptr name) { + DOH *val = Getattr(obj, name); + if (!val) { + return 0; + } else { + String &sval = ref_cast<String>(val); + return (sval != "0") ? val : NULL; + } + } + + int GetFlag(DOH *obj, const String_or_char_ptr name) { + return (DOH*) GetFlagAttr(obj, name) ? 1 : 0; + } + + void SetFlagAttr(DOH *obj, const String_or_char_ptr name, DOH *attr) { + Setattr(obj, name, attr ? attr : NewString("0")); + } + + void SetFlag(DOH *obj, const String_or_char_ptr name) { + Setattr(obj, name, NewString("1")); + } + +} Added: branches/swig-2.0/Source/DOH2/list.cxx =================================================================== --- branches/swig-2.0/Source/DOH2/list.cxx (rev 0) +++ branches/swig-2.0/Source/DOH2/list.cxx 2009-02-08 16:12:32 UTC (rev 11121) @@ -0,0 +1,125 @@ +/* + * This file is part of SWIG. + * + * SWIG 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 3 of the License, or + * (at your option) any later version. + * + * SWIG 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 SWIG. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "doh.h" +#include <cassert> +namespace doh { + + /* class List */ + + /* Constructors */ + + List::List() { + } + + List::List(const List &x) + :list_doh(x), Container(x) + {} + + /* inherit from DOH */ + + DOH* List::clone() const { + return new List(*this); + } + + void List::clear() { + list_doh::clear(); + DOH::clear(); + return; + } + + int List::size() const { + return list_doh::size(); + } + + /* internal iterator for List */ + class List::_iterator + : public _Iterator, public list_doh::iterator { + public: + _iterator(const list_doh::iterator& i) + :list_doh::iterator(i) + {} + virtual ~_iterator() { + } + }; + + /* inherit from Container */ + + Iterator List::first() { + Iterator i; + /* XXX potential memory leak since we only + * delete i._iter when the iterator reached + * its end. */ + i._iter = new _iterator(begin()); + i.object = this; + i.key = 0; + check_iter(i); + return i; + } + + Iterator& List::next(Iterator& i) { + _iterator* _i = dynamic_cast<_iterator*>(i._iter); + ++(*_i); + check_iter(i); + return i; + } + + void List::check_iter(Iterator& i) { + _iterator* _i = dynamic_cast<_iterator*>(i._iter); + if (0==_i) + return; + if (end() != *_i) { + i.item = (**_i); + } else { + i.item = 0; + delete i._iter; + i._iter = 0; + } + } + + /* Overloaded for convenience */ + void List::insert(size_t pos, DOH *x) { + iterator iter = begin(); + while (pos--) + iter++; + list_doh::insert(iter, x); + return; + } + + void List::erase(size_t pos, size_t n) { + iterator iter = begin(); + while (pos--) + iter++; + while (n--) + iter = list_doh::erase(iter); + return; + } + + /* DOH List methods */ + + List *NewList() { + return new List(); + } + + void SortList(DOH *lo, int (*cmp) (const String_or_char_ptr, const String_or_char_ptr)) { + List *l = doh_cast<List*>(lo); + if (!cmp) { + cmp = Cmp; + } + l->sort(cmp); + } +} Added: branches/swig-2.0/Source/DOH2/string.cxx =================================================================== --- branches/swig-2.0/Source/DOH2/string.cxx (rev 0) +++ branches/swig-2.0/Source/DOH2/string.cxx 2009-02-08 16:12:32 UTC (rev 11121) @@ -0,0 +1,639 @@ +/* + * This file is part of SWIG. + * + * SWIG 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 3 of the License, or + * (at your option) any later version. + * + * SWIG 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 SWIG. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "doh.h" +#include <cstring> +#include <cstdarg> +#include <cassert> +namespace doh { + + /* class String */ + + /* Constructors */ + String::String() + : sp(0) + {} + + String::String(const String& str) + : Filelike(str), std::string(str), sp(str.sp) + {} + + String::String(const std::string& str) + : Filelike(), std::string(str), sp(0) + {} + + + String::String(const char * s) + : std::string(s), sp(0) { + } + + String::String(const char *s, size_t n) + : std::string(s, n), sp(0) { + } + + /* inherit from DOH */ + DOH* String::clone() const { + return new String(*this); + } + + void String::clear() { + sp = 0; + std::string::clear(); + DOH::clear(); + return; + } + + int String::size() const { + return std::string::size(); + } + + /* inherit from Filelike */ + + int String::write(const char *buffer, size_t length) { + replace(sp, length, buffer); + sp += length; + return length; + } + + int String::read(char *buffer, size_t length) { + size_t readlen; + readlen = size() - sp; + if (readlen < 0) + return 0; + if (readlen > length) + readlen = length; + memmove(buffer, data(), readlen); + sp += readlen; + return readlen; + } + + /* count the occurrence of '\n' in a closed range */ + static int countline(const char *str, size_t l, size_t r) { + register int count = 0; + register const char *i = str + l; + register const char *rr = str + r; + while (i <= rr) { + /* XXX In the original DOH there is '++i', + * (accutally ++sp and --sp) + * but to conform with getc(), it should + * be i++. */ + if (*(i++) == '\n') + ++count; + } + return count; + } + int String::seek(off_t offset, int whence) { + int pos, nsp, inc; + int len = size(); + + if (whence == SEEK_SET) + pos = 0; + else if (whence == SEEK_CUR) + pos = sp; + else if (whence == SEEK_END) { + pos = len; + offset = -offset; + } else + pos = sp; + + nsp = pos + offset; + if (nsp < 0) + nsp = 0; + if ( len > 0 && nsp > len) + nsp = len; + + /* Set line number */ + if (sp < nsp) + _line += countline(c_str(), sp, nsp-1); + else + _line -= countline(c_str(), nsp+1, sp); + + sp = nsp; + assert( sp >= 0 ); + return 0; + } + + off_t String::tell() { + return sp; + } + + char String::getc() { + char c; + if (sp >= size()) + c = EOF; + else + c = c_str()[sp++]; + if (c == '\n') + _line++; + return c; + } + char String::putc(char ch) { + register int len = size(); + if (sp < len) { + at(sp++) = ch; + } else { + /* append to tail of the string */ + push_back(ch); + sp++; + } + return ch; + } + + char String::ungetc(char ch) { + if (ch == EOF) + return ch; + if (sp <= 0) + return EOF; + sp--; + if (ch == '\n') + _line--; + return ch; + } + + /* Override std::string methods */ + String& String::insert(size_t pos, const std::string &str) { + size_t len = str.size(); + std::string::insert(pos, str); + if (sp >= pos) { + _line += countline(str.c_str(), 0, len-1); + sp += len; + } + return *this; + } + + String& String::erase(size_t pos, size_t n) { + int eindex = pos + n; + int end; + /* Adjust file pointer sp and line count */ + if (sp > pos) { + if (sp > eindex) { + end = eindex; + sp -= n; + } else { + end = sp; + sp = pos; + } + _line -= countline(c_str(), pos, end-1); + } + std::string::erase(pos, n); + return *this; + } + + + /* DOH String methods */ + + String *NewStringEmpty() { + return new String(); + } + + String *NewString(String_or_char_ptr c) { + return new String(c); + } + + String *NewStringWithSize(const String_or_char_ptr c, int len) { + const char *p = c; + return new String(c, len); + } + + /*XXX const char* fmt is enough */ + String *NewStringf(const String_or_char_ptr fmt, VA_DEF) { + //va_list ap; + String *r = new String(); + const char * fmtstr = fmt; + //va_start(ap, fmt); + Printf(r, fmtstr, VA_CALL); + //va_end(ap); + return r; + } + + int Cmp(String_or_char_ptr obj1, String_or_char_ptr obj2) { + const String *str1 = obj1; // implicit cast + const String *str2 = obj2; + return str1->compare(*str2); + } + + const char *Char(const String_or_char_ptr s) { + return s; + } + + int Equal(const String_or_char_ptr obj1, const String_or_char_ptr obj2) { + return Cmp(obj1, obj2)==0; + } + + int Strcmp(const String_or_char_ptr s1, const String_or_char_ptr s2) { + const char *c1 = Char(s1); + const char *c2 = Char(s2); + if (c1 && c2) { + return strcmp(c1, c2); + } else { + return c1 < c2; + } + } + + int Strncmp(const String_or_char_ptr s1, const String_or_char_ptr s2, int n) { + return strncmp(Char(s1), Char(s2), n); + } + const char *Strstr(const String_or_char_ptr s1, const String_or_char_ptr s2) { + const char *p1 = Char(s1); + const char *p2 = Char(s2); + return p1 == 0 || p2 == 0 || *p2 == '\0' ? p1 : strstr(p1, p2); + } + + const char *Strchr(const String_or_char_ptr s1, int ch) { + return strchr(Char(s1), ch); + } + +void Chop(DOH *src) { + String &so = ref_cast<String>(src); + int len = so.size(); + int i = len; + while (i>0 && isspace(so[i-1])) { + i--; + } + so.erase(i, len-i); +} + +int Replace(DOH * src, const String_or_char_ptr token, + const String_or_char_ptr rep, int flags) { + String *so = doh_cast<String*>(src); + so->doh_replace(token, rep, flags); +} + + + /* The powerful DOH string replace function */ + + static int replace_simple(char* &str, int &str_len, off_t &str_sp, + const char *token, const char *rep, int flags, int count, + char *(*match) (char *, char *, const char *, int)); + static char *match_identifier(char *base, char *s, const char *token, int tokenlen); + static char *match_identifier_begin(char *base, char *s, const char *token, int tokenlen); + static char *match_identifier_end(char *base, char *s, const char *token, int tokenlen); + static char *match_simple(char *base, char *s, const char *token, int tokenlen); + + int String::doh_replace(const char *token, const char *rep, int flags) { + int len = size(); + int count = -1; + int ret; + char *str = new char[len+1]; + strcpy(str, c_str()); + if (flags & DOH_REPLACE_FIRST) + count = 1; + + if (flags & DOH_REPLACE_ID_END) { + ret = replace_simple(str, len, sp, token, rep, flags, count, + match_identifier_end); + } else if (flags & DOH_REPLACE_ID_BEGIN) { + ret = replace_simple(str, len, sp, token, rep, flags, count, + match_identifier_begin); + } else if (flags & DOH_REPLACE_ID) { + ret = replace_simple(str, len, sp, token, rep, flags, count, + match_identifier); + } else { + ret = replace_simple(str, len, sp, token, rep, flags, count, + match_simple); + } + + assert(strlen(str)==len); + assign(str); + delete[] str; + /* sp already set since we passed it as reference */ + return ret; + } + + +/* below code is adapted from old DOH */ + +/* ----------------------------------------------------------------------------- + * replace_simple(String *str, char *token, char *rep, int flags, int count) + * + * Replaces count non-overlapping occurrences of token with rep in a string. + * ----------------------------------------------------------------------------- */ + +static char *end_quote(char *s) { + char *qs; + char qc; + char *q; + char *nl; + qc = *s; + qs = s; + while (1) { + q = strpbrk(s + 1, "\"\'"); + nl = strchr(s + 1, '\n'); + if (nl && (nl < q)) { + /* A new line appears before the end of the string */ + if (*(nl - 1) == '\\') { + s = nl + 1; + continue; + } + /* String was terminated by a newline. Wing it */ + return qs; + } + if (!q && nl) { + return qs; + } + if (!q) + return 0; + if ((*q == qc) && (*(q - 1) != '\\')) + return q; + s = q; + } +} + +static char *match_simple(char *base, char *s, const char *token, int tokenlen) { + (void) base; + (void) tokenlen; + return strstr(s, token); +} + +static char *match_identifier(char *base, char *s, const char *token, int tokenlen) { + while (s) { + s = strstr(s, token); + if (!s) + return 0; + if ((s > base) && (isalnum((int) *(s - 1)) || (*(s - 1) == '_'))) { + s += tokenlen; + continue; + } + if (isalnum((int) *(s + tokenlen)) || (*(s + tokenlen) == '_')) { + s += tokenlen; + continue; + } + return s; + } + return 0; +} + + +static char *match_identifier_begin(char *base, char *s, const char *token, int tokenlen) { + while (s) { + s = strstr(s, token); + if (!s) + return 0; + if ((s > base) && (isalnum((int) *(s - 1)) || (*(s - 1) == '_'))) { + s += tokenlen; + continue; + } + return s; + } + return 0; +} + +static char *match_identifier_end(char *base, char *s, const char *token, int tokenlen) { + (void) base; + while (s) { + s = strstr(s, token); + if (!s) + return 0; + if (isalnum((int) *(s + tokenlen)) || (*(s + tokenlen) == '_')) { + s += tokenlen; + continue; + } ... [truncated message content] |