The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/boot/common/interp_backslash.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Redistribution and use in source and binary forms, with or without
    3  * modification, are permitted provided that the following conditions
    4  * are met:
    5  * 1. Redistributions of source code must retain the above copyright
    6  *    notice, this list of conditions and the following disclaimer.
    7  * 2. Redistributions in binary form must reproduce the above copyright
    8  *    notice, this list of conditions and the following disclaimer in the
    9  *    documentation and/or other materials provided with the distribution.
   10  *
   11  * Jordan K. Hubbard
   12  * 29 August 1998
   13  *
   14  * Routine for doing backslash elimination.
   15  */
   16 
   17 #include <sys/cdefs.h>
   18 __FBSDID("$FreeBSD: releng/8.2/sys/boot/common/interp_backslash.c 119483 2003-08-25 23:30:41Z obrien $");
   19 
   20 #include <stand.h>
   21 #include <string.h>
   22 #include "bootstrap.h"
   23 
   24 #define DIGIT(x) (isdigit(x) ? (x) - '' : islower(x) ? (x) + 10 - 'a' : (x) + 10 - 'A')
   25 
   26 /*
   27  * backslash: Return malloc'd copy of str with all standard "backslash
   28  * processing" done on it.  Original can be free'd if desired.
   29  */
   30 char *
   31 backslash(char *str)
   32 {
   33     /*
   34      * Remove backslashes from the strings. Turn \040 etc. into a single
   35      * character (we allow eight bit values). Currently NUL is not
   36      * allowed.
   37      *
   38      * Turn "\n" and "\t" into '\n' and '\t' characters. Etc.
   39      *
   40      */
   41     char *new_str;
   42     int seenbs = 0;
   43     int i = 0;
   44 
   45     if ((new_str = strdup(str)) == NULL)
   46         return NULL;
   47 
   48     while (*str) {
   49         if (seenbs) {
   50             seenbs = 0;
   51             switch (*str) {
   52             case '\\':
   53                 new_str[i++] = '\\';
   54                 str++;
   55                 break;
   56 
   57             /* preserve backslashed quotes, dollar signs */
   58             case '\'':
   59             case '"':
   60             case '$':
   61                 new_str[i++] = '\\';
   62                 new_str[i++] = *str++;
   63                 break;
   64 
   65             case 'b':
   66                 new_str[i++] = '\b';
   67                 str++;
   68                 break;
   69 
   70             case 'f':
   71                 new_str[i++] = '\f';
   72                 str++;
   73                 break;
   74 
   75             case 'r':
   76                 new_str[i++] = '\r';
   77                 str++;
   78                 break;
   79 
   80             case 'n':
   81                 new_str[i++] = '\n';
   82                 str++;
   83                 break;
   84 
   85             case 's':
   86                 new_str[i++] = ' ';
   87                 str++;
   88                 break;
   89 
   90             case 't':
   91                 new_str[i++] = '\t';
   92                 str++;
   93                 break;
   94 
   95             case 'v':
   96                 new_str[i++] = '\13';
   97                 str++;
   98                 break;
   99 
  100             case 'z':
  101                 str++;
  102                 break;
  103 
  104             case '': case '1': case '2': case '3': case '4':
  105             case '5': case '6': case '7': case '8': case '9': {
  106                 char val;
  107 
  108                 /* Three digit octal constant? */
  109                 if (*str >= '' && *str <= '3' && 
  110                     *(str + 1) >= '' && *(str + 1) <= '7' &&
  111                     *(str + 2) >= '' && *(str + 2) <= '7') {
  112 
  113                     val = (DIGIT(*str) << 6) + (DIGIT(*(str + 1)) << 3) + 
  114                         DIGIT(*(str + 2));
  115 
  116                     /* Allow null value if user really wants to shoot
  117                        at feet, but beware! */
  118                     new_str[i++] = val;
  119                     str += 3;
  120                     break;
  121                 }
  122 
  123                 /* One or two digit hex constant?
  124                  * If two are there they will both be taken.
  125                  * Use \z to split them up if this is not wanted.
  126                  */
  127                 if (*str == '' &&
  128                     (*(str + 1) == 'x' || *(str + 1) == 'X') &&
  129                     isxdigit(*(str + 2))) {
  130                     val = DIGIT(*(str + 2));
  131                     if (isxdigit(*(str + 3))) {
  132                         val = (val << 4) + DIGIT(*(str + 3));
  133                         str += 4;
  134                     }
  135                     else
  136                         str += 3;
  137                     /* Yep, allow null value here too */
  138                     new_str[i++] = val;
  139                     break;
  140                 }
  141             }
  142             break;
  143 
  144             default:
  145                 new_str[i++] = *str++;
  146                 break;
  147             }
  148         }
  149         else {
  150             if (*str == '\\') {
  151                 seenbs = 1;
  152                 str++;
  153             }
  154             else
  155                 new_str[i++] = *str++;
  156         }
  157     }
  158 
  159     if (seenbs) {
  160         /*
  161          * The final character was a '\'. Put it in as a single backslash.
  162          */
  163         new_str[i++] = '\\';
  164     }
  165     new_str[i] = '\0';
  166     return new_str;
  167 }

Cache object: 262eb4bc9346107e894cf9254a1cc2ad


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.