Beispiel #1
0
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;
}
Beispiel #2
0
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 {
Beispiel #4
0
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
}
Beispiel #5
0
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 */