Re: [Plplot-devel] Fix for 79-character truncation on plgfnam

2010-12-19 Thread David MacMahon

On Dec 19, 2010, at 1:09 PM, Alan W. Irwin wrote:

> Dave, do you see any downsides
> to the above idea as I have fleshed it out?

Only the ones I outlined earlier in this thread...

On Dec 18, 2010, at 11:34 AM, David MacMahon wrote:

> I think automatic allocation by the library function, while not a big 
> drawback, has a few potential points against it.  One it that memory 
> allocation is one of the (potentially) more expensive operations, so 
> minimizing it is desirable.  I don't think the use cases in question will 
> result in this being a significant factor.  The other issue is that once the 
> library has allocated and populated the buffer, language bindings sometimes 
> (typically?) require that the contents be copied into a suitably sized buffer 
> that the scripting language manages.  In this case the result is a double 
> allocation (one by the library function, one by the scripting language), a 
> extra strcpy from library buffer to scripting language buffer, and a free of 
> the buffer returned by the library function.
> 
> Getting the size first, allocating a buffer using he scripting language 
> memory management routines, then passing the pointer to the library routine 
> is, IMHO, more cleanly amenable to scripting language bindings (though I 
> write mine "manually" so I don't know whether this would apply to SWIG 
> generated bindings).
> 
> Again, I don't think these factors will be significant for the functions 
> under discussion, so I'll be happy with whatever consensus emerges.

Dave


--
Lotusphere 2011
Register now for Lotusphere 2011 and learn how
to connect the dots, take your collaborative environment
to the next level, and enter the era of Social Business.
http://p.sf.net/sfu/lotusphere-d2d
___
Plplot-devel mailing list
Plplot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/plplot-devel


Re: [Plplot-devel] Fix for 79-character truncation on plgfnam

2010-12-19 Thread Alan W. Irwin
Hi Dave (with a question for Andrew at the end):
> On Dec 18, 2010, at 6:30 PM, Alan W. Irwin wrote:

>> With plgnfnam that would be changed to something like
>>
>> (needed_size, fnam) = plgnfnam(100)
>> if needed_size >= 100:
>>  # Oops, 100 was too small.
>>  fname = plgnfnam(needed_size+1)[1]
>

> This is an example of why I like to hand code language bindings. 
IMHO, the plgnfnam function, if it is even exposed in the scripting
language, should take no arguments and always return a string
containing the entire contents.  Why make the user provide an initial
guess?  This requires them to check whether their guess was big enough
and try again (without forgetting the "+1") if it wasn't.  How
inconvenient!

Good points.  Hiding details is always good so I think we should do
this.

So far I think we are in consensus, but now I have had one more
thought that would change the proposed API to be quite different than
strlcpy.  (Sorry about that!) That thought is if information hiding is
good for high-level languages, why not do that at the C level right
from the start?  In other words, after this large sidetrack I have
come to the conclusion that we should use Andrew's idea to alloc
sufficient space inside plgnfnam, etc. to hold the string.  After all,
we can use strlen to determine the lengths of the version, device, and
filename strings for a particular stream so allocing inside the
routines with the exact size required seems like a good idea to me
with no worries about initial guesses for the size, reallocating, etc.

So the API would look like the following (dropping n from the name
with its mental association with a size argument and putting a 1 on
the end instead to differentiate this new set of routines from the
deprecated versions):

char * plgfnam1(void);

So a typical use fragment would be the following.  (I hope I have
gotten this right because I still often screw up C pointers due to my
lack of experience with C other than my contributions to PLplot).

char * fnam;
fnam = (char *) plgfname1();
fprintf( stdout, "PLplot file name: %s\n", fnam );
free(fnam);

And for Python, the call would be

fnam = plgfnam1()

or

fnam = plgfnam()

(which would be exactly equivalent to plgfnam1) with all details about
the C level call to plgfnam1() and freeing the buffer after the
string is copied to the Python level hidden in the swig-generated
interface.  And similarly for the other high-level languages.

