<commit_before>/*  XMMS2 - X Music Multiplexer System
 *  Copyright (C) 2003-2008 XMMS2 Team
 *
 *  PLUGINS ARE NOT CONSIDERED TO BE DERIVED WORK !!!
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 */
#include "cmd_pls.h"
#include "common.h"


cmds plist_commands[] = {
	{ "list", "List all available playlists", cmd_playlists_list },
	{ "active", "Displays the name of the active playlist", cmd_playlist_active },
	{ "create", "[playlistname] - Create a playlist", cmd_playlist_create },
	{ "type", "[playlistname] [type] - Set the type of the playlist (list, queue, pshuffle)", cmd_playlist_type },
	{ "load", "[playlistname] - Load 'playlistname' stored in medialib", cmd_playlist_load },
	{ "remove", "[playlistname] - Remove a playlist", cmd_playlist_remove },
	{ NULL, NULL, NULL },
};


extern gchar *listformat;

static void
add_item_to_playlist (xmmsc_connection_t *conn, gchar *playlist, gchar *item)
{
	xmmsc_result_t *res;
	gchar *url;

	url = format_url (item, G_FILE_TEST_IS_REGULAR);
	if (!url) {
		print_error ("Invalid url");
	}

	res = xmmsc_playlist_add_url (conn, playlist, url);
	xmmsc_result_wait (res);
	g_free (url);

	if (xmmsc_result_iserror (res)) {
		print_error ("Couldn't add %s to playlist: %s\n", item,
		             xmmsc_result_get_error (res));
	}
	xmmsc_result_unref (res);

	print_info ("Added %s", item);
}


static const gchar *
get_playlist_type_string (xmmsc_coll_type_t type)
{
	switch (type) {
	case XMMS_COLLECTION_TYPE_IDLIST:        return "list";
	case XMMS_COLLECTION_TYPE_QUEUE:         return "queue";
	case XMMS_COLLECTION_TYPE_PARTYSHUFFLE:  return "pshuffle";
	default:                                 return "unknown";
	}
}

static void
coll_copy_attributes (const char *key, const char *value, void *udata)
{
	xmmsc_coll_t *coll = (xmmsc_coll_t*) udata;

	xmmsc_coll_attribute_set (coll, key, value);
}

static void
playlist_setup_pshuffle (xmmsc_connection_t *conn, xmmsc_coll_t *coll, gchar *ref)
{
	xmmsc_result_t *psres;
	xmmsc_coll_t *refcoll;
	gchar *s_name, *s_namespace;

	if (!coll_read_collname (ref, &s_name, &s_namespace)) {
		print_error ("invalid source collection name");
	}

	/* Quick shortcut to use Universe for "All Media" */
	if (strcmp (s_name, "All Media") == 0) {
		refcoll = xmmsc_coll_universe ();
	} else {
		psres = xmmsc_coll_get (conn, s_name, s_namespace);
		xmmsc_result_wait (psres);

		if (xmmsc_result_iserror (psres)) {
			print_error ("%s", xmmsc_result_get_error (psres));
		}

		refcoll = xmmsc_coll_new (XMMS_COLLECTION_TYPE_REFERENCE);
		xmmsc_coll_attribute_set (refcoll, "reference", s_name);
		xmmsc_coll_attribute_set (refcoll, "namespace", s_namespace);
	}

	/* Set operand */
	xmmsc_coll_add_operand (coll, refcoll);
	xmmsc_coll_unref (refcoll);

	g_free (s_name);
	g_free (s_namespace);
}


static void
cmd_playlist_help (void) {
	gint i;

	print_info ("Available playlist commands:");
	for (i = 0; plist_commands[i].name; i++) {
		print_info ("  %s\t %s", plist_commands[i].name,
		            plist_commands[i].help);
	}
}


void
cmd_playlist (xmmsc_connection_t *conn, gint argc, gchar **argv)
{
	gint i;
	if (argc < 3) {
		cmd_playlist_help ();
		return;
	}

	for (i = 0; plist_commands[i].name; i++) {
		if (g_ascii_strcasecmp (plist_commands[i].name, argv[2]) == 0) {
			plist_commands[i].func (conn, argc, argv);
			return;
		}
	}

	cmd_playlist_help ();
	print_error ("Unrecognised playlist command: %s", argv[2]);
}


