#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct DOCUMENT {
int id;
char* body;
struct DOCUMENT* next;
};
struct IDS {
int id;
struct IDS* next;
};
struct WORDS {
char* word;
struct WORDS* next;
};
struct WORDIDSS {
char* word;
struct IDS* ids;
struct WORDIDSS* next;
};
char* STRING_new(char* w) {
char* s
= malloc(sizeof(char) * len
); return s;
}
void STRING_destroy(char* s) {
}
struct IDS* IDS_new(int id) {
struct IDS
* s
= malloc(sizeof(struct IDS
)); s->id = id;
s->next = NULL;
return s;
}
void IDS_destroy(struct IDS** s) {
struct IDS* a;
while (*s != NULL) {
a = *s;
*s = (*s)->next;
}
}
void IDS_add(struct IDS** s, int id) {
struct IDS* a = *s;
struct IDS* n = IDS_new(id);
if (a == NULL) {
*s = n;
} else {
while (a->next != NULL) {
a = a->next;
}
a->next = n;
}
}
struct WORDS* WORDS_new(char* word) {
struct WORDS
* s
= malloc(sizeof(struct WORDS
)); s->word = STRING_new(word);
s->next = NULL;
return s;
}
void WORDS_destroy(struct WORDS** s) {
struct WORDS* a;
while (*s != NULL) {
a = *s;
*s = (*s)->next;
STRING_destroy(a->word);
}
}
void WORDS_add(struct WORDS** s, char* word) {
struct WORDS* n = WORDS_new(word);
struct WORDS* a = *s;
if (a == NULL) {
*s = n;
} else {
while (a->next != NULL) {
a = a->next;
}
a->next = n;
}
}
struct WORDIDSS* WORDIDSS_new(char* word, int id) {
struct WORDIDSS
* s
= malloc(sizeof(struct WORDIDSS
)); s->word = STRING_new(word);
s->ids = IDS_new(id);
s->next = NULL;
return s;
}
void WORDIDSS_destroy(struct WORDIDSS** s) {
struct WORDIDSS* a;
while (*s != NULL) {
a = *s;
*s = (*s)->next;
STRING_destroy(a->word);
IDS_destroy(&a->ids);
}
}
void WORDIDSS_add(struct WORDIDSS** s, char* word, int id) {
struct WORDIDSS* a = *s;
if (a == NULL) {
*s = WORDIDSS_new(word, id);
} else {
while (1) {
if (strcmp(a
->word
, word
) == 0) { IDS_add(&a->ids, id);
break;
}
if (a->next == NULL) {
a->next = WORDIDSS_new(word, id);
break;
}
a = a->next;
}
}
}
void WORDIDSS_add_words(struct WORDIDSS** s, struct WORDS* words, int id) {
while (words != NULL) {
WORDIDSS_add(s, words->word, id);
words = words->next;
}
}
struct IDS* WORDIDSS_get(struct WORDIDSS* s, char* word) {
while (s != NULL) {
if (strcmp(s
->word
, word
) == 0) { return s->ids;
}
s = s->next;
}
return NULL;
}
int WORDIDSS_count(struct WORDIDSS* s) {
int i = 0;
while (s != NULL) {
i++;
s = s->next;
}
return i;
}
struct IDS* IDS_and(struct IDS* a, struct IDS* b) {
struct IDS* c = NULL;
while (a != NULL) {
if (b == NULL) {
break;
}
if (a->id < b->id) {
a = a->next;
} else if (a->id > b->id) {
b = b->next;
} else {
IDS_add(&c, a->id);
a = a->next;
b = b->next;
}
}
return c;
}
/* return new instance */
struct IDS* IDS_unique(struct IDS* s) {
struct IDS* n = NULL;
int id;
if (s != NULL) {
IDS_add(&n, s->id);
id = s->id;
s = s->next;
while (s != NULL) {
if (s->id != id) {
IDS_add(&n, s->id);
id = s->id;
}
s = s->next;
}
}
return n;
}
void IDS_print(struct IDS* s) {
while (s != NULL) {
s = s->next;
}
}
int IDS_count(struct IDS* s) {
int i = 0;
while (s != NULL) {
i++;
s = s->next;
}
return i;
}
struct DOCUMENT* DOCUMENT_new(int id, char* body, struct DOCUMENT* next) {
struct DOCUMENT
* s
= malloc(sizeof(struct DOCUMENT
)); s->id = id;
s->body = body;
s->next = next;
return s;
}
void DOCUMENT_destroy(struct DOCUMENT** s) {
struct DOCUMENT* a;
while (*s != NULL) {
a = *s;
*s = (*s)->next;
STRING_destroy(a->body);
}
}
void DOCUMENT_add(struct DOCUMENT** s, int id, char* body) {
struct DOCUMENT* n = DOCUMENT_new(id, STRING_new(body), NULL);
struct DOCUMENT* a = *s;
if (a == NULL) {
*s = n;
} else {
while (a->next != NULL) {
a = a->next;
}
a->next = n;
}
}
struct DOCUMENT* DOCUMENT_get(struct DOCUMENT* s, int id) {
while (s != NULL) {
if (s->id == id) {
return s;
}
s = s->next;
}
return NULL;
}
struct DOCUMENT* createDocs(char* filename) {
char row[65536];
FILE* f = NULL;
struct DOCUMENT* docs = NULL;
int i;
f
= fopen(filename
, "r"); i = 0;
while (fgets(row
, 65536, f
) != NULL
) { DOCUMENT_add(&docs, i, row);
i++;
}
return docs;
}
struct WORDIDSS* createWiss(struct DOCUMENT* docs, int rowSize, char* dlm) {
struct WORDIDSS* wiss = NULL;
char* row
= malloc(sizeof(char) * rowSize
); char* w;
while (docs != NULL) {
while (w != NULL) {
WORDIDSS_add(&wiss, w, docs->id);
}
docs = docs->next;
}
return wiss;
}
struct WORDS* inputQuery(int rowSize, char* dlm) {
struct WORDS* ws = NULL;
char* row
= malloc(sizeof(char) * rowSize
); char* w;
fgets(row
, 65536, stdin
); while (w != NULL) {
WORDS_add(&ws, w);
}
return ws;
}
/* return new instance */
struct IDS* andsearch(struct WORDS* ws, struct WORDIDSS* wiss) {
struct IDS* a = NULL;
struct IDS* b = NULL;
struct IDS* c = NULL;
if (ws != NULL) {
a = WORDIDSS_get(wiss, ws->word);
while (a != NULL) {
IDS_add(&b, a->id);
a = a->next;
}
ws = ws->next;
while (ws != NULL) {
c = b;
b = IDS_and(b, WORDIDSS_get(wiss, ws->word));
IDS_destroy(&c);
ws = ws->next;
}
}
return b;
}
void printinfo(struct IDS* ids, struct DOCUMENT* docs) {
struct DOCUMENT* doc;
while (ids != NULL) {
doc = DOCUMENT_get(docs, ids->id);
ids = ids->next;
}
}
void theme1(struct WORDIDSS* wiss) {
struct IDS* john = WORDIDSS_get(wiss, "john");
struct IDS* and = WORDIDSS_get(wiss, "and");
struct IDS* said = WORDIDSS_get(wiss, "said");
printf("Total number of words in the index = %d\n", WORDIDSS_count
(wiss
)); printf("john = %d\n", IDS_count
(john
)); printf("and = %d\n", IDS_count
(and
)); printf("said = %d\n", IDS_count
(said
)); }
void theme2(struct WORDIDSS* wiss, struct DOCUMENT* docs, int rowSize, char* dlm) {
struct WORDS* ws = inputQuery(rowSize, dlm);
struct IDS* ids = andsearch(ws, wiss);
struct IDS* uni = IDS_unique(ids);
if (IDS_count(uni) < 1) {
} else {
printinfo(uni, docs);
}
}
int main(int argc, char* argv[]) {
struct DOCUMENT* docs = NULL;
struct WORDIDSS* wiss = NULL;
const char* dlm = " \t\n";
const int rowSize = 65536;
char* filename;
if (argc < 3) {
return;
}
if (strcmp(argv
[1], "-f") != 0) { return;
}
filename = argv[2];
docs = createDocs(filename);
wiss = createWiss(docs, rowSize, dlm);
theme1(wiss);
theme2(wiss, docs, rowSize, dlm);
WORDIDSS_destroy(&wiss);
DOCUMENT_destroy(&docs);
return EXIT_SUCCESS;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgoKc3RydWN0IERPQ1VNRU5UIHsKICAgaW50IGlkOwogICBjaGFyKiBib2R5OwogICBzdHJ1Y3QgRE9DVU1FTlQqIG5leHQ7Cn07CgpzdHJ1Y3QgSURTIHsKICAgaW50IGlkOwogICBzdHJ1Y3QgSURTKiBuZXh0Owp9OwoKc3RydWN0IFdPUkRTIHsKICAgY2hhciogd29yZDsKICAgc3RydWN0IFdPUkRTKiBuZXh0Owp9OwoKc3RydWN0IFdPUkRJRFNTIHsKICAgY2hhciogd29yZDsKICAgc3RydWN0IElEUyogaWRzOwogICBzdHJ1Y3QgV09SRElEU1MqIG5leHQ7Cn07CgpjaGFyKiBTVFJJTkdfbmV3KGNoYXIqIHcpIHsKICAgaW50IGxlbiA9IHN0cmxlbih3KSArIDE7CiAgIGNoYXIqIHMgPSBtYWxsb2Moc2l6ZW9mKGNoYXIpICogbGVuKTsKICAgbWVtY3B5KHMsIHcsIGxlbik7CiAgIHJldHVybiBzOwp9Cgp2b2lkIFNUUklOR19kZXN0cm95KGNoYXIqIHMpIHsKICAgZnJlZShzKTsKfQoKc3RydWN0IElEUyogSURTX25ldyhpbnQgaWQpIHsKICAgc3RydWN0IElEUyogcyA9IG1hbGxvYyhzaXplb2Yoc3RydWN0IElEUykpOwogICBzLT5pZCA9IGlkOwogICBzLT5uZXh0ID0gTlVMTDsKICAgcmV0dXJuIHM7Cn0KCnZvaWQgSURTX2Rlc3Ryb3koc3RydWN0IElEUyoqIHMpIHsKICAgc3RydWN0IElEUyogYTsKICAgd2hpbGUgKCpzICE9IE5VTEwpIHsKICAgICAgYSA9ICpzOwogICAgICAqcyA9ICgqcyktPm5leHQ7CiAgICAgIGZyZWUoYSk7CiAgIH0KfQoKdm9pZCBJRFNfYWRkKHN0cnVjdCBJRFMqKiBzLCBpbnQgaWQpIHsKICAgc3RydWN0IElEUyogYSA9ICpzOwogICBzdHJ1Y3QgSURTKiBuID0gSURTX25ldyhpZCk7CiAgIGlmIChhID09IE5VTEwpIHsKICAgICAgKnMgPSBuOwogICB9IGVsc2UgewogICAgICB3aGlsZSAoYS0+bmV4dCAhPSBOVUxMKSB7CiAgICAgICAgIGEgPSBhLT5uZXh0OwogICAgICB9CiAgICAgIGEtPm5leHQgPSBuOwogICB9Cn0KCnN0cnVjdCBXT1JEUyogV09SRFNfbmV3KGNoYXIqIHdvcmQpIHsKICAgc3RydWN0IFdPUkRTKiBzID0gbWFsbG9jKHNpemVvZihzdHJ1Y3QgV09SRFMpKTsKICAgcy0+d29yZCA9IFNUUklOR19uZXcod29yZCk7CiAgIHMtPm5leHQgPSBOVUxMOwogICByZXR1cm4gczsKfQoKdm9pZCBXT1JEU19kZXN0cm95KHN0cnVjdCBXT1JEUyoqIHMpIHsKICAgc3RydWN0IFdPUkRTKiBhOwogICB3aGlsZSAoKnMgIT0gTlVMTCkgewogICAgICBhID0gKnM7CiAgICAgICpzID0gKCpzKS0+bmV4dDsKICAgICAgU1RSSU5HX2Rlc3Ryb3koYS0+d29yZCk7CiAgICAgIGZyZWUoYSk7CiAgIH0KfQoKdm9pZCBXT1JEU19hZGQoc3RydWN0IFdPUkRTKiogcywgY2hhciogd29yZCkgewogICBzdHJ1Y3QgV09SRFMqIG4gPSBXT1JEU19uZXcod29yZCk7CiAgIHN0cnVjdCBXT1JEUyogYSA9ICpzOwogICBpZiAoYSA9PSBOVUxMKSB7CiAgICAgICpzID0gbjsKICAgfSBlbHNlIHsKICAgICAgd2hpbGUgKGEtPm5leHQgIT0gTlVMTCkgewogICAgICAgICBhID0gYS0+bmV4dDsKICAgICAgfQogICAgICBhLT5uZXh0ID0gbjsKICAgfQp9CgpzdHJ1Y3QgV09SRElEU1MqIFdPUkRJRFNTX25ldyhjaGFyKiB3b3JkLCBpbnQgaWQpIHsKICAgc3RydWN0IFdPUkRJRFNTKiBzID0gbWFsbG9jKHNpemVvZihzdHJ1Y3QgV09SRElEU1MpKTsKICAgcy0+d29yZCA9IFNUUklOR19uZXcod29yZCk7CiAgIHMtPmlkcyA9IElEU19uZXcoaWQpOwogICBzLT5uZXh0ID0gTlVMTDsKICAgcmV0dXJuIHM7Cn0KCnZvaWQgV09SRElEU1NfZGVzdHJveShzdHJ1Y3QgV09SRElEU1MqKiBzKSB7CiAgIHN0cnVjdCBXT1JESURTUyogYTsKICAgd2hpbGUgKCpzICE9IE5VTEwpIHsKICAgICAgYSA9ICpzOwogICAgICAqcyA9ICgqcyktPm5leHQ7CiAgICAgIFNUUklOR19kZXN0cm95KGEtPndvcmQpOwogICAgICBJRFNfZGVzdHJveSgmYS0+aWRzKTsKICAgICAgZnJlZShhKTsKICAgfQp9Cgp2b2lkIFdPUkRJRFNTX2FkZChzdHJ1Y3QgV09SRElEU1MqKiBzLCBjaGFyKiB3b3JkLCBpbnQgaWQpIHsKICAgc3RydWN0IFdPUkRJRFNTKiBhID0gKnM7CiAgIGlmIChhID09IE5VTEwpIHsKICAgICAgKnMgPSBXT1JESURTU19uZXcod29yZCwgaWQpOwogICB9IGVsc2UgewogICAgICB3aGlsZSAoMSkgewogICAgICAgICBpZiAoc3RyY21wKGEtPndvcmQsIHdvcmQpID09IDApIHsKICAgICAgICAgICAgSURTX2FkZCgmYS0+aWRzLCBpZCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICB9CiAgICAgICAgIGlmIChhLT5uZXh0ID09IE5VTEwpIHsKICAgICAgICAgICAgYS0+bmV4dCA9IFdPUkRJRFNTX25ldyh3b3JkLCBpZCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICB9CiAgICAgICAgIGEgPSBhLT5uZXh0OwogICAgICB9CiAgIH0KfQoKdm9pZCBXT1JESURTU19hZGRfd29yZHMoc3RydWN0IFdPUkRJRFNTKiogcywgc3RydWN0IFdPUkRTKiB3b3JkcywgaW50IGlkKSB7CiAgIHdoaWxlICh3b3JkcyAhPSBOVUxMKSB7CiAgICAgIFdPUkRJRFNTX2FkZChzLCB3b3Jkcy0+d29yZCwgaWQpOwogICAgICB3b3JkcyA9IHdvcmRzLT5uZXh0OwogICB9Cn0KCnN0cnVjdCBJRFMqIFdPUkRJRFNTX2dldChzdHJ1Y3QgV09SRElEU1MqIHMsIGNoYXIqIHdvcmQpIHsKICAgd2hpbGUgKHMgIT0gTlVMTCkgewogICAgICBpZiAoc3RyY21wKHMtPndvcmQsIHdvcmQpID09IDApIHsKICAgICAgICAgcmV0dXJuIHMtPmlkczsKICAgICAgfQogICAgICBzID0gcy0+bmV4dDsKICAgfQogICByZXR1cm4gTlVMTDsKfQoKaW50IFdPUkRJRFNTX2NvdW50KHN0cnVjdCBXT1JESURTUyogcykgewogICBpbnQgaSA9IDA7CiAgIHdoaWxlIChzICE9IE5VTEwpIHsKICAgICAgaSsrOwogICAgICBzID0gcy0+bmV4dDsKICAgfQogICByZXR1cm4gaTsKfQoKc3RydWN0IElEUyogSURTX2FuZChzdHJ1Y3QgSURTKiBhLCBzdHJ1Y3QgSURTKiBiKSB7CiAgIHN0cnVjdCBJRFMqIGMgPSBOVUxMOwogICB3aGlsZSAoYSAhPSBOVUxMKSB7CiAgICAgIGlmIChiID09IE5VTEwpIHsKICAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgaWYgKGEtPmlkIDwgYi0+aWQpIHsKICAgICAgICAgYSA9IGEtPm5leHQ7CiAgICAgIH0gZWxzZSBpZiAoYS0+aWQgPiBiLT5pZCkgewogICAgICAgICBiID0gYi0+bmV4dDsKICAgICAgfSBlbHNlIHsKICAgICAgICAgSURTX2FkZCgmYywgYS0+aWQpOwogICAgICAgICBhID0gYS0+bmV4dDsKICAgICAgICAgYiA9IGItPm5leHQ7CiAgICAgIH0KICAgfQogICByZXR1cm4gYzsKfQoKLyogcmV0dXJuIG5ldyBpbnN0YW5jZSAqLwpzdHJ1Y3QgSURTKiBJRFNfdW5pcXVlKHN0cnVjdCBJRFMqIHMpIHsKICAgc3RydWN0IElEUyogbiA9IE5VTEw7CiAgIGludCBpZDsKICAgCiAgIGlmIChzICE9IE5VTEwpIHsKICAgICAgSURTX2FkZCgmbiwgcy0+aWQpOwogICAgICBpZCA9IHMtPmlkOwogICAgICBzID0gcy0+bmV4dDsKICAgICAgd2hpbGUgKHMgIT0gTlVMTCkgewogICAgICAgICBpZiAocy0+aWQgIT0gaWQpIHsKICAgICAgICAgICAgSURTX2FkZCgmbiwgcy0+aWQpOwogICAgICAgICAgICBpZCA9IHMtPmlkOwogICAgICAgICB9CiAgICAgICAgIHMgPSBzLT5uZXh0OwogICAgICB9CiAgIH0KICAgcmV0dXJuIG47Cn0KCnZvaWQgSURTX3ByaW50KHN0cnVjdCBJRFMqIHMpIHsKICAgd2hpbGUgKHMgIT0gTlVMTCkgewogICAgICBwcmludGYoIiVkXG4iLCBzLT5pZCk7CiAgICAgIHMgPSBzLT5uZXh0OwogICB9Cn0KCmludCBJRFNfY291bnQoc3RydWN0IElEUyogcykgewogICBpbnQgaSA9IDA7CiAgIHdoaWxlIChzICE9IE5VTEwpIHsKICAgICAgaSsrOwogICAgICBzID0gcy0+bmV4dDsKICAgfQogICByZXR1cm4gaTsKfQoKc3RydWN0IERPQ1VNRU5UKiBET0NVTUVOVF9uZXcoaW50IGlkLCBjaGFyKiBib2R5LCBzdHJ1Y3QgRE9DVU1FTlQqIG5leHQpIHsKICAgc3RydWN0IERPQ1VNRU5UKiBzID0gbWFsbG9jKHNpemVvZihzdHJ1Y3QgRE9DVU1FTlQpKTsKICAgcy0+aWQgPSBpZDsKICAgcy0+Ym9keSA9IGJvZHk7CiAgIHMtPm5leHQgPSBuZXh0OwogICByZXR1cm4gczsKfQoKdm9pZCBET0NVTUVOVF9kZXN0cm95KHN0cnVjdCBET0NVTUVOVCoqIHMpIHsKICAgc3RydWN0IERPQ1VNRU5UKiBhOwogICB3aGlsZSAoKnMgIT0gTlVMTCkgewogICAgICBhID0gKnM7CiAgICAgICpzID0gKCpzKS0+bmV4dDsKICAgICAgU1RSSU5HX2Rlc3Ryb3koYS0+Ym9keSk7CiAgICAgIGZyZWUoYSk7CiAgIH0KfQoKdm9pZCBET0NVTUVOVF9hZGQoc3RydWN0IERPQ1VNRU5UKiogcywgaW50IGlkLCBjaGFyKiBib2R5KSB7CiAgIHN0cnVjdCBET0NVTUVOVCogbiA9IERPQ1VNRU5UX25ldyhpZCwgU1RSSU5HX25ldyhib2R5KSwgTlVMTCk7CiAgIHN0cnVjdCBET0NVTUVOVCogYSA9ICpzOwogICBpZiAoYSA9PSBOVUxMKSB7CiAgICAgICpzID0gbjsKICAgfSBlbHNlIHsKICAgICAgd2hpbGUgKGEtPm5leHQgIT0gTlVMTCkgewogICAgICAgICBhID0gYS0+bmV4dDsKICAgICAgfQogICAgICBhLT5uZXh0ID0gbjsKICAgfQp9CgpzdHJ1Y3QgRE9DVU1FTlQqIERPQ1VNRU5UX2dldChzdHJ1Y3QgRE9DVU1FTlQqIHMsIGludCBpZCkgewogICB3aGlsZSAocyAhPSBOVUxMKSB7CiAgICAgIGlmIChzLT5pZCA9PSBpZCkgewogICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgICBzID0gcy0+bmV4dDsKICAgfQogICByZXR1cm4gTlVMTDsKfQoKc3RydWN0IERPQ1VNRU5UKiBjcmVhdGVEb2NzKGNoYXIqIGZpbGVuYW1lKSB7CiAgIGNoYXIgcm93WzY1NTM2XTsKICAgRklMRSogZiA9IE5VTEw7CiAgIHN0cnVjdCBET0NVTUVOVCogZG9jcyA9IE5VTEw7CiAgIGludCBpOwogICAgICAKICAgZiA9IGZvcGVuKGZpbGVuYW1lLCAiciIpOwogICBpID0gMDsKICAgd2hpbGUgKGZnZXRzKHJvdywgNjU1MzYsIGYpICE9IE5VTEwpIHsKICAgICAgcm93W3N0cmxlbihyb3cpIC0gMV0gPSAnXDAnOwogICAgICBET0NVTUVOVF9hZGQoJmRvY3MsIGksIHJvdyk7CiAgICAgIGkrKzsKICAgfQogICBmY2xvc2UoZik7CiAgIAogICByZXR1cm4gZG9jczsKfQoKc3RydWN0IFdPUkRJRFNTKiBjcmVhdGVXaXNzKHN0cnVjdCBET0NVTUVOVCogZG9jcywgaW50IHJvd1NpemUsIGNoYXIqIGRsbSkgewogICBzdHJ1Y3QgV09SRElEU1MqIHdpc3MgPSBOVUxMOwogICBjaGFyKiByb3cgPSBtYWxsb2Moc2l6ZW9mKGNoYXIpICogcm93U2l6ZSk7CiAgIGNoYXIqIHc7CiAgIHdoaWxlIChkb2NzICE9IE5VTEwpIHsKICAgICAgc3RyY3B5KHJvdywgZG9jcy0+Ym9keSk7CiAgICAgIHcgPSBzdHJ0b2socm93LCBkbG0pOwogICAgICB3aGlsZSAodyAhPSBOVUxMKSB7CiAgICAgICAgIFdPUkRJRFNTX2FkZCgmd2lzcywgdywgZG9jcy0+aWQpOwogICAgICAgICB3ID0gc3RydG9rKE5VTEwsIGRsbSk7CiAgICAgIH0KICAgICAgZG9jcyA9IGRvY3MtPm5leHQ7CiAgIH0KICAgZnJlZShyb3cpOwogICByZXR1cm4gd2lzczsKfQoKc3RydWN0IFdPUkRTKiBpbnB1dFF1ZXJ5KGludCByb3dTaXplLCBjaGFyKiBkbG0pIHsKICAgc3RydWN0IFdPUkRTKiB3cyA9IE5VTEw7CiAgIGNoYXIqIHJvdyA9IG1hbGxvYyhzaXplb2YoY2hhcikgKiByb3dTaXplKTsKICAgY2hhciogdzsKICAgcHJpbnRmKCJFbnRlciBRdWVyeToiKTsKICAgZmdldHMocm93LCA2NTUzNiwgc3RkaW4pOwogICB3ID0gc3RydG9rKHJvdywgZGxtKTsKICAgd2hpbGUgKHcgIT0gTlVMTCkgewogICAgICBXT1JEU19hZGQoJndzLCB3KTsKICAgICAgdyA9IHN0cnRvayhOVUxMLCBkbG0pOwogICB9CiAgIGZyZWUocm93KTsKICAgcmV0dXJuIHdzOwp9CgovKiByZXR1cm4gbmV3IGluc3RhbmNlICovCnN0cnVjdCBJRFMqIGFuZHNlYXJjaChzdHJ1Y3QgV09SRFMqIHdzLCBzdHJ1Y3QgV09SRElEU1MqIHdpc3MpIHsKICAgc3RydWN0IElEUyogYSA9IE5VTEw7CiAgIHN0cnVjdCBJRFMqIGIgPSBOVUxMOwogICBzdHJ1Y3QgSURTKiBjID0gTlVMTDsKICAgCiAgIGlmICh3cyAhPSBOVUxMKSB7CiAgICAgIGEgPSBXT1JESURTU19nZXQod2lzcywgd3MtPndvcmQpOwogICAgICB3aGlsZSAoYSAhPSBOVUxMKSB7CiAgICAgICAgIElEU19hZGQoJmIsIGEtPmlkKTsKICAgICAgICAgYSA9IGEtPm5leHQ7CiAgICAgIH0KICAgICAgd3MgPSB3cy0+bmV4dDsKICAgICAgd2hpbGUgKHdzICE9IE5VTEwpIHsKICAgICAgICAgYyA9IGI7CiAgICAgICAgIGIgPSBJRFNfYW5kKGIsIFdPUkRJRFNTX2dldCh3aXNzLCB3cy0+d29yZCkpOwogICAgICAgICBJRFNfZGVzdHJveSgmYyk7CiAgICAgICAgIHdzID0gd3MtPm5leHQ7CiAgICAgIH0KICAgfQogICByZXR1cm4gYjsKfQoKdm9pZCBwcmludGluZm8oc3RydWN0IElEUyogaWRzLCBzdHJ1Y3QgRE9DVU1FTlQqIGRvY3MpIHsKICAgc3RydWN0IERPQ1VNRU5UKiBkb2M7CiAgIHdoaWxlIChpZHMgIT0gTlVMTCkgewogICAgICBkb2MgPSBET0NVTUVOVF9nZXQoZG9jcywgaWRzLT5pZCk7CiAgICAgIHByaW50ZigiJWRcbiIsIGlkcy0+aWQpOwogICAgICBwcmludGYoIiVzXG4iLCBkb2MtPmJvZHkpOwogICAgICBwcmludGYoIlxuIik7CiAgICAgIGlkcyA9IGlkcy0+bmV4dDsKICAgfQp9Cgp2b2lkIHRoZW1lMShzdHJ1Y3QgV09SRElEU1MqIHdpc3MpIHsKICAgc3RydWN0IElEUyogam9obiA9IFdPUkRJRFNTX2dldCh3aXNzLCAiam9obiIpOwogICBzdHJ1Y3QgSURTKiBhbmQgPSBXT1JESURTU19nZXQod2lzcywgImFuZCIpOwogICBzdHJ1Y3QgSURTKiBzYWlkID0gV09SRElEU1NfZ2V0KHdpc3MsICJzYWlkIik7CiAgIAogICBwcmludGYoIlRvdGFsIG51bWJlciBvZiB3b3JkcyBpbiB0aGUgaW5kZXggPSAlZFxuIiwgV09SRElEU1NfY291bnQod2lzcykpOwogICBwcmludGYoImpvaG4gPSAlZFxuIiwgSURTX2NvdW50KGpvaG4pKTsKICAgcHJpbnRmKCJhbmQgPSAlZFxuIiwgSURTX2NvdW50KGFuZCkpOwogICBwcmludGYoInNhaWQgPSAlZFxuIiwgSURTX2NvdW50KHNhaWQpKTsKfQoKdm9pZCB0aGVtZTIoc3RydWN0IFdPUkRJRFNTKiB3aXNzLCBzdHJ1Y3QgRE9DVU1FTlQqIGRvY3MsIGludCByb3dTaXplLCBjaGFyKiBkbG0pIHsKICAgc3RydWN0IFdPUkRTKiB3cyA9IGlucHV0UXVlcnkocm93U2l6ZSwgZGxtKTsKICAgc3RydWN0IElEUyogaWRzID0gYW5kc2VhcmNoKHdzLCB3aXNzKTsKICAgc3RydWN0IElEUyogdW5pID0gSURTX3VuaXF1ZShpZHMpOwogICBpZiAoSURTX2NvdW50KHVuaSkgPCAxKSB7CiAgICAgIHByaW50Zigid29yZHMgbm90IGZvdW5kXG4iKTsKICAgfSBlbHNlIHsKICAgICAgcHJpbnRpbmZvKHVuaSwgZG9jcyk7CiAgIH0KICAgZnJlZSh1bmkpOwogICBmcmVlKGlkcyk7CiAgIGZyZWUod3MpOwp9CgoKaW50IG1haW4oaW50IGFyZ2MsIGNoYXIqIGFyZ3ZbXSkgewogICBzdHJ1Y3QgRE9DVU1FTlQqIGRvY3MgPSBOVUxMOwogICBzdHJ1Y3QgV09SRElEU1MqIHdpc3MgPSBOVUxMOwogICBjb25zdCBjaGFyKiBkbG0gPSAiIFx0XG4iOwogICBjb25zdCBpbnQgcm93U2l6ZSA9IDY1NTM2OwogICAKICAgY2hhciogZmlsZW5hbWU7CiAgIAogICBpZiAoYXJnYyA8IDMpIHsKICAgICAgcmV0dXJuOwogICB9CiAgIGlmIChzdHJjbXAoYXJndlsxXSwgIi1mIikgIT0gMCkgewogICAgICByZXR1cm47CiAgIH0KICAgCiAgIGZpbGVuYW1lID0gYXJndlsyXTsKICAgZG9jcyA9IGNyZWF0ZURvY3MoZmlsZW5hbWUpOwogICB3aXNzID0gY3JlYXRlV2lzcyhkb2NzLCByb3dTaXplLCBkbG0pOwoKICAgdGhlbWUxKHdpc3MpOwogICB0aGVtZTIod2lzcywgZG9jcywgcm93U2l6ZSwgZGxtKTsKICAgCiAgIFdPUkRJRFNTX2Rlc3Ryb3koJndpc3MpOwogICBET0NVTUVOVF9kZXN0cm95KCZkb2NzKTsKCiAgIHJldHVybiBFWElUX1NVQ0NFU1M7Cn0K