Пример #1
0
/*------------------------------------------------------------------
 *
 *------------------------------------------------------------------*/
int main(void)
   {
   Hash *iHash;
   int   i;
   int   counter;

   iHash = HashCreate(sizeof(int),3,compareFunc,hashFunc,NULL);

   for (i= 1; i<10; i++)
      HashAdd(iHash,&i);

   for (i=20; i>10; i--)
      HashAdd(iHash,&i);

   for (i=0; i<=21; i++)
      if (!HashFind(iHash,&i))
         printf("didn't find %d\n",i);

   counter = 1;
   HashIterate(iHash,iterateFunc,&counter);

   for (i=-1; i<5; i++)
      HashDelete(iHash,&i);

   for (i=21; i>15; i--)
      HashDelete(iHash,&i);

   counter = 1;
   HashIterate(iHash,iterateFunc,&counter);

   HashDestroy(iHash);

   return 0;
   }
Пример #2
0
void ProcessPreprocessedFile(istream &in, const char *input_file)
{
  Assert(g_working_directory && g_base_directory);

  // read our entire input into a buffer.
  Buffer file_buf;
  ReadInStream(in, &file_buf);

  // table with contents read so far for 
  HashTable<String*,FileData,String> file_table;

  // name of the original file which was being parsed, from which we will
  // get whether this is a C or a C++ file.
  const char *base_file = NULL;

  char *pos = (char*) file_buf.base;

  FileData *cur_data = NULL;
  while (*pos) {

    if (*pos == '#' && *(pos+1) == ' ') {
      // found a preprocessor line directive.
      // currently we just parse lines of the format '# line "file" ...

      // eat the '#'
      pos++;

      char *end_pos = NULL;
      long line = strtol(pos, &end_pos, 10);
      Assert(line >= 1);
      Assert(end_pos);

      char *start_quote = strchr(end_pos, '"');
      Assert(start_quote);

      char *end_quote = strchr(start_quote + 1, '"');
      Assert(end_quote);

      char *end_line = strchr(pos, '\n');
      Assert(end_line && end_line > end_quote);

      if (base_file == NULL) {
        // just mark the first # line directive we see as the base file.
        base_file = start_quote + 1;
      }

      *end_quote = 0;
      String *file = String::Make(NormalizeFile(start_quote + 1));

      Vector<FileData> *entries = file_table.Lookup(file, true);
      if (entries->Empty()) {
        entries->PushBack(FileData());

        cur_data = &entries->Back();
        cur_data->contents = new Buffer();
        cur_data->cur_line = 1;
      }
      else {
        Assert(entries->Size() == 1);
        cur_data = &entries->Back();
      }

      // insert enough newlines so that we've caught up with the # line.
      while ((long) cur_data->cur_line < line) {
        cur_data->contents->Append("\n", 1);
        cur_data->cur_line++;
      }

      // in some cases the # line directive will actually rewind the
      // apparent line to an earlier line, e.g.:
      // # 250 "foo.c"
      // something
      // else
      // # 250 "foo.c"
      // finally
      // in this case we'll replace the earlier newlines with spaces,
      // getting the string 'something else finally' at line 250.
      char *last_pos = (char*) cur_data->contents->pos - 1;
      while ((long) cur_data->cur_line > line) {
        while (*last_pos != '\n') last_pos--;
        *last_pos = ' ';
        cur_data->cur_line--;
      }

      pos = end_line + 1;
      continue;
    }

    if (cur_data == NULL) {
      // we can get here if the input is not actually preprocessed.
      // make data for the input file itself.
      Assert(input_file);
      String *file = String::Make(NormalizeFile(input_file));

      Vector<FileData> *entries = file_table.Lookup(file, true);
      Assert(entries->Empty());

      entries->PushBack(FileData());

      cur_data = &entries->Back();
      cur_data->contents = new Buffer();
      cur_data->cur_line = 1;
    }

    char *end_line = strchr(pos, '\n');
    if (end_line == NULL) {
      cur_data->contents->Append(pos, strlen(pos));
      break;
    }

    cur_data->contents->Append(pos, end_line - pos + 1);
    cur_data->cur_line++;

    pos = end_line + 1;
  }

  // figure out which of the files we read need to be added to the dbs.
  Transaction *query = new Transaction();
  HashIterate(file_table)
    QueryFileData(query, file_table.ItKey(), file_table.ItValueSingle());
  SubmitTransaction(query);

  // add those files we found in the query.
  Transaction *dump = new Transaction();
  HashIterate(file_table)
    DumpFileData(query, dump, file_table.ItKey(), file_table.ItValueSingle());
  SubmitTransaction(dump);

  delete query;
  delete dump;

  HashIterate(file_table)
    delete file_table.ItValueSingle().contents;
}