void
cmd_addid (xmmsc_connection_t *conn, gint argc, gchar **argv)
{
	gint i;
	gchar *playlist = NULL;
	xmmsc_result_t *res;

	if (argc < 3) {
		print_error ("Need a medialib id to add");
	}

	for (i = 2; argv[i]; i++) {
		guint id = strtoul (argv[i], NULL, 10);
		if (id) {
			res = xmmsc_playlist_add_id (conn, playlist, id);
			xmmsc_result_wait (res);

			if (xmmsc_result_iserror (res)) {
				print_error ("Couldn't add %d to playlist: %s", id,
				             xmmsc_result_get_error (res));
			}
			xmmsc_result_unref (res);

			print_info ("Added medialib id %d to playlist", id);
		} else if (i == 2) {
			/* First argument is the playlist name */
			playlist = argv[i];
		}
	}
}

void
cmd_add (xmmsc_connection_t *conn, gint argc, gchar **argv)
{
	gchar *playlist = NULL;
	gint i;

	if (argc < 3) {
		print_error ("Need a filename to add");
	}

	for (i = 2; argv[i]; i++) {
		/* FIXME: Fulhack to check for optional playlist argument */
		if (i == 2 && argc > 3 && !g_file_test (argv[i], G_FILE_TEST_EXISTS)) {
			playlist = argv[i++];
		}

		add_item_to_playlist (conn, playlist, argv[i]);
	}
}

void
cmd_addarg (xmmsc_connection_t *conn, gint argc, gchar **argv)
{
	xmmsc_result_t *res;
	gchar *playlist = NULL;
	gchar *url;
	int arg_start = 3;

	if (argc < 4) {
		print_error ("Need a filename and args to add");
	}

	url = format_url (argv[2], G_FILE_TEST_IS_REGULAR);
	if (!url) {
		url = format_url (argv[3], G_FILE_TEST_IS_REGULAR);
		if (!url) {
			print_error ("Invalid url");
		} else {
			/* FIXME: Fulhack to check for optional playlist argument */
			playlist = argv[2];
			arg_start = 4;
		}
	}

	/* Relax, it was const before.. Could we fix const-ness nicely? */
	res = xmmsc_playlist_add_args (conn, playlist, url, argc - arg_start,
	                               (const gchar **)&argv[arg_start]);
	xmmsc_result_wait (res);

	if (xmmsc_result_iserror (res)) {
		print_error ("Couldn't add %s to playlist: %s\n", url,
		             xmmsc_result_get_error (res));
	}
	xmmsc_result_unref (res);

	print_info ("Added %s", url);

	g_free (url);
}

void
cmd_insert (xmmsc_connection_t *conn, gint argc, gchar **argv)
{
	gchar *playlist = NULL;
	guint pos;
	gchar *url;
	char *endptr;
	xmmsc_result_t *res;

	if (argc < 4) {
		print_error ("Need a position and a file");
	}

	pos = strtol (argv[2], &endptr, 10);
	if (*endptr == '\0') {
		url = format_url (argv[3], G_FILE_TEST_IS_REGULAR);  /* No playlist name */
	}
	else {
		playlist = argv[2];  /* extract playlist name */
		pos = strtol (argv[3], NULL, 10);
		url = format_url (argv[4], G_FILE_TEST_IS_REGULAR);
	}

	if (!url) {
		print_error ("Invalid url");
	}

	res = xmmsc_playlist_insert_url (conn, playlist, pos, url);
	xmmsc_result_wait (res);

	if (xmmsc_result_iserror (res)) {
		print_error ("Unable to add %s at postion %u: %s", url,
		             pos, xmmsc_result_get_error (res));
	}
	xmmsc_result_unref (res);

	print_info ("Inserted %s at %u", url, pos);

	g_free (url);
}

