[PR] この広告は3ヶ月以上更新がないため表示されています。
ホームページを更新後24時間以内に表示されなくなります。

less

`Curses`端末制御ライブラリを用いた"less"コマンド
主に"sl"コマンドなどに用いられるライブラリです.
コンパイルする際は, 適当な名前のディレクトリを作り, その中に"Makefile",
を移動し, "src", "include"ディレクトリを作成し,
"src"にCソースファイル, "include"にヘッダーファイルを作成してください.

"curses"ライブラリを用いたのは初めてで他のサイトを見ながら作成してみました.
ファイヤープロジェクト
上のサイトに"curses"の使い方が書いてあります.

with line numberplain text
  1.  #Makefile
  2. CC = gcc
  3. FLAGS = -g -Wall -lcurses
  4. SOURCE = main.c size.c
  5. OBJC = main.o size.o
  6. PROJ = less
  7. INCLUDE = -I include
  8.  
  9. vpath %.c src/
  10. vpath %.h include/
  11.  
  12. $(PROJ):$(OBJC)
  13.     $(CC) $(FLAGS) $^ -o $@
  14.  
  15. main.o:$(SOURCE)
  16.     $(CC) $(INCLUDE) $^ -c $(FLAGS)
 #Makefile
CC = gcc
FLAGS = -g -Wall -lcurses
SOURCE = main.c size.c
OBJC = main.o size.o
PROJ = less
INCLUDE = -I include

vpath %.c src/
vpath %.h include/

$(PROJ):$(OBJC)
	$(CC) $(FLAGS) $^ -o $@

main.o:$(SOURCE)
	$(CC) $(INCLUDE) $^ -c $(FLAGS)
with line numberplain text
  1.  /* main.c */
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <curses.h>
  5. #include <message.h>
  6.  
  7. #define UP       1
  8. #define DOWN     2
  9. #define RIGHT    3
  10. #define LEFT     4
  11. #define LINE_TAB 6
  12. #define LINE_TOP 7
  13. #define LINE_END 8
  14. #define QUIT     9
  15.  
  16. extern long line_count(FILE *fp);
  17. extern int getkey(void);
  18. void close_fd(void);
  19.  
  20. FILE *fp = NULL;
  21.  
  22. int main(int argc, char **argv)
  23. {
  24.     int term_w   = 0;
  25.     int pad_line = 0;
  26.     int pad_w    = 0;
  27.     int pad_y;
  28.     int pad_x;
  29.     char *buff;
  30.     int ch;
  31.     int answer = 1;
  32.  
  33.     WINDOW *pad;
  34.  
  35.     if(argc < 2) {
  36.         print_help();
  37.         print_version();
  38.         exit(EXIT_FAILURE);
  39.     }
  40.  
  41.     if((fp = fopen(argv[1], "r")) == NULL) {
  42.         perror("fopen(3)");
  43.         exit(EXIT_FAILURE);
  44.     }
  45.  
  46.     atexit(close_fd);
  47.  
  48.     while(feof(fp) == 0) {
  49.         term_w = line_count(fp);
  50.         pad_line++;
  51.         if(term_w > pad_w)
  52.             pad_w = term_w;
  53.     }
  54.  
  55.     if(initscr() == NULL) {
  56.         perror("initscr(3)");
  57.         exit(EXIT_FAILURE);
  58.     }
  59.  
  60.     cbreak();
  61.     noecho();
  62.  
  63.     scrollok(stdscr, FALSE);
  64.  
  65.     pad = newpad(pad_line, ++pad_w);
  66.  
  67.     fseek(fp, 0, SEEK_SET);
  68.     buff = (char *)malloc(sizeof(char) * pad_w);
  69.  
  70.     for(pad_y = 0; pad_y < pad_line; pad_y++) {
  71.         fgets(buff, pad_w, fp);
  72.         mvwprintw(pad, pad_y, 0, "%s", buff);
  73.     }
  74.     free(buff);
  75.     refresh();
  76.     prefresh(pad, 0, 0, 0, 0, LINES - 1, COLS -1);
  77.     pad_y = 0;
  78.     pad_x = 0;
  79.  
  80.     curs_set(0);
  81.  
  82.     while(answer == 1) {
  83.         ch = getkey();
  84.  
  85.         switch(ch) {
  86.             case DOWN:
  87.                 if(pad_y < pad_line - LINES)
  88.                     ++pad_y;
  89.                 break;
  90.             case UP:
  91.                 if(pad_y == 0) 
  92.                     pad_y += 0;
  93.                 else if(pad_y != 0)
  94.                     --pad_y;
  95.                 break;
  96.             case LINE_TAB:
  97.                 if(pad_y < pad_line - LINES - 20)
  98.                     pad_y += 20;
  99.                 break;
  100.             case QUIT:
  101.                 answer = 0;
  102.                 break;
  103.             case LINE_TOP:
  104.                 pad_y = 0;
  105.                 break;
  106.             case LINE_END:
  107.                 pad_y = pad_line - LINES;
  108.                 break;
  109.         }
  110.         prefresh(pad, pad_y, pad_x, 0, 0, LINES - 1, COLS - 1);
  111.     }
  112.  
  113.     exit(EXIT_SUCCESS);
  114. }
  115.  
  116. void close_fd(void) {
  117.     endwin();
  118.     fclose(fp);
  119. }
 /* main.c */
