/* * vim:tw=80:expandtab * * Copyright (c) 2014 The MacPorts Project * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if HAVE_CONFIG_H #include #endif #include #include #include #include #include "portgroupobj.h" #include "registry.h" #include "util.h" const char* portgroup_props[] = { "name", "version", "size", "sha256", NULL }; /* ${portgroup} prop ?value? */ static int portgroup_obj_prop(Tcl_Interp* interp, reg_portgroup* portgroup, int objc, Tcl_Obj* const objv[]) { int index; if (objc > 3) { Tcl_WrongNumArgs(interp, 2, objv, "?value?"); return TCL_ERROR; } if (objc == 2) { /* ${portgroup} prop; return the current value */ reg_registry* reg = registry_for(interp, reg_attached); if (reg == NULL) { return TCL_ERROR; } if (Tcl_GetIndexFromObj(interp, objv[1], portgroup_props, "prop", 0, &index) == TCL_OK) { char* key = Tcl_GetString(objv[1]); char* value; reg_error error; if (reg_portgroup_propget(portgroup, key, &value, &error)) { Tcl_Obj* result = Tcl_NewStringObj(value, -1); Tcl_SetObjResult(interp, result); free(value); return TCL_OK; } return registry_failed(interp, &error); } return TCL_ERROR; } else { /* ${portgroup} prop name value; set a new value */ reg_registry* reg = registry_for(interp, reg_attached); if (reg == NULL) { return TCL_ERROR; } if (Tcl_GetIndexFromObj(interp, objv[1], portgroup_props, "prop", 0, &index) == TCL_OK) { char* key = Tcl_GetString(objv[1]); char* value = Tcl_GetString(objv[2]); reg_error error; if (reg_portgroup_propset(portgroup, key, value, &error)) { return TCL_OK; } return registry_failed(interp, &error); } return TCL_ERROR; } } typedef struct { char* name; int (*function)(Tcl_Interp* interp, reg_portgroup* portgroup, int objc, Tcl_Obj* const objv[]); } portgroup_obj_cmd_type; static portgroup_obj_cmd_type portgroup_cmds[] = { /* keys */ { "name", portgroup_obj_prop }, { "version", portgroup_obj_prop }, { "size", portgroup_obj_prop }, { "sha256", portgroup_obj_prop }, { NULL, NULL } }; /* ${portgroup} cmd ?arg ...? */ /* This function implements the command that will be called when a portgroup * created by `registry::portgroup` is used as a procedure. Since all data is kept * in a temporary sqlite3 database that is created for the current interpreter, * none of the sqlite3 functions used have any error checking. That should be a * safe assumption, since nothing outside of registry:: should ever have the * chance to touch it. */ int portgroup_obj_cmd(ClientData clientData, Tcl_Interp* interp, int objc, Tcl_Obj* const objv[]) { int cmd_index; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "cmd ?arg ...?"); return TCL_ERROR; } if (Tcl_GetIndexFromObjStruct(interp, objv[1], portgroup_cmds, sizeof(portgroup_obj_cmd_type), "cmd", 0, &cmd_index) == TCL_OK) { portgroup_obj_cmd_type* cmd = &portgroup_cmds[cmd_index]; return cmd->function(interp, (reg_portgroup*)clientData, objc, objv); } return TCL_ERROR; }