Andrew, is that what you had in mind from the get go?  Dave, do you see any 
downsides
to the above idea as I have fleshed it out?

Alan
__
Alan W. Irwin

Astronomical research affiliation with Department of Physics and Astronomy,
University of Victoria (astrowww.phys.uvic.ca).

Programming affiliations with the FreeEOS equation-of-state implementation
for stellar interiors (freeeos.sf.net); PLplot scientific plotting software
package (plplot.org); the libLASi project (unifont.org/lasi); the Loads of
Linux Links project (loll.sf.net); and the Linux Brochure Project
(lbproject.sf.net).
__

Linux-powered Science
__

--
Lotusphere 2011
Register now for Lotusphere 2011 and learn how
to connect the dots, take your collaborative environment
to the next level, and enter the era of Social Business.
http://p.sf.net/sfu/lotusphere-d2d
___
Plplot-devel mailing list
Plplot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/plplot-devel


Re: [Plplot-devel] Fix for 79-character truncation on plgfnam

2010-12-18 Thread David MacMahon

On Dec 18, 2010, at 6:30 PM, Alan W. Irwin wrote:

> On 2010-12-18 11:34-0800 David MacMahon wrote:
> 
>> Am I missing something?
> 
> See their example 1d where they check for truncation.  Instead of
> taking an error return at that point as they did in their sample code
> the user could instead realloc if they liked as in your original
> suggestion.

Thanks, I did miss something! :-)  The strlcpy model seems very similar to the 
WIN32 convention, only better in that it is more rigorously documented 
vis-a-vis NUL termination.

> Just because it appears to be better documented on the
> null-termination guarantee issue, I suggest we adopt the strlcpy
> model.  This gives the user in any language freedom to do anything
> they like if the returned size (which never counts the null
> terminator) is >= the value of n in the call.

I agree!

> For high-level languages
> like Python where the uses don't have to worry about allocation, they
> could just call the function again with n chosen to be the previous
> returned value + 1.

For high level languages like Python, any (re-)allocation could happen in the 
bindings and therefore be hidden from the end user.

> Also, I don't think we should use the wrinkle present in
> GetShortPathName of doing something special for the NULL buffer,
> size=0 call.  That does add a bit of convenience (but is not a
> necessity) for languages such as C where the buffer is alloced
> beforehand,

I agree about not treating a NULL pointer as a special case, but strlcpy 
inherently treats size=0 as a special case (i.e. no NUL terminator).  When 
size=0, strlcpy ignores the pointer and gives the same  result as the WIN32 
convention (though the WIN32 convention requires the pointer to be NULL).

> but that wrinkle makes no sense for higher level languages
> such as Python where the correctly sized buffer is created as needed.
> For example, a typical Python call to plgfnam is
> 
> fnam = plgfnam()
> 
> With plgnfnam that would be changed to something like
> 
> (needed_size, fnam) = plgnfnam(100)
> if needed_size >= 100:
>  # Oops, 100 was too small.
>  fname = plgnfnam(needed_size+1)[1]

This is an example of why I like to hand code language bindings.  IMHO, the 
plgnfnam function, if it is even exposed in the scripting language, should take 
no arguments and always return a string containing the entire contents.  Why 
make the user provide an initial guess?  This requires them to check whether 
their guess was big enough and try again (without forgetting the "+1") if it 
wasn't.  How inconvenient!  Why not just do all of that for them inside the 
bindings for the high-level language's plgfnam call (which would call plgnfnam 
under the covers)?

Dave


--
Lotusphere 2011
Register now for Lotusphere 2011 and learn how
to connect the dots, take your collaborative environment
to the next level, and enter the era of Social Business.
http://p.sf.net/sfu/lotusphere-d2d
___
Plplot-devel mailing list
Plplot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/plplot-devel


Re: [Plplot-devel] Fix for 79-character truncation on plgfnam

2010-12-18 Thread Alan W. Irwin
On 2010-12-18 11:34-0800 David MacMahon wrote:

