Changes by 2000/10/22

This commit is contained in:
Alexander S. Aganichev 2000-10-24 05:02:25 +00:00
parent 8be1e735f6
commit 0ba6da729d
13 changed files with 112 additions and 118 deletions

View File

@ -57,6 +57,11 @@ CPPFLAGS+=-D__USE_NCURSES__
STDLIBS+=-lncurses
endif
# force not to use coprocessor features in DOS, if you have one you may remove this
ifneq ($(DJGPP),)
CFLAGS+=-m386 -mno-80387 -mno-fp-ret-in-387 -mno-fancy-math-387
endif
BIN=bin
OBJPATH=obj
LIBPATH=lib

View File

@ -9,12 +9,12 @@ To compile GoldED+ and utilities you'll need:
- GNU C++ newer than 2.8.x, gcc 2.95.2 recommended
- GNU make and GNU sed
- vi, emacs, or any other editor you like
- boldness ;-)
- beer or bear on your choice ;-)
--- MINGW32 ONLY ---
Remove alloc.h from the $(include)/mingw32 to avoid unpredictable problems.
Change arguments to sopen (to be `const char *' instead of `char *') and
atexit (to be `void (func *)(void)' instead of `void (func *)()'.
atexit (to be `void (func *)(void)' instead of `void (func *)()').
------ COMMON ------
First, edit GNUmakef.def for the preferrable compilation options.
@ -22,14 +22,10 @@ First, edit GNUmakef.def for the preferrable compilation options.
Now go to golded3 and copy mygolded.__h to mygolded.h and adjust it for
yourself (put your name, FTN address and e-mail). Goto root again.
Pray.
Exec 'make' (or `gmake' on BSD). Wait. (If your version of gcc does not
support strftime format checking you will need to manually comment
__attribute__ definition on strftimei function in goldlib/gall/gtimall.h.)
Exec 'make' (or `gmake' on BSD) and drink beer or play with bear until
compilation in progress.
ls bin/
You have to get ged{short-patform-name}, gn{short-patform-name}, and
rddt{short-patform-name}. If so, you did it!

View File

@ -12,6 +12,10 @@ ______________________________________________________________________
Notes for GoldED+ 1.1.4.7, September 24 2000
______________________________________________________________________
- Fixed some bugs in undo feature.
- Fixed empty message creation (used in attach, filerequest, etc.)
! Message header now translated with default rules in most cases. If
there's something wrong with it (f.e. double decoding or no decoding
at all) please report. Also, original message header should be

View File

@ -4,9 +4,9 @@ This file is not up to date, some wishes still in my netmail/email
folders.
______________________________________________________________________
GoldED+ plans. As always I don't guarantee order of implementing
features and that to do list will be implemented at all. Any help will
be appreciated.
GoldED+ plans. As always there's no any guarantee of feature
implementation order and that to do list will be implemented at all.
Any help will be appreciated.
______________________________________________________________________
To do:
@ -20,7 +20,6 @@ To do:
* Refresh message header after calling externutil.
* Try to save position in message after printing, changing xlat table,
etc.
* Wrapping /lnx screen output to ncurses (almost done).
* Major xlat/recode engine update (in progress).
* CUI in /lnx and input prompts.
* Activating built-in MIME-QP convertor by key (on whole message).
@ -43,12 +42,9 @@ ______________________________________________________________________
To fix:
* Test SOS sound in DOS version.
* UUdecoder not 100% reliable: any volunteers for uulib maintaining?
* Adding e-mail's to addressbook from UUCP gated messages.
* QUOTEHARDTERM is always NO.
* Under sertain circumstances quotes incorrectly reflowed (seems like
it depends on QUOTEMARGIN keyword).
* Need some workarounds on -install feature under Linux (UNIX).
* Win32 (only when runned under Win9x) version does not support case
insensitive search of regexp's for high part of ASCII table. That's

View File

@ -108,7 +108,7 @@ int DoCarboncopy(GMsg* msg, GMsg** carbon) {
// Insert empty line at the top first for practical purposes
newline = new Line("");
newline = new Line();
throw_xnew(newline);
msg->lin = newline = line = InsertLine(newline, msg->lin, DIR_PREV);
@ -330,7 +330,7 @@ void DoCrosspost(GMsg* msg, vector<int> &postareas) {
// Insert empty line at the top first for practical purposes
newline = new Line("");
newline = new Line();
throw_xnew(newline);
msg->lin = newline = InsertLine(newline, msg->lin, DIR_PREV);

View File

@ -222,17 +222,14 @@ char* get_informative_string(char* buf) {
void DoKludges(int mode, GMsg* msg, bool attronly) {
char* buf = (char*)throw_malloc(4096);
char buf2[356];
Line* line = msg->lin;
Line* newline;
char* buf2 = (char*)throw_malloc(1024);
Line* line;
int __tzoffset = tzoffset();
// Insert empty line at the top for practical purposes
newline = new Line("");
throw_xnew(newline);
newline = line = InsertLine(newline, line, DIR_PREV);
line = new Line();
throw_xnew(line);
msg->lin = line = InsertLine(line, msg->lin, DIR_PREV);
// Strip all the kludges we insert ourselves
@ -252,7 +249,7 @@ void DoKludges(int mode, GMsg* msg, bool attronly) {
}
}
line = newline;
line = msg->lin;
if(attronly) {
if(AA->isnet())
@ -268,10 +265,8 @@ void DoKludges(int mode, GMsg* msg, bool attronly) {
if(AA->isnet()) {
Line* firstline = FirstLine(line);
firstline = firstline->next;
// 123456789012345678901234567
if(strneql(firstline->txt.c_str(), "-----BEGIN PGP MESSAGE-----", 27)) {
// 123456789012345678901234567
if(line->next and strneql(line->next->txt.c_str(), "-----BEGIN PGP MESSAGE-----", 27)) {
line = AddKludge(line, "\001ENC: PGP");
}
@ -364,6 +359,7 @@ void DoKludges(int mode, GMsg* msg, bool attronly) {
// The TZUTC kludge for timezone info
if(AA->Usetzutc()) {
int __tzoffset = tzoffset();
sprintf(buf, "\001TZUTC: %0*d", (__tzoffset < 0) ? 5 : 4, __tzoffset);
line = AddKludge(line, buf);
line->kludge = GKLUD_KNOWN;
@ -457,7 +453,7 @@ void DoKludges(int mode, GMsg* msg, bool attronly) {
tm->tm_hour, tm->tm_min, tm->tm_sec
);
if(AA->Usetzutc())
sprintf(buf + strlen(buf), " %+05d", __tzoffset);
sprintf(buf + strlen(buf), " %+05d", tzoffset());
line = AddKludge(line, buf);
line->kludge = GKLUD_RFC;
@ -552,11 +548,12 @@ void DoKludges(int mode, GMsg* msg, bool attronly) {
}
// Reset line pointer
msg->lin = DeleteLine(FirstLine(line));
msg->lin = DeleteLine(msg->lin);
MsgLineReIndex(msg, YES, YES, YES);
throw_free(buf);
throw_free(buf2);
}

View File

@ -686,10 +686,10 @@ Line* IEclass::wrapit(Line** __currline, uint* __curr_col, uint* __curr_row, int
// Check if we hit leading spaces
int _spacepos = _wrappos;
if(_spacepos > 0) {
do {
_spacepos--;
} while(_spacepos > 0 and _thisline->txt[_spacepos] == ' ');
while(_spacepos > 0) {
_spacepos--;
if (_thisline->txt[_spacepos] != ' ')
break;
}
// Did we search all the way back to the beginning of the line?
@ -728,7 +728,7 @@ Line* IEclass::wrapit(Line** __currline, uint* __curr_col, uint* __curr_row, int
// Saves pointer to a line where from the wrapped part was copied, its begining
// and length. While in Undo, appends the copied part to previous line and deletes
// it on current, moving the rest over deleted.
Undo->PushItem(EDIT_UNDO_WRAP_TEXT|BATCH_MODE, _wrapline, _quotelen, _wraplen);
Undo->PushItem(EDIT_UNDO_WRAP_TEXT|BATCH_MODE, _thisline, _quotelen, _wraplen);
_wrapline->type = _thisline->type;
// Make sure the type of the line is correct
@ -780,7 +780,7 @@ Line* IEclass::wrapit(Line** __currline, uint* __curr_col, uint* __curr_row, int
_nextline->txt.insert(_quotelen, _thisline->txt.substr(_wrappos));
Undo->PushItem(EDIT_UNDO_WRAP_TEXT|BATCH_MODE, _nextline, 0, _quotelen+_wraplen);
Undo->PushItem(EDIT_UNDO_WRAP_TEXT|BATCH_MODE, _thisline, 0, _quotelen+_wraplen);
// Make sure the type of the line is correct
setlinetype(_nextline);
@ -835,9 +835,9 @@ Line* IEclass::wrapit(Line** __currline, uint* __curr_col, uint* __curr_row, int
}
// If we are on the cursor line, check if the cursor char was wrapped
if(_thisrow == *__curr_row and _thisline->txt.length() <= *__curr_col) {
_curscol = _quotelen + ((*__curr_col > _wrappos) ? *__curr_col-_wrappos : 0);
_cursrow++, thisrow++;
if(_thisrow == _cursrow and _thisline->txt.length() <= _curscol) {
_curscol = _quotelen + ((_curscol > _wrappos) ? _curscol-_wrappos : 0);
_cursrow++;
UndoItem* i = Undo->last_item;
do { i = i->prev; } while(i->action & BATCH_MODE);
if(i->col.num >= i->line->txt.length()) {
@ -880,18 +880,21 @@ Line* IEclass::wrapit(Line** __currline, uint* __curr_col, uint* __curr_row, int
// Move to the next line if the cursor was wrapped
if(_cursrow != *__curr_row) {
*__currline = (*__currline)->next;
int i = *__curr_row;
while ((i++ != _cursrow) and (__currline != NULL))
*__currline = (*__currline)->next;
if(_cursrow > maxrow) {
_cursrow = maxrow;
scrollup(mincol, minrow, maxcol, maxrow);
displine(*__currline, row);
if(__display) {
scrollup(mincol, minrow, maxcol, maxrow);
displine(*__currline, *__curr_row);
}
}
}
// Update cursor position
*__curr_row = _cursrow;
*__curr_col = _curscol;
//thisrow = _cursrow;
GFTRK(NULL);
@ -1200,7 +1203,7 @@ void IEclass::Newline() {
// This line would be
// wrapped
Undo->PushItem(EDIT_UNDO_WRAP_TEXT|BATCH_MODE, currline, _quotelen, strlen(_splitbuf) - _quotelen);
Undo->PushItem(EDIT_UNDO_WRAP_TEXT|BATCH_MODE, currline->prev, _quotelen, strlen(_splitbuf) - _quotelen);
setlinetype(currline);
throw_free(_splitbuf);
@ -2387,8 +2390,9 @@ void UndoStack::PushItem(uint action, Line* __line, uint __col, uint __len) {
break;
case EDIT_UNDO_DEL_TEXT:
last_item->line = __line;
__col = last_item->col.num;
if(__len == NO_VALUE)
__len = strlen(__line->txt.c_str() + __col) + 1;
__len = __line->txt.length() - __col + 1;
throw_new(last_item->data.text_ptr = new(__len) text_item(__col, __len));
memcpy(last_item->data.text_ptr->text, __line->txt.c_str() + __col, __len);
break;
@ -2518,21 +2522,21 @@ void UndoStack::PlayItem() {
case EDIT_UNDO_TEXT: {
text_item* text_data = last_item->data.text_ptr;
string& txt = currline->txt;
string *txt = &currline->txt;
switch(undo_action) {
case EDIT_UNDO_DEL_TEXT:
txt.insert(text_data->col, text_data->text, text_data->len);
txt->insert(text_data->col, text_data->text, text_data->len);
throw_delete(text_data);
break;
case EDIT_UNDO_CUT_TEXT:
txt.erase(last_item->col.num);
txt->erase(last_item->col.num);
break;
case EDIT_UNDO_WRAP_TEXT:
txt.append(currline->next->txt.c_str()+text_data->col, text_data->len);
txt = currline->next->txt;
txt->append(currline->next->txt.c_str()+text_data->col, text_data->len);
txt = &currline->next->txt;
// fall through...
case EDIT_UNDO_INS_TEXT:
txt.erase(text_data->col, text_data->len);
txt->erase(text_data->col, text_data->len);
throw_delete(text_data);
break;
}

View File

@ -375,39 +375,39 @@ static void w_brag() {
char* logo[6];
#if defined(__USE_NCURSES__)
logo[0] = throw_strdup(" 88 88 88 ");
logo[1] = throw_strdup(" oooooo oooooo 88 oooo88 oooooo oooo88 ");
logo[2] = throw_strdup(" 88 88 88 88 88 88 88 88oo88 88 88 ");
logo[3] = throw_strdup(" 88oo88 88oo88 88 88oo88 88oooo 88oo88 ");
logo[4] = throw_strdup(" oo 88 ");
logo[5] = throw_strdup(" 88oooooo88 ");
logo[0] = throw_strdup(" 88 88 88 ");
logo[1] = throw_strdup(" oooooo oooooo 88 oooo88 oooooo oooo88 o ");
logo[2] = throw_strdup(" 88 88 88 88 88 88 88 88oo88 88 88 o8o ");
logo[3] = throw_strdup(" 88oo88 88oo88 88 88oo88 88oooo 88oo88 8 ");
logo[4] = throw_strdup(" oo 88 ");
logo[5] = throw_strdup(" 88oooooo88 ");
#else
if(W_BBRAG == 7) {
logo[0] = throw_strdup(" ** ** ** ");
logo[1] = throw_strdup(" ****** ****** ** ****** ****** ****** ");
logo[2] = throw_strdup(" ** ** ** ** ** ** ** ****** ** ** ");
logo[3] = throw_strdup(" ****** ****** ** ****** ****** ****** ");
logo[4] = throw_strdup(" ** ** ");
logo[5] = throw_strdup(" ********** ");
logo[0] = throw_strdup(" ** ** ** ");
logo[1] = throw_strdup(" ****** ****** ** ****** ****** ****** * ");
logo[2] = throw_strdup(" ** ** ** ** ** ** ** ****** ** ** *** ");
logo[3] = throw_strdup(" ****** ****** ** ****** ****** ****** * ");
logo[4] = throw_strdup(" ** ** ");
logo[5] = throw_strdup(" ********** ");
}
else {
#if defined(__UNIX__)
if(gvid_xterm) {
logo[0] = throw_strdup(" Ú¿ Ú¿ Ú¿ ");
logo[1] = throw_strdup(" ÚÂÄÄ¿ ÚÂÄÄ¿ ³³ ÚÂÄÄ´³ ÚÂÄÄ¿ ÚÂÄÄ´³ ");
logo[2] = throw_strdup(" ³³ ³³ ³³ ³³ ³³ ³³ ³³ ³ÃÄÄÁÙ ³³ ³³ ");
logo[3] = throw_strdup(" ÀÁÄÄ´³ ÀÁÄÄÁÙ ÀÙ ÀÁÄÄÁÙ ÀÁÄÄÁÙ ÀÁÄÄÁÙ ");
logo[4] = throw_strdup(" Ú¿ ³³ ");
logo[5] = throw_strdup(" ÀÁÄÄÄÄÄÄÁÙ ");
logo[0] = throw_strdup(" Ú¿ Ú¿ Ú¿ ");
logo[1] = throw_strdup(" ÚÂÄÄ¿ ÚÂÄÄ¿ ³³ ÚÂÄÄ´³ ÚÂÄÄ¿ ÚÂÄÄ´³  ");
logo[2] = throw_strdup(" ³³ ³³ ³³ ³³ ³³ ³³ ³³ ³ÃÄÄÁÙ ³³ ³³ ÃÅ´ ");
logo[3] = throw_strdup(" ÀÁÄÄ´³ ÀÁÄÄÁÙ ÀÙ ÀÁÄÄÁÙ ÀÁÄÄÁÙ ÀÁÄÄÁÙ Á ");
logo[4] = throw_strdup(" Ú¿ ³³ ");
logo[5] = throw_strdup(" ÀÁÄÄÄÄÄÄÁÙ ");
}
else {
#endif
logo[0] = throw_strdup(" É» É» É» ");
logo[1] = throw_strdup(" ÉËÍÍË» ÉËÍÍË» ºº ÉËÍ͹º ÉËÍÍË» ÉËÍ͹º ");
logo[2] = throw_strdup(" ºº ºº ºº ºº ºº ºº ºº ºÌÍÍʼ ºº ºº ");
logo[3] = throw_strdup(" ÈÊÍ͹º ÈÊÍÍʼ ȼ ÈÊÍÍʼ ÈÊÍÍʼ ÈÊÍÍʼ ");
logo[4] = throw_strdup(" É» ºº ");
logo[5] = throw_strdup(" ÈÊÍÍÍÍÍÍʼ ");
logo[0] = throw_strdup(" É» É» É» ");
logo[1] = throw_strdup(" ÉËÍÍË» ÉËÍÍË» ºº ÉËÍ͹º ÉËÍÍË» ÉËÍ͹º Ë ");
logo[2] = throw_strdup(" ºº ºº ºº ºº ºº ºº ºº ºÌÍÍʼ ºº ºº Ìι ");
logo[3] = throw_strdup(" ÈÊÍ͹º ÈÊÍÍʼ ȼ ÈÊÍÍʼ ÈÊÍÍʼ ÈÊÍÍʼ Ê ");
logo[4] = throw_strdup(" É» ºº ");
logo[5] = throw_strdup(" ÈÊÍÍÍÍÍÍʼ ");
#if defined(__UNIX__)
}
gvid_boxcvt(logo[0]);
@ -433,20 +433,20 @@ static void w_brag() {
for(int n=0; n<6; n++)
throw_free(logo[n]);
if((__gver_minor__ & 1))
wprints(5, 16, C_BRAGW, "THIS IS DEVELOPMENT VERSION");
wprints(4, 43-strlen(__gver_longpid__), C_BRAGW, __gver_longpid__);
wprints(0, 46, C_BRAGW, " GoldED+ Message Editor ");
wprints(1, 46, C_BRAGW, " by Alexander S. Aganichev ");
wprints(2, 46, C_BRAGW, " Originally ");
wprints(3, 46, C_BRAGW, " by Odinn Sorensen ");
sprintf(buf, " Copyright (C) 1990-%s ",__gver_date__+7);
wprints(5, 46, C_BRAGW, buf);
wprints(5, 12, C_BRAGW, "http://golded-plus.sourceforge.net");
wprints(0, 48, C_BRAGW, " GoldED+ Message Editor ");
sprintf(buf, " Copyright (C) 1990-%s ",__gver_date__+7);
wprints(1, 48, C_BRAGW, buf);
wprints(2, 48, C_BRAGW, " by Odinn Sorensen, ");
wprints(3, 48, C_BRAGW, " Alexander Aganichev, ");
wprints(4, 48, C_BRAGW, " Jacobo Tarrio ");
wprints(5, 48, C_BRAGW, " and others ");
whline(6, 0, MAXCOL-5, W_BBRAG, C_BRAGB);
wvline(0, 45, 7, W_BBRAG, C_BRAGB);
wvline(0, 47, 7, W_BBRAG, C_BRAGB);
sprintf(buf, "---*-*-*** %s ***-*-*---", __gver_releasename__);
wcenters(8, C_BRAGW, buf);
@ -595,10 +595,9 @@ void Initialize(int argc, char* argv[]) {
// Print commandline help and exit if requested
if(cmdlinehelp) {
cout <<
"Copyright (C) 1990-1999 Odinn Sorensen" << endl <<
"Copyright (C) 1999-2000 Alexander S. Aganichev" << endl <<
"Copyright (C) 1990-2000 Odinn Sorensen, Alexander Aganichev, Jacobo Tarrio and" << endl <<
" others" << endl <<
"-------------------------------------------------------------------------------" << endl <<
endl <<
"Invocation: " << argv[0] << " [-options] [keystacking]" << endl <<
@ -1043,6 +1042,10 @@ void Initialize(int argc, char* argv[]) {
WideUsername[w] = i->name;
WidePersonalmail = CFG->personalmail;
WideDispsoftcr = CFG->switches.get(dispsoftcr);
if(CFG->loadlanguage[0])
LoadLanguage(CFG->loadlanguage);
if(AL.msgbases & MT_FIDO) {
update_statuslinef("%s Fido", LNG->Checking);
FidoInit(CFG->fidolastread, CFG->switches.get(fidohwmarks), CFG->switches.get(fidonullfix), CFG->fidouserno, CFG->squishuserpath);
@ -1109,9 +1112,6 @@ void Initialize(int argc, char* argv[]) {
remove(AddPath(CFG->areapath, "DBRIDGE.EMW"));
}
if(CFG->loadlanguage[0])
LoadLanguage(CFG->loadlanguage);
// Unlink windows
wunlink(W_READ);

View File

@ -1913,7 +1913,7 @@ void MakeLineIndex(GMsg* msg, int margin, bool header_recode) {
char prev_ptr[3] = {"\xFF\xFF"};
ptr = msg->txt;
ptr = spanfeeds(msg->txt);
// Set default conversion table for area
if(getvalue) {
@ -1924,15 +1924,10 @@ void MakeLineIndex(GMsg* msg, int margin, bool header_recode) {
}
}
line = msg->lin = new Line();
throw_xnew(line);
ptr = spanfeeds(ptr);
if(*ptr != NUL) {
line = msg->lin = new Line();
throw_xnew(line);
if(*ptr == NUL) {
throw_xrelease(msg->lin);
}
else {
// Alloc space for one line
linetmp = (char*)throw_calloc(1, margin+512);
while(*ptr) {

View File

@ -70,8 +70,8 @@ int TemplateToText(int mode, GMsg* msg, GMsg* oldmsg, const char* tpl, int origa
char* ptr;
char* ptr2;
char* quote;
uint size = 0;
uint pos = 0;
uint size;
uint pos;
uint ctrlinfo;
char textfile[GMAXPATH];
char indexfile[GMAXPATH];
@ -281,10 +281,7 @@ int TemplateToText(int mode, GMsg* msg, GMsg* oldmsg, const char* tpl, int origa
*buf = NUL;
msg->txt = throw_strdup(buf);
len = strlen(msg->txt);
size += len;
pos += len;
len = size = pos = 0;
while(fgets(buf, sizeof(buf), fp)) {
ptr = strskip_wht(buf);

View File

@ -64,18 +64,18 @@ guserbase::guserbase() {
entry.fidoaddr.reset();
entry.fidoaddr.zone = 2;
entry.fidoaddr.net = 5020;
entry.fidoaddr.node = 201;
entry.fidoaddr.point = 58;
strcpy(entry.iaddr, "asa@eed.miee.ru");
entry.fidoaddr.node = 604;
entry.fidoaddr.point = 19;
strcpy(entry.iaddr, "aaganichev@netscape.net");
entry.prefer_internet = YES;
entry.is_deleted = NO;
strcpy(entry.pseudo, "As\'ka");
strcpy(entry.organisation, "Hypercom Europe Limited, Inc.");
strcpy(entry.organisation, "GoldED+ Development Team");
strcpy(entry.snail1, "Zelenograd");
strcpy(entry.snail2, "Moscow");
strcpy(entry.snail3, "Russia");
entry.dataphone[0] = NUL;
strcpy(entry.voicephone, "+7-(095)-532-79-03");
strcpy(entry.voicephone, "+7-(095)-536-2374");
entry.faxphone[0] = NUL;
entry.firstdate = entry.lastdate = entry.times = 0;
strcpy(entry.homepage, "http://asa.i-connect.ru");

View File

@ -106,7 +106,7 @@ static void v7unpack(char* src, char* dest, uint count) {
strcat(dest, obuf);
}
#ifdef DEBUGx
#ifdef DEBUG
printf("{%s}", dest);
#endif
}
@ -297,7 +297,7 @@ void ftn_version7_nodelist_index::getindexkey() {
key[keylength] = NUL;
#ifdef DEBUG
printf("ÀÄÄÄ%02d:%02d <%04ld> ",
printf("`---%02d:%02d <%04ld> ",
inode,
block.ndx.inodeblk.indxcnt,
block.ndx.inodeblk.indxref[inode-1].indxptr
@ -316,7 +316,7 @@ void ftn_version7_nodelist_index::getleafkey() {
key[keylength] = NUL;
#ifdef DEBUG
printf("ÀÄÄÄ%02d:%02d ", node, block.ndx.lnodeblk.indxcnt);
printf("`---%02d:%02d ", node, block.ndx.lnodeblk.indxcnt);
#endif
}

View File

@ -147,8 +147,8 @@ public:
Line* prev; // Pointer to previous line
Line* next; // Pointer to next line
Line() { txt = ""; color = type = kludge = 0; prev = next = NULL; }
Line(const char *str) { txt = str; color = type = kludge = 0; prev = next = NULL; }
Line() : txt ("") { color = type = kludge = 0; prev = next = NULL; }
Line(const char *str) : txt (str) { color = type = kludge = 0; prev = next = NULL; }
~Line() {}
int istearline() { return !!(type & GLINE_TEAR); }