예제 #1
0
파일: support.c 프로젝트: Mailaender/bam
hash_t string_hash(const char *str_in)
{
	return string_hash_add(5381, str_in);
}
예제 #2
0
파일: main.c 프로젝트: malind/bam
/* *** */
static int bam(const char *scriptfile, const char **targets, int num_targets)
{
	struct CONTEXT context;
	int build_error = 0;
	int setup_error = 0;
	int report_done = 0;

	/* build time */
	time_t starttime  = time(0x0);

	/* create the cache and tmp directory */
	file_createdir(".bam");
	
	/* zero out and create memory heap, graph */
	memset(&context, 0, sizeof(struct CONTEXT));
	context.graphheap = mem_create();
	context.deferredheap = mem_create();
	context.graph = node_graph_create(context.graphheap);
	context.exit_on_error = option_abort_on_error;
	context.buildtime = timestamp();

	/* create lua context */
	/* HACK: Store the context pointer as the userdata pointer to the allocator to make
		sure that we have fast access to it. This makes the context_get_pointer call very fast */
	context.lua = lua_newstate(lua_alloctor_malloc, &context);

	/* install panic function */
	lua_atpanic(context.lua, lf_panicfunc);

	/* load cache (thread?) */
	if(option_no_cache == 0)
	{
		/* create a hash of all the external variables that can cause the
			script to generate different results */
		hash_t cache_hash = 0;
		char hashstr[64];
		int i;
		for(i = 0; i < option_num_scriptargs; i++)
			cache_hash = string_hash_add(cache_hash, option_scriptargs[i]);

		string_hash_tostr(cache_hash, hashstr);
		sprintf(cache_filename, ".bam/%s", hashstr);

		event_begin(0, "cache load", cache_filename);
		context.cache = cache_load(cache_filename);
		event_end(0, "cache load", NULL);
	}

	/* do the setup */
	setup_error = bam_setup(&context, scriptfile, targets, num_targets);

	/* done with the loopup heap */
	mem_destroy(context.deferredheap);

	/* close the lua state */
	lua_close(context.lua);
	
	/* do actions if we don't have any errors */
	if(!setup_error)
	{
		event_begin(0, "prepare", NULL);
		build_error = context_build_prepare(&context);
		event_end(0, "prepare", NULL);
		
		if(!build_error)
		{
			event_begin(0, "prioritize", NULL);
			build_error = context_build_prioritize(&context);
			event_end(0, "prioritize", NULL);
		}

		if(!build_error)
		{
			if(option_debug_nodes) /* debug dump all nodes */
				node_debug_dump(context.graph);
			else if(option_debug_nodes_detailed) /* debug dump all nodes detailed */
				node_debug_dump_detailed(context.graph);
			else if(option_debug_jobs) /* debug dump all jobs */
				node_debug_dump_jobs(context.graph);
			else if(option_debug_joblist) /* debug dumps the joblist */
				context_dump_joblist(&context);
			else if(option_debug_dot) /* debug dump all nodes as dot */
				node_debug_dump_dot(context.graph, context.target);
			else if(option_debug_jobs_dot) /* debug dump all jobs as dot */
				node_debug_dump_jobs_dot(context.graph, context.target);
			else if(option_dry)
			{
			}
			else
			{
				/* run build or clean */
				if(option_clean)
				{
					event_begin(0, "clean", NULL);
					build_error = context_build_clean(&context);
					event_end(0, "end", NULL);
				}
				else
				{
					event_begin(0, "build", NULL);
					build_error = context_build_make(&context);
					event_end(0, "build", NULL);
					report_done = 1;
				}
			}
		}
	}		

	/* save cache (thread?) */
	if(option_no_cache == 0 && setup_error == 0)
	{
		event_begin(0, "cache save", cache_filename);
		cache_save(cache_filename, context.graph);
		event_end(0, "cache save", NULL);
	}
	
	/* clean up */
	mem_destroy(context.graphheap);
	free(context.joblist);
	cache_free(context.cache);

	/* print final report and return */
	if(setup_error)
	{
		/* no error message on setup error, it reports fine itself */
		return setup_error;
	}
	else if(build_error)
		printf("%s: error: a build step failed\n", session.name);
	else if(report_done)
	{
		if(context.num_jobs == 0)
			printf("%s: targets are up to date already\n", session.name);
		else
		{
			time_t s = time(0x0) - starttime;
			if(s <= 1)
				printf("%s: done\n", session.name);
			else
				printf("%s: done (%d:%.2d)\n", session.name, (int)(s/60), (int)(s%60));
		}
	}

	return build_error;
}