> Hi, Alan,
>
> On Dec 18, 2010, at 10:57 AM, Alan W. Irwin wrote:
>
>> Another model for plgnver, plgndev, and plgnfnam is one similar to
>> strlcpy that is discussed by Todd C. Miller and Theo de Raadt at
>> http://www.gratisoft.us/todd/papers/strlcpy.html.  That is a most
>> interesting paper to read.  I am not necessarily advocating something
>> similar to this model API.  I leave that to those more knowledgable in
>> C than I am.  However, I am mentioning this paper for further
>> discussion.
>

> It seems like strlcpy is a more convenient alternative to strncpy,
but I don't see how this would solve the allocation problem.  Wouldn't
the user still need to ensure that a large enough buffer has been
allocated?  If so, the problem of determining how large is large
enough still remains.  Am I missing something?

See their example 1d where they check for truncation.  Instead of
taking an error return at that point as they did in their sample code
the user could instead realloc if they liked as in your original
suggestion.  Of course, the real value of the strlcpy model is the
thought that has gone into the null termination issue as well as the
definition of the size of the buffer that is returned.  For example,
after much debate about the alternatives they decided to use the
snprintf return semantics, that is, the returned length does not
include the null terminator which is the same definition as the string
length calculated by strlen.

N.B. I have now found an additional useful reference for strlcpy which is
http://www.manpagez.com/man/3/strlcpy/

>
>>  Can you remember the name of the function you were using as 
>> the model
>> for your API suggestion for plgnver, plgndev, and plgnfnam?  If so,
>> that will give us a chance to dig into the official documention of
>> that function like we can currently do for getcwd and strlcpy. > Dave>
>

> OK, digging way back into my mental archives (and googling), I think
I first came across this approach in a previous life when I did
Windows programming.  An example of this approach can be seen in the
Windows GetShortPathName function (and probably others as well)...

>
> http://msdn.microsoft.com/en-us/library/aa364989(v=vs.85).aspx
>

> I mis-remembered the exact details of the return code.  The WIN32
functions seem to return the total size needed iff the buffer pointer
is NULL and the size is given as 0.  This shouldn't really change the
fundamentals of what I wrote earlier, however.

Thanks for that reference.  However, I have noticed some deficiencies
in that documentation of GetShortPathName.  There is no mention there
of null termination guaranteed in the result which is an important
issue covered in the strlcpy documentation.  For example, what happens
if the buffer receiving the result is too small?  Do you get a
truncated result with no null terminator or a truncated result of one
unit smaller in size followed by a null terminator, or nothing at all
in the result?

Just because it appears to be better documented on the
null-termination guarantee issue, I suggest we adopt the strlcpy
model.  This gives the user in any language freedom to do anything
they like if the returned size (which never counts the null
terminator) is >= the value of n in the call. For high-level languages
like Python where the uses don't have to worry about allocation, they
could just call the function again with n chosen to be the previous
returned value + 1.  For lower-level languages like C, they could
realloc the buffer using the correct size, return an error, or just
accept the truncated result.

Also, I don't think we should use the wrinkle present in
GetShortPathName of doing something special for the NULL buffer,
size=0 call.  That does add a bit of convenience (but is not a
necessity) for languages such as C where the buffer is alloced
beforehand, but that wrinkle makes no sense for higher level languages
such as Python where the correctly sized buffer is created as needed.
For example, a typical Python call to plgfnam is

fnam = plgfnam()

With plgnfnam that would be changed to something like

(needed_size, fnam) = plgnfnam(100)
if needed_size >= 100:
   # Oops, 100 was too small.
   fname = plgnfnam(needed_size+1)[1]

On the other hand, I would hope the PLplot version or device names are
unlikely to be greater than 20 characters in our lifetimes.  So for
that case, you normally wouldn't bother to check the needed size in
Python:

version = plgnfnam(20)[1]
devname = plgndev(20)[1]

