コード例 #1
0
ファイル: isbn.c プロジェクト: magsilva/bibclean
void
do_print_ISBN_table(VOID)
{
    size_t k;

    /* For brevity and readability, we output the country/language
       group prefix only when it changes, preceded by pair of newlines. */

    fprintf(stdlog, "%%%%%% ISBN ranges and country/language groups\n");
    for (k = 0; (ISBN_range[k].begin != (const char *)NULL); ++k)
    {
	const char *country_names;

	if (k == 0)
	{
	    if (ISBN_range[k].countries[0] == '\0')
		country_names = (const char *)NULL;
	    else
		country_names = ISBN_range[k].countries;
	}
	else if (STREQUAL(ISBN_range[k-1].countries,ISBN_range[k].countries) &&
		 (ISBN_match_country_language(ISBN_range[k-1].begin,ISBN_range[k].begin) == YES))
	    country_names = (const char *)NULL;
	else if (ISBN_range[k].countries[0] == '\0')
	    country_names = (const char *)NULL;
	else
	    country_names = ISBN_range[k].countries;

	/* We intentionally include `deleted' entries (beginning with a hyphen), so
	   as not to conceal information from the user. */
	fprintf(stdlog, "%s%-11s\t%-11s%s%s\n",
		      ((country_names == (const char *)NULL) ? "" : "\n\n"),
		      ISBN_range[k].begin,
		      ISBN_range[k].end,
		      ((country_names == (const char *)NULL) ? "" : "\t"),
		      ((country_names == (const char *)NULL) ? "" : country_names));
    }
}
コード例 #2
0
ファイル: isbn.c プロジェクト: magsilva/bibclean
/*
 * Search the ISBN_range[] table circularly from the last search
 * position for the next non-empty slot matching the_begin, and
 * install the new triple (the_begin,the_end,the_countries) there.
 * Otherwise, add the triple at the end, if enough space remains.
 */
