1. Sulaiman Mustafa
  2. clia

Source

clia / clia.c

/*
    clia.c
    Copyright 2012 Sulaiman Mustafa <seininn@hush.com>
    License: GPLv3 (Contact me for a possible alternative license)
    Webpage: people.sigh.asia/~sulaiman/software/libraries/clia
*/

#include <stdlib.h>
#include <string.h>

#define LONG_OPT 0
#define SHORT_OPT 1

struct option {
    int index, count;
    char *os[2];
};
static struct optionlist {
    struct option **list;
    int count, last;
} options = {NULL, 0, -1}; 


int clia_add(char *long_option, char *short_option) {
    ++options.count;
    if (
        !(options.list = realloc(options.list, sizeof(struct option *)*options.count) ) || 
        !(options.list[options.count-1] = malloc(sizeof(struct option)))
        ){
        return 1;
    }
    
    options.list[options.count-1]->index = 0;
    options.list[options.count-1]->count = 0;
    
    if ((options.list[options.count-1]->os[LONG_OPT] = malloc(strlen(long_option)*sizeof(char)+1))) {
        strcpy(options.list[options.count-1]->os[LONG_OPT], long_option);
    } else return 1;
    if ((options.list[options.count-1]->os[SHORT_OPT] = malloc(strlen(short_option)*sizeof(char)+1))) {
        strcpy(options.list[options.count-1]->os[SHORT_OPT], short_option);
    } else return 1;
    
    return 0;
}


int clia_parse(int argc, char **argv){
    char *arg;
    int type, i, j;

    for (i=0; i<argc; ++i){
        arg = argv[i];
        if (*arg == '-' && *(arg+1)){
            options.last = -1;
            
            if (*(arg+1) == '-' && !*(arg+2)) return 0;
            else if (*(arg+1) == '-' && *(arg+2)){ type=LONG_OPT; arg+=2; }
            else { type=SHORT_OPT; ++arg; }
            
            for (j=0;j<options.count;++j){
                if (!strcmp(options.list[j]->os[type], arg)){
                    options.last = j;
                    options.list[options.last]->index = i;
                    options.list[options.last]->count = 0;
                    break;
                }
            }
            if (options.last == -1){
                return i;
            }
        } 
        else if (options.last != -1) ++options.list[options.last]->count;
    }
    return 0;
}

int clia_get(char *long_option, char *resource){
    int i, out=-1;
    for (i=0; i<options.count; ++i){
        if (!strcmp(long_option, options.list[i]->os[LONG_OPT])) {
            if (*resource == 'c') out = options.list[i]->count;
            else out = options.list[i]->index;
            break;
        }
    }
    return out;
}

void clia_clear(){
    int i;
    for (i=0; i<options.count; ++i){
        free(options.list[i]->os[LONG_OPT]);
        free(options.list[i]->os[SHORT_OPT]);
        free(options.list[i]);
    }
    free(options.list);
    options.list = NULL;
    options.count = 0;
    return;   
}