#include <stdio.h>
#include <stdlib.h>
#include <curses.h>
#include <message.h>

#define UP       1
#define DOWN     2
#define RIGHT    3
#define LEFT     4
#define LINE_TAB 6
#define LINE_TOP 7
#define LINE_END 8
#define QUIT     9

extern long line_count(FILE *fp);
extern int getkey(void);
void close_fd(void);

FILE *fp = NULL;

int main(int argc, char **argv)
{
    int term_w   = 0;
    int pad_line = 0;
    int pad_w    = 0;
    int pad_y;
    int pad_x;
    char *buff;
    int ch;
    int answer = 1;

    WINDOW *pad;

    if(argc < 2) {
        print_help();
        print_version();
        exit(EXIT_FAILURE);
    }

    if((fp = fopen(argv[1], "r")) == NULL) {
        perror("fopen(3)");
        exit(EXIT_FAILURE);
    }

    atexit(close_fd);

    while(feof(fp) == 0) {
        term_w = line_count(fp);
        pad_line++;
        if(term_w > pad_w)
            pad_w = term_w;
    }

    if(initscr() == NULL) {
        perror("initscr(3)");
        exit(EXIT_FAILURE);
    }

    cbreak();
    noecho();

    scrollok(stdscr, FALSE);

    pad = newpad(pad_line, ++pad_w);

    fseek(fp, 0, SEEK_SET);
    buff = (char *)malloc(sizeof(char) * pad_w);

    for(pad_y = 0; pad_y < pad_line; pad_y++) {
        fgets(buff, pad_w, fp);
        mvwprintw(pad, pad_y, 0, "%s", buff);
    }
    free(buff);
    refresh();
    prefresh(pad, 0, 0, 0, 0, LINES - 1, COLS -1);
    pad_y = 0;
    pad_x = 0;

    curs_set(0);

    while(answer == 1) {
        ch = getkey();

        switch(ch) {
            case DOWN:
                if(pad_y < pad_line - LINES)
                    ++pad_y;
                break;
            case UP:
                if(pad_y == 0) 
                    pad_y += 0;
                else if(pad_y != 0)
                    --pad_y;
                break;
            case LINE_TAB:
                if(pad_y < pad_line - LINES - 20)
                    pad_y += 20;
                break;
            case QUIT:
                answer = 0;
                break;
            case LINE_TOP:
                pad_y = 0;
                break;
            case LINE_END:
                pad_y = pad_line - LINES;
                break;
        }
        prefresh(pad, pad_y, pad_x, 0, 0, LINES - 1, COLS - 1);
    }

    exit(EXIT_SUCCESS);
}

