Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

{b.u.i.o Dear Admin:}

Name: Anonymous 2013-09-16 14:14

I'd really love this board to have SexpCode support. If I write a patch, would you accept it?

(What does this board even run on? Kareha?)

Name: Anonymous 2013-09-16 14:18

Tablecat's software, made in Perl. You're better off writing your own BBS software and implementing Sexpcode in it.

Name: Anonymous 2013-09-16 14:22

>>1
I second that, if there isn't something else that admin with his burdens is busy with.

Name: Anonymous 2013-09-16 14:27

Join the work of https://ivasiwlrjq5dxk6b.tor2web.org/p/distbb/index
that's what we are working on.
I just love org-mode wonderful markup, and its extensions.

Name: Anonymous 2013-09-16 14:33

>>4
tor2web
lazy-kun here, thank you!

Name: Anonymous 2013-09-16 14:37

Tor2web Error: Generic Sock Error
fug, nevermind ;_;

Name: Anonymous 2013-09-16 15:30

>>6
I got to the page just fine:
DistBB
DistBB
Not logged in
Home Timeline Files Branches Tags Tickets Wiki Login

Digital signatures here.
This page was generated in about 0.005s by Fossil version [13ad130920] 2013-09-11 11:43:49

Use tor to get to the onion address, then. use the localhost trick if you must.

Name: Anonymous 2013-09-16 15:35

And remember to log in as anonymous (with the text captcha as password) to be able to navigate the repository's contents.

Name: Anonymous 2013-09-16 21:06

Name: Anonymous 2016-03-21 16:11

distbb when

Name: Anonymous 2016-03-23 12:49

dubs

Name: Anonymous 2016-03-23 15:20

>>4
org-mode is not wonderful at all. Go suck a dick, Emacs nigger.

Name: Anonymous 2016-03-23 16:47

