Ivan Shmakov <ivan@theory.asu.ru> writes:
Hamish <hamish_b@yahoo.com> writes:
[...]
>> + /* see v.in.ascii for a better solution */
>> + if (opt_fs->answer != NULL) {
>> + if (strcmp(opt_fs->answer, "space") == 0)
>> + fs = ' ';
>> + else if (strcmp(opt_fs->answer, "tab") == 0)
>> + fs = '\t';
>> + else if (strcmp(opt_fs->answer, "\\t") == 0)
>> + fs = '\t';
>> + else
>> + fs = opt_fs->answer[0];
>> + }
>> +
> Oh, the piece of code like this is a sure candidate for a library
> function! (taking into account the number of times it appears in
> the GRASS source.)
The base for this function may be like the following:
void
backslash (char *d, const char *s)
{
/* http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap05.html
*/
char *dp;
const char *sp;
for (dp = d, sp = s; *sp != '\0'; dp++, sp++) {
if (*sp != '\\') {
/* not an escape, just copy */
*dp = *sp;
continue;
}
/* advance to the next character */
++sp;
switch (*sp) {
case '\\': *dp = '\\'; break;
case 'a': *dp = '\a'; break;
case 'b': *dp = '\b'; break;
case 'f': *dp = '\f'; break;
case 'n': *dp = '\n'; break;
case 'r': *dp = '\r'; break;
case 't': *dp = '\t'; break;
case 'v': *dp = '\v'; break;
/* check if it's \O, \OO, \OOO or \xHH */
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7':
case 'x': case 'X':
{
const int hex_p = ((*sp) == 'x' || (*sp) == 'X');
char buf[4], *tail;
long r;
if (hex_p) {
strncpy (buf, sp + 1, 2);
buf[2] = '\0';
} else {
strncpy (buf, sp, sizeof (buf) - 1);
buf[sizeof (buf) - 1] = '\0';
}
/* 1 .. 3 octal or exactly two hexadecimal digits are expected
*/
if ((hex_p && (buf[0] == '\0' || buf[1] == '\0')
|| ((r = strtol (buf, &tail, hex_p ? 16 : 8)),
tail == buf))) {
/* NB: skips over unhandled escapes */
*(dp++) = '\\';
*(dp) = *(sp);
continue;
}
*dp = r;
sp += -1 + (hex_p ? 1 : 0) + (tail - buf);
}
break;
default:
/* NB: skips over unhandled escapes */
*(dp++) = '\\';
*(dp) = *(sp);
continue;
}
}
/* terminate the destination with NUL */
*dp = '\0';
}
Surprisingly enough, coreutils/src/printf.c has its print_esc ()
function putchar ()-based. So, I had to write the above.
Please note that the implementation above has one subtle
difference from that of the GNU Coreutils `printf' utility.
Namely, the latter allows for `\xH', while the former only
accepts `\xHH' (and passes `\xH' untransformed.) Also, the
implementation above gives no warning when for a malformed
escape.
Note also that the function above doesn't generally allow `d'
and `s' to overlap, except for the `d == s' case, which is
allowed.
May I suggest the function above (as `G_backslash') for
`lib/gis/strings.c'?
>> withcats = 0; nfiles = 0;
>> I did it as %c like r.cats, other modules are more liberal and allow
>> %s. Shrug.
> I have no use for %s just now, but there should probably be a
> GRASS-wide policy on using either %c or %s for `fs'. (In order for
> the user to learn this exactly once.)
Since the function above allows strings, I'd opt for allowing a
string for `sep' everywhere.