| 9382 | } |
| 9383 | |
| 9384 | int |
| 9385 | sym_val(const char *strval) /* up to 4*BUFSZ-1 long; only first few |
| 9386 | chars matter */ |
| 9387 | { |
| 9388 | char buf[QBUFSZ], tmp[QBUFSZ]; /* to hold truncated copy of 'strval' */ |
| 9389 | |
| 9390 | buf[0] = '\0'; |
| 9391 | if (!strval[0] || !strval[1]) { /* empty, or single character */ |
| 9392 | /* if single char is space or tab, leave buf[0]=='\0' */ |
| 9393 | if (!isspace((uchar) strval[0])) |
| 9394 | buf[0] = strval[0]; |
| 9395 | } else if (strval[0] == '\'') { /* single quote */ |
| 9396 | /* simple matching single quote; we know strval[1] isn't '\0' */ |
| 9397 | if (strval[2] == '\'' && !strval[3]) { |
| 9398 | /* accepts '\' as backslash and ''' as single quote */ |
| 9399 | buf[0] = strval[1]; |
| 9400 | |
| 9401 | /* if backslash, handle single or double quote or second backslash */ |
| 9402 | } else if (strval[1] == '\\' && strval[2] && strval[3] == '\'' |
| 9403 | && strchr("'\"\\", strval[2]) && !strval[4]) { |
| 9404 | buf[0] = strval[2]; |
| 9405 | |
| 9406 | /* not simple quote or basic backslash; |
| 9407 | strip closing quote and let escapes() deal with it */ |
| 9408 | } else { |
| 9409 | char *p; |
| 9410 | |
| 9411 | /* +1: skip opening single quote */ |
| 9412 | (void) strncpy(tmp, strval + 1, sizeof tmp - 1); |
| 9413 | tmp[sizeof tmp - 1] = '\0'; |
| 9414 | if ((p = strrchr(tmp, '\'')) != 0) { |
| 9415 | *p = '\0'; |
| 9416 | escapes(tmp, buf); |
| 9417 | } /* else buf[0] stays '\0' */ |
| 9418 | } |
| 9419 | } else { /* not lone char nor single quote */ |
| 9420 | (void) strncpy(tmp, strval, sizeof tmp - 1); |
| 9421 | tmp[sizeof tmp - 1] = '\0'; |
| 9422 | escapes(tmp, buf); |
| 9423 | } |
| 9424 | |
| 9425 | return (int) *buf; |
| 9426 | } |
| 9427 | |
| 9428 | /* data for option_help() */ |
| 9429 | static const char *opt_intro[] = { |
no test coverage detected