Note, even in the unlikely case that the version or device name were
greater than 20 characters, the above calls would be perfectly safe
and would yield properly truncated results at the 20th character.

Alan
__
Alan W. Irwin

Astronomical research affiliation with Department of Physics and Astronomy,
University of Victoria (astrowww.phys.uvic.ca).

Programming affiliations with the FreeEOS equation-of-state implementation
for

Re: [Plplot-devel] Fix for 79-character truncation on plgfnam

2010-12-18 Thread David MacMahon
Hi, Alan,

On Dec 18, 2010, at 10:57 AM, Alan W. Irwin wrote:

> Another model for plgnver, plgndev, and plgnfnam is one similar to
> strlcpy that is discussed by Todd C. Miller and Theo de Raadt at
> http://www.gratisoft.us/todd/papers/strlcpy.html.  That is a most
> interesting paper to read.  I am not necessarily advocating something
> similar to this model API.  I leave that to those more knowledgable in
> C than I am.  However, I am mentioning this paper for further
> discussion.

It seems like strlcpy is a more convenient alternative to strncpy, but I don't 
see how this would solve the allocation problem.  Wouldn't the user still need 
to ensure that a large enough buffer has been allocated?  If so, the problem of 
determining how large is large enough still remains.  Am I missing something?

>  Can you remember the name of the function you were using as 
> the model
> for your API suggestion for plgnver, plgndev, and plgnfnam?  If so,
> that will give us a chance to dig into the official documention of
> that function like we can currently do for getcwd and strlcpy.  Dave>

OK, digging way back into my mental archives (and googling), I think I first 
came across this approach in a previous life when I did Windows programming.  
An example of this approach can be seen in the Windows GetShortPathName 
function (and probably others as well)...

http://msdn.microsoft.com/en-us/library/aa364989(v=vs.85).aspx

I mis-remembered the exact details of the return code.  The WIN32 functions 
seem to return the total size needed iff the buffer pointer is NULL and the 
size is given as 0.  This shouldn't really change the fundamentals of what I 
wrote earlier, however.

> On 2010-12-18 13:59- Andrew Ross wrote:
> 
>> Down side for us [of automatic allocation] is that allocated memory
>> in C may be difficult to use in other languages.

I think automatic allocation by the library function, while not a big drawback, 
has a few potential points against it.  One it that memory allocation is one of 
the (potentially) more expensive operations, so minimizing it is desirable.  I 
don't think the use cases in question will result in this being a significant 
factor.  The other issue is that once the library has allocated and populated 
the buffer, language bindings sometimes (typically?) require that the contents 
be copied into a suitably sized buffer that the scripting language manages.  In 
this case the result is a double allocation (one by the library function, one 
by the scripting language), a extra strcpy from library buffer to scripting 
language buffer, and a free of the buffer returned by the library function.

