summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrés M <andmarti1424@users.noreply.github.com>2016-02-12 12:00:09 -0300
committerAndrés M <andmarti1424@users.noreply.github.com>2016-02-12 12:00:09 -0300
commit84b8c1ef8565f4cdfb7815ad6e71b5215f2aba63 (patch)
tree5b2b74661ceefe5223d3c8a35474ab7ec7a241fa
parent945074dc415f5a5f49d326ff6634acf5523350a2 (diff)
parent35382e66ea8b93015d7083d00a4b75a3b00c8ee1 (diff)
Merge pull request #53 from andmarti1424/dev
equal branches
-rw-r--r--KNOWN_ISSUES4
-rw-r--r--Readme.md2
-rw-r--r--src/cmds.c5
-rw-r--r--src/cmds_insert.c4
-rw-r--r--src/cmds_normal.c100
-rw-r--r--src/doc5
-rw-r--r--src/gram.y16
-rw-r--r--src/interp.c213
-rw-r--r--src/interp.h5
-rw-r--r--src/main.c31
-rw-r--r--src/sc.h12
-rw-r--r--src/screen.c38
-rw-r--r--src/screen.h1
-rw-r--r--src/utils/string.c6
-rw-r--r--src/utils/string.h1
15 files changed, 289 insertions, 154 deletions
diff --git a/KNOWN_ISSUES b/KNOWN_ISSUES
index b832395..795d2f4 100644
--- a/KNOWN_ISSUES
+++ b/KNOWN_ISSUES
@@ -7,3 +7,7 @@ This also happens in SC and has to be solved.
Problem: Some cell equations gets messy after undo/redos.
This fix requires implementation of Calc Chain. This will allow
to fix this problem when UNDOing actions that change cells equations.
+
+Problem: Extended ascii chars not showing correctly.
+Compile sc-im against -lncursesw and not -lncurses.
+
diff --git a/Readme.md b/Readme.md
index a074f28..04d8ea2 100644
--- a/Readme.md
+++ b/Readme.md
@@ -41,7 +41,7 @@ SC-IM stands for Spreadsheet Calculator Improvised. :-)
Please. I mean, Please.. make a DONATION with PayPal.
If you wish to make a donation, please send money to scim.spreadsheet@gmail.com via PayPal.
-Currently, we already received the amount of 20 USD and 30 euros.
+Currently, we already received the amount of 21 USD and 30 euros.
A lot of features are in the roadmap, such as multiple worksheets, and even a GTK gui!
Thanks.
diff --git a/src/cmds.c b/src/cmds.c
index 2ff2bc9..3bef04f 100644
--- a/src/cmds.c
+++ b/src/cmds.c
@@ -1512,6 +1512,7 @@ int is_single_command (struct block * buf, long timeout) {
else if (buf->value == 'b') res = MOVEMENT_CMD;
else if (buf->value == '/') res = MOVEMENT_CMD; // search
else if (buf->value == 'n') res = MOVEMENT_CMD; // repeat last goto cmd
+ else if (buf->value == 'N') res = MOVEMENT_CMD; // repeat last goto cmd - backwards
// edition commands
else if (buf->value == 'x') res = EDITION_CMD; // cuts a cell
@@ -1540,7 +1541,9 @@ int is_single_command (struct block * buf, long timeout) {
buf->pnext->value == 'g' ||
buf->pnext->value == 'G' ||
buf->pnext->value == '0' ||
- buf->pnext->value == '$')) res = MOVEMENT_CMD;
+ buf->pnext->value == 'l' ||
+ buf->pnext->value == '$'))
+ res = MOVEMENT_CMD;
else if (buf->value == 'g' && bs > 2 && timeout >= COMPLETECMDTIMEOUT)
res = MOVEMENT_CMD; // goto cell
diff --git a/src/cmds_insert.c b/src/cmds_insert.c
index 9366771..216c221 100644
--- a/src/cmds_insert.c
+++ b/src/cmds_insert.c
@@ -2,7 +2,7 @@
#include "cmds.h"
#include "screen.h"
#include <string.h>
-#include <ctype.h> // for isprint()
+//#include <ctype.h> // for isprint()
#include "buffer.h"
#include "sc.h" // for rescol
#include "utils/string.h"
@@ -42,7 +42,7 @@ void do_insertmode(struct block * sb) {
} else if (find_val(sb, OKEY_ENTER)) { // ENTER
insert_or_edit_cell();
- } else if ( strlen(inputline) < (COLS - 14) && isprint(sb->value)) { // Write new char
+ } else if ( strlen(inputline) < (COLS - 14) && sc_isprint(sb->value)) { // Write new char
ins_in_line(sb->value);
show_header(input_win);
diff --git a/src/cmds_normal.c b/src/cmds_normal.c
index 06c71d6..6ba76a0 100644
--- a/src/cmds_normal.c
+++ b/src/cmds_normal.c
@@ -28,9 +28,11 @@ void do_normalmode(struct block * buf) {
switch (buf->value) {
- // Movement commands
+ // MOVEMENT COMMANDS
case 'j':
case OKEY_DOWN:
+ lastcol = curcol;
+ lastrow = currow;
currow = forw_row(1)->row;
unselect_ranges();
update(TRUE);
@@ -38,6 +40,8 @@ void do_normalmode(struct block * buf) {
case 'k':
case OKEY_UP:
+ lastcol = curcol;
+ lastrow = currow;
currow = back_row(1)->row;
unselect_ranges();
update(TRUE);
@@ -45,6 +49,8 @@ void do_normalmode(struct block * buf) {
case 'h':
case OKEY_LEFT:
+ lastrow = currow;
+ lastcol = curcol;
curcol = back_col(1)->col;
unselect_ranges();
update(TRUE);
@@ -52,6 +58,8 @@ void do_normalmode(struct block * buf) {
case 'l':
case OKEY_RIGHT:
+ lastrow = currow;
+ lastcol = curcol;
curcol = forw_col(1)->col;
unselect_ranges();
update(TRUE);
@@ -59,6 +67,8 @@ void do_normalmode(struct block * buf) {
case '0':
case OKEY_HOME:
+ lastrow = currow;
+ lastcol = curcol;
curcol = left_limit()->col;
unselect_ranges();
update(TRUE);
@@ -66,18 +76,24 @@ void do_normalmode(struct block * buf) {
case '$':
case OKEY_END:
+ lastrow = currow;
+ lastcol = curcol;
curcol = right_limit()->col;
unselect_ranges();
update(TRUE);
break;
case '^':
+ lastcol = curcol;
+ lastrow = currow;
currow = goto_top()->row;
unselect_ranges();
update(TRUE);
break;
case '#':
+ lastcol = curcol;
+ lastrow = currow;
currow = goto_bottom()->row;
unselect_ranges();
update(TRUE);
@@ -96,6 +112,8 @@ void do_normalmode(struct block * buf) {
scerror("Cell column is hidden");
break;
}
+ lastrow = currow;
+ lastcol = curcol;
currow = e->row;
curcol = e->col;
update(TRUE);
@@ -156,6 +174,8 @@ void do_normalmode(struct block * buf) {
int n = LINES - RESROW - 1;
if (atoi(get_conf_value("half_page_scroll"))) n = n / 2;
struct ent * e = forw_row(n);
+ lastcol = curcol;
+ lastrow = currow;
currow = e->row;
unselect_ranges();
scroll_down(n);
@@ -169,6 +189,8 @@ void do_normalmode(struct block * buf) {
{
int n = LINES - RESROW - 1;
if (atoi(get_conf_value("half_page_scroll"))) n = n / 2;
+ lastcol = curcol;
+ lastrow = currow;
currow = back_row(n)->row;
unselect_ranges();
scroll_up(n);
@@ -178,6 +200,8 @@ void do_normalmode(struct block * buf) {
case 'w':
e = go_forward();
+ lastrow = currow;
+ lastcol = curcol;
currow = e->row;
curcol = e->col;
unselect_ranges();
@@ -186,37 +210,33 @@ void do_normalmode(struct block * buf) {
case 'b':
e = go_backward();
+ lastrow = currow;
+ lastcol = curcol;
currow = e->row;
curcol = e->col;
unselect_ranges();
update(TRUE);
break;
- case '/':
- {
- char cadena[] = ":int goto ";
- int i;
- for (i=0; i<strlen(cadena); i++) {
- flush_buf(buf);
- addto_buf(buf, cadena[i]);
- exec_single_cmd(buf);
- }
- break;
- }
-
case 'H':
+ lastrow = currow;
+ lastcol = curcol;
currow = vert_top()->row;
unselect_ranges();
update(TRUE);
break;
case 'M':
+ lastcol = curcol;
+ lastrow = currow;
currow = vert_middle()->row;
unselect_ranges();
update(TRUE);
break;
case 'L':
+ lastrow = currow;
+ lastcol = curcol;
currow = vert_bottom()->row;
unselect_ranges();
update(TRUE);
@@ -224,6 +244,8 @@ void do_normalmode(struct block * buf) {
case 'G': // goto end
e = go_end();
+ lastrow = currow;
+ lastcol = curcol;
currow = e->row;
curcol = e->col;
unselect_ranges();
@@ -233,6 +255,8 @@ void do_normalmode(struct block * buf) {
// GOTO goto
case ctl('a'):
e = go_home();
+ lastrow = currow;
+ lastcol = curcol;
curcol = e->col;
currow = e->row;
unselect_ranges();
@@ -241,24 +265,42 @@ void do_normalmode(struct block * buf) {
case 'g':
if (buf->pnext->value == '0') { // g0
+ lastcol = curcol;
+ lastrow = currow;
curcol = go_bol()->col;
} else if (buf->pnext->value == '$') { // g$
+ lastcol = curcol;
+ lastrow = currow;
curcol = go_eol()->col;
} else if (buf->pnext->value == 'g') { // gg
e = go_home();
+ lastcol = curcol;
+ lastrow = currow;
curcol = e->col;
currow = e->row;
} else if (buf->pnext->value == 'G') { // gG
e = go_end();
+ lastcol = curcol;
+ lastrow = currow;
currow = e->row;
curcol = e->col;
} else if (buf->pnext->value == 'M') { // gM
+ lastcol = curcol;
+ lastrow = currow;
curcol = horiz_middle()->col;
+ // goto last cell position
+ } else if (buf->pnext->value == 'l') { // gl
+ int newlr = currow;
+ int newlc = curcol;
+ curcol = lastcol;
+ currow = lastrow;
+ lastrow = newlr;
+ lastcol = newlc;
} else { // gA4 (goto cell)
(void) sprintf(interp_line, "goto %s", parse_cell_name(1, buf));
send_to_interp(interp_line);
@@ -267,6 +309,32 @@ void do_normalmode(struct block * buf) {
update(TRUE);
break;
+ // repeat last goto command - backwards
+ case 'N':
+ go_previous();
+ update(TRUE);
+ break;
+
+ // repeat last goto command
+ case 'n':
+ go_last();
+ update(TRUE);
+ break;
+
+ // END OF MOVEMENT COMMANDS
+
+ case '/':
+ {
+ char cadena[] = ":int goto ";
+ int i;
+ for (i=0; i<strlen(cadena); i++) {
+ flush_buf(buf);
+ addto_buf(buf, cadena[i]);
+ exec_single_cmd(buf);
+ }
+ break;
+ }
+
// repeat last command
case '.':
copybuffer(lastcmd_buffer, buf); // nose graba en lastcmd_buffer!!
@@ -418,12 +486,6 @@ void do_normalmode(struct block * buf) {
break;
}
- // repeat last goto command
- case 'n':
- go_last();
- update(TRUE);
- break;
-
// range lock / unlock / valueize
case 'r':
{
diff --git a/src/doc b/src/doc
index 497724e..09afeb2 100644
--- a/src/doc
+++ b/src/doc
@@ -41,6 +41,7 @@ Navigation commands:
gg , c-a: Go to home (first cell of spreadsheet).
G Go to last valid cell of spreadsheet.
gG Go to last valid cell of spreadsheet.
+ gl moves to last cell position
c-f , c-b: Scrolls down and up full screen.
set variable half_page_scroll to 1 to scroll half page,
instead of full page. see :set command for details.
@@ -141,10 +142,12 @@ Commands for handling cell content:
'/' is an alias for ':int goto '.
If a number is given, SC-IM will search for a cell containing that number. Searches for either strings or numbers proceed forward from the current cell, wrapping back to a0 at the end of the table, and terminate at the current cell if the string or number is not found.
Ex.: You can type '/4' to look for cells that has the value of 4.
- Or you can type '/value' to look for cells that has "value" as label content.
+ Or you can type '/"value"' to look for cells that has "value" as label content.
You can also quote a regular expression, and SC-IM will search for a cell containing a string matching the regular expression.
You can also search formatted numbers or expressions using regular expressions by preceding the opening quotes of the regular expression with a '#' (for formatted numbers) or a '%' (for expressions).
These are handy for searching for dates within a specified range or cells which reference a given cell, for example, although they are somewhat slower than searching through ordinary strings, since all numbers must be formatted or expressions decompiled on the fly during the search.
+ n Moves to next search match
+ N Moves to previous search match
rl Use this command to lock the current cell or a range of cells, i.e. make them immune to any type of editing. A locked cell can't be changed in any way until it is unlocked.
ru This command is the opposite of the rl command and thus unlocks a locked cell and makes it editable.
diff --git a/src/gram.y b/src/gram.y
index cc01128..7bceb40 100644
--- a/src/gram.y
+++ b/src/gram.y
@@ -422,10 +422,10 @@ command:
| S_GOTO var_or_range var_or_range { moveto($2.left.vp->row, $2.left.vp->col, $2.right.vp->row, $2.right.vp->col, $3.left.vp->row, $3.left.vp->col); }
| S_GOTO var_or_range { moveto($2.left.vp->row, $2.left.vp->col, $2.right.vp->row, $2.right.vp->col, -1, -1); }
- | S_GOTO num { num_search($2, 0, 0, maxrow, maxcol, 0); }
- | S_GOTO STRING { str_search($2, 0, 0, maxrow, maxcol, 0); }
- | S_GOTO '#' STRING { str_search($3, 0, 0, maxrow, maxcol, 1); }
- | S_GOTO '%' STRING { str_search($3, 0, 0, maxrow, maxcol, 2); }
+ | S_GOTO num { num_search($2, 0, 0, maxrow, maxcol, 0, 1); }
+ | S_GOTO STRING { str_search($2, 0, 0, maxrow, maxcol, 0, 1); }
+ | S_GOTO '#' STRING { str_search($3, 0, 0, maxrow, maxcol, 1, 1); }
+ | S_GOTO '%' STRING { str_search($3, 0, 0, maxrow, maxcol, 2, 1); }
| S_GOTO WORD { /* don't repeat last goto on "unintelligible word" */ ; }
@@ -928,16 +928,16 @@ errlist :
K_ERROR range { num_search((double)0,
$2.left.vp->row, $2.left.vp->col,
$2.right.vp->row, $2.right.vp->col,
- CELLERROR); }
+ CELLERROR, 1); }
| K_ERROR { num_search((double)0, 0, 0,
- maxrow, maxcol, CELLERROR); }
+ maxrow, maxcol, CELLERROR, 1); }
| K_INVALID range { num_search((double)0,
$2.left.vp->row, $2.left.vp->col,
$2.right.vp->row, $2.right.vp->col,
- CELLINVALID); }
+ CELLINVALID, 1); }
| K_INVALID { num_search((double)0, 0, 0,
- maxrow, maxcol, CELLINVALID); }
+ maxrow, maxcol, CELLINVALID, 1); }
;
*/
diff --git a/src/interp.c b/src/interp.c
index 101b933..cd48060 100644
--- a/src/interp.c
+++ b/src/interp.c
@@ -35,6 +35,7 @@
#include "range.h"
#include "xmalloc.h" // for scxfree
#include "lex.h" // for atocol
+#include "interp.h"
#include <unistd.h>
#ifdef UNDO
@@ -46,20 +47,17 @@
#endif
#ifdef RE_COMP
-extern char *re_comp(char *s);
-extern char *re_exec(char *s);
+extern char * re_comp(char *s);
+extern char * re_exec(char *s);
#endif
#ifdef REGCMP
-char *regcmp();
-char *regex();
+char * regcmp();
+char * regex();
#endif
void exit_app();
-/* Use this structure to save the last 'g' command */
-struct go_save gs;
-
/* g_type can be: */
#define G_NONE 0 /* Starting value - must be 0 */
#define G_NUM 1
@@ -68,6 +66,9 @@ struct go_save gs;
#define G_XSTR 4
#define G_CELL 5
+/* Use this structure to save the last 'g' command */
+struct go_save gs = { .g_type = G_NONE } ;
+
#define ISVALID(r,c) ((r)>=0 && (r)<maxrows && (c)>=0 && (c)<maxcols)
jmp_buf fpe_save;
@@ -209,7 +210,7 @@ double doindex(int minr, int minc, int maxr, int maxc, struct enode *val) {
}
if (c <= maxc && c >=minc && r <= maxr && r >=minr &&
- (p = *ATBL(tbl, r, c)) && p->flags&is_valid) {
+ (p = *ATBL(tbl, r, c)) && p->flags & is_valid) {
if (p->cellerror)
cellerror = CELLINVALID;
return p->v;
@@ -229,7 +230,7 @@ double dolookup(struct enode * val, int minr, int minc, int maxr, int maxc, int
cellerror = CELLOK;
v = eval(val);
for (r = minr, c = minc; r <= maxr && c <= maxc; r+=incr, c+=incc) {
- if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid) {
+ if ((p = *ATBL(tbl, r, c)) && p->flags & is_valid) {
if (p->v <= v) {
fndr = incc ? (minr + offset) : r;
fndc = incr ? (minc + offset) : c;
@@ -242,7 +243,7 @@ double dolookup(struct enode * val, int minr, int minc, int maxr, int maxc, int
scerror(" range specified to @[hv]lookup");
cellerror = CELLERROR;
}
- if (p && p->flags&is_valid) {
+ if (p && p->flags & is_valid) {
if (p->cellerror)
cellerror = CELLINVALID;
ret = p->v;
@@ -270,7 +271,7 @@ double dolookup(struct enode * val, int minr, int minc, int maxr, int maxc, int
}
}
}
- if (p && p->flags&is_valid)
+ if (p && p->flags & is_valid)
ret = p->v;
scxfree(s);
}
@@ -366,7 +367,7 @@ double doavg(int minr, int minc, int maxr, int maxc, struct enode *e) {
coloffset = c - minc;
}
if (!e || eval(e))
- if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid) {
+ if ((p = *ATBL(tbl, r, c)) && p->flags & is_valid) {
if (p->cellerror) cellerr = CELLINVALID;
v += p->v;
count++;
@@ -397,7 +398,7 @@ double dostddev(int minr, int minc, int maxr, int maxc, struct enode *e) {
coloffset = c - minc;
}
if (!e || eval(e))
- if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid) {
+ if ((p = *ATBL(tbl, r, c)) && p->flags & is_valid) {
if (p->cellerror) cellerr = CELLINVALID;
v = p->v;
lp += v*v;
@@ -428,7 +429,7 @@ double domax(int minr, int minc, int maxr, int maxc, struct enode *e) {
coloffset = c - minc;
}
if (!e || eval(e))
- if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid) {
+ if ((p = *ATBL(tbl, r, c)) && p->flags & is_valid) {
if (p->cellerror) cellerr = CELLINVALID;
if (! count) {
@@ -461,7 +462,7 @@ double domin(int minr, int minc, int maxr, int maxc, struct enode *e) {
coloffset = c - minc;
}
if (!e || eval(e))
- if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid) {
+ if ((p = *ATBL(tbl, r, c)) && p->flags & is_valid) {
if (p->cellerror) cellerr = CELLINVALID;
if (! count) {
v = p->v;
@@ -1675,14 +1676,36 @@ void mover(struct ent *d, struct ent *v1, struct ent *v2) {
// Goto subroutines */
void g_free() {
switch (gs.g_type) {
- case G_STR:
- case G_NSTR: scxfree(gs.g_s); break;
- default: break;
+ case G_STR:
+ case G_NSTR:
+ scxfree(gs.g_s);
+ break;
+ default:
+ break;
}
gs.g_type = G_NONE;
gs.errsearch = 0;
}
+void go_previous() {
+ int num = 0;
+
+ switch (gs.g_type) {
+ case G_NONE:
+ scerror("Nothing to repeat");
+ break;
+ case G_NUM:
+ num_search(gs.g_n, gs.g_row, gs.g_col, gs.g_lastrow, gs.g_lastcol, gs.errsearch, 0);
+ break;
+ case G_STR:
+ gs.g_type = G_NONE; /* Don't free the string */
+ str_search(gs.g_s, gs.g_row, gs.g_col, gs.g_lastrow, gs.g_lastcol, num, 0);
+ break;
+ default:
+ scerror("go_previous: internal error");
+ }
+}
+
/* repeat the last goto command */
void go_last() {
int num = 0;
@@ -1692,18 +1715,17 @@ void go_last() {
scerror("Nothing to repeat");
break;
case G_NUM:
- num_search(gs.g_n, gs.g_row, gs.g_col,
- gs.g_lastrow, gs.g_lastcol, gs.errsearch);
+ num_search(gs.g_n, gs.g_row, gs.g_col, gs.g_lastrow, gs.g_lastcol, gs.errsearch, 1);
+ break;
+ case G_CELL:
+ moveto(gs.g_row, gs.g_col, gs.g_lastrow, gs.g_lastcol, gs.strow, gs.stcol);
break;
-// case G_CELL:
-// moveto(gs.g_row, gs.g_col, gs.g_lastrow, gs.g_lastcol, gs.strow, gs.stcol);
-// break;
case G_XSTR:
case G_NSTR:
num++;
case G_STR:
gs.g_type = G_NONE; /* Don't free the string */
- str_search(gs.g_s, gs.g_row, gs.g_col, gs.g_lastrow, gs.g_lastcol, num);
+ str_search(gs.g_s, gs.g_row, gs.g_col, gs.g_lastrow, gs.g_lastcol, num, 1);
break;
default:
@@ -1715,36 +1737,38 @@ void go_last() {
* at row cornerrow and column cornercol in the upper left corner of the
* screen if possible.
*/
-void moveto(int row, int col, int lastrow, int lastcol, int cornerrow, int cornercol) {
+void moveto(int row, int col, int lastrow_, int lastcol_, int cornerrow, int cornercol) {
register int i;
//if (!loading && row != -1 && (row != currow || col != curcol)) remember(0);
+ lastrow = currow;
+ lastcol = curcol;
currow = row;
curcol = col;
g_free();
gs.g_type = G_CELL;
gs.g_row = currow;
gs.g_col = curcol;
- gs.g_lastrow = lastrow;
- gs.g_lastcol = lastcol;
+ gs.g_lastrow = lastrow_;
+ gs.g_lastcol = lastcol_;
//gs.strow = cornerrow;
//gs.stcol = cornercol;
if (cornerrow >= 0) {
- //strow = cornerrow;
- //stcol = cornercol;
- gs.stflag = 1;
+ //strow = cornerrow;
+ //stcol = cornercol;
+ gs.stflag = 1;
} else
- gs.stflag = 0;
+ gs.stflag = 0;
- for (rowsinrange = 0, i = row; i <= lastrow; i++) {
+ for (rowsinrange = 0, i = row; i <= lastrow_; i++) {
if (row_hidden[i]) {
scinfo("Cell's row is hidden");
continue;
}
rowsinrange++;
}
- for (colsinrange = 0, i = col; i <= lastcol; i++) {
+ for (colsinrange = 0, i = col; i <= lastcol_; i++) {
if (col_hidden[i]) {
colsinrange = 0;
scinfo("Cell's col is hidden");
@@ -1760,11 +1784,13 @@ void moveto(int row, int col, int lastrow, int lastcol, int cornerrow, int corne
/*
* 'goto' either a given number,'error', or 'invalid' starting at (currow,curcol)
+ * flow = 1, look forward
+ * flow = 0, look backwards
*/
-void num_search(double n, int firstrow, int firstcol, int lastrow, int lastcol, int errsearch) {
- register struct ent *p;
- register int r,c;
- int endr, endc;
+void num_search(double n, int firstrow, int firstcol, int lastrow_, int lastcol_, int errsearch, int flow) {
+ register struct ent * p;
+ register int r, c;
+ int endr, endc;
//if (!loading) remember(0);
g_free();
@@ -1772,36 +1798,49 @@ void num_search(double n, int firstrow, int firstcol, int lastrow, int lastcol,
gs.g_n = n;
gs.g_row = firstrow;
gs.g_col = firstcol;
- gs.g_lastrow = lastrow;
- gs.g_lastcol = lastcol;
+ gs.g_lastrow = lastrow_;
+ gs.g_lastcol = lastcol_;
gs.errsearch = errsearch;
- if (currow >= firstrow && currow <= lastrow &&
- curcol >= firstcol && curcol <= lastcol) {
- endr = currow;
- endc = curcol;
+ if (currow >= firstrow && currow <= lastrow_ && curcol >= firstcol && curcol <= lastcol_) {
+ endr = currow;
+ endc = curcol;
} else {
- endr = lastrow;
- endc = lastcol;
+ endr = lastrow_;
+ endc = lastcol_;
}
r = endr;
c = endc;
while (1) {
- if (c < lastcol)
- c++;
- else {
- if (r < lastrow) {
- while (++r < lastrow && row_hidden[r]) /* */;
- c = firstcol;
- } else {
- r = firstrow;
- c = firstcol;
+
+ if (flow) { // search forward
+ if (c < lastcol_)
+ c++;
+ else {
+ if (r < lastrow_) {
+ while (++r < lastrow_ && row_hidden[r]) /* */;
+ c = firstcol;
+ } else {
+ r = firstrow;
+ c = firstcol;
+ }
+ }
+ } else { // search backwards
+ if (c > firstcol)
+ c--;
+ else {
+ if (r > firstrow) {
+ while (--r > firstrow && row_hidden[r]) /* */;
+ c = lastcol_;
+ } else {
+ r = lastrow_;
+ c = lastcol_;
+ }
}
}
+
p = *ATBL(tbl, r, c);
- if (!col_hidden[c] && p && (p->flags & is_valid) &&
- (errsearch || (p->v == n)) && (!errsearch ||
- (p->cellerror == errsearch))) /* CELLERROR vs CELLINVALID */
+ if (! col_hidden[c] && p && (p->flags & is_valid) && (errsearch || (p->v == n)) && (! errsearch || (p->cellerror == errsearch))) /* CELLERROR vs CELLINVALID */
break;
if (r == endr && c == endc) {
if (errsearch) {
@@ -1813,6 +1852,8 @@ void num_search(double n, int firstrow, int firstcol, int lastrow, int lastcol,
}
}
+ lastrow = currow;
+ lastcol = curcol;
currow = r;
curcol = c;
rowsinrange = 1;
@@ -1823,9 +1864,12 @@ void num_search(double n, int firstrow, int firstcol, int lastrow, int lastcol,
} //else remember(1);
}
-/* 'goto' a cell containing a matching string */
-void str_search(char *s, int firstrow, int firstcol, int lastrow, int lastcol, int num) {
- struct ent *p;
+/* 'goto' a cell containing a matching string
+ * flow = 1, look forward
+ * flow = 0, look backwards
+ * */
+void str_search(char *s, int firstrow, int firstcol, int lastrow_, int lastcol_, int num, int flow) {
+ struct ent * p;
int r, c;
int endr, endc;
char * tmp;
@@ -1866,30 +1910,47 @@ void str_search(char *s, int firstrow, int firstcol, int lastrow, int lastcol, i
gs.g_s = s;
gs.g_row = firstrow;
gs.g_col = firstcol;
- gs.g_lastrow = lastrow;
- gs.g_lastcol = lastcol;
- if (currow >= firstrow && currow <= lastrow &&
- curcol >= firstcol && curcol <= lastcol) {
+ gs.g_lastrow = lastrow_;
+ gs.g_lastcol = lastcol_;
+ if (currow >= firstrow && currow <= lastrow_ &&
+ curcol >= firstcol && curcol <= lastcol_) {
endr = currow;
endc = curcol;
} else {
- endr = lastrow;
- endc = lastcol;
+ endr = lastrow_;
+ endc = lastcol_;
}
r = endr;
c = endc;
+
while (1) {
- if (c < lastcol) {
- c++;
- } else {
- if (r < lastrow) {
- while (++r < lastrow && row_hidden[r]) /* */;
- c = firstcol;
- } else {
- r = firstrow;
- c = firstcol;
+
+ if (flow) { // search forward
+ if (c < lastcol_)
+ c++;
+ else {
+ if (r < lastrow_) {
+ while (++r < lastrow_ && row_hidden[r]) /* */;
+ c = firstcol;
+ } else {
+ r = firstrow;
+ c = firstcol;
+ }
+ }
+ } else { // search backwards
+ if (c > firstcol)
+ c--;
+ else {
+ if (r > firstrow) {
+ while (--r > firstrow && row_hidden[r]) /* */;
+ c = lastcol_;
+ } else {
+ r = lastrow_;
+ c = lastcol_;
+ }
}
}
+
p = *ATBL(tbl, r, c);
if (gs.g_type == G_NSTR) {
*line = '\0';
@@ -1965,6 +2026,8 @@ void str_search(char *s, int firstrow, int firstcol, int lastrow, int lastcol, i
}
}
linelim = -1;
+ lastrow = currow;
+ lastcol = curcol;
currow = r;
curcol = c;
rowsinrange = 1;
diff --git a/src/interp.h b/src/interp.h
index b47a2d9..373b898 100644
--- a/src/interp.h
+++ b/src/interp.h
@@ -49,9 +49,10 @@ void yankr(struct ent *v1, struct ent *v2);
void mover(struct ent *d, struct ent *v1, struct ent *v2);
void g_free();
void go_last();
+void go_previous();
void moveto(int row, int col, int lastrow, int lastcol, int cornerrow, int cornercol);
-void num_search(double n, int firstrow, int firstcol, int lastrow, int lastcol, int errsearch);
-void str_search(char *s, int firstrow, int firstcol, int lastrow, int lastcol, int num);
+void num_search(double n, int firstrow, int firstcol, int lastrow, int lastcol, int errsearch, int flow);
+void str_search(char *s, int firstrow, int firstcol, int lastrow, int lastcol, int num, int flow);
void fill(struct ent *v1, struct ent *v2, double start, double inc);
void lock_cells(struct ent *v1, struct ent *v2);
void unlock_cells(struct ent *v1, struct ent *v2);
diff --git a/src/main.c b/src/main.c
index 1206d4c..3780e87 100644
--- a/src/main.c
+++ b/src/main.c
@@ -5,6 +5,7 @@
#include <string.h>
#include <time.h>
#include <fcntl.h> // for F_GETFL O_NONBLOCK F_SETFL
+#include <locale.h>
#include "main.h"
#include "shift.h"
@@ -30,6 +31,7 @@
#endif
int currow = 0, curcol = 0;
+int lastrow = 0, lastcol = 0;
int maxrows, maxcols;
int * fwidth;
int * precision;
@@ -86,6 +88,10 @@ struct history * commandline_history;
*********************************************************************/
int main (int argc, char ** argv) {
+#ifdef USELOCALE
+ setlocale(LC_ALL, "");
+#endif
+
// set up signals so we can catch them
signals();
@@ -95,7 +101,7 @@ int main (int argc, char ** argv) {
store_default_config_values();
// create command line history structure
-#if defined HISTORY_FILE
+#ifdef HISTORY_FILE
if (! atoi(get_conf_value("nocurses"))) {
commandline_history = (struct history *) create_history(':');
load_history(commandline_history);
@@ -146,6 +152,7 @@ int main (int argc, char ** argv) {
}
}
+
// load sc file
load_sc();
@@ -176,7 +183,8 @@ int main (int argc, char ** argv) {
start_screen(); // Already done above
// we show welcome screen if no spreadsheet was passed to SC-IM
- if ( ! c