Ejemplo n.º 1
0
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);
  }
}
Ejemplo n.º 2
0
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);
    }
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
        // 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;
        }
Ejemplo n.º 7
0
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;
            }
        }
    }
}
Ejemplo n.º 8
0
/**
 ** 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);
}