/* Helper function to compare two subjects; will be used for sorting and * when linking lost relatives later on */ int _art_subject_cmp (char *sa, char *sb) /*{{{*/ { char *end_a = sa + strlen (sa); char *end_b = sb + strlen (sb); char *was; /* find "(was: ...)" and set end_[ab] */ if (NULL != (was = strstr (sa, "(was:")) && (was != sa) && (*(end_a - 1) == ')')) end_a = was; if (NULL != (was = strstr (sb, "(was:")) && (was != sb) && (*(end_b - 1) == ')')) end_b = was; /* skip past re: */ while (*sa == ' ') sa++; while (*sb == ' ') sb++; if (((*sa | 0x20) == 'r') && ((*(sa + 1) | 0x20) == 'e') && (*(sa + 2) == ':')) { sa += 3; } if (((*sb | 0x20) == 'r') && ((*(sb + 1) | 0x20) == 'e') && (*(sb + 2) == ':')) { sb += 3; } while (1) { char cha, chb; while ((cha = *sa) == ' ') sa++; while ((chb = *sb) == ' ') sb++; if ((sa == end_a) && (sb == end_b)) return 0; /* This hack sorts "(3/31)" before "(25/31)" */ if (isdigit (cha) && isdigit (chb)) { int a = atoi (sa), b = atoi (sb); if (a != b) return a - b; } cha = UPPER_CASE(cha); chb = UPPER_CASE(chb); if (cha != chb) return (int) cha - (int) chb; sa++; sb++; } }
int32 strcmp_nocase (const char *str1, const char *str2) { char c1, c2; for (;;) { c1 = *(str1++); c1 = UPPER_CASE(c1); c2 = *(str2++); c2 = UPPER_CASE(c2); if (c1 != c2) return (c1-c2); if (c1 == '\0') return 0; } }
/* Case insensitive string compare */ static int32 id_cmp (char *str1, char *str2) { char c1, c2; for (;;) { c1 = *(str1++); c1 = UPPER_CASE(c1); c2 = *(str2++); c2 = UPPER_CASE(c2); if (c1 != c2) return (c1-c2); if (c1 == '\0') return 0; } }
void ucase(register char *cp) { if (cp) { while (*cp) { *cp = UPPER_CASE(*cp); cp++; } } }
int32 strcmp_nocase(const char *str1, const char *str2) { char c1, c2; if (str1 == str2) return 0; if (str1 && str2) { for (;;) { c1 = *(str1++); c1 = UPPER_CASE(c1); c2 = *(str2++); c2 = UPPER_CASE(c2); if (c1 != c2) return (c1 - c2); if (c1 == '\0') return 0; } } else return (str1 == NULL) ? -1 : 1; return 0; }
int32 strncmp_nocase(const char *str1, const char *str2, size_t len) { char c1, c2; if (str1 && str2) { size_t n; for (n = 0; n < len; ++n) { c1 = *(str1++); c1 = UPPER_CASE(c1); c2 = *(str2++); c2 = UPPER_CASE(c2); if (c1 != c2) return (c1 - c2); if (c1 == '\0') return 0; } } else return (str1 == NULL) ? -1 : 1; return 0; }
/* This is used if the key is not UTF-8, or it is but the search is case-sensitive */ static SLsearch_Type *bm_open_search (SLuchar_Type *key, int flags) { SLsearch_Type *st; size_t keylen; keylen = strlen ((char *)key); if (NULL == (st = (SLsearch_Type *)SLcalloc (1, sizeof (SLsearch_Type)))) return NULL; st->free_fun = bm_free; /* If the search is case-insensitive, then it must either be all ascii, or * it is not unicode. In either case, the UPPER_CASE and LOWER_CASE macros * should be ok to use. */ if (flags & SLSEARCH_CASELESS) { char *keyup = SLmake_nstring ((char *)key, keylen); if (keyup != NULL) { unsigned char *k = (unsigned char *)keyup; while (*k != 0) { *k = UPPER_CASE(*k); k++; } st->s.bm.key = (SLuchar_Type *)SLang_create_slstring (keyup); SLfree (keyup); } else st->s.bm.key = NULL; } else st->s.bm.key = (SLuchar_Type*) SLang_create_slstring ((char *)key); if (st->s.bm.key == NULL) { SLsearch_delete (st); return NULL; } st->s.bm.key_len = keylen; st->flags = flags; st->search_fun = bm_search; init_skip_table (st->s.bm.key, st->s.bm.key_len, st->s.bm.fskip_table, 1, flags); init_skip_table (st->s.bm.key, st->s.bm.key_len, st->s.bm.bskip_table, -1, flags); return st; }
void ucase(register char *cp) { for (; *cp; cp++) *cp = UPPER_CASE(*cp); }
/* Simple BM search--- case-sensitive, or case-less, or no UTF-8, or 7-bit ascii */ static SLuchar_Type * bm_search_forward (SLsearch_Type *st, SLuchar_Type *beg, SLuchar_Type *end) { register unsigned char char1; unsigned char *pos; size_t *skip_table; SLuchar_Type *key; SLstrlen_Type key_len; int case_fold; BoyerMoore_Search_Type *bm; bm = &st->s.bm; key_len = bm->key_len; st->match_len = 0; if ((key_len > (unsigned int) (end - beg)) || (key_len == 0)) return NULL; case_fold = st->flags & SLSEARCH_CASELESS; key = bm->key; skip_table = bm->fskip_table; char1 = key[key_len - 1]; beg += (key_len - 1); while(1) { SLuchar_Type ch; SLstrlen_Type j; while (beg < end) { SLstrlen_Type dbeg; ch = *beg; dbeg = skip_table[ch]; if ((dbeg < key_len) && ((ch == char1) || (case_fold && (char1 == UPPER_CASE(ch))))) break; beg += dbeg; } if (beg >= end) return NULL; pos = beg - (key_len - 1); for (j = 0; j < key_len; j++) { ch = pos[j]; if ((key[j] != ch) && ((case_fold == 0) || (key[j] != UPPER_CASE(ch)))) break; } if (j == key_len) { st->match_len = key_len; return pos; } beg += 1; } }
static SLuchar_Type * bm_search_backward (SLsearch_Type *st, SLuchar_Type *beg, SLuchar_Type *start, SLuchar_Type *end) { SLuchar_Type char1; SLstrlen_Type j, ofs; SLstrlen_Type key_len; SLuchar_Type *key; int case_fold; size_t *skip_table; BoyerMoore_Search_Type *bm; st->match_len = 0; bm = &st->s.bm; key_len = bm->key_len; if ((key_len > (unsigned int) (end - beg)) || (key_len == 0) || (end <= beg) || (start < beg) || (start >= end)) return NULL; case_fold = st->flags & SLSEARCH_CASELESS; key = bm->key; skip_table = bm->bskip_table; if (start + key_len > end) start = end - key_len; char1 = key[0]; while(1) { SLuchar_Type ch; while (beg <= start) { ch = *start; if ((ch == char1) || (case_fold && (char1 == UPPER_CASE(ch)))) break; ofs = skip_table[ch]; start -= ofs; } if (beg > start) return NULL; for (j = 1; j < key_len; j++) { ch = start[j]; if ((key[j] != ch) && ((case_fold == 0) || (key[j] != UPPER_CASE(ch)))) break; } if (j == key_len) { st->match_len = key_len; return start; } start--; } }
/* * D O F I L E */ void dofile(FILE *fp) { register int c; while ( (c = getc(fp)) != EOF ) { switch ( c ) { /* One of a kind functions */ case 'e': case 'F': putchar( c ); break; case 'f': case 't': putchar( c ); copy_string( fp ); break; case 'C': putchar( c ); COPY(3); break; case 'c': /* map x, y? */ putchar( c ); COPY(6); break; case 'a': /* map points? */ putchar( c ); COPY(12); break; case 'p': case 'm': case 'n': /* Two coordinates in, three out. Change command. */ putchar( UPPER_CASE(c) ); two_coord_out( fp, rmat ); break; case 'l': putchar( 'L' ); two_coord_out( fp, rmat ); two_coord_out( fp, rmat ); break; case 'P': case 'M': case 'N': putchar( c ); three_coord_out( fp, rmat ); break; case 'L': putchar( c ); three_coord_out( fp, rmat ); three_coord_out( fp, rmat ); break; case 's': { /* 2-D integer SPACE command. * This is the only AT&T compatible space * command; be certain to only output * with pl_space(), to ensure that output * file is AT&T style if input was. */ long minx, miny, maxx, maxy; point_t min, max; minx = getshort(fp); miny = getshort(fp); maxx = getshort(fp); maxy = getshort(fp); VSET( min, minx, miny, -1 ); VSET( max, maxx, maxy, -1 ); model_rpp( min, max ); minx = (long)floor( space_min[X] ); miny = (long)floor( space_min[Y] ); maxx = (long)ceil( space_max[X] ); maxy = (long)ceil( space_max[Y] ); if ( minx < -32768 ) minx = -32768; if ( miny < -32768 ) miny = -32768; if ( maxx > 32767 ) maxx = 32767; if ( maxy > 32767 ) maxy = 32767; pl_space( stdout, minx, miny, maxx, maxy ); } break; case 'S': { /* BRL-extended 3-D integer SPACE command */ point_t min, max; min[X] = getshort(fp); min[Y] = getshort(fp); min[Z] = getshort(fp); max[X] = getshort(fp); max[Y] = getshort(fp); max[Z] = getshort(fp); model_rpp( min, max ); pdv_3space( stdout, space_min, space_max ); } break; /* 2D and 3D IEEE */ case 'w': { /* BRL 2-D floating point SPACE command */ point_t min, max; min[X] = getdouble(fp); min[Y] = getdouble(fp); min[Z] = -1.0; max[X] = getdouble(fp); max[Y] = getdouble(fp); max[Z] = 1.0; model_rpp( min, max ); pdv_3space( stdout, space_min, space_max ); } break; case 'W': { /* BRL 3-D floating point SPACE command */ point_t min, max; min[X] = getdouble(fp); min[Y] = getdouble(fp); min[Z] = getdouble(fp); max[X] = getdouble(fp); max[Y] = getdouble(fp); max[Z] = getdouble(fp); model_rpp( min, max ); pdv_3space( stdout, space_min, space_max ); } break; case 'i': putchar(c); COPY(3*8); break; case 'r': putchar(c); COPY(6*8); break; case 'x': case 'o': case 'q': /* Two coordinates in, three out. Change command. */ putchar( UPPER_CASE(c) ); two_dcoord_out( fp, rmat ); break; case 'v': /* Two coordinates in, three out. Change command. */ putchar( 'V' ); two_dcoord_out( fp, rmat ); two_dcoord_out( fp, rmat ); break; case 'X': case 'O': case 'Q': putchar( c ); three_dcoord_out( fp, rmat ); break; case 'V': putchar( c ); three_dcoord_out( fp, rmat ); three_dcoord_out( fp, rmat ); break; default: fprintf( stderr, "plrot: unrecognized command '%c' (0x%x)\n", (isascii(c) && isprint(c)) ? c : '?', c ); fprintf( stderr, "plrot: ftell = %ld\n", ftell(fp) ); putchar( c ); break; } } }