xref: /reactos/base/applications/cmdutils/sort/sort.c (revision 50cf16b3)
1 /*
2  * PROJECT:   SORT - Adapted for ReactOS
3  * LICENSE:   GPL - See COPYING in the top level directory
4  * PURPOSE:   Reads line of a file and sorts them in order
5  * COPYRIGHT: Copyright 1995 Jim Lynch
6  *
7  */
8 
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <string.h>
12 
13 #define MAXRECORDS 65536 /* maximum number of records that can be sorted */
14 #define MAXLEN 4095 /* maximum record length */
15 
16 /* Reverse flag */
17 int rev;
18 
19 /* Help flag */
20 int help;
21 
22 /* Sort column */
23 int sortcol;
24 
25 /* Error counter */
26 int err = 0;
27 
28 int cmpr(const void *a, const void *b)
29 {
30     char *A, *B;
31 
32     A = *(char **) a;
33     B = *(char **) b;
34 
35     if (sortcol > 0)
36     {
37         if (strlen(A) > sortcol)
38         {
39             A += sortcol;
40         }
41         else
42         {
43             A = "";
44         }
45         if (strlen(B) > sortcol)
46         {
47             B += sortcol;
48         }
49         else
50         {
51             B = "";
52         }
53     }
54 
55     if (!rev)
56     {
57         return strcmp(A, B);
58     }
59     else
60     {
61         return strcmp(B, A);
62     }
63 }
64 
65 void usage(void)
66 {
67     fputs("SORT\n", stderr);
68     fputs("Sorts input and writes output to a file, console or a device.\n",
69           stderr);
70 
71     if (err)
72     {
73         fputs("Invalid parameter\n", stderr);
74     }
75 
76     fputs("    SORT [options] < [drive:1][path1]file1 > [drive2:][path2]file2\n",
77           stderr);
78 
79     fputs("    Command | SORT [options] > [drive:][path]file\n", stderr);
80     fputs("    Options:\n", stderr);
81     fputs("    /R   Reverse order\n", stderr);
82     fputs("    /+n  Start sorting with column n\n", stderr);
83     fputs("    /?   Help\n", stderr);
84 }
85 
86 int main(int argc, char **argv)
87 {
88     char temp[MAXLEN + 1];
89     char **list;
90 
91     /* Option character pointer */
92     char *cp;
93     int i, nr;
94 
95     sortcol = 0;
96     rev = 0;
97     while (--argc)
98     {
99         if (*(cp = *++argv) == '/')
100         {
101             switch (cp[1])
102             {
103                 case 'R':
104                 case 'r':
105                     rev = 1;
106                     break;
107 
108                 case '?':
109                 case 'h':
110                 case 'H':
111                     help = 1;
112                     break;
113 
114                 case '+':
115                     sortcol = atoi(cp + 1);
116                     if (sortcol)
117                     {
118                         sortcol--;
119                     }
120                     break;
121 
122                 default:
123                     err++;
124             }
125         }
126     }
127 
128     if (err || help)
129     {
130         usage();
131         exit(1);
132     }
133 
134     list = (char **) malloc(MAXRECORDS * sizeof(char *));
135     if (list == NULL)
136     {
137         fputs("SORT: Insufficient memory\n", stderr);
138         exit(3);
139     }
140 
141     for (nr = 0; nr < MAXRECORDS; nr++)
142     {
143         if (fgets(temp, MAXLEN, stdin) == NULL)
144         {
145             break;
146         }
147 
148         if(strlen(temp))
149         {
150             temp[strlen(temp) - 1] = '\0';
151         }
152 
153         list[nr] = (char *) malloc(strlen(temp) + 1);
154         if (list[nr] == NULL)
155         {
156             fputs("SORT: Insufficient memory\n", stderr);
157 
158             /* Cleanup memory */
159             for (i = 0; i < nr; i++)
160             {
161                 free(list[i]);
162             }
163             free(list);
164             exit(3);
165         }
166 
167         strcpy(list[nr], temp);
168     }
169 
170     if (nr == MAXRECORDS)
171     {
172         fputs("SORT: number of records exceeds maximum\n", stderr);
173 
174         /* Cleanup memory */
175         for (i = 0; i < nr; i++)
176         {
177             free(list[i]);
178         }
179         free(list);
180 
181         /* Bail out */
182         exit(4);
183     }
184 
185     qsort((void *)list, nr, sizeof(char *), cmpr);
186 
187     for (i = 0; i < nr; i++)
188     {
189         fputs(list[i], stdout);
190         fputs("\n", stdout);
191     }
192 
193     /* Cleanup memory */
194     for (i = 0; i < nr; i++)
195     {
196         free(list[i]);
197     }
198     free(list);
199     return 0;
200 }
201 /* EOF */
202