libexplain  1.4.D001
libexplain/string_buffer/putc_escaped.c
Go to the documentation of this file.
00001 /*
00002  * libexplain - Explain errno values returned by libc functions
00003  * Copyright (C) 2008-2010, 2013 Peter Miller
00004  * Written by Peter Miller <pmiller@opensource.org.au>
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU Lesser General Public License as
00008  * published by the Free Software Foundation; either version 3 of the
00009  * License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public License
00017  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00018  */
00019 
00020 #include <libexplain/ac/ctype.h>
00021 #include <libexplain/ac/limits.h>
00022 
00023 #include <libexplain/string_buffer.h>
00024 
00025 
00026 void
00027 explain_string_buffer_putc_escaped(explain_string_buffer_t *sb, int c,
00028     int delimiter)
00029 {
00030     if (c == delimiter || c == '\\')
00031     {
00032         explain_string_buffer_putc(sb, '\\');
00033         explain_string_buffer_putc(sb, c);
00034         return;
00035     }
00036     switch (c)
00037     {
00038     case '\a':
00039         explain_string_buffer_puts(sb, "\\a");
00040         break;
00041 
00042     case '\b':
00043         explain_string_buffer_puts(sb, "\\b");
00044         break;
00045 
00046     case '\f':
00047         explain_string_buffer_puts(sb, "\\f");
00048         break;
00049 
00050     case '\n':
00051         explain_string_buffer_puts(sb, "\\n");
00052         break;
00053 
00054     case '\r':
00055         explain_string_buffer_puts(sb, "\\r");
00056         break;
00057 
00058     case '\t':
00059         explain_string_buffer_puts(sb, "\\t");
00060         break;
00061 
00062     case '\v':
00063         explain_string_buffer_puts(sb, "\\v");
00064         break;
00065 
00066     case ' ':
00067     case '!':
00068     case '"':
00069     case '#':
00070     case '$':
00071     case '%':
00072     case '&':
00073     case '\'':
00074     case '(':
00075     case ')':
00076     case '*':
00077     case '+':
00078     case ',':
00079     case '-':
00080     case '.':
00081     case '/':
00082     case '0':
00083     case '1':
00084     case '2':
00085     case '3':
00086     case '4':
00087     case '5':
00088     case '6':
00089     case '7':
00090     case '8':
00091     case '9':
00092     case ':':
00093     case ';':
00094     case '<':
00095     case '=':
00096     case '>':
00097     case '?':
00098     case '@':
00099     case 'A':
00100     case 'B':
00101     case 'C':
00102     case 'D':
00103     case 'E':
00104     case 'F':
00105     case 'G':
00106     case 'H':
00107     case 'I':
00108     case 'J':
00109     case 'K':
00110     case 'L':
00111     case 'M':
00112     case 'N':
00113     case 'O':
00114     case 'P':
00115     case 'Q':
00116     case 'R':
00117     case 'S':
00118     case 'T':
00119     case 'U':
00120     case 'V':
00121     case 'W':
00122     case 'X':
00123     case 'Y':
00124     case 'Z':
00125     case '[':
00126     case '\\':
00127     case ']':
00128     case '^':
00129     case '_':
00130     case '`':
00131     case 'a':
00132     case 'b':
00133     case 'c':
00134     case 'd':
00135     case 'e':
00136     case 'f':
00137     case 'g':
00138     case 'h':
00139     case 'i':
00140     case 'j':
00141     case 'k':
00142     case 'l':
00143     case 'm':
00144     case 'n':
00145     case 'o':
00146     case 'p':
00147     case 'q':
00148     case 'r':
00149     case 's':
00150     case 't':
00151     case 'u':
00152     case 'v':
00153     case 'w':
00154     case 'x':
00155     case 'y':
00156     case 'z':
00157     case '{':
00158     case '|':
00159     case '}':
00160     case '~':
00161         printable:
00162         explain_string_buffer_putc(sb, c);
00163         break;
00164 
00165     default:
00166         /* this test will be locale specific */
00167         if (isprint((unsigned char)c))
00168             goto printable;
00169 
00170         /*
00171          * We can't use "\\%03o" or "\\%3.3o" or "\\%03.3o" here because
00172          * different systems interpret them differently.  One or the
00173          * other is often space padded rather than zero padded.
00174          * So we convert the value ourselves.
00175          */
00176         explain_string_buffer_putc(sb, '\\');
00177         if (CHAR_BIT > 8)
00178             explain_string_buffer_putc(sb, ((c >> 6) & 7) + '0');
00179         else
00180             explain_string_buffer_putc(sb, ((c >> 6) & 3) + '0');
00181         explain_string_buffer_putc(sb, ((c >> 3) & 7) + '0');
00182         explain_string_buffer_putc(sb, (c & 7) + '0');
00183         break;
00184     }
00185 }
00186 
00187 
00188 /* vim: set ts=8 sw=4 et : */