String concatenation function, request for comments.

M

michael.casey

I definitely see your point, and I went with the 'end of list marker'
method in my second version of the function posted Jun 5, 4:56 pm.

I could have been paying more attention when I spat the example code,
but I definitely agree that it is painstaking to count the args.
The second version uses an EOL macro to ease terminating the argument
list. I find this to be much easier.
 
C

CBFalconer

I am aware of strlcpy(), what I was trying to avoid is multi-line
string concatenations. How does the second version of the function
(posted Jun 5, 4:56 pm) hold up in terms of threading?

You failed to quote, so I have lost the context (see sig below). I
know of no second version, my implementation is unchanged, is
portable, and has no known reentrancy or threading problems. It
remains available at:

<http://cbfalconer.home.att.net/download/strlcpy.zip>
 
C

CBFalconer

I definitely see your point, and I went with the 'end of list marker'
method in my second version of the function posted Jun 5, 4:56 pm.

I could have been paying more attention when I spat the example code,
but I definitely agree that it is painstaking to count the args.
The second version uses an EOL macro to ease terminating the argument
list. I find this to be much easier.

This sounds as if you are building some form of variadic function.
My advice is: don't. Variadic functions are trouble and error
prone. Better to write a piece of code of the general form:

while (condition) {
/* concatenate thingb onto thinga */
}

which can take care of all the memory allocation etc. problems out
in the open.
 
M

michael.casey

Better to write a piece of code of the general form:
while (condition) {
/* concatenate thingb onto thinga */
}

This method seems far too redundant especially when frequently used in
practice. I see little advantage to using it apose to the current
implementation of my function, which could be described as a variadic
implementation of strlcat().

The largest problem with the current version is the usage of an 'end of
list' marker, which could easily be omitted. If it where omitted, the
bug would be simple to trace however. I would like to hear about any
concerns you have about its current implementation and use.
[...] I know of no second version, my implementation is unchanged, is
portable, and has no known reentrancy or threading problems. [...]

The second version I was refering to was that of my function:

Example:
char vbuf[VAST_BUF];
ret = vast(vbuf, VAST_BUF, "Put it", " together.", EOL);

[...]

#include <stdarg.h>

#define VAST_BUF 512

/*----------------------------­------------------------------­---------*\

|- vast(): Variable Argument String; concatenate arbitrary strings. -|

\*----------------------------­------------------------------­---------*/


/* End of List - Symbolize end of argument list. */

#define EOL (const char *)0

/* Would the const qualifyer be necessary here? */

char *vast(char *buf, size_t len, ...) {

const char *v;
int o = 0;

va_list ap;

va_start(ap, len);

/* Loop it while its hot. */

while(v = va_arg(ap, const char *)) {
/* Copy string to cumulative buffer so long as */
/* the total does not exceed (VAST_BUF - 1). */

while((buf[o] = *v++) && (o < VAST_BUF - 1))
o++;
}

va_end(ap);

buf[o] = '\0';

return(buf);

}
 
D

Default User

Correction: (o < VAST_BUF - 1) should be (o < len - 1).



Correction to what? Post with sufficient context for your replies. That
means all the time.




Brian
 
C

CBFalconer

Better to write a piece of code of the general form:

while (condition) {
/* concatenate thingb onto thinga */
}

This method seems far too redundant especially when frequently used
in practice. I see little advantage to using it apose to the current
implementation of my function, which could be described as a variadic
implementation of strlcat().

The largest problem with the current version is the usage of an 'end
of list' marker, which could easily be omitted. If it where omitted,
the bug would be simple to trace however. I would like to hear about
any concerns you have about its current implementation and use.
[...] I know of no second version, my implementation is unchanged, is
portable, and has no known reentrancy or threading problems. [...]

The second version I was refering to was that of my function:

Example:
char vbuf[VAST_BUF];
ret = vast(vbuf, VAST_BUF, "Put it", " together.", EOL);

Well, here you are starting at the right end, the interface to your
function. Get that right and you can then implement it in various
ways. My objection to your above interface is that there is no way
to control or prevent overflow, which is one of the points of
strlcat (its return shows what is actually needed). The other
direction is to have the routine always saw off the required space
via malloc, so it never fails barring memory exhaustion. Then your
prototype interface would be:

char *bigcat(const char *s1, ...);

returning NULL on failure, and requiring a final NULL in the list
of concatanees. The only interfacing foulup possible is omitting
the final NULL. An initial NULL could simply return an empty
string, so you can confidently pass the non-null results onward.
You are also confident that the returned item can be passed to
free. There are also no restrictions on the input strings
origins. The usage could then be:

