Changeset 1383


Ignore:
Timestamp:
Apr 5, 2009 1:43:10 AM (15 years ago)
Author:
gah
Message:

add switch parser to encoding routines

Location:
trunk/lang/tcl/src
Files:
2 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/lang/tcl/src/Makefile.in

    r1257 r1383  
    5656                RpSignal.o  \
    5757                RpSysinfo.o  \
     58                Switch.o \
    5859                RpUnitsTclInterface.o \
    5960                RpUtilsTclInterface.o
  • trunk/lang/tcl/src/RpEncodeTclInterface.cc

    r1382 r1383  
    1414#include <tcl.h>
    1515#include "RpEncode.h"
    16 
    17 extern "C" Tcl_AppInitProc RpEncoding_Init;
     16extern "C" {
     17#include "Switch.h"
     18extern Tcl_AppInitProc RpEncoding_Init;
     19}
    1820
    1921static Tcl_ObjCmdProc RpTclEncodingIs;
     
    113115 */
    114116
     117/*
     118 *---------------------------------------------------------------------------
     119 *
     120 * AsSwitch --
     121 *
     122 *      Convert a string represent a node number into its integer
     123 *      value.
     124 *
     125 * Results:
     126 *      The return value is a standard Tcl result.
     127 *
     128 *---------------------------------------------------------------------------
     129 */
     130/*ARGSUSED*/
     131static int
     132AsSwitch(
     133    ClientData clientData,      /* Not used. */
     134    Tcl_Interp *interp,         /* Interpreter to send results back to */
     135    const char *switchName,     /* Not used. */
     136    Tcl_Obj *objPtr,            /* String representation */
     137    char *record,               /* Structure record */
     138    int offset,                 /* Offset to field in structure */
     139    int flags)                  /* Not used. */
     140{
     141    int *flagsPtr = (int *)(record + offset);
     142    char c;
     143    char *string;
     144
     145    string = Tcl_GetString(objPtr);
     146    c = string[0];
     147    if ((c == 'b') && (strcmp(string, "b64") == 0)) {
     148        *flagsPtr = RPENC_B64;
     149    } else if ((c == 'z') && (strcmp(string, "zb64") == 0)) {
     150        *flagsPtr = RPENC_Z  | RPENC_B64;
     151    } else if ((c == 'z') && (strcmp(string, "z") == 0)) {
     152        *flagsPtr = RPENC_Z;
     153    } else {
     154        Tcl_AppendResult(interp, "bad order \"", string,
     155                 "\": should be breadthfirst, inorder, preorder, or postorder",
     156                 (char *)NULL);
     157        return TCL_ERROR;
     158    }
     159    return TCL_OK;
     160}
     161
     162static SwitchParseProc AsSwitch;
     163static SwitchCustom asSwitch = {
     164    AsSwitch, NULL, 0,
     165};
     166
     167typedef struct {
     168    unsigned int flags;
     169    unsigned int noheader;
     170} EncodeSwitches;
     171
     172static SwitchSpec encodeSwitches[] =
     173{
     174    {SWITCH_CUSTOM, "-as", "z|b64|zb64",
     175        offsetof(EncodeSwitches, flags), 0, 0, &asSwitch},
     176    {SWITCH_VALUE, "-no-header", "",
     177        offsetof(EncodeSwitches, noheader), 0, true},
     178    {SWITCH_END}
     179};
     180
    115181static int
    116182RpTclEncodingEncode (ClientData cdata, Tcl_Interp *interp, int objc,
    117183                     Tcl_Obj *const *objv)
    118184{
    119     const char* encodeType    = NULL; // name of the units provided by user
    120     const char* cmdName       = NULL;
    121     Rappture::Outcome err;
    122 
    123     int nextarg               = 0; // start parsing using the '2'th argument
    124 
    125     bool addHeader;
    126     int flags;
    127     addHeader = true;
    128 
    129     Tcl_Obj *result           = NULL;
    130 
    131     Tcl_ResetResult(interp);
    132 
    133     cmdName = Tcl_GetString(objv[nextarg++]);
    134 
    135     // parse through command line options
    136185    if (objc < 1) {
    137         Tcl_AppendResult(interp,
    138                 "wrong # args: should be \"", cmdName,
    139                 " ?-as z|b64|zb64? ?-no-header? ?--? <string>\"", (char*)NULL);
    140         return TCL_ERROR;
    141     }
    142     flags = 0;
    143     while ((objc - nextarg) > 0) {
    144         const char *option;
    145 
    146         option = Tcl_GetString(objv[nextarg]);
    147         if (*option == '-') {
    148             if (strcmp(option,"-as") == 0) {
    149                 nextarg++;
    150                 encodeType = NULL;
    151                 if (nextarg < objc) {
    152                     encodeType = Tcl_GetString(objv[nextarg]);
    153                     nextarg++;
    154                 }
    155                 if (strcmp(encodeType, "z") == 0) {
    156                     flags = RPENC_Z;
    157                 } else if (strcmp(encodeType, "b64") == 0) {
    158                     flags = RPENC_B64;
    159                 } else if (strcmp(encodeType, "zb64") == 0) {
    160                     flags = RPENC_B64 | RPENC_Z;
    161                 } else {
    162                     // user did not specify recognized wishes for this option,
    163                     Tcl_AppendResult(interp, "bad value \"",(char*)NULL);
    164                     if (encodeType != NULL) {
    165                         Tcl_AppendResult(interp, encodeType,(char*)NULL);
    166                     }
    167                     Tcl_AppendResult(interp,
    168                             "\": should be one of z, b64, zb64",
    169                             (char*)NULL);
    170                     return TCL_ERROR;
    171                 }
    172             } else if (strcmp(option,"-no-header") == 0) {
    173                 nextarg++;
    174                 addHeader = false;
    175             } else if (strcmp(option,"--") == 0) {
    176                 nextarg++;
    177                 break;
    178             } else {
    179                 Tcl_AppendResult(interp,
    180                     "bad option \"", option,
    181                     "\": should be -as, -no-header, --", (char*)NULL);
    182                 return TCL_ERROR;
    183             }
    184         } else {
    185             break;
    186         }
    187     }
    188 
    189     if ((objc - nextarg) != 1) {
    190         Tcl_AppendResult(interp,
    191                 "wrong # args: should be \"", cmdName,
    192                 " ?-as z|b64|zb64? ?-no-header? ?--? <string>\"", (char*)NULL);
    193         return TCL_ERROR;
    194     }
    195 
     186        Tcl_AppendResult(interp, "wrong # args: should be \"",
     187                Tcl_GetString(objv[0]),
     188                " ?-as z|b64|zb64? ?-no-header? ?--? string\"", (char*)NULL);
     189        return TCL_ERROR;
     190    }
     191    EncodeSwitches switches;
     192    switches.flags = 0;
     193    switches.noheader = 0;
     194    int n;
     195    n = Rp_ParseSwitches(interp, encodeSwitches, objc - 1, objv + 1, &switches,
     196                         SWITCH_OBJV_PARTIAL);
     197    if (n < 0) {
     198        return TCL_ERROR;
     199    }
     200    int last;
     201    last = n + 1;
     202    if ((objc - last) != 1) {
     203        Tcl_AppendResult(interp, "wrong # args: should be \"",
     204                Tcl_GetString(objv[0]),
     205                " ?-as z|b64|zb64? ?-no-header? ?--? string\"", (char*)NULL);
     206        return TCL_ERROR;
     207    }
    196208    int nBytes;
    197209    const char* string;
    198     string = (const char*)Tcl_GetByteArrayFromObj(objv[nextarg++], &nBytes);
     210    string = (const char*)Tcl_GetByteArrayFromObj(objv[last], &nBytes);
    199211    if (nBytes <= 0) {
    200212        return TCL_OK;          // Nothing to encode.
    201213    }
    202214    Rappture::Buffer buf(string, nBytes);
    203     if (addHeader) {
    204         flags |= RPENC_HDR;
    205     }
    206     if (!Rappture::encoding::encode(err, buf, flags)) {
    207         Tcl_AppendResult(interp, err.remark(), "\n", err.context(), NULL);
    208         return TCL_ERROR;
    209     }
    210     result = Tcl_NewByteArrayObj((const unsigned char*)buf.bytes(), buf.size());
    211     Tcl_SetObjResult(interp, result);
     215    if (!switches.noheader) {
     216        switches.flags |= RPENC_HDR;
     217    }
     218    Rappture::Outcome status;
     219    if (!Rappture::encoding::encode(status, buf, switches.flags)) {
     220        Tcl_AppendResult(interp, status.remark(), "\n", status.context(), NULL);
     221        return TCL_ERROR;
     222    }
     223    Tcl_SetByteArrayObj(Tcl_GetObjResult(interp),
     224                (const unsigned char*)buf.bytes(), buf.size());
    212225    return TCL_OK;
    213226}
     
    225238 */
    226239
    227 static int
    228 RpTclEncodingDecode (   ClientData cdata,
    229                         Tcl_Interp *interp,
    230                         int objc,
    231                         Tcl_Obj *const objv[]  )
    232 {
    233 
    234     const char* encodeType    = NULL; // name of the units provided by user
    235     const char* cmdName       = NULL;
    236     Rappture::Outcome err;
    237 
    238     int nextarg               = 0; // start parsing using the '2'th argument
    239     int flags;
    240 
    241     cmdName = Tcl_GetString(objv[nextarg++]);
    242 
    243     // parse through command line options
     240typedef struct {
     241    unsigned int flags;
     242} DecodeSwitches;
     243
     244static SwitchSpec decodeSwitches[] =
     245{
     246    {SWITCH_CUSTOM, "-as", "z|b64|zb64",
     247        offsetof(DecodeSwitches, flags), 0, 0, &asSwitch},
     248    {SWITCH_END}
     249};
     250
     251static int
     252RpTclEncodingDecode(ClientData clientData, Tcl_Interp *interp, int objc,
     253                    Tcl_Obj *const *objv)
     254{
    244255    if (objc < 1) {
    245         Tcl_AppendResult(interp,
    246                 "wrong # args: should be \"", cmdName,
     256        Tcl_AppendResult(interp, "wrong # args: should be \"",
     257                Tcl_GetString(objv[0]),
    247258                " ?-as z|b64|zb64? ?--? <string>\"", (char*)NULL);
    248259        return TCL_ERROR;
    249260    }
    250261
    251     flags = 0;
    252     while ((objc - nextarg) > 0) {
    253         const char *option;
    254 
    255         option = Tcl_GetString(objv[nextarg]);
    256         if (*option == '-') {
    257             if (strcmp(option,"-as") == 0) {
    258                 nextarg++;
    259                 encodeType = NULL;
    260                 if (nextarg < objc) {
    261                     encodeType = Tcl_GetString(objv[nextarg]);
    262                     nextarg++;
    263                 }
    264                 if (strcmp(encodeType,"z") == 0) {
    265                     flags = RPENC_Z;
    266                 } else if (strcmp(encodeType, "b64") == 0) {
    267                     flags = RPENC_B64;
    268                 } else if (strcmp(encodeType,"zb64") == 0) {
    269                     flags = RPENC_Z | RPENC_B64;
    270                 } else {
    271                     // user did not specify recognized wishes for this option,
    272                     Tcl_AppendResult(interp, "bad value \"",(char*)NULL);
    273                     if (encodeType != NULL) {
    274                         Tcl_AppendResult(interp, encodeType,(char*)NULL);
    275                     }
    276                     Tcl_AppendResult(interp,
    277                             "\": should be one of z, b64, zb64",
    278                             (char*)NULL);
    279                     return TCL_ERROR;
    280                 }
    281             } else if (strcmp(option,"--") == 0) {
    282                 nextarg++;
    283                 break;
    284             } else {
    285                 Tcl_AppendResult(interp,
    286                     "bad option \"", option,
    287                     "\": should be -as, --", (char*)NULL);
    288                 return TCL_ERROR;
    289             }
    290         } else {
    291             break;
    292         }
    293     }
    294 
    295     if ((objc - nextarg) != 1) {
    296         Tcl_AppendResult(interp,
    297                 "wrong # args: should be \"", cmdName,
    298                 " ?-as z|b64|zb64? ?--? <string>\"", (char*)NULL);
    299         return TCL_ERROR;
    300     }
    301 
     262    DecodeSwitches switches;
     263    switches.flags = 0;
     264    int n;
     265    n = Rp_ParseSwitches(interp, decodeSwitches, objc - 1, objv + 1, &switches,
     266                         SWITCH_OBJV_PARTIAL);
     267    if (n < 0) {
     268        return TCL_ERROR;
     269    }
     270    int last;
     271    last = n + 1;
     272    if ((objc - last) != 1) {
     273        Tcl_AppendResult(interp, "wrong # args: should be \"",
     274                Tcl_GetString(objv[0]),
     275                " ?-as z|b64|zb64? ?--? string\"", (char*)NULL);
     276        return TCL_ERROR;
     277    }
    302278    int nBytes;
    303279    const char* string;
    304     string = (const char*)Tcl_GetByteArrayFromObj(objv[nextarg++], &nBytes);
    305 
     280    string = (const char*)Tcl_GetByteArrayFromObj(objv[last], &nBytes);
     281    if (nBytes <= 0) {
     282        return TCL_OK;          // Nothing to decode.
     283    }
    306284    Rappture::Buffer buf(string, nBytes);
    307     if (!Rappture::encoding::decode(err, buf, flags)) {
    308         Tcl_AppendResult(interp, err.remark(), "\n", err.context(), NULL);
    309         return TCL_ERROR;
    310     }
    311     Tcl_Obj *objPtr;
    312     objPtr = Tcl_NewByteArrayObj((const unsigned char*)buf.bytes(), buf.size());
    313     Tcl_SetObjResult(interp, objPtr);
    314     return TCL_OK;
    315 }
     285    Rappture::Outcome status;
     286    if (!Rappture::encoding::decode(status, buf, switches.flags)) {
     287        Tcl_AppendResult(interp, status.remark(), "\n", status.context(), NULL);
     288        return TCL_ERROR;
     289    }
     290    Tcl_SetByteArrayObj(Tcl_GetObjResult(interp),
     291                (const unsigned char*)buf.bytes(), buf.size());
     292    return TCL_OK;
     293}
Note: See TracChangeset for help on using the changeset viewer.