void close_fd(void) {
    endwin();
    fclose(fp);
}
with line numberplain text
  1.  /* size.c */
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <termios.h>
  5. #include <unistd.h>
  6. #include <sys/ioctl.h>
  7.  
  8. #define UP       1
  9. #define DOWN     2
  10. #define RIGHT    3
  11. #define LEFT     4
  12. #define LINE_TAB 6
  13. #define LINE_TOP 7
  14. #define LINE_END 8
  15. #define QUIT     9
  16.  
  17. long line_count(FILE *fp) {
  18.     long read_line = 0;
  19.     int ch;
  20.  
  21.     while((ch = fgetc(fp)) != '\n' && ch != EOF) 
  22.         read_line++;
  23.  
  24.  
  25.     return read_line;
  26. }
  27.  
  28. int getkey(void) {
  29.     char ch;
  30.     struct termios tty, save;
  31.  
  32.     if(ioctl(0, TCGETS, &tty) == EOF) {
  33.         perror("ioctl(2)");
  34.         exit(EXIT_FAILURE);
  35.     }
  36.     save = tty;
  37.     tty.c_cc[VMIN] = 1;
  38.     tty.c_lflag &= ~ECHO;
  39.  
  40.     if(ioctl(0, TCSETS, &tty) == EOF) {
  41.         perror("ioctl(2)");
  42.         exit(EXIT_FAILURE);
  43.     }
  44.  
  45.     if(read(0, &ch, 1) == EOF) {
  46.         perror("read(2)");
  47.         exit(EXIT_FAILURE);
  48.     }
  49.  
  50.     if(ch == 'k')
  51.         return UP;
  52.     else if(ch == 'j')
  53.         return DOWN;
  54.     else if(ch == 'q') {
  55.         ioctl(0, TCSETS, &save);
  56.         return QUIT;
  57.     }
  58.     else if(ch == 'd')
  59.         return LINE_TAB;
  60.     else if(ch == 'G')
  61.         return LINE_END;
  62.     else if(ch == 'g') {
  63.         if(read(0, &ch, 1) == EOF) {
  64.             perror("read(2)");
  65.             exit(EXIT_FAILURE);
  66.         }
  67.         if(ch == 'g')
  68.             return LINE_TOP;
  69.         else
  70.             return 0;
  71.     }
  72.  
  73.     return EOF;
  74. }
 /* size.c */
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
#include <sys/ioctl.h>

#define UP       1
#define DOWN     2
#define RIGHT    3
#define LEFT     4
#define LINE_TAB 6
#define LINE_TOP 7
#define LINE_END 8
#define QUIT     9

long line_count(FILE *fp) {
    long read_line = 0;
    int ch;

    while((ch = fgetc(fp)) != '\n' && ch != EOF) 
        read_line++;


    return read_line;
}

int getkey(void) {
    char ch;
    struct termios tty, save;

    if(ioctl(0, TCGETS, &tty) == EOF) {
        perror("ioctl(2)");
        exit(EXIT_FAILURE);
    }
    save = tty;
    tty.c_cc[VMIN] = 1;
    tty.c_lflag &= ~ECHO;

    if(ioctl(0, TCSETS, &tty) == EOF) {
        perror("ioctl(2)");
        exit(EXIT_FAILURE);
    }

    if(read(0, &ch, 1) == EOF) {
        perror("read(2)");
        exit(EXIT_FAILURE);
    }

    if(ch == 'k')
        return UP;
    else if(ch == 'j')
        return DOWN;
    else if(ch == 'q') {
        ioctl(0, TCSETS, &save);
        return QUIT;
    }
    else if(ch == 'd')
        return LINE_TAB;
    else if(ch == 'G')
        return LINE_END;
    else if(ch == 'g') {
        if(read(0, &ch, 1) == EOF) {
            perror("read(2)");
            exit(EXIT_FAILURE);
        }
        if(ch == 'g')
            return LINE_TOP;
        else
            return 0;
    }

    return EOF;
}
with line numberplain text
  1.  /* message.h */
  2. void print_help(void) {
  3.     printf("Usage: ./less [Filename]\n");
  4. }
  5.  
  6. void print_version(void) {
  7.     printf("Version: 1.0.0\n");
  8. }
 /* message.h */
void print_help(void) {
    printf("Usage: ./less [Filename]\n");
}

void print_version(void) {
    printf("Version: 1.0.0\n");
}