Esempio n. 1
0
/* mktemplate - create a template entry based on a state, and connect the state
 *              to it
 */
void
mktemplate(int state[], int statenum, int comstate)
{
    int i, numdiff, tmpbase, tmp[CSIZE + 1];
    CCLTBL transset[CSIZE + 1];
    int tsptr;

    ++numtemps;

    tsptr = 0;

    /* Calculate where we will temporarily store the transition table
     * of the template in the tnxt[] array.  The final transition table
     * gets created by cmptmps().
     */

    tmpbase = numtemps * numecs;

    if (tmpbase + numecs >= current_max_template_xpairs) {
	current_max_template_xpairs += MAX_TEMPLATE_XPAIRS_INCREMENT;

	++num_reallocs;

	tnxt = reallocate_integer_array(tnxt,
					current_max_template_xpairs);
    }

    for (i = 1; i <= numecs; ++i) {
	if (state[i] == 0) {
	    tnxt[tmpbase + i] = 0;
	} else {
	    transset[tsptr++].ch = (Char) i;
	    transset[tsptr].why = cCnone;
	    tnxt[tmpbase + i] = comstate;
	}
    }

    if (usemecs)
	mkeccl(transset, tsptr, tecfwd, tecbck, numecs, 0);

    mkprot(tnxt + tmpbase, -numtemps, comstate);

    /* We rely on the fact that mkprot adds things to the beginning
     * of the proto queue.
     */

    numdiff = tbldiff(state, firstprot, tmp);
    mkentry(tmp, numecs, statenum, -numtemps, numdiff);
}
Esempio n. 2
0
void pass5(void)
{
    uint16_t n;
    struct dinode ino;
    int yes();

    for (n = ROOTINODE; n < 8 * (swizzle16(superblock.s_isize) - 2); ++n) {
        iread(n, &ino);

        if (ino.i_mode == 0) {
            if (linkmap[n] != -1)
                panic("Inconsistent linkmap");
            continue;
        }

        if (linkmap[n] == -1 && ino.i_mode != 0)
            panic("Inconsistent linkmap");

        if (linkmap[n] > 0 && swizzle16(ino.i_nlink) != linkmap[n]) {
            printf("Inode %d has link count %d should be %d. Fix? ",
                    n, swizzle16(ino.i_nlink), linkmap[n]);
            if (yes()) {
                ino.i_nlink = swizzle16(linkmap[n]);
                iwrite(n, &ino);
            }
        }

        if (linkmap[n] == 0) {
            if ((swizzle16(ino.i_mode) & F_MASK) == F_BDEV ||
                    (swizzle16(ino.i_mode) & F_MASK) == F_CDEV ||
                    (ino.i_size == 0)) {
                printf("Useless inode %d with mode 0%o has become detached. Link count is %d. Zap? ",
                        n, swizzle16(ino.i_mode), swizzle16(ino.i_nlink));
                if (yes()) {
                    ino.i_nlink = 0;
                    ino.i_mode = 0;
                    iwrite(n, &ino);
                    superblock.s_tinode =
                                swizzle16(swizzle16(superblock.s_tinode) + 1);
                    dwrite((blkno_t) 1, (char *) &superblock);
                }
            } else {
#if 0
                printf("Inode %d has become detached. Link count is %d. Fix? ",
                        n, swizzle16(ino.i_nlink));
                if (yes()) {
                    ino.i_nlink = 1;
                    iwrite(n, &ino);
                    mkentry(n);
                }
#else
                printf("Inode %d has become detached. Link count is %d. ",
                        n, swizzle16(ino.i_nlink));
                if (ino.i_nlink == 0)
                    printf("Zap? ");
                else
                    printf("Fix? ");
                if (yes()) {
                    if (ino.i_nlink == 0) {
                        ino.i_nlink = 0;
                        ino.i_mode = 0;
                        iwrite(n, &ino);
                        superblock.s_tinode =
                                swizzle16(swizzle16(superblock.s_tinode) + 1);
                        dwrite((blkno_t) 1, (char *) &superblock);
                    } else {
                        ino.i_nlink = swizzle16(1);
                        iwrite(n, &ino);
                        mkentry(n);
                    }
                }
#endif
            }
        }

    }
}
Esempio n. 3
0
/*
 * Do an "ls" style listing of a directory
 */
