void Archive::dump() const { printf("Archive data %p len %zu, firstRegularData %p\n", data.data(), data.size(), firstRegularData); printf("Symbol table %p, len %u\n", symbolTable.data, symbolTable.len); printf("string table %p, len %u\n", stringTable.data, stringTable.len); const uint8_t* buf = symbolTable.data; if (!buf) { for (auto c = child_begin(), e = child_end(); c != e; ++c) { printf("Child %p, len %u, name %s, size %u\n", c->data, c->len, c->getName().c_str(), c->getSize()); } return; } uint32_t symbolCount = read32be(buf); printf("Symbol count %u\n", symbolCount); buf += sizeof(uint32_t) + (symbolCount * sizeof(uint32_t)); uint32_t string_start_offset = buf - symbolTable.data; Symbol sym = {0, string_start_offset}; while (sym.symbolIndex != symbolCount) { printf("Symbol %u, offset %u\n", sym.symbolIndex, sym.stringIndex); // get the member uint32_t offset = read32be(symbolTable.data + sym.symbolIndex * 4); auto* loc = (const uint8_t*)&data[offset]; child_iterator it; it.child = Child(this, loc, &it.error); printf("Child %p, len %u\n", it.child.data, it.child.len); } }
void stmt::destroyChildren(pParseContext &C) { for (child_iterator i = child_begin(), e = child_end(); i != e; ) { // NOTE: it's valid for some children to be NULL if (stmt* child = *i++) child->destroy(C); } }
bool ParagraphComment::isWhitespaceNoCache() const { for (child_iterator I = child_begin(), E = child_end(); I != E; ++I) { if (const TextComment *TC = dyn_cast<TextComment>(*I)) { if (!TC->isWhitespace()) return false; } else return false; } return true; }
Archive::Archive(Buffer& b, bool& error) : data(b), symbolTable({nullptr, 0}), stringTable({nullptr, 0}), firstRegularData(nullptr) { error = false; if (data.size() < strlen(magic) || memcmp(data.data(), magic, strlen(magic))) { error = true; return; } // We require GNU format archives. So the first member may be named "/" and it // points to the symbol table. The next member may optionally be "//" and // point to a string table if a filename is too large to fit in the 16-char // name field of the header. child_iterator it = child_begin(false); if (it.hasError()) { error = true; return; } child_iterator end = child_end(); if (it == end) return; // Empty archive. const Child* c = &*it; auto increment = [&]() { ++it; error = it.hasError(); if (error) return true; c = &*it; return false; }; std::string name = c->getRawName(); if (name == "/") { symbolTable = c->getBuffer(); if (increment() || it == end) return; name = c->getRawName(); } if (name == "//") { stringTable = c->getBuffer(); if (increment() || it == end) return; setFirstRegular(*c); return; } if (name[0] != '/') { setFirstRegular(*c); return; } // Not a GNU archive. error = true; }
Archive::child_iterator Archive::child_begin(bool SkipInternal) const { if (data.size() == 0) return child_end(); if (SkipInternal) { child_iterator it; it.child = Child(this, firstRegularData, &it.error); return it; } auto* loc = (const uint8_t*)data.data() + strlen(magic); child_iterator it; it.child = Child(this, loc, &it.error); return it; }
// Return path when appended to parent will resolve to same as child path relativize(path parent, path child){ parent = canonical(parent); child = canonical(child); // Find common base path::const_iterator parent_iter(parent.begin()), child_iter(child.begin()); path::const_iterator child_end(child.end()), parent_end(parent.end()); while(parent_iter != parent_end && child_iter != child_end && *parent_iter == *child_iter) ++parent_iter, ++child_iter; // Navigate backwards in directory to reach previously found base path ret; while(parent_iter != parent_end) { if( (*parent_iter) != "." ) ret /= ".."; ++parent_iter; } // Now navigate down the directory branch ret.append(child_iter, child.end()); return ret; }
void EventDispatcherBase<TDerived>::markDescendantsForEntry() { for (auto state = derived().begin(); state != derived().end(); ++state) { if (!(state->m_flags & state_type::InEnterSet)) { state.skipChildren(); continue; } if (state->isCompound()) { // Exactly one state of a compound state has to be marked for entry. bool childMarked = false; for (auto child = state.child_begin(); child != state.child_end(); ++child) { if (child->m_flags & state_type::InEnterSet) { childMarked = true; break; } } if (!childMarked) { if (state->m_flags & (state_type::ShallowHistory | state_type::DeepHistory)) { using history_state_type = ShallowHistoryState<TDerived>; history_state_type* historyState = static_cast<history_state_type*>(&*state); if (historyState->m_latestActiveChild) { historyState->m_latestActiveChild->m_flags |= state_type::InEnterSet; continue; } } if (state_type* initialState = state->initialState()) { do { initialState->m_flags |= state_type::InEnterSet; initialState = initialState->parent(); } while (initialState != &*state); } else { state->m_children->m_flags |= state_type::InEnterSet; } } } else if (state->isParallel()) { // All child states of a parallel state have to be marked for entry. for (auto child = state.child_begin(); child != state.child_end(); ++child) { child->m_flags |= state_type::InEnterSet; } } } }
/** ** Call this to end the coprocess. Returns the exit code of the child. **/ int child_close(CHILD *handle) { int retstat = 1, done; /** ** This lets us close the most-recently-used coprocess gracefully without ** having a handle. Useful from registered signal/atexit handlers. **/ if (handle == NULL) handle = mru_handle; if ((mru_handle = handle) == NULL) return -1; /** If there's no child running, we're done **/ if (handle->cph_pid == 0) return 0; /** ... likewise for the stderr **/ (void) child_end(handle, CP_SHOW_ERR); /** provide a high-level dbg msg */ _dbg(F,L,2, "ending child %s (pid=%d) ...", handle->cph_cmd,handle->cph_pid); /** Optionally, tell the child explicitly to give up the ghost */ if (handle->cph_quit && *(handle->cph_quit)) { _dbg(F,L,4, "sending to pid %d: %s", handle->cph_pid, handle->cph_quit); (void) fputs(handle->cph_quit, handle->cph_down); } /** Remove the back and err file descriptors from npoll **/ poll_del_fd( fileno(handle->cph_back) ); poll_del_fd( fileno(handle->cph_err) ); /** Close the input pipe to the child, which should die gracefully. **/ if (fclose(handle->cph_down) == EOF || fclose(handle->cph_back) == EOF || fclose(handle->cph_err) == EOF) return -1; /** Reap the child. **/ while ((done = waitpid( handle->cph_pid, &retstat, WNOHANG)) <= 0) if (done < 0 && errno != EINTR) return -1; _dbg(F,L,3, "ended child %s (%d) d=%d r=%d", handle->cph_cmd, handle->cph_pid, done, retstat ); if (handle != NULL) { if (handle->cph_cmd) free(handle->cph_cmd); if (handle->cph_tag) free(handle->cph_tag); if (handle->cph_eot) free(handle->cph_eot); if (handle->cph_quit) free(handle->cph_quit); free(handle); } mru_handle = NULL; return _cp_retcode(retstat); }