Some fix for scrolling with lasso.
[tangerine.git] / workbench / c / Type.c
blobbd807c1e41e8b6ebbae4dbf17866d7b4f5ee88c1
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Type CLI command
6 Lang: English
7 */
9 /******************************************************************************
11 NAME
13 Type {<file | pattern>} [TO <name>] [OPT H | N] [HEX | NUMBER]
15 SYNOPSIS
17 FROM/A/M,TO/K,OPT/K,HEX/S,NUMBER/S
19 LOCATION
21 Workbench:C
23 FUNCTION
25 Displays content of a file
27 INPUTS
29 FROM -- one or more files to display
30 TO -- print output to file
31 OPT -- H or N (see HEX or NUMBER)
32 HEX -- displays output in hexadecimal format
33 NUMBER -- the lines are numbered
34 HEX and NUMBER are mutually exclusive
36 RESULT
38 NOTES
40 EXAMPLE
42 type abc.txt
43 type xyz.dat hex
45 BUGS
47 SEE ALSO
49 INTERNALS
51 HISTORY
53 ******************************************************************************/
55 #include <exec/memory.h>
56 #include <exec/execbase.h>
57 #include <proto/exec.h>
58 #include <proto/dos.h>
59 #include <dos/dos.h>
61 #include <string.h>
63 static const char version[] = "$VER: Type 42.0 (20.10.2005)\n";
65 #define BUFSIZE 8192
66 #define MAX_PATH_LEN 512
68 enum
70 ARG_FROM = 0,
71 ARG_TO,
72 ARG_OPT,
73 ARG_HEX,
74 ARG_NUMBER,
75 NUMARGS
78 struct file
80 BPTR fd;
81 UBYTE *cur;
82 ULONG cnt;
83 LONG error;
84 UBYTE buf[BUFSIZE];
87 const UBYTE hs[16]="0123456789abcdef";
89 #define putc(f,c) (*(f)->cur++=(c),--(f)->cnt?0:put(f))
90 static int put(struct file *f)
92 LONG size,subsize;
93 STRPTR buf;
94 size=f->cur-f->buf;
95 buf=f->buf;
96 while(size)
98 subsize=Write(f->fd,buf,size);
99 if(subsize<=0)
101 f->error=IoErr();
102 return 1;
104 buf+=subsize;
105 size-=subsize;
107 f->cur=f->buf;
108 f->cnt=BUFSIZE;
109 return 0;
112 #define getc(f) ((f)->cnt--?*(f)->cur++:get(f))
113 static int get(struct file *f)
115 LONG size;
116 size=Read(f->fd,f->buf,BUFSIZE);
117 if(size<0)
118 f->error=IoErr();
119 if(size<=0)
120 return -1;
121 f->cnt=size-1;
122 f->cur=f->buf;
123 return *f->cur++;
126 static void putlinequick(struct file *f, ULONG offset, UBYTE *buf)
128 int c, i, k;
129 UBYTE *b, *o;
130 o=f->cur;
131 if(offset>=0x10000)
133 if(offset>=0x100000)
135 if(offset>=0x1000000)
137 if(offset>=0x10000000)
139 *o++=hs[(offset>>28)&0xf];
140 f->cnt--;
142 *o++=hs[(offset>>24)&0xf];
143 f->cnt--;
145 *o++=hs[(offset>>20)&0xf];
146 f->cnt--;
148 *o++=hs[(offset>>16)&0xf];
149 f->cnt--;
151 *o++=hs[(offset>>12)&0xf];
152 *o++=hs[(offset>>8)&0xf];
153 *o++=hs[(offset>>4)&0xf];
154 *o++=hs[offset&0xf];
155 *o++=':';
156 *o++=' ';
157 b=buf;
158 for(i=0;i<4;i++)
160 for(k=0;k<4;k++)
162 c=*b++;
163 *o++=hs[c>>4];
164 *o++=hs[c&0xf];
166 *o++=' ';
168 b=buf;
169 for(i=0;i<16;i++)
171 c=*b++;
172 *o++=(c&0x7f)>=0x20&&c!=0x7f?c:'.';
174 *o++='\n';
175 f->cur=o;
176 f->cnt-=59;
179 static int putline(struct file *f, ULONG offset, UBYTE *buf, ULONG num)
181 int c, i;
182 UBYTE *b;
183 if(offset>=0x10000)
185 if(offset>=0x10000000&&putc(f,hs[(offset>>28)&0xf]))
186 return 1;
187 if(offset>=0x1000000&&putc(f,hs[(offset>>24)&0xf]))
188 return 1;
189 if(offset>=0x100000&&putc(f,hs[(offset>>20)&0xf]))
190 return 1;
191 if(offset>=0x10000&&putc(f,hs[(offset>>16)&0xf]))
192 return 1;
194 if(putc(f,hs[(offset>>12)&0xf]))
195 return 1;
196 if(putc(f,hs[(offset>>8)&0xf]))
197 return 1;
198 if(putc(f,hs[(offset>>4)&0xf]))
199 return 1;
200 if(putc(f,hs[offset&0xf]))
201 return 1;
202 if(putc(f,':'))
203 return 1;
204 if(putc(f,' '))
205 return 1;
206 b=buf;
207 for(i=0;i<16;i++)
209 if(i<num)
211 c=*b++;
212 if(putc(f,hs[c>>4]))
213 return 1;
214 if(putc(f,hs[c&0xf]))
215 return 1;
216 }else
218 if(putc(f,' '))
219 return 1;
220 if(putc(f,' '))
221 return 1;
223 if((i&3)==3)
224 if(putc(f,' '))
225 return 1;
227 b=buf;
228 for(i=0;i<num;i++)
230 c=*b++;
231 if(putc(f,(c&0x7f)>=0x20&&c!=0x7f?c:'.'))
232 return 1;
234 if(putc(f,'\n'))
235 return 1;
236 return 0;
239 LONG hexdumpfile(struct file *in, struct file *out)
241 UBYTE buf[16];
242 UBYTE *b;
243 LONG offset=0, n, c, tty;
244 LONG retval = RETURN_OK;
246 tty=IsInteractive(out->fd);
247 for(;;)
249 if(in->cnt>16)
251 b=in->cur;
252 n=16;
253 in->cur+=16;
254 in->cnt-=16;
255 }else
257 b=buf;
258 for(n=0;n<16;n++)
260 c=getc(in);
261 if(c<0)
263 break;
265 b[n]=c;
268 if(n==16)
270 if(out->cnt>=63)
271 putlinequick(out,offset,b);
272 else
273 if(putline(out,offset,b,n))
275 retval = RETURN_ERROR;
276 break;
278 }else
280 if(n)
281 putline(out,offset,b,n);
282 if(out->cur!=out->buf)
283 put(out);
284 break;
286 if(tty)
287 if(put(out))
289 retval = RETURN_ERROR;
290 break;
292 offset+=n;
294 if (CheckSignal(SIGBREAKF_CTRL_C))
296 retval = RETURN_WARN;
297 break;
301 return retval;
305 void putlinenumber(struct file * out, unsigned short line)
307 int x = 10000;
308 BOOL s = FALSE;
310 while (x)
312 if (line / x || s)
314 putc(out, line/x+'0');
315 line %= x;
316 s = TRUE;
318 else
319 putc(out, ' ');
321 x/=10;
324 putc(out, ' ');
327 LONG dumpfile(struct file *in, struct file *out, BOOL showline)
329 LONG c, lastc = 0;
330 unsigned short line = 0;
331 LONG retval = RETURN_OK;
333 if (showline)
334 putlinenumber(out, ++line);
336 if(1/*IsInteractive(out->fd)*/)
337 for(;;)
339 c=getc(in);
341 if(c<0)
343 if (lastc!='\n')
344 putc(out, '\n');
346 put(out);
347 break;
350 if (lastc==0x0a && showline)
351 putlinenumber(out, ++line);
353 if(putc(out,c)||(c=='\n' && put(out)))
355 if (c!='\n')
356 putc(out, '\n');
358 put(out);
359 retval = RETURN_ERROR;
360 break;
363 if ((c == '\n') && CheckSignal(SIGBREAKF_CTRL_C))
365 retval = RETURN_WARN;
366 break;
368 lastc = c;
371 return retval;
374 static LONG processfile(CONST_STRPTR name, struct file *in, struct file *out, IPTR *args, LONG *numfiles)
376 LONG error = 0;
378 in->fd = Open(name, MODE_OLDFILE);
379 if (in->fd)
381 (*numfiles)++;
382 in->cnt = 0;
384 if (args[2])
385 error = hexdumpfile(in, out);
386 else
387 error = dumpfile(in, out, args[3]);
389 Close(in->fd);
391 else
392 error = IoErr();
394 return error;
397 int __nocommandline;
399 struct MyAnchorPath
401 struct AnchorPath apath;
402 UBYTE buf[MAX_PATH_LEN - 1];
405 int main (void)
407 IPTR args[5]={ 0, 0, 0, 0, 0 };
408 struct RDArgs *rda;
409 struct file *in, *out;
410 STRPTR *names;
411 int retval = RETURN_OK;
412 struct MyAnchorPath apath;
414 rda=ReadArgs("FROM/A/M,TO/K,OPT/K,HEX/S,NUMBER/S",args,NULL);
415 if(rda==NULL)
417 PrintFault(IoErr(),"Type");
418 return RETURN_FAIL;
420 names=(STRPTR *)args[0];
422 in =AllocMem(sizeof(struct file),MEMF_ANY);
423 out=AllocMem(sizeof(struct file),MEMF_ANY);
425 if(in!=NULL&&out!=NULL)
427 out->cur=out->buf;
428 out->cnt=BUFSIZE;
429 apath.apath.ap_BreakBits = SIGBREAKF_CTRL_C;
430 apath.apath.ap_FoundBreak = 0;
431 apath.apath.ap_Flags = 0;
432 apath.apath.ap_Strlen = MAX_PATH_LEN;
433 if (args[1])
434 out->fd = Open((STRPTR) args[1], MODE_NEWFILE);
435 else
436 out->fd=Output();
437 if (out->fd)
439 while(*names!=NULL)
441 ULONG numfiles = 0;
442 LONG error;
444 for (error = MatchFirst(*names, &apath.apath);
445 !error;
446 error = MatchNext(&apath.apath))
448 error = processfile(apath.apath.ap_Buf, in, out, args, &numfiles);
449 if (error)
450 break;
452 MatchEnd(&apath.apath);
454 if (numfiles == 0 && error == ERROR_NO_MORE_ENTRIES)
456 error = -1;
459 if (error && error != ERROR_NO_MORE_ENTRIES)
461 if (*names && error != ERROR_BREAK)
463 Printf("TYPE: can't open %s\n", (LONG) *names);
466 if (error != -1)
468 PrintFault(error, NULL);
469 SetIoErr(error);
472 break;
474 names++;
477 if (args[ARG_TO])
478 Close(out->fd);
480 /* If all files got dumped, return ok, else error.
482 retval = *names ? RETURN_ERROR : RETURN_OK;
483 } else
485 PrintFault(IoErr(), NULL);
487 }else
489 PrintFault(ERROR_NO_FREE_STORE,"Type");
490 retval = RETURN_ERROR;
493 if(in!=NULL)
494 FreeMem(in,sizeof(struct file));
495 if(out!=NULL)
496 FreeMem(out,sizeof(struct file));
497 if(rda!=NULL)
498 FreeArgs(rda);
500 return retval;