テキストエディタを作っています(1)

勉強のためにCでcursesライブラリを使ってシンプルなテキストエディタを作っています。

入力できる文字は半角英数文字(アスキーコード32から126)と改行(LF,アスキーコード10)

できたもの

  • テキストデータを入れる双方向リストを作り、リストにノード(1文字のデータ)を追加・削除する処理
  • キーボードから入力された文字をリストに追加する処理
  • 編集対象のテキストファイルを読み込み、リストに入れる処理
  • リストのテキストデータをファイルに保存する処理
#include <stdlib.h>
#include <curses.h>
#include <stdio.h>
#include <stdlib.h>

struct charactor {
  char c;
  struct charactor *prev;
  struct charactor *next;
};

struct charactor *head;
struct charactor *tail;
struct charactor *current;

struct charactor *make_new_node(char c) {
  struct charactor *new;

  if ((new = (struct charactor*)malloc(sizeof(struct charactor))) == NULL) {
    exit(EXIT_FAILURE);
  }
  new->c = c;
  new->prev = NULL;
  new->next = NULL;

  return new;
}

void add_node(char c) {
  struct charactor *new;

  new = make_new_node(c);

  /* 新しいnodeが既存のnodeを指すようにする設定 */
  new->prev = current;
  new->next = current->next;

  /* 既存のnodeが新しいnodeを指すようにする設定 */
  (new->prev)->next = new;
  (new->next)->prev = new;

  current = new;
}

void delete_node(struct charactor *target) {
  (target->prev)->next = target->next;
  (target->next)->prev = target->prev;
  current = target->prev;
  free(target);
}

void free_list() {
  struct charactor *target;
  target = head;
  while (target != tail) {
    target = target->next;
    free(target->prev);
  }
  free(tail);
}

void initialize_list() {
  head = make_new_node('\0');
  tail = make_new_node('\0');
  head->next = tail;
  tail->prev = head;
  current = head;
}

void read_file(char *file) {
  FILE *fp;
  char c;

  if ((fp = fopen(file, "r")) == NULL) {
    perror("read_file fopen");
    exit(1);
  }

  while ((c = getc(fp)) != EOF) {
    add_node(c);
  }

  if (fclose(fp) == EOF) {
    perror("read_file fclose");
    exit(1);
  }
}

void save_file(char *file) {
  FILE *fp;
  struct charactor *target;

  if ((fp = fopen(file, "w")) == NULL) {
    perror("save_file fopen");
    exit(1);
  }

  target = head->next;
  while (target != tail) {
    if (putc(target->c, fp) == EOF) {
      perror("save_file putc");
      exit(1);
    }
    target = target->next;
  }

  if (fclose(fp) == EOF) {
    perror("save_file fclose");
    exit(1);
  }
}

int main(int argc, char *argv[]) {
  FILE *fp;
  char c;
  char *file_name;

  if (argc != 2) {
    fprintf(stderr, "usage: %s <file>\n", argv[0]);
    exit(1);
  }
  file_name = argv[1];

  initialize_list();
  read_file(file_name);

  initscr();
  noecho();
  cbreak();

  while ((c = getch()) != 'q') {
    if ((32 <= c && c <= 126) || c == 10) {
      add_node(c);
    }
  }

  save_file(file_name);

  endwin();

  free_list();

  return 0;
}

やりたいこと

  • プログラムを終了させる処理(今は仮にqを入力すると終了するようになっている(qが使えないエディタになってしまっている))
  • テキストデータを保存する処理を呼び出す処理(今はプログラムが終了するときに自動的に保存するようになっている)
  • テキストデータを画面に表示する処理(今はユーザーがテキストデータを頭の中で思い浮かべながら編集しないといけない目隠しテキストエディタになっている)
  • バックスペースの処理(今はひたすら追加することしかできない)