Name:
Anonymous
2007-12-27 22:52
#include <stdio.h>
#include <string.h>
#define MAX_NESTING 128
#define MAX_POST_SIZE 4096
typedef struct {
int id;
const char * name;
} Tags;
typedef struct {
int memory[MAX_NESTING];
int * ptr;
size_t elements;
} Stack;
void stackinit(Stack *);
int pushid(Stack *, int);
int popid(Stack *);
#define pushid(x,y) ((x)->elements++ == MAX_NESTING ? -1 : (*(x)->ptr++ = y))
#define popid(x) ((x)->elements ? (x)->elements--,*--(x)->ptr : 0)
#define stackinit(x) (void)((x)->elements = 0, (x)->ptr = (x)->memory)
int main(void) {
char buf[MAX_POST_SIZE] = {0};
char * p = buf;
int c;
size_t n;
Stack stack;
Tags tags[] = {
{ 0, ")"},
{ 1, "br"},
{ 2, "b"},
{ 3, "i"},
{ 4, "u"},
{ 5, "o"},
{ 6, "code"},
{ 7, "spoiler"} /*add more tags */
};
stackinit(&stack);
fread(buf, 1, sizeof buf - 1, stdin);
while(*p != 0) {
if(*p == '\\' && p[1]) {
putchar(p[1]);
p += 2;
continue;
} else if(*p == '(') {
if(p[1] == ' ') {
p++;
continue;
}
if(strtok(++p, " \n") == NULL) {
fputs(p, stdout);
break;
} else {
printf("[%s]", p);
for(n = 0; n < sizeof tags / sizeof tags[0]; n++)
if(strcmp(p, tags[n].name) == 0)
if(pushid(&stack, tags[n].id) == -1) {
fprintf(stderr, "max nesting level reached\n");
return -1;
}
p += strlen(p);
}
}
else if(*p == ')') {
c = popid(&stack);
for(n = 0; n < sizeof tags / sizeof tags[0]; n++)
if(c == tags[n].id) {
c ? printf("[/%s]", tags[n].name) : putchar(*tags[n].name);
break;
}
}
else putchar(*p);
p++;
}
putchar('\n');
return 0;
}
Example:
$ cc foo.c -o a
$ ./a
(i (b this is bold and italic) and this just italic)
^D
[i][b]this is bold and italic[/b] and this just italic[/i]
Name:
Anonymous
2007-12-28 19:34
data:application/xhtml+xml;base64,PCFET0NUWVBFIGh0bWwgUFVCTElDICItLy9XM0MvL0RURCBYSFRNTCAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvVFIveGh0bWwxMS9EVEQveGh0bWwxMS5kdGQiPg0KPCEtLSAoQykgTWljcm9zb2Z0IENvcnBvcmF0aW9uIDIwMDcuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIC0tPg0KPGh0bWwgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiPjxoZWFkPjxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0iYXBwbGljYXRpb24veG1sK3hodG1sOyBjaGFyc2V0PVVURi04IiAvPg0KPHRpdGxlPkJCQ29kZSAyLjA8L3RpdGxlPg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCmh0bWwsYm9keXtoZWlnaHQ6MTAwJTttYXJnaW46MDtwYWRkaW5nOjA7fQ0KI291dHB1dCwjaW5wdXR7cG9zaXRpb246YWJzb2x1dGU7fQ0KI29me3BhZGRpbmc6MTBweDtvdmVyZmxvdzphdXRvO30NCiNpbnB1dHtiYWNrZ3JvdW5kOiNFRUU7dGV4dC1hbGlnbjpjZW50ZXI7fQ0KLnNwb2lsZXIgeyBiYWNrZ3JvdW5kOiAjMDAwOyBjb2xvcjogIzAwMDsgfQ0KLnNwb2lsZXI6aG92ZXIgeyBjb2xvcjogI0ZGRjsgfQ0KLmFhIHsgdGV4dC1hbGlnbjogbGVmdDsgZm9udC1mYW1pbHk6IElQQU1vbmFQR290aGljLE1vbmEsJ01TIFBHb3RoaWMnLFlPekZvbnRBQTk3ICFpbXBvcnRhbnQgfQ0KLm8ge3RleHQtZGVjb3JhdGlvbjogb3ZlcmxpbmV9DQouZXhwZXJ0IHsgdGV4dC1kZWNvcmF0aW9uOiBvdmVybGluZSB1bmRlcmxpbmU7IGZvbnQtd2VpZ2h0OiBib2xkOyBmb250LXN0eWxlOiBpdGFsaWM7IH0NCjwvc3R5bGU+PHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPi8vPCFbQ0RBVEFbDQp2YXIgJD1mdW5jdGlvbigpe3JldHVybiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChhcmd1bWVudHNbMF0pLnN0eWxlfTsNCmZ1bmN0aW9uIG5zaXplKCkNCnsNCnZhciBjdz1kb2N1bWVudC5ib2R5LmNsaWVudFdpZHRoLGNoPWRvY3VtZW50LmJvZHkuY2xpZW50SGVpZ2h0Ow0KdmFyIG9oPWNoPjQwMD9jaC0yNTA6TWF0aC5mbG9vcihjaCouNzUpLCBpaD1jaD40MDA/MjUwOmNoLW9oOw0KJCgnb3V0cHV0JykuaGVpZ2h0PVN0cmluZyhvaCkrInB4IjsNCiQoJ2lucHV0JykudG9wPVN0cmluZyhvaCkrInB4IjsNCiQoJ2lucHV0Jykud2lkdGg9U3RyaW5nKGN3KSsicHgiOw0KJCgndHh0Jykud2lkdGg9U3RyaW5nKE1hdGguZmxvb3IoY3cqLjkpKSsicHgiOw0KJCgnaW5wdXQnKS5oZWlnaHQ9U3RyaW5nKGloKSsicHgiOw0KJCgndHh0JykuaGVpZ2h0PVN0cmluZyhpaC04KSsicHgiOw0KfQ0KdmFyIHRhZ3M9W1sncmVtJywwXSxbJ2InLDFdLFsnaScsMV0sWydtJywxLCd0dCddLFsncycsMV0sWyd1JywxXSxbJ3N1YicsMV0sWydzdXAnLDFdLFsnY29kZScsMTAwMV0sWydvJywyXSxbJ2FhJywyXSxbJ3Nwb2lsZXInLDJdLFsnZXhwZXJ0JywyXSxbJyMnLDEwMDNdXTsNCg0KZnVuY3Rpb24gY2goKQ0Kew0KICAgIHZhciBpID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3R4dCcpLnZhbHVlDQogICAgICAucmVwbGFjZSgvJi8sICImYW1wOyIpDQogICAgICAucmVwbGFjZSgvJmFtcDsjLywgIiYjIikNCiAgICAgIC5yZXBsYWNlKC88LywgIiZsdDsiKQ0KICAgICAgLnJlcGxhY2UoLz4vLCAiJmd0OyIpDQogICAgICAucmVwbGFjZSgvIi8sICImcXVvdDsiKQ0KICAgICAgLnJlcGxhY2UoLycvLCAiJiMzOTsiKQ0KICAgICAgLnJlcGxhY2UoLyhcclxufFtcclxuXSkvZywgIjxici8+Iik7DQoNCiAgdmFyIHRhZ3N0YWNrID0gQXJyYXkoKTsNCiAgdmFyIGV4Y2x1c2l2ZXRhZyA9ICIiOw0KDQogIHZhciByZWcgPSBuZXcgUmVnRXhwKCJcXFsoW15bXSo/KVxcXSIsImciKTsNCg0KICB3aGlsZShyciA9IHJlZy5leGVjKGkpKSAvLyBpZiB0aGVyZSB3YXMgYSBtYXRjaA0KICB7DQogICAgaWYgKGkuc3Vic3RyKHJyLmluZGV4LTEsMSkhPSJcXCIpIC8vIGlmIHRhZyBpc24ndCBlc2NhcGVkIHdpdGggYmFja3NsYXNoDQogICAgew0KICAgICAgaWYgKHJyWzFdLnN1YnN0cigwLDEpIT0iLyIgJiYgZXhjbHVzaXZldGFnPT0iIikgLy8gaWYgbm90IGEgY2xvc2luZyB0YWcNCiAgICAgIHsNCiAgICAgICAgaWYgKHJyWzFdPT0iYnIiKSAvLyBzcGVjaWFsIGNhc2UgZm9yIGJyIGFzIGl0IGRvZXNuJ3QgaW52b2x2ZSB0aGUgdGFnIHN0YWNrDQogICAgICAgIHsNCiAgICAgICAgICBpID0gaS5zdWJzdHJpbmcoMCwgcnIuaW5kZXgpICsgIjxiciBjbGVhcj1cImFsbFwiPiIgKyBpLnN1YnN0cmluZyhyci5pbmRleCtyclswXS5sZW5ndGgsIGkubGVuZ3RoKTsNCiAgICAgICAgfQ0KICAgICAgICBlbHNlDQogICAgICAgIHsNCiAgICAgICAgICBmb3IgKHZhciB4PTA7IHg8dGFncy5sZW5ndGg7IHgrKykgLy8gc2VhcmNoIGZvciB2YWxpZCB0YWdzDQogICAgICAgICAgDQogICAgICAgICAgew0KICAgICAgICAgIHRyeXsNCiAgICAgICAgICAgIGlmIChyclsxXT09dGFnc1t4XVswXSkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgdmFyIHN1YnR5cGUgPSB0YWdzW3hdWzFdOw0KICAgICAgICAgICAgICBpZiAoc3VidHlwZT49MTAwMCkNCiAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIGV4Y2x1c2l2ZXRhZyA9IHJyWzFdOw0KICAgICAgICAgICAgICAgIHN1YnR5cGUgPSBzdWJ0eXBlIC0gMTAwMDsNCiAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICB0YWdzdGFjay5wdXNoKFsNCiAgICAgICAgICAgICAgICByci5pbmRleCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogcG9zaXRpb24gb2YgWyBvZiB0YWcgaW4gc3RyaW5nICovDQogICAgICAgICAgICAgICAgcnJbMF0ubGVuZ3RoLCAgICAgICAgICAgICAgICAgICAgICAgIC8qIGxlbmd0aCBvZiB0YWcgaW5jbHVkaW5nIFtdICovDQogICAgICAgICAgICAgICAgcnJbMV0sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHR5cGUgb2YgdGFnICovDQogICAgICAgICAgICAgICAgc3VidHlwZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHR5cGUgb2Ygc3Vic3RpdHV0aW9uICovDQogICAgICAgICAgICAgICAgKHRhZ3NbeF0ubGVuZ3RoPjIpP3RhZ3NbeF1bMl06cnJbMV0gIC8qIHdoYXQgdG8gc3Vic3RpdHV0ZSAqLw0KICAgICAgICAgICAgICAgIF0pOw0KICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICB9Y2F0Y2goZSl7YWxlcnQoZSsnXG4nK3gpO30gIH0NCiAgICAgICAgfQ0KICAgICAgfQ0KICAgICAgZWxzZSAvLyBpZiBpdCBpcyBhIGNsb3NpbmcgdGFnDQogICAgICB7DQoJaWYgKGV4Y2x1c2l2ZXRhZz09IiIgfHwgKCIvIitleGNsdXNpdmV0YWc9PXJyWzFdKSkNCiAgICAgICAgew0KICAgICAgICAgIHZhciBsdCA9IHRhZ3N0YWNrW3RhZ3N0YWNrLmxlbmd0aC0xXTsNCiAgICAgICAgICBpZiAobHQpDQogICAgICAgICAgew0KICAgICAgICAgICAgaWYgKCIvIitsdFsyXT09cnJbMV0pDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgIGkgPSBpLnN1YnN0cmluZygwLGx0WzBdKQ0KICAgICAgICAgICAgICAgICsgKGx0WzNdPT0wPyIiOigNCiAgICAgICAgICAgICAgICAgICAgKGx0WzNdPT0zPyIiOigNCiAgICAgICAgICAgICAgICAgICAgICAiPCINCiAgICAgICAgICAgICAgICAgICAgKyAobHRbM109PTI/InNwYW4gY2xhc3M9XCIiOiIiKQ0KICAgICAgICAgICAgICAgICAgICArIGx0WzRdDQogICAgICAgICAgICAgICAgICAgICsgKGx0WzNdPT0yPyJcIiI6IiIpDQogICAgICAgICAgICAgICAgICAgICsgIj4iDQogICAgICAgICAgICAgICAgICAgICkpDQogICAgICAgICAgICAgICAgICArIGkuc3Vic3RyaW5nKGx0WzBdK2x0WzFdLCByci5pbmRleCkNCiAgICAgICAgICAgICAgICAgICsgKGx0WzNdPT0zPyIiOigNCiAgICAgICAgICAgICAgICAgICAgICAiPC8iDQogICAgICAgICAgICAgICAgICAgICsgKGx0WzNdPT0yPyJzcGFuIjpsdFs0XSkNCiAgICAgICAgICAgICAgICAgICAgKyAiPiIgDQogICAgICAgICAgICAgICAgICAgICkpDQogICAgICAgICAgICAgICAgICApKQ0KICAgICAgICAgICAgICAgICsgaS5zdWJzdHJpbmcocnIuaW5kZXgrcnJbMF0ubGVuZ3RoLCBpLmxlbmd0aCk7DQogICAgICAgICAgICAgIHRhZ3N0YWNrLnBvcCgpOw0KICAgICAgICAgICAgICBleGNsdXNpdmV0YWc9IiI7DQogICAgICAgICAgICB9DQogICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICAgIGVsc2UgLy8gdGFnIGlzIHByZWNlZGVkIGJ5IGEgYmFja3NsYXNoDQogICAgew0KICAgICAgaSA9IGkuc3Vic3RyaW5nKDAsIHJyLmluZGV4LTEpICsgaS5zdWJzdHJpbmcocnIuaW5kZXgsIGkubGVuZ3RoKTsNCiAgICB9DQogIH0NCiAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIm9mIikuaW5uZXJIVE1MID0gaTsNCn0NCg0KLy9dXT4NCjwvc2NyaXB0PjwvaGVhZD48Ym9keSBvbmxvYWQ9Im5zaXplKCk7IGNoKCk7IiBvbnJlc2l6ZT0ibnNpemUoKTtzZXRUaW1lb3V0KCduc2l6ZSgpJywxMDApOyI+DQo8ZGl2IGlkPSJvdXRwdXQiPjxkaXYgaWQ9Im9mIj48L2Rpdj48L2Rpdj4NCjxkaXYgaWQ9ImlucHV0Ij48dGV4dGFyZWEgaWQ9InR4dCIgb25rZXl1cD0iY2goKTsiPltleHBlcnRdRVhQRVJUIEJCQ09ERSBESVNQTEFZRVJbL2V4cGVydF0NCg0KVHlwZSB5b3VyIEJCQ29kZSBpbiB0aGUgYm94IGF0IHRoZSBib3R0b20sIGFuZCBpdCB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgcmVuZGVyZWQgYXQgdGhlIHRvcCBvZiB0aGUgcGFnZSENCg0KU3VwcG9ydGVkIHRhZ3M6IFxbI10sIFxbYl0sIFxbaV0sIFxbbV0sIFxbb10sIFxbc10sIFxbdV0sIFxbYWFdLCBcW2JyXSwgXFtzdWJdLCBcW3N1cF0sIFxbY29kZV0sIFxbZXhwZXJ0XSwgXFtzcG9pbGVyXTwvdGV4dGFyZWE+PC9kaXY+DQo8L2JvZHk+PC9odG1sPg0K