#include "munga.h" #include "notation.h" #include "namelist.h" //############################################################################# //############## NotationFile ########################################### //############################################################################# NotationFile::NotationFile( const char *filename, Enumeration operation_modes ) { Check_Pointer(this); //do not check filename here fileName = NULL; firstNotePage = lastNotePage = NULL; pageCount = cleanPageCount = 0; dirtyFlag = False; saveNotePage = NULL; operationModes = operation_modes; if (filename && *filename) { Check_Pointer(filename); ReadFile(filename); } Check(this); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // NotationFile::~NotationFile() { Check(this); NotePage *next = firstNotePage; if (dirtyFlag) { if (fileName && *fileName && !WriteFile()) { std::cerr << "NotationFile: Error writing file '" << fileName << "' - changes lost!" << std::endl; } } while (next) { Check(next); firstNotePage = next->nextNotePage; Unregister_Object(next); delete next; next = firstNotePage; } if (fileName) { Unregister_Pointer(fileName); delete fileName; } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical NotationFile::PageExists(const char *pagename) { // let FindNotePage() check this and pagename NotePage *notepage; return FindNotePage(pagename, ¬epage); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // long NotationFile::EntryCount(const char *pagename) { // let FindNotePage() check this and pagename NotePage *notepage; if (FindNotePage(pagename, ¬epage)) { Check(notepage); return ((operationModes&CleanEntryListMode)?notepage->cleanNotationCount:notepage->notationCount); } return 0; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // NotationFile::NotePage* NotationFile::SetPage( const char *pagename, const char *comment ) { // let FindNotePage() check this and pagename // let AppentPage() or SetComment() check comment NotePage *notepage; SetDirty(); if (!FindNotePage(pagename, ¬epage)) { notepage = AppendPage(pagename, comment); } else { notepage->SetComment(comment); } return notepage; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // NotationFile::NotePage* NotationFile::AppendPage( const char *pagename, const char *comment ) { Check(this); Check_Pointer(pagename); // let SetComment() check comment NotePage *notepage; SetDirty(); notepage = new NotePage(this); Register_Object(notepage); notepage->SetName(pagename, &cleanPageCount); notepage->SetComment(comment); AppendNotePage(notepage); return notepage; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // int NotationFile::GetEntry( const char *pagename, const char *entryname, const char **contents ) { Check(this); Check_Pointer(pagename); Check_Pointer(entryname); Check_Pointer(contents); NotePage *notepage; Notation *notation; //--------------- // return string //--------------- if (FindNotePage(pagename, ¬epage)) { Check(notepage); if (notepage->FindNote(entryname, ¬ation)) { Check(notation); *contents = notation->GetEntry(); return True; } } return False; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // int NotationFile::GetEntry( const char *pagename, const char *entryname, int *value ) { Check(this); Check_Pointer(pagename); Check_Pointer(entryname); Check_Pointer(value); const char *contents; //---------------- // return integer //---------------- if (GetEntry(pagename, entryname, &contents)) { Check_Pointer(contents); *value = atoi(contents); return True; } return False; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // int NotationFile::GetEntry( const char *pagename, const char *entryname, Scalar *value ) { Check(this); Check_Pointer(pagename); Check_Pointer(entryname); Check_Pointer(value); const char *contents; //--------------- // return scalar //--------------- if (GetEntry(pagename, entryname, &contents)) { Check_Pointer(contents); *value = atof(contents); return True; } return False; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // int NotationFile::GetEntry( const char *pagename, const char *entryname, double *value ) { Check(this); Check_Pointer(pagename); Check_Pointer(entryname); Check_Pointer(value); const char *contents; //--------------- // return double //--------------- if (GetEntry(pagename, entryname, &contents)) { Check_Pointer(contents); *value = atof(contents); return True; } return False; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // int NotationFile::GetLogicalEntry( const char *pagename, const char *entryname, Logical *value ) { Check(this); Check_Pointer(pagename); Check_Pointer(entryname); Check_Pointer(value); const char *contents; //---------------- // return Logical //---------------- if (GetEntry(pagename, entryname, &contents)) { Check_Pointer(contents); //-------------------------------------------------------- // these stricmp()'s must not affected by IgnoreCaseModes //-------------------------------------------------------- *value = (!stricmp(contents, "true") || !stricmp(contents, "yes") || atoi(contents) != 0); return True; } return False; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void NotationFile::SetEntry( const char *pagename, const char *entryname, const char *contents ) { Check(this); Check_Pointer(pagename); Check_Pointer(entryname); if (contents) { Check_Pointer(contents); } NotePage *notepage; Notation *notation; SetDirty(); //--------------- // assign string //--------------- if (!FindNotePage(pagename, ¬epage)) { notepage = AppendPage(pagename); } notation = new Notation; Register_Object(notation); notation->SetName(entryname, &(notepage->cleanNotationCount)); notation->SetEntry(contents); notepage->UpdateNote(notation); return; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void NotationFile::SetEntry( const char *pagename, const char *entryname, int value ) { Check(this); Check_Pointer(pagename); Check_Pointer(entryname); static char contents[12]; std::ostrstream stream(contents, sizeof(contents)); stream << value << std::ends; SetEntry(pagename, entryname, contents); return; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void NotationFile::SetEntry( const char *pagename, const char *entryname, Scalar value ) { Check(this); Check_Pointer(pagename); Check_Pointer(entryname); static char contents[32]; std::ostrstream stream(contents, sizeof(contents)); stream << value << std::ends; SetEntry(pagename, entryname, contents); return; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void NotationFile::SetEntry( const char *pagename, const char *entryname, double value ) { Check(this); Check_Pointer(pagename); Check_Pointer(entryname); static char contents[64]; std::ostrstream stream(contents, sizeof(contents)); stream << value << std::ends; SetEntry(pagename, entryname, contents); return; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void NotationFile::SetLogicalEntry( const char *pagename, const char *entryname, Logical value ) { Check(this); Check_Pointer(pagename); Check_Pointer(entryname); static char contents[6]; std::ostrstream stream(contents, sizeof(contents)); if (value) { stream << "True" << std::ends; } else { stream << "False" << std::ends; } SetEntry(pagename, entryname, contents); return; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void NotationFile::AppendEntry( const char *pagename, const char *entryname, const char *contents ) { Check(this); Check_Pointer(pagename); if (entryname) { Check_Pointer(entryname); } if (contents) { Check_Pointer(contents); } NotePage *notepage; Notation *notation; SetDirty(); //--------------- // assign string //--------------- if (!FindNotePage(pagename, ¬epage)) { notepage = AppendPage(pagename); } notation = new Notation; Register_Object(notation); notation->SetName(entryname, &(notepage->cleanNotationCount)); notation->SetEntry(contents); notepage->AppendNote(notation); return; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void NotationFile::AppendEntry( const char *pagename, const char *entryname, int value ) { Check(this); Check_Pointer(pagename); Check_Pointer(entryname); static char contents[12]; std::ostrstream stream(contents, sizeof(contents)); stream << value << std::ends; AppendEntry(pagename, entryname, contents); return; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void NotationFile::AppendEntry( const char *pagename, const char *entryname, Scalar value ) { Check(this); Check_Pointer(pagename); Check_Pointer(entryname); static char contents[32]; std::ostrstream stream(contents, sizeof(contents)); stream << value << std::ends; AppendEntry(pagename, entryname, contents); return; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void NotationFile::AppendEntry( const char *pagename, const char *entryname, double value ) { Check(this); Check_Pointer(pagename); Check_Pointer(entryname); static char contents[64]; std::ostrstream stream(contents, sizeof(contents)); stream << value << std::ends; AppendEntry(pagename, entryname, contents); return; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void NotationFile::AppendLogicalEntry( const char *pagename, const char *entryname, Logical value ) { Check(this); Check_Pointer(pagename); Check_Pointer(entryname); static char contents[6]; std::ostrstream stream(contents, sizeof(contents)); if (value) { stream << "True" << std::ends; } else { stream << "False" << std::ends; } AppendEntry(pagename, entryname, contents); return; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // NameList* NotationFile::MakeEntryList( const char *pagename, const char *entryname_prefix ) { Check(this); Check_Pointer(pagename); //do not check entryname_prefix here NotePage *notepage; //-------------------------------------------------- // return namelist of matching entries and contents //-------------------------------------------------- if (FindNotePage(pagename, ¬epage)) { return MakeEntryList(notepage, entryname_prefix); } return NULL; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // NameList* NotationFile::MakeEntryList( NotePage *notepage, const char *entryname_prefix ) { Check(this); Check(notepage); //do not check entryname_prefix here const char *name_prefix = entryname_prefix?entryname_prefix:"\0"; Check_Pointer(name_prefix); const int length = strlen(name_prefix); NameList *namelist; Notation *notation; const char *name; Logical prefix_matches, add_entry; //-------------------------------------------------- // return namelist of matching entries and contents //-------------------------------------------------- namelist = new NameList; //do not register namelist notation = notepage->firstNotation; while (notation) { Check(notation); name = notation->GetName(); if (name) { Check_Pointer(name); if (operationModes&IgnoreEntryCaseMode) { prefix_matches = (!strnicmp(name, name_prefix, length)); } else { prefix_matches = (!strncmp(name, name_prefix, length)); } } else { prefix_matches = (entryname_prefix == NULL); } if (operationModes&CleanEntryListMode) { add_entry = (notation->cleanNotation && prefix_matches); } else if (name) { add_entry = (prefix_matches); } else if (operationModes&SkipBlanksListMode) { add_entry = False; } else { //------------------------------------------------------ // HACK: NameList::AddEntry() should accept name==NULL //------------------------------------------------------ add_entry = False; //add_entry = (prefix_matches); } if (add_entry) { if (notation->GetEntry()) { Check_Pointer(notation->GetEntry()); } namelist->AddEntry(name, (void *)notation->GetEntry()); } notation = notation->nextNotation; } return namelist; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // NameList* NotationFile::MakePageList(const char *pagename_prefix) { Check(this); //do not check pagename_prefix here const char *name_prefix = pagename_prefix?pagename_prefix:"\0"; Check_Pointer(name_prefix); const int length = strlen(name_prefix); NameList *namelist; NotePage *notepage; const char *name; Logical prefix_matches, add_page; //----------------------------------------------------- // return namelist of matching pagenames and notepages //----------------------------------------------------- namelist = new NameList; //do not register namelist notepage = firstNotePage; while (notepage) { Check(notepage); name = notepage->GetName(); if (name) { Check_Pointer(name); if (operationModes&IgnorePageCaseMode) { prefix_matches = (!strnicmp(name, name_prefix, length)); } else { prefix_matches = (!strncmp(name, name_prefix, length)); } } else { prefix_matches = (pagename_prefix == NULL); } if (operationModes&CleanPageListMode) { add_page = (notepage->cleanPage && prefix_matches); } else if (name) { add_page = (prefix_matches); } else if (operationModes&SkipBlanksListMode) { add_page = False; } else { //------------------------------------------------------ // HACK: NameList::AddEntry() should accept name==NULL //------------------------------------------------------ add_page = False; //add_page = (pagename_prefix==NULL); } if (add_page) { namelist->AddEntry(name, (void *)notepage); } notepage = notepage->nextNotePage; } return namelist; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // AlphaNameList* NotationFile::MakeAlphaEntryList( const char *pagename, const char *entryname_prefix ) { Check(this); Check_Pointer(pagename); //do not check entryname_prefix here NotePage *notepage; //------------------------------------------------------- // return alphanamelist of matching entries and contents //------------------------------------------------------- if (FindNotePage(pagename, ¬epage)) { return MakeAlphaEntryList(notepage, entryname_prefix); } return NULL; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // AlphaNameList* NotationFile::MakeAlphaEntryList( NotePage *notepage, const char *entryname_prefix ) { Check(this); Check(notepage); //do not check entryname_prefix here const char *name_prefix = entryname_prefix?entryname_prefix:"\0"; Check_Pointer(name_prefix); const int length = strlen(name_prefix); AlphaNameList *namelist; Notation *notation; const char *name; Logical prefix_matches, add_entry; //------------------------------------------------------- // return alphanamelist of matching entries and contents //------------------------------------------------------- namelist = new AlphaNameList; //do not register namelist notation = notepage->firstNotation; while (notation) { Check(notation); name = notation->GetName(); if (name) { Check_Pointer(name); if (operationModes&IgnoreEntryCaseMode) { prefix_matches = (!strnicmp(name, name_prefix, length)); } else { prefix_matches = (!strncmp(name, name_prefix, length)); } } else { prefix_matches = (entryname_prefix == NULL); } if (operationModes&CleanEntryListMode) { add_entry = (notation->cleanNotation && prefix_matches); } else if (name) { add_entry = (prefix_matches); } else if (operationModes&SkipBlanksListMode) { add_entry = False; } else { //------------------------------------------------------ // HACK: NameList::AddEntry() should accept name==NULL //------------------------------------------------------ add_entry = False; //add_entry = (entryname_prefix==NULL); } if (add_entry) { if (notation->GetEntry()) { Check_Pointer(notation->GetEntry()); } namelist->AddEntry(name, (void *)notation->GetEntry()); } notation = notation->nextNotation; } return namelist; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // AlphaNameList* NotationFile::MakeAlphaPageList(const char *pagename_prefix) { Check(this); //do not check pagename_prefix here const char *name_prefix = pagename_prefix?pagename_prefix:"\0"; Check_Pointer(name_prefix); const int length = strlen(name_prefix); AlphaNameList *namelist; NotePage *notepage; const char *name; Logical prefix_matches, add_page; //---------------------------------------------------------- // return alphanamelist of matching pagenames and notepages //---------------------------------------------------------- namelist = new AlphaNameList; //do not register namelist notepage = firstNotePage; while (notepage) { Check(notepage); name = notepage->GetName(); if (name) { Check_Pointer(name); if (operationModes&IgnorePageCaseMode) { prefix_matches = (!strnicmp(name, name_prefix, length)); } else { prefix_matches = (!strncmp(name, name_prefix, length)); } } else { prefix_matches = (pagename_prefix == NULL); } if (operationModes&CleanPageListMode) { add_page = (notepage->cleanPage && prefix_matches); } else if (name) { add_page = (prefix_matches); } else if (operationModes&SkipBlanksListMode) { add_page = False; } else { //------------------------------------------------------ // HACK: NameList::AddEntry() should accept name==NULL //------------------------------------------------------ add_page = False; //add_page = (pagename_prefix==NULL); } if (add_page) { namelist->AddEntry(name, (void *)notepage); } notepage = notepage->nextNotePage; } return namelist; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void NotationFile::DeleteEntry( const char *pagename, const char *entryname ) { Check(this); Check_Pointer(pagename); Check_Pointer(entryname); NotePage *notepage; //--------------------------- // if found, delete Notation //--------------------------- if (FindNotePage(pagename, ¬epage)) { Check(notepage); SetDirty(); notepage->DeleteNote(entryname); } return; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void NotationFile::DeletePage(const char *pagename) { Check(this); Check_Pointer(pagename); NotePage *notepage, *prev; //---------------------------- // if found, delete Note_Page //---------------------------- if (FindNotePage(pagename, ¬epage, &prev)) { DeletePage(notepage, prev); } return; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void NotationFile::ReadFile(const char *filename) { Check(this); Check_Pointer(filename); std::ifstream notefile(filename); char buffer[512]; Logical was_empty = IsEmpty(); //------------------------------- // store first notation filename //------------------------------- if (!fileName) { fileName = new char[strlen(filename) + 1]; Register_Pointer(fileName); strcpy(fileName, filename); } //-------------------- // read notation file //-------------------- if (notefile) { //Dump( "--- read notation file ---" ); while (notefile.getline(buffer, sizeof(buffer))) { //------------------------------ // process line of NotationFile //------------------------------ Read(buffer); } notefile.close(); Read(NULL); // (reset static variable) //Dump( "--- end ---" ); } if (was_empty) { dirtyFlag = False; } return; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void NotationFile::ReadText( char *start, long length ) { Check(this); Check_Pointer(start); char *stop, *buffer; Logical was_empty = IsEmpty(); //-------------------------------- // read notation file from memory //-------------------------------- stop = start + length; while (start < stop) { //--------------------------------------------------------- // this must preceed Read() which does not preserve buffer //--------------------------------------------------------- buffer = start; start = strchr(buffer, '\0') + 1; //------------------------------ // process line of NotationFile //------------------------------ Read(buffer); } Read(NULL); // (reset static variable) if (was_empty) { dirtyFlag = False; } return; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical NotationFile::WriteFile(const char *filename) { Check(this); //do not check filename std::ofstream output; if (filename && *filename) { Check_Pointer(filename); output.open(filename); } else if (fileName && *fileName) { Check_Pointer(fileName); output.open(fileName); } else { return False; // you tried to WriteFile with no default fileName! } if (output.is_open()) { Write(output); output.close(); if (filename && *filename) { if (fileName) { Unregister_Pointer(fileName); delete fileName; } fileName = new char[strlen(filename) + 1]; Register_Pointer(fileName); strcpy(fileName, filename); } dirtyFlag = False; return True; } return False; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // long NotationFile::SizeOfText() { Check(this); std::ofstream dummy; return Write(dummy, Size_Only); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // long NotationFile::WriteText( char *buffer, long size ) { Check(this); Check_Pointer(buffer); Verify( size >= 0 ); std::ostrstream output(buffer, size); long actual_size; if ((actual_size = Write(output, Text_Memory)) <= size) { dirtyFlag = False; return actual_size; } return -1L; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void NotationFile::Abort() { Check(this); dirtyFlag = False; this->~NotationFile(); //this->NotationFile(); //does not compile! *this = NotationFile(); Check(this); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void NotationFile::DeleteStandardPages() { Check(this); NotePage *prev = NULL, *notepage = firstNotePage, *next; const char *name; while (notepage) { Check(notepage); next = notepage->nextNotePage; name = notepage->pageName; if (*name != '_' && strcmp(name, "LAB_ONLY") != 0) { DeletePage(notepage, prev); } else { prev = notepage; } notepage = next; } return; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void NotationFile::MarkLabOnly() { Check(this); if (!IsMarkedLabOnly()) { SetPage("LAB_ONLY","\t// this file has not been approved for release"); AppendEntry("LAB_ONLY", NULL, (char *)NULL); // (blank line) } return; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void NotationFile::AppendNotePage(NotePage *notepage) { Check(this); Check(notepage); //--------------------------------- // append NotePage to NotationFile //--------------------------------- if (!lastNotePage) { firstNotePage = notepage; } else { Check(lastNotePage); lastNotePage->nextNotePage = notepage; } lastNotePage = notepage; lastNotePage->nextNotePage = NULL; if (notepage->cleanPage) { ++cleanPageCount; } ++pageCount; return; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical NotationFile::FindNotePage( const char *pagename, NotePage **notepage ) { //----------------------------------------------------------------- // HACK: This routine should be changed to support NULL pagename. //----------------------------------------------------------------- Check(this); Check_Pointer(pagename); Check_Pointer(notepage); //------------------------------------------- // check to see if same as previous NotePage //------------------------------------------- if (saveNotePage && saveNotePage->pageName && ((operationModes&IgnorePageCaseMode && !stricmp(saveNotePage->pageName, pagename)) || (!(operationModes&IgnorePageCaseMode) && !strcmp(saveNotePage->pageName, pagename)))) { Check(saveNotePage); *notepage = saveNotePage; return True; } else { //------------------------------ // search for matching NotePage //------------------------------ NotePage *notepg = firstNotePage; while (notepg) { Check(notepg); if (notepg->pageName && ((operationModes&IgnorePageCaseMode && !stricmp(notepg->pageName, pagename)) || (!(operationModes&IgnorePageCaseMode) && !strcmp(notepg->pageName, pagename)))) { *notepage = saveNotePage = notepg; return True; } notepg = notepg->nextNotePage; } } //----------- // not found //----------- *notepage = NULL; return False; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical NotationFile::FindNotePage( const char *pagename, NotePage **notepage, NotePage **prevpage ) { //----------------------------------------------------------------- // HACK: This routine should be changed to support NULL pagename. //----------------------------------------------------------------- Check(this); Check_Pointer(pagename); Check_Pointer(notepage); Check_Pointer(prevpage); NotePage *notepg = firstNotePage, *prev = NULL; //------------------------------ // search for matching NotePage //------------------------------ while (notepg) { Check(notepg); if (notepg->pageName && ((operationModes&IgnorePageCaseMode && !stricmp(notepg->pageName, pagename)) || (!(operationModes&IgnorePageCaseMode) && !strcmp(notepg->pageName, pagename)))) { *notepage = notepg; *prevpage = prev; return True; } prev = notepg; notepg = notepg->nextNotePage; } //----------- // not found //----------- *notepage = *prevpage = NULL; return False; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void NotationFile::DeletePage( NotePage *notepage, NotePage *prev ) { Check(this); Check(notepage); //do not check prev here //--------------------------- // remove & delete Note_Page //--------------------------- SetDirty(); if (prev) { Check(prev); prev->nextNotePage = notepage->nextNotePage; } else { firstNotePage = notepage->nextNotePage; } if (lastNotePage == notepage) { lastNotePage = prev; } if (notepage == saveNotePage) { saveNotePage = NULL; } if (notepage->cleanPage) { --cleanPageCount; } --pageCount; Unregister_Object(notepage); delete notepage; return; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void NotationFile::Read(char *buffer) { Check(this); //do not check buffer here static NotePage *notepage = NULL; Notation *notation; char *token, *entry, *p; Logical // blank_line, comment_line; if (!buffer) { //------------------------------ // reset notepage for next read //------------------------------ notepage = NULL; return; } Check_Pointer(buffer); //-------------------------------- // find first non-blank character //-------------------------------- p = buffer; while (*p == ' ' || *p == '\t') { ++p; } //-------------------- // begin new NotePage //-------------------- if (*p == '[') { token = p+1; if ((p = strchr(token, ']')) != NULL) { *p = '\0'; ++p; } notepage = AppendPage(token, p); // std::cerr << "[" << notepage->GetName() << "]" << std::endl; // TESTING! // notepage->Write( std::cerr ); // TESTING! return; } //--------------------------------- // detect blank lines and comments //--------------------------------- // blank_line = (*p == '\0'); comment_line = Comment_Line(p); //--------------- // read Notation //--------------- token = p; if ((p = strchr(token, '=')) != NULL) { *p = '\0'; entry = ++p; // if (*entry == '\0') // { // entry = NULL; // } } else { entry = NULL; } if (*token == '\0') { token = NULL; } //------------------------ // remove trailing blanks //------------------------ if (token && !comment_line) { p = strchr(token, '\0') - 1; while (*p == ' ' || *p == '\t') { *p = '\0'; if (--p < token) { break; } } } if (!notepage) { notepage = new NotePage(this); Register_Object(notepage); AppendNotePage(notepage); } notation = new Notation; Register_Object(notation); notation->SetName(token, &(notepage->cleanNotationCount)); notation->SetEntry(entry); notepage->AppendNote(notation); // std::cerr << token << "=" << entry << std::endl; // TESTING! // notation->Write( std::cerr ); // TESTING! // notepage->Write( std::cerr ); // TESTING! return; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // long NotationFile::Write( std::ostream &stream, WriteMode mode ) { Check(this); NotePage *notepg = firstNotePage; long size = 0; while (notepg) { Check(notepg); size += notepg->WriteNote(stream, mode); notepg = notepg->nextNotePage; } return size; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical NotationFile::TestInstance() const { //do not Check(this); if (fileName) { Check_Pointer(fileName); } if (firstNotePage) { Check_Signature(firstNotePage); } if (lastNotePage) { Check_Signature(lastNotePage); } if (saveNotePage) { Check_Signature(saveNotePage); } return True; } //############################################################################# //############## NotationFile::Notation ################################# //############################################################################# NotationFile__Notation::~NotationFile__Notation() { Check(this); if (notationName) { Check_Pointer(notationName); Unregister_Pointer(notationName); delete notationName; } if (notationEntry) { Check_Pointer(notationEntry); Unregister_Pointer(notationEntry); delete notationEntry; } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void NotationFile::Notation::SetName( const char *entryname, long *clean_notation_count ) { Check(this); //do not check entryname here Check_Pointer(clean_notation_count); if (notationName) { if (cleanNotation) { cleanNotation = False; --(*clean_notation_count); } Check_Pointer(notationName); Unregister_Pointer(notationName); delete notationName; } if (entryname) // (do not add "&& *entryname") { Check_Pointer(entryname); notationName = new char[strlen(entryname) + 1]; Register_Pointer(notationName); strcpy(notationName, entryname); cleanNotation = (*notationName && !Comment_Line(notationName)); } else { notationName = NULL; } return; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void NotationFile::Notation::SetEntry(const char *contents) { Check(this); //do not check contents here if (notationEntry) { Check_Pointer(notationEntry); Unregister_Pointer(notationEntry); delete notationEntry; } if (contents) // (do not add "&& *contents") { Check_Pointer(contents); notationEntry = new char[strlen(contents) + 1]; Register_Pointer(notationEntry); strcpy(notationEntry, contents); } else { notationEntry = NULL; } return; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // long NotationFile::Notation::WriteNotation( std::ostream &stream, NotationFile::WriteMode mode ) const { Check(this); // Logical // comment_line = True; long size = 0; if (notationName) { Check_Pointer(notationName); if (mode) { stream << notationName; } if (mode != NotationFile::Disk_File) { size += strlen(notationName); } // comment_line = Comment_Line(notationName); // if (!comment_line) // { // stream << "="; // } } if (notationEntry) { Check_Pointer(notationEntry); // if (comment_line) // { // stream << "="; // } if (mode) { stream << "=" << notationEntry; } if (mode != NotationFile::Disk_File) { size += strlen(notationEntry) + 1; } } if (mode == NotationFile::Disk_File) { stream << std::endl; } else if (mode) { stream << std::ends; } if (mode != NotationFile::Disk_File) { size += 1; } return size; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical NotationFile::Notation::TestInstance() const { //do not Check(this); if (nextNotation) { Check_Signature(nextNotation); } if (notationName) { Check_Pointer(notationName); } if (notationEntry) { Check_Pointer(notationEntry); } return True; } //############################################################################# //############## NotationFile::NotePage ################################# //############################################################################# NotationFile__NotePage::NotationFile__NotePage(NotationFile *notation_file) { Check_Pointer(this); Check(notation_file); notationFile = notation_file; nextNotePage = NULL; firstNotation = lastNotation = NULL; notationCount = cleanNotationCount = 0; pageName = pageComment = NULL; cleanPage = False; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // NotationFile__NotePage::~NotationFile__NotePage() { Check(this); NotationFile::Notation *notation = firstNotation; while (notation) { Check(notation); firstNotation = notation->nextNotation; Unregister_Object(notation); delete notation; notation = firstNotation; } if (pageName) { Check_Pointer(pageName); Unregister_Pointer(pageName); delete pageName; } if (pageComment) { Check_Pointer(pageComment); Unregister_Pointer(pageComment); delete pageComment; } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void NotationFile::NotePage::SetName( const char *pagename, long *clean_page_count ) { Check(this); //do not check pagename here Check_Pointer(clean_page_count); if (pageName) { if (cleanPage) { cleanPage = False; --(*clean_page_count); } Check_Pointer(pageName); Unregister_Pointer(pageName); delete pageName; } if (pagename) // (do not add "&& *pagename") { Check_Pointer(pagename); pageName = new char[strlen(pagename) + 1]; Register_Pointer(pageName); strcpy(pageName, pagename); cleanPage = (*pageName && (*pageName != '!') && strcmp(pageName, "LAB_ONLY")); } else { pageName = NULL; } return; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void NotationFile::NotePage::SetComment(const char *comment) { Check(this); //do not check comment here if (pageComment) { Check_Pointer(pageComment); Unregister_Pointer(pageComment); delete pageComment; } if (comment && *comment) { Check_Pointer(comment); pageComment = new char[strlen(comment) + 1]; Register_Pointer(pageComment); strcpy(pageComment, comment); } else { pageComment = NULL; } return; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void NotationFile::NotePage::AppendNote(NotationFile::Notation *note) { Check(this); Check(note); //----------------------------- // append Notation to NotePage //----------------------------- if (!lastNotation) { firstNotation = note; } else { Check(lastNotation); lastNotation->nextNotation = note; } lastNotation = note; lastNotation->nextNotation = NULL; if (note->cleanNotation) { ++cleanNotationCount; } ++notationCount; return; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical NotationFile::NotePage::FindNote( const char *entryname, NotationFile::Notation **note ) { NotationFile::Notation *prev; return FindNote(entryname, note, &prev); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical NotationFile::NotePage::FindNote( const char *entryname, NotationFile::Notation **note, NotationFile::Notation **prev ) { //------------------------------------------------------------------ // HACK: This routine should be changed to support NULL entryname. //------------------------------------------------------------------ Check(this); Check_Pointer(entryname); Check_Pointer(note); Check_Pointer(prev); NotationFile::Notation *notation = firstNotation, *previous = NULL; //------------------------------ // search for matching Notation //------------------------------ while (notation) { Check(notation); if (notation->notationName && ((notationFile->operationModes&NotationFile::IgnoreEntryCaseMode && !stricmp(notation->notationName, entryname)) || (!(notationFile->operationModes&NotationFile::IgnoreEntryCaseMode) && !strcmp(notation->notationName, entryname)))) { *note = notation; *prev = previous; return True; } previous = notation; notation = notation->nextNotation; } //----------- // not found //----------- *note = *prev = NULL; return False; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void NotationFile::NotePage::UpdateNote(NotationFile::Notation *note) { Check(this); Check(note); NotationFile::Notation *notation, *prev; //------------------------------ // search for matching Notation //------------------------------ if (FindNote(note->notationName, ¬ation, &prev)) { Check(notation); //------------------ // replace Notation //------------------ if (prev) { Check(prev); prev->nextNotation = note; } else { firstNotation = note; } if ((note->nextNotation = notation->nextNotation) == NULL) { lastNotation = note; } Unregister_Object(notation); delete notation; } else { //----------------- // append Notation //----------------- AppendNote(note); } return; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void NotationFile::NotePage::DeleteNote(const char *entryname) { Check(this); Check_Pointer(entryname); NotationFile::Notation *notation, *prev; //------------------------------ // search for matching Notation //------------------------------ if (FindNote(entryname, ¬ation, &prev)) { Check(notation); //-------------------------- // remove & delete Notation //-------------------------- if (prev) { Check(prev); prev->nextNotation = notation->nextNotation; } else { firstNotation = notation->nextNotation; } if (lastNotation == notation) { lastNotation = prev; } if (notation->cleanNotation) { --cleanNotationCount; } --notationCount; Unregister_Object(notation); delete notation; } return; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // long NotationFile::NotePage::WriteNote( std::ostream &stream, NotationFile::WriteMode mode ) const { Check(this); NotationFile::Notation *notation = firstNotation; long size = 0; if (pageName) { Check_Pointer(pageName); if (mode) { stream << "[" << pageName << "]"; } if (mode != NotationFile::Disk_File) { size += strlen(pageName) + 2; } } if (pageComment) { Check_Pointer(pageComment); if (mode) { stream << pageComment; } if (mode != NotationFile::Disk_File) { size += strlen(pageComment); } } if (pageName || pageComment) { if (mode == NotationFile::Disk_File) { stream << std::endl; } else if (mode) { stream << std::ends; } if (mode != NotationFile::Disk_File) { size += 1; } } while (notation) { Check(notation); size += notation->WriteNotation(stream, mode); notation = notation->nextNotation; } return size; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical NotationFile::NotePage::TestInstance() const { //do not Check(this); if (nextNotePage) { Check_Signature(nextNotePage); } if (firstNotation) { Check_Signature(firstNotation); } if (lastNotation) { Check_Signature(lastNotation); } if (pageName) { Check_Pointer(pageName); } return True; } //############################################################################# //############## TestClass() ############################################ //############################################################################# #if defined(TEST_CLASS) #include "notation.tcp" #endif //===========================================================================//