1999-08-26 09:30:50 +00:00
|
|
|
|
/* where.c -- Implementation File (module.c template V1.0)
|
|
|
|
|
Copyright (C) 1995 Free Software Foundation, Inc.
|
1999-10-16 06:09:09 +00:00
|
|
|
|
Contributed by James Craig Burley.
|
1999-08-26 09:30:50 +00:00
|
|
|
|
|
|
|
|
|
This file is part of GNU Fortran.
|
|
|
|
|
|
|
|
|
|
GNU Fortran is free software; you can redistribute it and/or modify
|
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
|
the Free Software Foundation; either version 2, or (at your option)
|
|
|
|
|
any later version.
|
|
|
|
|
|
|
|
|
|
GNU Fortran is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
|
along with GNU Fortran; see the file COPYING. If not, write to
|
|
|
|
|
the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|
|
|
|
02111-1307, USA.
|
|
|
|
|
|
|
|
|
|
Related Modules:
|
|
|
|
|
|
|
|
|
|
Description:
|
|
|
|
|
Simple data abstraction for Fortran source lines (called card images).
|
|
|
|
|
|
|
|
|
|
Modifications:
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* Include files. */
|
|
|
|
|
|
|
|
|
|
#include "proj.h"
|
|
|
|
|
#include "where.h"
|
|
|
|
|
#include "lex.h"
|
|
|
|
|
#include "malloc.h"
|
|
|
|
|
|
|
|
|
|
/* Externals defined here. */
|
|
|
|
|
|
|
|
|
|
struct _ffewhere_line_ ffewhere_unknown_line_
|
|
|
|
|
=
|
1999-10-16 06:09:09 +00:00
|
|
|
|
{NULL, NULL, 0, 0, 0, {0}};
|
1999-08-26 09:30:50 +00:00
|
|
|
|
|
|
|
|
|
/* Simple definitions and enumerations. */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Internal typedefs. */
|
|
|
|
|
|
|
|
|
|
typedef struct _ffewhere_ll_ *ffewhereLL_;
|
|
|
|
|
|
|
|
|
|
/* Private include files. */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Internal structure definitions. */
|
|
|
|
|
|
|
|
|
|
struct _ffewhere_ll_
|
|
|
|
|
{
|
|
|
|
|
ffewhereLL_ next;
|
|
|
|
|
ffewhereLL_ previous;
|
|
|
|
|
ffewhereFile wf;
|
|
|
|
|
ffewhereLineNumber line_no; /* ffelex_line_number() at time of creation. */
|
|
|
|
|
ffewhereLineNumber offset; /* User-desired offset (usually 1). */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct _ffewhere_root_ll_
|
|
|
|
|
{
|
|
|
|
|
ffewhereLL_ first;
|
|
|
|
|
ffewhereLL_ last;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct _ffewhere_root_line_
|
|
|
|
|
{
|
|
|
|
|
ffewhereLine first;
|
|
|
|
|
ffewhereLine last;
|
|
|
|
|
ffewhereLineNumber none;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* Static objects accessed by functions in this module. */
|
|
|
|
|
|
|
|
|
|
static struct _ffewhere_root_ll_ ffewhere_root_ll_;
|
|
|
|
|
static struct _ffewhere_root_line_ ffewhere_root_line_;
|
|
|
|
|
|
|
|
|
|
/* Static functions (internal). */
|
|
|
|
|
|
|
|
|
|
static ffewhereLL_ ffewhere_ll_lookup_ (ffewhereLineNumber ln);
|
|
|
|
|
|
|
|
|
|
/* Internal macros. */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Look up line-to-line object from absolute line num. */
|
|
|
|
|
|
|
|
|
|
static ffewhereLL_
|
|
|
|
|
ffewhere_ll_lookup_ (ffewhereLineNumber ln)
|
|
|
|
|
{
|
|
|
|
|
ffewhereLL_ ll;
|
|
|
|
|
|
|
|
|
|
if (ln == 0)
|
|
|
|
|
return ffewhere_root_ll_.first;
|
|
|
|
|
|
|
|
|
|
for (ll = ffewhere_root_ll_.last;
|
|
|
|
|
ll != (ffewhereLL_) &ffewhere_root_ll_.first;
|
|
|
|
|
ll = ll->previous)
|
|
|
|
|
{
|
|
|
|
|
if (ll->line_no <= ln)
|
|
|
|
|
return ll;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assert ("no line num" == NULL);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Kill file object.
|
|
|
|
|
|
|
|
|
|
Note that this object must not have been passed in a call
|
|
|
|
|
to any other ffewhere function except ffewhere_file_name and
|
|
|
|
|
ffewhere_file_namelen. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ffewhere_file_kill (ffewhereFile wf)
|
|
|
|
|
{
|
|
|
|
|
malloc_kill_ks (ffe_pool_file (), wf,
|
|
|
|
|
offsetof (struct _ffewhere_file_, text)
|
|
|
|
|
+ wf->length + 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Create file object. */
|
|
|
|
|
|
|
|
|
|
ffewhereFile
|
|
|
|
|
ffewhere_file_new (char *name, size_t length)
|
|
|
|
|
{
|
|
|
|
|
ffewhereFile wf;
|
|
|
|
|
|
|
|
|
|
wf = malloc_new_ks (ffe_pool_file (), "ffewhereFile",
|
|
|
|
|
offsetof (struct _ffewhere_file_, text)
|
|
|
|
|
+ length + 1);
|
|
|
|
|
wf->length = length;
|
|
|
|
|
memcpy (&wf->text[0], name, length);
|
|
|
|
|
wf->text[length] = '\0';
|
|
|
|
|
|
|
|
|
|
return wf;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Set file and first line number.
|
|
|
|
|
|
|
|
|
|
Pass FALSE if no line number is specified. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ffewhere_file_set (ffewhereFile wf, bool have_num, ffewhereLineNumber ln)
|
|
|
|
|
{
|
|
|
|
|
ffewhereLL_ ll;
|
|
|
|
|
|
|
|
|
|
ll = malloc_new_kp (ffe_pool_file (), "ffewhereLL_", sizeof (*ll));
|
|
|
|
|
ll->next = (ffewhereLL_) &ffewhere_root_ll_.first;
|
|
|
|
|
ll->previous = ffewhere_root_ll_.last;
|
|
|
|
|
ll->next->previous = ll;
|
|
|
|
|
ll->previous->next = ll;
|
|
|
|
|
if (wf == NULL)
|
|
|
|
|
{
|
|
|
|
|
if (ll->previous == ll->next)
|
|
|
|
|
ll->wf = NULL;
|
|
|
|
|
else
|
|
|
|
|
ll->wf = ll->previous->wf;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
ll->wf = wf;
|
|
|
|
|
ll->line_no = ffelex_line_number ();
|
|
|
|
|
if (have_num)
|
|
|
|
|
ll->offset = ln;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (ll->previous == ll->next)
|
|
|
|
|
ll->offset = 1;
|
|
|
|
|
else
|
|
|
|
|
ll->offset
|
|
|
|
|
= ll->line_no - ll->previous->line_no + ll->previous->offset;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Do initializations. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ffewhere_init_1 ()
|
|
|
|
|
{
|
|
|
|
|
ffewhere_root_line_.first = ffewhere_root_line_.last
|
|
|
|
|
= (ffewhereLine) &ffewhere_root_line_.first;
|
|
|
|
|
ffewhere_root_line_.none = 0;
|
|
|
|
|
|
|
|
|
|
ffewhere_root_ll_.first = ffewhere_root_ll_.last
|
|
|
|
|
= (ffewhereLL_) &ffewhere_root_ll_.first;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return the textual content of the line. */
|
|
|
|
|
|
|
|
|
|
char *
|
|
|
|
|
ffewhere_line_content (ffewhereLine wl)
|
|
|
|
|
{
|
|
|
|
|
assert (wl != NULL);
|
|
|
|
|
return wl->content;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Look up file object from line object. */
|
|
|
|
|
|
|
|
|
|
ffewhereFile
|
|
|
|
|
ffewhere_line_file (ffewhereLine wl)
|
|
|
|
|
{
|
|
|
|
|
ffewhereLL_ ll;
|
|
|
|
|
|
|
|
|
|
assert (wl != NULL);
|
|
|
|
|
ll = ffewhere_ll_lookup_ (wl->line_num);
|
|
|
|
|
return ll->wf;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Lookup file object from line object, calc line#. */
|
|
|
|
|
|
|
|
|
|
ffewhereLineNumber
|
|
|
|
|
ffewhere_line_filelinenum (ffewhereLine wl)
|
|
|
|
|
{
|
|
|
|
|
ffewhereLL_ ll;
|
|
|
|
|
|
|
|
|
|
assert (wl != NULL);
|
|
|
|
|
ll = ffewhere_ll_lookup_ (wl->line_num);
|
|
|
|
|
return wl->line_num + ll->offset - ll->line_no;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Decrement use count for line, deallocate if no uses left. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ffewhere_line_kill (ffewhereLine wl)
|
|
|
|
|
{
|
|
|
|
|
#if 0
|
|
|
|
|
if (!ffewhere_line_is_unknown (wl))
|
|
|
|
|
fprintf (dmpout, "; ffewhere_line_kill %" ffewhereLineNumber_f "u, uses=%"
|
|
|
|
|
ffewhereUses_f_ "u\n",
|
|
|
|
|
wl->line_num, wl->uses);
|
|
|
|
|
#endif
|
|
|
|
|
assert (ffewhere_line_is_unknown (wl) || (wl->uses != 0));
|
|
|
|
|
if (!ffewhere_line_is_unknown (wl) && (--wl->uses == 0))
|
|
|
|
|
{
|
|
|
|
|
wl->previous->next = wl->next;
|
|
|
|
|
wl->next->previous = wl->previous;
|
|
|
|
|
malloc_kill_ks (ffe_pool_file (), wl,
|
|
|
|
|
offsetof (struct _ffewhere_line_, content)
|
|
|
|
|
+ wl->length + 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Make a new line or increment use count of existing one.
|
|
|
|
|
|
|
|
|
|
Find out where line object is, if anywhere. If in lexer, it might also
|
|
|
|
|
be at the end of the list of lines, else put it on the end of the list.
|
|
|
|
|
Then, if in the list of lines, increment the use count and return the
|
|
|
|
|
line object. Else, make an empty line object (no line) and return
|
|
|
|
|
that. */
|
|
|
|
|
|
|
|
|
|
ffewhereLine
|
|
|
|
|
ffewhere_line_new (ffewhereLineNumber ln)
|
|
|
|
|
{
|
|
|
|
|
ffewhereLine wl = ffewhere_root_line_.last;
|
|
|
|
|
|
|
|
|
|
/* If this is the lexer's current line, see if it is already at the end of
|
|
|
|
|
the list, and if not, make it and return it. */
|
|
|
|
|
|
|
|
|
|
if (((ln == 0) /* Presumably asking for EOF pointer. */
|
|
|
|
|
|| (wl->line_num != ln))
|
|
|
|
|
&& (ffelex_line_number () == ln))
|
|
|
|
|
{
|
|
|
|
|
#if 0
|
|
|
|
|
fprintf (dmpout,
|
|
|
|
|
"; ffewhere_line_new %" ffewhereLineNumber_f "u, lexer\n",
|
|
|
|
|
ln);
|
|
|
|
|
#endif
|
|
|
|
|
wl = malloc_new_ks (ffe_pool_file (), "FFEWHERE line",
|
|
|
|
|
offsetof (struct _ffewhere_line_, content)
|
|
|
|
|
+ (size_t) ffelex_line_length () + 1);
|
|
|
|
|
wl->next = (ffewhereLine) &ffewhere_root_line_;
|
|
|
|
|
wl->previous = ffewhere_root_line_.last;
|
|
|
|
|
wl->previous->next = wl;
|
|
|
|
|
wl->next->previous = wl;
|
|
|
|
|
wl->line_num = ln;
|
|
|
|
|
wl->uses = 1;
|
|
|
|
|
wl->length = ffelex_line_length ();
|
|
|
|
|
strcpy (wl->content, ffelex_line ());
|
|
|
|
|
return wl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* See if line is on list already. */
|
|
|
|
|
|
|
|
|
|
while (wl->line_num > ln)
|
|
|
|
|
wl = wl->previous;
|
|
|
|
|
|
|
|
|
|
/* If line is there, increment its use count and return. */
|
|
|
|
|
|
|
|
|
|
if (wl->line_num == ln)
|
|
|
|
|
{
|
|
|
|
|
#if 0
|
|
|
|
|
fprintf (dmpout, "; ffewhere_line_new %" ffewhereLineNumber_f "u, uses=%"
|
|
|
|
|
ffewhereUses_f_ "u\n", ln,
|
|
|
|
|
wl->uses);
|
|
|
|
|
#endif
|
|
|
|
|
wl->uses++;
|
|
|
|
|
return wl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Else, make a new one with a blank line (since we've obviously lost it,
|
|
|
|
|
which should never happen) and return it. */
|
|
|
|
|
|
|
|
|
|
fprintf (stderr,
|
|
|
|
|
"(Cannot resurrect line %lu for error reporting purposes.)\n",
|
|
|
|
|
ln);
|
|
|
|
|
|
|
|
|
|
wl = malloc_new_ks (ffe_pool_file (), "FFEWHERE line",
|
|
|
|
|
offsetof (struct _ffewhere_line_, content)
|
|
|
|
|
+ 1);
|
|
|
|
|
wl->next = (ffewhereLine) &ffewhere_root_line_;
|
|
|
|
|
wl->previous = ffewhere_root_line_.last;
|
|
|
|
|
wl->previous->next = wl;
|
|
|
|
|
wl->next->previous = wl;
|
|
|
|
|
wl->line_num = ln;
|
|
|
|
|
wl->uses = 1;
|
|
|
|
|
wl->length = 0;
|
|
|
|
|
*(wl->content) = '\0';
|
|
|
|
|
return wl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Increment use count of line, as in a copy. */
|
|
|
|
|
|
|
|
|
|
ffewhereLine
|
|
|
|
|
ffewhere_line_use (ffewhereLine wl)
|
|
|
|
|
{
|
|
|
|
|
#if 0
|
|
|
|
|
fprintf (dmpout, "; ffewhere_line_use %" ffewhereLineNumber_f "u, uses=%" ffewhereUses_f_
|
|
|
|
|
"u\n", wl->line_num, wl->uses);
|
|
|
|
|
#endif
|
|
|
|
|
assert (ffewhere_line_is_unknown (wl) || (wl->uses != 0));
|
|
|
|
|
if (!ffewhere_line_is_unknown (wl))
|
|
|
|
|
++wl->uses;
|
|
|
|
|
return wl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Set an ffewhere object based on a track index.
|
|
|
|
|
|
|
|
|
|
Determines the absolute line and column number of a character at a given
|
|
|
|
|
index into an ffewhereTrack array. wr* is the reference position, wt is
|
|
|
|
|
the tracking information, and i is the index desired. wo* is set to wr*
|
|
|
|
|
plus the continual offsets described by wt[0...i-1], or unknown if any of
|
|
|
|
|
the continual offsets are not known. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ffewhere_set_from_track (ffewhereLine *wol, ffewhereColumn *woc,
|
|
|
|
|
ffewhereLine wrl, ffewhereColumn wrc,
|
|
|
|
|
ffewhereTrack wt, ffewhereIndex i)
|
|
|
|
|
{
|
|
|
|
|
ffewhereLineNumber ln;
|
|
|
|
|
ffewhereColumnNumber cn;
|
|
|
|
|
ffewhereIndex j;
|
|
|
|
|
ffewhereIndex k;
|
|
|
|
|
|
|
|
|
|
if ((i == 0) || (i >= FFEWHERE_indexMAX))
|
|
|
|
|
{
|
|
|
|
|
*wol = ffewhere_line_use (wrl);
|
|
|
|
|
*woc = ffewhere_column_use (wrc);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ln = ffewhere_line_number (wrl);
|
|
|
|
|
cn = ffewhere_column_number (wrc);
|
|
|
|
|
for (j = 0, k = 0; j < i; ++j, k += 2)
|
|
|
|
|
{
|
|
|
|
|
if ((wt[k] == FFEWHERE_indexUNKNOWN)
|
|
|
|
|
|| (wt[k + 1] == FFEWHERE_indexUNKNOWN))
|
|
|
|
|
{
|
|
|
|
|
*wol = ffewhere_line_unknown ();
|
|
|
|
|
*woc = ffewhere_column_unknown ();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (wt[k] == 0)
|
|
|
|
|
cn += wt[k + 1] + 1;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ln += wt[k];
|
|
|
|
|
cn = wt[k + 1] + 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (ln == ffewhere_line_number (wrl))
|
|
|
|
|
{ /* Already have the line object, just use it
|
|
|
|
|
directly. */
|
|
|
|
|
*wol = ffewhere_line_use (wrl);
|
|
|
|
|
}
|
|
|
|
|
else /* Must search for the line object. */
|
|
|
|
|
*wol = ffewhere_line_new (ln);
|
|
|
|
|
*woc = ffewhere_column_new (cn);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Build next tracking index.
|
|
|
|
|
|
|
|
|
|
Set wt[i-1] continual offset so that it offsets from w* to (ln,cn). Update
|
|
|
|
|
w* to contain (ln,cn). DO NOT call this routine if i >= FFEWHERE_indexMAX
|
|
|
|
|
or i == 0. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ffewhere_track (ffewhereLine *wl, ffewhereColumn *wc, ffewhereTrack wt,
|
|
|
|
|
ffewhereIndex i, ffewhereLineNumber ln,
|
|
|
|
|
ffewhereColumnNumber cn)
|
|
|
|
|
{
|
|
|
|
|
unsigned int lo;
|
|
|
|
|
unsigned int co;
|
|
|
|
|
|
|
|
|
|
if ((ffewhere_line_is_unknown (*wl))
|
|
|
|
|
|| (ffewhere_column_is_unknown (*wc))
|
|
|
|
|
|| ((lo = ln - ffewhere_line_number (*wl)) >= FFEWHERE_indexUNKNOWN))
|
|
|
|
|
{
|
|
|
|
|
wt[i * 2 - 2] = wt[i * 2 - 1] = FFEWHERE_indexUNKNOWN;
|
|
|
|
|
ffewhere_line_kill (*wl);
|
|
|
|
|
ffewhere_column_kill (*wc);
|
|
|
|
|
*wl = FFEWHERE_lineUNKNOWN;
|
|
|
|
|
*wc = FFEWHERE_columnUNKNOWN;
|
|
|
|
|
}
|
|
|
|
|
else if (lo == 0)
|
|
|
|
|
{
|
|
|
|
|
wt[i * 2 - 2] = 0;
|
|
|
|
|
if ((co = cn - ffewhere_column_number (*wc)) > FFEWHERE_indexUNKNOWN)
|
|
|
|
|
{
|
|
|
|
|
wt[i * 2 - 1] = FFEWHERE_indexUNKNOWN;
|
|
|
|
|
ffewhere_line_kill (*wl);
|
|
|
|
|
ffewhere_column_kill (*wc);
|
|
|
|
|
*wl = FFEWHERE_lineUNKNOWN;
|
|
|
|
|
*wc = FFEWHERE_columnUNKNOWN;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
wt[i * 2 - 1] = co - 1;
|
|
|
|
|
ffewhere_column_kill (*wc);
|
|
|
|
|
*wc = ffewhere_column_use (ffewhere_column_new (cn));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
wt[i * 2 - 2] = lo;
|
|
|
|
|
if (cn > FFEWHERE_indexUNKNOWN)
|
|
|
|
|
{
|
|
|
|
|
wt[i * 2 - 1] = FFEWHERE_indexUNKNOWN;
|
|
|
|
|
ffewhere_line_kill (*wl);
|
|
|
|
|
ffewhere_column_kill (*wc);
|
|
|
|
|
*wl = ffewhere_line_unknown ();
|
|
|
|
|
*wc = ffewhere_column_unknown ();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
wt[i * 2 - 1] = cn - 1;
|
|
|
|
|
ffewhere_line_kill (*wl);
|
|
|
|
|
ffewhere_column_kill (*wc);
|
|
|
|
|
*wl = ffewhere_line_use (ffewhere_line_new (ln));
|
|
|
|
|
*wc = ffewhere_column_use (ffewhere_column_new (cn));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Clear tracking index for internally created track.
|
|
|
|
|
|
|
|
|
|
Set the tracking information to indicate that the tracking is at its
|
|
|
|
|
simplest (no spaces or newlines within the tracking). This means set
|
|
|
|
|
everything to zero in the current implementation. Length is the total
|
|
|
|
|
length of the token; length must be 2 or greater, since length-1 tracking
|
|
|
|
|
characters are set. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ffewhere_track_clear (ffewhereTrack wt, ffewhereIndex length)
|
|
|
|
|
{
|
|
|
|
|
ffewhereIndex i;
|
|
|
|
|
|
|
|
|
|
if (length > FFEWHERE_indexMAX)
|
|
|
|
|
length = FFEWHERE_indexMAX;
|
|
|
|
|
|
|
|
|
|
for (i = 1; i < length; ++i)
|
|
|
|
|
wt[i * 2 - 2] = wt[i * 2 - 1] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Copy tracking index from one place to another.
|
|
|
|
|
|
|
|
|
|
Copy tracking information from swt[start] to dwt[0] and so on, presumably
|
|
|
|
|
after an ffewhere_set_from_track call. Length is the total
|
|
|
|
|
length of the token; length must be 2 or greater, since length-1 tracking
|
|
|
|
|
characters are set. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ffewhere_track_copy (ffewhereTrack dwt, ffewhereTrack swt, ffewhereIndex start,
|
|
|
|
|
ffewhereIndex length)
|
|
|
|
|
{
|
|
|
|
|
ffewhereIndex i;
|
|
|
|
|
ffewhereIndex copy;
|
|
|
|
|
|
|
|
|
|
if (length > FFEWHERE_indexMAX)
|
|
|
|
|
length = FFEWHERE_indexMAX;
|
|
|
|
|
|
|
|
|
|
if (length + start > FFEWHERE_indexMAX)
|
|
|
|
|
copy = FFEWHERE_indexMAX - start;
|
|
|
|
|
else
|
|
|
|
|
copy = length;
|
|
|
|
|
|
|
|
|
|
for (i = 1; i < copy; ++i)
|
|
|
|
|
{
|
|
|
|
|
dwt[i * 2 - 2] = swt[(i + start) * 2 - 2];
|
|
|
|
|
dwt[i * 2 - 1] = swt[(i + start) * 2 - 1];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (; i < length; ++i)
|
|
|
|
|
{
|
|
|
|
|
dwt[i * 2 - 2] = 0;
|
|
|
|
|
dwt[i * 2 - 1] = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Kill tracking data.
|
|
|
|
|
|
|
|
|
|
Kill all the tracking information by killing incremented lines from the
|
|
|
|
|
first line number. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ffewhere_track_kill (ffewhereLine wrl, ffewhereColumn wrc UNUSED,
|
|
|
|
|
ffewhereTrack wt, ffewhereIndex length)
|
|
|
|
|
{
|
|
|
|
|
ffewhereLineNumber ln;
|
|
|
|
|
unsigned int lo;
|
|
|
|
|
ffewhereIndex i;
|
|
|
|
|
|
|
|
|
|
ln = ffewhere_line_number (wrl);
|
|
|
|
|
|
|
|
|
|
if (length > FFEWHERE_indexMAX)
|
|
|
|
|
length = FFEWHERE_indexMAX;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < length - 1; ++i)
|
|
|
|
|
{
|
|
|
|
|
if ((lo = wt[i * 2]) == FFEWHERE_indexUNKNOWN)
|
|
|
|
|
break;
|
|
|
|
|
else if (lo != 0)
|
|
|
|
|
{
|
|
|
|
|
ln += lo;
|
|
|
|
|
wrl = ffewhere_line_new (ln);
|
|
|
|
|
ffewhere_line_kill (wrl);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|