static void
add_ISBN_range(const char *the_begin, const char *the_end, const char *the_countries)
{
    static int error_count = 0;
    size_t k;
    static size_t start = (size_t) 0;

    /* Silently ignore invalid begin/end pairs */
    if (the_begin == (const char *)NULL)
	return;
    else if (the_end == (const char *)NULL)
	return;

    if (the_begin[0] == '-')
	start = 0;	/* because deletions must always find the first match */

    for (k = start;
	 (k < MAX_ISBN_RANGE) && (ISBN_range[k].begin != (const char *)NULL);
	 ++k)
    {
	if (ISBN_range[k].begin[0] == '-')
	{
	    if (STREQUAL(ISBN_range[k].begin,the_begin))
	    {				/* then already deleted this one */
		start = k;
		return;
	    }
	    else
	        continue;		/* ignore `deleted' entries */
	}
	else if ((the_begin[0] == '-') && STREQUAL(ISBN_range[k].begin, the_begin + 1))
	{	/* then `delete' this entry by changing its begin prefix to start with a hyphen */
	    ISBN_range[k].begin = Strdup(the_begin);
	    start = k;
	    return;
	}
	else if (STREQUAL(ISBN_range[k].begin, the_begin))
	{
	    add_one_ISBN_range(the_begin, the_end, the_countries, k);
	    start = k;
	    return;
	}
    }

    /* If we fell through, then restart the search in the beginning of the table */
    for (k = 0;
	 (k < start) && (ISBN_range[k].begin != (const char *)NULL); ++k)
    {
	if (ISBN_range[k].begin[0] == '-')
	{
	    if (STREQUAL(ISBN_range[k].begin,the_begin))
	    {				/* then already deleted this one */
		start = k;
		return;
	    }
	    else
	        continue;		/* ignore `deleted' entries */
	}
	else if ((the_begin[0] == '-') && STREQUAL(ISBN_range[k].begin, the_begin + 1))
	{	/* then `delete' this entry by changing its begin prefix to start with a hyphen */
	    ISBN_range[k].begin = Strdup(the_begin);
	    start = k;
	    return;
	}
	else if (STREQUAL(ISBN_range[k].begin, the_begin))
	{
	    add_one_ISBN_range(the_begin, the_end, the_countries, k);
	    start = k;
	    return;
	}
    }

    /* If we fell through, then add the new entry at the first deleted
       entry, or after the last used entry */
    for (k = 0;
	 ((k < MAX_ISBN_RANGE) &&
	  (ISBN_range[k].begin != (const char *)NULL) &&
	  (ISBN_range[k].begin[0] != '\0'));
	 ++k)
	continue;

    if (k < (MAX_ISBN_RANGE - 1))	/* then have space to store this new entry */
    {
	start = k;
	add_one_ISBN_range(the_begin, the_end, the_countries, k);
    }
    else if (++error_count == 1)	/* no more than one error message */
	fprintf(stdlog,
		      "More than %lu ISBN ranges fills internal table\n",
		      (unsigned long)MAX_ISBN_RANGE);
}
コード例 #3
0
static char *hbc_action(void *context, HBC_CALL_BACKS *cb,
			        const char *map_class, const char *where,
			        const char *cmd, const char *line,
			        ssize_t line_len, off_t offset)
{
    const char *cmd_args = cmd + strcspn(cmd, " \t");
    int     cmd_len = cmd_args - cmd;
    char   *ret;

    /*
     * XXX We don't use a hash table for action lookup. Mail rarely triggers
     * an action, and mail that triggers multiple actions is even rarer.
     * Setting up the hash table costs more than we would gain from using it.
     */
    while (*cmd_args && ISSPACE(*cmd_args))
	cmd_args++;

#define STREQUAL(x,y,l) (strncasecmp((x), (y), (l)) == 0 && (y)[l] == 0)

    if (cb->extend
	&& (ret = cb->extend(context, cmd, cmd_len, cmd_args, where, line,
			     line_len, offset)) != HBC_CHECKS_STAT_UNKNOWN)
	return (ret);

    if (STREQUAL(cmd, "WARN", cmd_len)) {
	cb->logger(context, "warning", where, line, cmd_args);
	return ((char *) line);
    }
    if (STREQUAL(cmd, "INFO", cmd_len)) {
	cb->logger(context, "info", where, line, cmd_args);
	return ((char *) line);
    }
    if (STREQUAL(cmd, "REPLACE", cmd_len)) {
	if (*cmd_args == 0) {
	    msg_warn("REPLACE action without text in %s map", map_class);
	    return ((char *) line);
	} else if (strcmp(where, HBC_CTXT_HEADER) == 0
		   && !is_header(cmd_args)) {
	    msg_warn("bad REPLACE header text \"%s\" in %s map -- "
		   "need \"headername: headervalue\"", cmd_args, map_class);
	    return ((char *) line);
	} else {
	    cb->logger(context, "replace", where, line, cmd_args);
	    return (mystrdup(cmd_args));
	}
    }
    if (cb->prepend && STREQUAL(cmd, "PREPEND", cmd_len)) {
	if (*cmd_args == 0) {
	    msg_warn("PREPEND action without text in %s map", map_class);
	} else if (strcmp(where, HBC_CTXT_HEADER) == 0
		   && !is_header(cmd_args)) {
	    msg_warn("bad PREPEND header text \"%s\" in %s map -- "
		   "need \"headername: headervalue\"", cmd_args, map_class);
	} else {
	    cb->logger(context, "prepend", where, line, cmd_args);
	    cb->prepend(context, REC_TYPE_NORM, cmd_args, strlen(cmd_args), offset);
	}
	return ((char *) line);
    }
    /* Allow and ignore optional text after the action. */

    if (STREQUAL(cmd, "IGNORE", cmd_len))
	/* XXX Not logged for compatibility with cleanup(8). */
	return (HBC_CHECKS_STAT_IGNORE);

    if (STREQUAL(cmd, "DUNNO", cmd_len)		/* preferred */
	||STREQUAL(cmd, "OK", cmd_len))		/* compatibility */
	return ((char *) line);

    msg_warn("unsupported command in %s map: %s", map_class, cmd);
    return ((char *) line);
}