9p / who / tweedy / 9C / 1


Exercise 1.22: Fold Lines

Code

#include <u.h>
#include <libc.h>
#include <bio.h>

#define STDIN   0
#define MAXLINE 1000    /* maximum input line size */
#define FOLD    80  /* maximum output line size */

int getline(Biobuf *buffer, char line[], int maxline);

/* fold long input lines into two or more shorter lines after the last non-blank character 
   that occurs before the nth column of input (this comment itself is a test of the program) */
/*-------|---------|---------|---------|---------|---------|---------|--------*/
/*0     10        20        30        40        50        60        70      80*/

void
main()
{
    int len, start, end;
    char line[MAXLINE];
    int remainder = 0;
    int i, k, s;

    Biobuf *bstdin;
    bstdin = Bfdopen(STDIN, OREAD);

    while((len = getline(bstdin, line, MAXLINE)) > 0){
        if(len <= FOLD+1){
            print("%s", line);
            remainder = 0;
        }
        else{
            for(i=1; i*FOLD <= ((len/FOLD)+1)*FOLD; ++i){       /* loop up through groups of FOLD characters */
                start = i*FOLD - FOLD - remainder;
                end = i*FOLD - remainder;
                if(end > len)
                    end = len;
                if(line[end] == ' '){               /* if the first character of the next group is a blank */
                    for(k = start; k < end; ++k)
                        print("%c", line[k]);       /* print that whole group */
                    print("\n");
                    remainder = 0;
                }
                else{                       /* otherwise do the main routine */
                    if(end-start < FOLD){           /* is a remainder the end of the line? */
                        for(k = start; k < end; ++k)
                            print("%c", line[k]);
                        remainder = 0;
                    }
                    else{                   /* if not, look for break points */
                    for(s = end; s > start && line[s] != ' '; --s)  /* try to find the last space */
                        ;
                    if(line[s] == ' ' && s != start){   /* found one? print the line up to there */
                        for(k = start; k < s; ++k)
                            print("%c", line[k]);
                        remainder = end - s;
                        print("\n");
                    }
                    else{                   /* otherwise print the whole group */
                        for(k = start; k < end; ++k)
                            print("%c", line[k]);
                        if(line[k-1] != '\n')
                            print("\n");                        
                    }
                    }
                }
            }
        }
    }

    exits(0);
}

/* getline: read a line into s, return length */
int getline(Biobuf *b, char s[], int lim)
{
    int c, i;

    for(i = 0; i<lim-1 && (c=Bgetc(b))>= 0 && c!='\n'; ++i)
        s[i] = c;
    if(c == '\n'){
        s[i] = c;
        ++i;
    }
    s[i] = '\0';
    return i;
}

Output

$ 9c fold.c; 9l fold.o -o fold
$ ./fold < fold.c
#include <u.h>
#include <libc.h>
#include <bio.h>

#define STDIN   0
#define MAXLINE 1000    /* maximum input line size */
#define FOLD    80  /* maximum output line size */

int getline(Biobuf *buffer, char line[], int maxline);

/* fold long input lines into two or more shorter lines after the last non-blank
 character 
   that occurs before the nth column of input (this comment itself is a test of
 the program) */
/*-------|---------|---------|---------|---------|---------|---------|--------*/
/*0     10        20        30        40        50        60        70      80*/

void
main()
{
    int len, start, end;
    char line[MAXLINE];
    int remainder = 0;
    int i, k, s;

    Biobuf *bstdin;
    bstdin = Bfdopen(STDIN, OREAD);

    while((len = getline(bstdin, line, MAXLINE)) > 0){
        if(len <= FOLD+1){
            print("%s", line);
            remainder = 0;
        }
        else{
            for(i=1; i*FOLD <= ((len/FOLD)+1)*FOLD; ++i){       /* loop up through groups of
 FOLD characters */
                start = i*FOLD - FOLD - remainder;
                end = i*FOLD - remainder;
                if(end > len)
                    end = len;
                if(line[end] == ' '){               /* if the first character of the next group is a
 blank */
                    for(k = start; k < end; ++k)
                        print("%c", line[k]);       /* print that whole group */
                    print("\n");
                    remainder = 0;
                }
                else{                       /* otherwise do the main routine */
                    if(end-start < FOLD){           /* is a remainder the end of the line? */
                        for(k = start; k < end; ++k)
                            print("%c", line[k]);
                        remainder = 0;
                    }
                    else{                   /* if not, look for break points */
                    for(s = end; s > start && line[s] != ' '; --s)  /* try to find the last
 space */
                        ;
                    if(line[s] == ' ' && s != start){   /* found one? print the line up to there
 */
                        for(k = start; k < s; ++k)
                            print("%c", line[k]);
                        remainder = end - s;
                        print("\n");
                    }
                    else{                   /* otherwise print the whole group */
                        for(k = start; k < end; ++k)
                            print("%c", line[k]);
                        if(line[k-1] != '\n')
                            print("\n");                        
                    }
                    }
                }
            }
        }
    }

    exits(0);
}

/* getline: read a line into s, return length */
int getline(Biobuf *b, char s[], int lim)
{
    int c, i;

    for(i = 0; i<lim-1 && (c=Bgetc(b))>= 0 && c!='\n'; ++i)
        s[i] = c;
    if(c == '\n'){
        s[i] = c;
        ++i;
    }
    s[i] = '\0';
    return i;
}
$ ./fold < LIPSUM
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
 incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis
ostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
 aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
iat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
a qui officia deserunt mollit anim id est laborum.

LIPSUM

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.



tweedy