<commit_before>/*
 * This file is part of Kotaka, a mud library for DGD
 * http://github.com/shentino/kotaka
 *
 * Copyright (C) 2018, 2021  <NAME>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include <status.h>
#include <kotaka/paths/system.h>
#include <kotaka/paths/verb.h>
#include <kotaka/assert.h>
#include <kotaka/log.h>

inherit LIB_VERB;
inherit "/lib/sort";
inherit "~System/lib/struct/list";

string *query_parse_methods()
{
	return ({ "raw" });
}

/*

an object is stale if:

* it inherits a destructed library
* any of its sources either don't exist or were modified after the object was compiled

*/

static void report_tick(mixed **list, object user, object proxy)
{
	int ctime, pindex, sz;
	mapping srcstat;
	mixed *info, *libs;
	object pinfo;
	string *incs, *libnames;
	string path;

	pindex = list_front(list);
	list_pop_front(list);

	if (!list_empty(list)) {
		call_out("report_tick", 0, list, user, proxy);
	}

	pinfo = OBJECTD->query_program_info(pindex);
	path = pinfo->query_path();

	if (pinfo->query_destructed()) {
		return;
	}

	libs = pinfo->query_inherits();
	libnames = ({ });
	ASSERT(libs);

	for (sz = sizeof(libs); --sz >= 0; ) {
		object pinfo2;

		pinfo2 = OBJECTD->query_program_info(libs[sz]);

		if (pinfo2->query_destructed()) {
			libnames += ({ pinfo2->query_path() });
		}
	}

	ctime = status(path, O_COMPILETIME);

	srcstat = ([ ]);
	/* 1 = modified */
	/* -1 = missing */

	info = proxy->file_info(path + ".c");

	if (!info) {
		srcstat[path + ".c"] = -1;
	} else if (info[1] > ctime) {
		srcstat[path + ".c"] = 1;
	}

	incs = pinfo->query_includes();

	for (sz = sizeof(incs); --sz >= 0; ) {
		string inc;

		inc = incs[sz];

		info = proxy->file_info(inc);

		if (!info) {
			srcstat[inc] = -1;
		} else if (info[1] > ctime) {
			srcstat[inc] = 1;
		}
	}

	if (map_sizeof(srcstat) || sizeof(libnames)) {
		int sz;
		int i;

		user->message("\n" + path + " is stale\n");

		qsort(libnames, 0, sizeof(libnames));

		if (sz = sizeof(libnames)) {
			user->message("  Destructed inherits\n");

			for (; i < sz; i++) {
				user->message("    " + libnames[i] + "\n");
			}

			if (map_sizeof(srcstat)) {
				user->message("\n");
			}
		}

		if (map_sizeof(srcstat)) {
			user->message("  Missing or modified sources\n");
		}

		switch (srcstat[path + ".c"]) {<commit_msg>Patch qsort to quicksort in stale verb<commit_after>/*
 * This file is part of Kotaka, a mud library for DGD
 * http://github.com/shentino/kotaka
 *
 * Copyright (C) 2018, 2021  <NAME>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include <status.h>
#include <kotaka/paths/system.h>
#include <kotaka/paths/verb.h>
#include <kotaka/assert.h>
#include <kotaka/log.h>

inherit LIB_VERB;
inherit "/lib/sort";
inherit "~System/lib/struct/list";

string *query_parse_methods()
{
	return ({ "raw" });
}

/*

an object is stale if:

* it inherits a destructed library
* any of its sources either don't exist or were modified after the object was compiled

*/

static void report_tick(mixed **list, object user, object proxy)
{
	int ctime, pindex, sz;
	mapping srcstat;
	mixed *info, *libs;
	object pinfo;
	string *incs, *libnames;
	string path;

	pindex = list_front(list);
	list_pop_front(list);

	if (!list_empty(list)) {
		call_out("report_tick", 0, list, user, proxy);
	}

	pinfo = OBJECTD->query_program_info(pindex);
	path = pinfo->query_path();

	if (pinfo->query_destructed()) {
		return;
	}

	libs = pinfo->query_inherits();
	libnames = ({ });
	ASSERT(libs);

	for (sz = sizeof(libs); --sz >= 0; ) {
		object pinfo2;

		pinfo2 = OBJECTD->query_program_info(libs[sz]);

		if (pinfo2->query_destructed()) {
			libnames += ({ pinfo2->query_path() });
		}
	}

	ctime = status(path, O_COMPILETIME);

	srcstat = ([ ]);
	/* 1 = modified */
	/* -1 = missing */

	info = proxy->file_info(path + ".c");

	if (!info) {
		srcstat[path + ".c"] = -1;
	} else if (info[1] > ctime) {
		srcstat[path + ".c"] = 1;
	}

	incs = pinfo->query_includes();

	for (sz = sizeof(incs); --sz >= 0; ) {
		string inc;

		inc = incs[sz];

		info = proxy->file_info(inc);

		if (!info) {
			srcstat[inc] = -1;
		} else if (info[1] > ctime) {
			srcstat[inc] = 1;
		}
	}

	if (map_sizeof(srcstat) || sizeof(libnames)) {
		int sz;
		int i;

		user->message("\n" + path + " is stale\n");

		quicksort(libnames, 0, sizeof(libnames));

		if (sz = sizeof(libnames)) {
			user->message("  Destructed inherits\n");

			for (; i < sz; i++) {
				user->message("    " + libnames[i] + "\n");
			}

			if (map_sizeof(srcstat)) {
				user->message("\n");
			}
		}

		if (map_sizeof(srcstat)) {
			user->message("  Missing or modified sources\n");
		}

		switch (srcstat[path + ".c"]) {
{'fraction_non_alphanumeric': 0.15462696667230588, 'fraction_numerical': 0.00845880561664693, 'mean_word_length': 3.4686318972033257, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6256067', 'n_tokens_mistral': 2293, 'n_tokens_neox': 2074, 'n_words': 624}