/*
 * Pound - pound.c(check_URL): test program
 * Copyright (C) 2003 Yoshinori TAKESAKO
 */
#include <stdio.h>

/*
 * Put your test data of pass URL (expect)
 */
char *pass_url[] = {
	"/",
	"/#",
	"/#flag",
	"/?query",
	"/?query#",
	"/?query#frag",
	"/index.html",
	"/index.html#",
	"/index.html#flag",
	"/cgi-bin/printenv.cgi",
	"/cgi-bin/printenv.cgi?",
	"/cgi-bin/printenv.cgi?#",
	"/cgi-bin/printenv.cgi?#frag",
	"/cgi-bin/printenv.cgi?query",
	"/cgi-bin/printenv.cgi?query#",
	"/cgi-bin/printenv.cgi?query#frag",
	"/cgi-bin/printenv.cgi?a=",
	"/cgi-bin/printenv.cgi?a=1",
	"/cgi-bin/printenv.cgi?a=1&",
	"/cgi-bin/printenv.cgi?a=1&b",
	"/cgi-bin/printenv.cgi?a=1&b=2",
	"/cgi-bin/printenv.cgi?a=1&b=2&",
	"/cgi-bin/printenv.cgi?a=1&b=2&&",
	"/cgi-bin/printenv.cgi?a=1#",
	"/cgi-bin/printenv.cgi?a=1&#",
	"/cgi-bin/printenv.cgi?a=1&b#",
	"/cgi-bin/printenv.cgi?a=1&b=2#",
	"/cgi-bin/printenv.cgi?a=1&b=2&#",
	"/cgi-bin/printenv.cgi?a=1&b=2&&#",
	"/cgi-bin/printenv.cgi?a=1#frag",
	"/cgi-bin/printenv.cgi?a=1&#frag",
	"/cgi-bin/printenv.cgi?a=1&b#frag",
	"/cgi-bin/printenv.cgi?a=1&b=2#frag",
	"/cgi-bin/printenv.cgi?a=1&b=2&#frag",
	"/cgi-bin/printenv.cgi?a=1&b=2&&#frag",
	NULL
};

/*
 * Put your test data of ignore URL (expect)
 */
char *ignore_url[] = {
	"/???",
	"/?query?",
	"/?a==1",
	"/#flag?a=1",
	"/?a=b=c=1",
	"/#flag#",
	NULL
};

/*
 * Put character set
 */
char *CS_segment = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.!~*'():@&=+$,%-{}<>\"|\\^[]'";
char *CS_parm    = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.!~*'():@&=+$,%-{}|\\^[]'";
char *CS_qid     = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.!~*'(),%-{}|\\^[]'";
char *CS_qval    = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789/_.!~*'(),%-{}|\\^[]'";
char *CS_frag    = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.!~*'(),%{}|\\^[]'";

/*
 * Check the validity of a URL (Fixed)
 */
static int
check_URL(char *line)
{
    int len, span;

    for(len = 0; line[len] == '/'; ) {
        len++;
        if(!(span = strspn(line + len, CS_segment))) {
            if(line[len] == '?' || line[len] == '#')
                break;
        } else
            len += span;
        if(line[len] == ';') {
            len++;
            if(!(span = strspn(line + len, CS_parm)))
                return -1;
            len += span;
        }
    }
    if(line[len] == '?') {
        len++;
        for(;;) {
            if(!(span = strspn(line + len, CS_qid))) {
                if(line[len] == 0 || line[len] == '#') {
                    break;
                } else if(line[len] == '&') {
                    len++;
                    continue;
                } else {
                    return -2;
                }
            }
            len += span;
            if(line[len] == '=') {
                len++;
                len += strspn(line + len, CS_qval);
            }
            if(line[len] == '&')
                len++;
            else
                break;
        }
    }
    if(line[len] == '#') {
        len++;
        len += strspn(line + len, CS_frag);
    }
    return line[len];
}

/*
 * Main
 */
int
main(int argc, char **argv)
{
	char *url;
	int i, result;
    
	for (i = 0; url = pass_url[i]; i++) {
		result = check_URL(url);
		if (result) {
			fprintf(stderr, "[FAILED]: check pass_url(% 2d) %s\n", result, url);
		} else {
			fprintf(stderr, "[  OK  ]: check pass_url(% 2d) %s\n", result, url);
		}
	}
	for (i = 0; url = ignore_url[i]; i++) {
		result = check_URL(url);
		if (!result) {
			fprintf(stderr, "[FAILED]: check ignore_url(% 2d) %s\n", result, url);
		} else {
			fprintf(stderr, "[  OK  ]: check ignore_url(% 2d) %s\n", result, url);
		}
	}
}


