2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
5 Desc: Sorts the contents of a file
8 /*****************************************************************************
16 FROM/A,TO/A,COLSTART/K,CASE/S,NUMERIC/S
24 Sorts the contents of a text file
28 FROM -- file to read from
29 TO -- file to output to
30 COLSTART -- column at which the comparison begins
31 CASE -- sort is case sensitive. Uppercase items are output first
32 NUMERIC -- lines are interpreted as numbers
46 ******************************************************************************/
48 #include <clib/macros.h>
49 #include <exec/memory.h>
50 #include <exec/types.h>
52 #include <dos/exall.h>
53 #include <proto/dos.h>
54 #include <proto/exec.h>
55 #include <proto/utility.h>
56 #include <proto/locale.h>
57 #include <libraries/locale.h>
58 #include <utility/tagitem.h>
61 #include <aros/debug.h>
65 #define TEMPLATE "FROM/A,TO/A,COLSTART/K,CASE/S,NUMERIC/S"
69 #define ARG_COLSTART 2
77 struct sorted_data
* next
;
79 ULONG len
; // length of line including '\n'.
82 struct Locale
* locale
;
84 int compare(struct sorted_data
* sd1
,
85 struct sorted_data
* sd2
,
89 ULONG len
= MIN(sd1
->len
, sd2
->len
);
91 #warning It seems like StrnCmp of locale does not work.
102 a
= IsUpper(locale
,(ULONG
)*(sd1
->data
+col
+i
));
103 b
= IsUpper(locale
,(ULONG
)*(sd2
->data
+col
+i
));
107 if (0 != (retval
= StrnCmp(locale
,
126 retval
=StrnCmp(locale
,
134 if (sd1
->len
< sd2
->len
)
145 char * str1
= sd1
->data
;
146 char * str2
= sd2
->data
;
150 if (str1
[i
] != str2
[i
])
151 return (int)(str1
[i
] - str2
[i
]);
156 return (int)sd1
->len
- (int)sd2
->len
;
161 struct sorted_data
* sort(UBYTE
* data
,
169 struct sorted_data
* first
= NULL
;
170 struct sorted_data
* cur
= NULL
;
171 struct sorted_data
* tooshort
= NULL
;
172 struct sorted_data
* tooshort_last
= NULL
;
176 while (*colstart
>= '0' && *colstart
<= '9')
177 col
= col
* 10 + *colstart
++ - '0';
182 while (pos
< data_len
)
187 while (pos
< data_len
&& data
[pos
] != 0x0a)
190 if (data
[pos
] == 0x0a || pos
== data_len
)
195 cur
= AllocMem(sizeof(struct sorted_data
), MEMF_ANY
|MEMF_CLEAR
);
199 cur
->data
= data
+ begin
;
205 ** Insert it into the list of sorted lines
210 ** To be first in the list?
212 if (compare(cur
, first
, col
, case_on
) < 0)
219 struct sorted_data
* _cur
= first
;
224 ** Insert it after the current one and before the
227 if (NULL
== _cur
->next
)
232 if (compare(cur
, _cur
->next
, col
, case_on
) < 0)
234 cur
-> next
= _cur
->next
;
242 } /* if (NULL != first) */
248 /* this line is too short to sort it in */
249 if (NULL
== tooshort
)
256 tooshort_last
->next
= cur
;
264 if (NULL
!= tooshort
)
266 tooshort_last
->next
= first
;
274 ULONG
write_data(struct sorted_data
* start
, BPTR file_out
)
281 struct sorted_data
* next
= start
->next
;
285 error
= Write(file_out
, start
->data
, start
->len
);
286 if (-1 != error
&& start
->data
[start
->len
-1] != 0x0a)
287 error
= Write(file_out
, "\n", 1);
293 FreeMem(start
, sizeof(struct sorted_data
));
307 IPTR args
[ARG_NUM
] = { (IPTR
) NULL
, (IPTR
) NULL
, (IPTR
) NULL
, FALSE
, FALSE
};
311 locale
= OpenLocale(NULL
);
314 PutStr("Could not open locale!\n");
318 rda
= ReadArgs(TEMPLATE
, args
, NULL
);
322 lock_in
= Lock((STRPTR
)args
[ARG_FROM
], ACCESS_READ
);
326 BPTR file_out
= Open((STRPTR
)args
[ARG_TO
], MODE_NEWFILE
);
328 if (NULL
!= file_out
)
330 struct FileInfoBlock fib
;
332 BOOL success
= Examine(lock_in
, &fib
);
335 ** Read the input file into memory
337 if (fib
.fib_Size
&& DOSTRUE
== success
)
338 data
= AllocVec(fib
.fib_Size
, MEMF_ANY
);
342 ULONG read
= Read(lock_in
, data
, fib
.fib_Size
);
346 struct sorted_data
* sd
;
349 (STRPTR
)args
[ARG_COLSTART
],
350 (BOOL
)args
[ARG_CASE
],
351 (BOOL
)args
[ARG_NUMERIC
]);
353 error
= write_data(sd
, file_out
);
359 } /* if (file_out) */
368 PrintFault(IoErr(), "Sort");