BEGIN {
    FS = ",[ ]*";

    if (!wrappers_file || !enum_file || !table_file)
    {
        print "Error: One or more filenames have not been specified.";
        exit 1;
    }

    print "/* This file has been automatically generated */" > enum_file;
    print "" >> enum_file;
    print "typedef enum" >> enum_file;
    print "{" >> enum_file;

    print "/* This file has been automatically generated */" > table_file;
    print "" >> table_file;
    print "const void *service_table[] =" >> table_file;
    print "{" >> table_file

    print "/* This file has been automatically generated */" > wrappers_file;
    print "" >> wrappers_file;
    print "#include <sdk/monolithium.h>" >> wrappers_file;
    print "" >> wrappers_file;
}

END {
    if (enum_file && table_file && wrappers_file) {
        print "" >> enum_file;
        print "    SERVICE_COUNT" >> enum_file;
        print "} syscall_number_t;" >> enum_file;

        print "};" >> table_file;
    }
}

/sysret_t syscall_[a-zA-Z0-9_]+\(.*\);/ {
    print substr($0, 1, length - 1) >> wrappers_file;
    print "{" >> wrappers_file;

    match($0, /\(.*\)/);
    name = substr($0, 10, RSTART - 10);

    print "    &" name "," >> table_file;
    print "    " toupper(name) "," >> enum_file;
    printf "    return syscall(" toupper(name) >> wrappers_file;

    $0 = substr($0, RSTART + 1, RLENGTH - 2);

    if ($0 != "void") {
        for (i = 1; i <= NF; i++) {
            match($i, /[a-zA-Z0-9_]*$/);
            printf ", " substr($i, RSTART) >> wrappers_file;
        }
    }

    print ");" >> wrappers_file;
    print "}" >> wrappers_file;
    print "" >> wrappers_file;
}
