Upload Tizen:Base source
[framework/base/util-linux-ng.git] / text-utils / odsyntax.c
1 /*-
2  * Copyright (c) 1990 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *      This product includes software developed by the University of
16  *      California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33
34  /* 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
35   * - added Native Language Support
36   */
37
38 #include <sys/types.h>
39 #include <stdlib.h>
40 #include <stdio.h>
41 #include <ctype.h>              /* for isdigit() */
42 #include <unistd.h>             /* for getopt() */
43 #include "hexdump.h"
44 #include "nls.h"
45
46 static void odoffset(int, char ***);
47 static void odprecede(void);
48
49 int deprecated;
50
51 void
52 oldsyntax(int argc, char ***argvp)
53 {
54         int ch;
55         char **argv;
56
57         deprecated = 1;
58         argv = *argvp;
59         while ((ch = getopt(argc, argv, "aBbcDdeFfHhIiLlOoPpswvXx")) != -1)
60                 switch (ch) {
61                 case 'a':
62                         odprecede();
63                         add("16/1 \"%3_u \" \"\\n\"");
64                         break;
65                 case 'B':
66                 case 'o':
67                         odprecede();
68                         add("8/2 \" %06o \" \"\\n\"");
69                         break;
70                 case 'b':
71                         odprecede();
72                         add("16/1 \"%03o \" \"\\n\"");
73                         break;
74                 case 'c':
75                         odprecede();
76                         add("16/1 \"%3_c \" \"\\n\"");
77                         break;
78                 case 'd':
79                         odprecede();
80                         add("8/2 \"  %05u \" \"\\n\"");
81                         break;
82                 case 'D':
83                         odprecede();
84                         add("4/4 \"     %010u \" \"\\n\"");
85                         break;
86                 case 'e':               /* undocumented in od */
87                 case 'F':
88                         odprecede();
89                         add("2/8 \"          %21.14e \" \"\\n\"");
90                         break;
91                         
92                 case 'f':
93                         odprecede();
94                         add("4/4 \" %14.7e \" \"\\n\"");
95                         break;
96                 case 'H':
97                 case 'X':
98                         odprecede();
99                         add("4/4 \"       %08x \" \"\\n\"");
100                         break;
101                 case 'h':
102                 case 'x':
103                         odprecede();
104                         add("8/2 \"   %04x \" \"\\n\"");
105                         break;
106                 case 'I':
107                 case 'L':
108                 case 'l':
109                         odprecede();
110                         add("4/4 \"    %11d \" \"\\n\"");
111                         break;
112                 case 'i':
113                         odprecede();
114                         add("8/2 \" %6d \" \"\\n\"");
115                         break;
116                 case 'O':
117                         odprecede();
118                         add("4/4 \"    %011o \" \"\\n\"");
119                         break;
120                 case 'v':
121                         vflag = ALL;
122                         break;
123                 case 'P':
124                 case 'p':
125                 case 's':
126                 case 'w':
127                 case '?':
128                 default:
129                         fprintf(stderr,
130                             _("od: od(1) has been deprecated for hexdump(1).\n"));
131                         if (ch != '?')
132                                 fprintf(stderr,
133 _("od: hexdump(1) compatibility doesn't support the -%c option%s\n"),
134                                     ch, ch == 's' ? _("; see strings(1).") : ".");
135                         usage();
136                 }
137
138         if (!fshead) {
139                 add("\"%07.7_Ao\n\"");
140                 add("\"%07.7_ao  \" 8/2 \"%06o \" \"\\n\"");
141         }
142
143         argc -= optind;
144         *argvp += optind;
145
146         if (argc)
147                 odoffset(argc, argvp);
148 }
149
150 #define ishexdigit(c) \
151         ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))
152
153 static void
154 odoffset(int argc, char ***argvp)
155 {
156         char *num, *p;
157         int base;
158         char *end;
159
160         /*
161          * The offset syntax of od(1) was genuinely bizarre.  First, if
162          * it started with a plus it had to be an offset.  Otherwise, if
163          * there were at least two arguments, a number or lower-case 'x'
164          * followed by a number makes it an offset.  By default it was
165          * octal; if it started with 'x' or '0x' it was hex.  If it ended
166          * in a '.', it was decimal.  If a 'b' or 'B' was appended, it
167          * multiplied the number by 512 or 1024 byte units.  There was
168          * no way to assign a block count to a hex offset.
169          *
170          * We assume it's a file if the offset is bad.
171          */
172         p = argc == 1 ? (*argvp)[0] : (*argvp)[1];
173         if (!p)
174                 return;
175
176         if (*p != '+' && (argc < 2 ||
177             (!isdigit((unsigned char)p[0]) &&
178              (p[0] != 'x' || !ishexdigit(p[1])))))
179                 return;
180
181         base = 0;
182         /*
183          * skip over leading '+', 'x[0-9a-fA-f]' or '0x', and
184          * set base.
185          */
186         if (p[0] == '+')
187                 ++p;
188         if (p[0] == 'x' && ishexdigit(p[1])) {
189                 ++p;
190                 base = 16;
191         } else if (p[0] == '0' && p[1] == 'x') {
192                 p += 2;
193                 base = 16;
194         }
195
196         /* skip over the number */
197         if (base == 16)
198                 for (num = p; ishexdigit(*p); ++p);
199         else
200                 for (num = p; isdigit((unsigned char)*p); ++p);
201
202         /* check for no number */
203         if (num == p)
204                 return;
205
206         /* if terminates with a '.', base is decimal */
207         if (*p == '.') {
208                 if (base)
209                         return;
210                 base = 10;
211         }
212
213         skip = strtol(num, &end, base ? base : 8);
214
215         /* if end isn't the same as p, we got a non-octal digit */
216         if (end != p) {
217                 skip = 0;
218                 return;
219         }
220
221         if (*p) {
222                 if (*p == 'B') {
223                         skip *= 1024;
224                         p++;
225                 } else if (*p == 'b') {
226                         skip *= 512;
227                         p++;
228                 }
229         }
230
231         if (*p) {
232                 skip = 0;
233                 return;
234         }
235
236         /*
237          * If the offset uses a non-octal base, the base of
238          * the offset is changed as well.  This isn't pretty,
239          * but it's easy.
240          */
241 #define TYPE_OFFSET     7
242         if (base == 16) {
243                 fshead->nextfu->fmt[TYPE_OFFSET] = 'x';
244                 fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'x';
245         } else if (base == 10) {
246                 fshead->nextfu->fmt[TYPE_OFFSET] = 'd';
247                 fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'd';
248         }
249
250         /* Terminate file list. */
251         (*argvp)[1] = NULL;
252 }
253
254 static void
255 odprecede(void)
256 {
257         static int first = 1;
258
259         if (first) {
260                 first = 0;
261                 add("\"%07.7_Ao\n\"");
262                 add("\"%07.7_ao  \"");
263         } else
264                 add("\"         \"");
265 }