bool queen::isValidMove(int errorCode, string fromFR, string toFR, map<string, piece*> *board) { if (fromFR == toFR) { if(errorCode==1) { cout << "\033[0;31mmoving to same square!! na na na, skipping your move wont work! \033[0m\n"; } return false; } if (!(sameFile (fromFR, toFR) || sameRank (fromFR, toFR) || sameDiagonal (fromFR, toFR))) { if(errorCode==1) { cout << "\033[0;31millegal move pattern for Queen \033[0m\n"; } return false; } if ((sameFile (fromFR, toFR) && !noVerticalObstr (fromFR, toFR, board)) || (sameRank (fromFR, toFR) && !noHorizontalObstr (fromFR, toFR, board)) || (sameDiagonal (fromFR, toFR) && !noDiagonalObstr (fromFR, toFR, board))) { if(errorCode==1) { cout <<"\033[0;31mthere is an obstruction on your way! \033[0m\n"; } return false; } if (sameColourAtToFR (toFR, board)) { if(errorCode==1) { cout << "\033[0;31mthere is a piece of your colour! \033[0m\n"; } return false; } return true; //no error }
// Called by the root thread to actually save the state and write the file. void SaveRequest::Perform() { // Check that we aren't overwriting our own parent. for (unsigned q = 0; q < newHierarchy-1; q++) { if (sameFile(hierarchyTable[q]->fileName, fileName)) { errorMessage = "File being saved is used as a parent of this file"; errCode = 0; return; } } SaveStateExport exports; // Open the file. This could quite reasonably fail if the path is wrong. exports.exportFile = _tfopen(fileName, _T("wb")); if (exports.exportFile == NULL) { errorMessage = "Cannot open save file"; errCode = errno; return; } // Scan over the permanent mutable area copying all reachable data that is // not in a lower hierarchy into new permanent segments. CopyScan copyScan(newHierarchy); copyScan.initialise(false); bool success = true; try { for (unsigned i = 0; i < gMem.npSpaces; i++) { PermanentMemSpace *space = gMem.pSpaces[i]; if (space->isMutable && ! space->noOverwrite && ! space->byteOnly) copyScan.ScanAddressesInRegion(space->bottom, space->top); } } catch (MemoryException &) { success = false; } // Copy the areas into the export object. Make sufficient space for // the largest possible number of entries. exports.memTable = new memoryTableEntry[gMem.neSpaces+gMem.npSpaces+1]; exports.ioMemEntry = 0; // The IO vector. unsigned memTableCount = 0; MemSpace *ioSpace = gMem.IoSpace(); exports.memTable[0].mtAddr = ioSpace->bottom; exports.memTable[0].mtLength = (char*)ioSpace->top - (char*)ioSpace->bottom; exports.memTable[0].mtFlags = 0; exports.memTable[0].mtIndex = 0; memTableCount++; // Permanent spaces at higher level. These have to have entries although // only the mutable entries will be written. for (unsigned w = 0; w < gMem.npSpaces; w++) { PermanentMemSpace *space = gMem.pSpaces[w]; if (space->hierarchy < newHierarchy) { memoryTableEntry *entry = &exports.memTable[memTableCount++]; entry->mtAddr = space->bottom; entry->mtLength = (space->topPointer-space->bottom)*sizeof(PolyWord); entry->mtIndex = space->index; if (space->isMutable) { entry->mtFlags = MTF_WRITEABLE; if (space->noOverwrite) entry->mtFlags |= MTF_NO_OVERWRITE; if (space->byteOnly) entry->mtFlags |= MTF_BYTES; } else entry->mtFlags = MTF_EXECUTABLE; } } unsigned permanentEntries = memTableCount; // Remember where new entries start. // Newly created spaces. for (unsigned i = 0; i < gMem.neSpaces; i++) { memoryTableEntry *entry = &exports.memTable[memTableCount++]; PermanentMemSpace *space = gMem.eSpaces[i]; entry->mtAddr = space->bottom; entry->mtLength = (space->topPointer-space->bottom)*sizeof(PolyWord); entry->mtIndex = space->index; if (space->isMutable) { entry->mtFlags = MTF_WRITEABLE; if (space->noOverwrite) entry->mtFlags |= MTF_NO_OVERWRITE; if (space->byteOnly) entry->mtFlags |= MTF_BYTES; } else entry->mtFlags = MTF_EXECUTABLE; } exports.memTableEntries = memTableCount; exports.ioSpacing = IO_SPACING; // Update references to moved objects. SaveFixupAddress fixup; for (unsigned l = 0; l < gMem.nlSpaces; l++) { LocalMemSpace *space = gMem.lSpaces[l]; fixup.ScanAddressesInRegion(space->bottom, space->lowerAllocPtr); fixup.ScanAddressesInRegion(space->upperAllocPtr, space->top); } GCModules(&fixup); // Update the global memory space table. Old segments at the same level // or lower are removed. The new segments become permanent. // Try to promote the spaces even if we've had a failure because export // spaces are deleted in ~CopyScan and we may have already copied // some objects there. if (! gMem.PromoteExportSpaces(newHierarchy) || ! success) { errorMessage = "Out of Memory"; errCode = ENOMEM; return; } // Remove any deeper entries from the hierarchy table. while (hierarchyDepth > newHierarchy-1) { hierarchyDepth--; delete(hierarchyTable[hierarchyDepth]); hierarchyTable[hierarchyDepth] = 0; } // Write out the file header. SavedStateHeader saveHeader; memset(&saveHeader, 0, sizeof(saveHeader)); saveHeader.headerLength = sizeof(saveHeader); strncpy(saveHeader.headerSignature, SAVEDSTATESIGNATURE, sizeof(saveHeader.headerSignature)); saveHeader.headerVersion = SAVEDSTATEVERSION; saveHeader.segmentDescrLength = sizeof(SavedStateSegmentDescr); if (newHierarchy == 1) saveHeader.parentTimeStamp = exportTimeStamp; else { saveHeader.parentTimeStamp = hierarchyTable[newHierarchy-2]->timeStamp; saveHeader.parentNameEntry = sizeof(TCHAR); // Always the first entry. } saveHeader.timeStamp = time(NULL); saveHeader.segmentDescrCount = exports.memTableEntries; // One segment for each space. // Write out the header. fwrite(&saveHeader, sizeof(saveHeader), 1, exports.exportFile); // We need a segment header for each permanent area whether it is // actually in this file or not. SavedStateSegmentDescr *descrs = new SavedStateSegmentDescr [exports.memTableEntries]; for (unsigned j = 0; j < exports.memTableEntries; j++) { memoryTableEntry *entry = &exports.memTable[j]; memset(&descrs[j], 0, sizeof(SavedStateSegmentDescr)); descrs[j].relocationSize = sizeof(RelocationEntry); descrs[j].segmentIndex = (unsigned)entry->mtIndex; descrs[j].segmentSize = entry->mtLength; // Set this even if we don't write it. descrs[j].originalAddress = entry->mtAddr; if (entry->mtFlags & MTF_WRITEABLE) { descrs[j].segmentFlags |= SSF_WRITABLE; if (entry->mtFlags & MTF_NO_OVERWRITE) descrs[j].segmentFlags |= SSF_NOOVERWRITE; if (j < permanentEntries && (entry->mtFlags & MTF_NO_OVERWRITE) == 0) descrs[j].segmentFlags |= SSF_OVERWRITE; if (entry->mtFlags & MTF_BYTES) descrs[j].segmentFlags |= SSF_BYTES; } } // Write out temporarily. Will be overwritten at the end. saveHeader.segmentDescr = ftell(exports.exportFile); fwrite(descrs, sizeof(SavedStateSegmentDescr), exports.memTableEntries, exports.exportFile); // Write out the relocations and the data. for (unsigned k = 1 /* Not IO area */; k < exports.memTableEntries; k++) { memoryTableEntry *entry = &exports.memTable[k]; // Write out the contents if this is new or if it is a normal, overwritable // mutable area. if (k >= permanentEntries || (entry->mtFlags & (MTF_WRITEABLE|MTF_NO_OVERWRITE)) == MTF_WRITEABLE) { descrs[k].relocations = ftell(exports.exportFile); // Have to write this out. exports.relocationCount = 0; // Create the relocation table. char *start = (char*)entry->mtAddr; char *end = start + entry->mtLength; for (PolyWord *p = (PolyWord*)start; p < (PolyWord*)end; ) { p++; PolyObject *obj = (PolyObject*)p; POLYUNSIGNED length = obj->Length(); // Most relocations can be computed when the saved state is // loaded so we only write out the difficult ones: those that // occur within compiled code. // exports.relocateObject(obj); if (length != 0 && obj->IsCodeObject()) machineDependent->ScanConstantsWithinCode(obj, &exports); p += length; } descrs[k].relocationCount = exports.relocationCount; // Write out the data. descrs[k].segmentData = ftell(exports.exportFile); fwrite(entry->mtAddr, entry->mtLength, 1, exports.exportFile); } } // If this is a child we need to write a string table containing the parent name. if (newHierarchy > 1) { saveHeader.stringTable = ftell(exports.exportFile); _fputtc(0, exports.exportFile); // First byte of string table is zero _fputts(hierarchyTable[newHierarchy-2]->fileName, exports.exportFile); _fputtc(0, exports.exportFile); // A terminating null. saveHeader.stringTableSize = (_tcslen(hierarchyTable[newHierarchy-2]->fileName) + 2)*sizeof(TCHAR); } // Rewrite the header and the segment tables now they're complete. fseek(exports.exportFile, 0, SEEK_SET); fwrite(&saveHeader, sizeof(saveHeader), 1, exports.exportFile); fwrite(descrs, sizeof(SavedStateSegmentDescr), exports.memTableEntries, exports.exportFile); // Add an entry to the hierarchy table for this file. (void)AddHierarchyEntry(fileName, saveHeader.timeStamp); delete[](descrs); }
/* * CopyOneFile - copy one file to another */ void CopyOneFile( char *dest, char *src ) { struct stat stat_s,stat_d; int i; unsigned srcattr; /* * first, check if source exists */ if( stat( src,&stat_s ) == - 1 ) { DropPrintALine("file \"%s\" not found.",src ); return; } _dos_getfileattr( src, &srcattr ); /* * check if the archive bit is set; if not, go back */ if( aflag ) { if( !(srcattr & _A_ARCH) ) { return; } } /* * if destination exists, make sure we can overwrite it */ if( stat( dest,&stat_d ) != -1 ) { #if !( defined( __OS2__ ) && defined( __386__ ) ) if( sameFile( dest, &stat_d, src, &stat_s ) ) { DropPrintALine( "%s and %s the same file, copy failed",src,dest ); return; } #endif if( !(stat_d.st_mode & S_IWRITE) ) { if( !fflag ) { DropPrintALine( "destination file %s is read only - use cp -f", dest); return; } else { chmod( dest, S_IWRITE | S_IREAD ); } } if( iflag ) { PrintALine( "overwrite %s (y\\n)", dest ); i = 0; while( i != 'y' && i != 'n' ) { i=getch(); } DropALine(); if( i=='n' ) { return; } } } /* * copy the file, and if it works, reset archive flag * of source (if needed) */ if( !GrabFile( src, &stat_s, dest, srcattr ) ) { return; } if( aflag ) { _dos_setfileattr( src, srcattr & (~_A_ARCH) ); } } /* CopyOneFile */