192 lines
5.0 KiB
C
192 lines
5.0 KiB
C
#include "cell.h"
|
|
|
|
#include <assert.h>
|
|
#include <string.h>
|
|
|
|
#include "default.h"
|
|
#include "eval.h"
|
|
#include "main.h"
|
|
|
|
const char *ColorAspect_Name[] =
|
|
{ [FOREGROUND] = "Foreground", [BACKGROUND] = "Background"
|
|
};
|
|
const ColorNum DefaultCN[] =
|
|
{ [FOREGROUND] = 0, [BACKGROUND] = 16, [NUM_COLOR_ASPECTS] = 255 };
|
|
|
|
const char *TokVariety_Name[] =
|
|
{ [BASE_CONT] = "Base Content", [ITER_CONT] = "Iterative Content",
|
|
[ATTR_REF] = "Attribute Reference", [CURR_VAL] = "Current Value",
|
|
[RES_VAL] = "Resultant Value", [CONTINGENT] = "Contingent Content"
|
|
};
|
|
|
|
/* initcellcontents - make a fresh cell into the "empty" one; don't worry
|
|
about freeing anything there, that will have been handled. */
|
|
void initcellcontents(Cell *fresh)
|
|
{
|
|
for (TokVariety tv = BASE_CONT; tv < CONTINGENT; ++tv)
|
|
fresh->tok[tv].type = EMPTY;
|
|
fresh->label = NULL;
|
|
fresh->precision = -1;
|
|
fresh->adjust = AUTOADJUST;
|
|
for (ColorAspect a = FOREGROUND; a < NUM_COLOR_ASPECTS; ++a)
|
|
fresh->aspect[a] = DefaultCN[a];
|
|
fresh->updated = 0;
|
|
fresh->shadowed = 0;
|
|
fresh->scientific = DEF_SCIENTIFIC;
|
|
fresh->locked = 0;
|
|
fresh->transparent = 0;
|
|
fresh->ignored = 0;
|
|
fresh->clock_t0 = 0;
|
|
fresh->clock_t1 = 0;
|
|
fresh->clock_t2 = 0;
|
|
fresh->bold = 0;
|
|
fresh->underline = 0;
|
|
}
|
|
|
|
/* getcont -- get contents */
|
|
Token gettok(const Cell *cell, TokVariety v)
|
|
{
|
|
Token emp;
|
|
emp.type = EMPTY;
|
|
if (cell == NULLCELL) return emp;
|
|
if (v == CONTINGENT)
|
|
v = (cell->clock_t0 && cell->tok[ITER_CONT].type != EMPTY)
|
|
? ITER_CONT : BASE_CONT;
|
|
return cell->tok[v];
|
|
}
|
|
|
|
/* getadjust -- get cell adjustment */
|
|
Adjust getadjust(const Cell* cell)
|
|
{
|
|
if (cell == NULLCELL) return LEFT;
|
|
else if (cell->adjust == AUTOADJUST)
|
|
return (cell->tok[CURR_VAL].type == INT
|
|
|| cell->tok[CURR_VAL].type == FLOAT) ? RIGHT : LEFT;
|
|
else return cell->adjust;
|
|
}
|
|
|
|
/* shadowed -- is cell shadowed? */
|
|
bool shadowed(const Cell *cell)
|
|
{
|
|
return (cell != NULLCELL) && cell->shadowed;
|
|
}
|
|
|
|
/* isbold -- is cell bold? */
|
|
bool isbold(const Cell* cell)
|
|
{
|
|
return (cell != NULLCELL) && cell->bold;
|
|
}
|
|
|
|
/* getcolor -- a color associated to cell */
|
|
ColorNum getcolor(const Cell* cell, ColorAspect aspect)
|
|
{
|
|
return cell == NULLCELL ? DefaultCN[aspect] : cell->aspect[aspect];
|
|
}
|
|
|
|
/* isunderline -- is cell underlined? */
|
|
bool underlined(const Cell *cell)
|
|
{
|
|
return (cell != NULLCELL) && cell->underline;
|
|
}
|
|
|
|
/* locked -- is cell locked? */
|
|
bool locked(const Cell *cell)
|
|
{
|
|
return (cell != NULLCELL) && cell->locked;
|
|
}
|
|
|
|
/* transparent -- is cell transparent? */
|
|
bool transparent(const Cell* cell)
|
|
{
|
|
return (cell != NULLCELL) && cell->transparent;
|
|
}
|
|
|
|
/* ignored -- is cell ignored? */
|
|
bool ignored(const Cell *cell)
|
|
{
|
|
return (cell != NULLCELL) && cell->ignored;
|
|
}
|
|
|
|
|
|
/* getscientific -- should value be displayed in scientific notation? */
|
|
bool getscientific(const Cell *cell )
|
|
{
|
|
return (cell == NULLCELL) ? DEF_SCIENTIFIC : cell->scientific;
|
|
}
|
|
|
|
/* getprecision -- get cell precision */
|
|
int getprecision(const Cell *cell)
|
|
{
|
|
if (cell == NULLCELL || cell->precision == -1) return def_precision;
|
|
return cell->precision;
|
|
}
|
|
|
|
/* getlabel -- get cell label */
|
|
const char *getlabel(const Cell* cell)
|
|
{
|
|
if (cell == NULLCELL || cell->label == (char*)0) return "";
|
|
return cell->label;
|
|
}
|
|
|
|
/* copytokens -- copy a sequence of tokens, possibly reallocating dest */
|
|
static void copytokens(Token*** totoks, Token** fromtoks)
|
|
{
|
|
size_t from_len = tveclen(fromtoks);
|
|
if (from_len == 0)
|
|
{
|
|
tvecfree(*totoks);
|
|
*totoks = EMPTY_TVEC;
|
|
return;
|
|
}
|
|
|
|
size_t to_len = tveclen(*totoks);
|
|
if (from_len > to_len || *totoks == fromtoks)
|
|
{
|
|
if (*totoks != fromtoks) tvecfree(*totoks);
|
|
*totoks = malloc((from_len+1)*sizeof(Token*));
|
|
(*totoks)[from_len] = NULLTOKEN;
|
|
} else {
|
|
tvecfreetoks(*totoks);
|
|
}
|
|
for (size_t i = 0; i<from_len; ++i) /* destination already has NULLTOKEN at end */
|
|
{
|
|
if (fromtoks[i] == NULLTOKEN) (*totoks)[i] = NULLTOKEN;
|
|
else
|
|
{
|
|
(*totoks)[i] = malloc(sizeof(Token));
|
|
*((*totoks)[i]) = tcopy(*(fromtoks[i]));
|
|
}
|
|
}
|
|
}
|
|
|
|
/* freecellcontents -- free the resources of the cell at destruction time */
|
|
void freecellcontents(Cell *faded)
|
|
{
|
|
for (TokVariety tv = BASE_CONT; tv < CONTINGENT; ++tv)
|
|
tfree(&(faded->tok[tv]));
|
|
if (faded->label != NULL) free(faded->label);
|
|
}
|
|
|
|
/* copycell - copies one Cell to another, handling any allocation issues */
|
|
void copycell(Cell *to, const Cell *fromcell, LabelHandling lh)
|
|
{
|
|
assert(to != NULLCELL);
|
|
if (to == fromcell) return;
|
|
|
|
freecellcontents(to);
|
|
if (fromcell != NULLCELL) {
|
|
memcpy(to, fromcell, sizeof(Cell));
|
|
for (TokVariety tv = BASE_CONT; tv < CONTINGENT; ++tv)
|
|
if (tv <= MAX_PERSIST_TV) to->tok[tv] = tcopy(fromcell->tok[tv]);
|
|
else to->tok[tv].type = EMPTY;
|
|
if (lh != PRESERVE_LABEL && fromcell->label != (char*)0) {
|
|
size_t len = strlen(fromcell->label);
|
|
to->label = strcpy(malloc(len+2), fromcell->label);
|
|
(to->label)[len] = '_';
|
|
(to->label)[len+1] = '\0';
|
|
}
|
|
} else {
|
|
initcellcontents(to);
|
|
}
|
|
}
|