9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
* [9fans] snprint(), getfields() specification
@ 2001-05-10 17:40 erik quanstrom
  0 siblings, 0 replies; 16+ messages in thread
From: erik quanstrom @ 2001-05-10 17:40 UTC (permalink / raw)
  To: 9fans

> The getfields() manpage says,
> 
> 	If there are more than maxargs fields, only the first maxargs
> 	fields will be set.
> 	...
> 	Getfields return the number of tokens processed.
> 
> snprint() says something similar.
> 
> In both cases, if the limit is too small, there's no way to find out
> how much space you actually needed.  Unix snprintf returns that value;
> compare with the limit to know if you need to allocate more space,
> or emit an error, or just use what you got.
> 
> I think we might be better off adopting that convention.

actually, the unix snprint (linux) says:

RETURN VALUE
       If the output was truncated, the return value is -1, otherwise it is the
       number of characters stored, not including the terminating null.


i don't see a problem with snprint() truncating the output -- you
shouldn't be using it if you don't have a maximum size in mind to begin with.
the n in snprint is just a fencepost.

what would be nice, though, is mprint(), which scott's very own print
library provides. mprint() allocates enough memory for whatever string
you want to format, and returns the buffer. very nice.

as an aside, i've added "long" formats to scott's library. they're
of the form "%{list %s}", for example. we were using installable
formats on a largish project where we had a lot of need to print out
this or that. it was quite a help to expand the namespace, in our
project. also, %{md5sum} is quite a lot more readable and unambiguous
than %M (which is probablly used anyway).

if there's any interest, i'd be happy to package up my mods & post them.

erik



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [9fans] snprint(), getfields() specification
  2001-05-10 14:30 rob pike
  2001-05-11  8:33 ` Douglas A. Gwyn
@ 2001-05-14  8:36 ` David Rubin
  1 sibling, 0 replies; 16+ messages in thread
From: David Rubin @ 2001-05-14  8:36 UTC (permalink / raw)
  To: 9fans

rob pike wrote:
> 
> By tradition, the return value of functions report what they did,
> not what they considered doing.

Rob, that's definitely .sig-worthy!

	david

-- 
If 91 were prime, it would be a counterexample to your conjecture.
    -- Bruce Wheeler


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [9fans] snprint(), getfields() specification
  2001-05-10 14:30 rob pike
@ 2001-05-11  8:33 ` Douglas A. Gwyn
  2001-05-14  8:36 ` David Rubin
  1 sibling, 0 replies; 16+ messages in thread
From: Douglas A. Gwyn @ 2001-05-11  8:33 UTC (permalink / raw)
  To: 9fans

rob pike wrote:
> By tradition, the return value of functions report what they did,
> not what they considered doing.

But if (part of) the purpose of the function *is* to probe,
returning the result of the probe is consistent.


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [9fans] snprint(), getfields() specification
  2001-05-10 21:38     ` Boyd Roberts
@ 2001-05-11  6:51       ` Steve Kilbane
  0 siblings, 0 replies; 16+ messages in thread
From: Steve Kilbane @ 2001-05-11  6:51 UTC (permalink / raw)
  To: 9fans

Boyd:
> no, return a value so you have the best possible idea of why it
> didn't 'work'. 

i know; i was thinking about rob's comments on consistent return
values. however, he's already gone beyond this anyway.

steve




