From varg at metalica.kh.ua Mon Aug 3 09:11:32 2009 From: varg at metalica.kh.ua (Alexei Sheplyakov) Date: Mon, 3 Aug 2009 10:11:32 +0300 Subject: [GiNaC-devel] Parser breakage changes In-Reply-To: <4A72D079.9040609@nikhef.nl> References: <20090710130646.92C655B4051@cebix.net> <20090731073612.GA18752@metalica.kh.ua> <4A72D079.9040609@nikhef.nl> Message-ID: <20090803071132.GA4430@metalica.kh.ua> Dear Jens, On Fri, Jul 31, 2009 at 01:07:37PM +0200, Jens Vollinga wrote: > because the parser as it was violated the basic assumption (not only > that of the people that complained but also mine!) that the parser, > without any tweaking, should just read any expression containing any > functions and classes defined at that moment. I think this assumption is bogus. Just because you've defined a (C++) type (class) doesn't mean you can print and/or parse objects of that type. Anyway, the old (bison-generated) parser never 'just read any expression containing any functions and classes defined at that moment' (actually it didn't handle any user defined classes at all). > A user shouldn't be forced to define his own reader just to get a simple > expression read in Making a type printable/readable (and/or serializable) always requires some boilerplate code. > Yeah, more boilerplate code, right, but now only people with special > needs have to go through this hassle and not the average user anymore. "A million lemmings can't be wrong"-alike arguments do nothing useful and make some people (including myself) very angry. Best regards, Alexei From sergstesh at yahoo.com Mon Aug 3 09:19:32 2009 From: sergstesh at yahoo.com (Sergei Steshenko) Date: Mon, 3 Aug 2009 00:19:32 -0700 (PDT) Subject: [GiNaC-devel] Parser breakage changes In-Reply-To: <20090803071132.GA4430@metalica.kh.ua> Message-ID: <577069.26475.qm@web35202.mail.mud.yahoo.com> --- On Mon, 8/3/09, Alexei Sheplyakov wrote: > From: Alexei Sheplyakov > Subject: Re: [GiNaC-devel] Parser breakage changes > To: "GiNaC development list" > Date: Monday, August 3, 2009, 12:11 AM [snip] > "A million lemmings can't be wrong"-alike arguments do > nothing useful and > make some people (including myself) very angry. > > Best regards, > ??? Alexei > And/or, as I typically put it, in the middle ages the vast majority of people used to think the Earth was flat. Regards, Sergei. From jensv at nikhef.nl Tue Aug 4 01:23:30 2009 From: jensv at nikhef.nl (Jens Vollinga) Date: Tue, 04 Aug 2009 01:23:30 +0200 Subject: [GiNaC-devel] Parser breakage changes In-Reply-To: <20090803071132.GA4430@metalica.kh.ua> References: <20090710130646.92C655B4051@cebix.net> <20090731073612.GA18752@metalica.kh.ua> <4A72D079.9040609@nikhef.nl> <20090803071132.GA4430@metalica.kh.ua> Message-ID: <4A777172.70708@nikhef.nl> Hi Alexei, Alexei Sheplyakov schrieb: > I think this assumption is bogus. Just because you've defined a (C++) type > (class) doesn't mean you can print and/or parse objects of that type. Anyway, > the old (bison-generated) parser never 'just read any expression containing > any functions and classes defined at that moment' (actually it didn't handle > any user defined classes at all). nothing has changed here. If you write your own type you still have to add extra read-in code. Ah yes, my sentence should not have included the word "classes", but you know the source code anyway. It makes sense to add another function to GiNaC, something like "get_builtin_reader()" or so. This function should return a reader that only knows about the official GiNaC approved functions and classes. Do you want to do this? Otherwise I'll it as soon as I find time. Regards, Jens From varg at metalica.kh.ua Tue Aug 4 08:30:05 2009 From: varg at metalica.kh.ua (Alexei Sheplyakov) Date: Tue, 4 Aug 2009 09:30:05 +0300 Subject: [GiNaC-devel] Parser breakage changes In-Reply-To: <4A777172.70708@nikhef.nl> References: <20090710130646.92C655B4051@cebix.net> <20090731073612.GA18752@metalica.kh.ua> <4A72D079.9040609@nikhef.nl> <20090803071132.GA4430@metalica.kh.ua> <4A777172.70708@nikhef.nl> Message-ID: <20090804063005.GA27374@metalica.kh.ua> Hi Jens, On Tue, Aug 04, 2009 at 01:23:30AM +0200, Jens Vollinga wrote: > It makes sense to add another function to GiNaC, something like > "get_builtin_reader()" or so. This function should return a reader that > only knows about the official GiNaC approved functions and classes. Do > you want to do this? Yes (as soon as I find time). But I'll omit some (most?) classes (indexed expressions, non-commutative products, etc), at least at the first step (at the moment the parser can't handle them anyway). Best regards, Alexei From jensv at nikhef.nl Tue Aug 4 09:11:58 2009 From: jensv at nikhef.nl (Jens Vollinga) Date: Tue, 04 Aug 2009 09:11:58 +0200 Subject: [GiNaC-devel] Parser breakage changes In-Reply-To: <20090804063005.GA27374@metalica.kh.ua> References: <20090710130646.92C655B4051@cebix.net> <20090731073612.GA18752@metalica.kh.ua> <4A72D079.9040609@nikhef.nl> <20090803071132.GA4430@metalica.kh.ua> <4A777172.70708@nikhef.nl> <20090804063005.GA27374@metalica.kh.ua> Message-ID: <4A77DF3E.9060304@nikhef.nl> Hi Alexei, Alexei Sheplyakov schrieb: > On Tue, Aug 04, 2009 at 01:23:30AM +0200, Jens Vollinga wrote: >> It makes sense to add another function to GiNaC, something like >> "get_builtin_reader()" or so. This function should return a reader that >> only knows about the official GiNaC approved functions and classes. Do >> you want to do this? sorry, maybe I should have written it more clearly: that "get_builtin_reader()" should just do what your old (1.5.2) "get_default_reader()" did. Then one has the choice between two built-in readers that should satisfy most demands. So, actually there is not much new coding, just adopting the old code to the new hacked way of doing it. Regards, Jens From kreckel at ginac.de Tue Aug 4 11:14:24 2009 From: kreckel at ginac.de (Richard B. Kreckel) Date: Tue, 04 Aug 2009 11:14:24 +0200 Subject: [GiNaC-devel] Debian files in git repository Message-ID: <4A77FBF0.9040400@ginac.de> Hi, I suppose nobody really cares about the debian/ directory. The files in there have not been maintained well, lately. Of course, this is because their lifecycle is better maintained over with the Debian packages. Anybody who cares about these files knows where they are: they are contained in the ginac_*.diff.gz files in the Debian package pool. Unless somebody speaks up, I will remove them from the repository, soon. Cheers -richy. -- Richard B. Kreckel From varg at metalica.kh.ua Tue Aug 4 11:52:37 2009 From: varg at metalica.kh.ua (Alexei Sheplyakov) Date: Tue, 4 Aug 2009 12:52:37 +0300 Subject: [GiNaC-devel] Debian files in git repository In-Reply-To: <4A77FBF0.9040400@ginac.de> References: <4A77FBF0.9040400@ginac.de> Message-ID: <20090804095237.GA11204@metalica.kh.ua> Dear Richard, On Tue, Aug 04, 2009 at 11:14:24AM +0200, Richard B. Kreckel wrote: > I suppose nobody really cares about the debian/ directory. That's not quite correct. I use those files to build up-to-date packages for lenny. > The files in there have not been maintained well, lately. Of course, > this is because their lifecycle is better maintained over with the Debian > packages. Anybody who cares about these files knows where they are: they > are contained in the ginac_*.diff.gz files in the Debian package pool. It would be nice if you put those *.diff.gz files somewhere on GiNaC web page too. > Unless somebody speaks up, I will remove them from the repository, soon. If this makes your task easier -- so be it, then. Best regards, Alexei From kreckel at ginac.de Tue Aug 4 23:07:37 2009 From: kreckel at ginac.de (Richard B. Kreckel) Date: Tue, 04 Aug 2009 23:07:37 +0200 Subject: [GiNaC-devel] Debian files in git repository In-Reply-To: <20090804095237.GA11204@metalica.kh.ua> References: <4A77FBF0.9040400@ginac.de> <20090804095237.GA11204@metalica.kh.ua> Message-ID: <4A78A319.9010209@ginac.de> Dear Alexei, Alexei Sheplyakov wrote: > On Tue, Aug 04, 2009 at 11:14:24AM +0200, Richard B. Kreckel wrote: >> I suppose nobody really cares about the debian/ directory. > > That's not quite correct. I use those files to build up-to-date packages > for lenny. Uhm, I never really had updates of stable Debian releases in mind since they won't let me update anyways. >> The files in there have not been maintained well, lately. Of course, >> this is because their lifecycle is better maintained over with the Debian >> packages. Anybody who cares about these files knows where they are: they >> are contained in the ginac_*.diff.gz files in the Debian package pool. > > It would be nice if you put those *.diff.gz files somewhere on GiNaC web > page too. Aha. But it would make even more sense to directly advertise your deb and deb-src repositories, right? I don't seem to be allowed to connect tohttp://theor.jinr.ru/~varg/debian/hep, though. I'm getting Error 403, access forbidden. >> Unless somebody speaks up, I will remove them from the repository, soon. > > If this makes your task easier -- so be it, then. It certainly doesn't make my life easier than not caring at all. ;-) But having two sources bears potential for confusion. Cheers -richy. -- Richard B. Kreckel From varg at metalica.kh.ua Fri Aug 7 22:22:18 2009 From: varg at metalica.kh.ua (Alexei Sheplyakov) Date: Fri, 7 Aug 2009 23:22:18 +0300 Subject: [GiNaC-devel] Fix the compliation error *for real* In-Reply-To: <20090731105027.2582E5B4045@cebix.net> References: <20090731105027.2582E5B4045@cebix.net> Message-ID: <20090807202158.GA16823@vargsbox.jinr.ru> Dear Jens, On Fri, Jul 31, 2009 at 12:50:26PM +0200, Jens Vollinga wrote: > commit eaf81b3115697a8e883848ace0ceb919cf443b2c > Author: Jens Vollinga > Date: Fri Jul 31 11:14:01 2009 +0200 > > Fixed cast that caused compile error on 64bit machines. Unfortunately the error is still here: libtool: compile: ccache g++-4.1 -DHAVE_CONFIG_H -I. -I../../../../work/sw/GiNaC/ginac -I../config -I/home/pc7135/varg/target/x86_64-linux-gnu/include -Wall -O2 -g -pipe -funroll-loops -ffast-math -finline-limit=1200 -m64 -march=k8 -mfpmath=sse -msse2 -MT parser.lo -MD -MP -MF .deps/parser.Tpo -c ../../../../work/sw/GiNaC/ginac/parser/parser.cpp -fPIC -DPIC -o .libs/parser.o ../../../../work/sw/GiNaC/ginac/parser/parser.cpp: In member function `GiNaC::ex GiNaC::parser::parse_identifier_expr()': ../../../../work/sw/GiNaC/ginac/parser/parser.cpp:73: error: cast from `GiNaC::ex (*)(const GiNaC::exvector&)' to `unsigned int' loses precision A simple test case: $ cat > test.cc << EOF unsigned test(const void* ptr) { return reinterpret_cast(ptr); } EOF $ g++ test.cc test.cc: In function `unsigned int test(const void*)': test.cc:3: error: cast from `const void*' to `unsigned int' loses precision I think the compiler is right since [expr.reinterpret.cast] says: "A pointer can be explicitly converted to any integral type large enough to hold it." The patch below fixes the problem. From: Alexei Sheplyakov Subject: [PATCH] Fix compilation error on 64-bit architectures for real. According to [expr.reinterpret.cast] it's not ok to convert a pointer into an integer of a different size. --- ginac/parser/parser.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/ginac/parser/parser.cpp b/ginac/parser/parser.cpp index 6ed364f..cfa313b 100644 --- a/ginac/parser/parser.cpp +++ b/ginac/parser/parser.cpp @@ -70,7 +70,8 @@ ex parser::parse_identifier_expr() // pointers. GiNaC::function* f = NULL; try { - f = new GiNaC::function(reinterpret_cast(reader->second), args); + unsigned serial = (unsigned)(unsigned long)(void *)(reader->second); + f = new GiNaC::function(serial, args); } catch ( std::runtime_error ) { if ( f ) delete f; -- 1.6.3.3 Best regards, Alexei From sergstesh at yahoo.com Sat Aug 8 01:04:46 2009 From: sergstesh at yahoo.com (Sergei Steshenko) Date: Fri, 7 Aug 2009 16:04:46 -0700 (PDT) Subject: [GiNaC-devel] Fix the compliation error *for real* In-Reply-To: <20090807202158.GA16823@vargsbox.jinr.ru> Message-ID: <148352.27339.qm@web35204.mail.mud.yahoo.com> --- On Fri, 8/7/09, Alexei Sheplyakov wrote: > From: Alexei Sheplyakov > Subject: [GiNaC-devel] Fix the compliation error *for real* > To: "GiNaC development list" > Date: Friday, August 7, 2009, 1:22 PM > Dear Jens, > > On Fri, Jul 31, 2009 at 12:50:26PM +0200, Jens Vollinga > wrote: > > > commit eaf81b3115697a8e883848ace0ceb919cf443b2c > > Author: Jens Vollinga > > Date:???Fri Jul 31 11:14:01 2009 +0200 > > > >? ???Fixed cast that caused compile > error on 64bit machines. > > Unfortunately the error is still here: > > libtool: compile:? ccache g++-4.1 -DHAVE_CONFIG_H -I. > -I../../../../work/sw/GiNaC/ginac -I../config > -I/home/pc7135/varg/target/x86_64-linux-gnu/include -Wall > -O2 -g -pipe -funroll-loops -ffast-math -finline-limit=1200 > -m64 -march=k8 -mfpmath=sse -msse2 -MT parser.lo -MD -MP -MF > .deps/parser.Tpo -c > ../../../../work/sw/GiNaC/ginac/parser/parser.cpp? > -fPIC -DPIC -o .libs/parser.o > ../../../../work/sw/GiNaC/ginac/parser/parser.cpp: In > member function `GiNaC::ex > GiNaC::parser::parse_identifier_expr()': > ../../../../work/sw/GiNaC/ginac/parser/parser.cpp:73: > error: cast from `GiNaC::ex (*)(const GiNaC::exvector&)' > to `unsigned int' loses precision > > > A simple test case: > $ cat > test.cc << EOF > unsigned test(const void* ptr) > { > ??? return > reinterpret_cast(ptr); > } > EOF > $ g++ test.cc > test.cc: In function `unsigned int test(const void*)': > test.cc:3: error: cast from `const void*' to `unsigned int' > loses precision > > > I think the compiler is right since [expr.reinterpret.cast] > says: > "A pointer can be explicitly converted to any integral type > large enough > to hold it." > > > The patch below fixes the problem. > > From: Alexei Sheplyakov > Subject: [PATCH] Fix compilation error on 64-bit > architectures for real. > > According to [expr.reinterpret.cast] it's not ok to convert > a pointer > into an integer of a different size. > > --- > ginac/parser/parser.cpp |? ? 3 ++- > 1 files changed, 2 insertions(+), 1 deletions(-) > > diff --git a/ginac/parser/parser.cpp > b/ginac/parser/parser.cpp > index 6ed364f..cfa313b 100644 > --- a/ginac/parser/parser.cpp > +++ b/ginac/parser/parser.cpp > @@ -70,7 +70,8 @@ ex parser::parse_identifier_expr() > ??? // pointers. > ??? GiNaC::function* f = NULL; > ??? try { > -??? ??? f = new > GiNaC::function(reinterpret_cast(reader->second), > args); > +??? ??? unsigned serial = > (unsigned)(unsigned long)(void *)(reader->second); > +??? ??? f = new > GiNaC::function(serial, args); > ??? } > ??? catch ( std::runtime_error ) { > ??? ??? if ( f ) delete f; > -- > 1.6.3.3 > > Best regards, > ??? Alexei > > > _______________________________________________ > GiNaC-devel mailing list > GiNaC-devel at ginac.de > https://www.cebix.net/mailman/listinfo/ginac-devel > Guys, I think a much more conceptually correct solution (even though this one works) would be to use size_t instead of unsigned long . The following links explain why: http://www.embedded.com/columns/programmingpointers/201803576 http://en.wikipedia.org/wiki/Stdlib.h#size_t http://www.cplusplus.com/reference/clibrary/cstddef/size_t/ . To put it shortly - size_t is big enough to represent output of sizeof(foo) for _any_ foo, so it is big enough to represent numeric value of _any_ pointer. Regards, Sergei. From varg at metalica.kh.ua Sat Aug 8 10:43:12 2009 From: varg at metalica.kh.ua (Alexei Sheplyakov) Date: Sat, 8 Aug 2009 11:43:12 +0300 Subject: [GiNaC-devel] Fix the compliation error *for real* ... and restore performance In-Reply-To: <20090807202158.GA16823@vargsbox.jinr.ru> References: <20090731105027.2582E5B4045@cebix.net> <20090807202158.GA16823@vargsbox.jinr.ru> Message-ID: <20090808084312.GA31113@vargsbox.jinr.ru> Hello, > Subject: [PATCH] Fix compilation error on 64-bit architectures for real. > > According to [expr.reinterpret.cast] it's not ok to convert a pointer > into an integer of a different size. [skipped the patch] Although reading user-defined classes works again it's a bit slower than it used to be. The fix is below (should be applied after the patch mentioned above). Please note: this patch is for 1.5 branch only, I'll post a different patch for the master branch. From: Alexei Sheplyakov Subject: [PATCH][GiNaC 1.5] Make the parser as fast as it used to be (before 1.5.2). Commit 8bf0597dde55e4c94a2ff39f1d8130902e3d7a9b (titled as 'Fixed the parser such that it can read in user defined classes again.') made the parser a bit slower, especially if the input contains many terms of user-defined type. The reason for that is quite simple: we throw and catch an exception every time we construct an object of user-defined type: // dirty hack to distinguish between serial numbers of functions and real // pointers. GiNaC::function* f = NULL; try { unsigned serial = (unsigned)(unsigned long)(void *)(reader->second); f = new GiNaC::function(serial, args); } catch ( std::runtime_error ) { if ( f ) delete f; ex ret = reader->second(args); return ret; } Fortunately functions are aligned and we can use much more efficient technique to distinguish between serial and pointers to functions. --- ginac/parser/default_reader.tpl | 55 ++++++++++++++++++++++++++++---------- ginac/parser/parser.cpp | 47 ++++++++++++++++++++++++--------- 2 files changed, 74 insertions(+), 28 deletions(-) diff --git a/ginac/parser/default_reader.tpl b/ginac/parser/default_reader.tpl index 5f83cfe..2018e04 100644 --- a/ginac/parser/default_reader.tpl +++ b/ginac/parser/default_reader.tpl @@ -19,6 +19,12 @@ COMMENT a part of GiNaC parser -- construct functions from a byte stream. #include "power.h" #include "operators.h" #include "inifcns.h" +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#ifdef HAVE_STDINT_H +#include // for uintptr_t +#endif namespace GiNaC { @@ -31,6 +37,31 @@ static ex [+ (get "name") +]_reader(const exvector& ev) (format '#f "~{ev[~a]~^, ~}" (sequence 0 (- nargs 1)))) +]); }[+ ENDFOR +] +// function::registered_functions() is protected, but we need to access it +class registered_functions_hack : public function +{ +public: + static const std::vector& get_registered_functions() + { + return function::registered_functions(); + } +private: + registered_functions_hack(); + registered_functions_hack(const registered_functions_hack&); + registered_functions_hack& operator=(const registered_functions_hack&); +}; + +// Encode an integer into a pointer to a function. Since functions +// are aligned (the minimal alignment depends on CPU architecture) +// we can distinguish between pointers and integers. +static reader_func encode_serial_as_reader_func(unsigned serial) +{ + uintptr_t u = (uintptr_t)serial; + u = (u << 1) | (uintptr_t)1; + reader_func ptr = reinterpret_cast((void *)u); + return ptr; +} + const prototype_table& get_default_reader() { using std::make_pair; @@ -42,22 +73,16 @@ const prototype_table& get_default_reader() (if (exist? "args") (get "args") "1") +])] = [+ (get "name") +]_reader;[+ ENDFOR +] - try { - for ( unsigned ser=0; ; ++ser ) { - GiNaC::function f(ser); - std::string name = f.get_name(); - for ( std::size_t nargs=0; ; ++nargs ) { - try { - function::find_function(name, nargs); - prototype proto = std::pair(name, nargs); - std::pair ins = reader.insert(std::pair(proto, (reader_func)ser)); - if ( ins.second ) break; - } - catch ( std::runtime_error ) { } - } - } + std::vector::const_iterator it = + registered_functions_hack::get_registered_functions().begin(); + std::vector::const_iterator end = + registered_functions_hack::get_registered_functions().end(); + unsigned serial = 0; + for (; it != end; ++it) { + prototype proto = make_pair(it->get_name(), it->get_nparams()); + reader[proto] = encode_serial_as_reader_func(serial); + ++serial; } - catch ( std::runtime_error ) { } initialized = true; } return reader; diff --git a/ginac/parser/parser.cpp b/ginac/parser/parser.cpp index cfa313b..acf5f3d 100644 --- a/ginac/parser/parser.cpp +++ b/ginac/parser/parser.cpp @@ -32,6 +32,36 @@ namespace GiNaC { +// +// Find out if ptr is a pointer to a function or a specially crafted integer. +// It's possible to distinguish between these because functions are aligned. +// Returns true if ptr is a pointer and false otherwise. +static bool decode_serial(unsigned& serial, const reader_func ptr) +{ + uintptr_t u = (uintptr_t)(void *)ptr; + if (u & 1) { + u >>= 1; + serial = (unsigned)u; + return false; + } + return true; +} + +// Figures out if ptr is a pointer to function or a serial of GiNaC function. +// In the former case calls that function, in the latter case constructs +// GiNaC function with corresponding serial and arguments. +static ex dispatch_reader_fcn(const reader_func ptr, const exvector& args) +{ + unsigned serial = 0; // dear gcc, could you please shut up? + bool is_ptr = decode_serial(serial, ptr); + if (is_ptr) + return ptr(args); + else + return function(serial, args); +} +// + + /// identifier_expr: identifier | identifier '(' expression* ')' ex parser::parse_identifier_expr() { @@ -66,19 +96,10 @@ ex parser::parse_identifier_expr() Parse_error_("no function \"" << name << "\" with " << args.size() << " arguments"); } - // dirty hack to distinguish between serial numbers of functions and real - // pointers. - GiNaC::function* f = NULL; - try { - unsigned serial = (unsigned)(unsigned long)(void *)(reader->second); - f = new GiNaC::function(serial, args); - } - catch ( std::runtime_error ) { - if ( f ) delete f; - ex ret = reader->second(args); - return ret; - } - return f->setflag(status_flags::dynallocated); + // reader->second might be a pointer to a C++ function or a specially + // crafted serial of a GiNaC::function. + ex ret = dispatch_reader_fcn(reader->second, args); + return ret; } /// paren_expr: '(' expression ')' -- 1.6.3.3 Best regards, Alexei From varg at metalica.kh.ua Sat Aug 8 10:45:16 2009 From: varg at metalica.kh.ua (Alexei Sheplyakov) Date: Sat, 8 Aug 2009 11:45:16 +0300 Subject: [GiNaC-devel] Fix the compliation error *for real* In-Reply-To: <148352.27339.qm@web35204.mail.mud.yahoo.com> References: <20090807202158.GA16823@vargsbox.jinr.ru> <148352.27339.qm@web35204.mail.mud.yahoo.com> Message-ID: <20090808084516.GA29873@vargsbox.jinr.ru> Hello, On Fri, Aug 07, 2009 at 04:04:46PM -0700, Sergei Steshenko wrote: > Guys, I think a much more conceptually correct solution (even though this > one works) would be to use > > size_t > > instead of > > unsigned long > . The politically correct type is uintptr_t. And (AFAIK) the sizeof(size_t) is NOT guaranteed to be the same as sizeof(void*). And on any sane platform sizeof(long) == sizeof(void*) anyway. Best regards, Alexei From varg at metalica.kh.ua Sat Aug 8 12:02:47 2009 From: varg at metalica.kh.ua (Alexei Sheplyakov) Date: Sat, 8 Aug 2009 13:02:47 +0300 Subject: [GiNaC-devel] [PATCH 1/6] G_eval: fix incorrect use of STL iterator. Message-ID: <20090808100247.GA895@vargsbox.jinr.ru> According to [lib.bidirectional.iterators] it's not OK to decrement an iterator pointing to the beginning of the sequence. Fortunately random access iterators provided by (current versions of) gcc/libstdc++ don't have this silly limitation, so the code which works with pointers works with iterators without any changes at all. However, - there's no guarantee that the current behavior won't change in the future - some non-GNU compilers are not that smart (i.e. the program segfaults upon when decrementing beginning-of-the-sequence iterator). --- ginac/inifcns_nstdsums.cpp | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ginac/inifcns_nstdsums.cpp b/ginac/inifcns_nstdsums.cpp index 2c4061a..b410533 100644 --- a/ginac/inifcns_nstdsums.cpp +++ b/ginac/inifcns_nstdsums.cpp @@ -569,11 +569,12 @@ ex G_eval(const Gparameter& a, int scale, const exvector& gsyms) Gparameter newa; Gparameter::const_iterator it2 = short_a.begin(); - for (--it2; it2 != it;) { - ++it2; + for (; it2 != it; ++it2) { newa.push_back(*it2); } + newa.push_back(*it); newa.push_back(a[0]); + it2 = it; ++it2; for (; it2 != short_a.end(); ++it2) { newa.push_back(*it2); -- 1.6.3.3 From varg at metalica.kh.ua Sat Aug 8 12:03:15 2009 From: varg at metalica.kh.ua (Alexei Sheplyakov) Date: Sat, 8 Aug 2009 13:03:15 +0300 Subject: [GiNaC-devel] [PATCH 3/6] modular_matrix: don't use STL iterators in {mul, sub}_col and friends. Message-ID: <20090808100315.GA1068@vargsbox.jinr.ru> Not using STL iterators makes the code simpler and cleaner. Also we don't have to argue whether the standard ([lib.random.access.iterators]) imposes any pre/post-condictions on operator+=. --- ginac/factor.cpp | 60 ++++++++++++++++++++--------------------------------- 1 files changed, 23 insertions(+), 37 deletions(-) diff --git a/ginac/factor.cpp b/ginac/factor.cpp index 2f9157b..c82e744 100644 --- a/ginac/factor.cpp +++ b/ginac/factor.cpp @@ -691,90 +691,76 @@ public: cl_MI operator()(size_t row, size_t col) const { return m[row*c + col]; } void mul_col(size_t col, const cl_MI x) { - mvec::iterator i = m.begin() + col; for ( size_t rc=0; rc::iterator i = m.begin() + row*c; for ( size_t cc=0; cc::iterator i1 = m.begin() + row1*c; - vector::iterator i2 = m.begin() + row2*c; for ( size_t cc=0; cc::iterator i1 = m.begin() + row1*c; - vector::iterator i2 = m.begin() + row2*c; for ( size_t cc=0; cc& newrow) { - mvec::iterator i1 = m.begin() + row*c; - mvec::const_iterator i2 = newrow.begin(), end = newrow.end(); - for ( ; i2 != end; ++i1, ++i2 ) { - *i1 = *i2; + for (std::size_t i2 = 0; i2 < newrow.size(); ++i2) { + std::size_t i1 = row*c + i2; + m[i1] = newrow[i2]; } } mvec::const_iterator row_begin(size_t row) const { return m.begin()+row*c; } -- 1.6.3.3 From varg at metalica.kh.ua Sat Aug 8 12:03:38 2009 From: varg at metalica.kh.ua (Alexei Sheplyakov) Date: Sat, 8 Aug 2009 13:03:38 +0300 Subject: [GiNaC-devel] [PATCH 5/6] ncmul::eval(): don't write beyond the end of the vector. Message-ID: <20090808100338.GA1164@vargsbox.jinr.ru> --- ginac/ncmul.cpp | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ginac/ncmul.cpp b/ginac/ncmul.cpp index 0c22a81..fff307d 100644 --- a/ginac/ncmul.cpp +++ b/ginac/ncmul.cpp @@ -339,15 +339,15 @@ ex ncmul::eval(int level) const if (assocseq.empty()) return _ex1; // determine return types - unsignedvector rettypes; - rettypes.reserve(assocseq.size()); + unsignedvector rettypes(assocseq.size()); size_t i = 0; size_t count_commutative=0; size_t count_noncommutative=0; size_t count_noncommutative_composite=0; cit = assocseq.begin(); citend = assocseq.end(); while (cit != citend) { - switch (rettypes[i] = cit->return_type()) { + rettypes[i] = cit->return_type(); + switch (rettypes[i]) { case return_types::commutative: count_commutative++; break; -- 1.6.3.3 From varg at metalica.kh.ua Sat Aug 8 12:03:48 2009 From: varg at metalica.kh.ua (Alexei Sheplyakov) Date: Sat, 8 Aug 2009 13:03:48 +0300 Subject: [GiNaC-devel] [PATCH 6/6] shaker_sort, permutation_sign: fix invalid use of STL iterators. Message-ID: <20090808100348.GA1207@vargsbox.jinr.ru> According to the standard incrementing end(), and decrementing begin() are ill-defined operations (see [lib.forward.iterators], [lib.bidirectional.iterators]). --- ginac/utils.h | 24 ++++++++++++++++++------ 1 files changed, 18 insertions(+), 6 deletions(-) diff --git a/ginac/utils.h b/ginac/utils.h index 393c474..e65bdae 100644 --- a/ginac/utils.h +++ b/ginac/utils.h @@ -128,7 +128,9 @@ int permutation_sign(It first, It last) sign = -sign; } else if (!(*other < *i)) return 0; - --i; --other; + --i; + if (i != first) + --other; } if (!swapped) return sign; @@ -147,7 +149,9 @@ int permutation_sign(It first, It last) sign = -sign; } else if (!(*i < *other)) return 0; - ++i; ++other; + ++i; + if (i != last) + ++other; } if (!swapped) return sign; @@ -181,7 +185,9 @@ int permutation_sign(It first, It last, Cmp comp, Swap swapit) sign = -sign; } else if (!comp(*other, *i)) return 0; - --i; --other; + --i; + if (i != first) + --other; } if (!swapped) return sign; @@ -200,7 +206,9 @@ int permutation_sign(It first, It last, Cmp comp, Swap swapit) sign = -sign; } else if (!comp(*i, *other)) return 0; - ++i; ++other; + ++i; + if (i != last) + ++other; } if (!swapped) return sign; @@ -232,7 +240,9 @@ void shaker_sort(It first, It last, Cmp comp, Swap swapit) flag = other; swapped = true; } - --i; --other; + --i; + if (i != first) + --other; } if (!swapped) return; @@ -249,7 +259,9 @@ void shaker_sort(It first, It last, Cmp comp, Swap swapit) flag = other; swapped = true; } - ++i; ++other; + ++i; + if (i != last) + ++other; } if (!swapped) return; -- 1.6.3.3 From varg at metalica.kh.ua Sat Aug 8 12:06:36 2009 From: varg at metalica.kh.ua (Alexei Sheplyakov) Date: Sat, 8 Aug 2009 13:06:36 +0300 Subject: [GiNaC-devel] [PATCH 2/6] check_parameter_G: fix pontential increment of end(). Message-ID: <20090808100636.GA1332@vargsbox.jinr.ru> Incrementing past-the-end iterator is not permitted by the standard, see [lib.input.iterators]. --- ginac/inifcns_nstdsums.cpp | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/ginac/inifcns_nstdsums.cpp b/ginac/inifcns_nstdsums.cpp index b410533..11a91dd 100644 --- a/ginac/inifcns_nstdsums.cpp +++ b/ginac/inifcns_nstdsums.cpp @@ -659,6 +659,8 @@ Gparameter::const_iterator check_parameter_G(const Gparameter& a, int scale, ++trailing_zeros; } } + if (lastnonzero == a.end()) + return a.end(); return ++lastnonzero; } -- 1.6.3.3 From varg at metalica.kh.ua Sat Aug 8 12:07:14 2009 From: varg at metalica.kh.ua (Alexei Sheplyakov) Date: Sat, 8 Aug 2009 13:07:14 +0300 Subject: [GiNaC-devel] [PATCH 4/6] symmetry::calchash(): be careful to not dereference past-the-end iterator. Message-ID: <20090808100714.GA1450@vargsbox.jinr.ru> --- ginac/symmetry.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/ginac/symmetry.cpp b/ginac/symmetry.cpp index 9e00a8c..725506f 100644 --- a/ginac/symmetry.cpp +++ b/ginac/symmetry.cpp @@ -190,7 +190,8 @@ unsigned symmetry::calchash() const if (type == none) { v = rotate_left(v); - v ^= *(indices.begin()); + if (!indices.empty()) + v ^= *(indices.begin()); } else { for (exvector::const_iterator i=children.begin(); i!=children.end(); ++i) { -- 1.6.3.3 From sergstesh at yahoo.com Sat Aug 8 14:04:59 2009 From: sergstesh at yahoo.com (Sergei Steshenko) Date: Sat, 8 Aug 2009 05:04:59 -0700 (PDT) Subject: [GiNaC-devel] Fix the compliation error *for real* In-Reply-To: <20090808084516.GA29873@vargsbox.jinr.ru> Message-ID: <361100.15895.qm@web35203.mail.mud.yahoo.com> --- On Sat, 8/8/09, Alexei Sheplyakov wrote: > From: Alexei Sheplyakov > Subject: Re: [GiNaC-devel] Fix the compliation error *for real* > To: "GiNaC development list" > Date: Saturday, August 8, 2009, 1:45 AM > Hello, > > On Fri, Aug 07, 2009 at 04:04:46PM -0700, Sergei Steshenko > wrote: > > Guys, I think a much more conceptually correct > solution (even though this > > one works) would be to use > > > > size_t > > > > instead of > > > > unsigned long > > . > > The politically correct type is uintptr_t. And (AFAIK) the > sizeof(size_t) is > NOT guaranteed to be the same as sizeof(void*). And on any > sane platform > sizeof(long) == sizeof(void*) anyway. > > Best regards, > ??? Alexei > _______________________________________________ Alexei, this is what http://www.cplusplus.com/reference/clibrary/cstddef/size_t/ says: " size_t corresponds to the integral data type returned by the language operator sizeof and is defined in the header file (among others) as an unsigned integral type. It expresses a size or count in bytes. ". Please note that 'sizeof' argument is _not_ mentioned, and it makes sense. My logic us that since size_t is is good for _any_ object, it is good for any array A, including the array occupying the whole address space. Here is the same interpretation: http://www.viva64.com/terminology/size_t.html : " size_t. A basic unsigned integer C/C++ type. The type?s size is chosen in such a way as to allow you to write the maximum size of a theoretically possible array into it. On a 32-bit system size_t will take 32 bits and on a 64-bit one ? 64 bits. In other words, a pointer can be safely put inside size_t type (an exception is class-function-pointers but this is a special case). size_t type is usually used for loop, array indexing, size storage and address arithmetic counters. In some cases using size_t type is more effective and safe than using a more habitual for the programmer unsigned type. " - please not the " In other words, a pointer can be safely put inside size_t type (an exception is class-function-pointers but this is a special case). size_t type is usually used for loop, array indexing, size storage and address arithmetic counters. " part. Regards, Sergei. From jensv at nikhef.nl Sun Aug 9 22:21:53 2009 From: jensv at nikhef.nl (Jens Vollinga) Date: Sun, 09 Aug 2009 22:21:53 +0200 Subject: [GiNaC-devel] [PATCH 5/6] ncmul::eval(): don't write beyond the end of the vector. In-Reply-To: <20090808100338.GA1164@vargsbox.jinr.ru> References: <20090808100338.GA1164@vargsbox.jinr.ru> Message-ID: <4A7F2FE1.3070909@nikhef.nl> Hi Alexei, I don't quite understand this patch (at least not in connection to its description). Yes, it improves the allocation, and then it does something that looks as if someone prefers to program in Python ... Is this the intent and the message is just wrong? Regards, Jens Alexei Sheplyakov schrieb: > --- > ginac/ncmul.cpp | 6 +++--- > 1 files changed, 3 insertions(+), 3 deletions(-) > > diff --git a/ginac/ncmul.cpp b/ginac/ncmul.cpp > index 0c22a81..fff307d 100644 > --- a/ginac/ncmul.cpp > +++ b/ginac/ncmul.cpp > @@ -339,15 +339,15 @@ ex ncmul::eval(int level) const > if (assocseq.empty()) return _ex1; > > // determine return types > - unsignedvector rettypes; > - rettypes.reserve(assocseq.size()); > + unsignedvector rettypes(assocseq.size()); > size_t i = 0; > size_t count_commutative=0; > size_t count_noncommutative=0; > size_t count_noncommutative_composite=0; > cit = assocseq.begin(); citend = assocseq.end(); > while (cit != citend) { > - switch (rettypes[i] = cit->return_type()) { > + rettypes[i] = cit->return_type(); > + switch (rettypes[i]) { > case return_types::commutative: > count_commutative++; > break; From git at ginac.de Sun Aug 9 23:36:50 2009 From: git at ginac.de (Jens Vollinga) Date: Sun, 9 Aug 2009 23:36:50 +0200 (CEST) Subject: [GiNaC-devel] [SCM] GiNaC -- a C++ library for symbolic computations branch, ginac_1-5, updated. release_1-4-0-210-g3f1026f Message-ID: <20090809213651.344B35B403F@cebix.net> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GiNaC -- a C++ library for symbolic computations". The branch, ginac_1-5 has been updated via 3f1026f0540e4e7ab86656389d09c2152269e6cf (commit) via ab8da4fe0687969d124c2c3b3e6ce62a63376a0a (commit) via dd19b7316b6eba5c49b6a4fb3503c504ec6c866a (commit) via 7f4a4ce46d799ba888b118dfdc8945c92a6c6d6f (commit) via 4ddeb4c2a625a069d71b510aab3ae53138670470 (commit) via 99c7ff6b72691f2eff30f94934d65d1ba7136ff9 (commit) via 554722426543a6e1445ead11167107a69fd21af9 (commit) via aa1afbbdb118846cfc266a1d7a8d5188ac214e0e (commit) via 14aeeca161c7cc2d145b0778ac234341068efef1 (commit) from 5252d38313c423465b9bc37b0618cb8de96d0d4e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3f1026f0540e4e7ab86656389d09c2152269e6cf Author: Alexei Sheplyakov Date: Sat Aug 8 13:03:15 2009 +0300 modular_matrix: don't use STL iterators in {mul, sub}_col and friends. Not using STL iterators makes the code simpler and cleaner. Also we don't have to argue whether the standard ([lib.random.access.iterators]) imposes any pre/post-condictions on operator+=. (cherry picked from commit 59ec13895c97ffd74979a0b811a7571f6de56386) commit ab8da4fe0687969d124c2c3b3e6ce62a63376a0a Author: Jens Vollinga Date: Sun Aug 9 23:38:48 2009 +0200 Added get_builtin_reader() that parses only the builtin GiNaC functions and pow, sqrt, and power. commit dd19b7316b6eba5c49b6a4fb3503c504ec6c866a Author: Jens Vollinga Date: Sun Aug 9 23:27:10 2009 +0200 Fixed include of stdint.h (parser.cpp needs the header as well). commit 7f4a4ce46d799ba888b118dfdc8945c92a6c6d6f Author: Alexei Sheplyakov Date: Sat Aug 8 13:03:48 2009 +0300 shaker_sort, permutation_sign: fix invalid use of STL iterators. According to the standard incrementing end(), and decrementing begin() are ill-defined operations (see [lib.forward.iterators], [lib.bidirectional.iterators]). (cherry picked from commit 694f839947982f5b12b6c629d5bab522c801630d) commit 4ddeb4c2a625a069d71b510aab3ae53138670470 Author: Alexei Sheplyakov Date: Sat Aug 8 13:07:14 2009 +0300 symmetry::calchash(): be careful to not dereference past-the-end iterator. (cherry picked from commit 526825bcee294cb20e37d8db6d5040ba0f8c428f) commit 99c7ff6b72691f2eff30f94934d65d1ba7136ff9 Author: Alexei Sheplyakov Date: Sat Aug 8 13:06:36 2009 +0300 check_parameter_G: fix pontential increment of end(). Incrementing past-the-end iterator is not permitted by the standard, see [lib.input.iterators]. (cherry picked from commit 49a44f7d55ec0d6686d3c32c7081a07d10c93274) commit 554722426543a6e1445ead11167107a69fd21af9 Author: Alexei Sheplyakov Date: Sat Aug 8 13:02:47 2009 +0300 G_eval: fix incorrect use of STL iterator. According to [lib.bidirectional.iterators] it's not OK to decrement an iterator pointing to the beginning of the sequence. Fortunately random access iterators provided by (current versions of) gcc/libstdc++ don't have this silly limitation, so the code which works with pointers works with iterators without any changes at all. However, - there's no guarantee that the current behavior won't change in the future - some non-GNU compilers are not that smart (i.e. the program segfaults upon when decrementing beginning-of-the-sequence iterator). (cherry picked from commit dda45abd8a2c408f8b3eb7959a10dfb2468ecc3a) commit aa1afbbdb118846cfc266a1d7a8d5188ac214e0e Author: Alexei Sheplyakov Date: Sat Aug 8 11:43:12 2009 +0300 Fix the compliation error *for real* ... and restore performance Commit 8bf0597dde55e4c94a2ff39f1d8130902e3d7a9b (titled as 'Fixed the parser such that it can read in user defined classes again.') made the parser a bit slower, especially if the input contains many terms of user-defined type. The reason for that is quite simple: we throw and catch an exception every time we construct an object of user-defined type: // dirty hack to distinguish between serial numbers of functions and real // pointers. GiNaC::function* f = NULL; try { unsigned serial = (unsigned)(unsigned long)(void *)(reader->second); f = new GiNaC::function(serial, args); } catch ( std::runtime_error ) { if ( f ) delete f; ex ret = reader->second(args); return ret; } Fortunately functions are aligned and we can use much more efficient technique to distinguish between serial and pointers to functions. commit 14aeeca161c7cc2d145b0778ac234341068efef1 Author: Alexei Sheplyakov Date: Fri Aug 7 23:22:18 2009 +0300 Fix the compliation error *for real* ----------------------------------------------------------------------- Summary of changes: ginac/factor.cpp | 60 +++++++++-------------- ginac/inifcns_nstdsums.cpp | 7 ++- ginac/parser/default_reader.tpl | 104 +++++++++++++++++++++++++++++++++------ ginac/parser/parse_context.h | 14 +++++- ginac/parser/parser.cpp | 46 +++++++++++++----- ginac/symmetry.cpp | 3 +- ginac/utils.h | 24 +++++++-- 7 files changed, 183 insertions(+), 75 deletions(-) hooks/post-receive -- GiNaC -- a C++ library for symbolic computations From git at ginac.de Sun Aug 9 23:36:51 2009 From: git at ginac.de (Jens Vollinga) Date: Sun, 9 Aug 2009 23:36:51 +0200 (CEST) Subject: [GiNaC-devel] [SCM] GiNaC -- a C++ library for symbolic computations branch, master, updated. release_1-4-0-197-g59ec138 Message-ID: <20090809213651.9D2F95B403E@cebix.net> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GiNaC -- a C++ library for symbolic computations". The branch, master has been updated via 59ec13895c97ffd74979a0b811a7571f6de56386 (commit) via 694f839947982f5b12b6c629d5bab522c801630d (commit) via 526825bcee294cb20e37d8db6d5040ba0f8c428f (commit) via 49a44f7d55ec0d6686d3c32c7081a07d10c93274 (commit) via dda45abd8a2c408f8b3eb7959a10dfb2468ecc3a (commit) from 619879b5bd86a99334affe1f05d17616cc2c1898 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 59ec13895c97ffd74979a0b811a7571f6de56386 Author: Alexei Sheplyakov Date: Sat Aug 8 13:03:15 2009 +0300 modular_matrix: don't use STL iterators in {mul, sub}_col and friends. Not using STL iterators makes the code simpler and cleaner. Also we don't have to argue whether the standard ([lib.random.access.iterators]) imposes any pre/post-condictions on operator+=. commit 694f839947982f5b12b6c629d5bab522c801630d Author: Alexei Sheplyakov Date: Sat Aug 8 13:03:48 2009 +0300 shaker_sort, permutation_sign: fix invalid use of STL iterators. According to the standard incrementing end(), and decrementing begin() are ill-defined operations (see [lib.forward.iterators], [lib.bidirectional.iterators]). commit 526825bcee294cb20e37d8db6d5040ba0f8c428f Author: Alexei Sheplyakov Date: Sat Aug 8 13:07:14 2009 +0300 symmetry::calchash(): be careful to not dereference past-the-end iterator. commit 49a44f7d55ec0d6686d3c32c7081a07d10c93274 Author: Alexei Sheplyakov Date: Sat Aug 8 13:06:36 2009 +0300 check_parameter_G: fix pontential increment of end(). Incrementing past-the-end iterator is not permitted by the standard, see [lib.input.iterators]. commit dda45abd8a2c408f8b3eb7959a10dfb2468ecc3a Author: Alexei Sheplyakov Date: Sat Aug 8 13:02:47 2009 +0300 G_eval: fix incorrect use of STL iterator. According to [lib.bidirectional.iterators] it's not OK to decrement an iterator pointing to the beginning of the sequence. Fortunately random access iterators provided by (current versions of) gcc/libstdc++ don't have this silly limitation, so the code which works with pointers works with iterators without any changes at all. However, - there's no guarantee that the current behavior won't change in the future - some non-GNU compilers are not that smart (i.e. the program segfaults upon when decrementing beginning-of-the-sequence iterator). ----------------------------------------------------------------------- Summary of changes: ginac/factor.cpp | 60 +++++++++++++++++--------------------------- ginac/inifcns_nstdsums.cpp | 7 +++- ginac/symmetry.cpp | 3 +- ginac/utils.h | 24 +++++++++++++---- 4 files changed, 48 insertions(+), 46 deletions(-) hooks/post-receive -- GiNaC -- a C++ library for symbolic computations From varg at metalica.kh.ua Mon Aug 10 07:41:39 2009 From: varg at metalica.kh.ua (Alexei Sheplyakov) Date: Mon, 10 Aug 2009 08:41:39 +0300 Subject: [GiNaC-devel] [PATCH 5/6] ncmul::eval(): don't write beyond the end of the vector. In-Reply-To: <4A7F2FE1.3070909@nikhef.nl> References: <20090808100338.GA1164@vargsbox.jinr.ru> <4A7F2FE1.3070909@nikhef.nl> Message-ID: <20090810054139.GA4606@metalica.kh.ua> Hi Jens, On Sun, Aug 09, 2009 at 10:21:53PM +0200, Jens Vollinga wrote: > Yes, it improves the allocation, unsignedvector rettypes; // rettypes.size() == 0 rettypes.reserve(assocseq.size()); // rettypes.size() == 0 since reserve() does NOT change the size of a vector. rettypes[i] = cit->return_type(); // Illegal according to the standard. Appears to work with some implementations // and segfault with others (i.e. m$vc) So the patch does fix the access beyond the vector boundary (as the commit message implies). > and then it does something that looks as if someone prefers to program > in Python ... I guess you mean this hunk: > - switch (rettypes[i] = cit->return_type()) { > + rettypes[i] = cit->return_type(); > + switch (rettypes[i]) { It makes code less obscure (IMNSHO), but it's not strictly necessary. Feel free to skip it. Best regards, Alexei From jensv at nikhef.nl Mon Aug 10 11:23:11 2009 From: jensv at nikhef.nl (Jens Vollinga) Date: Mon, 10 Aug 2009 11:23:11 +0200 Subject: [GiNaC-devel] [PATCH 5/6] ncmul::eval(): don't write beyond the end of the vector. In-Reply-To: <20090810054139.GA4606@metalica.kh.ua> References: <20090808100338.GA1164@vargsbox.jinr.ru> <4A7F2FE1.3070909@nikhef.nl> <20090810054139.GA4606@metalica.kh.ua> Message-ID: <4A7FE6FF.1090701@nikhef.nl> Hi Alexei, Alexei Sheplyakov schrieb: > rettypes.reserve(assocseq.size()); > // rettypes.size() == 0 since reserve() does NOT change the size of a vector. > rettypes[i] = cit->return_type(); > // Illegal according to the standard. Appears to work with some implementations > // and segfault with others (i.e. m$vc) > > So the patch does fix the access beyond the vector boundary (as the commit > message implies). oops, yes, sorry, I was confusing reserve with resize ... Thanks for all the patches. Is there something else you would want to see in 1.5.4? Otherwise I'll do a release soon. Regards, Jens From git at ginac.de Mon Aug 10 11:18:44 2009 From: git at ginac.de (Jens Vollinga) Date: Mon, 10 Aug 2009 11:18:44 +0200 (CEST) Subject: [GiNaC-devel] [SCM] GiNaC -- a C++ library for symbolic computations branch, ginac_1-5, updated. release_1-4-0-211-g7a2ac48 Message-ID: <20090810091845.38C665B4049@cebix.net> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GiNaC -- a C++ library for symbolic computations". The branch, ginac_1-5 has been updated via 7a2ac48810afb303e1580afb6266876dda3c5da0 (commit) from 3f1026f0540e4e7ab86656389d09c2152269e6cf (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7a2ac48810afb303e1580afb6266876dda3c5da0 Author: Alexei Sheplyakov Date: Sat Aug 8 13:03:38 2009 +0300 ncmul::eval(): don't write beyond the end of the vector. ----------------------------------------------------------------------- Summary of changes: ginac/ncmul.cpp | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) hooks/post-receive -- GiNaC -- a C++ library for symbolic computations From varg at metalica.kh.ua Mon Aug 10 20:03:41 2009 From: varg at metalica.kh.ua (Alexei Sheplyakov) Date: Mon, 10 Aug 2009 21:03:41 +0300 Subject: [GiNaC-devel] commit dd19b7316b6eba5c49b6a4fb3503c504ec6c866a In-Reply-To: <20090809213651.344B35B403F@cebix.net> References: <20090809213651.344B35B403F@cebix.net> Message-ID: <20090810180302.GA21115@vargsbox.jinr.ru> Hi Jens, On Sun, Aug 09, 2009 at 11:36:50PM +0200, Jens Vollinga wrote: > commit dd19b7316b6eba5c49b6a4fb3503c504ec6c866a > Author: Jens Vollinga > Date: Sun Aug 9 23:27:10 2009 +0200 > > Fixed include of stdint.h (parser.cpp needs the header as well). I'm afraid this commit is a bit wrong. diff --git a/ginac/parser/parse_context.h b/ginac/parser/parse_context.h index 47b150c..37e08aa 100644 --- a/ginac/parser/parse_context.h +++ b/ginac/parser/parse_context.h @@ -30,6 +30,12 @@ #include #include #include +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#ifdef HAVE_STDINT_H +#include // for uintptr_t +#endif This is a public header, and we shouldn't avoid using any HAVE_* macros (and config.h header) there. A software using libginac can define HAVE_* macros in its own config.h (and in a different way), as a result either GiNaC or that package (or both) might be very confused. Please #include config.h (and stdint.h) in each source file which needs it (specifically, parser.cpp and default_reader.tpl). Best regards, Alexei From varg at metalica.kh.ua Mon Aug 10 21:22:52 2009 From: varg at metalica.kh.ua (Alexei Sheplyakov) Date: Mon, 10 Aug 2009 22:22:52 +0300 Subject: [GiNaC-devel] [PATCH] Fix get_builtin_reader() and make it a bit simpler. Message-ID: <20090810192252.GA7627@vargsbox.jinr.ru> The code below seems to be too incorrect or at least too fragile enum { log, exp, // skipped NFUNCTIONS }; std::vector::const_iterator it = registered_functions_hack::get_registered_functions().begin(); unsigned serial = 0; for ( ; serialget_name(), it->get_nparams()); reader[proto] = encode_serial_as_reader_func(serial); } What happens if a user-defined function(s) get registered *before* "official" ones (so serials of built-in functions won't start from 0)? This can easily happen because the order of initialization in different compilation units is implementation defined. Or someone adds a built-in function and inserts REGISTER_FUNCTION_*P between REGISTER_FUNCTION_1P(log, ...) and REGISTER_FUNCTION_1P(exp, ...)? Or compiler decides to swap REGISTER_FUNCTION_1P(log, ...) and REGISTER_FUNCTION_1P(exp, ...)? The fix is simple: don't fiddle with serials, use the old (pre 1.5.2) approach, that is, let autogen produce the `reader functions' and use them to make a prototype_table. --- ginac/parser/builtin_fcns.def | 84 ++++++++++++++++++++++++++++++++++++++- ginac/parser/default_reader.tpl | 56 ++++---------------------- 2 files changed, 92 insertions(+), 48 deletions(-) diff --git a/ginac/parser/builtin_fcns.def b/ginac/parser/builtin_fcns.def index 96cd0a2..a7379d0 100644 --- a/ginac/parser/builtin_fcns.def +++ b/ginac/parser/builtin_fcns.def @@ -1,14 +1,96 @@ Autogen definitions ginacfcns; +function = { name = "log"; }; +function = { name = "exp"; }; +function = { name = "sin"; }; +function = { name = "cos"; }; +function = { name = "tan"; }; +function = { name = "asin"; }; +function = { name = "acos"; }; +function = { name = "atan"; }; + +function = { name = "sinh"; }; +function = { name = "cosh"; }; +function = { name = "tanh"; }; +function = { name = "asinh"; }; +function = { name = "acosh"; }; +function = { name = "atanh"; }; + +function = { + name = "atan2"; + args = 2; +}; + +function = { + name = "Li2"; + comment = "Dilogarithm"; +}; + +function = { + name = "Li3"; + comment = "Trilogarithm"; +}; + +function = { + name = "zetaderiv"; + comment = "Derivatives of Riemann's Zeta-function"; + args = 2; +}; + +function = { + name = "Li"; + args = 2; + comment = "Polylogarithm and multiple polylogarithm"; +}; + +function = { + name = "S"; + args = 3; + comment = "Nielsen's generalized polylogarithm"; +}; + +function = { + name = "H"; + args = 2; + comment = "Harmonic polylogarithm"; +}; + +function = { name = "lgamma"; }; +function = { name = "tgamma"; }; + +function = { + name = "beta"; + args = 2; + comment = "Beta-function"; +}; + +function = { name = "factorial"; }; + +function = { + name = "binomial"; + args = 2; +}; + +function = { + name = "Order"; + comment = "Order term function (for truncated power series)"; +}; + /* Thease are not functions, but anyway ... */ -function = { name = "sqrt"; }; +function = { + name = "sqrt"; + quasi = 1; +}; function = { name = "pow"; args = 2; + quasi = 1; }; function = { name = "power"; args = 2; + quasi = 1; }; + diff --git a/ginac/parser/default_reader.tpl b/ginac/parser/default_reader.tpl index e65802a..32f20f4 100644 --- a/ginac/parser/default_reader.tpl +++ b/ginac/parser/default_reader.tpl @@ -62,10 +62,10 @@ const prototype_table& get_default_reader() static bool initialized = false; static prototype_table reader; if (!initialized) { - [+ FOR function +] + [+ FOR function +][+ IF (exist? "quasi") +] reader[make_pair("[+ (get "name") +]", [+ (if (exist? "args") (get "args") "1") - +])] = [+ (get "name") +]_reader;[+ + +])] = [+ (get "name") +]_reader;[+ ENDIF +][+ ENDFOR +] std::vector::const_iterator it = registered_functions_hack::get_registered_functions().begin(); @@ -87,51 +87,13 @@ const prototype_table& get_builtin_reader() using std::make_pair; static bool initialized = false; static prototype_table reader; - if (!initialized) { - [+ FOR function +] - reader[make_pair("[+ (get "name") +]", [+ - (if (exist? "args") (get "args") "1") - +])] = [+ (get "name") +]_reader;[+ - ENDFOR +] - enum { - log, - exp, - sin, - cos, - tan, - asin, - acos, - atan, - sinh, - cosh, - tanh, - asinh, - acosh, - atanh, - atan2, - Li2, - Li3, - zetaderiv, - Li, - S, - H, - lgamma, - tgamma, - beta, - factorial, - binomial, - Order, - NFUNCTIONS - }; - std::vector::const_iterator it = - registered_functions_hack::get_registered_functions().begin(); - unsigned serial = 0; - for ( ; serialget_name(), it->get_nparams()); - reader[proto] = encode_serial_as_reader_func(serial); - } - initialized = true; - } + if (initialized) + return reader; + [+ FOR function +] + reader[make_pair("[+ (get "name") +]", [+ + (if (exist? "args") (get "args") "1") + +])] = [+ (get "name") +]_reader;[+ + ENDFOR +] return reader; } -- 1.6.3.3