if (!(s = bigcat(s1, s2, s3, s4, NULL))) theoperationfailed();
else {
/* further processing and use of s */
free(s);
}
s = NULL;

In fact, you can safely use this to inject things in front of a
bigcat string within the "further processing" above by:

s = bigcat("prefix string", s, NULL)

except that that is liable to a memory leak when the prefix
operation fails, similar to having realloc fail. The cure is the
same, use a temp.

Just some random thoughts.
 
B

Ben Pfaff

Michael A. Casey said:
The correction applies to the post above the one which you commented.

"above"? Everyone sees a different set of articles arranged in a
different order. This is why you should quote or, at the very
least, cite the Message-ID of the article you are referring to.
 
C

CBFalconer

*** Stupid top-posting corrected ***

Michael A. Casey said:
The correction applies to the post above the one which you commented.

I am beginning to think you belong to the intellectually challenged
class. You continue to fail to quote, fail to heed advice such as
my sig below, and make silly assumptions while posting
incomprehensible isolated and useless verbiage. You are getting
very close to plonk status in my book. We don't need this sort of
irritation.
 
M

michael.casey

I think you are being dramatic.
*** Stupid top-posting corrected ***



I am beginning to think you belong to the intellectually challenged
class.
Thanks.

You continue to fail to quote, fail to heed advice such as
my sig below, and make silly assumptions while posting
incomprehensible isolated and useless verbiage.

I have been using the secondary reply link.

I assumed that the "In-Reply-To" header was sufficient for any client
to sort messages in such a way which would allow me to reply to the
"above" post without needing to quote the entire thing. I used the term
"above" to describe the message I was replying to.
 
C

Chris Dollin

I assumed that the "In-Reply-To" header was sufficient for any client
to sort messages in such a way which would allow me to reply to the
"above" post without needing to quote the entire thing. I used the term
"above" to describe the message I was replying to.

The client may not have *seen* the message you're replying to. No amount
of sorting will help that.

The reader may have *seen* the message you're replying to yesterday;
today, as an already-seen message, it's not on view at all. No amount
of sorting will help that, either.

Quote what you want to refer to. Snip what you don't. If you don't
make the effort to be read, people won't make the effort to read.
 
D

Default User

Michael said:
The correction applies to the post above the one which you commented.


Don't top-post. Your reply belongs following the quoted material.

There was no "post above". I have my newsreader intelligently set to
display only unread messages. Usenet is not Google. Proper quoting is
required for ALL replies.



Brian
 
R

Richard Bos

Emmanuel Delahaye said:
Me wrote on 06/06/05 :

My definiton of 'formal' must be flawed...

I meant 'not-a-variadic'.

No, you're formally correct, but if all parameters to a variadic
function are known to be the same type (i.e., if all you don't know is
how many there are), then you can simulate a function with only variadic
parameters this way. The first parameter won't actually _be_ variadic,
but to the caller it might as well be. You won't need to pass an extra
arguments stating the number of the other args; you just need to pass a
terminator at the end. For example:

int printstrings(char *first, ...)
{
int count;
va_list arg;
char *str;

if (!first) return 0;

puts(first);
count=1;
va_start(arg, first);
str=va_arg(arg, char *);
while (str) {
puts(str);
count++;
str=va_arg(arg, char *);
}
return count;
}

(It occurs to me that one could write this as
for (va_start(arg, first); str=va_arg(arg, char *); ) {
puts(str);
count++;
}
This might be taking the power of C's for loop too far, but it is
elegant, isn't it?)

This can be called using printstrings((char *)0); or
printstrings("Hello, world!", (char *)0); or printstrings("Second try",
"Hello again", "Even more strings", (char *)0);, just as if it were a
variadic function without any fixed arguments. It does require that you
have some other way of determining the end of the argument list.

Richard
 
E

Emmanuel Delahaye

Richard Bos wrote on 08/06/05 :
No, you're formally correct, but if all parameters to a variadic
function are known to be the same type (i.e., if all you don't know is
how many there are), then you can simulate a function with only variadic
parameters this way. The first parameter won't actually _be_ variadic,
but to the caller it might as well be. You won't need to pass an extra
arguments stating the number of the other args; you just need to pass a
terminator at the end.

Ok, thanks for this enlightment.

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

..sig under repair
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,276
Latest member
Sawatmakal

Latest Threads

Top