void
cmd_insertid (xmmsc_connection_t *conn, gint argc, gchar **argv)
{
	gchar *playlist = NULL;
	guint pos, mlib_id;
	char *endptr;
	xmmsc_result_t *res;

	if (argc < 4) {
		print_error ("Need a position and a medialib id");
	}

	pos = strtol (argv[2], &endptr, 10);
	if (*endptr == '\0') {
		mlib_id = strtol (argv[3], NULL, 10); /* No playlist name */
	}
	else {
		playlist = argv[2];  /* extract playlist name */
		pos = strtol (argv[3], NULL, 10);
		mlib_id = strtol (argv[4], NULL, 10);
	}

	res = xmmsc_playlist_insert_id (conn, playlist, pos, mlib_id);
	xmmsc_result_wait (res);

	if (xmmsc_result_iserror (res)) {
		print_error ("Unable to insert %u at position %u: %s", mlib_id,
		             pos, xmmsc_result_get_error (res));
	}

	print_info ("Inserted %u at position %u", mlib_id, pos);

	xmmsc_result_unref (res);
}

void
cmd_radd (xmmsc_connection_t *conn, gint argc, gchar **argv)
{
	gchar *playlist = NULL;
	xmmsc_result_t *res;
	gint i;

	if (argc < 3) {
		print_error ("Missing argument(s)");
	}

	for (i = 2; i < argc; i++) {
		gchar *rfile;

		if (i == 2 && argc > 3 && !g_file_test (argv[i], G_FILE_TEST_EXISTS)) {
			playlist = argv[i];
			continue;
		}

		rfile = format_url (argv[i], G_FILE_TEST_IS_DIR);
		if (!rfile) {
			print_info ("Ignoring invalid path '%s'", argv[i]);
			continue;
		}

		res = xmmsc_playlist_radd (conn, playlist, rfile);
		g_free (rfile);

		xmmsc_result_wait (res);

		if (xmmsc_result_iserror (res)) {
			print_info ("Cannot add path '%s': %s",
			            argv[i], xmmsc_result_get_error (res));
		}

		xmmsc_result_unref (res);
	}
}

void
cmd_clear (xmmsc_connection_t *conn, gint argc, gchar **argv)
{
	gchar *playlist = NULL;
	xmmsc_result_t *res;

	if (argc == 3) {
		playlist = argv[2];
	}

	res = xmmsc_playlist_clear (conn, playlist);
	xmmsc_result_wait (res);

	if (xmmsc_result_iserror (res)) {
		print_error ("%s", xmmsc_result_get_error (res));
	}
	xmmsc_result_unref (res);
}


void
cmd_shuffle (xmmsc_connection_t *conn, gint argc, gchar **argv)
{
	gchar *playlist = NULL;
	xmmsc_result_t *res;

	if (argc == 3) {
		playlist = argv[2];
	}

	res = xmmsc_playlist_shuffle (conn, playlist);
	xmmsc_result_wait (res);

	if (xmmsc_result_iserror (res)) {
		print_error ("%s", xmmsc_result_get_error (res));
	}
	xmmsc_result_unref (res);
}


const gchar **
copy_string_array (gchar **array, gint num)
{
	gint i;
	const gchar **ret;

	ret = g_new (const gchar*, num + 1);

	for (i = 0; i < num; i++) {
		ret[i] = array[i];
	}
	ret[i] = NULL;

	return ret;
}

void
cmd_sort (xmmsc_connection_t *conn, gint argc, gchar **argv)
{
	gchar *playlist;
	const gchar **sortby;
	xmmsc_result_t *res;
	
	if (argc < 3) {
		print_error ("Sort needs a property to sort on, %d", argc);
	} else if (argc == 3) {
		playlist = NULL;
		sortby = copy_string_array (&argv[2], argc - 2);
	} else {
		playlist = argv[2];
		sortby = copy_string_array (&argv[3], argc - 3);
	}

	res = xmmsc_playlist_sort (conn, playlist, sortby);
	xmmsc_result_wait (res);

	if (xmmsc_result_iserror (res)) {
		print_error ("%s", xmmsc_result_get_error (res));
	}
	xmmsc_result_unref (res);

	g_free (sortby);
}