^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [9fans] snprint(), getfields() specification
  2001-05-10 18:13   ` Steve Kilbane
@ 2001-05-10 21:38     ` Boyd Roberts
  2001-05-11  6:51       ` Steve Kilbane
  0 siblings, 1 reply; 16+ messages in thread
From: Boyd Roberts @ 2001-05-10 21:38 UTC (permalink / raw)
  To: 9fans

From: "Steve Kilbane" <steve@whitecrow.demon.co.uk>
>
> I'd say adopt the other UNIX convention, and return -1. The arguments
> aren't "right" - insufficient space - so do nothing. It moves the
> speculative behaviour onto the user.

no, return a value so you have the best possible idea of why it
didn't 'work'.  if it was a space problem, allocate more space,
loop.

i recall that netscape on windows 3 allowed you to specify how
many tcp connection it would manage at once and the i/o buffer
size.  should you try a > 16kb read/write bad things happened
to your winsock dll.  my dll, which called winsock while doing
all the socks 4 work, had a parameter in the ini file to split
the i/o's up into chunks and then return the total read/written.

should the dll get an i/o error you'd get a short i/o so you'd
continue with the bit that was left and then get an error.  err,
of course, i'm referring to a correctly written winsock application.

yeah, i suffered that sort of junk for 2 years -- ouch.




^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [9fans] snprint(), getfields() specification
  2001-05-10 14:59 ` rob pike
  2001-05-10 16:42   ` Scott Schwartz
@ 2001-05-10 18:13   ` Steve Kilbane
  2001-05-10 21:38     ` Boyd Roberts
  1 sibling, 1 reply; 16+ messages in thread
From: Steve Kilbane @ 2001-05-10 18:13 UTC (permalink / raw)
  To: 9fans

I'd say adopt the other UNIX convention, and return -1. The arguments
aren't "right" - insufficient space - so do nothing. It moves the
speculative behaviour onto the user.

steve




^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [9fans] snprint(), getfields() specification
@ 2001-05-10 17:56 rob pike
  0 siblings, 0 replies; 16+ messages in thread
From: rob pike @ 2001-05-10 17:56 UTC (permalink / raw)
  To: 9fans

> would it not also avoid the proliferation of special interfaces for each possible
> routine that does formatting (including the ones users invent)?

yes it would. maybe i'll bite the bullet. sean dorward has been reworking
our print library; i'll talk to him about it.

-rob



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [9fans] snprint(), getfields() specification
@ 2001-05-10 17:51 forsyth
  0 siblings, 0 replies; 16+ messages in thread
From: forsyth @ 2001-05-10 17:51 UTC (permalink / raw)
  To: 9fans

>>If I had to pick one, I'd go for the length routine.  If you really
>>care, always use it; if you never care, you want the actual number of
>>bytes and the snprint (not snprintf) result seems better.

would it not also avoid the proliferation of special interfaces for each possible
routine that does formatting (including the ones users invent)?



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [9fans] snprint(), getfields() specification
@ 2001-05-10 16:56 rob pike
  0 siblings, 0 replies; 16+ messages in thread
From: rob pike @ 2001-05-10 16:56 UTC (permalink / raw)
  To: 9fans

The 9P2000 version of the Plan 9, with all its variable-sized pieces,
has this problem in many places.  I don't think a single best solution
exists, nor that this idea works for snprintf, but for example: In the
new stat, the buffer might not be long enough for the full entry.  In
that case, the return value is 2, which could never otherwise be the
right answer, and the first two bytes of the buffer contain the
required length.  (The first two bytes of any stat buffer hold the
length of the entire object.)  In the manner intended, I believe, for
snprintf, you have a chance to reallocate and retry.

A word for consistency: the return value is, as traditional, the
number of bytes affected by the operation that actually happened.

If you want to know big a buffer is required for snprintf, two methods
strike me as better than the C99 approach: some sort of length routine
that in practice you could always call (avoiding the retry case), or a
separate return path, such as an int*.  In practice, I probably
wouldn't use either, since I use snprint purely for safety, almost
never expecting a truncated answer and not really caring if I get one.
The C99 definition makes my standard usage more convoluted to achieve.

If I had to pick one, I'd go for the length routine.  If you really
care, always use it; if you never care, you want the actual number of
bytes and the snprint (not snprintf) result seems better.

-rob



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [9fans] snprint(), getfields() specification
  2001-05-10 14:59 ` rob pike
@ 2001-05-10 16:42   ` Scott Schwartz
  2001-05-10 18:13   ` Steve Kilbane
  1 sibling, 0 replies; 16+ messages in thread
From: Scott Schwartz @ 2001-05-10 16:42 UTC (permalink / raw)
  To: 9fans

(Well, not strlen.  Just a check to see if the return value was bigger
than the limit.)

What then is the elegant solution?


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [9fans] snprint(), getfields() specification
@ 2001-05-10 14:59 ` rob pike
  2001-05-10 16:42   ` Scott Schwartz
  2001-05-10 18:13   ` Steve Kilbane
  0 siblings, 2 replies; 16+ messages in thread
From: rob pike @ 2001-05-10 14:59 UTC (permalink / raw)
  To: 9fans

Observe the error:
>     some of the printed characters were discarded.
None of the printed characters was discarded.

I understood what was being said and I am objecting to the design.
I understand the idea - that you can't find out what you need any other
way, so return that information and use strlen() to find out what really
got done - but I still think it sets a dangerous precedent.  Like the strcpy()
that returned a pointer to the end of the string (fixed by ANSI C), the
return value sacrifices a long-standing principle to short-sighted
expedience.  C99 has made many mistakes, and this is hardly the worst,
but it bothers me that people are now (or will soon be) arguing that we
should follow a broken design (c.f. malloc(0)) because it's written down
somewhere.

I suppose we should fix (read break) our snprintf() implementation, but
I can at least hold on to the fact that snprint() is not defined by C99.

I really object to this speculative return value, but it's not my decision
so pooey.  It's malloc(0) and int a[0] all over again.

Sigh.

-rob



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [9fans] snprint(), getfields() specification
  2001-05-10 14:25 ` Greg Hudson
