Re: [PATCH 0/7] minmax: reduce compilation time

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, 26 Jul 2024 at 21:13, Linus Torvalds
<torvalds@xxxxxxxxxxxxxxxxxxx> wrote:
>
> Anyway, I'm throwing this out in the hopes that somebody will use this
> to go "look, file XYZ generates a ridiculous X-megabyte line".

Oh, and by "throwing this out" I meant to actually include the updated
"longest-line.c".

And somebody sane can write it in two lines of perl instead.

                Linus
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>

static void die(const char *reason)
{
	fprintf(stderr, "Fatal: %s\n", reason);
	exit(1);
}

static unsigned long find_line(const char *line, unsigned long len)
{
	unsigned long res = 0;
	do {
		res++;
		if (*line == '\n')
			break;
		line++;
	} while (--len);
	return res;
}

/*
 * By this time, we know the line length, and it has been
 * NUL-terminated. We can change it and use the underlying
 * data if we find a preprocessor linemarker.
 */
void track_cpp_line_number(char *line, unsigned long len,
	int *lineno, const char **filename)
{
	unsigned long num;
	char *end;

	if (line[0] != '#')
		return;
	if (line[1] != ' ')
		return;

	line += 2;
	len -= 2;

	num = strtoul(line, &end, 10);
	if (!num)
		return;
	if (end == line)
		return;

	len -= end - line;
	line = end;

	// Remove flag at the end
	if (len > 2) {
		if (line[len-2] == ' ' && isdigit(line[len-1])) {
			line[len-2] = 0;
			len -= 2;
		}			
	}

	// Remove spaces from end
	while (len > 1 && line[len-1] == ' ')
		line[--len] = 0;

	// We're done with 'len' now, don't bother */
	while (*line == ' ')
		line++;

	if (*line == '"') {
		end = strchr(++line, '"');
		if (end)
			*end = 0;
	}
	while (!strncmp(line, "./", 2))
		line += 2;

	*lineno = num-1;
	if (*line)
		*filename = line;
}

int main(int argc, char **argv)
{
	struct stat st;
	char *buf;
	unsigned long size;
	long longest_len = 0;
	char *longest_line = "";
	int longest_lineno = 0;
	const char *longest_file = "";
	const char *file;
	const char *unit;
	int lineno = 0, fd;

	fd = 0;
	file = "stdin";
	if (argc > 1) {
		file = argv[1];
		fd = open(file, O_RDONLY);
		if (fd < 0) die("open");
	}

	if (fstat(fd, &st)) die("stat");
	if (!S_ISREG(st.st_mode)) die("Not a regularfile");
	size = st.st_size;
	buf = malloc(size+1);
	if (!buf) die("malloc failed");
	if (read(fd, buf, size) != size) die("read failed");

	for (lineno = 1; size; lineno++) {
		unsigned long len;
		char *line = buf;

		/* Find the line, NUL-terminate it */
		len = find_line(buf, size);
		buf[len-1] = 0;

		buf += len;
		size -= len;

		/* Track preprocessor info */
		track_cpp_line_number(line, len-1, &lineno, &file);

		if (len <= longest_len)
			continue;

		longest_len = len;
		longest_line = line;
		longest_file = file;
		longest_lineno = lineno;
	}

	/* Limit printout of longest line arbitrarily */
	if (longest_len > 104)
		memcpy(longest_line + 100, "...", 4);

	unit = " bytes";
	if (longest_len > 10*1024) {
		unit = "kB";
		longest_len = (longest_len+512) / 1024;
	}

	printf("Longest line is %s:%d (%lu%s)\n",
		longest_file,
		longest_lineno,
		longest_len, unit);
	printf("   '%s'\n", longest_line);
	return 0;
}

[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux