Operating System/System Programming(Arif Butt)

Lec11) Design and Code of UNIX more utility

Tony Lim 2021. 6. 25. 18:38
728x90

notice it is just displaying only the first file. let's fix this issue.

 

 

we add while loop and used "argv[i]" instead of "argv[1]" . this way we can iteratively stdout files.

now it works fine.

#include <stdio.h>
#include <stdlib.h>

#define	PAGELEN	20
#define	LINELEN	512

void do_more(FILE *);
int  get_input();
int main(int argc , char *argv[])
{
   int i=0;
   if (argc == 1){
       printf("This is the help page\n");
       exit (0);
   }
   FILE * fp;
   while(++i < argc){
      fp = fopen(argv[i] , "r");
      if (fp == NULL){
         perror("Can't open file");
         exit (1);
      }
      do_more(fp);
      fclose(fp);
   }  
   return 0;
}

void do_more(FILE *fp)
{
   int num_of_lines = 0;
   int rv;
   char buffer[LINELEN];
   while (fgets(buffer, LINELEN, fp)){
      fputs(buffer, stdout);
      num_of_lines++;
      if (num_of_lines == PAGELEN){
         rv = get_input();		
         if (rv == 0)//user pressed q
            break;//
         else if (rv == 1)//user pressed space bar
            num_of_lines -= PAGELEN;
         else if (rv == 2)//user pressed return/enter
	    num_of_lines -= 1; //show one more line
         else if (rv == 3) //invalid character
            break; 
      }
  }
}

int get_input()
{
   int c;		
     c=getchar();
      if(c == 'q')
	 return 0;
      if ( c == ' ' )			
	 return 1;
      if ( c == '\n' )	
	 return 2;	
      return 3;
   return 0;
}

no change in main function , major change is in do_more function.

get_input compare input as ascii code and return integer.

when we input space and press enter will display next 20 lines.

when we input just enter only one more line will be display.

 

 

after Control Sequence Introducer ( \033[ ) we can use a specific Terminal Control Code like above.

 

#include <stdio.h>
#include <unistd.h>

int main(int argc, char* argv[])
{
//how to display text
printf("\e[7m This is in reverse video\n");
printf("\033[m This is in normal video\n");
printf("\033[1m This is bold \033[m \n");
printf("\033[4m This is underlined \033[m \n");

//Changing foreground and background colours
printf("\033[35m \033[40m This is in magenta colour with black back ground \033[39m \033[49m\n");

//cursor movement
printf("\033[10G This will start from column 10 \n");
printf("\033[10;20H This will appear in row 10 column 20 \n");
printf("\033[5B This is going to appear 5 lines below \n");

getchar();
//clearing parts of the screen
printf("\033[2J");
return 0;
}

works like css in browser , decoration is added.

 

#include <stdio.h>
#include <stdlib.h>

#define	PAGELEN	20
#define	LINELEN	512

void do_more(FILE *);
int  get_input();
int main(int argc , char *argv[])
{
   int i=0;
   if (argc == 1){
       printf("This is the help page\n");
       exit (0);
   }
   FILE * fp;
   while(++i < argc){
      fp = fopen(argv[i] , "r");
      if (fp == NULL){
         perror("Can't open file");
         exit (1);
      }
      do_more(fp);
      fclose(fp);
   }  
   return 0;
}

void do_more(FILE *fp)
{
   int num_of_lines = 0;
   int rv;
   char buffer[LINELEN];
   while (fgets(buffer, LINELEN, fp)){
      fputs(buffer, stdout);
      num_of_lines++;
      if (num_of_lines == PAGELEN){
         rv = get_input();		
         if (rv == 0){//user pressed q
            printf("\033[1A \033[2K \033[1G");
            break;
         }
         else if (rv == 1){//user pressed space bar
            printf("\033[1A \033[2K \033[1G");
            num_of_lines -= PAGELEN;
         }
         else if (rv == 2){//user pressed return/enter
            printf("\033[1A \033[2K \033[1G");
	         num_of_lines -= 1; //show one more line
            }
         else if (rv == 3){ //invalid character
            printf("\033[1A \033[2K \033[1G");
            break; 
         }
      }
  }
}

int get_input()
{
   int c;		
   printf("\033[7m --more--(%%) \033[m");
     c=getchar();
      if(c == 'q')
	 return 0;
      if ( c == ' ' )			
	 return 1;
      if ( c == '\n' )	
	 return 2;	
      return 3;
   return 0;
}

using terminal code 

  1. we go up one line
  2. erase current line
  3. move to column 1

if we compile this and run with some .txt files. there won't be any unintended enter space.

 

 

#include <stdio.h>
#include <stdlib.h>

#define	PAGELEN	20
#define	LINELEN	512

void do_more(FILE *);
int  get_input(FILE*);
int main(int argc , char *argv[])
{
   int i=0;
   if (argc == 1){
      do_more(stdin);
   }
   FILE * fp;
   while(++i < argc){
      fp = fopen(argv[i] , "r");
      if (fp == NULL){
         perror("Can't open file");
         exit (1);
      }
      do_more(fp);
      fclose(fp);
   }  
   return 0;
}

void do_more(FILE *fp)
{
   int num_of_lines = 0;
   int rv;
   char buffer[LINELEN];
   FILE* fp_tty = fopen("/dev//tty", "r");
   while (fgets(buffer, LINELEN, fp)){
      fputs(buffer, stdout);
      num_of_lines++;
      if (num_of_lines == PAGELEN){
         rv = get_input(fp_tty);		
         if (rv == 0){//user pressed q
            printf("\033[1A \033[2K \033[1G");
            break;//
         }
         else if (rv == 1){//user pressed space bar
            printf("\033[1A \033[2K \033[1G");
            num_of_lines -= PAGELEN;
         }
         else if (rv == 2){//user pressed return/enter
            printf("\033[1A \033[2K \033[1G");
	         num_of_lines -= 1; //show one more line
            }
         else if (rv == 3){ //invalid character
            printf("\033[1A \033[2K \033[1G");
            break; 
         }
      }
  }
}

int get_input(FILE* cmdstream)
{
   int c;		
   printf("\033[7m --more--(%%) \033[m");
     c = getc(cmdstream);
      if(c == 'q')
	 return 0;
      if ( c == ' ' )			
	 return 1;
      if ( c == '\n' )	
	 return 2;	
      return 3;
   return 0;
}

if there are no command line argument.  instead of just printing out "this is the help page" and exit. we take standard input as a parameter with do_more function.

first example  = standard input is pointing to text file not keyborad so it will take armyfriends.txt as input.

second example = with redirection our executable file is taking the result of "cat" command as input

 

  

 

 

 

728x90