194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata/* 294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * This file is part of ltrace. 3d8286ed3496bcd69cd4796f57a5b5c04859d2378Petr Machata * Copyright (C) 2011,2012,2013 Petr Machata, Red Hat Inc. 494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * Copyright (C) 1998,2004,2007,2008,2009 Juan Cespedes 594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * Copyright (C) 2006 Ian Wienand 694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * Copyright (C) 2006 Steve Fink 794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * 894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * This program is free software; you can redistribute it and/or 994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * modify it under the terms of the GNU General Public License as 1094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * published by the Free Software Foundation; either version 2 of the 1194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * License, or (at your option) any later version. 1294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * 1394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * This program is distributed in the hope that it will be useful, but 1494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * WITHOUT ANY WARRANTY; without even the implied warranty of 1594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * General Public License for more details. 1794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * 1894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * You should have received a copy of the GNU General Public License 1994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * along with this program; if not, write to the Free Software 2094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 2194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * 02110-1301 USA 2294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata */ 2394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 24caccda07541df0790887311d898405b2e4d78a5fPetr Machata#define _XOPEN_SOURCE /* For wcwidth from wchar.h. */ 25caccda07541df0790887311d898405b2e4d78a5fPetr Machata 267bafff09cc66e23519512a54e2d1ebd3664a1a70Steve Fink#include <ctype.h> 275e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes#include <stdlib.h> 2894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata#include <assert.h> 2994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata#include <inttypes.h> 3094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata#include <stdarg.h> 3194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata#include <stdio.h> 32307b90b158b79ba3aae61d5c6612b4769b10be5fPetr Machata#include <string.h> 33caccda07541df0790887311d898405b2e4d78a5fPetr Machata#include <wchar.h> 345e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes 351721fc956dfe30fd5dc5a49238c376ccbfdfd9d9Petr Machata#include "bits.h" 3694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata#include "expr.h" 37caccda07541df0790887311d898405b2e4d78a5fPetr Machata#include "lens_default.h" 38caccda07541df0790887311d898405b2e4d78a5fPetr Machata#include "options.h" 39caccda07541df0790887311d898405b2e4d78a5fPetr Machata#include "output.h" 40000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata#include "type.h" 41caccda07541df0790887311d898405b2e4d78a5fPetr Machata#include "value.h" 42d7b2292789462475ead5986c2dea25a0b8623f7dPetr Machata#include "zero.h" 435e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes 4494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata#define READER(NAME, TYPE) \ 4594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata static int \ 4694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata NAME(struct value *value, TYPE *ret, struct value_dict *arguments) \ 4794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata { \ 4894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata union { \ 4994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata TYPE val; \ 5094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata unsigned char buf[0]; \ 5194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata } u; \ 5294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata if (value_extract_buf(value, u.buf, arguments) < 0) \ 5394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata return -1; \ 5494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata *ret = u.val; \ 5594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata return 0; \ 56a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes } 5765b53df7fa2577c4138aef86c115873eab684a0aSteve Fink 5894078ecce3a103c28457e6f90f1e5b0dacc61146Petr MachataREADER(read_float, float) 5994078ecce3a103c28457e6f90f1e5b0dacc61146Petr MachataREADER(read_double, double) 6094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 6194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata#undef READER 6294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 6394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata#define HANDLE_WIDTH(BITS) \ 6494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata do { \ 6594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata long l; \ 6694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata if (value_extract_word(value, &l, arguments) < 0) \ 6794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata return -1; \ 6894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata int##BITS##_t i = l; \ 69e773f634dc1283a47786788e747aa5217f61c6fcPetr Machata uint64_t v = (uint64_t)(uint##BITS##_t)i; \ 7094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata switch (format) { \ 7194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata case INT_FMT_unknown: \ 72c1e4186bc03fff3ddc2682bc10b11075381a950bPetr Machata if (l < -10000 || l > 10000) \ 7394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata case INT_FMT_x: \ 74e773f634dc1283a47786788e747aa5217f61c6fcPetr Machata return fprintf(stream, "%#"PRIx64, v); \ 7594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata case INT_FMT_i: \ 76e773f634dc1283a47786788e747aa5217f61c6fcPetr Machata case INT_FMT_default: \ 7794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata return fprintf(stream, "%"PRIi##BITS, i); \ 7894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata case INT_FMT_u: \ 79e773f634dc1283a47786788e747aa5217f61c6fcPetr Machata return fprintf(stream, "%"PRIu64, v); \ 8094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata case INT_FMT_o: \ 81e773f634dc1283a47786788e747aa5217f61c6fcPetr Machata return fprintf(stream, "0%"PRIo64, v); \ 8294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata } \ 8394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata } while (0) 8494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 8594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataenum int_fmt_t 8694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{ 8794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata INT_FMT_i, 8894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata INT_FMT_u, 8994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata INT_FMT_o, 9094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata INT_FMT_x, 9194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata INT_FMT_unknown, 92e773f634dc1283a47786788e747aa5217f61c6fcPetr Machata INT_FMT_default, 9394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}; 9494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 9594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machatastatic int 9694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataformat_integer(FILE *stream, struct value *value, enum int_fmt_t format, 9794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata struct value_dict *arguments) 9894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{ 9994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata switch (type_sizeof(value->inferior, value->type)) { 10094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 10194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata case 1: HANDLE_WIDTH(8); 10294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata case 2: HANDLE_WIDTH(16); 10394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata case 4: HANDLE_WIDTH(32); 10494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata case 8: HANDLE_WIDTH(64); 10594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 10694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata default: 10794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata assert(!"unsupported integer width"); 10894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata abort(); 10994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 11094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata case -1: 11194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata return -1; 11294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata } 1136a48a6d7f428cd7f0796477a3892603a83fcce99Steve Fink} 1146a48a6d7f428cd7f0796477a3892603a83fcce99Steve Fink 11594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata#undef HANDLE_WIDTH 11694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 117f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesstatic int 11894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataacc_fprintf(int *countp, FILE *stream, const char *format, ...) 11994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{ 12094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata va_list pa; 12194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata va_start(pa, format); 122adec201a52c240cf4b533c05106aedddc911ca76Petr Machata int i = account_output(countp, vfprintf(stream, format, pa)); 12394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata va_end(pa); 12494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 12594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata return i; 1261150bc4b812f0150e832607b8724b023d6d7d575Steve Fink} 127a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes 128f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesstatic int 129c00837c2928da53a3515b107399b742ea157e78aPetr Machataprint_char(FILE *stream, int c) 13094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{ 13194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata const char *fmt; 13294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata switch (c) { 13394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata case -1: 13494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata fmt = "EOF"; 13594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata break; 13694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata case 0: 13794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata fmt = "\\0"; 13894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata break; 13994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata case '\a': 14094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata fmt = "\\a"; 14194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata break; 14294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata case '\b': 14394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata fmt = "\\b"; 14494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata break; 14594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata case '\t': 14694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata fmt = "\\t"; 14794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata break; 14894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata case '\n': 14994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata fmt = "\\n"; 15094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata break; 15194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata case '\v': 15294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata fmt = "\\v"; 15394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata break; 15494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata case '\f': 15594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata fmt = "\\f"; 15694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata break; 15794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata case '\r': 15894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata fmt = "\\r"; 15994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata break; 16094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata case '\\': 16194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata fmt = "\\\\"; 16294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata break; 16394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata default: 16494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata if (isprint(c) || c == ' ') 16594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata fmt = "%c"; 16694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata else 167987d27b3e97b208874ca967d536dc862dae2bd43Petr Machata fmt = "\\%03o"; 168a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes } 169a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes 170987d27b3e97b208874ca967d536dc862dae2bd43Petr Machata return fprintf(stream, fmt, c); 171e3f4a984db115979e09414b7281da98399dd8949Petr Machata} 172e3f4a984db115979e09414b7281da98399dd8949Petr Machata 173e3f4a984db115979e09414b7281da98399dd8949Petr Machatastatic int 174c00837c2928da53a3515b107399b742ea157e78aPetr Machataformat_char(FILE *stream, struct value *value, struct value_dict *arguments) 175c00837c2928da53a3515b107399b742ea157e78aPetr Machata{ 176c00837c2928da53a3515b107399b742ea157e78aPetr Machata long lc; 177c00837c2928da53a3515b107399b742ea157e78aPetr Machata if (value_extract_word(value, &lc, arguments) < 0) 178c00837c2928da53a3515b107399b742ea157e78aPetr Machata return -1; 179c00837c2928da53a3515b107399b742ea157e78aPetr Machata return print_char(stream, (int) lc); 180c00837c2928da53a3515b107399b742ea157e78aPetr Machata} 181c00837c2928da53a3515b107399b742ea157e78aPetr Machata 182c00837c2928da53a3515b107399b742ea157e78aPetr Machatastatic int 183c00837c2928da53a3515b107399b742ea157e78aPetr Machataformat_naked(FILE *stream, struct value *value, 184c00837c2928da53a3515b107399b742ea157e78aPetr Machata struct value_dict *arguments, 185c00837c2928da53a3515b107399b742ea157e78aPetr Machata int (*what)(FILE *, struct value *, struct value_dict *)) 186e3f4a984db115979e09414b7281da98399dd8949Petr Machata{ 187e3f4a984db115979e09414b7281da98399dd8949Petr Machata int written = 0; 188e3f4a984db115979e09414b7281da98399dd8949Petr Machata if (acc_fprintf(&written, stream, "'") < 0 189adec201a52c240cf4b533c05106aedddc911ca76Petr Machata || account_output(&written, 190c00837c2928da53a3515b107399b742ea157e78aPetr Machata what(stream, value, arguments)) < 0 191e3f4a984db115979e09414b7281da98399dd8949Petr Machata || acc_fprintf(&written, stream, "'") < 0) 19294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata return -1; 193e3f4a984db115979e09414b7281da98399dd8949Petr Machata 19494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata return written; 195e4b3263fb2b32eb5ee0f693fc223ed8c363fbd69Steve Fink} 196e4b3263fb2b32eb5ee0f693fc223ed8c363fbd69Steve Fink 197f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesstatic int 198f197727e6247be1ee08d2a667931aee20512ae18Petr Machataformat_double(FILE *stream, double value, enum int_fmt_t format) 199f197727e6247be1ee08d2a667931aee20512ae18Petr Machata{ 200f197727e6247be1ee08d2a667931aee20512ae18Petr Machata if (format == INT_FMT_x) 201f197727e6247be1ee08d2a667931aee20512ae18Petr Machata return fprintf(stream, "%a", value); 202f197727e6247be1ee08d2a667931aee20512ae18Petr Machata else 203f197727e6247be1ee08d2a667931aee20512ae18Petr Machata return fprintf(stream, "%f", value); 204f197727e6247be1ee08d2a667931aee20512ae18Petr Machata} 205f197727e6247be1ee08d2a667931aee20512ae18Petr Machata 206f197727e6247be1ee08d2a667931aee20512ae18Petr Machatastatic int 207f197727e6247be1ee08d2a667931aee20512ae18Petr Machataformat_floating(FILE *stream, struct value *value, struct value_dict *arguments, 208f197727e6247be1ee08d2a667931aee20512ae18Petr Machata enum int_fmt_t format) 20994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{ 21094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata switch (value->type->type) { 21194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata float f; 21294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata double d; 21394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata case ARGTYPE_FLOAT: 21494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata if (read_float(value, &f, arguments) < 0) 21594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata return -1; 216f197727e6247be1ee08d2a667931aee20512ae18Petr Machata return format_double(stream, f, format); 21794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata case ARGTYPE_DOUBLE: 21894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata if (read_double(value, &d, arguments) < 0) 21994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata return -1; 220f197727e6247be1ee08d2a667931aee20512ae18Petr Machata return format_double(stream, d, format); 22194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata default: 22294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata abort(); 223a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes } 2247bafff09cc66e23519512a54e2d1ebd3664a1a70Steve Fink} 2257bafff09cc66e23519512a54e2d1ebd3664a1a70Steve Fink 226f7c46bba61bb830e5a283ef8b0174f33c3989821Petr Machatastruct format_argument_data 227f7c46bba61bb830e5a283ef8b0174f33c3989821Petr Machata{ 228f7c46bba61bb830e5a283ef8b0174f33c3989821Petr Machata struct value *value; 229f7c46bba61bb830e5a283ef8b0174f33c3989821Petr Machata struct value_dict *arguments; 230f7c46bba61bb830e5a283ef8b0174f33c3989821Petr Machata}; 231f7c46bba61bb830e5a283ef8b0174f33c3989821Petr Machata 232f7c46bba61bb830e5a283ef8b0174f33c3989821Petr Machatastatic int 233f7c46bba61bb830e5a283ef8b0174f33c3989821Petr Machataformat_argument_cb(FILE *stream, void *ptr) 234f7c46bba61bb830e5a283ef8b0174f33c3989821Petr Machata{ 235f7c46bba61bb830e5a283ef8b0174f33c3989821Petr Machata struct format_argument_data *data = ptr; 236f7c46bba61bb830e5a283ef8b0174f33c3989821Petr Machata return format_argument(stream, data->value, data->arguments); 237f7c46bba61bb830e5a283ef8b0174f33c3989821Petr Machata} 238f7c46bba61bb830e5a283ef8b0174f33c3989821Petr Machata 239f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesstatic int 24094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataformat_struct(FILE *stream, struct value *value, struct value_dict *arguments) 24194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{ 24294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata int written = 0; 24394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata if (acc_fprintf(&written, stream, "{ ") < 0) 24494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata return -1; 245f7c46bba61bb830e5a283ef8b0174f33c3989821Petr Machata 246f7c46bba61bb830e5a283ef8b0174f33c3989821Petr Machata int need_delim = 0; 24794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata size_t i; 24894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata for (i = 0; i < type_struct_size(value->type); ++i) { 24994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata struct value element; 25094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata if (value_init_element(&element, value, i) < 0) 25194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata return -1; 252f7c46bba61bb830e5a283ef8b0174f33c3989821Petr Machata 253f7c46bba61bb830e5a283ef8b0174f33c3989821Petr Machata struct format_argument_data data = { &element, arguments }; 254f7c46bba61bb830e5a283ef8b0174f33c3989821Petr Machata int o = delim_output(stream, &need_delim, 255f7c46bba61bb830e5a283ef8b0174f33c3989821Petr Machata format_argument_cb, &data); 2568904cdcbac783406d6f6d601d8447961b67068cePetr Machata value_destroy(&element); 25794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata if (o < 0) 25894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata return -1; 259f7c46bba61bb830e5a283ef8b0174f33c3989821Petr Machata 26094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata written += o; 261a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes } 26294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata if (acc_fprintf(&written, stream, " }") < 0) 26394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata return -1; 26494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata return written; 26594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata} 2666a3e24dc1709530e59dd6ae3e91ced1c221fe1b9Steve Fink 267d8286ed3496bcd69cd4796f57a5b5c04859d2378Petr Machatastatic const char null_message[] = "nil"; 26894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataint 26994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataformat_pointer(FILE *stream, struct value *value, struct value_dict *arguments) 27094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{ 27126c0c9413c2558c3f95cb466b3734ea5ba57444dPetr Machata if (value_is_zero(value, arguments)) 272d8286ed3496bcd69cd4796f57a5b5c04859d2378Petr Machata return fprintf(stream, null_message); 27326c0c9413c2558c3f95cb466b3734ea5ba57444dPetr Machata 274307b90b158b79ba3aae61d5c6612b4769b10be5fPetr Machata /* The following is for detecting recursion. We keep track of 275307b90b158b79ba3aae61d5c6612b4769b10be5fPetr Machata * the values that were already displayed. Each time a 276307b90b158b79ba3aae61d5c6612b4769b10be5fPetr Machata * pointer should be dereferenced, we compare its value to the 277307b90b158b79ba3aae61d5c6612b4769b10be5fPetr Machata * value of each of the pointers dereferenced so far. If one 278307b90b158b79ba3aae61d5c6612b4769b10be5fPetr Machata * of them matches, instead of recursing, we just printf which 279307b90b158b79ba3aae61d5c6612b4769b10be5fPetr Machata * superstructure this pointer recurses to. */ 280307b90b158b79ba3aae61d5c6612b4769b10be5fPetr Machata static struct vect pointers = {}; 281307b90b158b79ba3aae61d5c6612b4769b10be5fPetr Machata if (pointers.elt_size == 0) 282307b90b158b79ba3aae61d5c6612b4769b10be5fPetr Machata VECT_INIT(&pointers, struct value *); 283307b90b158b79ba3aae61d5c6612b4769b10be5fPetr Machata 2846248a0ac394b2aa3b2267eaa1220a90b609b6f86Petr Machata /* Trim number of expanded structures of the same type. Even 2856248a0ac394b2aa3b2267eaa1220a90b609b6f86Petr Machata * for non-recursive structure, we don't want to expand all of 2866248a0ac394b2aa3b2267eaa1220a90b609b6f86Petr Machata * it if it's huge. */ 287307b90b158b79ba3aae61d5c6612b4769b10be5fPetr Machata size_t i; 2886248a0ac394b2aa3b2267eaa1220a90b609b6f86Petr Machata size_t len = vect_size(&pointers); 2896248a0ac394b2aa3b2267eaa1220a90b609b6f86Petr Machata assert(value->type->type == ARGTYPE_POINTER); 2906248a0ac394b2aa3b2267eaa1220a90b609b6f86Petr Machata struct arg_type_info *pointee = value->type->u.ptr_info.info; 2916248a0ac394b2aa3b2267eaa1220a90b609b6f86Petr Machata if (pointee->type == ARGTYPE_STRUCT) { 2926248a0ac394b2aa3b2267eaa1220a90b609b6f86Petr Machata size_t depth = 0; 2936248a0ac394b2aa3b2267eaa1220a90b609b6f86Petr Machata for (i = 0; i < len; ++i) { 2946248a0ac394b2aa3b2267eaa1220a90b609b6f86Petr Machata struct value *old 2956248a0ac394b2aa3b2267eaa1220a90b609b6f86Petr Machata = *VECT_ELEMENT(&pointers, struct value *, i); 2966248a0ac394b2aa3b2267eaa1220a90b609b6f86Petr Machata assert(old->type->type == ARGTYPE_POINTER); 2976248a0ac394b2aa3b2267eaa1220a90b609b6f86Petr Machata struct arg_type_info *old_pointee 2986248a0ac394b2aa3b2267eaa1220a90b609b6f86Petr Machata = old->type->u.ptr_info.info; 2996248a0ac394b2aa3b2267eaa1220a90b609b6f86Petr Machata if (old_pointee == pointee) 3006248a0ac394b2aa3b2267eaa1220a90b609b6f86Petr Machata depth++; 3016248a0ac394b2aa3b2267eaa1220a90b609b6f86Petr Machata } 3026248a0ac394b2aa3b2267eaa1220a90b609b6f86Petr Machata if (depth >= options.arraylen) 3036248a0ac394b2aa3b2267eaa1220a90b609b6f86Petr Machata return fprintf(stream, "..."); 3046248a0ac394b2aa3b2267eaa1220a90b609b6f86Petr Machata } 3056248a0ac394b2aa3b2267eaa1220a90b609b6f86Petr Machata 306307b90b158b79ba3aae61d5c6612b4769b10be5fPetr Machata for (i = len; i-- > 0 ;) { 307307b90b158b79ba3aae61d5c6612b4769b10be5fPetr Machata struct value **old = VECT_ELEMENT(&pointers, struct value *, i); 308307b90b158b79ba3aae61d5c6612b4769b10be5fPetr Machata int rc = value_equal(value, *old, arguments); 309307b90b158b79ba3aae61d5c6612b4769b10be5fPetr Machata if (rc < 0) 310307b90b158b79ba3aae61d5c6612b4769b10be5fPetr Machata return -1; 311307b90b158b79ba3aae61d5c6612b4769b10be5fPetr Machata if (rc > 0) { 312307b90b158b79ba3aae61d5c6612b4769b10be5fPetr Machata size_t reclevel = len - i - 1; 313307b90b158b79ba3aae61d5c6612b4769b10be5fPetr Machata char buf[reclevel + 1]; 314307b90b158b79ba3aae61d5c6612b4769b10be5fPetr Machata memset(buf, '^', sizeof buf); 315307b90b158b79ba3aae61d5c6612b4769b10be5fPetr Machata buf[reclevel] = 0; 316307b90b158b79ba3aae61d5c6612b4769b10be5fPetr Machata return fprintf(stream, "recurse%s", buf); 317307b90b158b79ba3aae61d5c6612b4769b10be5fPetr Machata } 318307b90b158b79ba3aae61d5c6612b4769b10be5fPetr Machata } 319307b90b158b79ba3aae61d5c6612b4769b10be5fPetr Machata 320307b90b158b79ba3aae61d5c6612b4769b10be5fPetr Machata /* OK, not a recursion. Remember this value for tracking. */ 321307b90b158b79ba3aae61d5c6612b4769b10be5fPetr Machata if (VECT_PUSHBACK(&pointers, &value) < 0) 322307b90b158b79ba3aae61d5c6612b4769b10be5fPetr Machata return -1; 323307b90b158b79ba3aae61d5c6612b4769b10be5fPetr Machata 32494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata struct value element; 32526c0c9413c2558c3f95cb466b3734ea5ba57444dPetr Machata int o; 32626c0c9413c2558c3f95cb466b3734ea5ba57444dPetr Machata if (value_init_deref(&element, value) < 0) { 32726c0c9413c2558c3f95cb466b3734ea5ba57444dPetr Machata o = -1; 32826c0c9413c2558c3f95cb466b3734ea5ba57444dPetr Machata goto done; 32926c0c9413c2558c3f95cb466b3734ea5ba57444dPetr Machata } 33026c0c9413c2558c3f95cb466b3734ea5ba57444dPetr Machata o = format_argument(stream, &element, arguments); 3318904cdcbac783406d6f6d601d8447961b67068cePetr Machata value_destroy(&element); 33226c0c9413c2558c3f95cb466b3734ea5ba57444dPetr Machata 33326c0c9413c2558c3f95cb466b3734ea5ba57444dPetr Machatadone: 334c28410e3f4bb4d40e48d58440800fbb080b2e3d6Petr Machata VECT_POPBACK(&pointers, struct value *, NULL, NULL); 3358904cdcbac783406d6f6d601d8447961b67068cePetr Machata return o; 3366a3e24dc1709530e59dd6ae3e91ced1c221fe1b9Steve Fink} 3376a3e24dc1709530e59dd6ae3e91ced1c221fe1b9Steve Fink 33894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata/* 33994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * LENGTH is an expression whose evaluation will yield the actual 34094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * length of the array. 34194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * 34294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * MAXLEN is the actual maximum length that we care about 34394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * 34494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * BEFORE if LENGTH>MAXLEN, we display ellipsis. We display it before 34594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * the closing parenthesis if BEFORE, otherwise after it. 34694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * 34794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * OPEN, CLOSE, DELIM are opening and closing parenthesis and element 34894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * delimiter. 34994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata */ 350c00837c2928da53a3515b107399b742ea157e78aPetr Machatastatic int 35194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataformat_array(FILE *stream, struct value *value, struct value_dict *arguments, 35294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata struct expr_node *length, size_t maxlen, int before, 35394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata const char *open, const char *close, const char *delim) 35494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{ 35594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata /* We need "long" to be long enough to cover the whole address 35694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * space. */ 357a77b267abb870c935f9b4187ca31409fa5eb9dcbPeter Wu (void)sizeof(char[1 - 2*(sizeof(long) < sizeof(void *))]); 35831af32cfcd61671cbb5e567870103766b3231521Petr Machata long l; 359d7b2292789462475ead5986c2dea25a0b8623f7dPetr Machata if (expr_eval_word(length, value, arguments, &l) < 0) 360d7b2292789462475ead5986c2dea25a0b8623f7dPetr Machata return -1; 36194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata size_t len = (size_t)l; 36294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 36394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata int written = 0; 36494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata if (acc_fprintf(&written, stream, "%s", open) < 0) 36594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata return -1; 3665e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes 36794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata size_t i; 36894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata for (i = 0; i < len && i <= maxlen; ++i) { 36994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata if (i == maxlen) { 37094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata if (before && acc_fprintf(&written, stream, "...") < 0) 37194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata return -1; 37294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata break; 37394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata } 37494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 37594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata if (i > 0 && acc_fprintf(&written, stream, "%s", delim) < 0) 37694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata return -1; 37794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 37894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata struct value element; 37994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata if (value_init_element(&element, value, i) < 0) 38094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata return -1; 381f6ec08afb96292fd3c802c1f633d8de249664c72Petr Machata int o = format_argument(stream, &element, arguments); 3828904cdcbac783406d6f6d601d8447961b67068cePetr Machata value_destroy(&element); 38394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata if (o < 0) 38494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata return -1; 38594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata written += o; 38694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata } 38794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata if (acc_fprintf(&written, stream, "%s", close) < 0) 38894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata return -1; 38994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata if (i == maxlen && !before && acc_fprintf(&written, stream, "...") < 0) 39094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata return -1; 39194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 39294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata return written; 39394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata} 39494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 39531af32cfcd61671cbb5e567870103766b3231521Petr Machatastatic int 39631af32cfcd61671cbb5e567870103766b3231521Petr Machatatoplevel_format_lens(struct lens *lens, FILE *stream, 397ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machata struct value *value, struct value_dict *arguments, 398ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machata enum int_fmt_t int_fmt) 39994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{ 40094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata switch (value->type->type) { 4012d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand case ARGTYPE_VOID: 40294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata return fprintf(stream, "<void>"); 40394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 40494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata case ARGTYPE_SHORT: 4052d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand case ARGTYPE_INT: 4062d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand case ARGTYPE_LONG: 407ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machata return format_integer(stream, value, int_fmt, arguments); 40894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 40994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata case ARGTYPE_USHORT: 41094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata case ARGTYPE_UINT: 4112d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand case ARGTYPE_ULONG: 412e773f634dc1283a47786788e747aa5217f61c6fcPetr Machata if (int_fmt == INT_FMT_i || int_fmt == INT_FMT_default) 413ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machata int_fmt = INT_FMT_u; 414ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machata return format_integer(stream, value, int_fmt, arguments); 41594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 4162d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand case ARGTYPE_CHAR: 417e773f634dc1283a47786788e747aa5217f61c6fcPetr Machata if (int_fmt == INT_FMT_default) 418c00837c2928da53a3515b107399b742ea157e78aPetr Machata return format_naked(stream, value, arguments, 419c00837c2928da53a3515b107399b742ea157e78aPetr Machata &format_char); 420e773f634dc1283a47786788e747aa5217f61c6fcPetr Machata return format_integer(stream, value, int_fmt, arguments); 42194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 42294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata case ARGTYPE_FLOAT: 42394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata case ARGTYPE_DOUBLE: 424f197727e6247be1ee08d2a667931aee20512ae18Petr Machata return format_floating(stream, value, arguments, int_fmt); 42594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 426e4b3263fb2b32eb5ee0f693fc223ed8c363fbd69Steve Fink case ARGTYPE_STRUCT: 42794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata return format_struct(stream, value, arguments); 42894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata 4297bafff09cc66e23519512a54e2d1ebd3664a1a70Steve Fink case ARGTYPE_POINTER: 430d8286ed3496bcd69cd4796f57a5b5c04859d2378Petr Machata if (value_is_zero(value, arguments)) 431d8286ed3496bcd69cd4796f57a5b5c04859d2378Petr Machata return fprintf(stream, null_message); 43294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata if (value->type->u.array_info.elt_type->type != ARGTYPE_VOID) 43394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata return format_pointer(stream, value, arguments); 43494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata return format_integer(stream, value, INT_FMT_x, arguments); 4357bafff09cc66e23519512a54e2d1ebd3664a1a70Steve Fink 43694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata case ARGTYPE_ARRAY: 43794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata return format_array(stream, value, arguments, 43894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata value->type->u.array_info.length, 439e3f4a984db115979e09414b7281da98399dd8949Petr Machata options.arraylen, 1, "[ ", " ]", ", "); 4405e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes } 44194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata abort(); 4425e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes} 44331af32cfcd61671cbb5e567870103766b3231521Petr Machata 44431af32cfcd61671cbb5e567870103766b3231521Petr Machatastatic int 44531af32cfcd61671cbb5e567870103766b3231521Petr Machatadefault_lens_format_cb(struct lens *lens, FILE *stream, 44631af32cfcd61671cbb5e567870103766b3231521Petr Machata struct value *value, struct value_dict *arguments) 44731af32cfcd61671cbb5e567870103766b3231521Petr Machata{ 448e773f634dc1283a47786788e747aa5217f61c6fcPetr Machata return toplevel_format_lens(lens, stream, value, arguments, 449e773f634dc1283a47786788e747aa5217f61c6fcPetr Machata INT_FMT_default); 45031af32cfcd61671cbb5e567870103766b3231521Petr Machata} 45131af32cfcd61671cbb5e567870103766b3231521Petr Machata 45231af32cfcd61671cbb5e567870103766b3231521Petr Machatastruct lens default_lens = { 45331af32cfcd61671cbb5e567870103766b3231521Petr Machata .format_cb = default_lens_format_cb, 45431af32cfcd61671cbb5e567870103766b3231521Petr Machata}; 455ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machata 456ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machata 457ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machatastatic int 458ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machatablind_lens_format_cb(struct lens *lens, FILE *stream, 459ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machata struct value *value, struct value_dict *arguments) 460ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machata{ 461ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machata return 0; 462ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machata} 463ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machata 464ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machatastruct lens blind_lens = { 465ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machata .format_cb = blind_lens_format_cb, 466ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machata}; 467ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machata 468ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machata 469ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machatastatic int 470ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machataoctal_lens_format_cb(struct lens *lens, FILE *stream, 471ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machata struct value *value, struct value_dict *arguments) 472ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machata{ 473ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machata return toplevel_format_lens(lens, stream, value, arguments, INT_FMT_o); 474ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machata} 475ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machata 476ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machatastruct lens octal_lens = { 477ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machata .format_cb = octal_lens_format_cb, 478ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machata}; 479ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machata 480ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machata 481ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machatastatic int 482ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machatahex_lens_format_cb(struct lens *lens, FILE *stream, 483ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machata struct value *value, struct value_dict *arguments) 484ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machata{ 485ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machata return toplevel_format_lens(lens, stream, value, arguments, INT_FMT_x); 486ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machata} 487ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machata 488ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machatastruct lens hex_lens = { 489ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machata .format_cb = hex_lens_format_cb, 490ce034981e2880eecb8a196c78182dfb4ae67850fPetr Machata}; 491b781916d24d6ee96842c818b5e18af31808d427dPetr Machata 492b781916d24d6ee96842c818b5e18af31808d427dPetr Machata 493b781916d24d6ee96842c818b5e18af31808d427dPetr Machatastatic int 494ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machatadec_lens_format_cb(struct lens *lens, FILE *stream, 495ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata struct value *value, struct value_dict *arguments) 496ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata{ 497ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata return toplevel_format_lens(lens, stream, value, arguments, INT_FMT_u); 498ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata} 499ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata 500ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machatastruct lens dec_lens = { 501ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata .format_cb = dec_lens_format_cb, 502ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata}; 503ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata 504ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata 505ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machatastatic int 506b781916d24d6ee96842c818b5e18af31808d427dPetr Machataguess_lens_format_cb(struct lens *lens, FILE *stream, 507b781916d24d6ee96842c818b5e18af31808d427dPetr Machata struct value *value, struct value_dict *arguments) 508b781916d24d6ee96842c818b5e18af31808d427dPetr Machata{ 509b781916d24d6ee96842c818b5e18af31808d427dPetr Machata return toplevel_format_lens(lens, stream, value, arguments, 510b781916d24d6ee96842c818b5e18af31808d427dPetr Machata INT_FMT_unknown); 511b781916d24d6ee96842c818b5e18af31808d427dPetr Machata} 512b781916d24d6ee96842c818b5e18af31808d427dPetr Machata 513b781916d24d6ee96842c818b5e18af31808d427dPetr Machatastruct lens guess_lens = { 514b781916d24d6ee96842c818b5e18af31808d427dPetr Machata .format_cb = guess_lens_format_cb, 515b781916d24d6ee96842c818b5e18af31808d427dPetr Machata}; 516e3f4a984db115979e09414b7281da98399dd8949Petr Machata 517e3f4a984db115979e09414b7281da98399dd8949Petr Machata 518e3f4a984db115979e09414b7281da98399dd8949Petr Machatastatic int 51938fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machatabool_lens_format_cb(struct lens *lens, FILE *stream, 52038fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machata struct value *value, struct value_dict *arguments) 52138fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machata{ 52238fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machata switch (value->type->type) { 52338fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machata case ARGTYPE_VOID: 52438fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machata case ARGTYPE_FLOAT: 52538fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machata case ARGTYPE_DOUBLE: 52638fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machata case ARGTYPE_STRUCT: 52738fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machata case ARGTYPE_POINTER: 52838fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machata case ARGTYPE_ARRAY: 52938fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machata return toplevel_format_lens(lens, stream, value, 530e773f634dc1283a47786788e747aa5217f61c6fcPetr Machata arguments, INT_FMT_default); 53138fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machata 53238fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machata int zero; 53338fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machata case ARGTYPE_SHORT: 53438fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machata case ARGTYPE_INT: 53538fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machata case ARGTYPE_LONG: 53638fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machata case ARGTYPE_USHORT: 53738fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machata case ARGTYPE_UINT: 53838fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machata case ARGTYPE_ULONG: 53938fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machata case ARGTYPE_CHAR: 54038fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machata if ((zero = value_is_zero(value, arguments)) < 0) 54138fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machata return -1; 54238fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machata if (zero) 54338fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machata return fprintf(stream, "false"); 54438fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machata else 54538fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machata return fprintf(stream, "true"); 54638fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machata } 54738fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machata abort(); 54838fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machata} 54938fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machata 55038fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machatastruct lens bool_lens = { 55138fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machata .format_cb = bool_lens_format_cb, 55238fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machata}; 55338fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machata 554c00837c2928da53a3515b107399b742ea157e78aPetr Machatastatic int 555c00837c2928da53a3515b107399b742ea157e78aPetr Machataredispatch_as_array(struct lens *lens, FILE *stream, 556c00837c2928da53a3515b107399b742ea157e78aPetr Machata struct value *value, struct value_dict *arguments, 557c00837c2928da53a3515b107399b742ea157e78aPetr Machata int (*cb)(struct lens *, FILE *, 558c00837c2928da53a3515b107399b742ea157e78aPetr Machata struct value *, struct value_dict *)) 559c00837c2928da53a3515b107399b742ea157e78aPetr Machata{ 560c00837c2928da53a3515b107399b742ea157e78aPetr Machata struct arg_type_info info[2]; 561c00837c2928da53a3515b107399b742ea157e78aPetr Machata type_init_array(&info[1], value->type->u.ptr_info.info, 0, 562c00837c2928da53a3515b107399b742ea157e78aPetr Machata expr_node_zero(), 0); 563c00837c2928da53a3515b107399b742ea157e78aPetr Machata type_init_pointer(&info[0], &info[1], 0); 564c00837c2928da53a3515b107399b742ea157e78aPetr Machata info->lens = lens; 565c00837c2928da53a3515b107399b742ea157e78aPetr Machata info->own_lens = 0; 566c00837c2928da53a3515b107399b742ea157e78aPetr Machata struct value tmp; 567c00837c2928da53a3515b107399b742ea157e78aPetr Machata if (value_clone(&tmp, value) < 0) 568c00837c2928da53a3515b107399b742ea157e78aPetr Machata return -1; 569c00837c2928da53a3515b107399b742ea157e78aPetr Machata value_set_type(&tmp, info, 0); 570c00837c2928da53a3515b107399b742ea157e78aPetr Machata int ret = cb(lens, stream, &tmp, arguments); 571c00837c2928da53a3515b107399b742ea157e78aPetr Machata type_destroy(&info[0]); 572c00837c2928da53a3515b107399b742ea157e78aPetr Machata type_destroy(&info[1]); 573c00837c2928da53a3515b107399b742ea157e78aPetr Machata value_destroy(&tmp); 574c00837c2928da53a3515b107399b742ea157e78aPetr Machata return ret; 575c00837c2928da53a3515b107399b742ea157e78aPetr Machata} 576c00837c2928da53a3515b107399b742ea157e78aPetr Machata 577c00837c2928da53a3515b107399b742ea157e78aPetr Machatastatic int 578c00837c2928da53a3515b107399b742ea157e78aPetr Machataformat_wchar(FILE *stream, struct value *value, struct value_dict *arguments) 579c00837c2928da53a3515b107399b742ea157e78aPetr Machata{ 580c00837c2928da53a3515b107399b742ea157e78aPetr Machata long l; 581c00837c2928da53a3515b107399b742ea157e78aPetr Machata if (value_extract_word(value, &l, arguments) < 0) 582c00837c2928da53a3515b107399b742ea157e78aPetr Machata return -1; 583c00837c2928da53a3515b107399b742ea157e78aPetr Machata wchar_t wc = (wchar_t) l; 584c00837c2928da53a3515b107399b742ea157e78aPetr Machata char buf[MB_CUR_MAX + 1]; 585c00837c2928da53a3515b107399b742ea157e78aPetr Machata 586c00837c2928da53a3515b107399b742ea157e78aPetr Machata int c = wctomb(buf, wc); 587c00837c2928da53a3515b107399b742ea157e78aPetr Machata if (c < 0) 588c00837c2928da53a3515b107399b742ea157e78aPetr Machata return -1; 589c00837c2928da53a3515b107399b742ea157e78aPetr Machata if (c == 1) 590c00837c2928da53a3515b107399b742ea157e78aPetr Machata return print_char(stream, buf[0]); 591c00837c2928da53a3515b107399b742ea157e78aPetr Machata 592c00837c2928da53a3515b107399b742ea157e78aPetr Machata buf[c] = 0; 593caccda07541df0790887311d898405b2e4d78a5fPetr Machata if (fprintf(stream, "%s", buf) < 0) 594caccda07541df0790887311d898405b2e4d78a5fPetr Machata return -1; 595caccda07541df0790887311d898405b2e4d78a5fPetr Machata 596caccda07541df0790887311d898405b2e4d78a5fPetr Machata c = wcwidth(wc); 597caccda07541df0790887311d898405b2e4d78a5fPetr Machata return c >= 0 ? c : 0; 598c00837c2928da53a3515b107399b742ea157e78aPetr Machata} 59938fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machata 60038fb49b852374d749bc91f1b8d91a2b5b2a57a10Petr Machatastatic int 601e3f4a984db115979e09414b7281da98399dd8949Petr Machatastring_lens_format_cb(struct lens *lens, FILE *stream, 602e3f4a984db115979e09414b7281da98399dd8949Petr Machata struct value *value, struct value_dict *arguments) 603e3f4a984db115979e09414b7281da98399dd8949Petr Machata{ 604e3f4a984db115979e09414b7281da98399dd8949Petr Machata switch (value->type->type) { 605e3f4a984db115979e09414b7281da98399dd8949Petr Machata case ARGTYPE_POINTER: 606e3f4a984db115979e09414b7281da98399dd8949Petr Machata /* This should really be written as either "string", 607e3f4a984db115979e09414b7281da98399dd8949Petr Machata * or, if lens, then string(array(char, zero)*). But 608e3f4a984db115979e09414b7281da98399dd8949Petr Machata * I suspect people are so used to the char * C idiom, 609e3f4a984db115979e09414b7281da98399dd8949Petr Machata * that string(char *) might actually turn up. So 610e3f4a984db115979e09414b7281da98399dd8949Petr Machata * let's just support it. */ 611c00837c2928da53a3515b107399b742ea157e78aPetr Machata switch ((int) value->type->u.ptr_info.info->type) 612c00837c2928da53a3515b107399b742ea157e78aPetr Machata case ARGTYPE_CHAR: 613c00837c2928da53a3515b107399b742ea157e78aPetr Machata case ARGTYPE_SHORT: 614c00837c2928da53a3515b107399b742ea157e78aPetr Machata case ARGTYPE_USHORT: 615c00837c2928da53a3515b107399b742ea157e78aPetr Machata case ARGTYPE_INT: 616c00837c2928da53a3515b107399b742ea157e78aPetr Machata case ARGTYPE_UINT: 617c00837c2928da53a3515b107399b742ea157e78aPetr Machata case ARGTYPE_LONG: 618c00837c2928da53a3515b107399b742ea157e78aPetr Machata case ARGTYPE_ULONG: 619c00837c2928da53a3515b107399b742ea157e78aPetr Machata return redispatch_as_array(lens, stream, value, 620c00837c2928da53a3515b107399b742ea157e78aPetr Machata arguments, 621c00837c2928da53a3515b107399b742ea157e78aPetr Machata &string_lens_format_cb); 622c00837c2928da53a3515b107399b742ea157e78aPetr Machata 623c00837c2928da53a3515b107399b742ea157e78aPetr Machata /* Otherwise dispatch to whatever the default for the 624c00837c2928da53a3515b107399b742ea157e78aPetr Machata * pointee is--most likely this will again be us. */ 625c00837c2928da53a3515b107399b742ea157e78aPetr Machata /* Fall through. */ 626e3f4a984db115979e09414b7281da98399dd8949Petr Machata case ARGTYPE_VOID: 627e3f4a984db115979e09414b7281da98399dd8949Petr Machata case ARGTYPE_FLOAT: 628e3f4a984db115979e09414b7281da98399dd8949Petr Machata case ARGTYPE_DOUBLE: 629e3f4a984db115979e09414b7281da98399dd8949Petr Machata case ARGTYPE_STRUCT: 630c00837c2928da53a3515b107399b742ea157e78aPetr Machata return toplevel_format_lens(lens, stream, value, 631c00837c2928da53a3515b107399b742ea157e78aPetr Machata arguments, INT_FMT_default); 632c00837c2928da53a3515b107399b742ea157e78aPetr Machata 633e3f4a984db115979e09414b7281da98399dd8949Petr Machata case ARGTYPE_SHORT: 634e3f4a984db115979e09414b7281da98399dd8949Petr Machata case ARGTYPE_INT: 635e3f4a984db115979e09414b7281da98399dd8949Petr Machata case ARGTYPE_LONG: 636e3f4a984db115979e09414b7281da98399dd8949Petr Machata case ARGTYPE_USHORT: 637e3f4a984db115979e09414b7281da98399dd8949Petr Machata case ARGTYPE_UINT: 638e3f4a984db115979e09414b7281da98399dd8949Petr Machata case ARGTYPE_ULONG: 639c00837c2928da53a3515b107399b742ea157e78aPetr Machata if (value->parent != NULL && value->type->lens == NULL) 640c00837c2928da53a3515b107399b742ea157e78aPetr Machata return format_wchar(stream, value, arguments); 641c00837c2928da53a3515b107399b742ea157e78aPetr Machata else 642c00837c2928da53a3515b107399b742ea157e78aPetr Machata return format_naked(stream, value, arguments, 643c00837c2928da53a3515b107399b742ea157e78aPetr Machata &format_wchar); 644e3f4a984db115979e09414b7281da98399dd8949Petr Machata 645e3f4a984db115979e09414b7281da98399dd8949Petr Machata case ARGTYPE_CHAR: 646e3f4a984db115979e09414b7281da98399dd8949Petr Machata return format_char(stream, value, arguments); 647e3f4a984db115979e09414b7281da98399dd8949Petr Machata 648e3f4a984db115979e09414b7281da98399dd8949Petr Machata case ARGTYPE_ARRAY: 649e3f4a984db115979e09414b7281da98399dd8949Petr Machata return format_array(stream, value, arguments, 650e3f4a984db115979e09414b7281da98399dd8949Petr Machata value->type->u.array_info.length, 651e3f4a984db115979e09414b7281da98399dd8949Petr Machata options.strlen, 0, "\"", "\"", ""); 652e3f4a984db115979e09414b7281da98399dd8949Petr Machata } 653e3f4a984db115979e09414b7281da98399dd8949Petr Machata abort(); 654e3f4a984db115979e09414b7281da98399dd8949Petr Machata} 655e3f4a984db115979e09414b7281da98399dd8949Petr Machata 656e3f4a984db115979e09414b7281da98399dd8949Petr Machatastruct lens string_lens = { 657e3f4a984db115979e09414b7281da98399dd8949Petr Machata .format_cb = string_lens_format_cb, 658e3f4a984db115979e09414b7281da98399dd8949Petr Machata}; 659ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata 660ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machatastatic int 661ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machataout_bits(FILE *stream, size_t low, size_t high) 662ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata{ 663ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata if (low == high) 664ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata return fprintf(stream, "%zd", low); 665ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata else 666ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata return fprintf(stream, "%zd-%zd", low, high); 667ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata} 668ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata 669ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machatastatic int 670ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machatabitvect_lens_format_cb(struct lens *lens, FILE *stream, 671ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata struct value *value, struct value_dict *arguments) 672ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata{ 673ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata unsigned char *data = value_get_data(value, arguments); 674ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata if (data == NULL) 675ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata return -1; 676ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata size_t sz = type_sizeof(value->inferior, value->type); 677ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata if (sz == (size_t)-1) 678ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata return -1; 679ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata 680ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata size_t i; 681ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata unsigned char buf[sz]; 682ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata switch ((int)value->type->type) { 683ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata union bitvect_integral_64 684ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata { 685ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata uint8_t u8; 686ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata uint16_t u16; 687ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata uint32_t u32; 688ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata uint64_t u64; 689ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata unsigned char buf[0]; 690ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata } bv; 691ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata 692ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata case ARGTYPE_POINTER: 693ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata return format_pointer(stream, value, arguments); 694ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata 695ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata case ARGTYPE_STRUCT: 696ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata case ARGTYPE_ARRAY: 697ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata break; 698ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata 699ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata default: 700ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata assert(sz <= sizeof(bv)); 701ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata memmove(bv.buf, data, sz); 702ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata 703ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata if (sz == 1) 704ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata bv.u64 = bv.u8; 705ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata else if (sz == 2) 706ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata bv.u64 = bv.u16; 707ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata else if (sz == 4) 708ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata bv.u64 = bv.u32; 709ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata 710ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata for (i = 0; i < sz; ++i) { 711ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata buf[i] = bv.u64 & 0xff; 712ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata bv.u64 >>= 8; 713ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata } 714ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata data = buf; 715ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata } 716ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata 717ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata size_t bits = 0; 718ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata for (i = 0; i < sz; ++i) 719ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata bits += bitcount(data[i]); 720ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata 721ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata /* If there's more 1's than 0's, show inverse. */ 722ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata unsigned neg = bits > sz * 4 ? 0xff : 0x00; 723ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata 724ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata int o = 0; 7256bb420106f77ef8f134a1d4c001668e832f96cc9Andrey Zonov if (acc_fprintf(&o, stream, "%s<", &"~"[neg == 0x00]) < 0) 726ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata return -1; 727ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata 728ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata size_t bitno = 0; 729ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata ssize_t low = -1; 730ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata for (i = 0; i < sz; ++i) { 731ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata unsigned char m; 732ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata unsigned char d = data[i] ^ neg; 733ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata for (m = 0x01; m != 0; m <<= 1) { 734ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata int bit = !!(m & d); 735ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata if (low < 0) { 736ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata if (bit) { 737ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata if (low == -2 738ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata && acc_fprintf(&o, stream, ",") < 0) 739ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata return -1; 740ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata low = bitno; 741ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata } 742ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata } else if (!bit) { 743ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata if (account_output(&o, out_bits(stream, low, 744ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata bitno-1)) < 0) 745ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata return -1; 746ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata low = -2; 747ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata } 748ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata bitno++; 749ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata } 750ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata } 751ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata if (low >= 0 && account_output(&o, out_bits(stream, low, bitno-1)) < 0) 752ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata return -1; 753ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata 754ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata if (fputc('>', stream) < 0) 755ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata return -1; 756ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata o += 1; 757ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata 758ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata return o; 759ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata} 760ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata 761ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machatastruct lens bitvect_lens = { 762ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata .format_cb = bitvect_lens_format_cb, 763ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207Petr Machata}; 764