#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdlib.h>
static void calcchars(int *counts, const char *buf)
{
for (; *buf; buf++)
if ((*buf & ~0x20) >= 'A' &&
(*buf & ~0x20) <= 'Z')
counts[(*buf & ~0x20) - 'A']++;
}
static int calccmp(int *target, int *candidate)
{
int i;
for (i = 0; i <= 'Z' - 'A'; i++)
if (target[i] < candidate[i])
return false;
return true;
}
struct result {
char *str;
size_t sl;
};
int rescmp(const void *a, const void *b)
{
const struct result *ar = a;
const struct result *br = b;
if (ar->sl - br->sl)
return br->sl - ar->sl;
return strcmp(ar
->str
, br
->str
); }
static void processfd(int *counts, int fd)
{
char buffer[8192];
size_t used = 0;
int r;
struct result *results = NULL;
size_t nres = 0;
while ((r = read(fd, buffer + used, sizeof(buffer) - used)) > 0) {
char *nlp;
used += r;
while ((nlp
= memchr(buffer
, '\n', used
))) { int lcounts['Z' - 'A' + 1] = { 0 };
int cmp;
*nlp = '\0';
calcchars(lcounts, buffer);
if (calccmp(counts, lcounts)) {
results
= realloc(results
, ++nres
* sizeof(*results
)); results[nres - 1].str = strdup(buffer);
results[nres - 1].sl = nlp - buffer;
}
memmove(buffer
, nlp
+ 1, used
- (nlp
- buffer
) - 1); used -= (nlp - buffer) + 1;
}
}
qsort(results
, nres
, sizeof(*results
), rescmp
); for (r = 0; r < nres; r++) {
results[r].str[results[r].sl] = '\n';
write(STDOUT_FILENO, results[r].str, results[r].sl + 1);
}
}
int main(int argc, char **argv)
{
int what['Z' - 'A' + 1] = { 0 };
int i;
calcchars(what, argv[1]);
if (argc > 2) {
for (i = 2; i < argc; i++) {
int fd = open(argv[i], O_RDONLY);
if (fd >= 0) {
processfd(what, fd);
close(fd);
}
}
} else {
processfd(what, STDIN_FILENO);
}
return 0;
}