Line data Source code
1 : /* Copyright 1989-2020 Free Software Foundation, Inc. 2 : Written by James Clark (jjc@jclark.com) 3 : 4 : This file is part of groff, the GNU roff typesetting system. 5 : 6 : groff is free software; you can redistribute it and/or modify it under 7 : the terms of the GNU General Public License as published by the Free 8 : Software Foundation, either version 3 of the License, or 9 : (at your option) any later version. 10 : 11 : groff is distributed in the hope that it will be useful, but WITHOUT ANY 12 : WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 : for more details. 15 : 16 : You should have received a copy of the GNU General Public License 17 : along with this program. If not, see <http://www.gnu.org/licenses/>. */ 18 : 19 : #ifdef HAVE_CONFIG_H 20 : #include <config.h> 21 : #endif 22 : 23 : #include <assert.h> 24 : #include <stdio.h> 25 : 26 : #include "errarg.h" 27 : 28 28708 : errarg::errarg(const char *p) : type(STRING) 29 : { 30 28708 : s = p ? p : "(null)"; 31 28708 : } 32 : 33 4334 : errarg::errarg() : type(EMPTY) 34 : { 35 4334 : } 36 : 37 427 : errarg::errarg(int nn) : type(INTEGER) 38 : { 39 427 : n = nn; 40 427 : } 41 : 42 9 : errarg::errarg(unsigned int uu) : type(UNSIGNED_INTEGER) 43 : { 44 9 : u = uu; 45 9 : } 46 : 47 212 : errarg::errarg(char cc) : type(CHAR) 48 : { 49 212 : c = cc; 50 212 : } 51 : 52 0 : errarg::errarg(unsigned char cc) : type(CHAR) 53 : { 54 0 : c = cc; 55 0 : } 56 : 57 40 : errarg::errarg(double dd) : type(DOUBLE) 58 : { 59 40 : d = dd; 60 40 : } 61 : 62 1442 : int errarg::empty() const 63 : { 64 1442 : return type == EMPTY; 65 : } 66 : 67 : extern "C" { 68 : const char *i_to_a(int); 69 : const char *ui_to_a(unsigned int); 70 : } 71 : 72 1442 : void errarg::print() const 73 : { 74 1442 : switch (type) { 75 418 : case INTEGER: 76 418 : fputs(i_to_a(n), stderr); 77 418 : break; 78 9 : case UNSIGNED_INTEGER: 79 9 : fputs(ui_to_a(u), stderr); 80 9 : break; 81 74 : case CHAR: 82 74 : putc(c, stderr); 83 74 : break; 84 908 : case STRING: 85 908 : fputs(s, stderr); 86 908 : break; 87 33 : case DOUBLE: 88 33 : fprintf(stderr, "%g", d); 89 33 : break; 90 0 : case EMPTY: 91 0 : break; 92 : } 93 1442 : } 94 : 95 : errarg empty_errarg; 96 : 97 1097 : void errprint(const char *format, 98 : const errarg &arg1, 99 : const errarg &arg2, 100 : const errarg &arg3) 101 : { 102 1097 : assert(format != 0 /* nullptr */); 103 : char c; 104 18622 : while ((c = *format++) != '\0') { 105 17525 : if (c == '%') { 106 1442 : c = *format++; 107 1442 : switch(c) { 108 0 : case '%': 109 0 : fputc('%', stderr); 110 0 : break; 111 978 : case '1': 112 978 : assert(!arg1.empty()); 113 978 : arg1.print(); 114 978 : break; 115 403 : case '2': 116 403 : assert(!arg2.empty()); 117 403 : arg2.print(); 118 403 : break; 119 61 : case '3': 120 61 : assert(!arg3.empty()); 121 61 : arg3.print(); 122 61 : break; 123 0 : default: 124 0 : assert(0 == "unsupported argument conversion (not in [%123])"); 125 : } 126 : } 127 : else 128 16083 : putc(c, stderr); 129 : } 130 1097 : } 131 : 132 : // Local Variables: 133 : // fill-column: 72 134 : // mode: C++ 135 : // End: 136 : // vim: set cindent noexpandtab shiftwidth=2 textwidth=72: