static int make_db_path(char *dst, const char *src, size_t limit) { int rc = -1; const char *top = _nc_tic_dir(0); if (src == top || _nc_is_abs_path(src)) { if (strlen(src) + 1 <= limit) { _nc_STRCPY(dst, src, limit); rc = 0; } } else { if (strlen(top) + strlen(src) + 2 <= limit) { _nc_SPRINTF(dst, _nc_SLIMIT(limit) "%s/%s", top, src); rc = 0; } } #if USE_HASHED_DB if (rc == 0) { static const char suffix[] = DBM_SUFFIX; size_t have = strlen(dst); size_t need = strlen(suffix); if (have > need && strcmp(dst + (int) (have - need), suffix)) { if (have + need <= limit) { _nc_STRCAT(dst, suffix, limit); } else { rc = -1; } } else if (_nc_is_dir_path(dst)) { rc = -1; } } #endif return rc; }
static void failed(const char *msg) { char temp[BUFSIZ]; size_t len = strlen(_nc_progname) + 2; if ((int) len < (int) sizeof(temp) - 12) { _nc_STRCPY(temp, _nc_progname, sizeof(temp)); _nc_STRCAT(temp, ": ", sizeof(temp)); } else { _nc_STRCPY(temp, "tset: ", sizeof(temp)); } _nc_STRNCAT(temp, msg, sizeof(temp), sizeof(temp) - strlen(temp) - 2); perror(temp); exit_error(); /* NOTREACHED */ }
/* * Convert a string to visible form. */ static char * visible(const char *string) { char *result = 0; size_t need = 1; int pass; int n; if (string != 0 && *string != '\0') { for (pass = 0; pass < 2; ++pass) { for (n = 0; string[n] != '\0'; ++n) { char temp[80]; _nc_STRNCPY(temp, visichar(string[n]), sizeof(temp) - 2); if (pass) { _nc_STRCAT(result, temp, need); } else { need += strlen(temp); } } if (!pass) result = typeCalloc(char, need); } } else {
vsscanf(const char *str, const char *format, va_list ap) { #if HAVE_VFSCANF || HAVE__DOSCAN /* * This code should work on anything descended from AT&T SVr1. */ FILE strbuf; strbuf._flag = _IOREAD; strbuf._ptr = strbuf._base = (unsigned char *) str; strbuf._cnt = strlen(str); strbuf._file = _NFILE; #if HAVE_VFSCANF return (vfscanf(&strbuf, format, ap)); #else return (_doscan(&strbuf, format, ap)); #endif #else static int can_convert = -1; int assigned = 0; int consumed = 0; T((T_CALLED("vsscanf(%s,%s,...)"), _nc_visbuf2(1, str), _nc_visbuf2(2, format))); /* * This relies on having a working "%n" format conversion. Check if it * works. Only very old C libraries do not support it. * * FIXME: move this check into the configure script. */ if (can_convert < 0) { int check1; int check2; if (sscanf("123", "%d%n", &check1, &check2) > 0 && check1 == 123 && check2 == 3) { can_convert = 1; } else { can_convert = 0; } } if (can_convert) { size_t len_fmt = strlen(format) + 32; char *my_fmt = malloc(len_fmt); ChunkType chunk, ctest; OtherType other, otest; ScanState state; unsigned n; int eaten; void *pointer; if (my_fmt != 0) { /* * Split the original format into chunks, adding a "%n" to the end * of each (except of course if it used %n), and use that * information to decide where to start scanning the next chunk. * * FIXME: does %n count bytes or characters? If the latter, this * will require further work for multibyte strings. */ while (*format != '\0') { /* find a chunk */ state = sUnknown; chunk = cUnknown; other = oUnknown; pointer = 0; for (n = 0; format[n] != 0 && state != sFinal; ++n) { my_fmt[n] = format[n]; switch (state) { case sUnknown: if (format[n] == '%') state = sPercent; break; case sPercent: if (format[n] == '%') { state = sUnknown; } else if (format[n] == L_SQUARE) { state = sLeft; } else { state = sNormal; --n; } break; case sLeft: state = sRange; if (format[n] == '^') { ++n; my_fmt[n] = format[n]; } break; case sRange: if (format[n] == R_SQUARE) { state = sFinal; chunk = cRange; } break; case sNormal: if (format[n] == '*') { state = sUnknown; } else { if ((ctest = final_ch(format[n], other)) != cUnknown) { state = sFinal; chunk = ctest; } else if ((otest = other_ch(format[n])) != oUnknown) { other = otest; } else if (isalpha(UChar(format[n]))) { state = sFinal; chunk = cError; } } break; case sFinal: break; } } my_fmt[n] = '\0'; format += n; if (chunk == cUnknown || chunk == cError) { if (assigned == 0) assigned = EOF; break; } /* add %n, if the format was not that */ if (chunk != cAssigned) { _nc_STRCAT(my_fmt, "%n", len_fmt); } switch (chunk) { case cAssigned: _nc_STRCAT(my_fmt, "%n", len_fmt); pointer = &eaten; break; case cInt: pointer = va_arg(ap, int *); break; case cShort: pointer = va_arg(ap, short *); break; case cFloat: pointer = va_arg(ap, float *); break; case cDouble: pointer = va_arg(ap, double *); break; case cLong: pointer = va_arg(ap, long *); break; case cPointer: pointer = va_arg(ap, void *); break; case cChar: case cRange: case cString: pointer = va_arg(ap, char *); break; case cError: case cUnknown: break; } /* do the conversion */ T(("...converting chunk #%d type %d(%s,%s)", assigned + 1, chunk, _nc_visbuf2(1, str + consumed), _nc_visbuf2(2, my_fmt))); if (sscanf(str + consumed, my_fmt, pointer, &eaten) > 0) consumed += eaten; else break; ++assigned; } free(my_fmt); } } returnCode(assigned); #endif }
static int next_char(void) { static char *result; static size_t allocated; int the_char; if (!yyin) { if (result != 0) { FreeAndNull(result); FreeAndNull(pushname); allocated = 0; } /* * An string with an embedded null will truncate the input. This is * intentional (we don't read binary files here). */ if (bufptr == 0 || *bufptr == '\0') return (EOF); if (*bufptr == '\n') { _nc_curr_line++; _nc_curr_col = 0; } else if (*bufptr == '\t') { _nc_curr_col = (_nc_curr_col | 7); } } else if (!bufptr || !*bufptr) { /* * In theory this could be recoded to do its I/O one character at a * time, saving the buffer space. In practice, this turns out to be * quite hard to get completely right. Try it and see. If you * succeed, don't forget to hack push_back() correspondingly. */ size_t used; size_t len; do { bufstart = 0; used = 0; do { if (used + (LEXBUFSIZ / 4) >= allocated) { allocated += (allocated + LEXBUFSIZ); result = typeRealloc(char, allocated, result); if (result == 0) return (EOF); if (bufstart) bufstart = result; } if (used == 0) _nc_curr_file_pos = ftell(yyin); if (fgets(result + used, (int) (allocated - used), yyin) != 0) { bufstart = result; if (used == 0) { if (_nc_curr_line == 0 && IS_TIC_MAGIC(result)) { _nc_err_abort("This is a compiled terminal description, not a source"); } _nc_curr_line++; _nc_curr_col = 0; } } else { if (used != 0) _nc_STRCAT(result, "\n", allocated); } if ((bufptr = bufstart) != 0) { used = strlen(bufptr); while (iswhite(*bufptr)) { if (*bufptr == '\t') { _nc_curr_col = (_nc_curr_col | 7) + 1; } else { _nc_curr_col++; } bufptr++; } /* * Treat a trailing <cr><lf> the same as a <newline> so we * can read files on OS/2, etc. */ if ((len = strlen(bufptr)) > 1) { if (bufptr[len - 1] == '\n' && bufptr[len - 2] == '\r') { len--; bufptr[len - 1] = '\n'; bufptr[len] = '\0'; } } } else { return (EOF); } } while (bufptr[len - 1] != '\n'); /* complete a line */ } while (result[0] == '#'); /* ignore comments */