// This may look like C code, but it is really -*- C++ -*- // ------------------------------------------------------------------ // The Goldware Library // Copyright (C) 1990-1999 Odinn Sorensen // ------------------------------------------------------------------ // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Library General Public // License as published by the Free Software Foundation; either // version 2 of the License, or (at your option) any later version. // // This library 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 // Library General Public License for more details. // // You should have received a copy of the GNU Library General Public // License along with this program; if not, write to the Free // Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, // MA 02111-1307, USA // ------------------------------------------------------------------ // $Id$ // ------------------------------------------------------------------ // Text -> Paragraph conversion. // ------------------------------------------------------------------ #include #include // ------------------------------------------------------------------ int GParagraph::ConvertText(char* _tptr, uint _tlen) { // Text position counter uint _tpos = 0; // Main conversion loop while(_tpos < _tlen) { // Skip SOFTCR, NUL and LF characters at the start of a paragraph while(_tpos < _tlen) { switch(*_tptr) { case SOFTCR: if(softcr != LF) break; // Allow soft-cr to be a real char case NUL: case LF: _tptr++; _tpos++; continue; } break; } // Break out of loop at end of text if(_tpos >= _tlen) break; // Paragraph start pointer and position char* _pptr = _tptr; uint _ppos = _tpos; // Find next CR or end of text while((*_tptr != CR) and (_tpos < _tlen)) _tptr++, _tpos++; // NUL-terminate paragraph (overwriting the CR if any) *_tptr = NUL; // Add paragraph AddParagraph(_pptr, _tpos-_ppos); } return lines; } // ------------------------------------------------------------------ uint GParagraph::CheckCtrlLines() { // Non-ctrl text size including a terminating CR uint _length = 0; if(paraidx) { // Flags int _got_tearline = false; int _got_origin = false; // Point to one item past the last item GParaData* _pdptr = ¶idx[lines]; int _line = lines; // Check paragraphs in bottom-up order do { // Previous paragraph _line--; _pdptr--; // Shortcut alias char* _ptr = _pdptr->text; // Switch the CHR4 value switch(*(dword*)_ptr) { // AREA: echo identifier case CHR4_AREA: // Mark all occurrences. Check in a separate loop afterwards if(strneql(_ptr, "AREA:", 5)) _pdptr->control = CTRL_AREA; break; // --- Tearline case CHR4_TEARLINENUL: case CHR4_TEARLINESPACE: // Only the last tearline is valid if(not _got_tearline) if(strneql(_ptr, "---\0", 4) or strneql(_ptr, "--- ", 4)) _pdptr->control = CTRL_TEARLINE, _got_tearline = true; break; // * Origin: case CHR4_ORIGIN: // Only the last origin is valid and only if before any tearline if(not _got_tearline and not _got_origin) if(strneql(_ptr, " * Origin: ", 11)) _pdptr->control = CTRL_ORIGIN, _got_origin = true; break; // SEEN-BY: (non-kludge version) case CHR4_SEENBY: // Non-kludge version is only valid after tearline/origin if(not _got_tearline and not _got_origin) if(strneql(_ptr, "SEEN-BY: ", 9)) _pdptr->control = CTRL_SEENBY; break; // Standard known kludges case CHR4_INTL: if(strneql(_ptr, "\001INTL ", 6)) _pdptr->control = CTRL_INTL; break; case CHR4_FMPT: if(strneql(_ptr, "\001FMPT ", 6)) _pdptr->control = CTRL_FMPT; break; case CHR4_TOPT: if(strneql(_ptr, "\001TOPT ", 6)) _pdptr->control = CTRL_TOPT; break; case CHR4_MSGID: if(strneql(_ptr, "\001MSGID: ", 8)) _pdptr->control = CTRL_MSGID; break; case CHR4_REPLY: if(strneql(_ptr, "\001REPLY: ", 8)) _pdptr->control = CTRL_REPLY; break; case CHR4_PID: if(strneql(_ptr, "\001PID: ", 6)) _pdptr->control = CTRL_PID; break; case CHR4_SEENBY1: if(strneql(_ptr, "\001SEEN-BY: ", 10)) _pdptr->control = CTRL_SEENBY1; break; case CHR4_PATH: if(strneql(_ptr, "\001PATH: ", 7)) _pdptr->control = CTRL_PATH; break; case CHR4_CHARSET: if(strneql(_ptr, "\001CHARSET: ", 10)) _pdptr->control = CTRL_CHARSET; break; case CHR4_CHRS: if(strneql(_ptr, "\001CHRS: ", 7)) _pdptr->control = CTRL_CHRS; break; case CHR4_TZUTC: if(strneql(_ptr, "\001TZUTC: ", 8)) _pdptr->control = CTRL_TZUTC; break; case CHR4_VIA: if(strneql(_ptr, "\001VIA: ", 6)) _pdptr->control = CTRL_VIA; break; case CHR4_FLAGS: if(strneql(_ptr, "\001FLAGS ", 7)) _pdptr->control = CTRL_FLAGS; break; } // Mark unknown kludges if(not _pdptr->control and (*_ptr == CTRL_A)) _pdptr->control = CTRL_UNKNOWNKLUDGE; // Calculate non-ctrl text size if(_pdptr->control < CTRL_KLUDGE) _length += _pdptr->length + 1; } while(_line); // Flags int _got_area = false; int _got_nonctrl = false; // Loop to check AREA: occurrences while(_line < lines) { // Is this a control line? if(_pdptr->control) { // Eliminate AREA: duplicates and any occurrence after first non-ctrl line if(_pdptr->control == CTRL_AREA) { if(_got_area or _got_nonctrl) _pdptr->control = 0; _got_area = true; } } else { // Flag first occurrence of a non-ctrl line _got_nonctrl = true; } // Next paragraph _pdptr++; _line++; } } // Return total non-ctrl text size return _length; } // ------------------------------------------------------------------