* A mark is an ifile (input file) plus a position within the file.
* Each mark is identified by a lowercase or uppercase letter.
#define NMARKS (2*26) /* a-z, A-Z */
static struct mark marks
[NMARKS
];
* Special mark for the "last mark"; addressed by the apostrophe.
static struct mark lmark
;
* Initialize the mark table to show no marks are set.
for (i
= 0; i
< NMARKS
; i
++)
marks
[i
].m_scrpos
.pos
= NULL_POSITION
;
lmark
.m_scrpos
.pos
= NULL_POSITION
;
* See if a mark letter is valid (between a and z).
if (c
>= 'a' && c
<= 'z')
if (c
>= 'A' && c
<= 'Z')
return (&marks
[c
-'A'+26]);
error("Invalid mark letter", NULL_PARG
);
* Get the mark structure identified by a character.
* The mark struct may come either from the mark table
* or may be constructed on the fly for certain characters like ^, $.
* Beginning of the current file.
m
->m_scrpos
.pos
= ch_zero();
* End of the current file.
error("Cannot seek to end of file", NULL_PARG
);
m
->m_scrpos
.pos
= ch_tell();
m
->m_scrpos
.ln
= sc_height
-1;
* Current position in the current file.
m
->m_scrpos
.pos
= ch_tell();
* Must be a user-defined mark.
if (m
->m_scrpos
.pos
== NULL_POSITION
)
error("Mark not set", NULL_PARG
);
* Is a mark letter is invalid?
return (getmark(c
) == NULL
);
* Set a user-defined mark.
* Set lmark (the mark named by the apostrophe).
if (scrpos
.pos
== NULL_POSITION
)
lmark
.m_ifile
= curr_ifile
;
* If we're trying to go to the lastmark and
* it has not been set to anything yet,
* set it to the beginning of the current file.
if (m
== &lmark
&& m
->m_scrpos
.pos
== NULL_POSITION
)
m
->m_scrpos
.pos
= ch_zero();
m
->m_scrpos
.ln
= jump_sline
;
* If we're using lmark, we must save the screen position now,
* because if we call edit() below, lmark will change.
* (We save the screen position even if we're not using lmark.)
if (m
->m_ifile
!= curr_ifile
)
* Not in the current file; edit the correct file.
if (edit(get_filename(m
->m_ifile
), 0))
jump_loc(scrpos
.pos
, scrpos
.ln
);
* Return the position associated with a given mark letter.
* We don't return which screen line the position
* is associated with, but this doesn't matter much,
* because it's always the first non-blank line on the screen.
if (m
->m_ifile
!= curr_ifile
)
error("Mark not in current file", NULL_PARG
);
return (m
->m_scrpos
.pos
);