blob: 28b1e3697ba80314962569e5617b56cc07cd2c79 [file] [log] [blame]
Eric Andersenaad1a882001-03-16 22:47:14 +00001/* vi: set sw=4 ts=4: */
2/*
3 * Utility routines.
4 *
Manuel Novoa III cad53642003-03-19 09:13:01 +00005 * Copyright (C) Manuel Novoa III <mjn3@codepoet.org>
Glenn L McGrathb4a1baa2003-01-13 22:09:50 +00006 * and Vladimir Oleynik <dzo@simtreas.ru>
Eric Andersenaad1a882001-03-16 22:47:14 +00007 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
Eric Andersenc7bda1c2004-03-15 08:29:22 +000022 *
Eric Andersenaad1a882001-03-16 22:47:14 +000023 */
24
25#include <stdio.h>
26#include <limits.h>
Eric Andersenb2a30052004-07-26 12:11:32 +000027#include <ctype.h>
Eric Andersenaad1a882001-03-16 22:47:14 +000028#include "libbb.h"
29
Manuel Novoa III 413db4d2004-07-29 23:15:16 +000030#define WANT_HEX_ESCAPES 1
31
32/* Usual "this only works for ascii compatible encodings" disclaimer. */
33#undef _tolower
34#define _tolower(X) ((X)|((char) 0x20))
35
Manuel Novoa III cad53642003-03-19 09:13:01 +000036char bb_process_escape_sequence(const char **ptr)
Eric Andersenaad1a882001-03-16 22:47:14 +000037{
Eric Andersene5dfced2001-04-09 22:48:12 +000038 static const char charmap[] = {
39 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', 0,
40 '\a', '\b', '\f', '\n', '\r', '\t', '\v', '\\', '\\' };
Eric Andersenaad1a882001-03-16 22:47:14 +000041
Manuel Novoa III 413db4d2004-07-29 23:15:16 +000042 const char *p;
43 const char *q;
44 unsigned int num_digits;
45 unsigned int r;
46 unsigned int n;
47 unsigned int d;
48 unsigned int base;
49
50 num_digits = n = 0;
51 base = 8;
Eric Andersene5dfced2001-04-09 22:48:12 +000052 q = *ptr;
Eric Andersenaad1a882001-03-16 22:47:14 +000053
Manuel Novoa III 413db4d2004-07-29 23:15:16 +000054#ifdef WANT_HEX_ESCAPES
Eric Andersenb2a30052004-07-26 12:11:32 +000055 if (*q == 'x') {
Eric Andersenb2a30052004-07-26 12:11:32 +000056 ++q;
Manuel Novoa III 413db4d2004-07-29 23:15:16 +000057 base = 16;
58 ++num_digits;
Eric Andersenb2a30052004-07-26 12:11:32 +000059 }
Manuel Novoa III 413db4d2004-07-29 23:15:16 +000060#endif
Eric Andersenb2a30052004-07-26 12:11:32 +000061
Manuel Novoa III cad53642003-03-19 09:13:01 +000062 do {
Manuel Novoa III 413db4d2004-07-29 23:15:16 +000063 d = (unsigned int)(*q - '0');
64#ifdef WANT_HEX_ESCAPES
65 if (d >= 10) {
66 d = ((unsigned int)(_tolower(*q) - 'a')) + 10;
67 }
68#endif
69
70 if (d >= base) {
71#ifdef WANT_HEX_ESCAPES
72 if ((base == 16) && (!--num_digits)) {
73/* return '\\'; */
74 --q;
75 }
76#endif
Eric Andersenccfc4482004-07-27 16:45:46 +000077 break;
Eric Andersenb2a30052004-07-26 12:11:32 +000078 }
Manuel Novoa III 413db4d2004-07-29 23:15:16 +000079
80 r = n * base + d;
81 if (r > UCHAR_MAX) {
82 break;
Eric Andersene5dfced2001-04-09 22:48:12 +000083 }
Manuel Novoa III 413db4d2004-07-29 23:15:16 +000084
85 n = r;
86 ++q;
87 } while (++num_digits < 3);
Eric Andersenaad1a882001-03-16 22:47:14 +000088
Eric Andersene5dfced2001-04-09 22:48:12 +000089 if (num_digits == 0) { /* mnemonic escape sequence? */
Manuel Novoa III cad53642003-03-19 09:13:01 +000090 p = charmap;
91 do {
Eric Andersene5dfced2001-04-09 22:48:12 +000092 if (*p == *q) {
93 q++;
94 break;
95 }
Manuel Novoa III cad53642003-03-19 09:13:01 +000096 } while (*++p);
Eric Andersene5dfced2001-04-09 22:48:12 +000097 n = *(p+(sizeof(charmap)/2));
98 }
Eric Andersenaad1a882001-03-16 22:47:14 +000099
Eric Andersene5dfced2001-04-09 22:48:12 +0000100 *ptr = q;
Manuel Novoa III 413db4d2004-07-29 23:15:16 +0000101
Eric Andersene5dfced2001-04-09 22:48:12 +0000102 return (char) n;
Eric Andersenaad1a882001-03-16 22:47:14 +0000103}
104
Eric Andersenaad1a882001-03-16 22:47:14 +0000105/* END CODE */
106/*
107Local Variables:
108c-file-style: "linux"
109c-basic-offset: 4
110tab-width: 4
111End:
112*/