static void
printlist(const char *name, char *basename)
{
	struct afile *fp, *list, *listp = NULL;
	struct direct *dp;
	struct afile single;
	RST_DIR *dirp;
	int entries, len, namelen;
	char locname[MAXPATHLEN + 1];

	dp = pathsearch(name);
	if (dp == NULL || (!dflag && TSTINO(dp->d_ino, dumpmap) == 0) ||
	    (!vflag && dp->d_ino == UFS_WINO))
		return;
	if ((dirp = rst_opendir(name)) == NULL) {
		entries = 1;
		list = &single;
		mkentry(name, dp, list);
		len = strlen(basename) + 1;
		if (strlen(name) - len > (unsigned short)single.len) {
			freename(single.fname);
			single.fname = savename(&name[len]);
			single.len = strlen(single.fname);
		}
	} else {
		entries = 0;
		while ((dp = rst_readdir(dirp)))
			entries++;
		rst_closedir(dirp);
		list = (struct afile *)malloc(entries * sizeof(struct afile));
		if (list == NULL) {
			fprintf(stderr, "ls: out of memory\n");
			return;
		}
		if ((dirp = rst_opendir(name)) == NULL)
			panic("directory reopen failed\n");
		fprintf(stderr, "%s:\n", name);
		entries = 0;
		listp = list;
		strncpy(locname, name, MAXPATHLEN);
		strncat(locname, "/", MAXPATHLEN);
		namelen = strlen(locname);
		while ((dp = rst_readdir(dirp))) {
			if (dp == NULL)
				break;
			if (!dflag && TSTINO(dp->d_ino, dumpmap) == 0)
				continue;
			if (!vflag && (dp->d_ino == UFS_WINO ||
			     strcmp(dp->d_name, ".") == 0 ||
			     strcmp(dp->d_name, "..") == 0))
				continue;
			locname[namelen] = '\0';
			if (namelen + dp->d_namlen >= MAXPATHLEN) {
				fprintf(stderr, "%s%s: name exceeds %d char\n",
					locname, dp->d_name, MAXPATHLEN);
			} else {
				strncat(locname, dp->d_name, (int)dp->d_namlen);
				mkentry(locname, dp, listp++);
				entries++;
			}
		}
		rst_closedir(dirp);
		if (entries == 0) {
			fprintf(stderr, "\n");
			free(list);
			return;
		}
		qsort((char *)list, entries, sizeof(struct afile), fcmp);
	}
	formatf(list, entries);
	if (dirp != NULL) {
		for (fp = listp - 1; fp >= list; fp--)
			freename(fp->fname);
		fprintf(stderr, "\n");
		free(list);
	}
}
Esempio n. 4
0
/* bldtbl - build table entries for dfa state
 *
 * synopsis
 *   int state[numecs], statenum, totaltrans, comstate, comfreq;
 *   bldtbl( state, statenum, totaltrans, comstate, comfreq );
 *
 * State is the statenum'th dfa state.  It is indexed by equivalence class and
 * gives the number of the state to enter for a given equivalence class.
 * totaltrans is the total number of transitions out of the state.  Comstate
 * is that state which is the destination of the most transitions out of State.
 * Comfreq is how many transitions there are out of State to Comstate.
 *
 * A note on terminology:
 *    "protos" are transition tables which have a high probability of
 * either being redundant (a state processed later will have an identical
 * transition table) or nearly redundant (a state processed later will have
 * many of the same out-transitions).  A "most recently used" queue of
 * protos is kept around with the hope that most states will find a proto
 * which is similar enough to be usable, and therefore compacting the
 * output tables.
 *    "templates" are a special type of proto.  If a transition table is
 * homogeneous or nearly homogeneous (all transitions go to the same
 * destination) then the odds are good that future states will also go
 * to the same destination state on basically the same character set.
 * These homogeneous states are so common when dealing with large rule
 * sets that they merit special attention.  If the transition table were
 * simply made into a proto, then (typically) each subsequent, similar
 * state will differ from the proto for two out-transitions.  One of these
 * out-transitions will be that character on which the proto does not go
 * to the common destination, and one will be that character on which the
 * state does not go to the common destination.  Templates, on the other
 * hand, go to the common state on EVERY transition character, and therefore
 * cost only one difference.
 */
void
bldtbl(int state[], int statenum, int totaltrans, int comstate, int comfreq)
{
    int extptr, extrct[2][CSIZE + 1];
    int mindiff, minprot, i, d;

    /* If extptr is 0 then the first array of extrct holds the result
     * of the "best difference" to date, which is those transitions
     * which occur in "state" but not in the proto which, to date,
     * has the fewest differences between itself and "state".  If
     * extptr is 1 then the second array of extrct hold the best
     * difference.  The two arrays are toggled between so that the
     * best difference to date can be kept around and also a difference
     * just created by checking against a candidate "best" proto.
     */

    extptr = 0;

    /* If the state has too few out-transitions, don't bother trying to
     * compact its tables.
     */

    if ((totaltrans * 100) < (numecs * PROTO_SIZE_PERCENTAGE))
	mkentry(state, numecs, statenum, JAMSTATE, totaltrans);

    else {
	/* "checkcom" is true if we should only check "state" against
	 * protos which have the same "comstate" value.
	 */
	int checkcom =
	comfreq * 100 > totaltrans * CHECK_COM_PERCENTAGE;

	minprot = firstprot;
	mindiff = totaltrans;

	if (checkcom) {
	    /* Find first proto which has the same "comstate". */
	    for (i = firstprot; i != NIL; i = protnext[i])
		if (protcomst[i] == comstate) {
		    minprot = i;
		    mindiff = tbldiff(state, minprot,
				      extrct[extptr]);
		    break;
		}
	}

	else {
	    /* Since we've decided that the most common destination
	     * out of "state" does not occur with a high enough
	     * frequency, we set the "comstate" to zero, assuring
	     * that if this state is entered into the proto list,
	     * it will not be considered a template.
	     */
	    comstate = 0;

	    if (firstprot != NIL) {
		minprot = firstprot;
		mindiff = tbldiff(state, minprot,
				  extrct[extptr]);
	    }
	}

	/* We now have the first interesting proto in "minprot".  If
	 * it matches within the tolerances set for the first proto,
	 * we don't want to bother scanning the rest of the proto list
	 * to see if we have any other reasonable matches.
	 */

	if (mindiff * 100 > totaltrans * FIRST_MATCH_DIFF_PERCENTAGE) {
	    /* Not a good enough match.  Scan the rest of the
	     * protos.
	     */
	    for (i = minprot; i != NIL; i = protnext[i]) {
		d = tbldiff(state, i, extrct[1 - extptr]);
		if (d < mindiff) {
		    extptr = 1 - extptr;
		    mindiff = d;
		    minprot = i;
		}
	    }
	}

	/* Check if the proto we've decided on as our best bet is close
	 * enough to the state we want to match to be usable.
	 */

	if (mindiff * 100 > totaltrans * ACCEPTABLE_DIFF_PERCENTAGE) {
	    /* No good.  If the state is homogeneous enough,
	     * we make a template out of it.  Otherwise, we
	     * make a proto.
	     */

	    if (comfreq * 100 >=
		totaltrans * TEMPLATE_SAME_PERCENTAGE)
		mktemplate(state, statenum, comstate);

	    else {
		mkprot(state, statenum, comstate);
		mkentry(state, numecs, statenum,
			JAMSTATE, totaltrans);
	    }
	}

	else {			/* use the proto */
	    mkentry(extrct[extptr], numecs, statenum,
		    prottbl[minprot], mindiff);

	    /* If this state was sufficiently different from the
	     * proto we built it from, make it, too, a proto.
	     */

	    if (mindiff * 100 >=
		totaltrans * NEW_PROTO_DIFF_PERCENTAGE)
		mkprot(state, statenum, comstate);

	    /* Since mkprot added a new proto to the proto queue,
	     * it's possible that "minprot" is no longer on the
	     * proto queue (if it happened to have been the last
	     * entry, it would have been bumped off).  If it's
	     * not there, then the new proto took its physical
	     * place (though logically the new proto is at the
	     * beginning of the queue), so in that case the
	     * following call will do nothing.
	     */

	    mv2front(minprot);
	}
    }
}
Esempio n. 5
0
/* cmptmps - compress template table entries
 *
 * Template tables are compressed by using the 'template equivalence
 * classes', which are collections of transition character equivalence
 * classes which always appear together in templates - really meta-equivalence
 * classes.
 */
void
cmptmps(void)
{
    int tmpstorage[CSIZE + 1];
    int *tmp = tmpstorage, i, j;
    int totaltrans, trans;

    peakpairs = numtemps * numecs + tblend;

    if (usemecs) {
	/* Create equivalence classes based on data gathered on
	 * template transitions.
	 */
	nummecs = cre8ecs(tecfwd, tecbck, numecs);
    }

    else
	nummecs = numecs;

    while (lastdfa + numtemps + 1 >= current_max_dfas)
	increase_max_dfas();

    /* Loop through each template. */

    for (i = 1; i <= numtemps; ++i) {
	/* Number of non-jam transitions out of this template. */
	totaltrans = 0;

	for (j = 1; j <= numecs; ++j) {
	    trans = tnxt[numecs * i + j];

	    if (usemecs) {
		/* The absolute value of tecbck is the
		 * meta-equivalence class of a given
		 * equivalence class, as set up by cre8ecs().
		 */
		if (tecbck[j] > 0) {
		    tmp[tecbck[j]] = trans;

		    if (trans > 0)
			++totaltrans;
		}
	    }

	    else {
		tmp[j] = trans;

		if (trans > 0)
		    ++totaltrans;
	    }
	}

	/* It is assumed (in a rather subtle way) in the skeleton
	 * that if we're using meta-equivalence classes, the def[]
	 * entry for all templates is the jam template, i.e.,
	 * templates never default to other non-jam table entries
	 * (e.g., another template)
	 */

	/* Leave room for the jam-state after the last real state. */
	mkentry(tmp, nummecs, lastdfa + i + 1, JAMSTATE, totaltrans);
    }
}