Exemple #1
0
// LAB2: below code is used to check the first fit allocation algorithm (your EXERCISE 1) 
// NOTICE: You SHOULD NOT CHANGE basic_check, default_check functions!
static void
default_check(void) {
    int count = 0, total = 0;
    list_entry_t *le = &free_list;
    while ((le = list_next(le)) != &free_list) {
        struct Page *p = le2page(le, page_link);
        assert(PageProperty(p));
        count ++, total += p->property;
    }
    assert(total == nr_free_pages());

    basic_check();

    struct Page *p0 = alloc_pages(5), *p1, *p2;
    assert(p0 != NULL);
    assert(!PageProperty(p0));

    list_entry_t free_list_store = free_list;
    list_init(&free_list);
    assert(list_empty(&free_list));
    assert(alloc_page() == NULL);

    unsigned int nr_free_store = nr_free;
    nr_free = 0;

    free_pages(p0 + 2, 3);
    assert(alloc_pages(4) == NULL);
    assert(PageProperty(p0 + 2) && p0[2].property == 3);
    assert((p1 = alloc_pages(3)) != NULL);
    assert(alloc_page() == NULL);
    assert(p0 + 2 == p1);

    p2 = p0 + 1;
    free_page(p0);
    free_pages(p1, 3);
    assert(PageProperty(p0) && p0->property == 1);
    assert(PageProperty(p1) && p1->property == 3);

    assert((p0 = alloc_page()) == p2 - 1);
    free_page(p0);
    assert((p0 = alloc_pages(2)) == p2 + 1);

    free_pages(p0, 2);
    free_page(p2);

    assert((p0 = alloc_pages(5)) != NULL);
    assert(alloc_page() == NULL);

    assert(nr_free == 0);
    nr_free = nr_free_store;

    free_list = free_list_store;
    free_pages(p0, 5);

    le = &free_list;
    while ((le = list_next(le)) != &free_list) {
        struct Page *p = le2page(le, page_link);
        count --, total -= p->property;
    }
    assert(count == 0);
    assert(total == 0);
}
static void
check_prop(GLuint prog, GLenum programInterface, int index, const char *name,
	   void *inputs, struct check_t c, bool *pass)
{
	int values[10], parent_idx, i;
	char subsubtest[150];
	GLsizei length, tmp = -1;
	char buf[21];
	GLenum pif;
	GLuint loc;

	/* skip the test if it is not supported */
	if(!check_extensions_prop(c.prop)) {
		return;
	}

	/* generate the name of the subsubtest for error-reporting purposes */
	snprintf(subsubtest, sizeof(subsubtest), "%s: %s on %s",
		 name, piglit_get_gl_enum_name(c.prop),
		 piglit_get_gl_enum_name(programInterface));

	/* retrieve the property */
	glGetProgramResourceiv(prog, programInterface, index, 1, &c.prop, 10,
			       &length, values);
	if (!piglit_check_gl_error(GL_NO_ERROR)) {
		printf("	Latest error generated while running '%s'\n",
		       subsubtest);
		*pass = false;
		return;
	}

	/* check the return value */
	switch (c.prop) {
	case GL_OFFSET:
	case GL_ARRAY_STRIDE:
	case GL_ATOMIC_COUNTER_BUFFER_INDEX:
		basic_check(subsubtest, values[0], c.values[0], pass);
		break;

	case GL_BLOCK_INDEX:
		/* check that the index of the parent matches the name
		 * of the parent
		 */
		switch (programInterface) {
		case GL_UNIFORM:
			pif = GL_UNIFORM_BLOCK;
			break;
		case GL_BUFFER_VARIABLE:
			pif = GL_SHADER_STORAGE_BLOCK;
			break;
		default:
			assert(!"unexpected programInterface value");
			pif = GL_NONE;
		}

		parent_idx = glGetProgramResourceIndex(prog, pif,
						       (char*)inputs);
		piglit_check_gl_error(GL_NO_ERROR);
		if (parent_idx != values[0]) {
			glGetProgramResourceName(prog, programInterface,
						 values[0], sizeof(buf), NULL,
						 buf);

			fprintf(stderr, "'%s' expected parent name to be %s"
				"(idx = %i) but got parent name %s(idx = %i)\n",
				subsubtest, (char*)inputs, parent_idx, buf,
				values[0]);
			*pass = false;
		}
		break;

	case GL_BUFFER_BINDING:
		if (values[0] < 0) {
			fprintf(stderr, "'%s' invalid buffer binding point\n",
				subsubtest);
			*pass = false;
		}

		/* Binding index is necessary for ATOMIC_COUNTER_BUFFER */
		if (programInterface == GL_ATOMIC_COUNTER_BUFFER) {
			if (values[0] != c.values[0]) {
				fprintf(stderr, "'%s' expected binding point %i"
						" but got %i\n", subsubtest,
					c.values[0], values[0]);
				*pass = false;
			}
			break;
		}

		/* check against another API call */
		if (programInterface != GL_UNIFORM_BLOCK) {
			break;
		}

		glGetActiveUniformBlockiv(prog, index, GL_UNIFORM_BLOCK_BINDING,
					  &tmp);
		piglit_check_gl_error(GL_NO_ERROR);
		if (tmp != values[0]) {
			fprintf(stderr, "'%s' inconsistent buffer binding point"
					"(%i) with glGetActiveUniformBlockiv"
					"(%i)\n", subsubtest, values[0], tmp);
			*pass = false;
		}

		break;

	case GL_ACTIVE_VARIABLES:
	case GL_COMPATIBLE_SUBROUTINES:
		switch (programInterface) {
		case GL_UNIFORM_BLOCK:
			pif = GL_UNIFORM;
			break;
		case GL_SHADER_STORAGE_BLOCK:
			pif = GL_BUFFER_VARIABLE;
			break;
		case GL_VERTEX_SUBROUTINE_UNIFORM:
			pif = GL_VERTEX_SUBROUTINE;
			break;
		case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
			pif = GL_TESS_CONTROL_SUBROUTINE;
			break;
		case GL_COMPUTE_SUBROUTINE_UNIFORM:
			pif = GL_COMPUTE_SUBROUTINE;
			break;
		case GL_ATOMIC_COUNTER_BUFFER:
			/* do nothing */
			break;
		default:
			assert(!"unexpected programInterface value");
			pif = GL_NONE;
		}

		/* check that the return count is as expected */
		if (c.count != length) {
			fprintf(stderr, "'%s' expected %zu entries but got %i"
					"\n", subsubtest, c.count, length);
			length = 1;
			*pass = false;
			break;
		}

		/* harcode the index test for GL_ATOMIC_COUNTER_BUFFER */
		if (programInterface == GL_ATOMIC_COUNTER_BUFFER) {

			if (values[0] != 0) {
				fprintf(stderr, "'%s' expected index 0 but got "
						"%i", subsubtest, values[0]);
				*pass = false;
			}
			break;
		}

		for (i = 0; i < length; i++) {
			buf[0] = '\0';
			glGetProgramResourceName(prog, pif, values[i],
						 sizeof(buf), NULL, buf);
			piglit_check_gl_error(GL_NO_ERROR);
			if (!is_resource_in_list(inputs, buf, i, false)) {
				fprintf(stderr, "'%s' could not find active "
					"resource '%s' (idx = %i) in the active"
					" list\n", subsubtest, buf, values[i]);
				*pass = false;
			}
		}
		break;

	case GL_BUFFER_DATA_SIZE:
		/* Nothing we can check here... */
		break;

	case GL_LOCATION:
		loc = glGetProgramResourceLocation(prog, programInterface,
						   name);
		piglit_check_gl_error(GL_NO_ERROR);
		if (loc != values[0]) {
			fprintf(stderr, "'%s' inconsistent value between "
					"glGetProgramResourceiv(%i) and "
					"glGetProgramResourceLocation(%i).\n",
				subsubtest, values[0], loc);
			*pass = false;
			break;
		}

		if (prog == prog_loc && values[0] != c.values[0]) {
			fprintf(stderr, "'%s' expected location %i but got "
					"%i\n", subsubtest, c.values[0],
					values[0]);
			*pass = false;
			break;
		}

		/* continue by testing the (in)validity of the index */
		basic_check(subsubtest, values[0], c.values[0], pass);
		break;

	case GL_LOCATION_INDEX:
		loc = glGetProgramResourceLocationIndex(prog, programInterface,
							name);
		piglit_check_gl_error(GL_NO_ERROR);
		if (loc != values[0]) {
			fprintf(stderr, "'%s' inconsistent value between "
					"glGetProgramResourceiv(%i) and "
					"glGetProgramResourceLocationIndex(%i)."
					"\n", subsubtest, values[0], loc);
			*pass = false;
			break;
		}

		/* continue by testing the (in)validity of the index */
		basic_check(subsubtest, values[0], c.values[0], pass);
		break;

	default:
		/* check that the return count is as expected */
		if (c.count != length) {
			fprintf(stderr, "'%s' expected %zu entries but got %i"
					"\n", subsubtest, c.count, length);
			length = 1;
			*pass = false;
			break;
		}

		/* go through all the values returned */
		for (i = 0; i < length; i++) {
			if (values[i] != c.values[i]) {
				fprintf(stderr, "'%s' expected %i but got %i at"
					" index %i\n", subsubtest, c.values[i],
					values[i], i);
				*pass = false;
			}
		}

		break;
	}
}
int
main(int argc, char **argv)
{
	const char *av = NULL;
	int func_total, file_total;
        char arg_dbpath[MAXPATHLEN];
	const char *index = NULL;
	int optchar;
        int option_index = 0;
	STATISTICS_TIME *tim;

	arg_dbpath[0] = 0;
	basic_check();
	/*
	 * Setup GTAGSCONF and GTAGSLABEL environment variable
	 * according to the --gtagsconf and --gtagslabel option.
	 */
	preparse_options(argc, argv);
	/*
	 * Load configuration values.
	 */
	if (!vgetcwd(cwdpath, sizeof(cwdpath)))
		die("cannot get current directory.");
	openconf(cwdpath);
	configuration();
	/*
	 * setup_langmap() is needed to use decide_lang().
	 */
	setup_langmap(langmap);
	save_environment(argc, argv);
	/*
	 * insert htags_options at the head of argv.
	 */
	setenv_from_config();
	{
		char *env = getenv("HTAGS_OPTIONS");
		if (env && *env)
			argv = prepend_options(&argc, argv, env);
	}
	while ((optchar = getopt_long(argc, argv, "acd:DfFghIm:nNoqst:Tvwx", long_options, &option_index)) != EOF) {
		switch (optchar) {
		case 0:
			/* already flags set */
			break;
		case OPT_AUTO_COMPLETION:
			auto_completion = 1;
			if (optarg) {
				if (atoi(optarg) > 0)
					auto_completion_limit = optarg;
				else
					die("The option value of --auto-completion must be numeric.");
			}
			break;
		case OPT_CFLOW:
			call_file = optarg;
			break;
		case OPT_CALL_TREE:
			call_file = optarg;
			break;
		case OPT_CALLEE_TREE:
			callee_file = optarg;
			break;
		case OPT_CVSWEB:
			cvsweb_url = optarg;
			break;
		case OPT_CVSWEB_CVSROOT:
			cvsweb_cvsroot = optarg;
			break;
		case OPT_GTAGSCONF:
		case OPT_GTAGSLABEL:
			/* These options are already parsed in preparse_options() */
			break;
		case OPT_INSERT_FOOTER:
			insert_footer = optarg;
			break;
		case OPT_INSERT_HEADER:
			insert_header = optarg;
			break;
		case OPT_HTML_HEADER:
			{
				STATIC_STRBUF(sb);
				if (!test("r", optarg))
					die("file '%s' not found.", optarg);
				strbuf_clear(sb);
				loadfile(optarg, sb);
				html_header = strbuf_value(sb);
			}
			break;
		case OPT_ITEM_ORDER:
			item_order = optarg;
			break;
		case OPT_TABS:
			if (atoi(optarg) > 0)
				tabs = atoi(optarg);
			else
				die("--tabs option requires numeric value.");
                        break;
		case OPT_NCOL:
			if (atoi(optarg) > 0)
				ncol = atoi(optarg);
			else
				die("--ncol option requires numeric value.");
                        break;
		case OPT_TREE_VIEW:
			tree_view = 1;
			if (optarg)
				tree_view_type = optarg;
			break;
                case 'a':
                        aflag++;
                        break;
                case 'd':
			strlimcpy(arg_dbpath, optarg, sizeof(arg_dbpath));
                        break;
                case 'D':
			dynamic = 1;
                        break;
                case 'f':
                        fflag++;
                        break;
                case 'F':
                        Fflag++;
                        break;
                case 'g':
                        gflag++;
                        break;
                case 'h':
			definition_header = AFTER_HEADER;
			if (optarg) {
				if (!strcmp(optarg, "before"))
					definition_header = BEFORE_HEADER;
				else if (!strcmp(optarg, "right"))
					definition_header = RIGHT_HEADER;
				else if (!strcmp(optarg, "after"))
					definition_header = AFTER_HEADER;
				else
					die("The option value of --func-header must be one of 'before', 'right' and 'after'.");
			}
                        break;
                case 'I':
                        Iflag++;
                        break;
                case 'm':
			main_func = optarg;
                        break;
                case 'n':
                        nflag++;
			if (optarg) {
				if (atoi(optarg) > 0)
					ncol = atoi(optarg);
				else
					die("The option value of --line-number must be numeric.");
			}
                        break;
                case 'o':
			other_files = 1;
                        break;
                case 's':
			symbol = 1;
                        break;
                case 'T':
			table_flist = 1;
			if (optarg) {
				if (atoi(optarg) > 0)
					flist_fields = atoi(optarg);
				else
					die("The option value of the --table-flist must be numeric.");
			}
                        break;
                case 't':
			title = optarg;
                        break;
                case 'q':
                        qflag++;
			setquiet();
                        break;
                case 'v':
                        vflag++;
			setverbose();
                        break;
                case 'w':
                        wflag++;
                        break;
                default:
                        usage();
                        break;
		}
	}
	/*
	 * Leaving everything to htags.
	 * Htags selects popular options for you.
	 */
	if (suggest2)
		suggest = 1;
	if (suggest) {
		int gtags_not_found = 0;
		char dbpath[MAXPATHLEN];

		aflag = Iflag = nflag = vflag = 1;
		setverbose();
		definition_header = AFTER_HEADER;
		other_files = symbol = show_position = table_flist = fixed_guide = 1;
		if (arg_dbpath[0]) {
			if (!test("f", makepath(arg_dbpath, dbname(GTAGS), NULL)))
				gtags_not_found = 1;
		} else if (gtagsexist(".", dbpath, sizeof(dbpath), 0) == 0) {
			gtags_not_found = 1;
		}
		if (gtags_not_found)
			gflag = 1;
	}
	if (suggest2) {
		Fflag = 1;				/* uses frame */
		fflag = dynamic = 1;			/* needs a HTTP server */
		auto_completion = tree_view = 1;	/* needs javascript */
	}
	if (call_file && !test("fr", call_file))
		die("cflow file not found. '%s'", call_file);
	if (callee_file && !test("fr", callee_file))
		die("cflow file not found. '%s'", callee_file);
	if (insert_header && !test("fr", insert_header))
		die("page header file '%s' not found.", insert_header);
	if (insert_footer && !test("fr", insert_footer))
		die("page footer file '%s' not found.", insert_footer);
	if (!fflag)
		auto_completion = 0;
        argc -= optind;
        argv += optind;
        if (!av)
                av = (argc > 0) ? *argv : NULL;

	if (debug)
		setdebug();
	settabs(tabs);					/* setup tab skip */
        if (qflag) {
                setquiet();
		vflag = 0;
	}
        if (show_version)
                version(av, vflag);
        if (show_help)
                help();
	/*
	 * Invokes gtags beforehand.
	 */
	if (gflag) {
		STRBUF *sb = strbuf_open(0);

		strbuf_puts(sb, gtags_path);
		if (vflag)
			strbuf_puts(sb, " -v");
		if (wflag)
			strbuf_puts(sb, " -w");
		if (suggest2 && enable_idutils && usable("mkid"))
			strbuf_puts(sb, " -I");
		if (arg_dbpath[0]) {
			strbuf_putc(sb, ' ');
			strbuf_puts(sb, arg_dbpath);
		}
		if (system(strbuf_value(sb)))
			die("cannot execute gtags(1) command.");
		strbuf_close(sb);
	}
	/*
	 * get dbpath.
	 */
	if (arg_dbpath[0]) {
		strlimcpy(dbpath, arg_dbpath, sizeof(dbpath));
	} else {
		int status = setupdbpath(0);
		if (status < 0)
			die_with_code(-status, "%s", gtags_dbpath_error);
		strlimcpy(dbpath, get_dbpath(), sizeof(dbpath));
	}
	if (!title) {
		char *p = strrchr(cwdpath, sep);
		title = p ? p + 1 : cwdpath;
	}
	if (cvsweb_url && test("d", "CVS"))
		use_cvs_module = 1;
	/*
	 * decide directory in which we make hypertext.
	 */
	if (av) {
		char realpath[MAXPATHLEN];

		if (!test("dw", av))
			die("'%s' is not writable directory.", av);
		if (chdir(av) < 0)
			die("directory '%s' not found.", av);
		if (!vgetcwd(realpath, sizeof(realpath)))
			die("cannot get current directory");
		if (chdir(cwdpath) < 0)
			die("cannot return to original directory.");
		snprintf(distpath, sizeof(distpath), "%s/HTML", realpath);
	} else {
		snprintf(distpath, sizeof(distpath), "%s/HTML", cwdpath);
	}
	/*
	 * Existence check of tag files.
	 */
	{
		int i;
		const char *path;
		GTOP *gtop;

		for (i = GPATH; i < GTAGLIM; i++) {
			path = makepath(dbpath, dbname(i), NULL);
			gtags_exist[i] = test("fr", path);
		}
		/*
		 * Real GRTAGS includes virtual GSYMS.
		 */
		gtags_exist[GSYMS] = symbol ? 1 : 0;
		if (!gtags_exist[GPATH] || !gtags_exist[GTAGS] || !gtags_exist[GRTAGS])
			die("GPATH, GTAGS and/or GRTAGS not found. Please reexecute htags with the -g option.");
		/*
		 * version check.
		 * Do nothing, but the version of tag file will be checked.
		 */
		gtop = gtags_open(dbpath, cwdpath, GTAGS, GTAGS_READ, 0);
		gtags_close(gtop);
		/*
		 * Check whether GRTAGS is empty.
		 */
		gtop = gtags_open(dbpath, cwdpath, GRTAGS, GTAGS_READ, 0);
		if (gtags_first(gtop, NULL, 0) == NULL)
			grtags_is_empty = 1;
		gtags_close(gtop);
	}
	/*
	 * make dbpath absolute.
	 */
	{
		char buf[MAXPATHLEN];
		if (realpath(dbpath, buf) == NULL)
			die("cannot get realpath of dbpath.");
		strlimcpy(dbpath, buf, sizeof(dbpath));
	}
	/*
	 * The older version (4.8.7 or former) of GPATH doesn't have files
         * other than source file. The oflag requires new version of GPATH.
	 */
	if (other_files) {
		GFIND *gp = gfind_open(dbpath, NULL, 0, 0);
		if (gp->version < 2)
			die("GPATH is old format. Please remake it by invoking gtags(1).");
		gfind_close(gp);
	}
	/*
	 * for global(1) and gtags(1).
	 */
	set_env("GTAGSROOT", cwdpath);
	set_env("GTAGSDBPATH", dbpath);
	set_env("GTAGSLIBPATH", "");
	/*------------------------------------------------------------------
	 * MAKE FILES
	 *------------------------------------------------------------------
	 *       HTML/cgi-bin/global.cgi ... CGI program (1)
	 *       HTML/cgi-bin/ghtml.cgi  ... unzip script (1)
	 *       HTML/.htaccess          ... skeleton of .htaccess (1)
	 *       HTML/help.html          ... help file (2)
	 *       HTML/R/                 ... references (3)
	 *       HTML/D/                 ... definitions (3)
	 *       HTML/search.html        ... search index (4)
	 *       HTML/defines.html       ... definitions index (5)
	 *       HTML/defines/           ... definitions index (5)
	 *       HTML/files/             ... file index (6)
	 *       HTML/index.html         ... index file (7)
	 *       HTML/mains.html         ... main index (8)
	 *       HTML/null.html          ... main null html (8)
	 *       HTML/S/                 ... source files (9)
	 *       HTML/I/                 ... include file index (9)
	 *       HTML/rebuild.sh         ... rebuild script (10)
	 *       HTML/style.css          ... style sheet (11)
	 *------------------------------------------------------------------
	 */
	/* for clean up */
	signal_setup();
	sethandler(clean);

        HTML = normal_suffix;

	message("[%s] Htags started", now());
	init_statistics();
	/*
	 * (#) check if GTAGS, GRTAGS is the latest.
	 */
	if (get_dbpath())
		message(" Using %s/GTAGS.", get_dbpath());
	if (grtags_is_empty)
		message(" GRTAGS is empty.");
	if (gpath_open(dbpath, 0) < 0)
		die("GPATH not found.");
	if (!w32) {
		/* UNDER CONSTRUCTION */
	}
	if (auto_completion || tree_view) {
		STATIC_STRBUF(sb);
		strbuf_clear(sb);
		strbuf_puts_nl(sb, "<script type='text/javascript' src='js/jquery.js'></script>");
		if (auto_completion)
			loadfile(makepath(datadir, "gtags/jscode_suggest", NULL), sb);
		if (tree_view)
			loadfile(makepath(datadir, "gtags/jscode_treeview", NULL), sb);
		jscode = strbuf_value(sb);
	}
	/*
	 * (0) make directories
	 */
	message("[%s] (0) making directories ...", now());
	if (!test("d", distpath))
		if (mkdir(distpath, 0777) < 0)
			die("cannot make directory '%s'.", distpath);
	make_directory_in_distpath("files");
	make_directory_in_distpath("defines");
	make_directory_in_distpath(SRCS);
	make_directory_in_distpath(INCS);
	make_directory_in_distpath(INCREFS);
	if (!dynamic) {
		make_directory_in_distpath(DEFS);
		make_directory_in_distpath(REFS);
		if (symbol)
			make_directory_in_distpath(SYMS);
	}
	if (fflag || dynamic)
		make_directory_in_distpath("cgi-bin");
	if (Iflag)
		make_directory_in_distpath("icons");
	if (auto_completion || tree_view)
		 make_directory_in_distpath("js");
	/*
	 * (1) make CGI program
	 */
	if (fflag || dynamic) {
		char cgidir[MAXPATHLEN];

		snprintf(cgidir, sizeof(cgidir), "%s/cgi-bin", distpath);
		message("[%s] (1) making CGI program ...", now());
		if (fflag || dynamic)
			makeprogram(cgidir, "global.cgi", 0755);
		if (auto_completion)
			makeprogram(cgidir, "completion.cgi", 0755);
		makehtaccess(cgidir, ".htaccess", 0644);
	} else {
		message("[%s] (1) making CGI program ...(skipped)", now());
	}
	if (av) {
		const char *path = makepath(distpath, "GTAGSROOT", NULL);
		FILE *op = fopen(path, "w");
		if (op == NULL)
			die("cannot make file '%s'.", path);
		fputs(cwdpath, op);
		fputc('\n', op);
		fclose(op);
	}
	/*
	 * (2) make help file
	 */
	message("[%s] (2) making help.html ...", now());
	makehelp("help.html");
	/*
	 * (#) load GPATH
	 */
	load_gpath(dbpath);

	/*
	 * (3) make function entries (D/ and R/)
	 *     MAKING TAG CACHE
	 */
	message("[%s] (3) making tag lists ...", now());
	cache_open();
	tim = statistics_time_start("Time of making tag lists");
	func_total = makedupindex();
	statistics_time_end(tim);
	message("Total %d functions.", func_total);
	/*
	 * (4) search index. (search.html)
	 */
	if (Fflag && fflag) {
		message("[%s] (4) making search index ...", now());
		makesearchindex("search.html");
	}
	{
		STRBUF *defines = strbuf_open(0);
		STRBUF *files = strbuf_open(0);

		/*
		 * (5) make definition index (defines.html and defines/)
		 *     PRODUCE @defines
		 */
		message("[%s] (5) making definition index ...", now());
		tim = statistics_time_start("Time of making definition index");
		func_total = makedefineindex("defines.html", func_total, defines);
		statistics_time_end(tim);
		message("Total %d functions.", func_total);
		/*
		 * (6) make file index (files.html and files/)
		 *     PRODUCE @files, %includes
		 */
		message("[%s] (6) making file index ...", now());
		init_inc();
		tim = statistics_time_start("Time of making file index");
		file_total = makefileindex("files.html", files);
		statistics_time_end(tim);
		message("Total %d files.", file_total);
		html_count += file_total;
		/*
		 * (7) make call tree using cflow(1)'s output (cflow.html)
		 */
		if (call_file || callee_file) {
			message("[%s] (7) making cflow index ...", now());
			tim = statistics_time_start("Time of making cflow index");
			if (call_file)
				if (makecflowindex("call.html", call_file) < 0)
					call_file = NULL;
			if (callee_file)
				if (makecflowindex("callee.html", callee_file) < 0)
					callee_file = NULL;
			statistics_time_end(tim);
		}
		/*
		 * [#] make include file index.
		 */
		message("[%s] (#) making include file index ...", now());
		tim = statistics_time_start("Time of making include file index");
		makeincludeindex();
		statistics_time_end(tim);
		/*
		 * [#] make a common part for mains.html and index.html
		 *     USING @defines @files
		 */
		message("[%s] (#) making a common part ...", now());
		index = makecommonpart(title, strbuf_value(defines), strbuf_value(files));

		strbuf_close(defines);
		strbuf_close(files);
	}
	/*
	 * (7)make index file (index.html)
	 */
	message("[%s] (7) making index file ...", now());
	makeindex("index.html", title, index);
	/*
	 * (8) make main index (mains.html)
	 */
	message("[%s] (8) making main index ...", now());
	makemainindex("mains.html", index);
	/*
	 * (9) make HTML files (SRCS/)
	 *     USING TAG CACHE, %includes and anchor database.
	 */
	message("[%s] (9) making hypertext from source code ...", now());
	tim = statistics_time_start("Time of making hypertext");
	makehtml(file_total);
	statistics_time_end(tim);
	/*
	 * (10) rebuild script. (rebuild.sh)
	 *
	 * Don't grant execute permission to rebuild script.
	 */
	makerebuild("rebuild.sh");
	if (chmod(makepath(distpath, "rebuild.sh", NULL), 0640) < 0)
		die("cannot chmod rebuild script.");
	/*
	 * (11) style sheet file (style.css)
	 */
	if (enable_xhtml) {
		char src[MAXPATHLEN];
		char dist[MAXPATHLEN];
		snprintf(src, sizeof(src), "%s/gtags/style.css", datadir);
		snprintf(dist, sizeof(dist), "%s/style.css", distpath);
		copyfile(src, dist);
	}
	if (auto_completion || tree_view) {
		char src[MAXPATHLEN];
		char dist[MAXPATHLEN];

		snprintf(src, sizeof(src), "%s/gtags/jquery", datadir);
		snprintf(dist, sizeof(dist), "%s/js", distpath);
		copydirectory(src, dist);
		snprintf(src, sizeof(src), "%s/gtags/jquery/images", datadir);
		snprintf(dist, sizeof(dist), "%s/js/images", distpath);
		copydirectory(src, dist);
	}
	message("[%s] Done.", now());
	if (vflag && (fflag || dynamic || auto_completion)) {
		message("\n[Information]\n");
		message(" o Htags was invoked with the -f, -c, -D or --auto-completion option. You should");
		message("   start http server so that cgi-bin/*.cgi is executed as a CGI script.");
 		message("\n If you are using Apache, 'HTML/.htaccess' might be helpful for you.\n");
		message(" Good luck!\n");
	}
	if (Iflag) {
		char src[MAXPATHLEN];
		char dist[MAXPATHLEN];

		snprintf(src, sizeof(src), "%s/gtags/icons", datadir);
		snprintf(dist, sizeof(dist), "%s/icons", distpath);
		copydirectory(src, dist);
	}
	gpath_close();
	/*
	 * Print statistics information.
	 */
	print_statistics(statistics);
	clean();
	return 0;
}
Exemple #4
0
// LAB2: below code is used to check the first fit allocation algorithm (your EXERCISE 1) 
// NOTICE: You SHOULD NOT CHANGE basic_check, default_check functions!
static void
default_check(void) {
	// 好吧,我们现在来看一下默认的测试吧!
    int count = 0, total = 0;
    list_entry_t *le = &free_list; // free_list应该是一个文件头吧!
    while ((le = list_next(le)) != &free_list) { // 开始遍历
        struct Page *p = le2page(le, page_link);
        assert(PageProperty(p));
        count ++, total += p->property; // counter表示一个有多少个page,total表示一共有多少个空闲页
    }
    assert(total == nr_free_pages());

    basic_check();

    struct Page *p0 = alloc_pages(5), *p1, *p2; // 分配5个页面给p0
    assert(p0 != NULL);
    assert(!PageProperty(p0));

    list_entry_t free_list_store = free_list;
    list_init(&free_list);
    assert(list_empty(&free_list));
    assert(alloc_page() == NULL); // 然后分配一个页面应该为空,确实应该为空

    unsigned int nr_free_store = nr_free;  // 空闲的页面的数目
    nr_free = 0; // 然后将他们全部变为0

    free_pages(p0 + 2, 3); // 这个玩意能free吗?
    assert(alloc_pages(4) == NULL); // 因为nr_free=3
    assert(PageProperty(p0 + 2) && p0[2].property == 3);
    assert((p1 = alloc_pages(3)) != NULL); // 给p1分配3块,现在nr_free=0
    assert(alloc_page() == NULL);
    assert(p0 + 2 == p1); 

    p2 = p0 + 1;
    free_page(p0); // 好吧,释放一个页面, nr_free=1
    free_pages(p1, 3); // 现在nr_free = 4
    assert(PageProperty(p0) && p0->property == 1);
    assert(PageProperty(p1) && p1->property == 3);
	/**   p0    p2    p1				end
	 *     |     |     |     |     |     |       
	 *     -------------------------------
 	 *     |  N           N     N     N  |
	 *	   |                             |
	 *     -------------------------------
	 */
    assert((p0 = alloc_page()) == p2 - 1); // 这里出错了。我倒是要看一看啦!这里应该不会出错啊,参照上面的图,重新分配的话,会分配p0,恰好是p2-1
    free_page(p0);
    assert((p0 = alloc_pages(2)) == p2 + 1); // 这里是测试first fit的
	/** start  p2    p0     		   end
	*     |     |     |     |     |     |
	*     -------------------------------
	*     |  N                       N  |
	*	  |                             |
	*     -------------------------------
	*/

    free_pages(p0, 2);
    free_page(p2);
	/** start  p2    p0     		   end
	*     |     |     |     |     |     |
	*     -------------------------------
	*     |  N     N     N     N     N  |
	*	  |                             |
	*     -------------------------------
	*/

    assert((p0 = alloc_pages(5)) != NULL);
    assert(alloc_page() == NULL);

    assert(nr_free == 0);
    nr_free = nr_free_store; // 恢复原来的样子

    free_list = free_list_store;
    free_pages(p0, 5);

    le = &free_list;
    while ((le = list_next(le)) != &free_list) { // 又要开始遍历了,这里主要是测试经过这么折腾之后,没有出现页丢失的情况
        struct Page *p = le2page(le, page_link);
        count --, total -= p->property;
    }
    assert(count == 0);
    assert(total == 0);
}