Commit 60db45be 60db45be4fab2c7a4559605e5d1f483c5058bd05 by Sergey Poznyakoff

Rename mu_locus_tracker to mu_linetrack

1 parent 3a441d83
......@@ -17,13 +17,14 @@ struct mu_locus_range
struct mu_locus_point end;
};
typedef struct mu_locus_track *mu_locus_track_t;
typedef struct mu_linetrack *mu_linetrack_t;
struct mu_locus_track_stat
struct mu_linetrack_stat
{
unsigned start_line;
size_t n_lines;
size_t n_chars;
unsigned start_line; /* Start line number (1-based) */
size_t n_lines; /* Number of lines, including the recent (incomplete)
one */
size_t n_chars; /* Total number of characters */
};
int mu_ident_ref (char const *name, char const **refname);
......@@ -47,17 +48,15 @@ mu_locus_point_same_line (struct mu_locus_point const *a,
void mu_lrange_debug (struct mu_locus_range const *loc,
char const *fmt, ...);
int mu_locus_track_create (mu_locus_track_t *ret,
int mu_linetrack_create (mu_linetrack_t *ret,
char const *file_name, size_t max_lines);
void mu_locus_track_free (mu_locus_track_t trk);
void mu_locus_track_destroy (mu_locus_track_t *trk);
size_t mu_locus_track_level (mu_locus_track_t trk);
void mu_locus_tracker_advance (struct mu_locus_track *trk,
struct mu_locus_range *loc,
char const *text, size_t leng);
int mu_locus_tracker_retreat (struct mu_locus_track *trk, size_t n);
int mu_locus_tracker_stat (struct mu_locus_track *trk,
struct mu_locus_track_stat *st);
void mu_linetrack_free (mu_linetrack_t trk);
void mu_linetrack_destroy (mu_linetrack_t *trk);
void mu_linetrack_advance (mu_linetrack_t trk,
struct mu_locus_range *loc,
char const *text, size_t leng);
int mu_linetrack_retreat (mu_linetrack_t trk, size_t n);
int mu_linetrack_stat (mu_linetrack_t trk, struct mu_linetrack_stat *st);
void mu_stream_print_locus_range (mu_stream_t stream,
......
......@@ -20,7 +20,7 @@ noinst_LTLIBRARIES = liblocus.la
liblocus_la_SOURCES = \
ident.c\
debug.c\
tracker.c
linetrack.c
AM_CPPFLAGS = @MU_LIB_COMMON_INCLUDES@ -I/libmailutils
......
......@@ -4,22 +4,36 @@
#include <mailutils/locus.h>
#include <mailutils/error.h>
struct mu_locus_track
/* The line-tracker structure keeps track of the last N lines read from a
text input file. For each line read it keeps the number of characters
in that line including the newline. This information is stored in a
syclic stack of N elements. Top of stack always represents the current
line. For the purpose of line tracker, current line is the line that is
being visited, such that its final newline character has not yet been
seen. Once the newline is seen, the line is pushed on stack, and a new
current line is assumed.
The value of N must not be less than 2.
*/
struct mu_linetrack
{
char const *file_name; /* Name of the source file */
size_t max_lines; /* Max. number of lines history kept by tracker */
size_t head; /* Bottom of stack */
size_t level; /* Number of elements on stack */
unsigned hline; /* Number of line corresponding to cols[head] */
unsigned *cols; /* Cyclic stack */
char const *file_name; /* Name of the source file */
size_t max_lines; /* Max. number of lines history kept by tracker (N) */
size_t head; /* Index of the eldest element on stack */
size_t tos; /* Index of the most recent element on stack
(< max_lines) */
unsigned hline; /* Number of line corresponding to cols[head] */
unsigned *cols; /* Cyclic stack or character counts.
Number of characters in line (hline + n) is
cols[head + n] (0 <= n <= tos). */
};
int
mu_locus_track_create (mu_locus_track_t *ret,
mu_linetrack_create (mu_linetrack_t *ret,
char const *file_name, size_t max_lines)
{
int rc;
struct mu_locus_track *trk;
struct mu_linetrack *trk;
trk = malloc (sizeof *trk);
if (!trk)
......@@ -43,7 +57,7 @@ mu_locus_track_create (mu_locus_track_t *ret,
max_lines = 2;
trk->max_lines = max_lines;
trk->head = 0;
trk->level = 0;
trk->tos = 0;
trk->hline = 1;
trk->cols[0] = 0;
......@@ -52,7 +66,7 @@ mu_locus_track_create (mu_locus_track_t *ret,
}
void
mu_locus_track_free (mu_locus_track_t trk)
mu_linetrack_free (mu_linetrack_t trk)
{
if (trk)
{
......@@ -63,54 +77,48 @@ mu_locus_track_free (mu_locus_track_t trk)
}
void
mu_locus_track_destroy (mu_locus_track_t *trk)
mu_linetrack_destroy (mu_linetrack_t *trk)
{
if (trk)
{
mu_locus_track_free (*trk);
mu_linetrack_free (*trk);
*trk = NULL;
}
}
size_t
mu_locus_track_level (mu_locus_track_t trk)
{
return trk->level;
}
static inline unsigned *
cols_tos_ptr (mu_locus_track_t trk)
cols_tos_ptr (mu_linetrack_t trk)
{
return &trk->cols[(trk->head + trk->level) % trk->max_lines];
return &trk->cols[(trk->head + trk->tos) % trk->max_lines];
}
static inline unsigned
cols_peek (mu_locus_track_t trk, size_t n)
cols_peek (mu_linetrack_t trk, size_t n)
{
return trk->cols[(trk->head + n) % trk->max_lines];
}
static inline unsigned *
push (mu_locus_track_t trk)
push (mu_linetrack_t trk)
{
unsigned *ptr;
if (trk->level == trk->max_lines)
if (trk->tos == trk->max_lines - 1)
{
trk->head++;
trk->hline++;
}
else
trk->level++;
trk->tos++;
*(ptr = cols_tos_ptr (trk)) = 0;
return ptr;
}
static inline unsigned *
pop (mu_locus_track_t trk)
pop (mu_linetrack_t trk)
{
if (trk->level == 0)
if (trk->tos == 0)
return NULL;
trk->level--;
trk->tos--;
return cols_tos_ptr (trk);
}
......@@ -119,12 +127,11 @@ pop (mu_locus_track_t trk)
#endif
int
mu_locus_tracker_stat (struct mu_locus_track *trk,
struct mu_locus_track_stat *st)
mu_linetrack_stat (struct mu_linetrack *trk, struct mu_linetrack_stat *st)
{
size_t i, nch = 0;
for (i = 0; i <= trk->level; i++)
for (i = 0; i <= trk->tos; i++)
{
unsigned n = cols_peek (trk, i);
if (SIZE_MAX - nch < n)
......@@ -133,14 +140,16 @@ mu_locus_tracker_stat (struct mu_locus_track *trk,
}
st->start_line = trk->hline;
st->n_lines = trk->level;
st->n_lines = trk->tos + 1;
st->n_chars = nch;
return 0;
}
void
mu_locus_tracker_advance (struct mu_locus_track *trk,
struct mu_locus_range *loc,
char const *text, size_t leng)
mu_linetrack_advance (struct mu_linetrack *trk,
struct mu_locus_range *loc,
char const *text, size_t leng)
{
unsigned *ptr;
......@@ -148,7 +157,7 @@ mu_locus_tracker_advance (struct mu_locus_track *trk,
return;
loc->beg.mu_file = loc->end.mu_file = trk->file_name;
loc->beg.mu_line = trk->hline + trk->level;
loc->beg.mu_line = trk->hline + trk->tos;
ptr = cols_tos_ptr (trk);
loc->beg.mu_col = *ptr + 1;
while (leng--)
......@@ -160,14 +169,14 @@ mu_locus_tracker_advance (struct mu_locus_track *trk,
}
if (*ptr)
{
loc->end.mu_line = trk->hline + trk->level;
loc->end.mu_line = trk->hline + trk->tos;
loc->end.mu_col = *ptr;
}
else
{
/* Text ends with a newline. Keep the previos line number. */
loc->end.mu_line = trk->hline + trk->level - 1;
loc->end.mu_col = cols_peek (trk, trk->level - 1) - 1;
loc->end.mu_line = trk->hline + trk->tos - 1;
loc->end.mu_col = cols_peek (trk, trk->tos - 1) - 1;
if (loc->end.mu_col + 1 == loc->beg.mu_col)
{
/* This happens if the previous line contained only newline. */
......@@ -177,11 +186,11 @@ mu_locus_tracker_advance (struct mu_locus_track *trk,
}
int
mu_locus_tracker_retreat (struct mu_locus_track *trk, size_t n)
mu_linetrack_retreat (struct mu_linetrack *trk, size_t n)
{
struct mu_locus_track_stat st;
struct mu_linetrack_stat st;
mu_locus_tracker_stat (trk, &st);
mu_linetrack_stat (trk, &st);
if (n > st.n_chars)
return ERANGE;
else
......
......@@ -19,7 +19,7 @@ fsfolder
globtest
imapio
listop
loctrack
linetrack
logstr
mailcap
mimehdr
......
......@@ -54,7 +54,7 @@ noinst_PROGRAMS = \
globtest\
imapio\
listop\
loctrack\
linetrack\
logstr\
mailcap\
mimehdr\
......@@ -107,7 +107,7 @@ TESTSUITE_AT = \
inline-comment.at\
linecon.at\
list.at\
loctrack.at\
linetrack.at\
logstr.at\
mailcap.at\
mimehdr.at\
......
......@@ -14,12 +14,12 @@
# You should have received a copy of the GNU General Public License
# along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>.
AT_BANNER([Locus tracker])
AT_BANNER([Line tracker])
m4_pushdef([TRACKTEST],[
AT_SETUP([$1])
AT_KEYWORDS([tracker $2])
AT_CHECK([loctrack liber $3 <<EOT
AT_CHECK([linetrack liber $3 <<EOT
$4[]EOT
],
[0],
......@@ -103,7 +103,7 @@ three
liber:2.1-3: two\n
liber:3.1-5: three
],
[loctrack: retreat count too big
[linetrack: retreat count too big
])
m4_popdef([TRACKTEST])
\ No newline at end of file
m4_popdef([TRACKTEST])
......
......@@ -6,7 +6,7 @@ main (int argc, char **argv)
{
unsigned long max_lines;
char *end;
mu_locus_track_t trk;
mu_linetrack_t trk;
int rc;
char *buf = NULL;
size_t size, n;
......@@ -26,7 +26,7 @@ main (int argc, char **argv)
return 1;
}
MU_ASSERT (mu_locus_track_create (&trk, argv[1], max_lines));
MU_ASSERT (mu_linetrack_create (&trk, argv[1], max_lines));
while ((rc = mu_stream_getline (mu_strin, &buf, &size, &n)) == 0 && n > 0)
{
struct mu_locus_range lr;
......@@ -43,17 +43,17 @@ main (int argc, char **argv)
mu_error ("bad number");
continue;
}
rc = mu_locus_tracker_retreat (trk, x);
rc = mu_linetrack_retreat (trk, x);
if (rc == ERANGE)
mu_error ("retreat count too big");
else if (rc)
mu_diag_funcall (MU_DIAG_ERROR, "mu_locus_tracker_retreat", buf+2,
mu_diag_funcall (MU_DIAG_ERROR, "mu_linetrack_retreat", buf+2,
rc);
}
else
{
mu_c_str_unescape (buf, "\\\n", "\\n", &tok);
mu_locus_tracker_advance (trk, &lr, tok, strlen (tok));
mu_linetrack_advance (trk, &lr, tok, strlen (tok));
free (tok);
mu_stream_lprintf (mu_strout, &lr, "%s\n", buf);
}
......
......@@ -212,4 +212,4 @@ m4_include([msgset.at])
m4_include([globtest.at])
m4_include([loctrack.at])
m4_include([linetrack.at])
......