Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] View of /branches/pure-cfg/src/lib/common/input.c
ViewVC logotype

View of /branches/pure-cfg/src/lib/common/input.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1255 - (download) (as text) (annotate)
Mon May 23 23:46:34 2011 UTC (10 years, 4 months ago) by glk
File size: 13747 byte(s)
incomplete commit of the previous bugfix
/*! \file input.c
 *
 * \author John Reppy, Gordon Kindlmann
 */

/*
 * COPYRIGHT (c) 2011 The Diderot Project (http://diderot-language.cs.uchicago.edu)
 * All rights reserved.
 */
#include "Diderot/diderot.h"
#include <teem/hest.h>

/* FIXME: eventally we should change the naming conventions in the header files to be generic */
#if defined(DIDEROT_SINGLE_PRECISION)
#define vec2(a,b)      vec2f(a,b)
#define vec3(a,b,c)    vec3f(a,b,c)
#define vec4(a,b,c,d)  vec4f(a,b,c,d)
#else
#define vec2(a,b)      vec2d(a,b)
#define vec3(a,b,c)    vec3d(a,b,c)
#define vec4(a,b,c,d)  vec4d(a,b,c,d)
#endif

Status_t Diderot_InputString (const char *name, const char **v, bool hasDflt)
{
    return DIDEROT_FAIL;
}

Status_t Diderot_InputReal (const char *name, Diderot_real_t *v, bool hasDflt)
{
    char   buf[256];
    double   f;
    
    while (true) {
        if (hasDflt)
            printf("Enter value for %s (default %lf): ", name, (double)*v);
        else
            printf("Enter value for %s: ", name);
        fflush (stdout);
        
        char *p = fgets(buf, sizeof(buf), stdin);
        if (p == NULL)
            return DIDEROT_FAIL;   // EOF
        int n = sscanf(buf, "%lf\n", &f);
        if (n == 1) {
            *v = (Diderot_real_t)f;
            return DIDEROT_OK;;
        }
        else if (hasDflt)
            return DIDEROT_OK;;
    }
    
}

Status_t Diderot_InputVec2 (const char *name, Diderot_vec2_t *v, bool hasDflt)
{
    char   buf[256];
    double   f1, f2;
    
    while (true) {
        if (hasDflt) {
            Diderot_union2_t u;
            u.v = *v;
            printf("Enter value for %s (default %f %f): ",
                   name, (double)(u.r[0]), (double)(u.r[1]));
        }
        else
            printf("Enter value for %s: ", name);
        fflush (stdout);
        
        char *p = fgets(buf, sizeof(buf), stdin);
        if (p == NULL)
            return DIDEROT_FAIL;   // EOF
        int n = sscanf(buf, "%lf %lf\n", &f1, &f2);
        if (n == 2) {
            *v = vec2((Diderot_real_t)f1, (Diderot_real_t)f2);
            return DIDEROT_OK;;
        }
        else if (hasDflt)
            return DIDEROT_OK;;
    }
    
}

Status_t Diderot_InputVec3 (const char *name, Diderot_vec3_t *v, bool hasDflt)
{
    char   buf[256];
    double   f1, f2, f3;
    
    while (true) {
        if (hasDflt) {
            Diderot_union3_t u;
            u.v = *v;
            printf("Enter value for %s (default %f %f %f): ",
                   name, (double)(u.r[0]), (double)(u.r[1]), (double)(u.r[2]));
        }
        else
            printf("Enter value for %s: ", name);
        fflush (stdout);
        
        char *p = fgets(buf, sizeof(buf), stdin);
        if (p == NULL)
            return DIDEROT_FAIL;   // EOF
        int n = sscanf(buf, "%lf %lf %lf\n", &f1, &f2, &f3);
        if (n == 3) {
            *v = vec3((Diderot_real_t)f1, (Diderot_real_t)f2, (Diderot_real_t)f3);
            return DIDEROT_OK;;
        }
        else if (hasDflt)
            return DIDEROT_OK;;
    }
    
}

//! Option type tags
typedef enum {
    optTypeUnknown,       // 0 
    optTypeFlag,          // 1
    optTypeBool,          // 2
    optTypeInt,           // 3
    optTypeReal,          // 4
    optTypeReal2,         // 5
    optTypeReal3,         // 6
    optTypeReal4,         // 7
    optTypeString         // 8
} optType_t;

typedef struct {
    char   *name;         // option name
    char   *desc;         // option description (a phrase or sentence)
    optType_t ty;         // option type
    union {               // storage that is passed into hest
        int b;            // storage for boolean-valued options
        double r[4];      // storage for real-valued options
        int64_t i[4];     // storage for integer-valued options
        char *s;          // storage for string-valued options
    } hval;
    void *valp;           // pointer to Diderot global variable being set
} optDef_t;

struct Diderot_Options_s {
    char *progInfo;       // documentation string for describing whole program,
                          // intended to be one or more sentences
    hestOpt *hopt;        // dynamically managed hest options
    hestParm *hparm;      // hest parameters
    optDef_t **odef;      // dynamically reallocated via odefArr
    unsigned int odefNum; // length of meaningful values in odef[]
    airArray *odefArr;    // manages odef and odefNum;
    airArray *mop;        // manages hopt, hparm, and odefArr
};

static void *optDefNew () {
    optDef_t *odef = AIR_CALLOC(1, optDef_t);
    odef->name = odef->desc = NULL;
    odef->ty = optTypeUnknown;
    /* not trying to initialize hval */
    odef->valp = NULL;
    return (void*)odef;
}

static void *optDefNix (void *_odef) {
    optDef_t *odef = (optDef_t *)_odef;
    airFree(odef->name);
    airFree(odef->desc);
    if (optTypeString == odef->ty) {
        airFree(odef->hval.s);
    }
    airFree(odef);
    return NULL;
}

struct Diderot_Options_s *Diderot_Options_New (void) {
    static const char me[]="Diderot_Options_New";
    struct Diderot_Options_s *dopts = AIR_CALLOC(1, struct Diderot_Options_s);
    if (!dopts) {
        fprintf (stderr, "%s: unable to allocate output\n", me);
        exit (1);
    }
    dopts->progInfo = NULL;
    dopts->mop = airMopNew();
    dopts->hopt = NULL;
    dopts->hparm = hestParmNew();
    dopts->hparm->noArgsIsNoProblem = AIR_TRUE;
    airMopAdd(dopts->mop, dopts->hparm, (airMopper)hestParmFree, airMopAlways);
    dopts->odef = NULL;
    dopts->odefNum = 0;
    dopts->odefArr = airArrayNew((void**)(&dopts->odef), &dopts->odefNum, 
                                 sizeof(optDef_t*), 8 /* allocation increment */);
    if (!(dopts->odefArr)) {
        fprintf (stderr, "%s: unable to allocate option array\n", me);
        exit (1);
    }
    airArrayPointerCB(dopts->odefArr, optDefNew, optDefNix);
    airMopAdd(dopts->mop, dopts->odefArr, (airMopper)airArrayNuke, airMopAlways);
    
    return dopts;
}

void Diderot_Options_Nix (struct Diderot_Options_s *dopts) {
    if (dopts) {
        airFree(dopts->progInfo);
        airMopOkay(dopts->mop);
        free(dopts);
    }
    return;
}

void Diderot_OptProgramInfoSet (struct Diderot_Options_s *dopts,
                                const char *progInfo) {
    static const char me[]="Diderot_OptProgramInfoSet";

    if (progInfo) {
        if (!( dopts->progInfo = airStrdup(progInfo) )) {
            fprintf (stderr, "%s: unable to copy program info", me);
            exit (1);
        }
    }
}

static optDef_t *optAdd (struct Diderot_Options_s *dopts,
                         const char *name, const char *desc, 
                         void *valp, optType_t ty) {
    static const char me[]="optAdd";
    unsigned int nidx;
    
    if (!( name && desc )) {
        fprintf (stderr, "%s: need both name (%p) and desc (%p) non-NULL\n",
                 me, name, desc);
        exit (1);
    }
    nidx = airArrayLenIncr(dopts->odefArr, 1);
    if (!dopts->odef) {
        fprintf (stderr, "%s: unable to reallocate option array\n", me);
        exit (1);
    }
    optDef_t *odef = dopts->odef[nidx];
    odef->name = airStrdup(name);
    odef->desc = airStrdup(desc);
    if (!(odef->name && odef->desc)) {
        fprintf (stderr, "%s: unable to allocate strings (%p,%p)\n",
                 me, odef->name, odef->desc);
        exit (1);
    }
    odef->valp = valp;
    odef->ty = ty;
    
    return odef;
}

void Diderot_OptAddFlag (struct Diderot_Options_s *dopts,
                         const char *name, const char *desc,
                         bool *flg) {
    optDef_t *odef = optAdd (dopts, name, desc, (void*)flg, optTypeFlag);
    hestOptAdd (&dopts->hopt, name, NULL, airTypeInt, 0, 0, &odef->hval.b,
                NULL, desc);
}

void Diderot_OptAddBool (struct Diderot_Options_s *dopts,
                         const char *name, const char *desc,
                         bool *v, bool hasDflt) {
    optDef_t *odef = optAdd (dopts, name, desc, (void*)v, optTypeBool);
    hestOptAdd (&dopts->hopt, name, "bool", airTypeBool, 1, 1, &odef->hval.b, 
                hasDflt ? (*v ? "true" : "false") : NULL, desc);
}

void Diderot_OptAddInt (struct Diderot_Options_s *dopts,
                        const char *name, const char *desc,
                        Diderot_int_t *v, bool hasDflt) {
    char buf[AIR_STRLEN_HUGE] = "";
    if (hasDflt) {
        sprintf (buf, "%ld", (long)*v);
    }
    optDef_t *odef = optAdd (dopts, name, desc, (void*)v, optTypeInt);
    hestOptAdd (&dopts->hopt, name, "int", airTypeLongInt, 1, 1, odef->hval.i, 
                hasDflt ? buf : NULL, desc);
}

void Diderot_OptAddReal (struct Diderot_Options_s *dopts,
                         const char *name, const char *desc,
                         Diderot_real_t *v, bool hasDflt) {
    char buf[AIR_STRLEN_HUGE] = "";
    if (hasDflt) {
        sprintf (buf, "%lf", (double)*v);
    }
    optDef_t *odef = optAdd (dopts, name, desc, (void*)v, optTypeReal);
    hestOptAdd (&dopts->hopt, name, "val", airTypeDouble, 1, 1, odef->hval.r,
                hasDflt ? buf : NULL, desc);
}

void Diderot_OptAddReal2 (struct Diderot_Options_s *dopts,
                          const char *name, const char *desc,
                          Diderot_vec2_t *v, bool hasDflt) {
    char buf[AIR_STRLEN_HUGE] = "";

    if (hasDflt) {
        Diderot_union2_t u;
        u.v = *v;
        sprintf (buf, "%lf %lf", (double)(u.r[0]), (double)(u.r[1]));
    }
    optDef_t *odef = optAdd (dopts, name, desc, (void*)v, optTypeReal2);
    hestOptAdd (&dopts->hopt, name, "x y", airTypeDouble, 2, 2, odef->hval.r,
                hasDflt ? buf : NULL, desc);
}

void Diderot_OptAddReal3 (struct Diderot_Options_s *dopts,
                          const char *name, const char *desc,
                          Diderot_vec3_t *v, bool hasDflt) {
    char buf[AIR_STRLEN_HUGE] = "";

    if (hasDflt) {
        Diderot_union3_t u;
        u.v = *v;
        sprintf (buf, "%lf %lf %lf",
                 (double)(u.r[0]), (double)(u.r[1]), (double)(u.r[2]));
    }
    optDef_t *odef = optAdd (dopts, name, desc, (void*)v, optTypeReal3);
    hestOptAdd (&dopts->hopt, name, "x y z", airTypeDouble, 3, 3, odef->hval.r,
                hasDflt ? buf : NULL, desc);
}

