Хрестоматия по программированию на Си в Unix



         

Примеры. Хрестоматия по программированию на Си в Unix - стр. 4


if( mychdir(newdir) < 0){ /* не могу перейти в каталог */ Message("Не могу перейти в %s", *newdir ? newdir : "???"); beep(); return (-1); } if( ReadDir(CWD, &wd->d)){ /* содержимое изменилось */ InitTblFromDir (wd, YES, oldbase); return 1; } return 0; } /* Проверить содержимое обеих панелей */ void checkBothPanes(){ /* Случай NON_VALID нужен только для того, чтобы Init... восстановил "аварийную" картинку в панели */ if( ReadDir(tpane1.d.name, &tpane1.d) NON_VALID(&tpane1.d)) InitTblFromDir(&tpane1, NO, NULL); if( tpane1.t.exposed == NO ) TblDraw(&tpane1.t); if( ReadDir(tpane2.d.name, &tpane2.d) NON_VALID(&tpane2.d)) InitTblFromDir(&tpane2, NO, NULL); if( tpane2.t.exposed == NO ) TblDraw(&tpane2.t); } /*-----------------------------------------------------------------* * Ввод команд и выдача подсказки. * *-----------------------------------------------------------------*/ /* Особая обработка отдельных клавиш в редакторе строки */ char e_move = NO; /* кнопки со стрелками <- -> двигают курсор по строке/по таблице */ int e_hit[] = { KEY_LEFT, KEY_RIGHT, KEY_UP, KEY_DOWN, KEY_F(0), KEY_IC, ctrl('G'), ctrl('E'), ctrl('L'), ctrl('F'), ctrl('X'), ctrl('Y'), -1 }; int e_handler (LineEdit *le, int c, HandlerReply *reply){ *reply = HANDLER_CONTINUE; switch(c){ /* Перемещение по таблице без выхода из редактора строки */ case KEY_LEFT: if( !SEL_PANE !e_move){ *reply=HANDLER_SWITCH; return c; } TblPointAt(A_tbl, A_tbl->current - A_tbl->height); break; case KEY_RIGHT: if( !SEL_PANE !e_move){ *reply=HANDLER_SWITCH; return c; } TblPointAt(A_tbl, A_tbl->current + A_tbl->height); break; case KEY_DOWN: if( !SEL_PANE){ *reply=HANDLER_SWITCH; return c; } TblPointAt(A_tbl, A_tbl->current + 1); break; case KEY_UP: if( !SEL_PANE){ *reply=HANDLER_SWITCH; return c; } TblPointAt(A_tbl, A_tbl->current - 1); break; case KEY_F(0): /* F10 */ e_move = !e_move; break; case KEY_IC: if( !SEL_PANE){ *reply=HANDLER_SWITCH; return c; } TblRetag(A_tbl, A_tbl->current, T_LABEL); TblPointAt(A_tbl, A_tbl->current+1); break; /* Подстановки */ case ctrl('G'): /* подставить полное имя домашнего каталога */ LeInsStr(le, getenv("HOME")); LeInsStr(le, " "); break; case ctrl('E'): /* подставить имя выбранного файла */ if( A_tbl->nitems ) LeInsStr(le, T_ITEMF(A_tbl, A_tbl->current, 0)); LeInsStr(le, " "); break; case ctrl('L'): /* подставить имя выбранного файла из другой панели */ LeInsStr(le, T_ITEMF(B_tbl, B_tbl->current, 0)); LeInsStr(le, " "); break; case ctrl('X'): case ctrl('Y'): /* подстановка имен помеченных файлов */ { int label = (c == ctrl('X') ? T_LABEL : T_HATCH); register i; for(i=0; i < A_tbl->nitems && le->len < le->maxlen; ++i ) if( T_TST(A_tbl, i, label)){ LeInsStr(le, " "); LeInsStr(le, T_ITEMF(A_tbl, i, 0)); } } break; case ctrl('F'): /* подставить имя текущего каталога */ LeInsStr(le, CWD); LeInsStr(le, " "); break; } return c; } /* При начале редактирования ставь курсор в конец строки */ void e_pos (LineEdit *le){ le->pos = le->len; } /* Обозначить, что мы покинули редактор строки */ void e_hide(LineEdit *le){ le->sel_attrib = le->fr_attrib = le->bg_attrib = A_ITALICS; LeDraw(le); } /* Отредактировать строку в предпоследней строке окна */ char *Edit(WINDOW *w, char *src, RunType dorun){ static char CMD[MAXLEN]; /* буфер для строки команды */ int c; if(w != TOPW){ beep(); return NULL; }/* это должно быть верхнее окно */ keypad(w, TRUE); /* Проинициализировать редактор строки */ switch(dorun){ case NORUN: edit.histIn = edit.histOut = NULL; break; case RUNCMD: edit.histIn = edit.histOut = &hedit; break; case FIND: case TAG: edit.histIn = edit.histOut = &hpat; break; case CHDIR: edit.histIn = &hcwd; edit.histOut = NULL; break; } edit.line = CMD; edit.maxlen = sizeof(CMD)-1; edit.top = wlines(w)-2; edit.left = 2; edit.width = wcols (w)-4 - (1+BARWIDTH); edit.insert = YES; edit.nc = YES; edit.win = w; edit.wl_attrib = edit.bg_attrib=A_REVERSE; edit.fr_attrib=A_STANDOUT; edit.sel_attrib = A_NORMAL|A_BLINK; edit.posMe = e_pos; edit.hitkeys = (SEL_PANE ? e_hit : e_hit+5); edit.handler = e_handler; /* edit.hideMe = e_hide; вызывается ЯВНО */ /* остальные поля равны 0, т.к. edit - статическое данное */ for(;;){ strcpy(CMD, src); if(*src){ strcat(CMD, " "); } c = LeEdit( &edit ); if( LE_REFUSED(&edit) dorun != RUNCMD !*CMD c != '\n' ) break; /* курсор в нижнюю строку экрана */ attrset(A_NORMAL); move(LINES-1, 0); refresh(); resetterm(); /* приостановить работу curses-а */ putchar('\n'); /* промотать экран на строку */ system(CMD); /* выполнить команду внешним Шеллом */ fprintf(stderr,"Нажми ENTER чтобы продолжить --- ");gets(CMD); fixterm(); /* возобновить работу curses-а */ RedrawScreen(); /* перерисовать экран */ if(w == panewin){ checkBothPanes(); if(A_tbl->nitems) TblPoint(A_tbl, A_tbl->current, NO); } src = ""; /* во второй раз ничего не подставлять */ } wattrset(w, A_NORMAL); /* ? */ e_hide ( &edit ); return ( *CMD && !LE_REFUSED(&edit)) ? CMD : NULL; } /* Выдача подсказки а также сообщений об ошибках. */ /* В этом же окне можно набирать команды (dorun==RUNCMD). */ char *help(char *msg, RunType dorun){ register i; char *s; static char *helptext[] = { "ESC - выход в главное меню", "F1 - подсказка", "INS - пометить файл", "ctrl/E - подставить имя выбранного файла", "ctrl/L - подставить имя из другой панели", "ctrl/X - подставить помеченные файлы", "ctrl/Y - подставить помеченные курсивом", "ctrl/G - подставить имя домашнего каталога", "ctrl/F - подставить имя текущего каталога", "F4 - история", "F7 - переключить режим вставки/замены", "F10 - переключить перемещения по строке/по панели", }; #define HELPLINES (sizeof(helptext)/sizeof helptext[0]) Sel save_current_menu = current_menu; /* "выскакивающее" POP-UP window */ WINDOW *w = newwin(2+1+HELPLINES+1, 70, 2, (COLS-70)/2); if( w == NULL ) return NULL; current_menu = SEL_HELP; wattrset(w, A_REVERSE); /* это будет инверсное окно */ werase (w); /* заполнить инверсным фоном */ wborder(w); RaiseWin(w); /* окно появляется */ if(*msg){ wattron (w, A_BOLD); mvwaddstr(w, 1+HELPLINES, 2, msg); wattroff(w, A_BOLD); } for(i=0; i < HELPLINES; i++) mvwaddstr(w, 1+i, 2, helptext[i]); s = Edit(w, "", dorun); PopWin(); /* окно исчезает */ current_menu = save_current_menu; return s; } /*-----------------------------------------------------------------* * Управляющее меню. * *-----------------------------------------------------------------*/ int f_left(), f_right(), f_pull(), f_help(), f_sort(), f_dir(), f_bye(), f_redraw(),f_cdroot(); /* Обратите внимание, что можно указывать не все поля структуры, * а только первые. Остальные равны 0 */ #ifndef __GNUC__ Info mwrk_info[] = { /* строки для главного меню */ { "\\Current directory", 0 , f_left }, /* 0 */ { "\\Root directory", M_HATCH , f_right }, /* 1 */ { "\\Menus", 0 , f_pull }, /* 2 */ { "\1", /* гориз. черта */ 0 }, /* 3 */ { "\\Help", 0 , f_help }, /* 4 */ { "Un\\implemented", I_NOSEL }, /* 5 */ { "Change \\sorttype", 0 , f_sort }, /* 6 */ { "Look directory \\history", 0 , f_dir }, /* 7 */ { "\1", /* гориз. черта */ 0 }, /* 8 */ { "\\Quit", M_BOLD , f_bye }, /* 9 */ { "\1", /* гориз. черта */ 0 }, /* 10 */ { "\\Redraw screen", M_HATCH , f_redraw}, /* 11 */ { "Chdir both panels to /", M_HATCH , f_cdroot}, /* 12 */ { NULL, 0 } }; #else /* GNU C-компилятор 1.37 не может инициализировать поля-union-ы */ static char _gnu_[] = "Compiled with GNU C-compiler"; Info mwrk_info[] = { /* строки для главного меню */ { "\\Current directory", 0 }, { "\\Root directory", M_HATCH }, { "\\Menus", 0 }, { "\1", /* гориз. черта */ 0 }, { "\\Help", 0 }, { "Un\\implemented", I_NOSEL }, { "Change \\sorttype", 0 }, { "Look directory \\history", 0 }, { "\1", /* гориз. черта */ 0 }, { "\\Quit", M_BOLD }, { "\1", /* гориз. черта */ 0 }, { "\\Redraw screen", M_HATCH }, { "Chdir both panels to /", M_HATCH }, { NULL, 0 } }; void mwrk_init(){ mwrk_info [0].any.act = f_left; mwrk_info [1].any.act = f_right; mwrk_info [2].any.act = f_pull; mwrk_info [4].any.act = f_help; mwrk_info [6].any.act = f_sort; mwrk_info [7].any.act = f_dir; mwrk_info [9].any.act = f_bye; mwrk_info[11].any.act = f_redraw; mwrk_info[12].any.act = f_cdroot; } #endif char *mwrk_help[] = { "Перейти в левую панель", "Перейти в правую панель", "Перейти в строчное меню", "", "Выдать подсказку", "Не реализовано", "Изменить тип сортировки имен", "История путешествий", "", "Выход", "", "Перерисовка экрана", "Обе панели поставить в корневой каталог", NULL }; void m_help(Menu *m, int n, int among){ Message(mwrk_help[n]); } /* Выбор в рабочем (командном) меню */ void SelectWorkingMenu(int sel){ if(sel == NOSELECTED) sel = MnuUsualSelect( & mwrk, NO); if( M_REFUSED(&mwrk)) help("Выбери Quit", NORUN); else if(mwrk.items[sel].any.act) (*mwrk.items[sel].any.act)(); if( !done) MnuHide( & mwrk ); } f_left () { current_menu = SEL_PANE1; return 0; } f_right() { current_menu = SEL_PANE2; return 0; } f_pull () { current_menu = SEL_PULL; return 0; } f_help () { help("Нажми ENTER или набери команду:", RUNCMD); return 0; } f_sort () { SelectSortType(NOSELECTED); return 0; } f_dir () { Info *idir; if(idir = HistSelect(&hcwd, 20, 3)) cd(idir->s, &tpane2, CWD); current_menu = SEL_PANE2; return 0; } f_bye () { done++; return 0; } f_redraw() { RedrawScreen(); return 0; } f_cdroot() { cd("/", &tpane1, CWD); cd("/", &tpane2, CWD); checkBothPanes(); return 0; } /*-----------------------------------------------------------------* * Выдача информации про файл, редактирование кодов доступа. * *-----------------------------------------------------------------*/ void MYwaddstr(WINDOW *w, int y, int x, int maxwidth, char *s){ register pos; for(pos=0; *s && *s != '\n' && pos < maxwidth; ++s){ wmove(w, y, x+pos); if( *s == '\t') pos += 8 - (pos & 7); else if( *s == '\b'){ if(pos) --pos; } else if( *s == '\r') pos = 0; else { ++pos; waddch(w, isprint(*s) ? *s : '?'); } } } /* Просмотр начала файла в противоположной панели. */ void fastView( char *name, /* имя файла */ unsigned mode, /* некоторые типы файлов не просматривать */ Table *otbl /* противоположная панель */ ){ FILE *fp; register int x, y; char buf[512];




Содержание  Назад  Вперед