(root)/
glibc-2.38/
support/
support_quote_blob_main.c
       1  /* Quote a blob so that it can be used in C literals.
       2     Copyright (C) 2018-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <support/support.h>
      20  #include <support/xmemstream.h>
      21  
      22  char *
      23  SUPPORT_QUOTE_BLOB (const void *blob, size_t length)
      24  {
      25    struct xmemstream out;
      26    xopen_memstream (&out);
      27  
      28    const CHAR *p = blob;
      29    for (size_t i = 0; i < length; ++i)
      30      {
      31        CHAR ch = p[i];
      32  
      33        /* Use C backslash escapes for those control characters for
      34  	 which they are defined.  */
      35        switch (ch)
      36  	{
      37  	case L_('\a'):
      38  	  putc_unlocked ('\\', out.out);
      39  	  putc_unlocked ('a', out.out);
      40  	  break;
      41  	case L_('\b'):
      42  	  putc_unlocked ('\\', out.out);
      43  	  putc_unlocked ('b', out.out);
      44  	  break;
      45  	case L_('\f'):
      46  	  putc_unlocked ('\\', out.out);
      47  	  putc_unlocked ('f', out.out);
      48  	  break;
      49  	case L_('\n'):
      50  	  putc_unlocked ('\\', out.out);
      51  	  putc_unlocked ('n', out.out);
      52  	  break;
      53  	case L_('\r'):
      54  	  putc_unlocked ('\\', out.out);
      55  	  putc_unlocked ('r', out.out);
      56  	  break;
      57  	case L_('\t'):
      58  	  putc_unlocked ('\\', out.out);
      59  	  putc_unlocked ('t', out.out);
      60  	  break;
      61  	case L_('\v'):
      62  	  putc_unlocked ('\\', out.out);
      63  	  putc_unlocked ('v', out.out);
      64  	  break;
      65  	case L_('\\'):
      66  	case L_('\''):
      67  	case L_('\"'):
      68  	  putc_unlocked ('\\', out.out);
      69  	  putc_unlocked (ch, out.out);
      70  	  break;
      71  	default:
      72  	  if (ch < L_(' ') || ch > L_('~'))
      73  	    /* For narrow characters, use octal sequences because they
      74  	       are fixed width, unlike hexadecimal sequences.  For
      75  	       wide characters, use N2785 delimited escape
      76  	       sequences.  */
      77  	    if (WIDE)
      78  	      fprintf (out.out, "\\x{%x}", (unsigned int) ch);
      79  	    else
      80  	      fprintf (out.out, "\\%03o", (unsigned int) ch);
      81  	  else
      82  	    putc_unlocked (ch, out.out);
      83  	}
      84      }
      85  
      86    xfclose_memstream (&out);
      87    return out.buffer;
      88  }