mirror of
https://github.com/ascii-boxes/boxes.git
synced 2025-06-12 12:56:38 +02:00
Bugfix: Horizontal box parts were not correctly detected if the west box
side was empty (reported: Tobias Buchal) Bugfix: boxes could hang in detect_horiz() due to goeast/west confusion
This commit is contained in:
parent
532bd941b3
commit
3f2f687128
196
src/remove.c
196
src/remove.c
@ -4,7 +4,7 @@
|
||||
* Date created: June 23, 1999 (Wednesday, 20:59h)
|
||||
* Author: Copyright (C) 1999 Thomas Jensen
|
||||
* tsjensen@stud.informatik.uni-erlangen.de
|
||||
* Version: $Id: remove.c,v 1.3 1999/07/20 18:57:16 tsjensen Exp tsjensen $
|
||||
* Version: $Id: remove.c,v 1.4 1999/08/21 16:03:31 tsjensen Exp tsjensen $
|
||||
* Language: ANSI C
|
||||
* World Wide Web: http://home.pages.de/~jensen/boxes/
|
||||
* Purpose: Box removal, i.e. the deletion of boxes
|
||||
@ -25,6 +25,9 @@
|
||||
* Revision History:
|
||||
*
|
||||
* $Log: remove.c,v $
|
||||
* Revision 1.4 1999/08/21 16:03:31 tsjensen
|
||||
* Bugfix: When matching vertical side shape lines, ignore empty shape lines
|
||||
*
|
||||
* Revision 1.3 1999/07/20 18:57:16 tsjensen
|
||||
* Added GNU GPL disclaimer
|
||||
* Does not kill leading/trailing blank lines anymore when !opt.killblank
|
||||
@ -50,7 +53,7 @@
|
||||
#include "remove.h"
|
||||
|
||||
static const char rcsid_remove_c[] =
|
||||
"$Id: remove.c,v 1.3 1999/07/20 18:57:16 tsjensen Exp tsjensen $";
|
||||
"$Id: remove.c,v 1.4 1999/08/21 16:03:31 tsjensen Exp tsjensen $";
|
||||
|
||||
|
||||
|
||||
@ -98,7 +101,7 @@ static int best_match (const line_t *line,
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Find match for WEST side
|
||||
* Find match for WEST side (TODO: nicht wenn BLEF leer)
|
||||
*/
|
||||
quality = 0;
|
||||
cs = opt.design->shape + WNW;
|
||||
@ -315,7 +318,7 @@ static int hmm (const int aside, const size_t follow,
|
||||
|
||||
static int detect_horiz (const int aside, size_t *hstart, size_t *hend)
|
||||
/*
|
||||
* Detect which part of the input belongs to the top of the box
|
||||
* Detect which part of the input belongs to the top/bottom of the box
|
||||
*
|
||||
* aside part of box to detect (BTOP or BBOT)
|
||||
* hstart index of first line of detected box part (result)
|
||||
@ -324,9 +327,10 @@ static int detect_horiz (const int aside, size_t *hstart, size_t *hend)
|
||||
* We assume the horizontal parts of the box to be in one piece, i.e. no
|
||||
* blank lines inserted. Lines may be missing, though. Lines may not be
|
||||
* duplicated. They may be shifted left and right by inserting whitespace,
|
||||
* but whitespace which is part of the box must not have been deleted.
|
||||
* Unfortunately, they may even differ in length as long as each line is
|
||||
* in itself a valid horizontal box line.
|
||||
* but whitespace which is part of the box must not have been deleted
|
||||
* (unless it's because an entire box side is empty). Box part lines may
|
||||
* even differ in length as long as each line is in itself a valid
|
||||
* horizontal box line.
|
||||
*
|
||||
* RETURNS: == 0 success (hstart & hend are set)
|
||||
* != 0 error
|
||||
@ -337,18 +341,20 @@ static int detect_horiz (const int aside, size_t *hstart, size_t *hend)
|
||||
size_t follow; /* possible box line */
|
||||
sentry_t *cs; /* current shape */
|
||||
line_t *line; /* currently processed input line */
|
||||
size_t lcnt; /* index of currently proc.inp.line */
|
||||
char *p; /* middle line part scanner */
|
||||
size_t lcnt; /* line counter */
|
||||
char *p = NULL; /* middle line part scanner */
|
||||
char *q; /* space check rover */
|
||||
char *wcs = NULL; /* west corner shape position */
|
||||
char *ecs = NULL; /* east corner shape position */
|
||||
char *ecs_save; /* temp copy of ecs */
|
||||
int mmok = 0; /* true if middle match was ok */
|
||||
size_t mheight; /* regular height of box part */
|
||||
int result_init = 0; /* true if hstart was set */
|
||||
int goeast, gowest;
|
||||
int result_init = 0; /* true if hstart etc. was init. */
|
||||
int nowside; /* true if west side is empty */
|
||||
int goeast; /* no. of finds to ignore on right */
|
||||
int gowest; /* set to request search start incr. */
|
||||
|
||||
*hstart = *hend = 0;
|
||||
nowside = empty_side (opt.design->shape, BLEF);
|
||||
|
||||
mheight = opt.design->shape[sides[aside][0]].height;
|
||||
if (aside == BTOP) {
|
||||
@ -375,80 +381,98 @@ static int detect_horiz (const int aside, size_t *hstart, size_t *hend)
|
||||
/*
|
||||
* Look for west corner shape
|
||||
*/
|
||||
cs = opt.design->shape + sides[aside][aside==BTOP?0:SHAPES_PER_SIDE-1];
|
||||
if (gowest) {
|
||||
wcs = strstr (wcs+1, cs->chars[follow]);
|
||||
gowest = 0;
|
||||
}
|
||||
else if (!wcs) {
|
||||
wcs = strstr (line->text, cs->chars[follow]);
|
||||
}
|
||||
if (wcs) {
|
||||
for (q=wcs-1; q>=line->text; --q) {
|
||||
if (*q != ' ' && *q != '\t')
|
||||
break;
|
||||
}
|
||||
if (q >= line->text)
|
||||
if (!goeast) {
|
||||
if (nowside) {
|
||||
wcs = NULL;
|
||||
if (gowest) {
|
||||
gowest = 0;
|
||||
if (*p == ' ' || *p == '\t')
|
||||
++p;
|
||||
else
|
||||
break;
|
||||
}
|
||||
else {
|
||||
p = line->text;
|
||||
}
|
||||
}
|
||||
else {
|
||||
cs = opt.design->shape + sides[aside][aside==BTOP?0:SHAPES_PER_SIDE-1];
|
||||
if (gowest) {
|
||||
gowest = 0;
|
||||
wcs = strstr (wcs+1, cs->chars[follow]);
|
||||
}
|
||||
else {
|
||||
wcs = strstr (line->text, cs->chars[follow]);
|
||||
}
|
||||
if (wcs) {
|
||||
for (q=wcs-1; q>=line->text; --q) {
|
||||
if (*q != ' ' && *q != '\t')
|
||||
break;
|
||||
}
|
||||
if (q >= line->text)
|
||||
wcs = NULL;
|
||||
}
|
||||
if (!wcs)
|
||||
break;
|
||||
|
||||
p = wcs + cs->width;
|
||||
}
|
||||
}
|
||||
/* Now, wcs is either NULL (if west side is empty) */
|
||||
/* or not NULL (if west side is not empty). In any case, p */
|
||||
/* points to where we start searching for the east corner. */
|
||||
#ifdef DEBUG
|
||||
if (wcs)
|
||||
fprintf (stderr, "West corner shape matched at position %d.\n",
|
||||
wcs - line->text);
|
||||
fprintf (stderr, "West corner shape matched at "
|
||||
"position %d.\n", wcs - line->text);
|
||||
else
|
||||
fprintf (stderr, "West corner shape not found.\n");
|
||||
fprintf (stderr, "West box side is empty.\n");
|
||||
#endif
|
||||
|
||||
p = wcs + cs->width;
|
||||
|
||||
/*
|
||||
* Look for east corner shape
|
||||
*/
|
||||
if (wcs) {
|
||||
cs = opt.design->shape + sides[aside][aside==BTOP?SHAPES_PER_SIDE-1:0];
|
||||
ecs_save = ecs;
|
||||
ecs = my_strnrstr (p, cs->chars[follow], cs->width, goeast);
|
||||
if (ecs) {
|
||||
for (q=ecs+cs->width; *q; ++q) {
|
||||
if (*q != ' ' && *q != '\t')
|
||||
break;
|
||||
}
|
||||
if (*q)
|
||||
ecs = NULL;
|
||||
cs = opt.design->shape + sides[aside][aside==BTOP?SHAPES_PER_SIDE-1:0];
|
||||
ecs = my_strnrstr (p, cs->chars[follow], cs->width, goeast);
|
||||
if (ecs) {
|
||||
for (q=ecs+cs->width; *q; ++q) {
|
||||
if (*q != ' ' && *q != '\t')
|
||||
break;
|
||||
}
|
||||
if (!ecs) {
|
||||
gowest = 1;
|
||||
if (*q)
|
||||
ecs = NULL;
|
||||
}
|
||||
if (!ecs) {
|
||||
if (goeast == 0)
|
||||
break;
|
||||
else {
|
||||
goeast = 0;
|
||||
ecs = ecs_save;
|
||||
gowest = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (ecs)
|
||||
fprintf (stderr, "East corner shape matched at position %d.\n",
|
||||
ecs-line->text);
|
||||
else
|
||||
fprintf (stderr, "East corner shape not found.\n");
|
||||
fprintf (stderr, "East corner shape matched at position %d.\n",
|
||||
ecs-line->text);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check if text between corner shapes is valid
|
||||
*/
|
||||
if (wcs && ecs) {
|
||||
mmok = !hmm (aside, follow, p, ecs, 0);
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "Text between corner shapes is%s valid.\n",
|
||||
mmok? "": " NOT");
|
||||
#endif
|
||||
if (!mmok)
|
||||
++goeast;
|
||||
}
|
||||
mmok = !hmm (aside, follow, p, ecs, 0);
|
||||
if (!mmok)
|
||||
++goeast;
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "Text between corner shapes is %s.\n",
|
||||
mmok? "VALID": "NOT valid");
|
||||
#endif
|
||||
|
||||
} while (!mmok && wcs);
|
||||
} while (!mmok);
|
||||
|
||||
/*
|
||||
* Proceed to next line
|
||||
*/
|
||||
if (wcs && ecs && mmok) { /* match found */
|
||||
if (mmok) { /* match found */
|
||||
if (!result_init) {
|
||||
result_init = 1;
|
||||
if (aside == BTOP)
|
||||
@ -465,8 +489,11 @@ static int detect_horiz (const int aside, size_t *hstart, size_t *hend)
|
||||
if (result_init)
|
||||
break;
|
||||
}
|
||||
|
||||
wcs = NULL;
|
||||
ecs = NULL;
|
||||
p = NULL;
|
||||
mmok = 0;
|
||||
|
||||
if (aside == BTOP) {
|
||||
++follow;
|
||||
@ -826,27 +853,44 @@ int remove_box()
|
||||
*/
|
||||
boxstart = 0;
|
||||
textstart = 0;
|
||||
detect_horiz (BTOP, &boxstart, &textstart);
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "----> First line of box is %d, ", boxstart);
|
||||
fprintf (stderr, "first line of box body (text) is %d.\n", textstart);
|
||||
#endif
|
||||
if (empty_side (opt.design->shape, BTOP)) {
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "----> Top box side is empty: boxstart == textstart == 0.\n");
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
detect_horiz (BTOP, &boxstart, &textstart);
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "----> First line of box is %d, ", boxstart);
|
||||
fprintf (stderr, "first line of box body (text) is %d.\n", textstart);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Phase 2: Find out how many lines belong to the bottom of the box
|
||||
*/
|
||||
textend = 0;
|
||||
boxend = 0;
|
||||
detect_horiz (BBOT, &textend, &boxend);
|
||||
if (textend == 0 && boxend == 0) {
|
||||
if (empty_side (opt.design->shape, BBOT)) {
|
||||
textend = input.anz_lines;
|
||||
boxend = input.anz_lines;
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "----> Bottom box side is empty: boxend == textend == %d.\n",
|
||||
input.anz_lines);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
textend = 0;
|
||||
boxend = 0;
|
||||
detect_horiz (BBOT, &textend, &boxend);
|
||||
if (textend == 0 && boxend == 0) {
|
||||
textend = input.anz_lines;
|
||||
boxend = input.anz_lines;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "----> Last line of box body (text) is %d, ", textend-1);
|
||||
fprintf (stderr, "last line of box is %d.\n", boxend-1);
|
||||
#endif
|
||||
}
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "----> Last line of box body (text) is %d, ", textend-1);
|
||||
fprintf (stderr, "last line of box is %d.\n", boxend-1);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Phase 3: Iterate over body lines, removing box sides where applicable
|
||||
@ -865,12 +909,12 @@ int remove_box()
|
||||
}
|
||||
else if (m == 0) {
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "line %2d: no side match\n", j);
|
||||
fprintf (stderr, "\033[00;33;01mline %2d: no side match\033[00m\n", j);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "\033[00;33mline %2d: west: %d (\'%c\') to "
|
||||
fprintf (stderr, "\033[00;33;01mline %2d: west: %d (\'%c\') to "
|
||||
"%d (\'%c\') [len %d]; east: %d (\'%c\') to %d (\'%c\')"
|
||||
" [len %d]\033[00m\n", j,
|
||||
ws? ws-input.lines[j].text:0, ws?ws[0]:'?',
|
||||
|
Loading…
x
Reference in New Issue
Block a user