示例#1
0
文件: catom.cpp 项目: dwillmer/atom
void CAtom::remove_guard( CAtom** ptr )
{
    if( !*ptr )
        return;
    GuardMap* map = guard_map();
    if( !map || map->empty() )
        return;
    bool more = false;  // if the CAtom has more pointers attached to it.
    GuardMap::iterator it = map->find( *ptr );
    const GuardMap::iterator end = map->end();
    for( ; it != end && it->first == *ptr; ++it )
    {
        if( it->second == ptr )
        {
            if( !more )
            {
                ++it;
                more = ( it != end ) && ( it->first == *ptr );
                --it;
            }
            map->erase( it );
            break;
        }
        more = true;
    }
    if( !more )
        ( *ptr )->set_has_guards( false );
}
示例#2
0
文件: catom.cpp 项目: dwillmer/atom
void CAtom::clear_guards( CAtom* o )
{
    GuardMap* map = 0;
    try
    {
        map = guard_map();
    }
    catch( std::bad_alloc& )
    {
        // do nothing in case of OOM - code below is safe
    }
    if( !map || map->empty() )
        return;
    GuardMap::iterator it = map->find( o );
    GuardMap::iterator first = it;
    const GuardMap::iterator end = map->end();
    for( ; it != end && it->first == o; ++it )
        *it->second = 0;
    map->erase( first, it );
    o->set_has_guards( false );
}
示例#3
0
// Merge adjacent blocks with identical guards.
static void mergeGuards(std::deque<std::string>& file_lines, GuardMap& guard_map) {
  if (guard_map.size() < 2) {
    return;
  }

  auto current = guard_map.begin();
  auto next = current;
  ++next;

  while (next != guard_map.end()) {
    if (current->second != next->second) {
      ++current;
      ++next;
      continue;
    }

    // Scan from the end of current to the beginning of next.
    bool in_block_comment = false;
    bool valid = true;

    FileLocation current_location = current->first.end;
    FileLocation end_location = next->first.start;

    auto nextLine = [&current_location]() {
      ++current_location.line;
      current_location.column = 1;
    };

    auto nextCol = [&file_lines, &current_location, &nextLine]() {
      if (current_location.column == file_lines[current_location.column - 1].length()) {
        nextLine();
      } else {
        ++current_location.column;
      }
    };

    // The end location will point to the semicolon, which we don't want to read, so skip it.
    nextCol();

    while (current_location < end_location) {
      const std::string& line = file_lines[current_location.line - 1];
      size_t line_index = current_location.column - 1;

      if (in_block_comment) {
        size_t pos = line.find("*/", line_index);
        if (pos == std::string::npos) {
          D("Didn't find block comment terminator, skipping line\n");
          nextLine();
          continue;
        } else {
          D("Found block comment terminator\n");
          in_block_comment = false;
          current_location.column = pos + 2;
          nextCol();
          continue;
        }
      } else {
        size_t pos = line.find_first_not_of(" \t", line_index);
        if (pos == std::string::npos) {
          nextLine();
          continue;
        }

        current_location.column = pos + 1;
        if (line[pos] != '/') {
          D("Trailing character '%c' is not a slash: %s\n", line[pos], line.substr(pos).c_str());
          valid = false;
          break;
        }

        nextCol();
        if (line.length() <= pos + 1) {
          // Trailing slash at the end of a line?
          D("Trailing slash at end of line\n");
          valid = false;
          break;
        }

        if (line[pos + 1] == '/') {
          // C++ style comment
          nextLine();
        } else if (line[pos + 1] == '*') {
          // Block comment
          nextCol();
          in_block_comment = true;
          D("In a block comment\n");
        } else {
          // Garbage?
          D("Unexpected output after /: %s\n", line.substr(pos).c_str());
          valid = false;
          break;
        }
      }
    }

    if (!valid) {
      D("Not merging blocks %s and %s\n", to_string(current->first).c_str(),
        to_string(next->first).c_str());
      ++current;
      ++next;
      continue;
    }

    D("Merging blocks %s and %s\n", to_string(current->first).c_str(),
      to_string(next->first).c_str());

    Location merged = current->first;
    merged.end = next->first.end;

    DeclarationAvailability avail = current->second;

    guard_map.erase(current);
    guard_map.erase(next);
    bool dummy;
    std::tie(current, dummy) = guard_map.insert(std::make_pair(merged, avail));
    next = current;
    ++next;
  }
}