/*
 * Copyright (c) 2001 Wichert Akkerman <wichert@cistron.nl>
 * Copyright (c) 2004-2015 Dmitry V. Levin <ldv@altlinux.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <linux/ioctl.h>

struct ioctlent {
	const char *info;
	const char *name;
	unsigned int dir;
	unsigned int type_nr;
	unsigned int size;
};

static int
is_prefix(const char *s1, const char *s2)
{
	size_t len = strlen(s1);

	if (len > strlen(s2))
		return 0;
	return !memcmp(s1, s2, len);
}

static int
compare_name_info(const void* a, const void* b)
{
	int rc;

	const char *name1 = ((struct ioctlent *) a)->name;
	const char *name2 = ((struct ioctlent *) b)->name;
	const char *info1 = ((struct ioctlent *) a)->info;
	const char *info2 = ((struct ioctlent *) b)->info;

	rc = strcmp(name1, name2);
	if (rc)
		return rc;

	/*
	 * exception from lexicographical order:
	 * "asm/" < "asm-generic/"
	 */
	if (is_prefix("asm/", info1) &&
	    is_prefix("asm-generic/", info2))
		return -1;

	if (is_prefix("asm/", info2) &&
	    is_prefix("asm-generic/", info1))
		return 1;

	return strcmp(info1, info2);
}

static unsigned int
code(const struct ioctlent *e)
{
	return e->type_nr |
		(e->size << _IOC_SIZESHIFT) |
		(e->dir << _IOC_DIRSHIFT);
}

static int
compare_code_name(const void* a, const void* b)
{
	unsigned int code1 = code((struct ioctlent *) a);
	unsigned int code2 = code((struct ioctlent *) b);
	const char *name1 = ((struct ioctlent *) a)->name;
	const char *name2 = ((struct ioctlent *) b)->name;
	return (code1 > code2) ?
		1 : (code1 < code2) ? -1 : strcmp(name1, name2);
}

static void
ioctlsort(struct ioctlent *ioctls, size_t nioctls)
{
	size_t i;

	qsort(ioctls, nioctls, sizeof(ioctls[0]), compare_name_info);

	for (i = 1; i < nioctls; ++i)
		if (!strcmp(ioctls[i-1].name, ioctls[i].name)) {
			/*
			 * If there are multiple definitions for the same
			 * name, keep the first one and mark all the rest
			 * for deletion.
			 */
			ioctls[i].info = NULL;
		}

	for (i = 1; i < nioctls; ++i)
		if (!ioctls[i].info) {
			/*
			 * Change ioctl code of marked elements
			 * to make them sorted to the end of array.
			 */
			ioctls[i].dir =
			ioctls[i].type_nr =
			ioctls[i].size = 0xffffffffu;
		}

	qsort(ioctls, nioctls, sizeof(ioctls[0]), compare_code_name);

	puts("/* Generated by ioctlsort. */");
	for (i = 0; i < nioctls; ++i) {
		if (!ioctls[i].info) {
			/*
			 * We've reached the first element marked for deletion.
			 */
			break;
		}
		if (i == 0 || code(&ioctls[i-1]) != code(&ioctls[i]) ||
		    !is_prefix(ioctls[i-1].name, ioctls[i].name))
			printf("{ \"%s\", %#010x },\n",
				ioctls[i].name, code(ioctls+i));
	}
}

static struct ioctlent ioctls[] = {
#ifdef IOCTLSORT_INC
# include IOCTLSORT_INC
#else
# include "ioctls_arch.h"
# include "ioctls_inc.h"
#endif
};

int
main(void)
{
	ioctlsort(ioctls, sizeof(ioctls) / sizeof(ioctls[0]));
	return 0;
}