gint
cmp (const void *av, const void *bv)
{
	gint result;
	gint a = *(gint *) av;
	gint b = *(gint *) bv;

	result = (a > b ? -1 : 1);
<commit_msg>OTHER: Whitespace fix in src/clients/cli/cmd_pls.c.<commit_after>/*  XMMS2 - X Music Multiplexer System
 *  Copyright (C) 2003-2008 XMMS2 Team
 *
 *  PLUGINS ARE NOT CONSIDERED TO BE DERIVED WORK !!!
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 */
#include "cmd_pls.h"
#include "common.h"


cmds plist_commands[] = {
	{ "list", "List all available playlists", cmd_playlists_list },
	{ "active", "Displays the name of the active playlist", cmd_playlist_active },
	{ "create", "[playlistname] - Create a playlist", cmd_playlist_create },
	{ "type", "[playlistname] [type] - Set the type of the playlist (list, queue, pshuffle)", cmd_playlist_type },
	{ "load", "[playlistname] - Load 'playlistname' stored in medialib", cmd_playlist_load },
	{ "remove", "[playlistname] - Remove a playlist", cmd_playlist_remove },
	{ NULL, NULL, NULL },
};


extern gchar *listformat;

static void
add_item_to_playlist (xmmsc_connection_t *conn, gchar *playlist, gchar *item)
{
	xmmsc_result_t *res;
	gchar *url;

	url = format_url (item, G_FILE_TEST_IS_REGULAR);
	if (!url) {
		print_error ("Invalid url");
	}

	res = xmmsc_playlist_add_url (conn, playlist, url);
	xmmsc_result_wait (res);
	g_free (url);

	if (xmmsc_result_iserror (res)) {
		print_error ("Couldn't add %s to playlist: %s\n", item,
		             xmmsc_result_get_error (res));
	}
	xmmsc_result_unref (res);

	print_info ("Added %s", item);
}


static const gchar *
get_playlist_type_string (xmmsc_coll_type_t type)
{
	switch (type) {
	case XMMS_COLLECTION_TYPE_IDLIST:        return "list";
	case XMMS_COLLECTION_TYPE_QUEUE:         return "queue";
	case XMMS_COLLECTION_TYPE_PARTYSHUFFLE:  return "pshuffle";
	default:                                 return "unknown";
	}
}

static void
coll_copy_attributes (const char *key, const char *value, void *udata)
{
	xmmsc_coll_t *coll = (xmmsc_coll_t*) udata;

	xmmsc_coll_attribute_set (coll, key, value);
}

static void
playlist_setup_pshuffle (xmmsc_connection_t *conn, xmmsc_coll_t *coll, gchar *ref)
{
	xmmsc_result_t *psres;
	xmmsc_coll_t *refcoll;
	gchar *s_name, *s_namespace;

	if (!coll_read_collname (ref, &s_name, &s_namespace)) {
		print_error ("invalid source collection name");
	}

	/* Quick shortcut to use Universe for "All Media" */
	if (strcmp (s_name, "All Media") == 0) {
		refcoll = xmmsc_coll_universe ();
	} else {
		psres = xmmsc_coll_get (conn, s_name, s_namespace);
		xmmsc_result_wait (psres);

		if (xmmsc_result_iserror (psres)) {
			print_error ("%s", xmmsc_result_get_error (psres));
		}

		refcoll = xmmsc_coll_new (XMMS_COLLECTION_TYPE_REFERENCE);
		xmmsc_coll_attribute_set (refcoll, "reference", s_name);
		xmmsc_coll_attribute_set (refcoll, "namespace", s_namespace);
	}

	/* Set operand */
	xmmsc_coll_add_operand (coll, refcoll);
	xmmsc_coll_unref (refcoll);

	g_free (s_name);
	g_free (s_namespace);
}


static void
cmd_playlist_help (void) {
	gint i;

	print_info ("Available playlist commands:");
	for (i = 0; plist_commands[i].name; i++) {
		print_info ("  %s\t %s", plist_commands[i].name,
		            plist_commands[i].help);
	}
}


void
cmd_playlist (xmmsc_connection_t *conn, gint argc, gchar **argv)
{
	gint i;
	if (argc < 3) {
		cmd_playlist_help ();
		return;
	}

	for (i = 0; plist_commands[i].name; i++) {
		if (g_ascii_strcasecmp (plist_commands[i].name, argv[2]) == 0) {
			plist_commands[i].func (conn, argc, argv);
			return;
		}
	}

	cmd_playlist_help ();
	print_error ("Unrecognised playlist command: %s", argv[2]);
}


void
cmd_addid (xmmsc_connection_t *conn, gint argc, gchar **argv)
{
	gint i;
	gchar *playlist = NULL;
	xmmsc_result_t *res;

	if (argc < 3) {
		print_error ("Need a medialib id to add");
	}

	for (i = 2; argv[i]; i++) {
		guint id = strtoul (argv[i], NULL, 10);
		if (id) {
			res = xmmsc_playlist_add_id (conn, playlist, id);
			xmmsc_result_wait (res);

			if (xmmsc_result_iserror (res)) {
				print_error ("Couldn't add %d to playlist: %s", id,
				             xmmsc_result_get_error (res));
			}
			xmmsc_result_unref (res);

			print_info ("Added medialib id %d to playlist", id);
		} else if (i == 2) {
			/* First argument is the playlist name */
			playlist = argv[i];
		}
	}
}

void
cmd_add (xmmsc_connection_t *conn, gint argc, gchar **argv)
{
	gchar *playlist = NULL;
	gint i;

	if (argc < 3) {
		print_error ("Need a filename to add");
	}

	for (i = 2; argv[i]; i++) {
		/* FIXME: Fulhack to check for optional playlist argument */
		if (i == 2 && argc > 3 && !g_file_test (argv[i], G_FILE_TEST_EXISTS)) {
			playlist = argv[i++];
		}

		add_item_to_playlist (conn, playlist, argv[i]);
	}
}

void
cmd_addarg (xmmsc_connection_t *conn, gint argc, gchar **argv)
{
	xmmsc_result_t *res;
	gchar *playlist = NULL;
	gchar *url;
	int arg_start = 3;

	if (argc < 4) {
		print_error ("Need a filename and args to add");
	}

	url = format_url (argv[2], G_FILE_TEST_IS_REGULAR);
	if (!url) {
		url = format_url (argv[3], G_FILE_TEST_IS_REGULAR);
		if (!url) {
			print_error ("Invalid url");
		} else {
			/* FIXME: Fulhack to check for optional playlist argument */
			playlist = argv[2];
			arg_start = 4;
		}
	}

	/* Relax, it was const before.. Could we fix const-ness nicely? */
	res = xmmsc_playlist_add_args (conn, playlist, url, argc - arg_start,
	                               (const gchar **)&argv[arg_start]);
	xmmsc_result_wait (res);

	if (xmmsc_result_iserror (res)) {
		print_error ("Couldn't add %s to playlist: %s\n", url,
		             xmmsc_result_get_error (res));
	}
	xmmsc_result_unref (res);

	print_info ("Added %s", url);

	g_free (url);
}

void
cmd_insert (xmmsc_connection_t *conn, gint argc, gchar **argv)
{
	gchar *playlist = NULL;
	guint pos;
	gchar *url;
	char *endptr;
	xmmsc_result_t *res;

	if (argc < 4) {
		print_error ("Need a position and a file");
	}

	pos = strtol (argv[2], &endptr, 10);
	if (*endptr == '\0') {
		url = format_url (argv[3], G_FILE_TEST_IS_REGULAR);  /* No playlist name */
	}
	else {
		playlist = argv[2];  /* extract playlist name */
		pos = strtol (argv[3], NULL, 10);
		url = format_url (argv[4], G_FILE_TEST_IS_REGULAR);
	}

	if (!url) {
		print_error ("Invalid url");
	}

	res = xmmsc_playlist_insert_url (conn, playlist, pos, url);
	xmmsc_result_wait (res);

	if (xmmsc_result_iserror (res)) {
		print_error ("Unable to add %s at postion %u: %s", url,
		             pos, xmmsc_result_get_error (res));
	}
	xmmsc_result_unref (res);

	print_info ("Inserted %s at %u", url, pos);

	g_free (url);
}

void
cmd_insertid (xmmsc_connection_t *conn, gint argc, gchar **argv)
{
	gchar *playlist = NULL;
	guint pos, mlib_id;
	char *endptr;
	xmmsc_result_t *res;

	if (argc < 4) {
		print_error ("Need a position and a medialib id");
	}

	pos = strtol (argv[2], &endptr, 10);
	if (*endptr == '\0') {
		mlib_id = strtol (argv[3], NULL, 10); /* No playlist name */
	}
	else {
		playlist = argv[2];  /* extract playlist name */
		pos = strtol (argv[3], NULL, 10);
		mlib_id = strtol (argv[4], NULL, 10);
	}

	res = xmmsc_playlist_insert_id (conn, playlist, pos, mlib_id);
	xmmsc_result_wait (res);

	if (xmmsc_result_iserror (res)) {
		print_error ("Unable to insert %u at position %u: %s", mlib_id,
		             pos, xmmsc_result_get_error (res));
	}

	print_info ("Inserted %u at position %u", mlib_id, pos);

	xmmsc_result_unref (res);
}

void
cmd_radd (xmmsc_connection_t *conn, gint argc, gchar **argv)
{
	gchar *playlist = NULL;
	xmmsc_result_t *res;
	gint i;

	if (argc < 3) {
		print_error ("Missing argument(s)");
	}

	for (i = 2; i < argc; i++) {
		gchar *rfile;

		if (i == 2 && argc > 3 && !g_file_test (argv[i], G_FILE_TEST_EXISTS)) {
			playlist = argv[i];
			continue;
		}

		rfile = format_url (argv[i], G_FILE_TEST_IS_DIR);
		if (!rfile) {
			print_info ("Ignoring invalid path '%s'", argv[i]);
			continue;
		}

		res = xmmsc_playlist_radd (conn, playlist, rfile);
		g_free (rfile);

		xmmsc_result_wait (res);

		if (xmmsc_result_iserror (res)) {
			print_info ("Cannot add path '%s': %s",
			            argv[i], xmmsc_result_get_error (res));
		}

		xmmsc_result_unref (res);
	}
}

void
cmd_clear (xmmsc_connection_t *conn, gint argc, gchar **argv)
{
	gchar *playlist = NULL;
	xmmsc_result_t *res;

	if (argc == 3) {
		playlist = argv[2];
	}

	res = xmmsc_playlist_clear (conn, playlist);
	xmmsc_result_wait (res);

	if (xmmsc_result_iserror (res)) {
		print_error ("%s", xmmsc_result_get_error (res));
	}
	xmmsc_result_unref (res);
}


void
cmd_shuffle (xmmsc_connection_t *conn, gint argc, gchar **argv)
{
	gchar *playlist = NULL;
	xmmsc_result_t *res;

	if (argc == 3) {
		playlist = argv[2];
	}

	res = xmmsc_playlist_shuffle (conn, playlist);
	xmmsc_result_wait (res);

	if (xmmsc_result_iserror (res)) {
		print_error ("%s", xmmsc_result_get_error (res));
	}
	xmmsc_result_unref (res);
}


const gchar **
copy_string_array (gchar **array, gint num)
{
	gint i;
	const gchar **ret;

	ret = g_new (const gchar*, num + 1);

	for (i = 0; i < num; i++) {
		ret[i] = array[i];
	}
	ret[i] = NULL;

	return ret;
}

void
cmd_sort (xmmsc_connection_t *conn, gint argc, gchar **argv)
{
	gchar *playlist;
	const gchar **sortby;
	xmmsc_result_t *res;

	if (argc < 3) {
		print_error ("Sort needs a property to sort on, %d", argc);
	} else if (argc == 3) {
		playlist = NULL;
		sortby = copy_string_array (&argv[2], argc - 2);
	} else {
		playlist = argv[2];
		sortby = copy_string_array (&argv[3], argc - 3);
	}

	res = xmmsc_playlist_sort (conn, playlist, sortby);
	xmmsc_result_wait (res);

	if (xmmsc_result_iserror (res)) {
		print_error ("%s", xmmsc_result_get_error (res));
	}
	xmmsc_result_unref (res);

	g_free (sortby);
}


gint
cmp (const void *av, const void *bv)
{
	gint result;
	gint a = *(gint *) av;
	gint b = *(gint *) bv;

	result = (a > b ? -1 : 1);

{'fraction_non_alphanumeric': 0.13945494721335625, 'fraction_numerical': 0.007758409035109256, 'mean_word_length': 3.8617808546192407, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2979976', 'n_tokens_mistral': 8666, 'n_tokens_neox': 8311, 'n_words': 2148}