1865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata/* 2865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata * This file is part of ltrace. 3865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. 4865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata * 5865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata * This program is free software; you can redistribute it and/or 6865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata * modify it under the terms of the GNU General Public License as 7865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata * published by the Free Software Foundation; either version 2 of the 8865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata * License, or (at your option) any later version. 9865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata * 10865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata * This program is distributed in the hope that it will be useful, but 11865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata * WITHOUT ANY WARRANTY; without even the implied warranty of 12865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata * General Public License for more details. 14865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata * 15865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata * You should have received a copy of the GNU General Public License 16865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata * along with this program; if not, write to the Free Software 17865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 18865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata * 02110-1301 USA 19865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata */ 20865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata 21865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata#include <assert.h> 22865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata#include <stdlib.h> 23865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata 24865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata#include "param.h" 25865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata#include "type.h" 26865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata#include "value.h" 27865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata#include "expr.h" 28865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata 29865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machatavoid 30865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machataparam_init_type(struct param *param, struct arg_type_info *type, int own) 31865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata{ 32865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata param->flavor = PARAM_FLAVOR_TYPE; 33865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata param->u.type.type = type; 34865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata param->u.type.own_type = own; 35865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata} 36865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata 37865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machatavoid 38865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machataparam_init_stop(struct param *param) 39865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata{ 40865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata param->flavor = PARAM_FLAVOR_STOP; 41865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata} 42865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata 43865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machatavoid 44e36298a706b96bfdf9335fbe8288827761d77957Petr Machataparam_init_pack(struct param *param, enum param_pack_flavor ppflavor, 45865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata struct expr_node *args, size_t nargs, int own_args, 46865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata struct param_enum *(*init)(struct value *cb_args, 47865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata size_t nargs, 48865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata struct value_dict *arguments), 49865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata int (*next)(struct param_enum *context, 50865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata struct arg_type_info *infop, 51865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata int *insert_stop), 52865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata enum param_status (*stop)(struct param_enum *ctx, 53865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata struct value *value), 54865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata void (*done)(struct param_enum *)) 55865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata{ 56865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata param->flavor = PARAM_FLAVOR_PACK; 57865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata param->u.pack.args = args; 58865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata param->u.pack.nargs = nargs; 59865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata param->u.pack.own_args = own_args; 60e36298a706b96bfdf9335fbe8288827761d77957Petr Machata param->u.pack.ppflavor = ppflavor; 61865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata param->u.pack.init = init; 62865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata param->u.pack.next = next; 63865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata param->u.pack.stop = stop; 64865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata param->u.pack.done = done; 65865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata} 66865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata 67865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machatastruct param_enum * 68865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machataparam_pack_init(struct param *param, struct value_dict *fargs) 69865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata{ 70865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata struct value cb_args[param->u.pack.nargs]; 71865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata size_t i; 72865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata 73865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata /* For evaluation of argument expressions, we pass in this as 74865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata * a "current" value. */ 75865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata struct arg_type_info *void_type = type_get_simple(ARGTYPE_VOID); 76865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata struct value void_val; 77865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata value_init_detached(&void_val, NULL, void_type, 0); 78865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata 79865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata struct param_enum *ret = NULL; 80865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata for (i = 0; i < param->u.pack.nargs; ++i) { 81865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata if (expr_eval(¶m->u.pack.args[i], &void_val, 82865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata fargs, &cb_args[i]) < 0) 83865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata goto release; 84865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata } 85865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata 86865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata ret = param->u.pack.init(cb_args, param->u.pack.nargs, fargs); 87865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata 88865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machatarelease: 89865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata while (i-- > 0) 90865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata value_destroy(&cb_args[i]); 91865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata return ret; 92865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata} 93865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata 94865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machataint 95865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machataparam_pack_next(struct param *param, struct param_enum *context, 96865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata struct arg_type_info *infop, int *insert_stop) 97865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata{ 98865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata return param->u.pack.next(context, infop, insert_stop); 99865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata} 100865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata 101865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machataenum param_status 102865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machataparam_pack_stop(struct param *param, 103865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata struct param_enum *context, struct value *value) 104865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata{ 105865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata return param->u.pack.stop(context, value); 106865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata} 107865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata 108865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machatavoid 109865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machataparam_pack_done(struct param *param, struct param_enum *context) 110865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata{ 111865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata return param->u.pack.done(context); 112865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata} 113865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata 114865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machatavoid 115865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machataparam_destroy(struct param *param) 116865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata{ 117865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata if (param == NULL) 118865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata return; 119865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata 120865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata switch (param->flavor) { 121865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata case PARAM_FLAVOR_TYPE: 122865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata if (param->u.type.own_type) { 123865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata type_destroy(param->u.type.type); 124865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata free(param->u.type.type); 125865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata } 126865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata return; 127865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata 128865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata case PARAM_FLAVOR_PACK: 129865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata if (param->u.pack.own_args) { 130865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata size_t i; 131865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata for (i = 0; i < param->u.pack.nargs; ++i) 132865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata expr_destroy(¶m->u.pack.args[i]); 133865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata free(param->u.pack.args); 134865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata } 1356e570e5bf8e0a9049cb1bad3ca4f82fae116c741Petr Machata return; 1366e570e5bf8e0a9049cb1bad3ca4f82fae116c741Petr Machata 137865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata case PARAM_FLAVOR_STOP: 138865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata return; 139865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata } 140865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata 141865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata assert(!"Unknown value of param flavor!"); 142865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata abort(); 143865303f5abd934aff8e054ff8d8117e9cd36dda3Petr Machata} 144