// Add a filter to filters structure void add_filter(char * criteria) { int cp = 0; char c; while (criteria[cp]) { int pos = exists_freed_filter(); // we check if there exists a freed filter if (pos == -1) { // if not we alloc a new one filters = (struct filter_item *) scxrealloc((char *) filters, (howmany++ + 1) * (sizeof(struct filter_item))); pos = howmany-1; } filters[pos].eval = (char *) scxmalloc(sizeof(char) * strlen(criteria) + 1); filters[pos].eval[0] = '\0'; while (criteria[cp] && criteria[cp] != ';' && criteria[cp] != '\n') { c = criteria[cp]; if (c == '"') { cp++; continue; } if (criteria[cp++] == '\'') c ='"'; sprintf(filters[pos].eval + strlen(filters[pos].eval), "%c", c); } if (criteria[cp] == ';') cp++; } return; }
// Apply filters to a range void enable_filters(struct ent * left, struct ent * right) { int minr = left->row < right->row ? left->row : right->row; int maxr = left->row > right->row ? left->row : right->row; int i, r, c = 0; char cadena[200] = ""; char aux[200] = ""; results = (int *) scxrealloc((char *) results, (maxr - minr + 3) * sizeof(int)); results[0] = minr; // keep in first position the first row of the range! results[1] = maxr; // keep in second position the last row of the range! if (filters == NULL) { scerror("There are no filters defined"); return; } active = 1; for (r = minr; r <= maxr; r++) { results[r-minr+2] = 0; // show row by default (0 = NOT HIDDEN) for (i = 0; i < howmany; i++, c=0) { cadena[0]='\0'; if (filters[i].eval == NULL) continue; while (filters[i].eval[c] != '\0') { if (filters[i].eval[c] == '#' || filters[i].eval[c] == '$') { if (isalpha(toupper(filters[i].eval[++c]))) sprintf(cadena + strlen(cadena), "%c", filters[i].eval[c]); if (isalpha(toupper(filters[i].eval[++c]))) sprintf(cadena + strlen(cadena), "%c", filters[i].eval[c]); sprintf(cadena + strlen(cadena), "%d", r); continue; } else sprintf(cadena + strlen(cadena), "%c", filters[i].eval[c]); c++; } sprintf(aux, "eval %s", cadena); send_to_interp(aux); if ( (! seval_result && str_in_str(filters[i].eval, "seval") != -1) || ! eval_result) { results[r-minr+2] = 1; // this row does not eval to expression. we hide it. (1 = HIDDEN)! i = howmany; } } } // oculto las filas que no cumplen con los filtros for (r = results[0]; r <= results[1]; r++) { row_hidden[r] = results[r-results[0]+2]; } return; }
bool format(char *fmt, int lprecision, double val, char *buf, int buflen) { register char *cp; char *tmp, *tp; bool comma = false, negative = false; char *integer = NULL, *decimal = NULL; char *exponent = NULL; int exp_val = 0; int width; char prtfmt[32]; static char *mantissa = NULL; static char *tmpfmt1 = NULL, *tmpfmt2 = NULL, *exptmp = NULL; static unsigned mantlen = 0, fmtlen = 0; char *fraction = NULL; int zero_pad = 0; if (fmt == NULL) return(true); if (strlen(fmt) + 1 > fmtlen) { fmtlen = strlen(fmt) + 40; tmpfmt1 = scxrealloc(tmpfmt1, fmtlen); tmpfmt2 = scxrealloc(tmpfmt2, fmtlen); exptmp = scxrealloc(exptmp, fmtlen); } fmt = strcpy(tmpfmt1, fmt); if (buflen + 1 > mantlen) { mantlen = buflen + 40; mantissa = scxrealloc(mantissa, mantlen); } /* * select positive or negative format if necessary */ for (cp = fmt; *cp != ';' && *cp != EOS; cp++) { if (*cp == '\\') cp++; } if (*cp == ';') { if (val < 0.0) { val = -val; /* format should provide sign if desired */ fmt = cp + 1; } else *cp = EOS; } /* * extract other information from format and produce a * format string stored in tmpfmt2 also scxmalloc()'d above */ tmp = tmpfmt2; for (cp = fmt, tp = tmp; *cp != EOS; cp++) { switch (*cp) { case '\\': *tp++ = *cp++; *tp++ = *cp; break; case ',': comma = true; break; case '.': if (decimal == NULL) decimal = tp; *tp++ = *cp; break; case '%': val *= 100.0; *tp++ = *cp; break; default: *tp++ = *cp; break; } } *tp = EOS; fmt = tmpfmt2; /* The following line was necessary due to problems with the gcc * compiler and val being a negative zero. Thanks to Mike Novack for * the suggestion. - CRM */ val = (val + 1.0) - 1.0; if (val < 0.0) { negative = true; val = -val; } /* * extract the exponent from the format if present */ for (cp = fmt; *cp != EOS; cp++) { if (*cp == '\\') cp++; else if (*cp == 'e' || *cp == 'E') { if (cp[1] == '+' || cp[1] == '-') { exponent = strcpy(exptmp, cp); *cp = EOS; if (val != 0.0) { while (val < 1.0) { val *= 10.0; exp_val--; } while (val >= 10.0) { val /= 10.0; exp_val++; } } break; } } } /* * determine maximum decimal places and use sprintf * to build initial character form of formatted value. */ width = 0; if (decimal) { *decimal++ = EOS; for (cp = decimal; *cp != EOS; cp++) { switch (*cp) { case '\\': cp++; break; case '#': width++; break; case '0': zero_pad = ++width; break; case '&': width += lprecision; zero_pad = width; break; } } zero_pad = strlen(decimal) - zero_pad; } (void) sprintf(prtfmt, "%%.%dlf", width); (void) sprintf(mantissa, prtfmt, val); for (cp = integer = mantissa; *cp != dpoint && *cp != EOS; cp++) { if (*integer == '0') integer++; } if (*cp == dpoint) { fraction = cp + 1; *cp = EOS; cp = fraction + strlen(fraction) - 1; for (; zero_pad > 0; zero_pad--, cp--) { if (*cp == '0') *cp = EOS; else break; } } else fraction = ""; /* * format the puppy */ { static char *citmp = NULL, *cftmp = NULL; static unsigned cilen = 0, cflen = 0; char *ci, *cf, *ce; int len_ci, len_cf, len_ce; bool ret = false; ci = fmt_int(integer, fmt, comma, negative); len_ci = strlen(ci); if (len_ci >= cilen) { cilen = len_ci + 40; citmp = scxrealloc(citmp, cilen); } ci = strcpy(citmp, ci); cf = decimal ? fmt_frac(fraction, decimal, lprecision) : ""; len_cf = strlen(cf); if (len_cf >= cflen) { cflen = len_cf + 40; cftmp = scxrealloc(cftmp, cilen); } cf = strcpy(cftmp, cf); ce = (exponent) ? fmt_exp(exp_val, exponent) : ""; len_ce = strlen(ce); /* * Skip copy assuming sprintf doesn't call our format functions * ce = strcpy(scxmalloc((unsigned)((len_ce = strlen(ce)) + 1)), ce); */ if (len_ci + len_cf + len_ce < buflen) { (void) sprintf(buf, "%s%s%s", ci, cf, ce); ret = true; } return (ret); } }
void sortrange (struct ent *left, struct ent *right, char *criteria) { int minr, minc, maxr, maxc, r, c; int *rows, col = 0; int cp = 0; struct ent *p; minr = left->row < right->row ? left->row : right->row; minc = left->col < right->col ? left->col : right->col; maxr = left->row > right->row ? left->row : right->row; maxc = left->col > right->col ? left->col : right->col; sort = (struct sortcrit *)scxmalloc((2 * sizeof(struct sortcrit))); rows = (int *)scxmalloc((maxr - minr + 1) * sizeof(int)); for (r = minr, c = 0; r <= maxr; r++, c++) rows[c] = r; if (!criteria) { sort[0].direction = 1; sort[0].type = 1; sort[0].column = minc; sort[1].direction = 1; sort[1].type = 0; sort[1].column = minc; howmany = 2; } else { for (howmany = 0; criteria[cp]; howmany++) { if (howmany > 1) sort = (struct sortcrit *)scxrealloc((char *)sort, (howmany + 1) * (sizeof(struct sortcrit))); switch (criteria[cp++]) { case '+': sort[howmany].direction = 1; break; case '-': sort[howmany].direction = -1; break; default: error("Invalid sort criteria"); return; } switch (criteria[cp++]) { case '#': sort[howmany].type = 0; break; case '$': sort[howmany].type = 1; break; default: error("Invalid sort criteria"); return; } if (criteria[cp]) col = toupper(criteria[cp++]) - 'A'; else { error("Invalid sort criteria"); return; } if (criteria[cp] && criteria[cp] != '+' && criteria[cp] != '-') col = (col + 1) * 26 + toupper(criteria[cp++]) - 'A'; sort[howmany].column = col; if (col < minc || col > maxc) { error("Invalid sort criteria"); return; } } } qsort(rows, maxr - minr + 1, sizeof(int), compare); erase_area(minr, minc, maxr, maxc, 1); sync_ranges(); for (c = 0, p = delbuf[dbidx]; p; p = p->next) { if (rows[c] != p->row) { for (c = 0; c <= maxr - minr && rows[c] != p->row; c++) ; if (c > maxr - minr) { error("sort error"); return; } } p->row = minr + c; } scxfree((char *)sort); scxfree((char *)rows); if (criteria) scxfree(criteria); r = currow; c = curcol; currow = minr; curcol = minc; pullcells('m'); flush_saved(); currow = r; curcol = c; }