I use Emacs all the time, for (programming 'Lisp), and yes, org-mode is useless shit.

Name: Anonymous 2016-03-23 18:00

Has anyone actually implemented a parser for this? If not, I'll begin right away. I remember discussing this around the time this thread was made and I want to put it on my own software.

Name: Anonymous 2016-03-23 18:14

Name: Anonymous 2016-03-25 20:27

testing {b.i.o.u testing}

Name: Anonymous 2016-03-25 20:41

{define super sup*3}{super*3 Only three sups, or maybe an error.}

{v Invalid function}

{i teee

est}

{

Name: Anonymous 2016-03-25 20:51

{define super sup*3}{super*3 Only three sups, or maybe an error.}

Name: Anonymous 2016-03-25 20:52

{i teeee

eeesst}

Name: Anonymous 2016-03-25 21:09

I have successfully ``{i transpiled}'' {b Xarn}'s sexpcode library to JengaScript via Emscripten. If you want to try it out, {url https://gist.githubusercontent.com/anonymous/99170ec685323ae39a51/raw/604b8d54eccf44f524fc9186f235a95928d6404f/sexpcode.js here is a user script}.

Name: Anonymous 2016-03-25 21:41

It runs on something I wrote. See the FAQ linked in the top right.

If you write a perl sexpcode parser that can be easily imported as a module, I'd accept it, sure.

Name: Anonymous 2016-03-25 21:41

Just noticed the post date... never mind.

Name: Anonymous 2016-03-27 4:41

>>21,22
Hey just because I'm necrobumping doesn't mean I'm not serious. I have a perl module for you

Name: Anonymous 2016-03-27 4:42

The fossil is disabled I guess?

Name: Anonymous 2016-03-27 6:25

>>24
SQLITE_READONLY: statement aborts at 21: [UPDATE user SET cookie='69696969696969696969696969696969696969696969696969', ipaddr='257.130', cexpire=julianday('now')+31557600/86400.0 WHERE uid=6] attempt to write a readonly datab
Database Error
attempt to write a readonly database: {UPDATE user SET cookie='69696969696969696969696969696969696969696969696969', ipaddr='257.130', cexpire=julianday('now')+31557600/86400.0 WHERE uid=6}
If you have recently updated your fossil executable, you might need to run "fossil all rebuild" to bring the repository schemas up to date.
Hmm, maybe it's because we never used it even though Admin-kike-sama did her best to try to make us happy?

Name: Anonymous 2016-03-27 15:20

Name: Anonymous 2016-03-27 16:49

I really don't like this code. I hope you will accept my changes.
There is however still a big room for improvement.

#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include <stdlib.h>
#include <ctype.h>
#include <search.h>

#include "sexpcode.h"

#ifndef MAX_ITERS
# define MAX_ITERS 3
#endif

#ifndef MAX_DEFINES
# define MAX_DEFINES 1024
#endif

#ifndef MAX_BUN_TAG_LENGTH
# define MAX_BUN_TAG_LENGTH 1024
#endif

#ifndef MAX_ARITY
# define MAX_ARITY 255
#endif

extern struct sexpcode_func *(*get_func) (char *);

/* Pass 0 */

#define P0_NORMAL 0
#define P0_HAD_BRACE 1
#define P0_GETTING_START_TAG 2
#define P0_HAD_SPACE 3
#define P0_GETTING_END_TAG 4
#define P0_VERBATIM 5

char *
pass0 (const char *content)
{
/*
Pass 0 deals with Bun's verbatim syntax and backslash escaping.
*/
unsigned char mode = P0_NORMAL;
char tag[MAX_BUN_TAG_LENGTH + 1], sp = ' ';
int tagsize = 0;
FILE *output = tmpfile ();

for (; *content != 0; ++content)
{
if (mode == P0_NORMAL)
{
if (*content == '\\')
{
++content;
if (*content == '{')
fputc (1, output); /* I am afraid I don't understand these two lines, why does it print 1 and 2? */
else if (*content == '}')
fputc (2, output);
else
fputc (*content, output);
}
else if (*content == '{')
mode = P0_HAD_BRACE;
else
{
fputc (*content, output);
if (*content == 0)
break;
}
}
else if (mode == P0_HAD_BRACE)
{
if (isalpha (*content))
{
fputc ('{', output);
mode = P0_NORMAL;
fputc (*content, output);
}
else if (*content == '{')
fputc ('{', output);
else
{
mode = P0_GETTING_START_TAG;
tagsize = 0;
tag[tagsize++] = *content;
}

}
else if (mode == P0_GETTING_START_TAG)
{
if (isspace (*content))
{
mode = P0_VERBATIM;
tag[tagsize] = 0;
}
else if (tagsize < MAX_BUN_TAG_LENGTH)
tag[tagsize++] = *content;
else
{
fputs ("Maximum length for Bun's verbatim tag exceeded.\n", stderr);
fclose (output);
return NULL;
}

}
else if (mode == P0_VERBATIM)
{
if (isspace (*content))
{
sp = *content;
mode = P0_HAD_SPACE;
}
else if (*content == '{')
fputc (1, output); /* again */
else if (*content == '}')
fputc (2, output);
else
fputc (*content, output);
}
else if (mode == P0_HAD_SPACE)
{
if (*content == tag[0])
{
mode = P0_GETTING_END_TAG;
tagsize = 1;
}
else
{
fputc (sp, output);
fputc (*content, output);
mode = P0_VERBATIM;
}
}
else if (mode == P0_GETTING_END_TAG)
{
if (*content == '}' && tag[tagsize] == 0)
mode = P0_NORMAL;
else if (*content == tag[tagsize])
++tagsize;
else
{
size_t i;

fputc (sp, output);
for (i = 0; i < tagsize; ++i)
fputc (tag[i], output);
fputc (*content, output);

mode = P0_VERBATIM;
}

}

}

fputc (0, output);

if (mode == P0_NORMAL)
{
int output_size = ftell (output);
char *ret;

ret = malloc (output_size);
rewind (output);
fread (ret, 1, output_size, output);
fclose (output);

return ret;
}
else
{
fputs ("Didn't finish pass 0 in normal state.\n", stderr);
fclose (output);
return NULL;
}
}

/* Pass 1 */

struct popped_function
{
char *func;
int iters;
char *args;
};

struct fundef
{
char *expr;
int at;
};

int do_pass1 (char *);
int substitute_def (char *);
int parse_expression (char *, char *, char **, int);
struct popped_function *pop_function (char **);
char *pop_arg (char **);

int at;

struct fundef *defs[MAX_DEFINES];
int defs_ptr = 0;

FILE *output;

char *
pass1 (char *content)
{
/*
Pass 1 expands composed and iterated functions and substitutes definitions,
leaving the code in normal form.
*/
int ret;
size_t i;

output = tmpfile ();

hcreate (MAX_DEFINES);

ret = do_pass1 (content);
fputc (0, output);

hdestroy ();
for (i = 0; i < defs_ptr; ++i)
free (defs[i]);

if (ret)
{
fclose (output);
return NULL;
}
else
{
long output_size = ftell (output);
content = malloc (output_size);
rewind (output);
fread (content, 1, output_size, output);
fclose (output);

return content;
}
}

int
do_pass1 (char *content)
{
char *func_expr, *subject;
int open_braces, fs;

/* Scan to the first { */
for (; *content != '{'; ++content)
{
if (!*content) /* No SexpCode here */
return 0;
if (*content == '}')
{
fputs ("Unexpected }.\n", stderr);
return 1;
}
fputc (*content, output);
}

/* Extract the function expression */
func_expr = ++content;

for (open_braces = 0; !(isspace (*content) && open_braces == 0); ++content)
{
switch (*content)
{
case '{':
++open_braces;
break;
case '}':
--open_braces;
break;
case 0:
/* Premature EOS */
fputs ("Function expression ended abruptly.\n", stderr);
return 1;
}
}
*content = 0;

/* Extract the subject of function application */
subject = ++content;
for (open_braces = 0; !(*content == '}' && open_braces == 0); ++content)
{
switch (*content)
{
case '{':
++open_braces;
break;
case '}':
--open_braces;
break;
case 0:
/* Premature EOS */
fputs ("Unclosed statement.\n", stderr);
return 1;
}
}
*content = 0;

if (strcmp ("define", func_expr) == 0)
{
/* Function definition */
ENTRY r, *e;
struct fundef *fd;

r.key = pop_arg (&subject);

if (r.key == NULL || (r.key[0] == '\'' && r.key[1] == '{') ||
*subject == 0)
{
fputs ("Malformed definition.\n", stderr);
return 1;
}

fd = malloc (sizeof (struct fundef));
defs[defs_ptr++] = fd;

fd->expr = subject;
fd->at = at++;
r.data = fd;

/* hsearch is dumb */
if ((e = hsearch (r, FIND)) != NULL)
((struct fundef *) e->data)->expr = subject;
else if (hsearch (r, ENTER) == NULL)
{
fputs ("Definition table is full.\n", stderr);
return 1;
}

}
else if (strcmp ("undefine", func_expr) == 0)
{
/* Function undefinition */
ENTRY r, *e;

r.key = subject;

if ((e = hsearch (r, FIND)) != NULL)
((struct fundef *) e->data)->expr = NULL;

}
else
{
/* Normal function expression */
fs = parse_expression (func_expr, NULL, &subject, at);
if (fs < 0)
return 1;

if (do_pass1 (subject))
return 1;

for (; fs > 0; --fs)
fputc ('}', output);
}

return do_pass1 (content + 1);
}

int
parse_expression (char *func_expr, char *args, char **content, int curat)
{
struct popped_function *p;
char *subject = *content;
size_t i, fs = 0;
int verbatim = 0;
ENTRY e, *r;

while ((p = pop_function (&func_expr)) != NULL)
{
if (p->iters > MAX_ITERS || p->iters < 0)
{
fprintf (stderr, "Invalid number of iters: %d.\n", p->iters);
return -1;
}

e.key = p->func;

if (p->args != NULL)
{
/* Second argument syntax; recurse */
for (i = 0; i < p->iters; ++i)
{
int j = parse_expression (p->func, p->args, &subject, curat);

if (j < 0)
return -1;

fs += j;
}

}
else if (strcmp ("verbatim", p->func) == 0) /* Ugly hack for composed verbatim FIXME */
verbatim = 1;
else if ((r = hsearch (e, FIND)) != NULL &&
((struct fundef *) r->data)->expr != NULL &&
((struct fundef *) r->data)->at < curat)
{
/* Definition substitition; recurse */
int j;
char *expr = malloc (strlen (((struct fundef *) r->data)->expr) + 1);

strcpy (expr, ((struct fundef *) r->data)->expr);
curat = at;

j = parse_expression (expr,
args, content, ((struct fundef *) r->data)->at);
free (expr);

if (j < 0)
return -1;

fs += j;

}
else
{
/* Normal function */
struct sexpcode_func *f = get_func (p->func);

if (f == NULL)
{
fprintf (stderr, "Unknown function: %s.\n", p->func);
return -1;
}

for (i = 0; i < p->iters; ++i)
{
size_t j;

fprintf (output, "{%s ", p->func);

for (j = 0; j < f->arity; ++j)
{
char *arg;

if ((arg = pop_arg (&args)) == NULL)
if ((arg = pop_arg (&subject)) == NULL)
{
fprintf (stderr, "Not enough args to %s\n", p->func);
return -1;
}

fprintf (output, "%s ", arg);
}

++fs;
}

*content = subject;
}

free (p);
}

if (verbatim)
{
fputs ("{verbatim ", output);
++fs;
}

return fs; /* size_t to int? */
}

struct popped_function *
pop_function (char **func_expr)
{
char *expr = *func_expr, *rest = *func_expr;
struct popped_function *r;;

if (!*expr)
return NULL;

r = malloc (sizeof (struct popped_function));
r->iters = 1;

if (*expr == '{')
{
int open_braces;

++rest;
++expr;

r->func = expr;

/* Scan to of expression, balancing braces */
for (open_braces = 0; !(isspace (*rest) && open_braces == 0); ++rest)
{
switch (*rest)
{
case '{':
++open_braces;
break;
case '}':
--open_braces;
break;
case 0:
fputs ("Partial function expression ran off end.\n", stderr);
free (r);
return NULL;
}
}
*rest = 0;
r->args = ++rest;

/* Scan to end of arglist, balancing braces */
for (open_braces = 0; !(*rest == '}' && open_braces == 0); ++rest)
{
switch (*rest)
{
case '{':
++open_braces;
break;
case '}':
--open_braces;
break;
case 0:
fputs ("Partial function args ran off end.\n", stderr);
free (r);
return NULL;
}
}
*rest = 0;
++rest;

if (*rest == '^' || *rest == '*')
{
r->iters = atoi (rest + 1);
for (; isdigit (*rest); ++rest);
if (*rest != 0 && *rest != '.')
{
fputs ("Faulty iter specification.\n", stderr);
free (r);
return NULL;
}
}

if (*rest == 0) /* End of expression */
--rest;
else if (*rest == '.')
*rest = 0;
else
{
fputs ("Illegal juxtaposition.\n", stderr);
free (r);
return NULL;
}
}
else
{
r->func = expr;
r->args = NULL;

for (;; ++rest)
{
if (*rest == '^' || *rest == '*')
{
*rest++ = 0;
r->iters = atoi (rest);
for (; isdigit (*rest); ++rest);
if (*rest != 0 && *rest != '.')
{
fputs ("Faulty iter specification.\n", stderr);
free (r);
return NULL;
}
}
if (*rest == 0)
{
/* End of function expression */
--rest;
break;
}
else if (*rest == '.')
{
*rest = 0;
break;
}
}
}

*func_expr = ++rest;

return r;
}struct fundef

char *
pop_arg (char **content)
{
char *arg = *content, *rest;

if (arg == NULL)
return NULL;

/* Get rid of preceding whitespace */
for (; *arg && isspace (*arg); ++arg);
rest = arg;

if (*arg == '\'' && *(arg + 1) == '{')
{
for (; *rest && *rest != '}'; ++rest);
if (!*rest)
{
fputs ("Arg ran off string.\n", stderr);
return NULL;
}
++rest;
}
else
for (; *rest && !isspace (*rest); ++rest);

*rest = 0;
*content = ++rest;

return arg;
}

/* Pass 2 */

char *sexpcode_unescape (char *);

char *
pass2 (char *content)
{
/*
Pass 2 translates normal-form SexpCode to output using an external get_func.
*/
output = tmpfile ();

if (do_sexpcode (content))
{
fclose (output);
return NULL;
}
else
{
int output_size = ftell (output) + 1;

fputc (0, output);
content = malloc (output_size);
rewind (output);
fread (content, 1, output_size, output);
fclose (output);

return content;
}
}

int
do_sexpcode (char *content)
{
size_t i, open_braces;
char *args[MAX_ARITY], *start = content, *rest;
struct sexpcode_func *f;

/* Find the first { */
for (; *content != '{'; ++content)
{
switch (*content)
{
case 0:
/* No SexpCode here */
return 0;
case 1:
*content = '{';
if (0)
case 2:
*content = '}';
default:
fputc (*content, output);
}
}

*content++ = 0;
start = content;

/* Find the matching } */
for (open_braces = 0; open_braces != 0 || *content != '}'; ++content)
{
switch (*content)
{
case '{':
++open_braces;
break;
case '}':
--open_braces;
break;
case 0:
fputs ("Unclosed expression.\n", stderr);
return 1;
}
}

*content = 0;
rest = ++content;

/* Extract function */
for (content = start; *content && !isspace (*content); ++content);

if (!*content)
{
fputs (stderr, "{problem}\n", stderr);
return 1;
}

*content++ = 0;
f = get_func (start);

if (f == NULL)
{
fprintf (stderr, "Not a real function: %s.\n", start);
return 1;
}

/* Extract arguments */
for (i = 0; i < f->arity; ++i)
{
args[i] = sexpcode_unescape (pop_arg (&content));

if (args[i] == NULL)
{
fprintf (stderr, "Bad args to %s.\n", start);
return 1;
}

if (args[i][0] == '\'' && args[i][1] == '{')
{
args[i] += 2;
args[i][strlen (args[i]) - 1] = 0;
}
}

/* Apply */
f->func (content, args);

return do_sexpcode (rest);
}

char *
sexpcode_unescape (char *content)
{
char *start = content;

do
{
if (*content == 1)
*content = '{';
if (*content == 2)
*content = '}';
}
while (*content++);

return start;
}

/* All together now */

char *
sexpcode (const char *input)
{
char *a;
return !(a = pass0 (input)) || !(a = pass1 (a)) ? NULL : pass2 (a);
}

________________________________________
/* sexpcode.h */

struct sexpcode_func {
char *name;
int arity;
void (*func)(char *, char **);
};

char *pass0 (const char *);
char *pass1 (char *);
char *pass2 (char *);

char *sexpcode_unescape(char *);
int do_sexpcode(char *);

char *sexpcode(const char *);

________________________________________
/* html.h */
struct sexpcode_func *(html_get_func)(char *);

________________________________________
/* html.c */

#include <stdio.h>
#include <string.h>
#include <stddef.h>

#include "sexpcode.h"
#include "html.h"

extern FILE *output;

/* Arity 0 */
void html_b (char *, char **);
void html_i (char *, char **);
void html_o (char *, char **);
void html_u (char *, char **);
void html_s (char *, char **);
void html_m (char *, char **);
void html_tt (char *, char **);
void html_spoiler (char *, char **);
void html_sub (char *, char **);
void html_sup (char *, char **);
void html_quote (char *, char **);
void html_verbatim (char *, char **);

/* Arity 1*/
void html_url (char *, char **);
void html_code (char *, char **);
void html_img (char *, char **);
void html_ruby (char *, char **);

struct sexpcode_func html_functions[] =
{
{"b", 0, html_b},
{"i", 0, html_i},
{"o", 0, html_o},
{"u", 0, html_u},
{"s", 0, html_s},
{"m", 0, html_m},
{"tt", 0, html_tt},
{"spoiler", 0, html_spoiler},
{"sub", 0, html_sub},
{"sup", 0, html_sup},
{"quote", 0, html_quote},
{"verbatim", 0, html_verbatim},
{"url", 1, html_url},
{"code", 1, html_code},
{"img", 1, html_img},
{"ruby", 1, html_ruby}
};

struct sexpcode_func *
html_get_func(char *funcname)
{
size_t i;
for (i = 0; i < sizeof html_functions / sizeof html_functions[0]; i++)
if (strcmp (funcname, html_functions[i].name) == 0)
return &html_functions[i];
return NULL;
}

/* Arity 0 */
void
html_b (char *content, char **args)
{
fputs ("<b>", output);
do_sexpcode (content);
fputs ("</b>", output);
}

void
html_i (char *content, char **args)
{
fputs ("<i>", output);
do_sexpcode (content);
fputs ("</i>", output);
}

void
html_o (char *content, char **args)
{
fputs ("<span class=\"o\">", output);
do_sexpcode (content);
fputs ("</span>", output);
}

void
html_u (char *content, char **args)
{
fputs ("<u>", output);
do_sexpcode (content);
fputs ("</u>", output);
}

void
html_s(char *content, char **args)
{
fputs ("<s>", output);
do_sexpcode (content);
fputs ("</s>", output);
}

void
html_m(char *content, char **args)
{
fputs ("<m>", output);
do_sexpcode (content);
fputs ("</m>", output);
}

void
html_tt(char *content, char **args)
{
fputs ("<tt>", output);
do_sexpcode (content);
fputs ("</tt>", output);
}

void
html_spoiler(char *content, char **args)
{
fputs ("<span class=\"spoiler\">", output);
do_sexpcode (content);
fputs ("</span>", output);
}

void
html_sub(char *content, char **args)
{
fputs ("<sub>", output);
do_sexpcode (content);
fputs ("</sub>", output);
}

void
html_sup(char *content, char **args)
{
fputs ("<sup>", output);
do_sexpcode (content);
fputs ("</sup>", output);
}

void
html_quote(char *content, char **args)
{
fputs ("<blockquote>", output);
do_sexpcode (content);
fputs ("</blockquote>", output);
}

void
html_verbatim(char *content, char **args)
{
fputs (sexpcode_unescape (content), output);
}

/* Arity 1 */
void
html_url(char *content, char **args)
{
fprintf (output, "<a href=\"%s\">", args[0]);
do_sexpcode (content);
fputs ("</a>", output);
}

void
html_code(char *content, char **args)
{
fprintf (output, "<code title=\"%s code\">", args[0]);
do_sexpcode (content);
fputs ("</code>", output);
}

void
html_img(char *content, char **args)
{
fprintf (output,
"<img src=\"%s\" title=\"%s\" />",
args[0],
sexpcode_unescape (content));
}

void
html_ruby(char *content, char **args)
{
fputs ("<ruby>", output);
do_sexpcode (content);
fprintf (output, "<rt>%s</rt></ruby>", args[0]);
}

________________________________________
/* compile.h */
char *do_compile_sexpcode (char *);

________________________________________
/* compile.c */
#include <string.h>
#include <stdlib.h>

#include "sexpcode.h"
#include "html.h"

struct sexpcode_func *(*get_func)(char*);

char *
do_compile_sexpcode (char *buffa)
{
char *original;

original = malloc (sizeof *original * strlen (buffa));
strcpy (original, buffa);

get_func = html_get_func;

return !(buffa = pass0 (buffa)) || !(buffa = pass1 (buffa)) || !(buffa = pass2 (buffa)) ? original : buffa;
}

Name: Anonymous 2016-03-27 17:41

>>27
I thought it was cute, but I don't write much C. I'm not sure how I feel about your whitespace parens fetish but it looks fine and yes you can do whatever you want with it!

As for your "printing 1 and 2" question, as far as I gather, this is to support the "verbatim" function (which allows you to do {verbatim {b this} bbcode will not be {i processed}} &c.). check the do_sexpcode function. It replaces these with { and } respectively

Name: Anonymous 2016-03-27 18:09

>>28
I don't really care about formatting, but it auto-runs indent on saving, this is why I posted it like this.
Thank you for explaining about verbatim. While it seems a bit hack-ish but also cool.

Name: Anonymous 2016-04-01 15:28

{code.b SEXPCODE WHEN
E
X
P
C
O
D
E

W
H
E
N}

Name: Anonymous 2016-04-06 19:38

Check 'em dubs

Name: Anonymous 2016-04-06 23:06

>>31
You call those ``dubs''?? Check out THESE dubs and weep, bitch boy!

Name: Anonymous 2016-04-07 1:38

Sexpcode needs parens, not braces

Name: Anonymous 2016-04-07 2:57

>>33
Parens are used way more often than braces, it'd be a pain to escape all those parens. If anything, they should have been square brackets.

Name: Anonymous 2016-04-07 15:37

>>27
*content != 0

Why do people do this?

Name: Anonymous 2016-06-01 17:37

It's been two months. Had a chance to grok that source yet, Admin-hakase?

Name: Anonymous 2016-06-03 16:05

Admin-sama has abandoned us!

Name: Anonymous 2016-06-03 16:44

Admin-kuso, why?

Name: Anonymous 2016-06-04 0:56

sage

Name: Anonymous 2016-06-04 14:26

>>39
What the fuck is wrong with you?

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List