void Diderot_OptAddReal4 (struct Diderot_Options_s *dopts,
                          const char *name, const char *desc,
                          Diderot_vec4_t *v, bool hasDflt) {
    char buf[AIR_STRLEN_HUGE] = "";

    if (hasDflt) {
        Diderot_union4_t u;
        u.v = *v;
        sprintf (buf, "%lf %lf %lf %lf",
                 (double)(u.r[0]), (double)(u.r[1]),
                 (double)(u.r[2]), (double)(u.r[3]));
    }
    optDef_t *odef = optAdd (dopts, name, desc, (void*)v, optTypeReal4);
    hestOptAdd (&dopts->hopt, name, "x y z w", airTypeDouble, 4, 4, odef->hval.r,
                hasDflt ? buf : NULL, desc);
}

void Diderot_OptAddString (struct Diderot_Options_s *dopts,
                           const char *name, const char *desc,
                           char **v, bool hasDflt) {
    optDef_t *odef = optAdd (dopts, name, desc, (void*)v, optTypeString);
    hestOptAdd (&dopts->hopt, name, "str", airTypeString, 1, 1, &odef->hval.s,
                hasDflt ? *v : NULL, desc);
}

void Diderot_ProcessOptions (struct Diderot_Options_s *dopts,
                             int argc, const char **argv) {
    static const char me[]="Diderot_ProcessOptions";

    hestParseOrDie (dopts->hopt, argc-1, argv+1, dopts->hparm, argv[0],
                    dopts->progInfo ? dopts->progInfo : "(no program info set)",
                    AIR_TRUE, AIR_TRUE, AIR_TRUE);
    airMopAdd (dopts->mop, dopts->hopt, (airMopper)hestOptFree, airMopAlways);
    airMopAdd (dopts->mop, dopts->hopt, (airMopper)hestParseFree, airMopAlways);

    // convert values learned by hest to their Diderot representations
    for (int i = 0;  i < dopts->odefNum;  i++) {
        optDef_t *odef = dopts->odef[i];
        switch (odef->ty) {
        case optTypeFlag:
        case optTypeBool:
            *(bool*)(odef->valp) = odef->hval.b ? true : false;
            break;
        case optTypeInt:
            *(Diderot_int_t *)(odef->valp) = (Diderot_int_t)(odef->hval.i[0]);
            break;
        case optTypeReal:
            *(Diderot_real_t *)(odef->valp) = (Diderot_real_t)(odef->hval.r[0]);
            break;
        case optTypeReal2:
            *(Diderot_vec2_t *)(odef->valp) = vec2((Diderot_real_t)(odef->hval.r[0]),
                                                   (Diderot_real_t)(odef->hval.r[1]));
            break;
        case optTypeReal3:
            *(Diderot_vec3_t *)(odef->valp) = vec3((Diderot_real_t)(odef->hval.r[0]),
                                                   (Diderot_real_t)(odef->hval.r[1]),
                                                   (Diderot_real_t)(odef->hval.r[2]));
            break;
        case optTypeReal4:
            *(Diderot_vec4_t *)(odef->valp) = vec4((Diderot_real_t)(odef->hval.r[0]),
                                                   (Diderot_real_t)(odef->hval.r[1]),
                                                   (Diderot_real_t)(odef->hval.r[2]),
                                                   (Diderot_real_t)(odef->hval.r[3]));
            break;
        case optTypeString: 
            if (!( *(char **)(odef->valp) = airStrdup(odef->hval.s) )) {
                fprintf(stderr, "%s: unable to allocate string copy\n", me);
                exit (1);
            }
            break;
        default:
            fprintf (stderr, "%s: unknown option type %d\n", me, odef->ty);
            exit (1);
        }
    }
}

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0