void del_range(struct ent *left, struct ent *right) { struct range *r; int minr, minc, maxr, maxc; 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; left = lookat(minr, minc); right = lookat(maxr, maxc); if (find_range((char *)0, 0, left, right, &r)) return; if (r->r_next) r->r_next->r_prev = r->r_prev; if (r->r_prev) r->r_prev->r_next = r->r_next; else rng_base = r->r_next; scxfree((char *)(r->r_name)); scxfree((char *)r); modflg++; }
// Funcion que elimina todos los yank ents guardados y libera la memoria asignada void free_yanklist () { if (yanklist == NULL) return; int c; struct ent * r = yanklist; struct ent * e; while (r != NULL) { e = r->next; if (r->format) scxfree(r->format); if (r->label) scxfree(r->label); if (r->expr) efree(r->expr); if (r->ucolor) free(r->ucolor); free(r); r = e; } for (c = 0; c < COLFORMATS; c++) { if (colformat[c] != NULL) scxfree(colformat[c]); colformat[c] = NULL; } yanklist = NULL; return; }
// Free memory of entire filters structure void free_filters() { if (filters == NULL) return; int i; for (i=0; i < howmany; i++) if (filters[i].eval != NULL) scxfree((char *) filters[i].eval); scxfree((char *) filters); filters = NULL; return; }
void clean_range() { register struct range *r; register struct range *nextr; r = rng_base; rng_base = (struct range *)0; while (r) { nextr = r->r_next; scxfree((char *)(r->r_name)); scxfree((char *)r); r = nextr; } }
void del_abbr(char *abbrev) { struct abbrev *a; struct abbrev *prev; if (!(a = find_abbr(abbrev, strlen(abbrev), &prev))) return; if (a->a_next) a->a_next->a_prev = a->a_prev; if (a->a_prev) a->a_prev->a_next = a->a_next; else abbr_base = a->a_next; scxfree((char *)(a->abbr)); scxfree((char *)a); }
// Remove a filter, freeing its memory void del_filter(int id) { if (filters == NULL || id < 0 || id > howmany) { scerror("Cannot delete the filter"); return; } if (filters[id].eval != NULL) { scxfree((char *) filters[id].eval); filters[id].eval = NULL; } return; }
void clean_crange(void) { register struct crange *cr; register struct crange *nextcr; cr = color_base; color_base = (struct crange *)0; while (cr) { nextcr = cr->r_next; scxfree((char *)cr); cr = nextcr; } }
void clean_frange() { register struct frange *fr; register struct frange *nextfr; fr = frame_base; frame_base = (struct frange *)0; while (fr) { nextfr = fr->r_next; scxfree((char *)fr); fr = nextfr; } lastfr = 0; }
void add_crange(struct ent *r_left, struct ent *r_right, int pair) { struct crange *r; int minr, minc, maxr, maxc; minr = r_left->row < r_right->row ? r_left->row : r_right->row; minc = r_left->col < r_right->col ? r_left->col : r_right->col; maxr = r_left->row > r_right->row ? r_left->row : r_right->row; maxc = r_left->col > r_right->col ? r_left->col : r_right->col; if (!pair) { if (color_base) for (r = color_base; r; r = r->r_next) if ( (r->r_left->row == r_left->row) && (r->r_left->col == r_left->col) && (r->r_right->row == r_right->row) && (r->r_right->col == r_right->col)) { if (r->r_next) r->r_next->r_prev = r->r_prev; if (r->r_prev) r->r_prev->r_next = r->r_next; else color_base = r->r_next; scxfree((char *)r); modflg++; FullUpdate++; return; } error("Color range not defined"); return; } r = (struct crange *)scxmalloc((unsigned)sizeof(struct crange)); r->r_left = lookat(minr, minc); r->r_right = lookat(maxr, maxc); r->r_color = pair; r->r_next = color_base; r->r_prev = (struct crange *)0; if (color_base) color_base->r_prev = r; color_base = r; modflg++; FullUpdate++; }
void doseval (struct enode *e, int row, int col, int fd) { char *s; gmyrow = row; gmycol = col; s = seval(e); if (s) write(fd, s, strlen(s)); write(fd, "\n", 1); linelim = -1; efree(e); if (s) scxfree(s); }
void doquery (char *s, char *data, int fd) { goraw(); query(s, data); deraw(0); if (linelim >= 0) { write(fd, line, strlen(line)); write(fd, "\n", 1); } line[0] = '\0'; linelim = -1; error(" "); update(0); if (s) scxfree(s); }
void doeval (struct enode *e, char *fmt, int row, int col, int fd) { double v; gmyrow = row; gmycol = col; v = eval(e); if (fmt) { if (*fmt == ctl('d')) { time_t tv = v; strftime(line, FBUFLEN, fmt + 1, localtime(&tv)); } else format(fmt, precision[col], v, line, FBUFLEN); } else sprintf(line, "%.15g", v); strcat(line, "\n"); write(fd, line, strlen(line)); linelim = -1; efree(e); if (fmt) scxfree(fmt); }
void add_frange(struct ent *or_left, struct ent *or_right, struct ent *ir_left, struct ent *ir_right, int toprows, int bottomrows, int leftcols, int rightcols) { struct frange *r; int minr, minc, maxr, maxc; minr = or_left->row < or_right->row ? or_left->row : or_right->row; minc = or_left->col < or_right->col ? or_left->col : or_right->col; maxr = or_left->row > or_right->row ? or_left->row : or_right->row; maxc = or_left->col > or_right->col ? or_left->col : or_right->col; or_left = lookat(minr, minc); or_right = lookat(maxr, maxc); if (ir_left) { minr = ir_left->row < ir_right->row ? ir_left->row : ir_right->row; minc = ir_left->col < ir_right->col ? ir_left->col : ir_right->col; maxr = ir_left->row > ir_right->row ? ir_left->row : ir_right->row; maxc = ir_left->col > ir_right->col ? ir_left->col : ir_right->col; ir_left = lookat(minr, minc); ir_right = lookat(maxr, maxc); if (ir_left->row < or_left->row || ir_left->col < or_left->col || ir_right->row > or_right->row || ir_right->col > or_right->col) { error("Invalid parameters"); return; } } if (frame_base) { /* * Has this frange already been created? If so, any negative * parameters mean "don't change this value." */ for (r = frame_base; r; r = r->r_next) { if ((r->or_left == or_left) && (r->or_right == or_right)) { if (ir_left) { r->ir_left = ir_left; r->ir_right = ir_right; } else { if (toprows < 0) toprows = r->ir_left->row - r->or_left->row; if (bottomrows < 0) bottomrows = r->or_right->row - r->ir_right->row; if (leftcols < 0) leftcols = r->ir_left->col - r->or_left->col; if (rightcols < 0) rightcols = r->or_right->col - r->ir_right->col; r->ir_left = lookat(r->or_left->row + toprows, r->or_left->col + leftcols); r->ir_right = lookat(r->or_right->row - bottomrows, r->or_right->col - rightcols); } /* If all frame sides are 0, delete the frange */ if (r->ir_left == r->or_left && r->ir_right == r->or_right) { if (r->r_next) r->r_next->r_prev = r->r_prev; if (r->r_prev) r->r_prev->r_next = r->r_next; else frame_base = r->r_next; scxfree((char *)r); } modflg++; FullUpdate++; return; } } /* * See if the specified range overlaps any previously created frange. */ for (r = frame_base; r; r = r->r_next) { if ( !(r->or_left->row > or_right->row || r->or_right->row < or_left->row || r->or_left->col > or_right->col || r->or_right->col < or_left->col)) { error("Framed ranges may not be nested or overlapping"); return; } } } if (ir_left != or_left || ir_right != or_right) { r = (struct frange *)scxmalloc((unsigned)sizeof(struct frange)); r->or_left = or_left; r->or_right = or_right; if (ir_left) { r->ir_left = ir_left; r->ir_right = ir_right; } else { if (toprows < 0) toprows = 0; if (bottomrows < 0) bottomrows = 0; if (leftcols < 0) leftcols = 0; if (rightcols < 0) rightcols = 0; r->ir_left = lookat(r->or_left->row + toprows, r->or_left->col + leftcols); r->ir_right = lookat(r->or_right->row - bottomrows, r->or_right->col - rightcols); } r->r_next = frame_base; r->r_prev = (struct frange *)0; if (frame_base) frame_base->r_prev = r; frame_base = r; modflg++; FullUpdate++; } }
/* erase the database (tbl, etc.) */ void erasedb() { int r, c; char * home; for (c = 0; c <= maxcol; c++) { fwidth[c] = DEFWIDTH; precision[c] = DEFPREC; realfmt[c] = DEFREFMT; } for (r = 0; r <= maxrow; r++) { register struct ent ** pp = ATBL(tbl, r, 0); for (c = 0; c++ <= maxcol; pp++) if (*pp != NULL) { //(*pp)->next = freeents; /* save [struct ent] for reuse */ //freeents = *pp; clearent(*pp); } } for (c = 0; c < COLFORMATS; c++) if (colformat[c]) { scxfree(colformat[c]); colformat[c] = NULL; } maxrow = 0; maxcol = 0; clean_range(); propagation = 10; calc_order = BYROWS; prescale = 1.0; tbl_style = 0; optimize = 0; currow = curcol = 0; if (usecurses && has_colors()) color_set(0, NULL); if (mdir) { scxfree(mdir); mdir = NULL; } if (autorun) { scxfree(autorun); autorun = NULL; } for (c = 0; c < FKEYS; c++) if (fkey[c]) { scxfree(fkey[c]); fkey[c] = NULL; } // Load $HOME/.scrc if present. if ((home = getenv("HOME"))) { strcpy(curfile, home); strcat(curfile, "/.scimrc"); if ((c = open(curfile, O_RDONLY)) > -1) { close(c); (void) readfile(curfile, 0); } } /* // Load ./.scimrc if present and $HOME/.scimrc contained `set scrc'. if (scrc && strcmp(home, getcwd(curfile, PATHLEN)) && (c = open(".scimrc", O_RDONLY)) > -1) { close(c); (void) readfile(".scimrc", 0); } */ * curfile = '\0'; }
int yylex() { char *p = line + linelim; int ret=0; static int isfunc = 0; static bool isgoto = 0; static bool colstate = 0; static int dateflag; static char *tokenst = NULL; static int tokenl; while (isspace(*p)) p++; if (*p == '\0') { isfunc = isgoto = 0; ret = -1; } else if (isalpha(*p) || (*p == '_')) { register char *la; /* lookahead pointer */ register struct key *tblp; if (!tokenst) { tokenst = p; tokenl = 0; } /* * This picks up either 1 or 2 alpha characters (a column) or * tokens made up of alphanumeric chars and '_' (a function or * token or command or a range name) */ while (isalpha(*p) && isascii(*p)) { p++; tokenl++; } la = p; while (isdigit(*la) || (*la == '$')) la++; /* * A COL is 1 or 2 char alpha with nothing but digits following * (no alpha or '_') */ if (!isdigit(*tokenst) && tokenl && tokenl <= 2 && (colstate || (isdigit(*(la-1)) && !(isalpha(*la) || (*la == '_'))))) { ret = COL; yylval.ival = atocol(tokenst, tokenl); } else { while (isalpha(*p) || (*p == '_') || isdigit(*p)) { p++; tokenl++; } ret = WORD; if (!linelim || isfunc) { if (isfunc) isfunc--; for (tblp = linelim ? experres : statres; tblp->key; tblp++) if (((tblp->key[0]^tokenst[0])&0137)==0 && tblp->key[tokenl]==0) { int i = 1; while (i<tokenl && ((tokenst[i]^tblp->key[i])&0137)==0) i++; if (i >= tokenl) { ret = tblp->val; colstate = (ret <= S_FORMAT); if (isgoto) { isfunc = isgoto = 0; if (ret != K_ERROR && ret != K_INVALID) ret = WORD; } break; } } } if (ret == WORD) { struct range *r; char *path; if (!find_range(tokenst, tokenl, (struct ent *)0, (struct ent *)0, &r)) { yylval.rval.left = r->r_left; yylval.rval.right = r->r_right; if (r->r_is_range) ret = RANGE; else ret = VAR; } else if ((path = scxmalloc((unsigned)PATHLEN)) && plugin_exists(tokenst, tokenl, path)) { strcat(path, p); yylval.sval = path; ret = PLUGIN; } else { scxfree(path); linelim = p-line; yyerror("Unintelligible word"); } } } } else if ((*p == '.') || isdigit(*p)) { #ifdef SIGVOID void (*sig_save)(); #else int (*sig_save)(); #endif double v = 0.0; int temp; char *nstart = p; sig_save = signal(SIGFPE, fpe_trap); if (setjmp(fpe_buf)) { (void) signal(SIGFPE, sig_save); yylval.fval = v; error("Floating point exception\n"); isfunc = isgoto = 0; tokenst = NULL; return FNUMBER; } if (*p=='.' && dateflag) { /* .'s in dates are returned as tokens. */ ret = *p++; dateflag--; } else { if (*p != '.') { tokenst = p; tokenl = 0; do { v = v*10.0 + (double) ((unsigned) *p - '0'); tokenl++; } while (isdigit(*++p)); if (dateflag) { ret = NUMBER; yylval.ival = (int)v; /* * If a string of digits is followed by two .'s separated by * one or two digits, assume this is a date and return the * .'s as tokens instead of interpreting them as decimal * points. dateflag counts the .'s as they're returned. */ } else if (*p=='.' && isdigit(*(p+1)) && (*(p+2)=='.' || (isdigit(*(p+2)) && *(p+3)=='.'))) { ret = NUMBER; yylval.ival = (int)v; dateflag = 2; } else if (*p == 'e' || *p == 'E') { while (isdigit(*++p)) /* */; if (isalpha(*p) || *p == '_') { linelim = p - line; return (yylex()); } else ret = FNUMBER; } else if (isalpha(*p) || *p == '_') { linelim = p - line; return (yylex()); } } if ((!dateflag && *p=='.') || ret == FNUMBER) { ret = FNUMBER; yylval.fval = strtod(nstart, &p); if (!finite(yylval.fval)) ret = K_ERR; else decimal = TRUE; } else { /* A NUMBER must hold at least MAXROW and MAXCOL */ /* This is consistent with a short row and col in struct ent */ if (v > (double)32767 || v < (double)-32768) { ret = FNUMBER; yylval.fval = v; } else { temp = (int)v; if((double)temp != v) { ret = FNUMBER; yylval.fval = v; } else { ret = NUMBER; yylval.ival = temp; } } } } (void) signal(SIGFPE, sig_save); } else if (*p=='"') { char *ptr; ptr = p+1; /* "string" or "string\"quoted\"" */ while (*ptr && ((*ptr != '"') || (*(ptr-1) == '\\'))) ptr++; ptr = scxmalloc((unsigned)(ptr-p)); yylval.sval = ptr; p++; while (*p && ((*p != '"') || (*(p-1) == '\\' && *(p+1) != '\0' && *(p+1) != '\n'))) *ptr++ = *p++; *ptr = '\0'; if (*p) p++; ret = STRING; } else if (*p=='[') { while (*p && *p!=']') p++; if (*p) p++; linelim = p-line; tokenst = NULL; return yylex(); } else ret = *p++; linelim = p-line; if (!isfunc) isfunc = ((ret == '@') + (ret == S_GOTO) - (ret == S_SET)); if (ret == S_GOTO) isgoto = TRUE; tokenst = NULL; return ret; }
void add_range(char *name, struct ent_ptr left, struct ent_ptr right, int is_range) { struct range *r; register char *p; int minr, minc, maxr, maxc; int minrf, mincf, maxrf, maxcf; register struct ent *rcp; struct range *prev = 0; if (left.vp->row < right.vp->row) { minr = left.vp->row; minrf = left.vf & FIX_ROW; maxr = right.vp->row; maxrf = right.vf & FIX_ROW; } else { minr = right.vp->row; minrf = right.vf & FIX_ROW; maxr = left.vp->row; maxrf = right.vf & FIX_ROW; } if (left.vp->col < right.vp->col) { minc = left.vp->col; mincf = left.vf & FIX_COL; maxc = right.vp->col; maxcf = right.vf & FIX_COL; } else { minc = right.vp->col; mincf = right.vf & FIX_COL; maxc = left.vp->col; maxcf = left.vf & FIX_COL; } left.vp = lookat(minr, minc); left.vf = minrf | mincf; right.vp = lookat(maxr, maxc); right.vf = maxrf | maxcf; if (!find_range(name, strlen(name), (struct ent *)0, (struct ent *)0, &prev)) { error("Error: range name \"%s\" already defined", name); scxfree(name); return; } for (p = name; *p; p++) if (!(isalpha(*p) || isdigit(*p) || *p == '_')) { error("Invalid range name \"%s\" - illegal combination", name); scxfree(name); return; } p = name; if (isdigit(*p) || (isalpha(*p++) && (isdigit(*p) || (isalpha(*p++) && isdigit(*p))))) { if (*name == '0' && (name[1] == 'x' || name[1] == 'X')) { ++p; while (isxdigit(*++p)) /* */; if (*p == 'p' || *p == 'P') while (isxdigit(*++p)) /* */; } else { while (isdigit(*++p)) /* */; if (isdigit(*name) && (*p == 'e' || *p == 'E')) while (isdigit(*++p)) /* */; } if (!(*p)) { error("Invalid range name \"%s\" - ambiguous", name); scxfree(name); return; } } if (autolabel && minc>0 && !is_range) { rcp = lookat(minr, minc-1); if (rcp->label==0 && rcp->expr==0 && rcp->v==0) label(rcp, name, 0); } r = (struct range *)scxmalloc((unsigned)sizeof(struct range)); r->r_name = name; r->r_left = left; r->r_right = right; r->r_is_range = is_range; if (prev) { r->r_next = prev->r_next; r->r_prev = prev; prev->r_next = r; if (r->r_next) r->r_next->r_prev = r; } else { r->r_next = rng_base; r->r_prev = (struct range *)0; if (rng_base) rng_base->r_prev = r; rng_base = r; } modflg++; }
void add_abbr(char *string) { struct abbrev *a; register char *p; struct abbrev *prev = NULL; char *expansion; if (!string || *string == '\0') { if (!are_abbrevs()) { error("No abbreviations defined"); return; } else { FILE *f; int pid; char px[MAXCMD]; char *pager; struct abbrev *a; struct abbrev *nexta; strlcpy(px, "| ", sizeof px); if (!(pager = getenv("PAGER"))) pager = DFLT_PAGER; strlcat(px, pager, sizeof px); f = openfile(px, sizeof px, &pid, NULL); if (!f) { error("Can't open pipe to %s", pager); return; } (void) fprintf(f, "\n%-15s %s\n","Abbreviation","Expanded"); if (!brokenpipe) (void) fprintf(f, "%-15s %s\n", "------------", "--------"); for (a = nexta = abbr_base; nexta; a = nexta, nexta = a->a_next) ; while (a) { (void) fprintf(f, "%-15s %s\n", a->abbr, a->exp); if (brokenpipe) return; a = a->a_prev; } closefile(f, pid, 0); return; } } if ((expansion = strchr(string, ' '))) *expansion++ = '\0'; if (isalpha((int)*string) || isdigit((int)*string) || *string == '_') { for (p = string; *p; p++) if (!(isalpha((int)*p) || isdigit((int)*p) || *p == '_')) { error("Invalid abbreviation: %s", string); scxfree(string); return; } } else { for (p = string; *p; p++) if ((isalpha((int)*p) || isdigit((int)*p) || *p == '_') && *(p+1)) { error("Invalid abbreviation: %s", string); scxfree(string); return; } } if (expansion == NULL) { if ((a = find_abbr(string, strlen(string), &prev))) { error("abbrev \"%s %s\"", a->abbr, a->exp); return; } else { error("abreviation \"%s\" doesn't exist", string); return; } } if (find_abbr(string, strlen(string), &prev)) del_abbr(string); a = scxmalloc(sizeof(struct abbrev)); a->abbr = string; a->exp = expansion; if (prev) { a->a_next = prev->a_next; a->a_prev = prev; prev->a_next = a; if (a->a_next) a->a_next->a_prev = a; } else { a->a_next = abbr_base; a->a_prev = NULL; if (abbr_base) abbr_base->a_prev = a; abbr_base = a; } }
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; }