Don't call InvertPixelArray with negative width and/or height.
[tangerine.git] / workbench / c / Join.c
blob2423b5b0032fdde13ccc413f11fb9cc9c7063f8c
1 /*
2 Copyright © 1995-2004, The AROS Development Team. All rights reserved.
3 $Id$
5 Join - Create a single file from several.
6 */
8 /******************************************************************************
11 NAME
13 Join [FILE] {(file | pattern)} AS|TO (filename)
15 SYNOPSIS
17 FILE/M/A,AS=TO/K/A
19 LOCATION
21 Workbench:C
23 FUNCTION
25 Join makes one big file of all listed files by putting them together
26 in the order given. The destination file may not have the same name
27 as any of input files. You must supply a destination file name. The
28 original files remian unchanged. Any number of files can be Join:ed in
29 one operation.
31 INPUTS
33 FILE -- files to join
34 TO=AS -- the name of the combined file
36 RESULT
38 NOTES
40 EXAMPLE
42 BUGS
44 SEE ALSO
46 INTERNALS
48 ******************************************************************************/
50 #define DEBUG 0
51 #include <aros/debug.h>
53 #include <exec/types.h>
54 #include <exec/memory.h>
55 #include <dos/dos.h>
56 #include <dos/dosasl.h>
58 #include <proto/exec.h>
59 #include <proto/dos.h>
61 #define ARG_TEMPLATE "FILE/M/A,AS=TO/K/A"
62 #define ARG_FILE 0
63 #define ARG_AS 1
64 #define ARG_COUNT 2
66 #define BUFFERSIZE 32768 /* Buffersize used when reading & writing */
68 /****** StringID's for getstring() **************************************/
70 #define STR_ABORTED 1 /* Aborted */
71 #define STR_REMOVINGDEST 2 /* Removing destination-file */
72 #define STR_ERR_OPENREAD 3 /* Error opening file for reading */
73 #define STR_ERR_NOMEM 4 /* Error allocating memory */
74 #define STR_ERR_WRITING 5 /* Error while writing to file */
75 #define STR_ERR_OPENWRITE 6 /* Error opening file for writing */
76 #define STR_ERR_READING 7 /* Error while reading from file */
78 /****** Version- and error-header ***************************************/
80 static const char version[] = "$VER: Join 41.1 (07.09.1999)";
81 static char ERROR_HEADER[] = "Join";
83 /****** Prototypes for local functions **********************************/
85 LONG append( BPTR destfile , STRPTR srcfilename );
86 STRPTR getstring( LONG stringid );
87 int doJoin(STRPTR *files, BPTR destfile);
89 /****** Functions *******************************************************/
91 int main( void )
93 struct RDArgs *rda = NULL ;
95 IPTR args[ARG_COUNT] = { (IPTR) NULL , (IPTR) NULL };
96 STRPTR *files;
97 STRPTR destination;
98 BPTR destfile = NULL;
99 LONG rc = RETURN_OK;
101 if( (rda = ReadArgs( ARG_TEMPLATE , args , NULL )) )
103 if( args[ARG_FILE] && args[ARG_AS] )
105 destination = (STRPTR)args[ARG_AS];
106 files = (STRPTR *)args[ARG_FILE];
108 if( (destfile = Open( destination , MODE_NEWFILE )) )
110 rc = doJoin(files, destfile);
111 Close(destfile);
112 if (rc != RETURN_OK)
114 Printf(", %s.\n", getstring(STR_REMOVINGDEST));
115 DeleteFile(destination);
118 else
120 PrintFault(IoErr() , ERROR_HEADER);
121 rc = RETURN_FAIL;
124 else
126 rc = RETURN_FAIL;
129 FreeArgs(rda);
131 else
133 PrintFault(IoErr(), ERROR_HEADER);
134 rc = RETURN_FAIL;
137 return rc;
141 #define MAX_PATH_LEN 512
144 int doJoin(STRPTR *files, BPTR destfile)
146 struct AnchorPath *ap;
148 LONG i; /* Loop variable over patterns */
149 LONG match; /* Loop variable over files */
150 LONG rc = RETURN_OK;
151 ULONG numfiles;
153 ap = (struct AnchorPath *)AllocVec(sizeof(struct AnchorPath) +
154 MAX_PATH_LEN, MEMF_CLEAR);
156 if (ap == NULL)
158 SetIoErr(ERROR_NO_FREE_STORE);
159 return RETURN_FAIL;
162 ap->ap_Strlen = MAX_PATH_LEN;
164 /* Loop over the arguments */
165 for (i = 0; files[i] != NULL; i++)
167 ap->ap_BreakBits = SIGBREAKF_CTRL_C;
168 ap->ap_FoundBreak = 0;
169 numfiles = 0;
170 for (match = MatchFirst(files[i], ap); match == 0;
171 match = MatchNext(ap))
173 if(append(destfile, ap->ap_Buf) != RETURN_OK )
175 Printf("%s: %s", ERROR_HEADER, getstring(STR_ABORTED));
176 rc = RETURN_FAIL;
177 break;
179 numfiles++;
182 MatchEnd(ap);
183 if (ap->ap_FoundBreak & SIGBREAKF_CTRL_C)
185 SetIoErr(ERROR_BREAK);
186 numfiles = 0;
188 if (!numfiles)
190 PrintFault(IoErr(), NULL);
191 rc = RETURN_FAIL;
192 break;
196 FreeVec(ap);
198 return rc;
202 LONG append(BPTR destfile, STRPTR srcfilename)
204 BYTE *buffer = NULL;
205 LONG actualLength = 0;
206 BPTR srcfile = NULL;
208 BOOL rc = RETURN_OK;
210 if ( (buffer = AllocMem( BUFFERSIZE , MEMF_ANY )) )
212 if ( (srcfile = Open( srcfilename , MODE_OLDFILE )) )
214 ULONG brk;
215 while(!(brk = SetSignal(0,0) & SIGBREAKF_CTRL_C) && (actualLength = Read(srcfile, buffer, BUFFERSIZE)) != -1 )
217 if (Write(destfile, buffer, actualLength) != actualLength )
219 Printf("%s: %s.\n", ERROR_HEADER, getstring(STR_ERR_WRITING));
220 rc = RETURN_FAIL;
222 break;
225 if (actualLength < BUFFERSIZE)
227 break;
230 if (actualLength == -1)
232 PrintFault(IoErr(), NULL);
233 Printf( "%s: %s.\n", (ULONG)ERROR_HEADER,
234 (ULONG)getstring(STR_ERR_READING));
235 rc = RETURN_FAIL;
238 if (brk)
240 PrintFault(ERROR_BREAK, NULL);
241 SetIoErr(ERROR_BREAK);
242 rc = RETURN_FAIL;
245 Close(srcfile);
247 else
249 PrintFault(IoErr(), NULL);
250 Printf("%s: %s: '%s'\n",
251 ERROR_HEADER,
252 getstring(STR_ERR_OPENREAD),
253 srcfilename);
255 rc = RETURN_FAIL;
258 FreeMem(buffer, BUFFERSIZE);
260 else
262 Printf("%s: %s.\n", ERROR_HEADER, getstring(STR_ERR_NOMEM));
263 rc = RETURN_FAIL;
266 return rc;
270 STRPTR getstring(LONG stringid)
272 switch(stringid)
274 case STR_ABORTED:
275 return "Aborted";
277 case STR_REMOVINGDEST:
278 return "removed incomplete destination-file";
280 case STR_ERR_OPENREAD:
281 return "Could not open file for reading";
283 case STR_ERR_NOMEM:
284 return "Could not allocate memory";
286 case STR_ERR_WRITING:
287 return "Error while writing";
289 case STR_ERR_OPENWRITE:
290 return "Could not open file for writing";
292 case STR_ERR_READING:
293 return "Error while writing";
295 default:
296 return "[Error: Unknown StringID]";