From 6f9e88bee99e0fae4d7ec67022979501c7fa2b01 Mon Sep 17 00:00:00 2001 From: sinanmohd Date: Thu, 30 Jun 2022 22:46:08 +0530 Subject: 5.17 --- 5.17.c | 259 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 259 insertions(+) create mode 100644 5.17.c diff --git a/5.17.c b/5.17.c new file mode 100644 index 0000000..3469a4e --- /dev/null +++ b/5.17.c @@ -0,0 +1,259 @@ +#include +#include +#include +#include + +#define MAXLINES 5000 + +char *lineptr[MAXLINES]; + +int realines(char *lineptr[], int max); +void writelines(char *lineptr[], int nlins); +void my_qsort(char *lineptr[], int left, int right, int (*cmp)(const char *, const char *)); +int numcmp(const char to[], const char from[]); +int strcmp_ignore_case(const char str1[], const char str2[]); +int reverse(const char str1[], const char str2[]); +int mystcmp(const char to[], const char from[]); +int (*compare)(const char str1[], const char str2[]); +int (*strcmp_base)(const char to[], const char from[]); +int isdirectory(char input); +int field_skip(const char str[]); + +int directory_order_bool, field_bool; + + +int +main(int argc, char *argv[]) +{ + char flag; + int numeric = 0, reverse_bool = 0, ignore_case_bool = 0; + int nlins; + + while (--argc > 0 && **++argv == '-') + while ((flag = *++*argv)) + switch (flag) { + case 'n' : + numeric = 1; + break; + case 'r' : + reverse_bool = 1; + break; + case 'f' : + ignore_case_bool = 1; + break; + case 'd' : + directory_order_bool = 1; + break; + case 'l' : + while (isdigit(*++*argv)) + field_bool = field_bool * 10 + **argv - '0'; + + (*argv)--; + break; + default : + printf("Err: illigial option %c\n", flag); + } + + if (argc) + printf("Usage: sort -nrf\n"); + else if ((nlins = realines(lineptr, MAXLINES)) > 0) { + + strcmp_base = ignore_case_bool ? strcmp_ignore_case : mystcmp; + compare = numeric ? numcmp : strcmp_base; + + my_qsort(lineptr, 0, nlins - 1, reverse_bool ? reverse : compare); + writelines(lineptr, nlins); + } + + return 0; +} + +void swap(char *lineptr[], int to, int from); + +void +my_qsort(char *lineptr[], int left, int right, int (*cmp)(const char *, const char *)) +{ + int last, i; + + if (left >= right) + return; + + swap(lineptr, left, (left+right)/2); + last = left; + + for (i = left+1; i <= right; i++) { + if ((*cmp)(lineptr[i], lineptr[left]) < 0) + swap(lineptr, ++last, i); + + } + swap(lineptr, left, last); + + my_qsort(lineptr, left, last-1, cmp); + my_qsort(lineptr, last+1, right, cmp); +} + +int +numcmp(const char to[], const char from[]) +{ + if (field_bool) { + to += field_skip(to); + from += field_skip(from); + } + + double n1 = atof(to); + double n2 = atof(from); + + if (n1 < n2) + return -1; + else if (n1 > n2) + return 1; + else + return 0; +} + +void +swap(char *lineptr[], int to, int from) +{ + char *temp; + + temp = lineptr[to]; + lineptr[to] = lineptr[from]; + lineptr[from] = temp; +} + +void +writelines(char *lineptr[], int nlins) +{ + while (nlins--) + printf("%s", *lineptr++); +} + +#define MAXLEN 1000 +int sneed_getine(char str[], int max); + +int +realines(char *lineptr[], int max) +{ + int len, nlins; + char buff[MAXLEN], *temp; + + for (nlins = 0; (len = sneed_getine(buff, MAXLEN)) > 0; nlins++) { + if (nlins < max && (temp = malloc(len+1)) != NULL) { + strcpy(temp, buff); + lineptr[nlins] = temp; + } + + else + return -1; + } + + return nlins; +} + +int +sneed_getine(char str[], int max) +{ + char input; + char *str_og = str; + + while ( --max && (input = getchar()) != EOF && input != '\n') + *str++ = input; + + if (max && input == '\n') + *str++ = input; + + *str = '\0'; + + return str - str_og; +} + +int +reverse(const char str1[], const char str2[]) +{ + return (*compare)(str2, str1); +} + +int +strcmp_ignore_case(const char to[], const char from[]) +{ + if (field_bool) { + to += field_skip(to); + from += field_skip(from); + } + + if (directory_order_bool) { + for (; *to && *from; to++, from++) + if ((isdirectory(tolower(*from)) && tolower(*from) != tolower(*to)) || (field_bool && (isblank(*from) || isblank(*to)))) + break; + } + + else + for (; *to && *from && tolower(*to) == tolower(*from); to++, from++) + if (field_bool && (isblank(*from) || isblank(*to))) + break; + + return tolower(*to) - tolower(*from); +} + +int +isdirectory(char input) +{ + if (isalpha(input) || isdigit(input) || isblank(input)) + return 1; + else + return 0; +} + +int +mystcmp(const char to[], const char from[]) +{ + if (field_bool) { + to += field_skip(to); + from += field_skip(from); + } + + if (directory_order_bool) { + for (; *to && *from; to++, from++) + if ((isdirectory(*from) && *from != *to) || (field_bool && (isblank(*from) || isblank(*to)))) + break; + } + + else + for (; *to && *from && *to == *from; to++, from++) + if (field_bool && (isblank(*from) || isblank(*to))) + break; + + return *to - *from; +} + +int +field_skip(const char str[]) +{ + int count, inside; + const char *str_og; + + str_og = str; + + while (isblank(*str)) + str++; + + while (isblank(*str)) + str++; + + for (count = 1, inside = 1; count < field_bool && *str; str++) { + if (inside == 1 && isblank(*str)) + inside = 0; + + if (inside == 0 && !isblank(*str)) { + inside = 1; + count++; + } + } + + if (count != field_bool) { + printf("Err: field not available\n"); + return 0; + } + + return str - str_og; +} -- cgit v1.2.3