Last commit for inifile.c: 8a155c1522c0818d43b6bae4cc5806ea41f88793

Parallel md code using OpenMP and MPI

Ramses van Zon [2016-09-29 14:34:01]
Parallel md code using OpenMP and MPI
#include "inifile.h"
#include <string.h>
#include <assert.h>

const key_value_t* kvt_lookup_entry(const key_value_table_t* table, const char* key)
{
    for (int i=0;i<table->length;i++)
        if (strcmp(key, table->entry[i].key)==0)
            return table->entry + i;
    return NULL;
}

const char* kvt_lookup(const key_value_table_t* table, const char* key)
{
    const key_value_t* entry = kvt_lookup_entry(table, key);
    if (entry != NULL)
        return entry->value;
    else {
        fprintf(stderr, "Warning: could not find a value for '%s'.\n", key);
        return NULL;
    }
}

const char* kvt_lookup_with_default(const key_value_table_t* table, const char* key, const char* def)
{
    const key_value_t* entry = kvt_lookup_entry(table, key);
    if (entry != NULL)
        return entry->value;
    else
        return def;
}

const key_value_t* kvt_begin(const key_value_table_t* table)
{
    return table->entry;
}

const key_value_t* kvt_end(const key_value_table_t* table)
{
    return table->entry + table->length;
}

const key_value_t* kvt_insert(key_value_table_t* table,
                              const char key[MAXKEYLEN],
                              const char value[MAXVALUELEN])
{
    key_value_t* existing_entry = (key_value_t*)kvt_lookup_entry(table, key);
    if (existing_entry==NULL) {
        int len = table->length;
        if (len < MAXTABLELEN) {
            strncpy(table->entry[len].key, key, MAXKEYLEN);
            strncpy(table->entry[len].value, value, MAXVALUELEN);
            table->length ++;
            return table->entry + len;
        } else {
            return NULL;
        }
    } else {
        strncpy(existing_entry->value, value, MAXVALUELEN);
        return existing_entry;
    }
}

void kvt_read_name(key_value_table_t* table, const char* filename);

static void TRIMWHITESPACE(char** str)
{
    if (*str && **str && (*str)[strlen(*str)-1] == '\n')
        (*str)[strlen(*str)-1] = '\0';
    while (*str && **str && ( **str == ' ' || **str == '\t' ) )
        (*str)++;
    while (*str && **str && ( (*str)[strlen(*str)-1]==' '||(*str)[strlen(*str)-1]=='\t'))
        (*str)[strlen(*str)-1]='\0';
}

static void TRIMQUOTES(char** str) {
    if ((*str)[0]=='"' && (*str)[strlen(*str)-1]=='"') {
        (*str)[strlen(*str)-1]='\0';
        (*str)++;
    }
    if ((*str)[0]=='\'' && (*str)[strlen(*str)-1]=='\'') {
        (*str)[strlen(*str)-1]='\0';
        (*str)++;
    }
}

static char* process_keyval_inputline(char** key, char** value)
{
    static char empty[1] = "";
    char* equalsign = strchr(*key, '=');
    if (equalsign) {
        *equalsign = '\0';
        *value = equalsign+1;
    } else {
        *value = empty;
    }
    TRIMWHITESPACE(key);
    /* treat trailing # as comments */
    char* hash = strchr(*value, '#');
    if (hash) *hash='\0';
    TRIMWHITESPACE(value);
    char* space = strchr(*value, ' ');
    if (!space) space = strchr(*value, '\t');
    if (space) {
        *space = '\0';
        return space+1;
    } else {
        return NULL;
    }
}

static void kvt_read_knowingly(key_value_table_t* table, FILE* f, const char* openfiles)
{
    char*  line = NULL;
    size_t len = 0;
    char empty[1] = "";
    while (getline(&line, &len, f) != -1) {
        char* key = line;
        char* value = NULL;
        if (key) {
            TRIMWHITESPACE(&key);
            if (key[0] == '#') {
                /* interpret the next word as a command followed by an argument string */
                /* skip pound sign and immediately following white space */
                char* command = key+1;
                char* args = NULL;
                while (command && ( command[0] == ' ' || command[0] == '\t' ) )
                    command++;
                /* next white space or tab is delimiter */
                char* space = strchr(command, ' ');
                if (!space) space = strchr(key, '\t');
                if (space) {
                    *space = '\0';
                    args = space+1;
                } else {
                    args = empty;
                }
                TRIMWHITESPACE(&args);
                /* trim surrounding quotes */
                TRIMQUOTES(&args);
                if (strcmp(command,"include")==0) {
                    if (openfiles && strcmp(args,openfiles)==0)
                        fprintf(stderr, "Warning: file '%s' included recursively; skipping.\n", openfiles);
                    else
                        kvt_read_name(table, args);
                }
            } else {
                while (key && key[0]) {
                    char* nextkey = process_keyval_inputline(&key, &value);
                    kvt_insert(table, key, value);
                    key = nextkey;
                }
            }
        }
    }
    free(line);
}

void kvt_read_name(key_value_table_t* table, const char* filename)
{
    FILE* f  = fopen(filename, "r");
    if (f == NULL) {
        fprintf(stderr, "Warning: file '%s' could not be read; skipping.\n", filename);
    } else {
        kvt_read_knowingly(table, f, filename);
        fclose(f);
    }
}

void kvt_read(key_value_table_t* table, FILE* f) {
    kvt_read_knowingly(table, f, NULL);
}


int kvt_lookup_int(const key_value_table_t* table, const char* key)
{
    const char* value = kvt_lookup(table, key);
    if (value) {
        int result;
        sscanf(value, "%d", &result);
        return result;
    } else {
        exit(1);
    }
}

int kvt_lookup_int_with_default(const key_value_table_t* table, const char* key, int def)
{
    const char* value = kvt_lookup(table, key);
    if (value) {
        int result;
        sscanf(value, "%d", &result);
        return result;
    } else {
        return def;
    }
}

long kvt_lookup_long(const key_value_table_t* table, const char* key)
{
    const char* value = kvt_lookup(table, key);
    if (value) {
        long result;
        sscanf(value, "%ld", &result);
        return result;
    } else {
        exit(1);
    }
}

long kvt_lookup_long_with_default(const key_value_table_t* table, const char* key, long def)
{
    const char* value = kvt_lookup(table, key);
    if (value) {
        long result;
        sscanf(value, "%ld", &result);
        return result;
    } else {
        return def;
    }
}

long long kvt_lookup_long_long(const key_value_table_t* table, const char* key)
{
    const char* value = kvt_lookup(table, key);
    if (value) {
        long long result;
        sscanf(value, "%lld", &result);
        return result;
    } else {
        exit(1);
    }
}

long long kvt_lookup_long_long_with_default(const key_value_table_t* table, const char* key, long long def)
{
    const char* value = kvt_lookup(table, key);
    if (value) {
        long long result;
        sscanf(value, "%lld", &result);
        return result;
    } else {
        return def;
    }
}

double kvt_lookup_double(const key_value_table_t* table, const char* key)
{
    const char* value = kvt_lookup(table, key);
    if (value) {
        double result;
        sscanf(value, "%lf", &result);
        return result;
    } else {
        exit(1);
    }
}

double kvt_lookup_double_with_default(const key_value_table_t* table, const char* key, double def)
{
    const char* value = kvt_lookup(table, key);
    if (value) {
        double result;
        sscanf(value, "%lf", &result);
        return result;
    } else {
        return def;
    }
}
ViewGit