summaryrefslogtreecommitdiff
path: root/pith/osdep
diff options
context:
space:
mode:
Diffstat (limited to 'pith/osdep')
-rw-r--r--pith/osdep/color.c1256
-rw-r--r--pith/osdep/color.h25
2 files changed, 2 insertions, 1279 deletions
diff --git a/pith/osdep/color.c b/pith/osdep/color.c
index cad5502e..faf3c675 100644
--- a/pith/osdep/color.c
+++ b/pith/osdep/color.c
@@ -31,7 +31,7 @@ static char rcsid[] = "$Id: color.c 761 2007-10-23 22:35:18Z hubert@u.washington
#include <system.h>
#include "./color.h"
-#include "./collate.h"
+
/*
@@ -91,1257 +91,3 @@ pico_set_colorp(COLOR_PAIR *col, int flags)
{
return(pico_set_colors(col ? col->fg : NULL, col ? col->bg : NULL, flags));
}
-
-
- /*
- * Extended Justification support also does not belong here
- * but otherwise webpine will not build, so we move everything
- * here. Hopefully this will be the permanent place for these
- * routines. These routines used to be in pico/word.c
- */
-#define NSTRING 256
-#include "../../include/general.h"
-
-/* Support of indentation of paragraphs */
-#define is_indent_char(c) (((c) == '.' || (c) == '}' || (c) == RPAREN || \
- (c) == '*' || (c) == '+' || is_a_digit(c) || \
- ISspace(c) || (c) == '-' || \
- (c) == ']') ? 1 : 0)
-#define allowed_after_digit(c,word,k) ((((c) == '.' && \
- allowed_after_period(next((word),(k)))) ||\
- (c) == RPAREN || (c) == '}' || (c) == ']' ||\
- ISspace(c) || is_a_digit(c) || \
- ((c) == '-' ) && \
- allowed_after_dash(next((word),(k)))) \
- ? 1 : 0)
-#define allowed_after_period(c) (((c) == RPAREN || (c) == '}' || (c) == ']' ||\
- ISspace(c) || (c) == '-' || \
- is_a_digit(c)) ? 1 : 0)
-#define allowed_after_parenth(c) (ISspace(c) ? 1 : 0)
-#define allowed_after_space(c) (ISspace(c) ? 1 : 0)
-#define allowed_after_braces(c) (ISspace(c) ? 1 : 0)
-#define allowed_after_star(c) ((ISspace(c) || (c) == RPAREN ||\
- (c) == ']' || (c) == '}') ? 1 : 0)
-#define allowed_after_dash(c) ((ISspace(c) || is_a_digit(c)) ? 1 : 0)
-#define EOLchar(c) (((c) == '.' || (c) == ':' || (c) == '?' ||\
- (c) == '!') ? 1 : 0)
-
-
-/* Extended justification support */
-#define is_cquote(c) ((c) == '>' || (c) == '|' || (c) == ']' || (c) == ':')
-#define is_cword(c) ((((c) >= 'a') && ((c) <= 'z')) || \
- (((c) >= 'A') && ((c) <= 'Z')) || \
- (((c) >= '0') && ((c) <= '9')) || \
- ((c) == ' ') || ((c) == '?') || \
- ((c) == '@') || ((c) == '.') || \
- ((c) == '!') || ((c) == '\'') || \
- ((c) == ',') || ((c) == '\"') ? 1 : 0)
-#define isaquote(c) ((c) == '\"' || (c) == '\'')
-#define is8bit(c) ((((int) (c)) & 0x80) ? 1 : 0)
-#define iscontrol(c) (iscntrl(((int) (c)) & 0x7f) ? 1 : 0)
-#define forbidden(c) (((c) == '\"') || ((c) == '\'') || ((c) == '$') ||\
- ((c) == ',') || ((c) == '.') || ((c) == '-') ||\
- ((c) == LPAREN) || ((c) == '/')|| ((c) == '`') ||\
- ((c) == '{') || ((c) == '\\') || (iscontrol((c))) ||\
- (((c) >= '0') && ((c) <= '9')) || ((c) == '?'))
-#define is_cletter(c) ((((c) >= 'a') && ((c) <= 'z'))) ||\
- ((((c) >= 'A') && ((c) <= 'Z'))||\
- is8bit(c))
-#define is_cnumber(c) ((c) >= '0' && (c) <= '9')
-#define allwd_after_word(c) (((c) == ' ') || ((c) == '>') || is_cletter(c))
-#define allwd_after_qsword(c) (((c) != '\\') && ((c) != RPAREN))
-#define before(word,i) (((i) > 0) ? (word)[(i) - 1] : 0)
-#define next(w,i) ((((w)[(i)]) != 0) ? ((w)[(i) + 1]) : 0)
-#define now(w,i) ((w)[(i)])
-#define is_qsword(c) (((c) == ':') || ((c) == RPAREN) ? 1 : 0)
-#define is_colon(c) (((c) == ':') ? 1 : 0)
-#define is_rarrow(c) (((c) == '>') ? 1 : 0)
-#define is_tilde(c) (((c) == '~') ? 1 : 0)
-#define is_dash(c) (((c) == '-') ? 1 : 0)
-#define is_pound(c) (((c) == '#') ? 1 : 0)
-#define is_a_digit(c) ((((c) >= '0') && ((c) <= '9')) ? 1 : 0)
-#define is_allowed(c) (is_cquote(c) || is_cword(c) || is_dash(c) || \
- is_pound(c))
-#define qs_allowed(a) (((a)->qstype != qsGdb) && ((a)->qstype != qsProg))
-
-/* Internal justification functions */
-QSTRING_S *is_quote(char **, char *, int);
-QSTRING_S *qs_normal_part(QSTRING_S *);
-QSTRING_S *qs_remove_trailing_spaces(QSTRING_S *);
-QSTRING_S *trim_qs_from_cl(QSTRING_S *, QSTRING_S *, QSTRING_S *);
-QSTRING_S *fix_qstring(QSTRING_S *, QSTRING_S *, QSTRING_S *);
-QSTRING_S *fix_qstring_allowed(QSTRING_S *, QSTRING_S *, QSTRING_S *);
-QSTRING_S *qs_add(char **, char *, QStrType, int, int, int, int);
-QSTRING_S *remove_qsword(QSTRING_S *);
-QSTRING_S *do_raw_quote_match(char **, char *, char *, char *, QSTRING_S **, QSTRING_S **);
-void free_qs(QSTRING_S **);
-int word_is_prog(char *);
-int qstring_is_normal(QSTRING_S *);
-int exists_good_part(QSTRING_S *);
-int strcmp_qs(char *, char *);
-int count_levels_qstring(QSTRING_S *);
-int same_qstring(QSTRING_S *, QSTRING_S *);
-int isaword(char *,int ,int);
-int isamailbox(char *,int ,int);
-int double_check_qstr(char *);
-
-int
-word_is_prog(char *word)
-{
- static char *list1[] = {"#include",
- "#define",
- "#ifdef",
- "#ifndef",
- "#elif",
- "#if",
- NULL};
- static char *list2[] = {"#else",
- "#endif",
- NULL};
- int i, j = strlen(word), k, rv = 0;
-
- for(i = 0; rv == 0 && list1[i] && (k = strlen(list1[i])) && k < j; i++)
- if(!strncmp(list1[i], word, k) && ISspace(word[k]))
- rv++;
-
- if(rv)
- return rv;
-
- for(i = 0; rv == 0 && list2[i] && (k = strlen(list2[i])) && k <= j; i++)
- if(!strncmp(list2[i], word, k) && (!word[k] || ISspace(word[k])))
- rv++;
-
- return rv;
-}
-
-/*
- * This function creates a qstring pointer with the information that
- * is_quote handles to it.
- * Parameters:
- * qs - User supplied quote string
- * word - The line of text that the user is trying to read/justify
- * beginw - Where we need to start copying from
- * endw - Where we end copying
- * offset - Any offset in endw that we need to account for
- * typeqs - type of the string to be created
- * neednext - boolean, indicating if we need to compute the next field
- * of leave it NULL
- *
- * It is a mistake to call this function if beginw >= endw + offset.
- * Please note the equality sign in the above inequality (this is because
- * we always assume that qstring->value != "").
- */
-QSTRING_S *
-qs_add(char **qs, char word[NSTRING], QStrType typeqs, int beginw, int endw,
- int offset, int neednext)
-{
- QSTRING_S *qstring, *nextqs;
- int i;
-
- qstring = (QSTRING_S *) malloc (sizeof(QSTRING_S));
- memset (qstring, 0, sizeof(QSTRING_S));
- qstring->qstype = qsNormal;
-
- if (beginw == 0){
- beginw = endw + offset;
- qstring->qstype = typeqs;
- }
-
- nextqs = neednext ? is_quote(qs, word+beginw, 1) : NULL;
-
- qstring->value = (char *) malloc((beginw+1)*sizeof(char));
- strncpy(qstring->value, word, beginw);
- qstring->value[beginw] = '\0';
-
- qstring->next = nextqs;
-
- return qstring;
-}
-
-int
-qstring_is_normal(QSTRING_S *cl)
-{
- for (;cl && (cl->qstype == qsNormal); cl = cl->next);
- return cl ? 0 : 1;
-}
-
-/*
- * Given a quote string, this function returns the part that is the leading
- * normal part of it. (the normal part is the part that is tagged qsNormal,
- * that is to say, the one that is not controversial at all (like qsString
- * for example).
- */
-QSTRING_S *
-qs_normal_part(QSTRING_S *cl)
-{
-
- if (!cl) /* nothing in, nothing out */
- return cl;
-
- if (cl->qstype != qsNormal)
- free_qs(&cl);
-
- if (cl)
- cl->next = qs_normal_part(cl->next);
-
- return cl;
-}
-
-/*
- * this function removes trailing spaces from a quote string, but leaves the
- * last one if there are trailing spaces
- */
-QSTRING_S *
-qs_remove_trailing_spaces(QSTRING_S *cl)
-{
- QSTRING_S *rl = cl;
- if (!cl) /* nothing in, nothing out */
- return cl;
-
- if (cl->next)
- cl->next = qs_remove_trailing_spaces(cl->next);
- else{
- if (value_is_space(cl->value))
- free_qs(&cl);
- else{
- int i, l;
- i = l = strlen(cl->value) - 1;
- while (cl->value && cl->value[i]
- && ISspace(cl->value[i]))
- i--;
- i += (i < l) ? 2 : 1;
- cl->value[i] = '\0';
- }
- }
- return cl;
-}
-
-/*
- * This function returns if two strings are the same quote string.
- * The call is not symmetric. cl must preceed the line nl. This function
- * should be called for comparing the last part of cl and nl.
- */
-int
-strcmp_qs(char *valuecl, char *valuenl)
-{
- int j;
-
- for (j = 0; valuecl[j] && (valuecl[j] == valuenl[j]); j++);
- return !strcmp(valuecl, valuenl)
- || (valuenl[j] && value_is_space(valuenl+j)
- && value_is_space(valuecl+j)
- && strlenis(valuecl+j) >= strlenis(valuenl+j))
- || (!valuenl[j] && value_is_space(valuecl+j));
-}
-
-int
-count_levels_qstring(QSTRING_S *cl)
-{
- int count;
- for (count = 0; cl ; count++, cl = cl->next);
-
- return count;
-}
-
-int
-value_is_space(char *value)
-{
- for (; value && *value && ISspace(*value); value++);
-
- return value && *value ? 0 : 1;
-}
-
-void
-free_qs(QSTRING_S **cl)
-{
- if (!(*cl))
- return;
-
- if ((*cl)->next)
- free_qs(&((*cl)->next));
-
- (*cl)->next = (QSTRING_S *) NULL;
-
- if ((*cl)->value)
- free((void *)(*cl)->value);
- (*cl)->value = (char *) NULL;
- free((void *)(*cl));
- *cl = (QSTRING_S *) NULL;
-}
-
-/*
- * This function returns the number of agreements between
- * cl and nl. The call is not symmetric. cl must be the line
- * preceding nl.
- */
-int
-same_qstring(QSTRING_S *cl, QSTRING_S *nl)
-{
- int same = 0, done = 0;
-
- for (;cl && nl && !done; cl = cl->next, nl = nl->next)
- if (cl->qstype == nl->qstype
- && (!strcmp(cl->value, nl->value)
- || (!cl->next && strcmp_qs(cl->value, nl->value))))
- same++;
- else
- done++;
- return same;
-}
-
-QSTRING_S *
-trim_qs_from_cl(QSTRING_S *cl, QSTRING_S *nl, QSTRING_S *pl)
-{
- QSTRING_S *cqstring = pl ? pl : nl;
- QSTRING_S *tl = pl ? pl : nl;
- int p, c;
-
- if (qstring_is_normal(tl))
- return tl;
-
- p = same_qstring(pl ? pl : cl, pl ? cl : nl);
-
- for (c = 1; c < p; c++, cl = cl->next, tl = tl->next);
-
- /*
- * cl->next and tl->next differ, it may be because cl->next does not
- * exist or tl->next does not exist or simply both exist but are
- * different. In this last case, it may be that cl->next->value is made
- * of spaces. If this is the case, tl advances once more.
- */
-
- if (tl->next){
- if (cl && cl->next && value_is_space(cl->next->value))
- tl = tl->next;
- if (tl->next)
- free_qs(&(tl->next));
- }
-
- if (!p)
- free_qs(&cqstring);
-
- return cqstring;
-}
-
-/* This function trims cl so that it returns a real quote string based
- * on information gathered from the previous and next lines. pl and cl are
- * also trimmed, but that is done in another function, not here.
- */
-QSTRING_S *
-fix_qstring(QSTRING_S *cl, QSTRING_S *nl, QSTRING_S *pl)
-{
- QSTRING_S *cqstring = cl, *nqstring = nl, *pqstring = pl;
- int c, n;
-
- if (qstring_is_normal(cl))
- return cl;
-
- c = count_levels_qstring(cl);
- n = same_qstring(cl,nl);
-
- if (!n){ /* no next line or no agreement with next line */
- int p = same_qstring(pl, cl); /* number of agreements between pl and cl */
- QSTRING_S *tl; /* test line */
-
- /*
- * Here p <= c, so either p < c or p == c. If p == c, we are done,
- * and return cl. If not, there are two cases, either p == 0 or
- * 0 < p < c. In the first case, we do not have enough evidence
- * to return anything other than the normal part of cl, in the second
- * case we can only return p levels of cl.
- */
-
- if (p == c)
- tl = cqstring;
- else{
- if (p){
- for (c = 1; c < p; c++)
- cl = cl->next;
- free_qs(&(cl->next));
- tl = cqstring;
- }
- else{
- int done = 0;
- QSTRING_S *al = cl; /* another line */
- /*
- * Ok, we really don't have enough evidence to return anything,
- * different from the normal part of cl, but it could be possible
- * that we may want to accept the not-normal part, so we better
- * make an extra test to determine what needs to be freed
- */
- while (pl && cl && cl->qstype == pl->qstype
- && !strucmp(cl->value, pl->value)){
- cl = cl->next;
- pl = pl->next;
- }
- if (pl && cl && cl->qstype == pl->qstype
- && strcmp_qs(pl->value, cl->value))
- cl = cl->next; /* next level differs only in spaces */
- while (!done){
- while (cl && cl->qstype == qsNormal)
- cl = cl->next;
- if (cl){
- if ((cl->qstype == qsString)
- && (cl->value[strlen(cl->value) - 1] == '>'))
- cl = cl->next;
- else done++;
- }
- else done++;
- }
- if (al == cl){
- free_qs(&(cl));
- tl = cl;
- }
- else {
- while (al && (al->next != cl))
- al = al->next;
- cl = al;
- if (cl && cl->next)
- free_qs(&(cl->next));
- tl = cqstring;
- }
- }
- }
- return tl;
- }
- if (n + 1 < c){ /* if there are not enough agreements */
- int p = same_qstring(pl, cl); /* number of agreement between pl and cl */
- QSTRING_S *tl; /* test line */
- /*
- * There's no way we can use cl in this case, but we can use
- * part of cl, this is if pl does not have more agreements
- * with cl.
- */
- if (p == c)
- tl = cqstring;
- else{
- int m = p < n ? n : p;
- for (c = 1; c < m; c++){
- pl = pl ? pl->next : (QSTRING_S *) NULL;
- nl = nl ? nl->next : (QSTRING_S *) NULL;
- cl = cl->next;
- }
- if (p == n && pl && pl->next && nl && nl->next
- && ((cl->next->qstype == pl->next->qstype)
- || (cl->next->qstype == nl->next->qstype))
- && (strcmp_qs(cl->next->value, pl->next->value)
- || strcmp_qs(pl->next->value, cl->next->value)
- || strcmp_qs(cl->next->value, nl->next->value)
- || strcmp_qs(nl->next->value, cl->next->value)))
- cl = cl->next; /* next level differs only in spaces */
- if (cl->next)
- free_qs(&(cl->next));
- tl = cqstring;
- }
- return tl;
- }
- if (n + 1 == c){
- int p = same_qstring(pl, cl);
- QSTRING_S *tl; /* test line */
-
- /*
- * p <= c, so p <= n+1, which means p < n + 1 or p == n + 1.
- * If p < n + 1, then p <= n.
- * so we have three possibilities:
- * p == n + 1 or p == n or p < n.
- * In the first case we copy p == n + 1 == c levels, in the second
- * and third case we copy n levels, and check if we can copy the
- * n + 1 == c level.
- */
- if (p == n + 1) /* p == c, in the above sense of c */
- tl = cl; /* use cl, this is enough evidence */
- else{
- for (c = 1; c < n; c++)
- cl = cl->next;
- /*
- * Here c == n, we only have one more level of cl, and at least one
- * more level of nl
- */
- if (cl->next->qstype == qsNormal)
- cl = cl->next;
- if (cl->next)
- free_qs(&(cl->next));
- tl = cqstring;
- }
- return tl;
- }
- if (n == c) /* Yeah!!! */
- return cqstring;
-}
-
-QSTRING_S *
-fix_qstring_allowed(QSTRING_S *cl, QSTRING_S *nl, QSTRING_S *pl)
-{
- if(!cl)
- return (QSTRING_S *) NULL;
-
- if (qs_allowed(cl))
- cl->next = fix_qstring_allowed(cl->next, (nl ? nl->next : NULL),
- (pl ? pl->next : NULL));
- else
- if((nl && cl->qstype == nl->qstype) || (pl && cl->qstype == pl->qstype)
- || (!nl && !pl))
- free_qs(&cl);
- return cl;
-}
-
-/*
- * This function flattens the quote string returned to us by is_quote. A
- * crash in this function implies a bug elsewhere.
- */
-void
-flatten_qstring(QSTRING_S *qs, char *buff, int bufflen)
-{
- int i, j;
- if(!buff || bufflen <= 0)
- return;
-
- for (i = 0; qs; qs = qs->next)
- for (j = 0; i < bufflen - 1
- && (qs->value[j]) && (buff[i++] = qs->value[j]); j++);
- buff[i] = '\0';
-}
-
-extern int list_len;
-
-
-int
-double_check_qstr(char *q)
-{
- if(!q || !*q)
- return 0;
-
- return (*q == '#') ? 1 : 0;
-}
-
-/*
- * Given a string, we return the position where the function thinks that
- * the quote string is over, if you are ever thinking of fixing something,
- * you got to the right place. Memory freed by caller. Experience shows
- * that it only makes sense to initialize memory when we need it, not at
- * the start of this function.
- */
-QSTRING_S *
-is_quote (char **qs,char *word, int been_here)
-{
- int i = 0, j, nxt, prev, finished = 0, offset;
- unsigned char c;
- QSTRING_S *qstring = (QSTRING_S *) NULL;
-
- if (word == NULL || word[0] == '\0')
- return (QSTRING_S *) NULL;
-
- while (!finished){
- /*
- * Before we apply our rules, let's advance past the quote string
- * given by the user, this will avoid not recognition of the
- * user's indent string and application of the arbitrary rules
- * below. Notice that this step may bring bugs into this
- * procedure, but these bugs will only appear if the indent string
- * is really really strange and the text to be justified
- * cooperates a lot too, so in general this will not be a problem.
- * If you are concerned about this bug, simply remove the
- * following lines after this comment and before the "switch"
- * command below and use a more normal quote string!.
- */
- for(j = 0; j < list_len; j++){
- if(!double_check_qstr(qs[j])){
- i += advance_quote_string(qs[j], word, i);
- if (!word[i]) /* went too far? */
- return qs_add(qs, word, qsNormal, 0, i, 0, 0);
- }
- else
- break;
- }
-
- switch (c = (unsigned char) now(word,i)){
- case NBSP:
- case TAB :
- case ' ' : { QSTRING_S *nextqs, *d;
-
- for (; ISspace(word[i]); i++); /* FIX ME */
- nextqs = is_quote(qs,word+i, 1);
- /*
- * Merge qstring and nextqs, since this is an artificial
- * separation, unless nextqs is of different type.
- * What this means in practice is that if
- * qs->qstype == qsNormal and qs->next != NULL, then
- * qs->next->qstype != qsNormal.
- *
- * Can't use qs_add to merge because it could lead
- * to an infinite loop (e.g a line "^ ^").
- */
- i += nextqs && nextqs->qstype == qsNormal
- ? strlen(nextqs->value) : 0;
- qstring = (QSTRING_S *) malloc (sizeof(QSTRING_S));
- memset (qstring, 0, sizeof(QSTRING_S));
- qstring->value = (char *) malloc((i+1)*sizeof(char));
- strncpy(qstring->value, word, i);
- qstring->value[i] = '\0';
- qstring->qstype = qsNormal;
- if(nextqs && nextqs->qstype == qsNormal){
- d = nextqs->next;
- nextqs->next = NULL;
- qstring->next = d;
- free_qs(&nextqs);
- }
- else
- qstring->next = nextqs;
-
- return qstring;
- }
- break;
- case RPAREN: /* parenthesis ')' */
- if ((i != 0) || ((i == 0) && been_here))
- i++;
- else
- if (i == 0)
- return qs_add(qs, word, qsChar, i, i, 1, 1);
- else
- finished++;
- break;
-
- case ':': /* colon */
- case '~': nxt = next(word,i);
- if ((is_tilde(c) && (nxt == '/'))
- || (is_colon(c) && !is_cquote(nxt)
- && !is_cword(nxt) && nxt != RPAREN))
- finished++;
- else if (is_cquote(c)
- || is_cquote(nxt)
- || (c != '~' && nxt == RPAREN)
- || (i != 0 && ISspace(nxt))
- || is_cquote(prev = before(word,i))
- || (ISspace(prev) && !is_tilde(c))
- || (is_tilde(c) && nxt != '/'))
- i++;
- else if (i == 0 && been_here)
- return qs_add(qs, word, qsChar, i, i, 1, 1);
- else
- finished++;
- break;
-
- case '<' :
- case '=' :
- case '-' : offset = is_cquote(nxt = next(word,i)) ? 2
- : (nxt == c && is_cquote(next(word,i+1))) ? 3 : -1;
-
- if (offset > 0)
- return qs_add(qs, word, qsString, i, i, offset, 1);
- else
- finished++;
- break;
-
- case '[' :
- case '+' : /* accept +>, *> */
- case '*' : if (is_rarrow(nxt = next(word, i)) || /* stars */
- (ISspace(nxt) && is_rarrow(next(word,i+1))))
- i++;
- else
- finished++;
- break;
-
- case '^' :
- case '!' :
- case '%' : if (next(word,i) != c)
- return qs_add(qs, word, qsChar, i, i+1, 0, 1);
- else
- finished++;
- break;
-
- case '_' : if(ISspace(next(word, i)))
- return qs_add(qs, word, qsChar, i, i+1, 0, 1);
- else
- finished++;
- break;
-
- case '#' : { QStrType qstype = qsChar;
- if((nxt = next(word, i)) != c){
- if(isdigit((int) nxt))
- qstype = qsGdb;
- else
- if(word_is_prog(word))
- qstype = qsProg;
- return qs_add(qs, word, qstype, i, i+1, 0, 1);
- }
- else
- finished++;
- break;
- }
-
- default:
- if (is_cquote(c))
- i++;
- else if (is_cletter(c)){
- for (j = i; (is_cletter(nxt = next(word,j)) || is_cnumber(nxt))
- && !(ISspace(nxt));j++);
- /*
- * The whole reason why we are splitting the quote
- * string is so that we will be able to accept quote
- * strings that are strange in some way. Here we got to
- * a point in which a quote string might exist, but it
- * could be strange, so we need to create a "next" field
- * for the quote string to warn us that something
- * strange is coming. We need to confirm if this is a
- * good choice later. For now we will let it pass.
- */
- if (isaword(word,i,j) || isamailbox(word,i,j)){
- int offset;
- QStrType qstype;
-
- offset = (is_cquote(c = next(word,j))
- || (c == RPAREN)) ? 2
- : ((ISspace(c)
- && is_cquote(next(word,j+1))) ? 3 : -1);
-
- qstype = (is_cquote(c) || (c == RPAREN))
- ? (is_qsword(c) ? qsWord : qsString)
- : ((ISspace(c) && is_cquote(next(word,j+1)))
- ? (is_qsword(next(word,j+1))
- ? qsWord : qsString)
- : qsString);
-
- /*
- * qsWords are valid quote strings only when
- * they are followed by text.
- */
- if (offset > 0 && qstype == qsWord &&
- !allwd_after_qsword(now(word,j + offset)))
- offset = -1;
-
- if (offset > 0)
- return qs_add(qs, word, qstype, i, j, offset, 1);
- }
- finished++;
- }
- else{
- if(i > 0)
- return qs_add(qs, word, qsNormal, 0, i, 0, 1);
- else if(!forbidden(c))
- return qs_add(qs, word, qsChar, 0, 1, 0, 1);
- else /* chao pescao */
- finished++;
- }
- break;
- } /* End Switch */
- } /* End while */
- if (i > 0)
- qstring = qs_add(qs, word, qsNormal, 0, i, 0, 0);
- return qstring;
-}
-
-int
-isaword(char word[NSTRING], int i, int j)
-{
- return i <= j && is_cletter(word[i]) ?
- (i < j ? isaword(word,i+1,j) : 1) : 0;
-}
-
-int
-isamailbox(char word[NSTRING], int i, int j)
-{
- return i <= j && (is_cletter(word[i]) || is_a_digit(word[i])
- || word[i] == '.')
- ? (i < j ? isamailbox(word,i+1,j) : 1) : 0;
-}
-
-/*
- This routine removes the last part that is qsword or qschar that is not
- followed by a normal part. This means that if a qsword or qschar is
- followed by a qsnormal (or qsstring), we accept the qsword (or qschar)
- as part of a quote string.
- */
-QSTRING_S *
-remove_qsword(QSTRING_S *cl)
-{
- QSTRING_S *np = cl;
- QSTRING_S *cp = np; /* this variable trails cl */
-
- while(1){
- while (cl && cl->qstype == qsNormal)
- cl = cl->next;
-
- if (cl){
- if (((cl->qstype == qsWord) || (cl->qstype == qsChar))
- && !exists_good_part(cl)){
- if (np == cl) /* qsword or qschar at the beginning */
- free_qs(&cp);
- else{
- while (np->next != cl)
- np = np->next;
- free_qs(&(np->next));
- }
- break;
- }
- else
- cl = cl->next;
- }
- else
- break;
- }
- return cp;
-}
-
-int
-exists_good_part (QSTRING_S *cl)
-{
- return (cl ? (((cl->qstype != qsWord) && (cl->qstype != qsChar)
- && qs_allowed(cl) && !value_is_space(cl->value))
- ? 1 : exists_good_part(cl->next))
- : 0);
-}
-
-int
-line_isblank(char **q, char *GLine, char *NLine, char *PLine, int buflen)
-{
- int n = 0;
- QSTRING_S *cl;
- char qstr[NSTRING];
-
- cl = do_raw_quote_match(q, GLine, NLine, PLine, NULL, NULL);
-
- flatten_qstring(cl, qstr, NSTRING);
-
- free_qs(&cl);
-
- for(n = strlen(qstr); n < buflen && GLine[n]; n++)
- if(!ISspace((unsigned char) GLine[n]))
- return(FALSE);
-
- return(TRUE);
-}
-
-QSTRING_S *
-do_raw_quote_match(char **q, char *GLine, char *NLine, char *PLine, QSTRING_S **nlp, QSTRING_S **plp)
-{
- QSTRING_S *cl, *nl = NULL, *pl = NULL;
- char nbuf[NSTRING], pbuf[NSTRING], buf[NSTRING];
- int emptypl = 0, emptynl = 0;
-
- if (!(cl = is_quote(q, GLine, 0))) /* if nothing in, nothing out */
- return cl;
-
- nl = is_quote(q, NLine, 0); /* Next Line */
- if (nlp) *nlp = nl;
- pl = is_quote(q, PLine, 0); /* Previous Line */
- if (plp) *plp = pl;
- /*
- * If there's nothing in the preceeding or following line
- * there is not enough information to accept it or discard it. In this
- * case it's likely to be an isolated line, so we better accept it
- * if it does not look like a word.
- */
- flatten_qstring(pl, pbuf, NSTRING);
- emptypl = (!PLine || !PLine[0] ||
- (pl && value_is_space(pbuf)) && !PLine[strlen(pbuf)]) ? 1 : 0;
- if (emptypl){
- flatten_qstring(nl, nbuf, NSTRING);
- emptynl = (!NLine || !NLine[0] ||
- (nl && value_is_space(nbuf) && !NLine[strlen(nbuf)])) ? 1 : 0;
- if (emptynl){
- cl = remove_qsword(cl);
- if((cl = fix_qstring_allowed(cl, NULL, NULL)) != NULL)
- cl = qs_remove_trailing_spaces(cl);
- free_qs(&nl);
- free_qs(&pl);
- if(nlp) *nlp = NULL;
- if(plp) *plp = NULL;
-
- return cl;
- }
- }
-
- /*
- * If either cl, nl or pl contain suspicious characters that may make
- * them (or not) be quote strings, we need to fix them, so that the
- * next pass will be done correctly.
- */
-
- cl = fix_qstring(cl, nl, pl);
- nl = trim_qs_from_cl(cl, nl, NULL);
- pl = trim_qs_from_cl(cl, NULL, pl);
- if((cl = fix_qstring_allowed(cl, nl, pl)) != NULL){
- nl = trim_qs_from_cl(cl, nl, NULL);
- pl = trim_qs_from_cl(cl, NULL, pl);
- }
- else{
- free_qs(&nl);
- free_qs(&pl);
- }
- if(nlp)
- *nlp = nl;
- else
- free_qs(&nl);
- if(plp)
- *plp = pl;
- else
- free_qs(&pl);
- return cl;
-}
-
-QSTRING_S *
-do_quote_match(char **q, char *GLine, char *NLine, char *PLine, char *rqstr,
-int rqstrlen, int plb)
-{
- QSTRING_S *cl, *nl = NULL, *pl = NULL;
- int c, n, p,i, j, NewP, NewC, NewN, clength, same = 0;
- char nbuf[NSTRING], pbuf[NSTRING], buf[NSTRING];
-
- if(rqstr)
- *rqstr = '\0';
-
- /* if nothing in, nothing out */
- cl = do_raw_quote_match(q, GLine, NLine, PLine, &nl, &pl);
- if(cl == NULL){
- free_qs(&nl);
- free_qs(&pl);
- return cl;
- }
-
- flatten_qstring(cl, rqstr, rqstrlen);
- flatten_qstring(cl, buf, NSTRING);
- flatten_qstring(nl, nbuf, NSTRING);
- flatten_qstring(pl, pbuf, NSTRING);
-
- /*
- * Once upon a time, is_quote used to return the length of the quote
- * string that it had found. One day, not long ago, black hand came
- * and changed all that, and made is_quote return a quote string
- * divided in several fields, making the algorithm much more
- * complicated. Fortunately black hand left a few comments in the
- * source code to make it more understandable. Because of this change
- * we need to compute the lengths of the quote strings separately
- */
- c = buf && buf[0] ? strlen(buf) : 0;
- n = nbuf && nbuf[0] ? strlen(nbuf) : 0;
- p = pbuf && pbuf[0] ? strlen(pbuf) : 0;
- /*
- * When quote strings contain only blank spaces (ascii code 32) the
- * above count is equal to the length of the quote string, but if
- * there are TABS, the length of the quote string as seen by the user
- * is different than the number that was just computed. Because of
- * this we demand a recount (hmm.. unless you are in Florida, where
- * recounts are forbidden)
- */
- NewP = strlenis(pbuf);
- NewC = strlenis(buf);
- NewN = strlenis(nbuf);
-
- /*
- * For paragraphs with spaces in the first line, but no space in the
- * quote string of the second line, we make sure we choose the quote
- * string without a space at the end of it.
- */
- if ((NLine && !NLine[0])
- && ((PLine && !PLine[0])
- || (((same = same_qstring(pl, cl)) != 0)
- && (same != count_levels_qstring(cl)))))
- cl = qs_remove_trailing_spaces(cl);
- else
- if (NewC > NewN){
- int agree = 0;
- for (j = 0; (j < n) && (GLine[j] == NLine[j]); j++);
- clength = j;
- /* clength is the common length in which Gline and Nline agree */
- /* j < n means that they do not agree fully */
- /* GLine = " \tText"
- NLine = " Text" */
- if(j == n)
- agree++;
- if (clength < n){ /* see if buf and nbuf are padded with spaces and tabs */
- for (i = clength; i < n && ISspace(NLine[i]); i++);
- if (i == n){/* padded NLine until the end of spaces? */
- for (i = clength; i < c && ISspace(GLine[i]); i++);
- if (i == c) /* Padded CLine until the end of spaces? */
- agree++;
- }
- }
- if (agree){
- for (j = clength; j < c && ISspace(GLine[j]); j++);
- if (j == c){
- /*
- * If we get here, it means that the current line has the same
- * quote string (visually) than the next line, but both of them
- * are padded with different amount of TABS or spaces at the end.
- * The current line (GLine) has more spaces/TABs than the next
- * line. This is the typical situation that is found at the
- * begining of a paragraph. We need to check this, however, by
- * checking the previous line. This avoids that we confuse
- * ourselves with being in the last line of a paragraph.
- * Example when it should not free_qs(cl)
- * " Text in Paragraph 1" (PLine)
- * " Text in Paragraph 1" (GLine)
- * " Other Paragraph Number 2" (NLine)
- *
- * Example when it should free_qs(cl):
- * ":) " (PLine) p = 3, j = 3
- * ":) Text" (GLine) c = 5
- * ":) More text" (NLine) n = 3
- *
- * Example when it should free_qs(cl):
- * ":) " (PLine) p = 3, j = 3
- * ":) > > > Text" (GLine) c = 11
- * ":) > > > More text" (NLine) n = 9
- *
- * Example when it should free_qs(cl):
- * ":) :) " (PLine) p = 6, j = 3
- * ":) > > > Text" (GLine) c = 11
- * ":) > > > More text" (NLine) n = 9
- *
- * Example when it should free_qs(cl):
- * ":) > > > " (PLine) p = 13, j = 11
- * ":) > > > Text" (GLine) c = 11
- * ":) > > > More text" (NLine) n = 9
- *
- * The following example is very interesting. The "Other Text"
- * line below should free the quote string an make it equal to the
- * quote string of the line below it, but any algorithm trying
- * to advance past that line should make it stop there, so
- * we need one more check, to check the raw quote string and the
- * processed quote string at the same time.
- * FREE qs in this example.
- * " Some Text" (PLine) p = 3, j = 0
- * "\tOther Text" (GLine) c = 1
- * " More Text" (NLine) n = 3
- *
- */
- for (j = 0; (j < p) && (GLine[j] == PLine[j]); j++);
- if ((p != c || j != p) && NLine[n])
- if(!get_indent_raw_line(q, PLine, nbuf, NSTRING, p, plb)
- || NewP + strlenis(nbuf) != NewC){
- free_qs(&cl);
- free_qs(&pl);
- return nl;
- }
- }
- }
- }
-
- free_qs(&nl);
- free_qs(&pl);
-
- return cl;
-}
-
-/*
- * Given a line, an initial position, and a quote string, we advance the
- * current line past the quote string, including arbitraty spaces
- * contained in the line, except that it removes trailing spaces. We do
- * not handle TABs, if any, contained in the quote string. At least not
- * yet.
- *
- * Arguments: q - quote string
- * l - a line to process
- * i - position in the line to start processing. i = 0 is the
- * begining of that line.
- */
-int
-advance_quote_string(char *q, char l[NSTRING], int i)
-{
- int n = 0, j = 0, is = 0, es = 0;
- int k, m, p, adv;
- char qs[NSTRING] = {'\0'};
- if(!q || !*q)
- return(0);
- for (p = strlen(q); (p > 0) && (q[p - 1] == ' '); p--, es++);
- if (!p){ /* string contains only spaces */
- for (k = 0; ISspace(l[i + k]); k++);
- k -= k % es;
- return k;
- }
- for (is = 0; ISspace(q[is]); is++); /* count initial spaces */
- for (m = 0 ; is + m < p ; m++)
- qs[m] = q[is + m]; /* qs = quote string without any space at the end */
- /* advance as many spaces as there are at the begining */
- for (k = 0; ISspace(l[i + j]); k++, j++);
- /* now find the visible string in the line */
- for (m = 0; qs[m] && l[i + j] == qs[m]; m++, j++);
- if (!qs[m]){ /* no match */
- /*
- * So far we have advanced at least "is" spaces, plus the visible
- * string "qs". Now we need to advance the trailing number of
- * spaces "es". If we can do that, we have found the quote string.
- */
- for (p = 0; ISspace(l[i + j + p]); p++);
- adv = advance_quote_string(q, l, i + j + ((p < es) ? p : es));
- n = ((p < es) ? 0 : es) + k + m + adv;
- }
- return n;
-}
-
-/*
- * This function returns the effective length in screen of the quote
- * string. If the string contains a TAB character, it is added here, if
- * not, the length returned is the length of the string
- */
-int strlenis(char *qstr)
-{
- int i, rv = 0;
- for (i = 0; qstr && qstr[i]; i++)
- rv += ((qstr[i] == TAB) ? (~rv & 0x07) + 1 : 1);
- return rv;
-}
-
-int
-is_indent (char word[NSTRING], int plb)
-{
- int i = 0, finished = 0, c, nxt, j, k, digit = 0, bdigits = -1, alpha = 0;
-
- if (!word || !word[0])
- return i;
-
- for (i = 0, j = 0; ISspace(word[i]); i++, j++);
- while ((i < NSTRING - 2) && !finished){
- switch (c = now(word,i)){
- case NBSP:
- case TAB :
- case ' ' : for (; ISspace(word[i]); i++);
- if (!is_indent_char(now(word,i)))
- finished++;
- break;
-
- case '+' :
- case '.' :
- case ']' :
- case '*' :
- case '}' :
- case '-' :
- case RPAREN:
- nxt = next(word,i);
- if ((c == '.' && allowed_after_period(nxt) && alpha)
- || (c == '*' && allowed_after_star(nxt))
- || (c == '}' && allowed_after_braces(nxt))
- || (c == '-' && allowed_after_dash(nxt))
- || (c == '+' && allowed_after_dash(nxt))
- || (c == RPAREN && allowed_after_parenth(nxt))
- || (c == ']' && allowed_after_parenth(nxt)))
- i++;
- else
- finished++;
- break;
-
- default : if (is_a_digit(c) && plb){
- if (bdigits < 0)
- bdigits = i; /* first digit */
- for (k = i; is_a_digit(now(word,k)); k++);
- if (k - bdigits > 2){ /* more than 2 digits? */
- i = bdigits; /* too many! */
- finished++;
- }
- else{
- if(allowed_after_digit(now(word,k),word,k)){
- alpha++;
- i = k;
- }
- else{
- i = bdigits;
- finished++;
- }
- }
- }
- else
- finished++;
- break;
-
- }
- }
- if (i == j)
- i = 0; /* there must be something more than spaces in an indent string */
- return i;
-}
-
-int
-get_indent_raw_line(char **q, char *GLine, char *buf, int buflen, int k, int plb)
-{
- int i, j;
- char testline[1024];
-
- if(k > 0){
- for(j = 0; GLine[j] != '\0'; j++){
- testline[j] = GLine[j];
- testline[j+1] = '\0';
- if(strlenis(testline) >= strlenis(buf))
- break;
- }
- k = ++j; /* reset k */
- }
- i = is_indent(GLine+k, plb);
-
- for (j = 0; j < i && j < buflen && (buf[j] = GLine[j + k]); j++);
- buf[j] = '\0';
-
- return i;
-}
-
-/* support for remembering quote strings across messages */
-char **allowed_qstr = NULL;
-int list_len = 0;
-
-void
-free_allowed_qstr(void)
-{
- int i;
- char **q = allowed_qstr;
-
- if(q == NULL)
- return;
-
- for(i = 0; i < list_len; i++)
- fs_give((void **)&q[i]);
-
- fs_give((void **)q);
- list_len = 0;
-}
-
-void
-add_allowed_qstr(void *q, int type)
-{
- int i;
-
- if(allowed_qstr == NULL){
- allowed_qstr = malloc(sizeof(char *));
- list_len = 0;
- }
-
- if(type == 0){
- allowed_qstr[list_len] = malloc((1+strlen((char *)q))*sizeof(char));
- strcpy(allowed_qstr[list_len], (char *)q);
- }
- else
- allowed_qstr[list_len] = (char *) ucs4_to_utf8_cpystr((UCS *)q);
-
- fs_resize((void **)&allowed_qstr, (++list_len + 1)*sizeof(char *));
- allowed_qstr[list_len] = NULL;
-}
-
-void
-record_quote_string (QSTRING_S *qs)
-{
- int i, j, k;
-
- for(; qs && qs->value; qs = qs->next){
- j = 0;
- for (; ;){
- k = j;
- for(i = 0; i < list_len; i++){
- j += advance_quote_string(allowed_qstr[i], qs->value, j);
- for(; ISspace(qs->value[j]); j++);
- }
- if(k == j)
- break;
- }
- if(qs->value[j] != '\0')
- add_allowed_qstr((void *)(qs->value + j), 0);
- }
-}
-
-/* type utf8: code 0; ucs4: code 1. */
-char **
-default_qstr(void *q, int type)
-{
- if(allowed_qstr == NULL)
- add_allowed_qstr(q, type);
-
- return allowed_qstr;
-}
-
diff --git a/pith/osdep/color.h b/pith/osdep/color.h
index 929389a2..32c86242 100644
--- a/pith/osdep/color.h
+++ b/pith/osdep/color.h
@@ -17,24 +17,6 @@
#ifndef PITH_OSDEP_COLOR_INCLUDED
#define PITH_OSDEP_COLOR_INCLUDED
-/*
- * struct that will help us determine what the quote string of a line
- * is. The "next" field indicates the presence of a possible continuation.
- * The idea is that if a continuation fails, we free it and check for the
- * remaining structure left
- */
-
-typedef enum {qsNormal, qsString, qsWord, qsChar, qsGdb, qsProg, qsText} QStrType;
-
-typedef struct QSTRING {
- char *value; /* possible quote string */
- QStrType qstype; /* type of quote string */
- struct QSTRING *next; /* possible continuation */
-} QSTRING_S;
-
-#define UCH(c) ((unsigned char) (c))
-#define NBSP UCH('\240')
-#define ISspace(c) (UCH(c) == ' ' || UCH(c) == TAB || UCH(c) == NBSP)
#define RGBLEN 11
#define MAXCOLORLEN 11 /* longest string a color can be */
@@ -111,11 +93,6 @@ char *pico_get_last_fg_color(void);
char *pico_get_last_bg_color(void);
char *color_to_canonical_name(char *);
int pico_count_in_color_table(void);
-int is_indent(char *, int);
-int get_indent_raw_line (char **, char *, char *, int, int, int);
-int line_isblank(char **, char *, char *, char *, int);
-int strlenis(char *);
-int value_is_space(char *);
-int advance_quote_string(char *, char *, int);
+
#endif /* PITH_OSDEP_COLOR_INCLUDED */