Wednesday Sep 03, 2008
Wednesday Sep 03, 2008
As of today, strsep() function lives in Nevada's libc (tracked by CR 4383867 and PSARC 2008/305). This constitutes another step in the quest for more feature-full (in terms of compatibility) libc in OpenSolaris. In binary form, the changes will be available in build 99. The documentation will be part of the string(3C) man page.
Here's a small example of how to use it:
#include <stdio.h>
#include <string.h>
#include <err.h>
int parse(const char *str) {
char *p = NULL;
char *inputstring, *origstr;
int ret = 1;
if (str == NULL)
errx(1, "NULL string");
/*
* We have to remember original pointer because strsep()
* will change 'inputstr' pointer.
*/
if ((origstr = inputstring = strdup(str)) == NULL)
errx(1, "strdup() failed");
printf("=== parsing '%s'\n", inputstring);
for ((p = strsep(&inputstring, ",")); p != NULL;
(p = strsep(&inputstring, ","))) {
if (p != NULL && *p != '\0')
printf("%s\n", p);
else if (p != NULL) {
warnx("syntax error");
ret = 0;
goto bad;
}
}
bad:
printf("=== finished parsing\n");
free(origstr);
return (ret);
}
int main(int argc, char *argv[]) {
if (argc != 2)
errx(1, "usage: prog ");
if (!parse(argv[1]))
exit(1);
return (0);
}
This example was actually used as a unit test (use e.g. "1,22,33,44" and "1,22,,44,33" as input string) and it also nicely illustrates important properties of strsep() behavior:
There is a function in Solaris' libc which can do token splitting and does not modify the original string - strcspn(). The other notable property of strsep() is that (unlike strtok()) it does not conform to ANSI-C. Time to draw a table:
function(s) ISO C90 modifies detects
input empty fields
-------------+----------+----------+--------------+
strsep() No Yes Yes
strtok() Yes Yes No
strcspn() Yes No Sort of
None of the above functions is bullet-proof. The bottom line is the user should decide which is the most suitable for given task and use it with its properties in mind.
tags:
libc
onnv
opensolaris
strsep
Linkage:
Technorati cosmos
Tuesday Aug 28, 2007
In my previous entry about BSD compatibility gap closure process I have promised to provide a guide on how to get new code into libc. I will use changes done via CR 6495220 to illustrate the process with examples.
Process related and technical changes which are usually needed:
$ nm -x /usr/lib/libc.so.1 | grep '|_\?err$' [5783] |0x00049c40|0x00000030|FUNC |GLOB |0 |13 |_err [6552] |0x00049c40|0x00000030|FUNC |WEAK |0 |13 |err
pvs -dsv -N SUNW_1.23 /usr/lib/libc.so.1 \
| sed -n '1,/SUNW.*:/p' | egrep '((v?errx?)|(v?warnx?));'
vwarnx;
...
If you're adding private (underscored) symbols do not forget to add them to the SUNWprivate section. This is usually the case because the strong symbols
are accompanied by weak symbols. Weak symbols go to the global part of the most recent
SUNW section and strong symbols go to global part of SUNWprivate section.
foo = FUNCTION FILTER libc.so.1;This was done with the *fp functions in libipsecutils' mapfile. The specialty in that case was that the *fp functions were renamed to underscored variants while moving them via redefines in errfp.h.
/builds/.../usr/include/err.h", line 43: warning: function argument declared inconsistently: warn(arg 1) in utils.c(62) char * and llib-lc:err.h(43) const char * (E_INCONS_ARG_DECL2)The problem with this output is that there are cca 23 files named utils.c in ONNV. CR 6585621 is waiting someone to provide remedy for that via adding -F flag to LINTFLAGS in $SRC/lib and $SRC/cmd.
[6583] | 301316| 37|FUNC |GLOB |0 |13 |_warnx [1925] | 320000| 96|FUNC |LOCL |0 |13 |_warnxThis can be usually solved by renaming the local variant.
tags:
bsd
libc
opensolaris
solaris
Linkage:
Technorati cosmos