Example #1
0
static void
hash_init (unsigned int modulus, unsigned int entry_tab_size)
{
  struct htab *htab_r;

  htab_r = (struct htab *)
    xmalloc (sizeof (struct htab) + sizeof (struct entry *) * modulus);

  htab_r->entry_tab = (struct entry *)
    xmalloc (sizeof (struct entry) * entry_tab_size);

  htab_r->modulus = modulus;
  htab_r->entry_tab_size = entry_tab_size;
  htab = htab_r;

  hash_reset ();
}
Example #2
0
void
index_merge(const struct of *of, struct mparse *mp,
		struct buf *dbuf, struct buf *buf, DB *hash,
		struct mdb *mdb, struct recs *recs,
		const char *basedir)
{
	recno_t		 rec;
	int		 ch, skip;
	DBT		 key, val;
	DB		*files;  /* temporary file name table */
	char	 	 emptystring[1] = {'\0'};
	struct mdoc	*mdoc;
	struct man	*man;
	char		*p;
	const char	*fn, *msec, *march, *mtitle;
	uint64_t	 mask;
	size_t		 sv;
	unsigned	 seq;
	uint64_t	 vbuf[2];
	char		 type;

	if (warnings) {
		files = NULL;
		hash_reset(&files);
	}

	rec = 0;
	for (of = of->first; of; of = of->next) {
		fn = of->fname;

		/*
		 * Try interpreting the file as mdoc(7) or man(7)
		 * source code, unless it is already known to be
		 * formatted.  Fall back to formatted mode.
		 */

		mparse_reset(mp);
		mdoc = NULL;
		man = NULL;

		if ((MANDOC_SRC & of->src_form ||
		    ! (MANDOC_FORM & of->src_form)) &&
		    MANDOCLEVEL_FATAL > mparse_readfd(mp, -1, fn))
			mparse_result(mp, &mdoc, &man);

		if (NULL != mdoc) {
			msec = mdoc_meta(mdoc)->msec;
			march = mdoc_meta(mdoc)->arch;
			if (NULL == march)
				march = "";
			mtitle = mdoc_meta(mdoc)->title;
		} else if (NULL != man) {
			msec = man_meta(man)->msec;
			march = "";
			mtitle = man_meta(man)->title;
		} else {
			msec = of->sec;
			march = of->arch;
			mtitle = of->title;
		}

		/*
		 * Check whether the manual section given in a file
		 * agrees with the directory where the file is located.
		 * Some manuals have suffixes like (3p) on their
		 * section number either inside the file or in the
		 * directory name, some are linked into more than one
		 * section, like encrypt(1) = makekey(8).  Do not skip
		 * manuals for such reasons.
		 */

		skip = 0;
		assert(of->sec);
		assert(msec);
		if (strcasecmp(msec, of->sec))
			WARNING(fn, basedir, "Section \"%s\" manual "
				"in \"%s\" directory", msec, of->sec);
		/*
		 * Manual page directories exist for each kernel
		 * architecture as returned by machine(1).
		 * However, many manuals only depend on the
		 * application architecture as returned by arch(1).
		 * For example, some (2/ARM) manuals are shared
		 * across the "armish" and "zaurus" kernel
		 * architectures.
		 * A few manuals are even shared across completely
		 * different architectures, for example fdformat(1)
		 * on amd64, i386, sparc, and sparc64.
		 * Thus, warn about architecture mismatches,
		 * but don't skip manuals for this reason.
		 */

		assert(of->arch);
		assert(march);
		if (strcasecmp(march, of->arch))
			WARNING(fn, basedir, "Architecture \"%s\" "
				"manual in \"%s\" directory", 
				march, of->arch);

		/*
		 * By default, skip a file if the title given
		 * in the file disagrees with the file name.
		 * Do not warn, this happens for all MLINKs.
		 */

		assert(of->title);
		assert(mtitle);
		if (strcasecmp(mtitle, of->title))
			skip = 1;

		/*
		 * Build a title string for the file.  If it matches
		 * the location of the file, remember the title as
		 * found; else, remember it as missing.
		 */

		if (warnings) {
			buf->len = 0;
			buf_appendb(buf, mtitle, strlen(mtitle));
			buf_appendb(buf, "(", 1);
			buf_appendb(buf, msec, strlen(msec));
			if ('\0' != *march) {
				buf_appendb(buf, "/", 1);
				buf_appendb(buf, march, strlen(march));
			}
			buf_appendb(buf, ")", 2);
			for (p = buf->cp; '\0' != *p; p++)
				*p = tolower(*p);
			key.data = buf->cp;
			key.size = buf->len;
			val.data = NULL;
			val.size = 0;
			if (0 == skip)
				val.data = emptystring;
			else {
				ch = (*files->get)(files, &key, &val, 0);
				if (ch < 0) {
					perror("hash");
					exit((int)MANDOCLEVEL_SYSERR);
				} else if (ch > 0) {
					val.data = (void *)fn;
					val.size = strlen(fn) + 1;
				} else
					val.data = NULL;
			}
			if (NULL != val.data &&
			    (*files->put)(files, &key, &val, 0) < 0) {
				perror("hash");
				exit((int)MANDOCLEVEL_SYSERR);
			}
		}

		if (skip && !use_all)
			continue;

		/*
		 * The index record value consists of a nil-terminated
		 * filename, a nil-terminated manual section, and a
		 * nil-terminated description.  Use the actual
		 * location of the file, such that the user can find
		 * it with man(1).  Since the description may not be
		 * set, we set a sentinel to see if we're going to
		 * write a nil byte in its place.
		 */

		dbuf->len = 0;
		type = mdoc ? 'd' : (man ? 'a' : 'c');
		buf_appendb(dbuf, &type, 1);
		buf_appendb(dbuf, fn, strlen(fn) + 1);
		buf_appendb(dbuf, of->sec, strlen(of->sec) + 1);
		buf_appendb(dbuf, of->title, strlen(of->title) + 1);
		buf_appendb(dbuf, of->arch, strlen(of->arch) + 1);

		sv = dbuf->len;

		/*
		 * Collect keyword/mask pairs.
		 * Each pair will become a new btree node.
		 */

		hash_reset(&hash);
		if (mdoc)
			pmdoc_node(hash, buf, dbuf,
				mdoc_node(mdoc), mdoc_meta(mdoc));
		else if (man)
			pman_node(hash, buf, dbuf, man_node(man));
		else
			pformatted(hash, buf, dbuf, of, basedir);

		/* Test mode, do not access any database. */

		if (NULL == mdb->db || NULL == mdb->idx)
			continue;

		/*
		 * Make sure the file name is always registered
		 * as an .Nm search key.
		 */
		buf->len = 0;
		buf_append(buf, of->title);
		hash_put(hash, buf, TYPE_Nm);

		/*
		 * Reclaim an empty index record, if available.
		 * Use its record number for all new btree nodes.
		 */

		if (recs->cur > 0) {
			recs->cur--;
			rec = recs->stack[(int)recs->cur];
		} else if (recs->last > 0) {
			rec = recs->last;
			recs->last = 0;
		} else
			rec++;
		vbuf[1] = htobe64(rec);

		/*
		 * Copy from the in-memory hashtable of pending
		 * keyword/mask pairs into the database.
		 */

		seq = R_FIRST;
		while (0 == (ch = (*hash->seq)(hash, &key, &val, seq))) {
			seq = R_NEXT;
			assert(sizeof(uint64_t) == val.size);
			memcpy(&mask, val.data, val.size);
			vbuf[0] = htobe64(mask);
			val.size = sizeof(vbuf);
			val.data = &vbuf;
			dbt_put(mdb->db, mdb->dbn, &key, &val);
		}
		if (ch < 0) {
			perror("hash");
			exit((int)MANDOCLEVEL_SYSERR);
		}

		/*
		 * Apply to the index.  If we haven't had a description
		 * set, put an empty one in now.
		 */

		if (dbuf->len == sv)
			buf_appendb(dbuf, "", 1);

		key.data = &rec;
		key.size = sizeof(recno_t);

		val.data = dbuf->cp;
		val.size = dbuf->len;

		if (verb)
			printf("%s: Adding to index: %s\n", basedir, fn);

		dbt_put(mdb->idx, mdb->idxn, &key, &val);
	}

	/*
	 * Iterate the remembered file titles and check that
	 * all files can be found by their main title.
	 */

	if (warnings) {
		seq = R_FIRST;
		while (0 == (*files->seq)(files, &key, &val, seq)) {
			seq = R_NEXT;
			if (val.size)
				WARNING((char *)val.data, basedir, 
					"Probably unreachable, title "
					"is %s", (char *)key.data);
		}
		(*files->close)(files);
	}
}
Example #3
0
static int
hash_insert (ino_t ino, dev_t dev)
{
  struct htab *htab_r = htab;	/* Initially a copy of the global `htab'.  */

  if (htab_r->first_free_entry >= htab_r->entry_tab_size)
    {
      int i;
      struct entry *ep;
      unsigned modulus;
      unsigned entry_tab_size;

      /* Increase the number of hash entries, and re-hash the data.
	 The method of shrimping and increasing is made to compactify
	 the heap.  If twice as much data would be allocated
	 straightforwardly, we would never re-use a byte of memory.  */

      /* Let `htab' shrimp.  Keep only the header, not the pointer vector.  */

      htab_r = (struct htab *)
	xrealloc ((char *) htab_r, sizeof (struct htab));

      modulus = 2 * htab_r->modulus;
      entry_tab_size = 2 * htab_r->entry_tab_size;

      /* Increase the number of possible entries.  */

      htab_r->entry_tab = (struct entry *)
	xrealloc ((char *) htab_r->entry_tab,
		 sizeof (struct entry) * entry_tab_size);

      /* Increase the size of htab again.  */

      htab_r = (struct htab *)
	xrealloc ((char *) htab_r,
		 sizeof (struct htab) + sizeof (struct entry *) * modulus);

      htab_r->modulus = modulus;
      htab_r->entry_tab_size = entry_tab_size;
      htab = htab_r;

      i = htab_r->first_free_entry;

      /* Make the increased hash table empty.  The entries are still
	 available in htab->entry_tab.  */

      hash_reset ();

      /* Go through the entries and install them in the pointer vector
	 htab->hash.  The items are actually inserted in htab->entry_tab at
	 the position where they already are.  The htab->coll_link need
	 however be updated.  Could be made a little more efficient.  */

      for (ep = htab_r->entry_tab; i > 0; i--)
	{
	  hash_insert2 (htab_r, ep->ino, ep->dev);
	  ep++;
	}
    }

  return hash_insert2 (htab_r, ino, dev);
}
Example #4
0
static void
du_files (char **files)
{
  struct saved_cwd cwd;
  ino_t initial_ino;		/* Initial directory's inode. */
  dev_t initial_dev;		/* Initial directory's device. */
  int i;			/* Index in FILES. */

  if (save_cwd (&cwd))
    exit (1);

  /* Remember the inode and device number of the current directory.  */
  if (stat (".", &stat_buf))
    error (1, errno, _("current directory"));
  initial_ino = stat_buf.st_ino;
  initial_dev = stat_buf.st_dev;

  for (i = 0; files[i]; i++)
    {
      char *arg;
      int s;

      arg = files[i];

      /* Delete final slash in the argument, unless the slash is alone.  */
      s = strlen (arg) - 1;
      if (s != 0)
	{
	  if (arg[s] == '\\')
	    arg[s] = 0;

	  str_copyc (path, arg);
	}
      else if (arg[0] == '\\')
	str_trunc (path, 0);	/* Null path for root directory.  */
      else
	str_copyc (path, arg);

      if (!opt_combined_arguments)
	hash_reset ();

      count_entry (arg, 1, 0);

      /* chdir if `count_entry' has changed the working directory.  */
      if (stat (".", &stat_buf))
	error (1, errno, ".");
      if (stat_buf.st_ino != initial_ino || stat_buf.st_dev != initial_dev)
	{
	  if (restore_cwd (&cwd, _("starting directory"), NULL))
	    exit (1);
	}
    }

  if (opt_combined_arguments)
    {
      if (opt_human_readable)
	{
	  char buf[LONGEST_HUMAN_READABLE + 1];
	  printf("%s\ttotal\n", human_readable (tot_size, buf,
						LONGEST_HUMAN_READABLE + 1));
	}
      else
	{
	  printf (_("%ld\ttotal\n"), output_size == size_bytes ? tot_size
		  : convert_blocks (tot_size, output_size == size_kilobytes));
	}
      fflush (stdout);
    }

  free_cwd (&cwd);
}
Example #5
0
int main(int argc, char **argv)
{
  char buf[1024];
  char *string[1024];
  char *ptr, *chkstr;
  int loop, ctr = 0;
  hash_t *hash;


  testinfo("creating hash table");
  if(!(hash = hash_create(0, strkey, free)))
    errkill(-1, "failed (%s)", strerror(errno));
  passed();

  /* load strings */
  printf("\nloading strings from stdin:\n");
  while(fgets(buf, sizeof(buf), stdin))
    {
    printf("reading %i:", ctr);
    fflush(stdout);

    /* chomp newline */
    ptr = ((buf + strlen(buf)) - 1);
    if((ptr >= buf) && (*ptr == '\n'))
      *ptr = 0;

    if(!ctr && !(chkstr = strdup(buf)))
      errkill(-1, "error loading strings");
    if(!(string[ctr++] = strdup(buf)))
      errkill(-1, "error loading strings");
    printf("[%s]\n", string[ctr - 1]);
    if(ctr >= 1024)
      break;
    }

  /* store strings in hash */
  printf("\nstoring strings in hash:\n");
  for(loop=0; loop<ctr; loop++)
    {
    testinfo("storing [%s]...", string[loop]);
    if(hash_set(hash, string[loop], string[loop]))
      errkill(-1, "failed");
    passed();
    }

  /* test values */
  printf("\nlooking up stored values:\n");
  for(loop=0; loop<ctr; loop++)
    {
    testinfo("testing [%s]", string[loop]);
    if(!(ptr = hash_get(hash, string[loop])))
      errkill(-1, "failed");
    if(strcmp(ptr, string[loop]))
      errkill(-1, "error");
    passed();
    }

  testinfo("\ntesting hash reset");
  hash_reset(hash);
  if(hash_get(hash, chkstr))
    errkill(-1, "reset failed");
  free(chkstr);
  passed();

  testinfo("\nfreeing hash table");
  hash_free(hash);
  passed();

  printf("\n-- all tests passed --\n\n");
  return(0);
}
Example #6
0
/* mutator_reset */
int mutator_reset(Mutator * mutator)
{
	return hash_reset(mutator);
}
Example #7
0
int compress (char* input_file_name)
{
	int ret, c;
	FILE* input_file;
	int hash_elem_pointer;	//pointer to the actual node
	
	input_file = fopen(input_file_name, "r");
	
	//read a character and perform the compression until EOF is found
	while(1){
		c = getc(input_file);
		
		again:	if (c == EOF)
				{					
					//emit the last father_index
					ret = emit((uint64_t)hash_elem_pointer);
					if (ret < 0)
					{
						fprintf(stderr, "Unable to emit the last symbol\n");
						free(hash_table);
						return -1;
					}
					
					//emit the EOF value
					ret = emit((uint64_t)0);
					if (ret < 0)
					{
						fprintf(stderr, "Unable to emit the EOF\n");
						free(hash_table);
						return -1;
					}					
					
					break;
				}
			
				//search the character into the hash table
				ret = hash_search(hash_elem_pointer, (char)c);
				if (ret != 0)
				{
					//correspondent child was found so simply advance the pointer 
					hash_elem_pointer = ret;
				}
				else
				{
					//emit the father_index
					ret = emit((uint64_t)hash_elem_pointer);
					if (ret < 0)
					{
						fprintf(stderr, "Unable to emit the EOF\n");
						free(hash_table);
						return -1;
					}
					
					if (++hash_elem_counter == dictionary_size)
						hash_reset();
					
					else{
 						//add the new node 
 						ret = hash_add(hash_elem_pointer, (char)c);
 						if (ret != 0){
 							fprintf(stderr, "Error in hash_add");
 							free(hash_table);
 							return -1;
 						}
					}
					
					//restart the search from the root
					hash_elem_pointer = 0;
					//now search the character c again
					goto again;
				}
	}
	
	free(hash_table);
	return 0;
}
Example #8
0
/*
 *  resets the hash table using hash_reset()
 */
void (conf_hashreset)(void)
{
    hash_reset();
}