Getting the size first, allocating a buffer using he scripting language memory 
management routines, then passing the pointer to the library routine is, IMHO, 
more cleanly amenable to scripting language bindings (though I write mine 
"manually" so I don't know whether this would apply to SWIG generated bindings).

Again, I don't think these factors will be significant for the functions under 
discussion, so I'll be happy with whatever consensus emerges.

Dave


--
Lotusphere 2011
Register now for Lotusphere 2011 and learn how
to connect the dots, take your collaborative environment
to the next level, and enter the era of Social Business.
http://p.sf.net/sfu/lotusphere-d2d
___
Plplot-devel mailing list
Plplot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/plplot-devel


Re: [Plplot-devel] Fix for 79-character truncation on plgfnam

2010-12-18 Thread Alan W. Irwin
Hi Andrew (with one question for Dave):

Thanks for contributing to this discussion.

On 2010-12-18 13:59- Andrew Ross wrote:

> I think passing a buffer size is the safest way to go. If you wanted a
> constant buffer length, then it should be PATH_MAX to ensure any path
> will fit, but this still has risks associated.

Agreed.

>
> Note other functions (e.g. getcwd - Linux extension) interpret a null
> buffer differently, and will allocate a buffer using malloc in this
> case to allocate a buffer. If the buffer size parameter > 0 then the
> allocated buffer is of that size. If if is zero then a buffer big
> enough to return the path is allocated. Note getcwd also returns null
> if the buffer is not big enough and sets errno to ERANGE.
>
> I'm not necessarily suggesting this is better, but it an alternative
> approach. Plus side is that it is easier for the user - allocations
> are done automatically.

Another model for plgnver, plgndev, and plgnfnam is one similar to
strlcpy that is discussed by Todd C. Miller and Theo de Raadt at
http://www.gratisoft.us/todd/papers/strlcpy.html.  That is a most
interesting paper to read.  I am not necessarily advocating something
similar to this model API.  I leave that to those more knowledgable in
C than I am.  However, I am mentioning this paper for further
discussion.

 
Can you remember the name of the function you were using as the model
for your API suggestion for plgnver, plgndev, and plgnfnam?  If so,
that will give us a chance to dig into the official documention of
that function like we can currently do for getcwd and strlcpy. 


> Down side for us [of automatic allocation] is that allocated memory
> in C may be difficult to use in other languages.

Unless I misunderstood you, I think that allocation, possible
reallocation, and free of a C buffer is a given (which I like) for all
approaches discussed so far.  For example, this is true for the getcwd
Linux extension approach, the strlcpy approach, or Dave's approach.
After the C buffer is filled with the character-string information
from the PLplot core library, then it is up to each language interface
to pass that information on to the language environment in appropriate
form.  That seems to be the model used in our swig-based language
bindings and also for Tcl (if I am following that generated code
correctly).  My guess is our remaining language bindings follow that
model as well.  Regardless, they all currently implement plgver,
plgdev, and plgfnam without issues so that means it should be possible
to adapt those approaches to the plgnver, plgndev, and plgnfnam cases
once we finalize the API for those.

Alan
__
Alan W. Irwin

Astronomical research affiliation with Department of Physics and Astronomy,
University of Victoria (astrowww.phys.uvic.ca).

Programming affiliations with the FreeEOS equation-of-state implementation
for stellar interiors (freeeos.sf.net); PLplot scientific plotting software
package (plplot.org); the libLASi project (unifont.org/lasi); the Loads of
Linux Links project (loll.sf.net); and the Linux Brochure Project
(lbproject.sf.net).
__

Linux-powered Science
__

--
Lotusphere 2011
Register now for Lotusphere 2011 and learn how
to connect the dots, take your collaborative environment
to the next level, and enter the era of Social Business.
http://p.sf.net/sfu/lotusphere-d2d
___
Plplot-devel mailing list
Plplot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/plplot-devel


Re: [Plplot-devel] Fix for 79-character truncation on plgfnam

2010-12-18 Thread Andrew Ross
On Fri, Dec 17, 2010 at 10:53:44AM -0800, Alan Irwin wrote:
> On 2010-12-16 21:15-0800 David MacMahon wrote:
> 
> > Hi, Alan,
> >
> > On Dec 16, 2010, at 6:54 PM, Alan W. Irwin wrote:
> >
> >> Here is what I propose instead of this temporary measure.  We go with
> >> a backward-incompatible API change (and associated soname bump to
> >> force everybody to recompile) of
> >>
> >> c_plgfnam( char *fnam ); ==> c_plgfnam( char *fnam, PLINT n);
> >>
> >> where n is the size of the buffer that has been allocated.
> >> Internally, c_plgfnam will use n for the strncpy call as well as
> >> figuring out the last byte to zero.
> >>
> >> Note, the other two PLplot functions (plgver and plgdev) that return
> >> character strings have recommendations in the documentation to
> >> allocate 80-byte buffers to contain the version string and device
> >> name.
> >
> 
> > I notice that all of these functions currently have a null return
> type.  One approach I've seen elsewhere, is to have functions like
> this return an int indicating how many bytes were copied into the
> buffer if the pointer given is non-null *or*, if the given pointer is
> null, how many more bytes are needed to fill the buffer.
> 
> > This allows the client code to determine the buffer size needed,
> (re-)allocate the buffer dynamically, then fill the buffer...
> 
> >
> > bufsize = plgver(NULL, 0);
> > buf = (char *)malloc(bufsize+1);
> > plgver(buf, bufsize);
> > buf[bufsize] = '\0';
> >
> > // Note how this can be used to determine
> > // whether a buffer is already big enough
> >
> > extra = plgfnam(NULL, bufsize);
> > if(extra > 0) {
> >  buf = (char *)realloc(buf, bufsize+extra+1);
> > }
> > bufsize += extra;
> >
> > // if extra < 0, bufsize will be smaller
> > // than size of region allocated
> > plgfnam(buf, bufsize);
> > buf[bufsize] = '\0';
> 
> I very much like the general idea of using a returned value to always
> allow changing the buffer size as appropriate.  So many thanks for
> bringing up this possibility, and I hope the result is we handle
> these buffer size issues in an absolutely ideal way.
> 
> Furthermore, I have now changed my mind about two matters I discussed in
> my previous post.
> 
> I now think we should prevent the soname bump (for now) by simply
> deprecating plgver, plgdev, and plgfnam and adding new functions
> called plgnver, plgndev, and plgnfnam that handle the buffer size
> issue in an ideal way. My original thought was we wouldn't need
> plgnver and plgndev.  But now I think we do just based on the
> interests of uniformity.

I think passing a buffer size is the safest way to go. If you wanted a
constant buffer length, then it should be PATH_MAX to ensure any path
will fit, but this still has risks associated. 

Note other functions (e.g. getcwd - Linux extension) interpret a null
buffer differently, and will allocate a buffer using malloc in this
case to allocate a buffer. If the buffer size parameter > 0 then the 
allocated buffer is of that size. If if is zero then a buffer big
enough to return the path is allocated. Note getcwd also returns null 
if the buffer is not big enough and sets errno to ERANGE. 

I'm not necessarily suggesting this is better, but it an alternative 
approach. Plus side is that it is easier for the user - allocations
are done automatically. Down side for us is that allocated memory
in C may be difficult to use in other languages.

> 
> Of course, propagation of this new plgnver, plgndev, and plgnfnam
> functionality to some languages might be tricky.  I checked that for
> our swig-based languages (Python, Java, and Lua), and I don't think it
> will be a problem for that case. swig allows inserting arbitrary C
> code such as the above allocs or reallocs into the interface. And it
> is obviously not a problem to implement the new functionality in our
> C++ language bindings.  However, I would like all the language gurus
> to think about implementing this new functionality for their favorite
> language such as Ada (Jerry), D (Werner), Fortran 77, Fortran 95, and
> Tcl (Arjen), OCaml (Hez), Octave (Andrew), and the externally
> developed perl/PDL bindings (Doug Hunt who also lurks here).

Andrew

--
Lotusphere 2011
Register now for Lotusphere 2011 and learn how
to connect the dots, take your collaborative environment
to the next level, and enter the era of Social Business.
http://p.sf.net/sfu/lotusphere-d2d
___
Plplot-devel mailing list
Plplot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/plplot-devel


Re: [Plplot-devel] Fix for 79-character truncation on plgfnam

2010-12-17 Thread Alan W. Irwin
On 2010-12-16 21:15-0800 David MacMahon wrote:

> Hi, Alan,
>
> On Dec 16, 2010, at 6:54 PM, Alan W. Irwin wrote:
>
>> Here is what I propose instead of this temporary measure.  We go with
>> a backward-incompatible API change (and associated soname bump to
>> force everybody to recompile) of
>>
>> c_plgfnam( char *fnam ); ==> c_plgfnam( char *fnam, PLINT n);
>>
>> where n is the size of the buffer that has been allocated.
>> Internally, c_plgfnam will use n for the strncpy call as well as
>> figuring out the last byte to zero.
>>
>> Note, the other two PLplot functions (plgver and plgdev) that return
>> character strings have recommendations in the documentation to
>> allocate 80-byte buffers to contain the version string and device
>> name.
>

> I notice that all of these functions currently have a null return
type.  One approach I've seen elsewhere, is to have functions like
this return an int indicating how many bytes were copied into the
buffer if the pointer given is non-null *or*, if the given pointer is
null, how many more bytes are needed to fill the buffer.

> This allows the client code to determine the buffer size needed,
(re-)allocate the buffer dynamically, then fill the buffer...

>
> bufsize = plgver(NULL, 0);
> buf = (char *)malloc(bufsize+1);
> plgver(buf, bufsize);
> buf[bufsize] = '\0';
>
> // Note how this can be used to determine
> // whether a buffer is already big enough
>
> extra = plgfnam(NULL, bufsize);
> if(extra > 0) {
>  buf = (char *)realloc(buf, bufsize+extra+1);
> }
> bufsize += extra;
>
> // if extra < 0, bufsize will be smaller
> // than size of region allocated
> plgfnam(buf, bufsize);
> buf[bufsize] = '\0';

I very much like the general idea of using a returned value to always
allow changing the buffer size as appropriate.  So many thanks for
bringing up this possibility, and I hope the result is we handle
these buffer size issues in an absolutely ideal way.

Furthermore, I have now changed my mind about two matters I discussed in
my previous post.

I now think we should prevent the soname bump (for now) by simply
deprecating plgver, plgdev, and plgfnam and adding new functions
called plgnver, plgndev, and plgnfnam that handle the buffer size
issue in an ideal way. My original thought was we wouldn't need
plgnver and plgndev.  But now I think we do just based on the
interests of uniformity.

Of course, propagation of this new plgnver, plgndev, and plgnfnam
functionality to some languages might be tricky.  I checked that for
our swig-based languages (Python, Java, and Lua), and I don't think it
will be a problem for that case. swig allows inserting arbitrary C
code such as the above allocs or reallocs into the interface. And it
is obviously not a problem to implement the new functionality in our
C++ language bindings.  However, I would like all the language gurus
to think about implementing this new functionality for their favorite
language such as Ada (Jerry), D (Werner), Fortran 77, Fortran 95, and
Tcl (Arjen), OCaml (Hez), Octave (Andrew), and the externally
developed perl/PDL bindings (Doug Hunt who also lurks here).

Alan
__
Alan W. Irwin

Astronomical research affiliation with Department of Physics and Astronomy,
University of Victoria (astrowww.phys.uvic.ca).

Programming affiliations with the FreeEOS equation-of-state implementation
for stellar interiors (freeeos.sf.net); PLplot scientific plotting software
package (plplot.org); the libLASi project (unifont.org/lasi); the Loads of
Linux Links project (loll.sf.net); and the Linux Brochure Project
(lbproject.sf.net).
__

Linux-powered Science
__

--
Lotusphere 2011
Register now for Lotusphere 2011 and learn how
to connect the dots, take your collaborative environment
to the next level, and enter the era of Social Business.
http://p.sf.net/sfu/lotusphere-d2d
___
Plplot-devel mailing list
Plplot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/plplot-devel


Re: [Plplot-devel] Fix for 79-character truncation on plgfnam

2010-12-16 Thread David MacMahon
Hi, Alan,

On Dec 16, 2010, at 6:54 PM, Alan W. Irwin wrote:

> Here is what I propose instead of this temporary measure.  We go with
> a backward-incompatible API change (and associated soname bump to
> force everybody to recompile) of
> 
> c_plgfnam( char *fnam ); ==> c_plgfnam( char *fnam, PLINT n);
> 
> where n is the size of the buffer that has been allocated. 
> Internally, c_plgfnam will use n for the strncpy call as well as
> figuring out the last byte to zero.
> 
> Note, the other two PLplot functions (plgver and plgdev) that return
> character strings have recommendations in the documentation to
> allocate 80-byte buffers to contain the version string and device
> name.

I notice that all of these functions currently have a null return type.  One 
approach I've seen elsewhere, is to have functions like this return an int 
indicating how many bytes were copied into the buffer if the pointer given is 
non-null *or*, if the given pointer is null, how many more bytes are needed to 
fill the buffer.

This allows the client code to determine the buffer size needed, (re-)allocate 
the buffer dynamically, then fill the buffer...

bufsize = plgver(NULL, 0);
buf = (char *)malloc(bufsize+1);
plgver(buf, bufsize);
buf[bufsize] = '\0';

// Note how this can be used to determine
// whether a buffer is already big enough

extra = plgfnam(NULL, bufsize);
if(extra > 0) {
  buf = (char *)realloc(buf, bufsize+extra+1);
}
bufsize += extra;

// if extra < 0, bufsize will be smaller
// than size of region allocated
plgfnam(buf, bufsize);
buf[bufsize] = '\0';

Just an idea,
Dave


--
Lotusphere 2011
Register now for Lotusphere 2011 and learn how
to connect the dots, take your collaborative environment
to the next level, and enter the era of Social Business.
http://p.sf.net/sfu/lotusphere-d2d
___
Plplot-devel mailing list
Plplot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/plplot-devel


[Plplot-devel] Fix for 79-character truncation on plgfnam

2010-12-16 Thread Alan W. Irwin
Andrew, I would very much appreciate your and other PLplot API
expert's comments on this issue.

I noticed during some of my generic testing today that the output file
name was truncated for the 31st example at the 79th character.  This
seems to be a rather tight limit for today's computers where full
pathnames of files can reach far beyond 79 characters.

Accordingly I have replaced (revision 11375) all occurrences of 80 by
256 in examples/*/*31* and changed plgfnam internally so that it
truncates at the 255th character.  The result works, but I view this
internal change to plgfnam as a dangerous temporary measure because
those who stick with the old limit of 80-byte buffers for their
plgfnam calls will have a guaranteed buffer overflow because the
revised plgfnam puts a "\0" in the 256th byte of the buffer.

Here is what I propose instead of this temporary measure.  We go with
a backward-incompatible API change (and associated soname bump to
force everybody to recompile) of

c_plgfnam( char *fnam ); ==> c_plgfnam( char *fnam, PLINT n);

where n is the size of the buffer that has been allocated. 
Internally, c_plgfnam will use n for the strncpy call as well as
figuring out the last byte to zero.

Note, the other two PLplot functions (plgver and plgdev) that return
character strings have recommendations in the documentation to
allocate 80-byte buffers to contain the version string and device
name.  That recommendation should be entirely safe for the forseeable
future.  Note it is only a recommendation and inside those routines
that limit is not enforced.  However, plgfnam is quite different. The
80-byte buffer limit there is recommended and also enforced internally
by the implementation (before the above commit).  That caused
truncated filename results to be returned whenever the length of the
full pathnames of files used by file device drivers exceeded 79 bytes.

I need comments and discussion by our API experts here to make sure
the proposed backwards-incompatible change to the plgfnam API is the
way to go.

Alan
__
Alan W. Irwin

Astronomical research affiliation with Department of Physics and Astronomy,
University of Victoria (astrowww.phys.uvic.ca).

Programming affiliations with the FreeEOS equation-of-state implementation
for stellar interiors (freeeos.sf.net); PLplot scientific plotting software
package (plplot.org); the libLASi project (unifont.org/lasi); the Loads of
Linux Links project (loll.sf.net); and the Linux Brochure Project
(lbproject.sf.net).
__

Linux-powered Science
__

--
Lotusphere 2011
Register now for Lotusphere 2011 and learn how
to connect the dots, take your collaborative environment
to the next level, and enter the era of Social Business.
http://p.sf.net/sfu/lotusphere-d2d
___
Plplot-devel mailing list
Plplot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/plplot-devel