#include "buff.h" line_t* __search_pos(int addr){ int i; line_t *cur = b_start; for(i=1; i next; } return cur; } int __get_lines(FILE *fin, line_t **first, line_t **last, int *tot){ char buff[4096]; int n,s, num_alloc=0; line_t *l; n = 0; *tot = 0; *first = *last = NULL; while(feof(fin) == 0){ if (!fgets(buff, 4095, fin)) break; if (buff[0] == '.') break; s = strlen(buff) + 1; *tot += s -1; l = malloc(sizeof(line_t)); l->c = malloc(s * sizeof(char)); num_alloc +=1; memcpy(l->c, buff, s); l->s = s; if (*first == NULL){ *first = *last = l; (*first) -> next = (*last) -> next = NULL; (*first) -> prev = (*last) -> prev = NULL; } else{ (*last) -> next = l; l->prev = *last; l->next = NULL; *last = l; } n += 1; } fprintf(stderr, " >>>> get_lines: num_alloc: %d\n", num_alloc); return n; } int read_file(){ FILE *fin; int tot; fprintf(stderr, " >>> reading file: %s\n", fname); if (!(fin = fopen(fname, "r"))){ return -1; } if (b_start){ addr1=num, addr2=1; delete_lines(); } num = pos = __get_lines(fin, &b_start, &b_end, &tot); fprintf (stderr, " >>>> read_file: pos: %d num: %d\n", pos, num); cur = b_end; fclose(fin); printf("%d\n", tot); return 0; } void print_cur_line(char lineno){ if (!b_start){ E; return; } if (lineno) printf("%d\t", pos); printf("%s", cur->c); } void print_lines(char lineno){ line_t *p; int i=0; p = b_start; fprintf(stderr, ">>> *** addr1: %d addr2: %d ***\n", addr1, addr2); for (i=1; inext; pos = i; cur = p; while(pos < addr1){ if (lineno) printf("%d\t", pos); printf("%s", cur->c); cur = cur->next; pos += 1; } if (lineno) printf("%d\t", pos); printf("%s", cur->c); } int move_to_line(int addr, char print){ if (addr > num) return -1; else if (addr >= 0){ pos = addr; cur = __search_pos(pos); if (print) print_cur_line(0); } return pos; } void print_lineno(){ printf("%d\n", addr1); } int move_forward(int n){ if (pos + n > num){ E; return -1; } while(n-- > 0){ cur = cur->next; } pos += n; return 0; } int move_backward(int n){ if (pos - n < 1){ E; return -1; } while(n-- >0){ cur = cur->prev; } pos -= n; return 0; } /* add lines after pos */ void append_lines(){ int n, tot; line_t *first, *last; first = last = NULL; n = __get_lines(stdin, &first, &last, &tot); if (addr1 == 0){ fprintf(stderr, " >>> append (zero): pos: %d n:%d\n", pos, n); last->next = b_start; if (b_start) b_start -> prev = last; b_start = first; num += n; move_to_line(n,0); } else{ fprintf(stderr, " >>> append (non-zero): pos: %d n:%d\n", pos, n); last -> next = cur -> next; cur->next = first; first->prev = cur; num += n; //move_forward(n); pos += n; cur = last; } } void insert_lines(){ int n, tot; line_t *first, *last; first = last = NULL; n = __get_lines(stdin, &first, &last, &tot); if (addr1 == 0){ fprintf(stderr, " >>> insert (zero): pos: %d n:%d\n", pos, n); last->next = b_start; b_start -> prev = last; b_start = first; num += n; move_to_line(n,0); } else{ fprintf(stderr, " >>> insert (non-zero): pos: %d n:%d\n", pos, n); cur -> prev -> next = first; first -> prev = cur -> prev; last -> next = cur; num += n; pos -=1 ; cur = last; } } void delete_lines(){ line_t *handle; int num_free = 0; if (addr1 == -1){ addr1 = pos; } if (addr2 == -1){ addr2 = addr1; } if (addr1 < addr2){ return; } move_to_line(addr2,0); fprintf(stderr, " >>> delete: addr1: %d addr2: %d pos: %d\n", addr1, addr2, pos); if (addr2 <= 1){ /* we are deleting the first line */ while(pos <= addr1){ free(cur->c); num_free += 1; if (cur -> next){ cur = cur -> next; free(cur -> prev); } else { free(cur); cur = NULL; pos ++; break; } pos ++; } fprintf(stderr, " >>>> delete_lines: num_free: %d\n", num_free); /* free(b_start); */ b_start = cur; if (cur){ pos = 1; cur = b_start; } else pos = 0; } else{ handle = cur->prev; while(pos < addr1){ free(cur->c); cur = cur -> next; free(cur->prev); pos ++; } handle->next = cur -> next; free(cur->c); free(cur); if (handle -> next){ pos = addr2 ; cur = handle->next; } else{ pos = addr2 - 1; cur = handle; } } num -= addr1 - addr2 + 1; } void change_lines(){ delete_lines(); addr2 = addr1 =pos; append_lines(); } int write_lines(){ FILE *fout; line_t *l; int tot=0; if (! (fout = fopen(fname, "w+"))){ return -1; } l = b_start; while(l){ tot += fprintf(fout, "%s", l->c); l = l->next; } fclose(fout); printf("%d\n", tot); return 0; }