123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363 |
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #define MAXLINES 20000
- #define MAXLEN 1000
- #define ERR_TOOBIG 1
- #define ARGUMENT_PROBLEM 2
- int getline1(char *, int);
- char *lineptr[MAXLINES];
- int readlines(char *lineptr[], int nlines);
- void writelines(char *lineptr[], int nlines);
- void swap(void *v[], int, int);
- void qsort1(void *v[], int left, int right, int noSort, int caseInsensitive, int directory,
- int (*comp)(void *, void *, int, int));
- int numcmp(char *, char *, int, int);
- int isAlphaNumeric(char);
- void zerome(int*);
- void zero (int*, int);
- void reverse(void *v[], int left, int right)
- {
- int i, last;
- if (left >= right)
- return;
- swap(v,left,right);
- reverse(v,left+1,right-1);
- }
- void zerome(int* c)
- {
- *c = 0;
- }
- void zero (int* a, int len)
- {
- for (int i =0; i<len; i++)
- zerome( a+i );
-
-
- }
-
- int main(int argc, char *argv[])
- {
- int strcmp1(char *s, char *t);
- int strcmp2(char *s, char *t, int u, int v);
- int fieldcount = 1;
-
- for (int i=0; i< argc; i++)
- if ( strcmp1(argv[i], "-l") ==0 ) fieldcount++;
- int help = 0;
-
-
-
-
- int field [fieldcount] ;
- zero(field,fieldcount);
-
-
- int fieldlen [fieldcount] ;
- zero(fieldlen,fieldcount);
- for (int i=0; i< argc; i++)
- {
- if ( strcmp1(argv[i], "-l") ==0 )
- {
- field[i+1] = i;
-
- if ((i+1) > argc)
- {
- printf ("-l out of bounds");
- return ARGUMENT_PROBLEM;
- }
- fieldlen[i+1]=atoi(argv[i+1]);
-
- }
- }
-
- int numeric[fieldcount];
- int backwards[fieldcount];
- int caseInsensitive[fieldcount];
- int directory[fieldcount];
- int noSort[fieldcount];
-
- zero(numeric,fieldcount);
- zero(backwards,fieldcount);
- zero(caseInsensitive,fieldcount) ;
- zero(directory,fieldcount);
- zero(noSort,fieldcount);
-
- for (int i=0, j=0; i < fieldcount; i++)
- {
- int nextfield = field[i];
-
- for (; j<argc; j++)
-
- {
- if (j==nextfield && nextfield != 0)
- i++;
-
- noSort[i] |= (strcmp1(argv[j], "-x") == 0);
- numeric[i] |= (strcmp1(argv[j], "-n") == 0);
- caseInsensitive[i] |= (( strcmp1(argv[j], "-f") == 0 ) || ( strcmp1(argv[j], "-df") ==0 ));
- backwards[i] |= ( strcmp1(argv[j], "-r") ==0 ) ;
- directory[i] |= (( strcmp1(argv[j], "-d") ==0 ) || ( strcmp1(argv[j], "-df") ==0 ));
-
-
-
- help |= (( strcmp1(argv[j], "-h") ==0 ) || ( strcmp1(argv[j], "--help") ==0 ));
- }
-
- }
-
- if (help)
- {
- printf ("./qsort [-l OPTIONS]* \n");
- printf (" OPTIONS: \n");
- printf (" -x : don't actually sort fields \n");
- printf (" -n : sort by number \n");
- printf (" -r : reverse (5-14) \n");
- printf (" -f : fold lower/upper case together (5-15) \n");
- printf (" -d : sort as if directory structure (5-16) \n");
- printf (" -fd : -f and -d (5-16) \n");
- printf (" -l N demarcates the next field by N \n");
- return(0);
- }
- printf("fieldcount %d\n",fieldcount);
-
-
- for (int i = 0; i < fieldcount; i++)
- {
- printf ("numeric, %d \ncaseInsensitive %d\nbackwards %d\nnosort %d\ni %d\ndirectory %d\n\n",numeric[i],caseInsensitive[i],backwards[i],noSort[i],i,directory[i]);
- }
- int nlines = -1;
-
- int first = 0;
- int last = -1;
- if ((nlines = readlines(lineptr, MAXLINES)) >= 0)
- {
- for (int i =0 ; i < fieldcount; i++)
- {
- first = field[i];
-
- if (fieldlen[0]==0)
- {
- last = nlines-1;
- }
- else
- last = first+fieldlen[i];
- if (last == 0)
- last = nlines-1;
-
-
-
- qsort1( (void**) lineptr, first, last, noSort[i], caseInsensitive[i], directory[i],
- (int (*)(void*,void*,int,int)) (numeric ? numcmp : strcmp2 ) );
-
- if(backwards[i])
- reverse((void**)lineptr, first, last);
- }
-
-
- writelines(lineptr, nlines);
-
- return 0;
- } else {
- printf("input %d too big to sort, contact devs with this error message \n",nlines);
- return ERR_TOOBIG;
- }
- }
-
- void qsort1(void *v[], int left, int right, int noSort, int caseInsensitive, int directory,
- int (*comp)(void *, void *, int, int))
- {
- if (noSort) return;
- int i, last;
- if (left >= right)
- return;
- swap(v, left, (left + right)/2);
- last = left;
- for (i = left+1; i <= right; i++)
- if ((*comp)(v[i], v[left], caseInsensitive, directory) < 0)
- swap(v, ++last, i);
- swap(v, left, last);
- qsort1(v, left, last-1, noSort, caseInsensitive, directory, comp);
- qsort1(v, last+1, right, noSort, caseInsensitive, directory, comp);
- }
- int isAlphaNumeric(char a)
- {
- return
- (
- ( (a >= 'A') && (a <= 'Z') ) ||
- ( (a >= '0') && (a <= '9') ) ||
- ( (a >= 'a') && (a <= 'z') ) ||
- (a == ' ')
- );
- }
- int strcmp2(char *s, char *t, int caseInsensitive, int dirmode)
- {
- for ( ; *s == *t; s++, t++)
- if (*s == '\0')
- return 0;
- int ci= caseInsensitive;
- char str = *s;
-
- char stt = *t;
-
-
- if (ci)
- {
- if (((str >= 'a') && (str <= 'z'))
- && ((stt >= 'a') && (stt <= 'z')))
- return *s - *t;
- if ((str >= 'a') && (str <= 'z'))
- return *s - *t -32;
- if ((stt >= 'a') && (stt <= 'z'))
- return *s - *t +32;
- }
- if (dirmode)
-
-
-
- {
-
- if (isAlphaNumeric(str) || isAlphaNumeric(stt))
- return *s - *t;
-
- return (char)0;
- }
- return *s - *t;
- }
- int strcmp1(char *s, char *t)
- {
- int u=1;
- int v=0;
- return strcmp2(s,t,u,v);
- }
-
- void writelines(char *lineptr[], int nlines)
- {
- while (nlines-- > 0)
- printf("%s\n", *lineptr++);
- }
-
- int numcmp(char *s1, char *s2, int dud, int dud2)
- {
-
- double v1, v2;
- v1 = atof(s1);
- v2 = atof(s2);
- if (v1 < v2)
- return -1;
- else if (v1 > v2)
- return 1;
- else
- return 0;
- }
- int getline1(char s[],int lim)
- {
- int c, i;
- for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
- s[i] = c;
- if (c == '\n') {
- s[i] = c;
- ++i;
- }
- s[i] = '\0';
- return i;
- }
-
- int readlines(char *lineptr[], int maxlines)
- {
- int len, nlines;
- char *p, line[MAXLEN];
- nlines = 0;
- while ((len = getline1(line, MAXLEN)) > 0)
- {
- p = malloc(sizeof(char)*len);
- if (nlines >= maxlines || p == NULL)
- return -1;
- else {
- line[len-1] = '\0';
- strcpy(p, line);
- lineptr[nlines++] = p;
- }
- }
- return nlines;
- }
-
- void swap(void *v[], int i, int j)
- {
- void *temp;
- temp = v[i];
- v[i] = v[j];
- v[j] = temp;
- }
|