1ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata/* 2ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata * This file is part of ltrace. 3e56fe644f725f2c1c8308e7c2b5f9cd02e89eed0Petr Machata * Copyright (C) 2012,2013 Petr Machata, Red Hat Inc. 4ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata * 5ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata * This program is free software; you can redistribute it and/or 6ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata * modify it under the terms of the GNU General Public License as 7ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata * published by the Free Software Foundation; either version 2 of the 8ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata * License, or (at your option) any later version. 9ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata * 10ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata * This program is distributed in the hope that it will be useful, but 11ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata * WITHOUT ANY WARRANTY; without even the implied warranty of 12ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata * General Public License for more details. 14ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata * 15ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata * You should have received a copy of the GNU General Public License 16ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata * along with this program; if not, write to the Free Software 17ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 18ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata * 02110-1301 USA 19ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata */ 20ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 2182ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata#include <alloca.h> 22f7650d1e1c09e360a0cd27ee99b051cc9b127091Petr Machata#include <errno.h> 23ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata#include <stdlib.h> 24ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata#include <string.h> 2582ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata#include <stdio.h> 26ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 27b1ab2aefa199ea8e14e29bac78ae71030c2d4863Petr Machata#include "common.h" 28ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata#include "callback.h" 29ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata#include "param.h" 30f7650d1e1c09e360a0cd27ee99b051cc9b127091Petr Machata#include "prototype.h" 31ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata#include "type.h" 3282ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata#include "options.h" 3382ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata#include "read_config_file.h" 3482ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata#include "backend.h" 35ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 3608cdf328add7b723b94b151866e5d0173662f6c6Petr Machatastruct protolib_cache g_protocache; 3708cdf328add7b723b94b151866e5d0173662f6c6Petr Machatastatic struct protolib legacy_typedefs; 38ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 39ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machatavoid 40ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machataprototype_init(struct prototype *proto) 41ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata{ 42ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata VECT_INIT(&proto->params, struct param); 43ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 44ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata proto->return_info = NULL; 45ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata proto->own_return_info = 0; 46ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata} 47ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 48ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machatastatic void 49ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machataparam_destroy_cb(struct param *param, void *data) 50ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata{ 51ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata param_destroy(param); 52ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata} 53ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 54ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machatavoid 55ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machataprototype_destroy(struct prototype *proto) 56ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata{ 57ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata if (proto == NULL) 58ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata return; 59ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata if (proto->own_return_info) { 60ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata type_destroy(proto->return_info); 61ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata free(proto->return_info); 62ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata } 63ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 64ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata VECT_DESTROY(&proto->params, struct param, ¶m_destroy_cb, NULL); 65ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata} 66ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 67ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machataint 68ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machataprototype_push_param(struct prototype *proto, struct param *param) 69ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata{ 70ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata return VECT_PUSHBACK(&proto->params, param); 71ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata} 72ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 73ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machatasize_t 74ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machataprototype_num_params(struct prototype *proto) 75ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata{ 76ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata return vect_size(&proto->params); 77ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata} 78ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 79ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machatavoid 80ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machataprototype_destroy_nth_param(struct prototype *proto, size_t n) 81ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata{ 82ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata assert(n < prototype_num_params(proto)); 83ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata VECT_ERASE(&proto->params, struct param, n, n+1, 84ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata ¶m_destroy_cb, NULL); 85ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata} 86ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 87ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machatastruct param * 88ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machataprototype_get_nth_param(struct prototype *proto, size_t n) 89ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata{ 90ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata assert(n < prototype_num_params(proto)); 91ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata return VECT_ELEMENT(&proto->params, struct param, n); 92ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata} 93ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 94ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machatastruct each_param_data { 95ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata struct prototype *proto; 96ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata enum callback_status (*cb)(struct prototype *, struct param *, void *); 97ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata void *data; 98ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata}; 99ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 100ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machatastatic enum callback_status 101ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machataeach_param_cb(struct param *param, void *data) 102ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata{ 103ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata struct each_param_data *cb_data = data; 104ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata return (cb_data->cb)(cb_data->proto, param, cb_data->data); 105ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata} 106ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 107ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machatastruct param * 108ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machataprototype_each_param(struct prototype *proto, struct param *start_after, 109ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata enum callback_status (*cb)(struct prototype *, 110ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata struct param *, void *), 111ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata void *data) 112ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata{ 113ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata struct each_param_data cb_data = { proto, cb, data }; 114ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata return VECT_EACH(&proto->params, struct param, start_after, 115ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata &each_param_cb, &cb_data); 116ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata} 117ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 118ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machatavoid 1193ac9b91974678878889776221c390f39f5c2ffcfPetr Machatanamed_type_init(struct named_type *named, 1203ac9b91974678878889776221c390f39f5c2ffcfPetr Machata struct arg_type_info *info, int own_type) 1213ac9b91974678878889776221c390f39f5c2ffcfPetr Machata{ 1223ac9b91974678878889776221c390f39f5c2ffcfPetr Machata named->info = info; 1233ac9b91974678878889776221c390f39f5c2ffcfPetr Machata named->own_type = own_type; 1243ac9b91974678878889776221c390f39f5c2ffcfPetr Machata named->forward = 0; 1253ac9b91974678878889776221c390f39f5c2ffcfPetr Machata} 1263ac9b91974678878889776221c390f39f5c2ffcfPetr Machata 1273ac9b91974678878889776221c390f39f5c2ffcfPetr Machatavoid 128ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machatanamed_type_destroy(struct named_type *named) 129ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata{ 1303ac9b91974678878889776221c390f39f5c2ffcfPetr Machata if (named->own_type) { 131ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata type_destroy(named->info); 132ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata free(named->info); 133ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata } 134ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata} 135ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 136f7650d1e1c09e360a0cd27ee99b051cc9b127091Petr Machatavoid 137ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machataprotolib_init(struct protolib *plib) 138ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata{ 13997485501f87e5452bc49721003ebfb9717f497b6Peter Wu DICT_INIT(&plib->prototypes, char *, struct prototype, 140f7650d1e1c09e360a0cd27ee99b051cc9b127091Petr Machata dict_hash_string, dict_eq_string, NULL); 141ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 14297485501f87e5452bc49721003ebfb9717f497b6Peter Wu DICT_INIT(&plib->named_types, char *, struct named_type, 143f7650d1e1c09e360a0cd27ee99b051cc9b127091Petr Machata dict_hash_string, dict_eq_string, NULL); 144ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 145ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata VECT_INIT(&plib->imports, struct protolib *); 1467f1d856ea4882a23461886d0f589244cc11f0b2fPetr Machata 1477f1d856ea4882a23461886d0f589244cc11f0b2fPetr Machata plib->refs = 0; 148ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata} 149ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 150ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machatastatic void 151f7650d1e1c09e360a0cd27ee99b051cc9b127091Petr Machatadestroy_prototype_cb(struct prototype *proto, void *data) 152ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata{ 153ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata prototype_destroy(proto); 154ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata} 155ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 156ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machatastatic void 157f7650d1e1c09e360a0cd27ee99b051cc9b127091Petr Machatadestroy_named_type_cb(struct named_type *named, void *data) 158ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata{ 159ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata named_type_destroy(named); 160ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata} 161ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 162ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machatavoid 163ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machataprotolib_destroy(struct protolib *plib) 164ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata{ 1657f1d856ea4882a23461886d0f589244cc11f0b2fPetr Machata assert(plib->refs == 0); 1667f1d856ea4882a23461886d0f589244cc11f0b2fPetr Machata 167ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata VECT_DESTROY(&plib->imports, struct prototype *, NULL, NULL); 168ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 169f7650d1e1c09e360a0cd27ee99b051cc9b127091Petr Machata DICT_DESTROY(&plib->prototypes, const char *, struct prototype, 170f7650d1e1c09e360a0cd27ee99b051cc9b127091Petr Machata dict_dtor_string, destroy_prototype_cb, NULL); 171ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 172f7650d1e1c09e360a0cd27ee99b051cc9b127091Petr Machata DICT_DESTROY(&plib->named_types, const char *, struct named_type, 173f7650d1e1c09e360a0cd27ee99b051cc9b127091Petr Machata dict_dtor_string, destroy_named_type_cb, NULL); 174ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata} 175ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 176ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machatastatic struct protolib ** 177ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machataeach_import(struct protolib *plib, struct protolib **start_after, 178ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata enum callback_status (*cb)(struct protolib **, void *), void *data) 179ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata{ 18082ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata assert(plib != NULL); 181ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata return VECT_EACH(&plib->imports, struct protolib *, 182ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata start_after, cb, data); 183ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata} 184ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 185ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machatastatic enum callback_status 186ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machatais_or_imports(struct protolib **plibp, void *data) 187ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata{ 18882ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata assert(plibp != NULL); 18982ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata assert(*plibp != NULL); 190ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata struct protolib *import = data; 191ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata if (*plibp == import 192ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata || each_import(*plibp, NULL, &is_or_imports, import) != NULL) 193ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata return CBS_STOP; 194ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata else 195ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata return CBS_CONT; 196ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata} 197ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 198ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machataint 199ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machataprotolib_add_import(struct protolib *plib, struct protolib *import) 200ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata{ 20182ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata assert(plib != NULL); 20282ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata assert(import != NULL); 20382ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata if (is_or_imports(&import, plib) == CBS_STOP) { 20482ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata fprintf(stderr, "Recursive import rejected.\n"); 205ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata return -2; 20682ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata } 207ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 20882ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata return VECT_PUSHBACK(&plib->imports, &import) < 0 ? -1 : 0; 209ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata} 210ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 211ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machatastatic int 212f7650d1e1c09e360a0cd27ee99b051cc9b127091Petr Machatabailout(const char *name, int own) 213f7650d1e1c09e360a0cd27ee99b051cc9b127091Petr Machata{ 214f7650d1e1c09e360a0cd27ee99b051cc9b127091Petr Machata int save_errno = errno; 215f7650d1e1c09e360a0cd27ee99b051cc9b127091Petr Machata if (own) 216f7650d1e1c09e360a0cd27ee99b051cc9b127091Petr Machata free((char *)name); 217f7650d1e1c09e360a0cd27ee99b051cc9b127091Petr Machata errno = save_errno; 218f7650d1e1c09e360a0cd27ee99b051cc9b127091Petr Machata return -1; 219f7650d1e1c09e360a0cd27ee99b051cc9b127091Petr Machata} 220f7650d1e1c09e360a0cd27ee99b051cc9b127091Petr Machata 221ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machataint 222ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machataprotolib_add_prototype(struct protolib *plib, const char *name, int own_name, 223ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata struct prototype *proto) 224ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata{ 22582ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata assert(plib != NULL); 226b1ab2aefa199ea8e14e29bac78ae71030c2d4863Petr Machata if (strdup_if(&name, name, !own_name) < 0) 227f7650d1e1c09e360a0cd27ee99b051cc9b127091Petr Machata return -1; 228f7650d1e1c09e360a0cd27ee99b051cc9b127091Petr Machata if (DICT_INSERT(&plib->prototypes, &name, proto) < 0) 229f7650d1e1c09e360a0cd27ee99b051cc9b127091Petr Machata return bailout(name, own_name); 230f7650d1e1c09e360a0cd27ee99b051cc9b127091Petr Machata return 0; 231ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata} 232ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 233ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machataint 234ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machataprotolib_add_named_type(struct protolib *plib, const char *name, int own_name, 235ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata struct named_type *named) 236ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata{ 23782ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata assert(plib != NULL); 238b1ab2aefa199ea8e14e29bac78ae71030c2d4863Petr Machata if (strdup_if(&name, name, !own_name) < 0) 239f7650d1e1c09e360a0cd27ee99b051cc9b127091Petr Machata return -1; 240f7650d1e1c09e360a0cd27ee99b051cc9b127091Petr Machata if (DICT_INSERT(&plib->named_types, &name, named) < 0) 241f7650d1e1c09e360a0cd27ee99b051cc9b127091Petr Machata return bailout(name, own_name); 242f7650d1e1c09e360a0cd27ee99b051cc9b127091Petr Machata return 0; 243ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata} 244ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 245ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machatastruct lookup { 246ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata const char *name; 2473ac9b91974678878889776221c390f39f5c2ffcfPetr Machata struct dict *(*getter)(struct protolib *plib); 24882f748d1bc2b95d594327ad15f3a6908070dd5c3Petr Machata bool imports; 24982f748d1bc2b95d594327ad15f3a6908070dd5c3Petr Machata void *result; 250ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata}; 251ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 2523ac9b91974678878889776221c390f39f5c2ffcfPetr Machatastatic struct dict * 2533ac9b91974678878889776221c390f39f5c2ffcfPetr Machataget_prototypes(struct protolib *plib) 2543ac9b91974678878889776221c390f39f5c2ffcfPetr Machata{ 25582ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata assert(plib != NULL); 256f7650d1e1c09e360a0cd27ee99b051cc9b127091Petr Machata return &plib->prototypes; 2573ac9b91974678878889776221c390f39f5c2ffcfPetr Machata} 2583ac9b91974678878889776221c390f39f5c2ffcfPetr Machata 2593ac9b91974678878889776221c390f39f5c2ffcfPetr Machatastatic struct dict * 2603ac9b91974678878889776221c390f39f5c2ffcfPetr Machataget_named_types(struct protolib *plib) 2613ac9b91974678878889776221c390f39f5c2ffcfPetr Machata{ 26282ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata assert(plib != NULL); 263f7650d1e1c09e360a0cd27ee99b051cc9b127091Petr Machata return &plib->named_types; 2643ac9b91974678878889776221c390f39f5c2ffcfPetr Machata} 2653ac9b91974678878889776221c390f39f5c2ffcfPetr Machata 266ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machatastatic enum callback_status 2673ac9b91974678878889776221c390f39f5c2ffcfPetr Machataprotolib_lookup_rec(struct protolib **plibp, void *data) 268ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata{ 26982ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata assert(plibp != NULL); 27082ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata assert(*plibp != NULL); 271ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata struct lookup *lookup = data; 2723ac9b91974678878889776221c390f39f5c2ffcfPetr Machata struct dict *dict = (*lookup->getter)(*plibp); 273ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 274f7650d1e1c09e360a0cd27ee99b051cc9b127091Petr Machata lookup->result = dict_find(dict, &lookup->name); 275ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata if (lookup->result != NULL) 276ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata return CBS_STOP; 277ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 27882f748d1bc2b95d594327ad15f3a6908070dd5c3Petr Machata if (lookup->imports && each_import(*plibp, NULL, &protolib_lookup_rec, 27982f748d1bc2b95d594327ad15f3a6908070dd5c3Petr Machata lookup) != NULL) { 280ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata assert(lookup->result != NULL); 281ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata return CBS_STOP; 282ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata } 283ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 284ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata return CBS_CONT; 285ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata} 286ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 2873ac9b91974678878889776221c390f39f5c2ffcfPetr Machatastatic void * 2883ac9b91974678878889776221c390f39f5c2ffcfPetr Machataprotolib_lookup(struct protolib *plib, const char *name, 28982f748d1bc2b95d594327ad15f3a6908070dd5c3Petr Machata struct dict *(*getter)(struct protolib *), 29082f748d1bc2b95d594327ad15f3a6908070dd5c3Petr Machata bool imports) 291ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata{ 29282ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata assert(plib != NULL); 29382f748d1bc2b95d594327ad15f3a6908070dd5c3Petr Machata struct lookup lookup = { name, getter, imports, NULL }; 2943ac9b91974678878889776221c390f39f5c2ffcfPetr Machata if (protolib_lookup_rec(&plib, &lookup) == CBS_STOP) 295ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata assert(lookup.result != NULL); 296ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata else 297ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata assert(lookup.result == NULL); 298ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata return lookup.result; 299ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata} 300ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machata 3013ac9b91974678878889776221c390f39f5c2ffcfPetr Machatastruct prototype * 30282f748d1bc2b95d594327ad15f3a6908070dd5c3Petr Machataprotolib_lookup_prototype(struct protolib *plib, const char *name, bool imports) 3033ac9b91974678878889776221c390f39f5c2ffcfPetr Machata{ 30482ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata assert(plib != NULL); 30582f748d1bc2b95d594327ad15f3a6908070dd5c3Petr Machata return protolib_lookup(plib, name, &get_prototypes, imports); 3063ac9b91974678878889776221c390f39f5c2ffcfPetr Machata} 3073ac9b91974678878889776221c390f39f5c2ffcfPetr Machata 308ebc56a70e20ca0b3fc49c0eb5fc83e56c5e1fa5bPetr Machatastruct named_type * 30982f748d1bc2b95d594327ad15f3a6908070dd5c3Petr Machataprotolib_lookup_type(struct protolib *plib, const char *name, bool imports) 3103ac9b91974678878889776221c390f39f5c2ffcfPetr Machata{ 31182ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata assert(plib != NULL); 31282f748d1bc2b95d594327ad15f3a6908070dd5c3Petr Machata return protolib_lookup(plib, name, &get_named_types, imports); 3133ac9b91974678878889776221c390f39f5c2ffcfPetr Machata} 31482ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 31582ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machatastatic void 31682ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machatadestroy_protolib_cb(struct protolib **plibp, void *data) 31782ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata{ 31882ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata assert(plibp != NULL); 3197f1d856ea4882a23461886d0f589244cc11f0b2fPetr Machata 320e56fe644f725f2c1c8308e7c2b5f9cd02e89eed0Petr Machata if (*plibp != NULL 321e56fe644f725f2c1c8308e7c2b5f9cd02e89eed0Petr Machata && --(*plibp)->refs == 0) { 3227f1d856ea4882a23461886d0f589244cc11f0b2fPetr Machata protolib_destroy(*plibp); 3237f1d856ea4882a23461886d0f589244cc11f0b2fPetr Machata free(*plibp); 3247f1d856ea4882a23461886d0f589244cc11f0b2fPetr Machata } 32582ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata} 32682ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 32782ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machatavoid 32882ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machataprotolib_cache_destroy(struct protolib_cache *cache) 32982ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata{ 33082ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata DICT_DESTROY(&cache->protolibs, const char *, struct protolib *, 33182ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata dict_dtor_string, destroy_protolib_cb, NULL); 33282ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata} 33382ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 33482ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machatastruct load_config_data { 33582ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata struct protolib_cache *self; 33682ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata const char *key; 33782ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata struct protolib *result; 33882ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata}; 33982ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 34082ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machatastatic struct protolib * 34182ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machataconsider_config_dir(struct protolib_cache *cache, 34282ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata const char *path, const char *key) 34382ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata{ 34482ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata size_t len = sizeof ".conf"; 34582ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata char *buf = alloca(strlen(path) + 1 + strlen(key) + len); 346b5c837f545342b6017fe6ec7aa60c1fc866fde06Petr Machata sprintf(buf, "%s/%s.conf", path, key); 34782ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 348a5e983bd5555c496a209f3e3a48e2826940b09f5Petr Machata return protolib_cache_file(cache, buf, 0); 34982ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata} 35082ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 35182ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machatastatic enum callback_status 35282ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machataconsider_confdir_cb(struct opt_F_t *entry, void *d) 35382ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata{ 35482ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata if (opt_F_get_kind(entry) != OPT_F_DIR) 35582ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata return CBS_CONT; 35682ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata struct load_config_data *data = d; 35782ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 35882ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata data->result = consider_config_dir(data->self, 35982ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata entry->pathname, data->key); 36082ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata return data->result != NULL ? CBS_STOP : CBS_CONT; 36182ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata} 36282ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 36382ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machatastatic int 36482ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machataload_dash_F_dirs(struct protolib_cache *cache, 36582ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata const char *key, struct protolib **retp) 36682ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata{ 36782ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata struct load_config_data data = {cache, key}; 36882ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 36982ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata if (VECT_EACH(&opt_F, struct opt_F_t, NULL, 37082ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata consider_confdir_cb, &data) == NULL) 37182ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata /* Not found. That's fine. */ 37282ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata return 0; 37382ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 37482ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata if (data.result == NULL) 37582ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata /* There were errors. */ 37682ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata return -1; 37782ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 37882ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata *retp = data.result; 37982ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata return 0; 38082ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata} 38182ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 38282ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machatastatic int 38382ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machataload_config(struct protolib_cache *cache, 38482ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata const char *key, int private, struct protolib **retp) 38582ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata{ 38682ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata const char **dirs = NULL; 38782ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata if (os_get_config_dirs(private, &dirs) < 0 38882ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata || dirs == NULL) 38982ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata return -1; 39082ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 39182ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata for (; *dirs != NULL; ++dirs) { 39282ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata struct protolib *plib = consider_config_dir(cache, *dirs, key); 39382ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata if (plib != NULL) { 39482ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata *retp = plib; 39582ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata break; 39682ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata } 39782ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata } 39882ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 39982ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata return 0; 40082ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata} 40182ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 402aa3db6b1234da0e542ba7782849cf200d0d91c1cPetr Machatastatic enum callback_status 403aa3db6b1234da0e542ba7782849cf200d0d91c1cPetr Machataimport_legacy_file(char **fnp, void *data) 404aa3db6b1234da0e542ba7782849cf200d0d91c1cPetr Machata{ 405aa3db6b1234da0e542ba7782849cf200d0d91c1cPetr Machata struct protolib_cache *cache = data; 406aa3db6b1234da0e542ba7782849cf200d0d91c1cPetr Machata struct protolib *plib = protolib_cache_file(cache, *fnp, 1); 407aa3db6b1234da0e542ba7782849cf200d0d91c1cPetr Machata if (plib != NULL) { 408aa3db6b1234da0e542ba7782849cf200d0d91c1cPetr Machata /* The cache now owns the file name. */ 409aa3db6b1234da0e542ba7782849cf200d0d91c1cPetr Machata *fnp = NULL; 410aa3db6b1234da0e542ba7782849cf200d0d91c1cPetr Machata if (protolib_add_import(&cache->imports, plib) < 0) 411aa3db6b1234da0e542ba7782849cf200d0d91c1cPetr Machata return CBS_STOP; 412aa3db6b1234da0e542ba7782849cf200d0d91c1cPetr Machata } 413aa3db6b1234da0e542ba7782849cf200d0d91c1cPetr Machata 414aa3db6b1234da0e542ba7782849cf200d0d91c1cPetr Machata return CBS_CONT; 415aa3db6b1234da0e542ba7782849cf200d0d91c1cPetr Machata} 416aa3db6b1234da0e542ba7782849cf200d0d91c1cPetr Machata 4174c4e4012db96aee7ef236c0684690842fb6a3e47Petr Machatastatic int 4184c4e4012db96aee7ef236c0684690842fb6a3e47Petr Machataadd_ltrace_conf(struct protolib_cache *cache) 4194c4e4012db96aee7ef236c0684690842fb6a3e47Petr Machata{ 4204c4e4012db96aee7ef236c0684690842fb6a3e47Petr Machata /* Look into private config directories for .ltrace.conf and 4214c4e4012db96aee7ef236c0684690842fb6a3e47Petr Machata * into system config directories for ltrace.conf. If it's 4224c4e4012db96aee7ef236c0684690842fb6a3e47Petr Machata * found, add it to implicit import module. */ 423aa3db6b1234da0e542ba7782849cf200d0d91c1cPetr Machata struct vect legacy_files; 424aa3db6b1234da0e542ba7782849cf200d0d91c1cPetr Machata VECT_INIT(&legacy_files, char *); 425aa3db6b1234da0e542ba7782849cf200d0d91c1cPetr Machata if (os_get_ltrace_conf_filenames(&legacy_files) < 0) { 426aa3db6b1234da0e542ba7782849cf200d0d91c1cPetr Machata vect_destroy(&legacy_files, NULL, NULL); 4274c4e4012db96aee7ef236c0684690842fb6a3e47Petr Machata return -1; 428aa3db6b1234da0e542ba7782849cf200d0d91c1cPetr Machata } 4294c4e4012db96aee7ef236c0684690842fb6a3e47Petr Machata 430aa3db6b1234da0e542ba7782849cf200d0d91c1cPetr Machata int ret = VECT_EACH(&legacy_files, char *, NULL, 431aa3db6b1234da0e542ba7782849cf200d0d91c1cPetr Machata import_legacy_file, cache) == NULL ? 0 : -1; 432aa3db6b1234da0e542ba7782849cf200d0d91c1cPetr Machata VECT_DESTROY(&legacy_files, char *, vect_dtor_string, NULL); 433aa3db6b1234da0e542ba7782849cf200d0d91c1cPetr Machata return ret; 4344c4e4012db96aee7ef236c0684690842fb6a3e47Petr Machata} 4354c4e4012db96aee7ef236c0684690842fb6a3e47Petr Machata 43682ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machatastatic enum callback_status 43782ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machataadd_imports_cb(struct opt_F_t *entry, void *data) 43882ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata{ 43982ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata struct protolib_cache *self = data; 44082ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata if (opt_F_get_kind(entry) != OPT_F_FILE) 44182ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata return CBS_CONT; 44282ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 44382ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata struct protolib *new_import 444a5e983bd5555c496a209f3e3a48e2826940b09f5Petr Machata = protolib_cache_file(self, entry->pathname, 0); 44582ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 44682ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata if (new_import == NULL 44782ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata || protolib_add_import(&self->imports, new_import) < 0) 44882ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata /* N.B. If new_import is non-NULL, it has been already 44982ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata * cached. We don't therefore destroy it on 45082ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata * failures. */ 45182ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata return CBS_STOP; 45282ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 45382ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata return CBS_CONT; 45482ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata} 45582ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 45682ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machataint 45782ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machataprotolib_cache_init(struct protolib_cache *cache, struct protolib *import) 45882ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata{ 45997485501f87e5452bc49721003ebfb9717f497b6Peter Wu DICT_INIT(&cache->protolibs, char *, struct protolib *, 46082ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata dict_hash_string, dict_eq_string, NULL); 46182ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata protolib_init(&cache->imports); 46282ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 46382ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata /* At this point the cache is consistent. This is important, 46482ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata * because next we will use it to cache files that we load 46582ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata * due to -F. 46682ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata * 46782ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata * But we are about to construct the implicit import module, 46882ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata * which means this module can't be itself imported to the 46982ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata * files that we load now. So remember that we are still 47082ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata * bootstrapping. */ 47182ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata cache->bootstrap = 1; 47282ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 47382ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata if (protolib_add_import(&cache->imports, &legacy_typedefs) < 0 47482ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata || (import != NULL 47582ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata && protolib_add_import(&cache->imports, import) < 0) 4764c4e4012db96aee7ef236c0684690842fb6a3e47Petr Machata || add_ltrace_conf(cache) < 0 47782ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata || VECT_EACH(&opt_F, struct opt_F_t, NULL, 47882ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata add_imports_cb, cache) != NULL) { 47982ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata protolib_cache_destroy(cache); 48082ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata return -1; 48182ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata } 48282ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 48382ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata cache->bootstrap = 0; 48482ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata return 0; 48582ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata} 48682ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 48782ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machatastatic enum callback_status 48882ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machataadd_import_cb(struct protolib **importp, void *data) 48982ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata{ 49082ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata struct protolib *plib = data; 49182ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata if (protolib_add_import(plib, *importp) < 0) 49282ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata return CBS_STOP; 49382ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata else 49482ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata return CBS_CONT; 49582ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata} 49682ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 49782ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machatastatic struct protolib * 49882ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machatabuild_default_config(struct protolib_cache *cache, const char *key) 49982ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata{ 50082ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata struct protolib *new_plib = malloc(sizeof(*new_plib)); 50182ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata if (new_plib == NULL) { 50282ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata fprintf(stderr, "Couldn't create config module %s: %s\n", 50382ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata key, strerror(errno)); 50482ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata return NULL; 50582ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata } 50682ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 50782ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata protolib_init(new_plib); 50882ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 50982ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata /* If bootstrapping, copy over imports from implicit import 51082ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata * module to new_plib. We can't reference the implicit 51182ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata * import module itself, because new_plib will become part of 51282ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata * this same implicit import module itself. */ 51382ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata if ((cache->bootstrap && each_import(&cache->imports, NULL, 51482ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata add_import_cb, new_plib) != NULL) 51582ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata || (!cache->bootstrap 51682ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata && protolib_add_import(new_plib, &cache->imports) < 0)) { 51782ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 51882ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata fprintf(stderr, 51982ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata "Couldn't add imports to config module %s: %s\n", 52082ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata key, strerror(errno)); 52182ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata protolib_destroy(new_plib); 52282ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata free(new_plib); 52382ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata return NULL; 52482ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata } 52582ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 52682ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata return new_plib; 52782ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata} 52882ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 52982ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machatastatic void 53082ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machataattempt_to_cache(struct protolib_cache *cache, 53182ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata const char *key, struct protolib *plib) 53282ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata{ 533a5e983bd5555c496a209f3e3a48e2826940b09f5Petr Machata if (protolib_cache_protolib(cache, key, 1, plib) == 0 53482ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata || plib == NULL) 53582ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata /* Never mind failing to store a NULL. */ 53682ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata return; 53782ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 53882ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata /* Returning a protolib that hasn't been cached would leak 53982ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata * that protolib, but perhaps it's less bad then giving up 54082ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata * outright. At least print an error message. */ 54182ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata fprintf(stderr, "Couldn't cache prototype library for %s\n", key); 54298a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata free((void *) key); 54382ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata} 54482ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 54598a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machataint 54698a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machataprotolib_cache_maybe_load(struct protolib_cache *cache, 54798a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata const char *key, int own_key, bool allow_private, 54898a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata struct protolib **retp) 54982ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata{ 55098a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata if (DICT_FIND_VAL(&cache->protolibs, &key, retp) == 0) 55198a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata return 0; 55282ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 553b1ab2aefa199ea8e14e29bac78ae71030c2d4863Petr Machata if (strdup_if(&key, key, !own_key) < 0) { 554a5e983bd5555c496a209f3e3a48e2826940b09f5Petr Machata fprintf(stderr, "Couldn't cache %s: %s\n", 555a5e983bd5555c496a209f3e3a48e2826940b09f5Petr Machata key, strerror(errno)); 55698a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata return -1; 557a5e983bd5555c496a209f3e3a48e2826940b09f5Petr Machata } 558a5e983bd5555c496a209f3e3a48e2826940b09f5Petr Machata 55998a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata *retp = NULL; 56098a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata if (load_dash_F_dirs(cache, key, retp) < 0 56198a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata || (*retp == NULL && allow_private 56298a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata && load_config(cache, key, 1, retp) < 0) 56398a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata || (*retp == NULL 56498a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata && load_config(cache, key, 0, retp) < 0)) 56598a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata { 56682ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata fprintf(stderr, 56782ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata "Error occurred when attempting to load a prototype " 56882ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata "library for %s.\n", key); 569d2154eae286064c4114ec924186535961dfaad79Petr Machata if (!own_key) 570d2154eae286064c4114ec924186535961dfaad79Petr Machata free((void *) key); 57198a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata return -1; 57298a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata } 57382ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 57498a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata if (*retp != NULL) 57598a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata attempt_to_cache(cache, key, *retp); 57698a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata else if (!own_key) 57798a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata free((void *) key); 57898a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata 57998a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata return 0; 58098a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata} 58198a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata 58298a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machatastruct protolib * 58398a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machataprotolib_cache_load(struct protolib_cache *cache, 58498a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata const char *key, int own_key, bool allow_private) 58598a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata{ 58698a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata struct protolib *plib; 58798a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata if (protolib_cache_maybe_load(cache, key, own_key, 58898a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata allow_private, &plib) < 0) 58998a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata return NULL; 59098a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata 59198a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata if (plib == NULL) 59298a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata plib = protolib_cache_default(cache, key, own_key); 59398a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata 59498a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata return plib; 59598a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata} 59698a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata 59798a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machatastruct protolib * 59898a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machataprotolib_cache_default(struct protolib_cache *cache, 59998a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata const char *key, int own_key) 60098a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata{ 60198a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata if (strdup_if(&key, key, !own_key) < 0) { 60298a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata fprintf(stderr, "Couldn't cache default %s: %s\n", 60398a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata key, strerror(errno)); 60498a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata return NULL; 60598a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata } 60698a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata 60798a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata struct protolib *plib = build_default_config(cache, key); 60898a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata 60998a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata /* Whatever came out of this (even NULL), store it in 61098a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata * the cache. */ 61182ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata attempt_to_cache(cache, key, plib); 61298a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata 61382ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata return plib; 61482ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata} 61582ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 61682ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machatastruct protolib * 617a5e983bd5555c496a209f3e3a48e2826940b09f5Petr Machataprotolib_cache_file(struct protolib_cache *cache, 618a5e983bd5555c496a209f3e3a48e2826940b09f5Petr Machata const char *filename, int own_filename) 61982ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata{ 62082ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata { 62182ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata struct protolib *plib; 62282ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata if (DICT_FIND_VAL(&cache->protolibs, &filename, &plib) == 0) 62382ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata return plib; 62482ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata } 62582ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 62682ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata FILE *stream = fopen(filename, "r"); 62782ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata if (stream == NULL) 62882ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata return NULL; 62982ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 630b1ab2aefa199ea8e14e29bac78ae71030c2d4863Petr Machata if (strdup_if(&filename, filename, !own_filename) < 0) { 631a5e983bd5555c496a209f3e3a48e2826940b09f5Petr Machata fprintf(stderr, "Couldn't cache %s: %s\n", 632a5e983bd5555c496a209f3e3a48e2826940b09f5Petr Machata filename, strerror(errno)); 63382ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata fclose(stream); 63482ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata return NULL; 63582ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata } 63682ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 637a5e983bd5555c496a209f3e3a48e2826940b09f5Petr Machata struct protolib *new_plib = build_default_config(cache, filename); 638a5e983bd5555c496a209f3e3a48e2826940b09f5Petr Machata if (new_plib == NULL 639a5e983bd5555c496a209f3e3a48e2826940b09f5Petr Machata || read_config_file(stream, filename, new_plib) < 0) { 64082ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata fclose(stream); 641a5e983bd5555c496a209f3e3a48e2826940b09f5Petr Machata if (own_filename) 64298a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata free((char *) filename); 643a5e983bd5555c496a209f3e3a48e2826940b09f5Petr Machata if (new_plib != NULL) { 644a5e983bd5555c496a209f3e3a48e2826940b09f5Petr Machata protolib_destroy(new_plib); 645a5e983bd5555c496a209f3e3a48e2826940b09f5Petr Machata free(new_plib); 646a5e983bd5555c496a209f3e3a48e2826940b09f5Petr Machata } 64782ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata return NULL; 64882ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata } 64982ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 65082ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata attempt_to_cache(cache, filename, new_plib); 65182ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata fclose(stream); 65282ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata return new_plib; 65382ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata} 65482ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata 65582ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machataint 65682ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machataprotolib_cache_protolib(struct protolib_cache *cache, 657a5e983bd5555c496a209f3e3a48e2826940b09f5Petr Machata const char *filename, int own_filename, 658a5e983bd5555c496a209f3e3a48e2826940b09f5Petr Machata struct protolib *plib) 65982ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata{ 660b1ab2aefa199ea8e14e29bac78ae71030c2d4863Petr Machata if (strdup_if(&filename, filename, !own_filename) < 0) { 661a5e983bd5555c496a209f3e3a48e2826940b09f5Petr Machata fprintf(stderr, "Couldn't cache %s: %s\n", 662a5e983bd5555c496a209f3e3a48e2826940b09f5Petr Machata filename, strerror(errno)); 663a5e983bd5555c496a209f3e3a48e2826940b09f5Petr Machata return -1; 664a5e983bd5555c496a209f3e3a48e2826940b09f5Petr Machata } 665a5e983bd5555c496a209f3e3a48e2826940b09f5Petr Machata 666a5e983bd5555c496a209f3e3a48e2826940b09f5Petr Machata int rc = DICT_INSERT(&cache->protolibs, &filename, &plib); 667a5e983bd5555c496a209f3e3a48e2826940b09f5Petr Machata if (rc < 0 && own_filename) 66898a7dce70986f2394d22ee5dd8ed355ceb2104b4Petr Machata free((char *) filename); 669e56fe644f725f2c1c8308e7c2b5f9cd02e89eed0Petr Machata if (rc == 0 && plib != NULL) 6707f1d856ea4882a23461886d0f589244cc11f0b2fPetr Machata plib->refs++; 671a5e983bd5555c496a209f3e3a48e2826940b09f5Petr Machata return rc; 67282ce0f8e3aefc3f833e7059f3cedeacedca0cad2Petr Machata} 67308cdf328add7b723b94b151866e5d0173662f6c6Petr Machata 674f70812ec281a829ca7a758337aacec58eca41550Petr Machatastatic void 675f70812ec281a829ca7a758337aacec58eca41550Petr Machatadestroy_global_config(void) 676f70812ec281a829ca7a758337aacec58eca41550Petr Machata{ 677f70812ec281a829ca7a758337aacec58eca41550Petr Machata protolib_cache_destroy(&g_protocache); 678f70812ec281a829ca7a758337aacec58eca41550Petr Machata protolib_destroy(&legacy_typedefs); 679f70812ec281a829ca7a758337aacec58eca41550Petr Machata} 680f70812ec281a829ca7a758337aacec58eca41550Petr Machata 68108cdf328add7b723b94b151866e5d0173662f6c6Petr Machatavoid 68208cdf328add7b723b94b151866e5d0173662f6c6Petr Machatainit_global_config(void) 68308cdf328add7b723b94b151866e5d0173662f6c6Petr Machata{ 68408cdf328add7b723b94b151866e5d0173662f6c6Petr Machata protolib_init(&legacy_typedefs); 68508cdf328add7b723b94b151866e5d0173662f6c6Petr Machata 686c65c24a7e4645559a0fb050ff5a96ec248827562Petr Machata struct arg_type_info *ptr_info = type_get_voidptr(); 68708cdf328add7b723b94b151866e5d0173662f6c6Petr Machata static struct named_type voidptr_type; 688c65c24a7e4645559a0fb050ff5a96ec248827562Petr Machata named_type_init(&voidptr_type, ptr_info, 0); 68908cdf328add7b723b94b151866e5d0173662f6c6Petr Machata 690f9f3df4c9e232dc06b769daa5edf489675c5cdfcPetr Machata /* Build legacy typedefs first. This is used by 691f9f3df4c9e232dc06b769daa5edf489675c5cdfcPetr Machata * protolib_cache_init call below. */ 69208cdf328add7b723b94b151866e5d0173662f6c6Petr Machata if (protolib_add_named_type(&legacy_typedefs, "addr", 0, 69308cdf328add7b723b94b151866e5d0173662f6c6Petr Machata &voidptr_type) < 0 69408cdf328add7b723b94b151866e5d0173662f6c6Petr Machata || protolib_add_named_type(&legacy_typedefs, "file", 0, 69508cdf328add7b723b94b151866e5d0173662f6c6Petr Machata &voidptr_type) < 0) { 69608cdf328add7b723b94b151866e5d0173662f6c6Petr Machata fprintf(stderr, 69708cdf328add7b723b94b151866e5d0173662f6c6Petr Machata "Couldn't initialize aliases `addr' and `file'.\n"); 698f9f3df4c9e232dc06b769daa5edf489675c5cdfcPetr Machata 699f70812ec281a829ca7a758337aacec58eca41550Petr Machata exit(1); 70008cdf328add7b723b94b151866e5d0173662f6c6Petr Machata } 70108cdf328add7b723b94b151866e5d0173662f6c6Petr Machata 70208cdf328add7b723b94b151866e5d0173662f6c6Petr Machata if (protolib_cache_init(&g_protocache, NULL) < 0) { 70308cdf328add7b723b94b151866e5d0173662f6c6Petr Machata fprintf(stderr, "Couldn't init prototype cache\n"); 704f70812ec281a829ca7a758337aacec58eca41550Petr Machata exit(1); 70508cdf328add7b723b94b151866e5d0173662f6c6Petr Machata } 70608cdf328add7b723b94b151866e5d0173662f6c6Petr Machata 707f70812ec281a829ca7a758337aacec58eca41550Petr Machata atexit(destroy_global_config); 70808cdf328add7b723b94b151866e5d0173662f6c6Petr Machata} 709