@ 2001-05-10 14:44   ` William Josephson
  0 siblings, 0 replies; 16+ messages in thread
From: William Josephson @ 2001-05-10 14:44 UTC (permalink / raw)
  To: 9fans

On Thu, May 10, 2001 at 10:25:11AM -0400, Greg Hudson wrote:
> Rob Pike wrote:
> > Really?  Unix sprintf tells you what it printed and snprintf tells
> > you what it *might* have printed?  That's a scary inconsistency.
> 
> They both return the length of the formatted string.  Would it be any
> less scary for sprintf to return the length of the formatted string
> and snprintf to return something different and less informative?

As you say, snprintf returns the length of the formatted string, not
the length of the string it would have generated had the buffer not
been of fixed length.  This is not how I initially interpreted the
description that Rob is responding to and I suspect it is not how he
interpreted it either.

Per the man page:

     snprintf() and vsnprintf() will write at most size-1 of the characters
     printed into the output string (the size'th character then gets the ter-
     minating `\0'); if the return value is greater than or equal to the size
     argument, the string was too short and some of the printed characters
     were discarded.

 -WJ



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [9fans] snprint(), getfields() specification
@ 2001-05-10 14:30 rob pike
  2001-05-11  8:33 ` Douglas A. Gwyn
  2001-05-14  8:36 ` David Rubin
  0 siblings, 2 replies; 16+ messages in thread
From: rob pike @ 2001-05-10 14:30 UTC (permalink / raw)
  To: 9fans

By tradition, the return value of functions report what they did,
not what they considered doing.

-rob



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [9fans] snprint(), getfields() specification
  2001-05-10 13:56 rob pike
@ 2001-05-10 14:25 ` Greg Hudson
  2001-05-10 14:44   ` William Josephson
  0 siblings, 1 reply; 16+ messages in thread
From: Greg Hudson @ 2001-05-10 14:25 UTC (permalink / raw)
  To: 9fans

Rob Pike wrote:
> Really?  Unix sprintf tells you what it printed and snprintf tells
> you what it *might* have printed?  That's a scary inconsistency.

They both return the length of the formatted string.  Would it be any
less scary for sprintf to return the length of the formatted string
and snprintf to return something different and less informative?

Edge cases introduce consistency choices.  Better to avoid them,
e.g. with asprintf().


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [9fans] snprint(), getfields() specification
@ 2001-05-10 13:56 rob pike
  2001-05-10 14:25 ` Greg Hudson
  0 siblings, 1 reply; 16+ messages in thread
From: rob pike @ 2001-05-10 13:56 UTC (permalink / raw)
  To: 9fans

Really?  Unix sprintf tells you what it printed and snprintf tells you
what it *might* have printed?  That's a scary inconsistency.

-rob



^ permalink raw reply	[flat|nested] 16+ messages in thread

* [9fans] snprint(), getfields() specification
@ 2001-05-10  5:11 Scott Schwartz
  0 siblings, 0 replies; 16+ messages in thread
From: Scott Schwartz @ 2001-05-10  5:11 UTC (permalink / raw)
  To: 9fans

The getfields() manpage says,

	If there are more than maxargs fields, only the first maxargs
	fields will be set.
	...
	Getfields return the number of tokens processed.

snprint() says something similar.

In both cases, if the limit is too small, there's no way to find out
how much space you actually needed.  Unix snprintf returns that value;
compare with the limit to know if you need to allocate more space,
or emit an error, or just use what you got.

I think we might be better off adopting that convention.



^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2001-05-14  8:36 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-05-10 17:40 [9fans] snprint(), getfields() specification erik quanstrom
  -- strict thread matches above, loose matches on Subject: below --
2001-05-10 17:56 rob pike
2001-05-10 17:51 forsyth
2001-05-10 16:56 rob pike
     [not found] <rob@plan9.bell-labs.com>
2001-05-10 14:59 ` rob pike
2001-05-10 16:42   ` Scott Schwartz
2001-05-10 18:13   ` Steve Kilbane
2001-05-10 21:38     ` Boyd Roberts
2001-05-11  6:51       ` Steve Kilbane
2001-05-10 14:30 rob pike
2001-05-11  8:33 ` Douglas A. Gwyn
2001-05-14  8:36 ` David Rubin
2001-05-10 13:56 rob pike
2001-05-10 14:25 ` Greg Hudson
2001-05-10 14:44   ` William Josephson
2001-05-10  5:11 Scott Schwartz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).