filename_t* filename_t::parentDirectory (void) { ___CBTPUSH; char* name; int namelen; int* indices; filename_t* result; if (isRoot ()) { /* / */ result = this; reserve (); } else if (isReflexive ()) { /* . */ namelen = 2; allocateNameAndIndices (&name, namelen, &indices, 1); strcpy (name, ".."); indices[0] = namelen; result = new filename_t (name, indices, 1, 1); } else if (m_indexCount > 1) { /* /a/b, a/b, ../a */ namelen = m_indices[m_indexCount - 2]; allocateNameAndIndices (&name, namelen, &indices, m_indexCount - 1); SUBSTRING (name, m_name, namelen); memcpy (indices, m_indices, sizeof (int) * (m_indexCount - 1)); result = new filename_t (name, indices, m_indexCount - 1, m_parentDirs); } else if (isAbsolute ()) { /* /a */ namelen = 1; allocateNameAndIndices (&name, namelen, &indices, 1); strcpy (name, "/"); indices[0] = namelen; result = new filename_t (name, indices, 1, 0); } else if (m_parentDirs > 0) { /* .. */ namelen = m_indices[0] + 3; allocateNameAndIndices (&name, namelen, &indices, 1); stpcpy (stpcpy (name, m_name), "/.."); indices[0] = namelen; result = new filename_t (name, indices, 1, m_parentDirs + 1); } else { /* a */ namelen = 1; allocateNameAndIndices (&name, namelen, &indices, 1); strcpy (name, "."); indices[0] = namelen; result = new filename_t (name, indices, 1, 0); } ___CBTPOP; return result; }
filename_t* filename_t::concat (filename_t* other) { ___CBTPUSH; char* name; int* indices; filename_t* result; if (other->isAbsolute ()) { result = NULL; } else if (other->isReflexive ()) { result = this; reserve (); } else if (isReflexive ()) { result = other; other->reserve (); } else if (other->m_parentDirs == 0) { const int otherLen = other->m_indices[other->m_indexCount - 1]; if (isRoot ()) { allocateNameAndIndices (&name, 1 + otherLen, &indices, other->m_indexCount); memcpy (mempcpy (name, "/", 1), other->m_name, otherLen + 1); addIndices (indices, other->m_indices, other->m_indexCount, 1); result = new filename_t (name, indices, other->m_indexCount, m_parentDirs); } else { const int thisLen = m_indices[m_indexCount - 1]; allocateNameAndIndices (&name, thisLen + otherLen + 1, &indices, m_indexCount + other->m_indexCount); memcpy (mempcpy (mempcpy (name, m_name, thisLen), "/", 1), other->m_name, otherLen + 1); memcpy (indices, m_indices, sizeof (int) * m_indexCount); addIndices (indices + m_indexCount, other->m_indices, other->m_indexCount, thisLen + 1); result = new filename_t (name, indices, m_indexCount + other->m_indexCount, m_parentDirs); } } else if (m_indexCount - (m_parentDirs != 0) > other->m_parentDirs) { const int otherIndexCount = other->m_indexCount - 1; const int thisIndexCount = m_indexCount - other->m_parentDirs; const int thisLen = m_indices[thisIndexCount - 1]; const int otherLen = other->m_indices[otherIndexCount] - other->m_indices[0]; allocateNameAndIndices (&name, thisLen + otherLen, &indices, thisIndexCount + otherIndexCount); memcpy (mempcpy (name, m_name, thisLen), other->m_name + other->m_indices[0], otherLen + 1); memcpy (indices, m_indices, sizeof (int) * thisIndexCount); addIndices (indices + thisIndexCount, other->m_indices + 1, otherIndexCount, thisLen - other->m_indices[0]); result = new filename_t (name, indices, thisIndexCount + otherIndexCount, m_parentDirs); } else if (isAbsolute ()) { if (other->m_indexCount > 1) { const int otherIndexCount = other->m_indexCount - 1; const int otherLen = other->m_indices[otherIndexCount] - other->m_indices[0]; allocateNameAndIndices (&name, otherLen, &indices, otherIndexCount); memcpy (name, other->m_name + other->m_indices[0], otherLen + 1); addIndices (indices, other->m_indices + 1, otherIndexCount, -other->m_indices[0]); result = new filename_t (name, indices, otherIndexCount, 0); } else { allocateNameAndIndices (&name, 1, &indices, 1); memcpy (name, "/", 2); indices[0] = 1; result = new filename_t (name, indices, 1, 0); } } else if (m_parentDirs == 0) { const int parentDirs = other->m_parentDirs - m_indexCount; if (parentDirs > 0 || other->m_indexCount > 1) { const int indexCount = other->m_indexCount - (parentDirs == 0); const int nameOffset = other->m_indices[0] + 1 - 3 * parentDirs; const int nameLen = other->m_indices[other->m_indexCount - 1] - nameOffset; allocateNameAndIndices (&name, nameLen, &indices, indexCount); memcpy (name, other->m_name + nameOffset, nameLen + 1); addIndices (indices, other->m_indices + (parentDirs == 0), indexCount, -nameOffset); result = new filename_t (name, indices, indexCount, parentDirs); } else { allocateNameAndIndices (&name, 1, &indices, 1); memcpy (name, ".", 2); indices[0] = 1; result = new filename_t (name, indices, 1, 0); } } else { const int extraParentDirs = other->m_parentDirs - m_indexCount + 1; if (extraParentDirs > 0 || other->m_indexCount > 1) { const int indexCount = other->m_indexCount; const int nameOffset = other->m_indices[0] + 1 - 3 * extraParentDirs; const int nameLen = other->m_indices[other->m_indexCount - 1] - nameOffset; allocateNameAndIndices (&name, nameLen + 3 * m_parentDirs, &indices, indexCount); memcpy (mempcpy (name, m_name, 3 * m_parentDirs), other->m_name + nameOffset, nameLen + 1); name[3 * m_parentDirs - 1] = '/'; addIndices (indices, other->m_indices, indexCount, 3 * m_parentDirs - nameOffset); result = new filename_t (name, indices, indexCount, m_parentDirs + extraParentDirs); } else { allocateNameAndIndices (&name, 3 * m_parentDirs - 1, &indices, 1); mempcpy (name, m_name, 3 * m_parentDirs - 1); indices[0] = 3 * m_parentDirs - 1; name[3 * m_parentDirs - 1] = 0; result = new filename_t (name, indices, 1, m_parentDirs); } } ___CBTPOP; return result; }
bool BinaryRelation::isEquivalence() const { return(isReflexive() && isSymmetric() && isTransitive()); }