diff options
-rw-r--r-- | toys/posix/cut.c | 106 |
1 files changed, 46 insertions, 60 deletions
diff --git a/toys/posix/cut.c b/toys/posix/cut.c index 38f136e2..b23535c3 100644 --- a/toys/posix/cut.c +++ b/toys/posix/cut.c @@ -1,6 +1,7 @@ /* cut.c - Cut from a file. * - * Copyright 2012 Ranjan Kumar <ranjankumar.bth@gmail.com>, Kyungwan Han <asura321@gamil.com> + * Copyright 2012 Ranjan Kumar <ranjankumar.bth@gmail.com> + * Copyright 2012 Kyungwan Han <asura321@gmail.com> * * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/cut.html @@ -14,57 +15,52 @@ config CUT Print selected parts of lines from each FILE to standard output. - -b LIST select only these bytes from LIST. - -c LIST select only these characters from LIST. - -f LIST select only these fields. - -d DELIM use DELIM instead of TAB for field delimiter. - -s do not print lines not containing delimiters. - -n don't split multibyte characters (Ignored). + -b LIST select only these bytes from LIST. + -c LIST select only these characters from LIST. + -f LIST select only these fields. + -d DELIM use DELIM instead of TAB for field delimiter. + -s do not print lines not containing delimiters. + -n don't split multibyte characters (Ignored). */ #define FOR_cut #include "toys.h" -typedef struct _slist { - int start_position; - int end_position; - struct _slist *next; -} SLIST; - GLOBALS( char *delim; char *flist; char *clist; char *blist; - struct _slist *slist_head; + + void *slist_head; unsigned nelem; ) +struct slist { + struct slist *next; + int start, end; +}; + void (*do_cut)(int); static void do_fcut(int fd); static void do_bccut(int fd); -static void free_list(void); -/* - * add items in the slist. - */ static void add_to_list(int start, int end) { - SLIST *current, *head_ref, *temp1_node; + struct slist *current, *head_ref, *temp1_node; head_ref = TT.slist_head; - temp1_node = (SLIST *)xzalloc(sizeof(SLIST)); - temp1_node->start_position = start; - temp1_node->end_position = end; - temp1_node->next = NULL; + temp1_node = xzalloc(sizeof(struct slist)); + temp1_node->start = start; + temp1_node->end = end; /* Special case for the head end */ - if (head_ref == NULL || (head_ref)->start_position >= start) { + if (!head_ref || head_ref->start >= start) { temp1_node->next = head_ref; head_ref = temp1_node; } else { /* Locate the node before the point of insertion */ current = head_ref; - while (current->next!=NULL && current->next->start_position < temp1_node->start_position) + while (current->next && current->next->start < temp1_node->start) current = current->next; temp1_node->next = current->next; current->next = temp1_node; @@ -174,16 +170,25 @@ void cut_main(void) free(TT.delim); TT.delim = NULL; } - free_list(); + llist_traverse(TT.slist_head, free); } // perform cut operation on the given delimiter. static void do_fcut(int fd) { - char *buff; - char *delimiter = TT.delim; + char *buff, *pfield = 0, *delimiter = TT.delim; + + for (;;) { + unsigned cpos = 0; + int start, ndelimiters = -1; + int nprinted_fields = 0; + struct slist *temp_node = TT.slist_head; + + free(pfield); + pfield = 0; + + if (!(buff = get_line(fd))) break; - while ((buff = get_line(fd))) { //does line have any delimiter?. if (strrchr(buff, (int)delimiter[0]) == NULL) { //if not then print whole line and move to next line. @@ -191,19 +196,16 @@ static void do_fcut(int fd) continue; } - unsigned cpos = 0; - int start, ndelimiters = -1; - int nprinted_fields = 0; - char *pfield = xzalloc(strlen(buff) + 1); - SLIST *temp_node = TT.slist_head; + pfield = xzalloc(strlen(buff) + 1); - if (temp_node != NULL) { + if (temp_node) { //process list on each line. while (cpos < TT.nelem && buff) { if (!temp_node) break; - start = temp_node->start_position; + start = temp_node->start; do { - char *field = NULL; + char *field = 0; + //count number of delimeters per line. while (buff) { if (ndelimiters < start) { @@ -222,16 +224,14 @@ static void do_fcut(int fd) } } start++; - if ((temp_node->end_position < 0) || (!buff)) break; - } while(start <= temp_node->end_position); + if ((temp_node->end < 0) || !buff) break; + } while(start <= temp_node->end); temp_node = temp_node->next; cpos++; } } xputc('\n'); - free(pfield); - pfield = NULL; - }//End of while loop. + } } // perform cut operation char or byte. @@ -243,18 +243,18 @@ static void do_bccut(int fd) unsigned cpos = 0; int buffln = strlen(buff); char *pfield = xzalloc(buffln + 1); - SLIST *temp_node = TT.slist_head; + struct slist *temp_node = TT.slist_head; if (temp_node != NULL) { while (cpos < TT.nelem) { int start; if (!temp_node) break; - start = temp_node->start_position; + start = temp_node->start; while (start < buffln) { //to avoid duplicate field printing. if (pfield[start]) { - if (++start <= temp_node->end_position) continue; + if (++start <= temp_node->end) continue; temp_node = temp_node->next; break; } else { @@ -262,7 +262,7 @@ static void do_bccut(int fd) pfield[start] = (char) 0x23; //put some char at this position. xputc(buff[start]); } - if (++start > temp_node->end_position) { + if (++start > temp_node->end) { temp_node = temp_node->next; break; } @@ -275,17 +275,3 @@ static void do_bccut(int fd) pfield = NULL; } } - -/* - * free the slist. -*/ -static void free_list(void) -{ - SLIST *temp; - - while (TT.slist_head != NULL) { - temp = TT.slist_head->next; - free(TT.slist_head); - TT.slist_head = temp; - } -} |