/* Large less programed by M.Suzuki ver 0.1 2008/8/4 key binding n,j,^n scroll up p,k,^p scroll down / i-search ESC i-search cancel TAB next search(i-search only) q quit */#include <stdio.h>#include <string.h>#include <curses.h>#include <pthread.h>#define LINE_MAX 256 /* file text width max */#define False 0#define True (!False)staticpthread_mutex_tfile_mutex;staticFILE*fileFp;staticFILE*seekFp;staticfpos_tlineTop;staticfpos_tlineMax;staticboolreadMaxFlag;staticboolabortFlag;staticvoidScanWait(){pthread_mutex_lock(&file_mutex);while(lineTop+LINES>=lineMax){staticstructtimespectime10ms={0,10*1000*1000};pthread_mutex_unlock(&file_mutex);nanosleep(&time10ms,NULL);pthread_mutex_lock(&file_mutex);if(readMaxFlag){break;}}/* end of while */pthread_mutex_unlock(&file_mutex);}staticchar*ReadLine(inty,char*buff){char*text=NULL;ScanWait();pthread_mutex_lock(&file_mutex);if(lineTop+y+1<lineMax){fpos_toffset=sizeof(fpos_t)*(lineTop+y);fsetpos(seekFp,&offset);fread(&offset,sizeof(fpos_t),1,seekFp);fsetpos(fileFp,&offset);if(fgets(buff,LINE_MAX,fileFp)){text=buff;}}pthread_mutex_unlock(&file_mutex);returntext;}staticvoidDrawLine(inty){char*text;charbuff[LINE_MAX+1];text=ReadLine(y,buff);if(text==NULL){text="~";}mvinsstr(y,0,text);}staticvoidViewAll(){inty;erase();for(y=0;y<LINES;y++){DrawLine(y);}}staticvoidRollUp(){ScanWait();pthread_mutex_lock(&file_mutex);if(lineTop>=lineMax){if(readMaxFlag){pthread_mutex_unlock(&file_mutex);return;}}lineTop++;pthread_mutex_unlock(&file_mutex);move(0,0);deleteln();move(LINES-1,0);DrawLine(LINES-1);refresh();}staticvoidRollDown(){pthread_mutex_lock(&file_mutex);if(lineTop<=0){pthread_mutex_unlock(&file_mutex);return;}lineTop--;pthread_mutex_unlock(&file_mutex);move(0,0);insdelln(1);DrawLine(0);refresh();}staticvoidSearch(){charsearch[LINE_MAX];intlen=0;while(1){intkey=getch();inty=0;if(key==0x1b){break;}if(key=='\t'){y=1;}else{if(len<LINE_MAX){search[len++]=key;search[len]='\0';}}while(1){charbuff[LINE_MAX+1];if(ReadLine(y,buff)==NULL){return;}if(strstr(buff,search)){pthread_mutex_lock(&file_mutex);lineTop+=y;pthread_mutex_unlock(&file_mutex);ViewAll();break;}y++;}/* end of while */}/* end of while */}staticvoidKeyLoop(){ViewAll();while(1){intkey=getch();if(key=='q'){break;}switch(key){case'N'-'@':case'n':case'j':RollUp();break;case'P'-'@':case'p':case'k':RollDown();break;case'/':Search();break;}/* end of switch */}/* end of while */}void*ScanThread(void*arg){fpos_tfilePos;fgetpos(fileFp,&filePos);while(1){charbuff[LINE_MAX+1];fpos_tfpos=sizeof(fpos_t)*lineMax;pthread_mutex_lock(&file_mutex);fsetpos(seekFp,&fpos);fwrite(&filePos,sizeof(fpos_t),1,seekFp);lineMax++;fsetpos(fileFp,&filePos);if(fgets(buff,LINE_MAX,fileFp)==NULL){break;}fgetpos(fileFp,&filePos);if(abortFlag){break;}pthread_mutex_unlock(&file_mutex);}/* end of while */readMaxFlag=True;pthread_mutex_unlock(&file_mutex);returnNULL;}staticvoidMainLoop(){pthread_tscanThread_id;chartmpName[L_tmpnam];tmpnam(tmpName);if((seekFp=fopen(tmpName,"w+b"))==NULL){perror(tmpName);return;}pthread_mutex_init(&file_mutex,NULL);lineTop=0;lineMax=0;if(pthread_create(&scanThread_id,NULL,ScanThread,NULL)!=0){perror("ScanThread");return;}initscr();noecho();raw();cbreak();KeyLoop();nocbreak();noraw();echo();endwin();pthread_mutex_lock(&file_mutex);abortFlag=True;pthread_mutex_unlock(&file_mutex);pthread_join(scanThread_id,NULL);fclose(seekFp);remove(tmpName);}intmain(intargc,char*argv[]){char*fname=NULL;inti;for(i=1;i<argc;i++){char*p=argv[i];if(*p=='-'){/* option */}else{fname=argv[i];}}/* end of for */if(fname!=NULL){if((fileFp=fopen(fname,"r"))==NULL){perror(fname);return1;}MainLoop();fclose(fileFp);}return0;}
M.Suzuki #6984() [ C ] Rating0/0=0.00
Rating0/0=0.00-0+
[ reply ]