common.c
author Tero Marttila <terom@fixme.fi>
Fri, 06 Jun 2008 18:35:46 +0300
changeset 11 082bfaf38cf0
parent 8 4d38ccbeb93e
child 12 43297144f196
permissions -rw-r--r--
* massive structural rewrite. Split off code into several new modules (render, render_png, render_local) and updated new modules to use them.
* the beginnings of render_multi, really not done yet

committer: Tero Marttila <terom@fixme.fi>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>

#include "common.h"

void die (const char *msg) {
    perror(msg);
    exit(EXIT_FAILURE);
}

void error (const char *fmt, ...) {
    va_list va;

    va_start(va, fmt);
    vfprintf(stderr, fmt, va);
    va_end(va);

    fprintf(stderr, "\n");
}

void perr (const char *fmt, ...) {
    va_list va;

    va_start(va, fmt);
    vfprintf(stderr, fmt, va);
    va_end(va);

    fprintf(stderr, ": %s\n", strerror(errno));
}

void perr_exit (const char *fmt, ...) {
    va_list va;

    va_start(va, fmt);
    vfprintf(stderr, fmt, va);
    va_end(va);

    fprintf(stderr, ": %s\n", strerror(errno));
    exit(EXIT_FAILURE);
}

void err_exit (const char *fmt, ...) {
    va_list va;

    va_start(va, fmt);
    vfprintf(stderr, fmt, va);
    va_end(va);

    fprintf(stderr, "\n");
    exit(EXIT_FAILURE);
}

void err_func (const char *func, const char *fmt, ...) {
    va_list va;
    
    fprintf(stderr, "%s: ", func);

    va_start(va, fmt);
    vfprintf(stderr, fmt, va);
    va_end(va);

    fprintf(stderr, "\n");
}

void perr_func (const char *func, const char *fmt, ...) {
    va_list va;
    
    fprintf(stderr, "%s: ", func);

    va_start(va, fmt);
    vfprintf(stderr, fmt, va);
    va_end(va);

    fprintf(stderr, ": %s\n", strerror(errno));
}

int parse_hostport (char *hostport, char **host, char **port) {
    char *c;

    char brace = 0, colon = 0;

    *host = *port = NULL;

    for (c = hostport; *c != '\0'; c++) {
        if (isspace(*c))
            continue;

        switch (*c) {
            case '[':
                if (c > hostport) {
                    error("parse_hostport: %c must be first char, if any: %s", *c, hostport);
                    return -1;
                }
                
                brace = *c;
                break;

            case ']':
                if (!brace) {
                    error("parse_hostport: %c without matching brace: %s", *c, hostport);
                    return -1;
                }

                if (!*host) {
                    error("parse_hostport: empty hostname: %s", hostport);
                    return -1;
                }

                brace = 0;
                break;
            
            case ':':
                if (brace) {
                    // colons inside braces are left as-is
                    continue;
                }

                if (!*host) {
                    error("parse_hostport: colon before hostname: %s", hostport);
                    return -1;
                }

                if (*port) {
                    error("parse_hostport: colon after port: %s", hostport);
                    return -1;
                }

                if (colon) {
                    error("parse_hostport: too many colons: %s", hostport);
                    return -1;
                };

                // finished parsing the host part, move on to the port part
                colon = ':';
                *c = '\0';
                break;

            default:
                if (!*host) {
                    // first char of the host
                    *host = c;

                } else if (colon && !*port) {
                    // first char of the port
                    *port = c;

                } // else a part of either, don't care about it

                break;
        }
    }

    if (!*host) {
        error("parse_hostport: missing hostname: %s", hostport);
        return -1;
    }

    if (brace) {
        error("parse_hostport: missing close-brace for %c: %s", brace, hostport);
        return -1;
    }

    if (colon && !*port) {
        error("parse_hostport: missing port: %s", hostport);
        return -1;
    }

    return 0;
}