+ All Categories

Lab

Date post: 27-Nov-2014
Category:
Upload: kothapalli-venkata-rao
View: 508 times
Download: 4 times
Share this document with a friend
Popular Tags:
169
SYSTEM SOFTWARE AND COMPILER DESIGN LABORATORY PART – A LEX AND YACC PROGRAMS Execute the following programs using LEX : 1) a. Program to count the number of characters, words, spaces and lines in a given input file. b. Program to count the numbers of comment lines in a given C program. Also eliminate them and copy the resulting program into separate file. 2) a. Program to recognize a valid arithmetic expression and to recognize the identifiers and operators present. Print them separately. b. Program to recognize whether a given sentence is simple or compound. 3) Program to recognize and count the number of identifiers in a given input file. Execute the following programs using YACC : 4) a. Program to recognize a valid arithmetic expression that uses operators +, -, * and /. b. Program to recognize a valid variable, which starts with a letter, followed by any number of letters or digits. 5) a. Program to evaluate an arithmetic expression involving operators +, -, * and . b. Program to recognize strings ‘aaab’, ‘abbb’, ‘ab’ and ‘a’ using the grammar (anbn, n>= 0). 6) Program to recognize the grammar (an b, n>= 10). PART – B UNIX PROGRAMMING 1. a) Non-recursive shell script that accepts any number of argument and prints them in the Reverse order, (For example, if the script is named rargs, then executing rargs A B C should produce C B A on the standard output). b) C program that creates a child process to read commands from the standard input and execute them (a minimal implementation of a shell –like program). You can assume that no arguments will be passed to the commands to be executed. 2. a) Shell script that accepts two file names as arguments, checks if the permissions for these files are identical and if the permissions are identical, outputs the common permissions, otherwise outputs each file name followed by its permissions. b) C program to create a file with 16 bytes of arbitrary data from the beginning and another 16 bytes of arbitrary data from an offset of 48. Display the file contents
Transcript
Page 1: Lab

1System Software and Compiler Design

SYSTEM SOFTWARE AND COMPILER DESIGNLABORATORY

PART – A

LEX AND YACC PROGRAMS

Execute the following programs using LEX :1) a. Program to count the number of characters, words, spaces and lines in a given

input file.b. Program to count the numbers of comment lines in a given C program. Also

eliminate them and copy the resulting program into separate file.2) a. Program to recognize a valid arithmetic expression and to recognize the

identifiers and operators present. Print them separately.b. Program to recognize whether a given sentence is simple or compound.

3) Program to recognize and count the number of identifiers in a given input file.

Execute the following programs using YACC :4) a. Program to recognize a valid arithmetic expression that uses operators +, -, *

and /.b. Program to recognize a valid variable, which starts with a letter, followed by

any number of letters or digits.5) a. Program to evaluate an arithmetic expression involving operators +, -, * and .

b. Program to recognize strings ‘aaab’, ‘abbb’, ‘ab’ and ‘a’ using the grammar(anbn, n>= 0).

6) Program to recognize the grammar (an b, n>= 10).

PART – B

UNIX PROGRAMMING

1. a) Non-recursive shell script that accepts any number of argument and printsthem in the Reverse order, (For example, if the script is named rargs, thenexecuting rargs A B C should produce C B A on the standard output).

b) C program that creates a child process to read commands from the standardinput and execute them (a minimal implementation of a shell –like program).You can assume that no arguments will be passed to the commands to beexecuted.

2. a) Shell script that accepts two file names as arguments, checks if the permissionsfor these files are identical and if the permissions are identical, outputs thecommon permissions, otherwise outputs each file name followed by itspermissions.

b) C program to create a file with 16 bytes of arbitrary data from the beginning andanother 16 bytes of arbitrary data from an offset of 48. Display the file contents

Page 2: Lab

2 System Software and Compiler Design

to demonstrate how the hole in file is handled.3. a) Shell function that takes a valid directory names as an argument and recursively

descends all the subdirectories, finds the maximum length of any file in thathierarchy and writes this maximum value to the standard output

b) C program that accepts valid file names as command line arguments and foreach of the arguments, prints the type of the file (Regular file, Directory file,Character special file, Block special file, Symbolic link etc.)

4. a) Shell script that accepts file names specified as arguments and creates a shellscript that contains this file as well as the code to recreate these files. Thus ifthe script generated by your script is executed, it would recreate the originalfiles(This is same as the “bundle” script described by Brain W. Kernighan andRob Pike in “ The Unix Programming Environment”, Prentice – Hall India).

b) C program to do the following: Using fork( ) create a child process. The childprocess prints its own process-id and id of its parent and then exits. The parentprocess waits for its child to finish (by executing the wait( )) and prints its ownprocess-id and the id of its child process and then exits.

COMPILER DESIGN

5. Write a C program to implement the syntax-directed definition of “if E then S1” and“if E then S1 else S2”. (Refer Fig. 8.23 in the text book prescribed for 06CS62 CompilerDesign, Alfred V Aho, Ravi Sethi, Jeffrey D Ullman: Compilers- Principles, Techniquesand Tools, Addison-Wesley, 2007.)

6. Write a yacc program that accepts a regular expression as input and produce itsparse tree as output.

Introduction to lex

The word lexical in the traditional sense means pertaining to words. In terms ofprogramming languages, words are objects like variable names, numbers, keywords etc.Such words are traditionally called tokens.

A lexical analyzer, or lexer for short, will take input as a string of individual lettersand divide this string into tokens. Additionally, it will filter out whatever separates thetokens (the so-called white-space), i.e., lay-out characters (spaces,newlines etc.) andcomments.

The lexical analyzer is the first phase of a compiler. Its main task is to read the inputcharacters and produce as output a sequence of tokens that the parser uses for syntaxanalysis.This interaction, summarized schematically in Fig. 1.1, is commonly implementedby making the lexical analyzer be a subroutine or a co routine of the parser.

Several tools have been built for constructing lexical analyzers from special purposenotations based on regular expressions.In this section, we describe a particular tool,called Lex that has been widely used to specify lexical analyzers for a variety oflanguages. We refer to the tool as Lex compiler, and its input specification as the Lexlanguage.

Page 3: Lab

3System Software and Compiler Design

Lex is generally used in the manner depicted in Fig 1.2. First, a specification of alexical analyzer is prepared by creating a program lex.l in the lex language. Then, lex.lis run through the Lex compiler to produce a C program lex.yy.c. The program lex.yy.cconsists of a tabular representation of a transition diagram constructed from the regularexpression of lex.l, together with a standard routine that uses the table to recognizelexemes. The actions associated with regular expression in lex.l are pieces of C code andare carried over directly to lex.yy.c. Finally lex.yy.c is run through the C compiler toproduce an object program a.out, which is the lexical analyzer that transforms an inputstream into a sequence of tokens.

token

PARSERLEXICAL

ANALYZER

SYMBOLTABLE

get nexttoken

Fig. 1.1 : Interaction of lexical analyzer with parser

Lexcompiler

lex.yy.cLex source

Program lex.1

CCompiler a.outlex.yy.c

a.out Sequence oftokens

inputstream

Fig. 1.2 : Creating a lexical analyzer with Lex

Page 4: Lab

4 System Software and Compiler Design

Lex specifications

A Lex program consists of three parts :

declarations%%translation rules%%auxiliary procedures

The declarations section includes declarations of variables,constants,and regulardefinitions.

The translation rules of a lex program are statements of the formR1 {action1}R2 {action2}.... ....

Rn {action n} where each Ri is regular expression and each action i, is a programfragment describing what action the lexical analyzer should take when pattern Rimatches lexeme.Typically, action i will return control to the parser. In Lex actions arewritten in C;in general,however,they can be in any implementation language.

The third section holds whatever auxiliary procedures are needed by the actions.

THE ROLE OF PARSERThe parser obtains a string of tokens from the lexical analyzer and verifies that the

string can be generated by grammar for the source language. We expect the parser toreport any syntax errors in an intelligible fashion. It should also recover from commonlyoccurring errors so that it can continue processing the remainder of its input. We knowthat programs can contain errors at many different levels. For example, errors can be

1. Lexical ,such as misspelling an identifier,keyword,or operator.

2. Syntactic,such as arithmetic expression with unbalanced parentheses

3. Sematic,such as an operator applied to an incompatible operand.

4. Logical,such as infinitely recursive call.

Often much of the error detection and recovery in a compiler is centered around thesyntax analysis phase

LEXICAL CONVENTIONSThe notations for specifying tokens :

1. . Matches any single character except the newline (\n)

2. * Matches zero or more copies of the preceding expression.

3. [ ] A character class which matches any character within the brackets.

4. ^ Matches the beginning of a line as the first character of a regular expression.

Page 5: Lab

5System Software and Compiler Design

5. $ Matches the end of line as the last character of a regular expression.

6. \ Used to escape metacharacter.

7. + Matches one or more occurrence of the preceding regular expression.

For example [0-9]+ matches .12.,.9..but not an empty string.

8. ? Matches zero or one occurrence

9. | Matches either the preceding regular expression or the following expression. Forexample are | is | because matches any three words.

10. / Matches the preceding regular expression but only if followed by the regularexpression.

11. ( ) Groups of series of regular expressions together into a new regular expression.

12. Blanks between tokens are optional, with the exception that keywords must besurrounded by blanks, new lines, the beginning of the program, or the final dot.

Execute the following programs using LEX :1a. Program to count the number of characters, words, spaces and lines in a given

input file.

Program name: 1a.l

%{ int characters=0,spaces=0,words=0,lines=0;%}%%[\n] {lines++;}[^\t\n ]+ {characters+=yyleng,words++;}" " {spaces++;}%%int main(int argc,char *argv[]){yyin=fopen(argv[1],"r");yylex();printf("Number of characters:%d\n",characters);printf("Number of spaces:%d\n",spaces);printf("Number of words:%d\n",words);printf("Number of lines:%d\n",lines);}

Output:

$ vi sample.txtThis is the input to the first lab programon lex

Page 6: Lab

6 System Software and Compiler Design

$ lex 1a.l$ cc –o 1a lex.yy.c -ll$./1a sample.txt

Number of characters: 39Number of spaces: 9Number of words: 11Number of lines: 2

Explanation

The first section, the definition section, introduces any initial C program code wewant copied into final program. i.e. Take a variable for representing a character, line,space and words.

%{ int characters=0,lines=0,spaces=0,words=0;%}

The next section is the rules section .Each rule is made of two parts: a pattern andan action, separated by white space. The lexer that lex generates will execute the actionwhen it recognizes the pattern.

1. To count the number of line the pattern: [\n] .After lexer recognizes the [\n] patternit should perform the action .Here the action is to increment the line value, so theaction is represented by {lines++;}

2. To count the space the pattern : . ..After lexer recognizing the . . pattern it shouldperform the action. Here the action is to increment the space value, so the action isrepresented by {spaces++;}

3. To count the words and characters the regular expression : [^\t\n]+. Here ^matches the beginning of a line as the first character of a regular expression. Thetool lex provides an internal variable yyleng which contains the length of the stringour lexer recognized. + symbol matches one or more occurrence of the precedingregular expression. So the action is represented by {characters+=yyleng,words++;}

The next section is procedures section, we know that when a program is invoked,the execution starts from the function main( ). We can pass the parameters to thefunction main( ) whenever the program is invoked and are called command lineparameters. To access the command line parameters the function main should have thefollowing format :

Syntax : main(int argc, char *argv[]){

------------}

Page 7: Lab

7System Software and Compiler Design

The function main( ) can take two arguments namely argc and argv where argc mustbe an integer variable whereas argv is an array of strings.argc indicates the number ofparameters passed and argv represents a parameter that is passed to function main.

The file should be opened before reading or writing with the help of fopen function

Syntax : fopen(char *filename, char *mode)Return values-file pointer if successful.-NULL if unsuccessful.

A lex lexer reads its input from the standard I/O file yyin.The default value of yyin isstdin, since the default input source is standard input. If you to change the source youshould mentioned it explicitly.

yylex( ) : You call yylex ( ) to start or resume scanning. If a lex action does a return to passa value to the calling program ,the next call to yylex( ) will continue from the point whereit left off. All the code in the rules section is copied into yylex( ).

1b. Program to count the numbers of comment lines in a given C program. Alsoeliminate them and copy the resulting program into separate file.

Program name : 1b.l

%{ int comment=0;%}%%"/*"[\n]*.*[\n]*"*/" {comment++;}"/*"[\"*/"]* { fprintf(yyout," "); }%%int main(){yyin=fopen(argv[1],"r");yyout=fopen(argv[2],"w");yylex();printf("Number of comment lines in the given file: %d\n",comment);}

Output :

$ vi input/* this is a sample input */void main(){ int a,b,c; /* variable declaration */

Page 8: Lab

8 System Software and Compiler Design

printf(“\n hello”); /* code of the program */}

$ lex 1b.l$ cc –o 1b lex.yy.c -ll$ ./1b input outputNumber of comment lines in the given file: 3

$ cat output

void main(){ int a,b,c; printf(“\n hello”);

}

ExplanationThe first section, the definition section, introduces any initial C program code we

want copied into final program. i.e. Take a variable for representing comment line.

%{ int comment=0;%}

The next section is the rules section .Each rule is made of two parts: a pattern andan action, separated by white space. The lexer that lex generates will execute the actionwhen it recognizes the pattern.

1. C style comment line is enclosed with /* and */ characters. To count the numbersof comment line the pattern: "/*"[\n]*.*[\n]*"*/".After lexer recognizes the "/*"[\n]*.*[\n]*"*/" pattern it should perform the action.

Here the action is to increment the comment value , so the action is represented by{comment++;}. As you know . (dot) doesn.t match the newline character ,it matchesthe character.

2. Now to eliminate the comment line and then to copy the remaining content in filethe pattern : /*"[\"*/"]* . Here the metacharacter \ is to suppress the character *. Afterlexer recognizes the pattern it inserts whitespace in the place of comment line andcopies the remaining content of the file.

fprintf()functionThe function is similar to that of printf( ) except the syntax .The Prototype of fprintf is :

Syntax : fprintf(fp, "control string" , list)fp : file fpointer associated with the file.

Page 9: Lab

9System Software and Compiler Design

2a. Program to recognize a valid arithmetic expression and to recognize theidentifiers and operators present. Print them separately.

Program name : 2a.l

%{ int operatorcnt=0,identifiercnt=0,bracket=0;%}%%[+] {printf("+");operatorcnt++;}[-] {printf("-");operatorcnt++;}[*] {printf("*");operatorcnt++;}[/] {printf("/");operatorcnt++;}[a-zA-Z0-9]+ { identifiercnt++;}[(] {bracket++;}[)] {bracket--;}%%int main(){printf("Enter the expression:\n");yylex();printf("Number of Operators=%d\n", operatorcnt);printf("Number of Identifiers=%d\n",identifiercnt);if(operatorcnt >= identifiercnt || bracket!=0 || identifiercnt==1)printf("Invalid expression\n");elseprintf("Valid expression\n");}

$ lex 2a.l$ cc –o 2a lex.yy.c –ll$ ./2aEnter the expression :a+b*c+*Number of Operators = 2Number of Identifiers = 3( Press Control-d)Valid expression

$ ./2aEnter the exprexssion :(1+2*3+*Number of Operators = 2

Page 10: Lab

10 System Software and Compiler Design

Number of Identifiers = 3

{Press Control-dInvalid expression

$ ./2aEnter the exprexssion :(1+2*3)+*Number of Operators = 2Number of Identifiers = 3

{Press Control-dValid expression

ExplanationThe first section, the definition section, introduces any initial C program code we

want copied into final program. i.e. Take variables for representing the operators,identifiers and for brackets.

%{ int operatorcnt=0,identifiercnt=0,bracket=0;%}

The next section is the rules section .Each rule is made of two parts: a pattern andan action, separated by white space. The lexer that lex generates will execute the actionwhen it recognizes the pattern.

1. To recognize the operators the pattern is : [ + ] ,[ - ],[ * ],[ / ]. After lexer recognizesthe pattern it should perform the action .Here the action is to display the operatorand to count the operator, so the action is represented by

{printf("operator");operatorcnt++;}

2. To recognize the identifiers the pattern is :[a-zA-Z0-9]+ . After lexer recognizes thepattern it should perform the action .Here the action is to increments the identifiervalue.

3. To recognize the brackets the pattern is [ ( ] and [ )].After lexer recognizes thepattern it should perform the action. Here the action is to increment brackets anddecrement the bracket values respectively.

2b. Program to recognize whether a given sentence is simple or compound.

Program name : 2b.l

%{ int flag=0;%}

Page 11: Lab

11System Software and Compiler Design

%%" and " |" or " |" but " |" because " |" than " {flag=1;}%%int main(){printf("Enter the sentence:\n");yylex();if(flag==1) printf("Given sentence is compound sentence\n");else printf("Given sentence is simple sentence\n");}

Output :

$ lex 2b.l$ cc –o 2b lex.yy.c –ll$ ./2bEnter the sentenceThis is ss labThis is ss lab(Press control-d)Given sentence is simple sentence

$ ./2bEnter the sentenceI and youIyou(Press control-d)Given sentence is compund sentence

ExplanationThe first section, the definition section, introduces any initial C program code we

want copied into final program. i.e. Take variables for representing the words whichleads to a compound statement.

%{ int flag=0;%}

The next section is the rules section .Each rule is made of two parts: a pattern andan action, separated by white space. The lexer that lex generates will execute the actionwhen it recognizes the pattern.

Page 12: Lab

12 System Software and Compiler Design

1. List few words which lead to compound statement. After lexer recognizes thepattern it should perform the action .Here the action is to set the value as itrecognizes the words in the given statement

3. Program to recognize and count the number of identifiers in a given input file.

%{int count=0;%}%%("int ")|("float ")|("double ")|("char ") {int ch;ch=input();

for(;;){

if(ch==',') { count++; }

else if(ch==';') {count++;break; }

ch = input(); } }%%int main(int argc, char *argv[]){

yyin=fopen(argv[1],"r");yylex();printf("Number of identifiers are :%d\n",count);

}

Output :

$ vi input.txtint main() {

int a,b,c;char x,y;printf(“hello”);

}$ lex 3.l$ cc –o 3 lex.yy.c –ll$ ./3 input.txtNumber of identifiers are 5

Page 13: Lab

13System Software and Compiler Design

YACC Introduction

The unix utility yacc (Yet Another Compiler Compiler) parses a stream of token,typically generated by lex, according to a user-specified grammar.

2.1 Structure of a yacc file

A yacc file looks much like a lex file :

definitions%%rules%%Code

Definition : All code between %{ and %} is copied to the beginning of the resulting C file.

Rules : A number of combinations of pattern and action: if the action is more than a singlecommand it needs to be in braces.

Code : This can be very elaborate, but the main ingredient is the call to yylex, the lexicalanalyzer. If the code segment is left out, a default main is used which only calls yylex.

Definition sectionThere are three things that can go in the definitions section :C code : Any code between %{ and %} is copied to the C file. This is typically used fordefining file variables, and for prototypes of routines that are defined in the codesegment.

Definitions : The definition section of a lex file was concerned with characters; in yaccthis is tokens.

Example : %token NUMBER.

These token definitions are written to a .h file when yacc compiles thisfile.Associativity rules These handles associativity and priority of operators.

2.2 Lex Yacc interactionConceptually, lex parses a file of characters and outputs a stream of tokens; yacc

accepts a stream of tokens and parses it, performing actions as appropriate. In practice,they are more tightly coupled. If your lex program is supplying a tokenizer, the yaccprogram will repeatedly call the yylex routine. The lex rules will probably function bycalling return everytime they have parsed a token.If lex is to return tokens that yacc willprocess, they have to agree on what tokens there are.This is done as follows :

For Example

1. The yacc file will have token definition %token NUMBER in the definitions section.

2. When the yacc file is translated with yacc .d , a header file y.tab.h is created that hasdefinitions like #define NUMBER 258.

3. The lex file can then call return NUMBER, and the yacc program can match on thistoken.

Page 14: Lab

14 System Software and Compiler Design

2.3 Rules sectionThe rules section contains the grammar of the language you want to parse. This

looks like statement :

INTEGER ‘=’ expression| expression;expression : NUMBER ‘+’ NUMBER| NUMBER ‘-‘ NUMBER;

This is the general form of context-free grammars, with a set of actions associatedwith each matching right-hand side. It is a good convention to keep non-terminals(names that can be expanded further) in lower case and terminals (the symbols that arefinally matched) in upper case. The terminal symbols get matched with return codesfrom the lex tokenizer. They are typically defines coming from %token definitions in theyacc program or character values.

Compiling and running a simple parserOn a UNIX system, yacc takes your grammar and creates y.tab.c, the C Language

parser, and y.tab.h, the include file with the token number definitions. Lex createslex.yy.c,the C language lexer .You need only compile them together with the yacc and lexlibraries. The Libraries contain usable default versions of all of the supporting routines,including main( ) that calls the parser yyparse( ) and exits.

$ lex filename.l /* makes lex.yy.c */$ yacc -d filename.y /* makes y.tab.c and y.tab.h */$ cc lex.yy.c y.tab.c –ll /* compile and link C files */$ ./a.out

Execute the following programs using YACC :

4a. Program to recognize a valid arithmetic expression that uses operators +, -, *and /.

Lex file-name : 4a.l

%{#include "y.tab.h"%}%%[a-zA-Z][a-zA-Z0-9]* {return ID;}[0-9]+ {return NUMBER;}. {return yytext[0];}\n {return 0;}%%

Page 15: Lab

15System Software and Compiler Design

Yacc file-name : 4a.y

%token NUMBER ID%left '+''-'%left '*''/'%%expr:expr '+' expr;|expr '-' expr;|expr '*' expr;|expr '/' expr;|'('expr')'|NUMBER|ID;%%int main(){printf("Enter the Expression\n");yyparse();printf("Valid Expression\n");}int yyerror(){printf("Expression is invalid\n");exit(0);}

Output :

$ lex 4a.l$ yacc –d 4a.y$ cc –o 4a lex.yy.c y.tab.c –ll$ ./4aEnter the Expressiona+b*cValid Expression$./4aEnter the Expressiona+b*cExpression is invalid

ExplanationLEXER(lex code)

We need a lexer to feed it tokens. The yyparse( ) parser is the high level routine, andcalls the lexer whenever it needs a token from the input .As soon as the lexer finds tokenof interest to the parser ,it return to the parser ,returning the token code as value. Yacc

Page 16: Lab

16 System Software and Compiler Design

defines the token names in the parser as C preprocessor names in y.tab.h so the lexer canuse them.

1. Strings of digits are number ,To match the string of digit the pattern is : [0-9]+.Action is to return the token NUMBER value.

2. Strings of alphabets are identifiers. To match an identifiers the pattern[a-zA-z][a-zA-Z0-9]*. Action is to return the token ID value.

3. . (dot) matches a character. Whenever a lexer matches a token , the text of the tokenis stored in the null terminated string yytext . This rule says to return any characterotherwise not handled as a single character token to the parser. Character token areusually punctuation such as parentheses ,semicolons and single-character operator.If the parser receives a token that it doesn.t know about ,it generates a syntax error,so this rule lets you handle all of the single-character tokens easily while lettingyacc.s error checking catch and complain about invalid input.

4. A newline (\n) character returns an end of input token(number zero ) to tell theparser that there is no more to read.

PARSER(Yacc code)The token definition for the number ad identifiers %token NUMBER IDYacc lets you to specify the operator precedence.s explicitly.

%left ‘+’’-‘%left ‘*’’/’

Each of these declarations defines a level of precedence. That .+.and .-. are leftassociative and have lower precedence level,.*. and ./. are left associative and have thehigher precedence level.

Grammar for an valid Expression is as followsexpr:expr '+' expr;|expr '-' expr;|expr '*' expr;|expr '/' expr;|'('expr')'|NUMBER|ID

yyparse( ) : The entry point to a yacc-generated parser is yyparse ( ).Whenever yourprograms call yyparse( ) ,the parser attempts to parse an input stream. The parser returnsa value of zero if the parse succeeds and non-zero if not.

yyerror( ) : Whenever a yacc parser detects a syntax error ,it calls yyerror ( ) to reportthe error to the user.

4b. Program to recognize a valid variable, which starts with a letter, followed by anynumber of letters or digits.

Lex file-name : 4b.l

Page 17: Lab

17System Software and Compiler Design

%{#include"y.tab.h"%}%%[0-9] {return DIG;}[a-z] {return LET;}. {return yytext[0];}\n {return 0;} /*Logical EOF*/%%

Yacc file-name : 4b.y

%token LET%token DIG%%stmt:id {printf("Valid identifier \n");};id: letter next| letter {;};next: letter next| digit next| letter| digit {;};letter: LET {;};digit: DIG {;};%%int main(){printf("Enter an identifier:");yyparse();}int yyerror(){printf("Not a valid identifier\n");exit(0);}

Output :

$ lex 4b.l$ yacc –d 4b.y$ cc –o 4b lex.yy.c y.tab.c –ll

Page 18: Lab

18 System Software and Compiler Design

$./4bEnter an identifier :abc21Valid indetitifier$./4bEnter an identifier :21abcNot a valid identifier

ExplanationLEXER(lex code)

1. To match the digit the pattern is [0-9].Action is to return the token DIG value.2. To match the letter the pattern is [a-z].Action is to return the token DIG value.

PARSER(yacc code)The grammar to recognize a valid identifierstatement: id;id: letter next| letter {;};next: letter next| digit next| letter| digit {;};letter: LET {;};digit: DIG {;}

5a. Program to evaluate an arithmetic expression involving operators +, -, * and .

Lex File-name : 5a.l

%{#include"y.tab.h"extern int yylval;%}%%[0-9]+ {yylval=atoi(yytext); return(NUM);}[ \t];. {return yytext[0];}\n {return 0;}%%

Yacc file-name : 5a.y

%token NUM

Page 19: Lab

19System Software and Compiler Design

%left '+''-'%left '*''/'%%stmt : expr { printf("Result:%d\n",$1);return 0; };expr :expr'+'expr {$$=$1+$3;}| expr'-'expr {$$=$1-$3;}| expr'*'expr {$$=$1*$3;}| expr'/'expr {$$=$1/$3;}| '('expr')' {$$=-$2;}| NUM {$$=$1;};%%int main(){printf("Enter the expression\n");yyparse();}int yyerror(){printf("Invalid input\n");exit(0);}

Output :

$ lex 5a.l$ yacc –d 5a.y$ cc –o 5a lex.yy.c y.tab.c -ll$ ./5aEnter the expression5+3Result:8$./5aEnter the expression4*5+2Result:22

ExplanationLexer

String of digit is number ,whitespace is ignored. Whenever the lexer returns a tokento the parser ,if the toke has an associated value, the lexer must store the value in yylvalbefor returning. We explicitly declare yylval.

ParserThe grammar is as followsexpr :expr'+'expr {$$=$1+$3;}

Page 20: Lab

20 System Software and Compiler Design

| expr'-'expr {$$=$1-$3;}| expr'*'expr {$$=$1*$3;}| expr'/'expr {$$=$1/$3;}| '('expr')' {$$=-$2;}| NUM {$$=$1;};

5b. Program to recognize strings .aaab., .abbb., .ab. and .a. using the grammar (anbn , n>= 0).

Lex file-name : 5b.l

%{#include"y.tab.h"%}%%a {return A;}b {return B;}. {return yytext[0];}\n {return yytext[0];}%%

Yacc file-name : 5b.y

%token A B%%str : s'\n' {return 0;}s : A s B ;| ;%%int main(){printf("Enter the string\n");yyparse();printf("Valid string");}int yyerror(){printf("Invalid string");exit(0);}

Output :

$ lex 5b.l$ yacc –d 5b.y

Page 21: Lab

21System Software and Compiler Design

$ cc –o 5b lex.yy.c y.tab.c –ll$ ./5bEnter the stringaaaabbbbvalid string$ ./5bEnter the stringaabbbbInvalid string

ExplanationLEXERTo match the string .a. the pattern is .a.. Action is to return the token A value .To match the string .b. the pattern is .b.. Action is to return the token B value .

PARSERThe grammar is as follow: string : s'\n's : A s B ;

6. Program to recognize the grammar (an b, n>=10).

Lex file-name : 6.l

%{#include"y.tab.h"%}%%a {return A;}b {return B;}. {return yytext[0];}\n {return yytext[0];}%%

Yacc file-name : 6.y

%token A B%%str: s'\n' {return 0;}s : A A A A A A A A A A x B ;x : A x| ;%%int main(){printf("Enter the string\n");yyparse();

Page 22: Lab

22 System Software and Compiler Design

printf("Valid string");}int yyerror(){printf("Invalid string");exit(0);}

Output :

$ lex 6.l$ yacc –d 6.y$ cc –o 6 lex.yy.c y.tab.c –ll$./6Enter the stringaaaaaaaaaaaabValid string$./6Enter the stringaabInvalid string

ExplanationLEXER1.To match the string .a. the pattern is .a.. Action is to return the token A value .2.To match the string .b. the pattern is .b.. Action is to return the token B value .

PARSERThe grammar is as follow: string : s ‘\n’s : A A A A A A A A A A x B ;x : A x| ;

INTRODUCTION TO SHELL PROGRAMMING

A set of commands that are taken together as a single unit within a file and executedat a stretch is called a shell program or a shell script. A shell script is named just like allother files. However, by convention shell script name uses .sh extension. A shell programruns in the interpretive mode, that is, one statement is executed at a time.

Example :

#!/bin/sh

echo “Today’s date is :’date’” #to display the date

echo “My shell : $SHELL”

example.sh

Page 23: Lab

23System Software and Compiler Design

The first line is interpreter line. Here, this line specifies the shell we are using i.eBourne shellA shell script is executed by using the shell command sh as shown below.

$sh example.sh

Today.s date is : Sat Jan 27 09:10:18 IST 2004My Shell :/bin/sh

CommentsIn shell scripts comments are written using the hash (#) character as the first

character of the comment line.

The read CommandThe read command or statement is the shell.s internal tool for taking the input from

the user ,i.e., making scripts interactive. It is used with one or more variables. Inputsupplied through the standard input is read into the variables.

When you use a statement like read x the script pauses at that point to take inputfrom the keyboard. Whatever you enter is stored in the variable x. Since this is a form ofassignment ,no $ is used before x. To display that value we have to use $ symbol alongwith variable.

Special parameters Used by Shell.

Variable Significance

$#

$*

$0

$1, $2, $3, .....

$?

$$

$!

Number of arguments specified in command line.

Complete set of positional parameters as a single string.

Name of the file or executed command.

Positional parameters representing command line arguments.

Exit status of last executed command.

PID of current shell.

PID of the last background job.

#!/bin/sh

echo “Enter the value of x”

read x

echo “The value of x is : $x”

value.sh

Page 24: Lab

24 System Software and Compiler Design

Using command line

$ sh command.sh cse ise

The program Name:command.shThe number of arguments specified is :2The arguments are : cse iseValue of cse and ise

The first argument is read by the shell into the parameter $1 ,the second argumentinto $2.We can use more positional parameters in this way up to $9.(and using the shiftcommand, you can go beyond.

The if ConditionalThis is the simplest of all the branching control structures. It has the following

general formats.

Every if is close with corresponding fi ,and you.ll encounter an error of one is notpresent. If command succeeds ,the sequence of commands following it is executed .Ifcommand fails,then the else statement(if present) is executed.

Using test and [ ] to evaluate expressions.When you use if to evaluate expressions, you need the test statement because the

true or false values returned by expressions can.t be directly handled by if. test Usescertain operators to evaluate the condition and either a true or false exit status,which isthen used by if for making decisions.

#!/bin/sh

echo “The program name : $0”

echo “The number of arguments specified is : $#”

echo “The arguments are : $*”

command.sh

echo “Value of $1 and $2”

it

fs

Page 25: Lab

25System Software and Compiler Design

Numerical comparison operators used by test

The operators begins with . (hyphen) ,followed by a two-letter string. The operatorsare quite mnemonic; -eq implies equal to ,-lt less than and so on.

Example :$ a=8 ; b=9 ;$ $a .eq $b ; echo $?$ 1$ test $a .lt $b$ 0

expr : Computationexpr can perform basic arithmetic operations (+,-,*,/,%).

$ a=2 ; b=9$ c= ‘expr $x + $y ‘ ; echo .$c.$ 11

The operands must be enclosed on either side by whitespace. For multiplication wehave to use \ (Escaping technique) to prevent the shell from interpreting it asmetacharacter.

while Loopingwhile statement repeatedly performs a set of instructions until the control command

returns a true exit status. The general syntax of this :

while condition is true docommands done

The commands enclosed by do and done are executed repeatedly as long ascondition remains true.

The case conditionalIn case statement ,the statement which matches an expression is executed. The

general syntax of the case statement is as follows :

Operator Meaning

-eq

-ne

-gt

-ge

-lt

-le

Equal to

Not equal to

Greater than

Greater than or equal to

Less than

Less than or equal to

Page 26: Lab

26 System Software and Compiler Design

case expression inpattern1)command1;;pattern2)command2;;pattern3)command2;;....esac

case first matches expression with pattern1.If match succeeds, the it.s executescommand1.If matches fails, the pattern2 is matched ,and so forth. Each command list isterminated with a pair of semicolons, and the entire construct is closed with esac(reverse of case).

eval commandThe use of eval command makes the shell to scan the command line once more, that

is, second time and then actually executes the command line.

Example :$ b=a$ c=b$ eval echo \$$c$ a

The first two statements in this example are assignment statement. When the shellcomes cross the third statement, because of eval; it first scans the statements once forany possible pre-evaluation or substitution. Here because of metacharacter \ the first $is overlooked and the next variable $c gets evaluated resulting b. After this evaluation thethird statement will be equivalent to echo $b. Then this statement gets executed as usualby the shell resulting as the answer.

PART B

UNIX PROGRAMMING

1. a) Non-recursive shell script that accepts any number of arguments andprints them in the reverse order.

Filename : 1a.sh

echo "number of arguments are : $#"len=$#while [ $len -ne 0 ] do eval echo \$$len len=`expr $len - 1` done

Page 27: Lab

27System Software and Compiler Design

Output :

$ sh 1a.sh 1 2 3number of arguments are : 3321$ ./1a.sh rahul raj raninumber of arguments are : 3ranirajrahul

Explanation :The special shell parameters $# holds the number of arguments passed in the

command line .Assume you are passing three arguments X Y Z .So $# value will be 3. Thewhile loop does the operation still control command returns a true exit status.

The use of eval command makes the shell to scan the command line once more, thatis, second time and then actually executes the command line. Here because ofmetacharacter \ the first $ is overlooked and the next variable $len is gets evaluatedresulting 3. After this evaluation the statement will be equivalent to echo $3. So thepositional parameter $3 value is displayed and so on the remaining positional parametervalue is displayed. While evaluating the expression the operands must be enclosed oneither side by whitespace.

1. b) C program that creates a child process to read commands from thestandard input and execute them ( a minimal implementation of a shell �����like a program). You can assume that no arguments will be passed to thecommands to be executed.

Filename : 1b.c

#include<stdio.h>#include<sys/types.h>int main(){ char cmd[20]; pid_t pid; int ch; pid=fork(); if(pid == 0) { do { printf("\n Enter the command to be executed : "); scanf("%s",cmd);

Page 28: Lab

28 System Software and Compiler Design

system(cmd); printf("\n Enter 1 to continue and 0 to exit : "); scanf("%d",&ch); } while(ch!=0); } wait();}

Output :

$ cc 1b.c$ ./a.out

Enter the command to be executed : datewed Dec 16 11:05:52 IST 2009

Enter 1 to continue and 0 to exit : 1Enter the command to be executed : cal December 2009Su Mo Tu We Th Fr Sa 1 2 3 4 56 7 8 9 10 11 1213 14 15 16 17 18 1920 21 22 23 24 25 2627 28 29 30 31

Explanation :All processes in a UNIX system ,expect the very first process (Process 0) which is

created by the system boot code and remaining are created via the fork system call.

The fork system call is used to create a child process .The function prototype of forkis :

#include <unistd.h>pid_t fork(void);

Returns : 0 in child, process ID of child in parent, -1 on error

The new process created by fork is called the child process. This function is calledonce but returns twice. The only difference in the returns is that the return value in thechild is 0, whereas the return value in the parent is the process ID of the new child. Thereason the child’s process ID is returned to the parent is that a process can have morethan one child, and there is no function that allows a process to obtain the process IDsof its children. The reason fork returns 0 to the child is that a process can have only asingle parent, and the child can always call getppid to obtain the process ID of its parent.(Process ID 0 is reserved for use by the kernel, so it’s not possible for 0 to be the processID of a child.)

Page 29: Lab

29System Software and Compiler Design

System functionThe system function allows the users to access the standard output or standard input

of the executed command. The function prototype of system function.

#include <stdlib.h>int system(const char *smdstring);

Returns : See below

If cmdstring is a null pointer, system returns nonzero only if a command processoris available. Because system is implemented by calling fork, exec, and waitpid, there arethree types of return values.

1. If either the fork fails or waitpid returns an error other than EINTR, system returns1 with errno set to indicate the error.

2. If the exec fails, implying that the shell can’t be executed, the return value is as if theshell had executed exit(127).

3. Otherwise, all three functions fork, exec, and waitpidsucceed, and the return valuefrom system is the termination status of the shell, in the format specified for waitpid.

Wait functionWhen a process terminates, either normally or abnormally, the kernel notifies the

parent by sending the SIGCHLD signal to the parent. Because the termination of a childis an asynchronous event it can happen at any time while the parent is running this signalis the asynchronous notification from the kernel to the parent. The parent can choose toignore this signal, or it can provide a function that is called when the signal occurs: asignal handler. The default action for this signal is to be ignored. So we need to be awarethat a process that calls wait .The function prototype of wait function

#include <sys/wait.h>pid_t wait(int *statloc);

Return : process ID, or 1 on error

2. a) Shell script that accepts two file names as arguments, checks if thepermissions of these files are identical and if the permissions are identical,outputs the common permission, otherwise outputs each file name followedby its permission.

Filename : 2a.sh

ls -l $1 | cut –c 1-10 > file1perls -l $2 | cut -c 1-10 > file2perif cmp file1per file2perthenecho "Both the files have same permission"cat file1perelse

Page 30: Lab

30 System Software and Compiler Design

echo "Both the files have different permission"echo "The permission of first file $1 is "cat file1perecho "The permission of second file $2 is "cat file2perfi

Output :

$cat > file1this is first file content$cat > file2this is second file content$sh 2a.sh file1 file2Both the files have same permission-rw-r--r--$chmod 777 file2$sh 2a.sh file1 file2file1per file2per differ: byte 4, line 1Both the files have different permissionThe permission of first file file1 is-rw-r--r--The permission of second file file2 is-rwxrwxrwx

Explanation :Listing the file attributes is done with ls � l (long) option. This option displays all the 7attributes of a file - like its permission, links, owner, group owner, size, last modificationtime and filename.

$ ls – ltotal 45-rw-r—r-- 1 root root 65 Dec 16 10:89 input.txt

To extract the specific field we need to use simple filter cut follows with .c optionwith a list of column numbers. Ranges can be specified using the hyphen. To extract thepermission field we have use cut c � 1-10. Here we are using pipeline mechanism toredirect the output of ls � l to the simple filter cut. A pipe is general mechanism by usingwhich ,the output of one program is redirected as the input to another program directlywithout using any temporary files in between. In pipeline , the command on the left ofthe | must use standard output and the one on the right must use standard input.

2. b) C program to create a file with 16 bytes of arbitary data from the beginningand another 16 bytes of arbitary data from an offset of 48. Display the filecontents to demonstrate how the hole in file is handled.

Page 31: Lab

31System Software and Compiler Design

Filename : 2b.c

#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<unistd.h>int main() { int fd; char buf1[]="Department of IS"; char buf2[]="Department of CS"; fd=creat("ise",0622); if(fd < 0) { printf("\n Error in creating file"); exit(0); } write(fd,buf1,16); lseek(fd,48,SEEK_SET); write(fd,buf2,16); exit(0); }

Output :

$cc 2b.c$./a.out$od -c ise0000000 D e p a r t m e n t o f I S0000020 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0\0 \0*0000060 D e p a r t m e n t o f C S0000100

Theoretical Explanation :creat Function

A new file can be created by calling the creat function. The function prototype ofcreat function

#include <fcntl.h>int creat(const char *pathname, mode_t mode);

Returns : file descriptor opened for write-only if OK, 1 on error

write FunctionData is written to an open file with the write function.

Page 32: Lab

32 System Software and Compiler Design

#include <unistd.h>ssize_t write(int filedes, const void *buf, size_t nbytes);

Returns: number of bytes written if OK, 1 on error

lseek FunctionEvery open file has an associated "current file offset," normally a non-negative

integer that measures the number of bytes from the beginning of the file .Read and writeoperations normally start at the current file offset and cause the offset to be incrementedby the number of bytes read or written. By default, this offset is initialized to 0 when a fileis opened, unless the O_APPEND option is specified. An open file’s offset can be setexplicitly by calling lseek. The function prototype of lseek function :

#include <unistd.h>off_t lseek(int filedes, off_t offset, int whence);

Returns: new file offset if OK, 1 on error

The interpretation of the offset depends on the value of the whence argument.

• If whence is SEEK_SET, the file’s offset is set to offset bytes from the beginning of thefile.

• If whence is SEEK_CUR, the file’s offset is set to its current value plus the offset. Theoffset can be positive or negative.

• If whence is SEEK_END, the file’s offset is set to the size of the file plus the offset.The offset can be positive or negative.

3. a) Shell script that takes a valid directory names as as argument andrecursively descends all the subdirectories, finds the maximum length ofany file in that hierarchy and writes this maximum valut to the standardoutput.

Filename : 3a.sh

maxsize=`ls -lR $1 | grep '^-' | cut -c 38-43 | sort -n | tail-1`echo "The max size of the file in directort $1 is $maxsize bytes"

Output :

$ls -ltotal 12-rwxr-xr-x 1 root root 148 Mar 1 22:17 1a.sh-rwxr-xr-x 1 root root 366 Mar 1 22:17 2a.sh-rwxrwxrwx 1 root root 192 Mar 1 22:17 3a.sh

$ sh 3a.sh /root/6ise/unixThe max size of the file in directort /root/6ise/unix is 366 bytes

Page 33: Lab

33System Software and Compiler Design

Explanation :

To take the input from the user we have to use read statement with a variable.Recursively to descend all the files in list we need to use ls command with � R option.Also� l is used for long listing. The output of ls command is piped to a terminal using teecommand ,as well as to a file. Then further it is piped to the simple filter cut . To extractspecific column we need use .c option with a list of column numbers, delimited by acomma. To extract the filesize field we need to use the range 38-43. Then at last the outputis redirected to an another file. To display the content of a file we can use cat command.Then the file content is sorted with respect to numerals using sort � n option. Then thesorted output is redirected to an another file. So the last line while have the maximumvalue ,we can extract that using the filter tail with �1 option from the file.

3. b) C program that accepts valid file names as coomand line arguments andfor each of the arguments, prints the type of the file ( Regular file,directory file, character special file, block special file, symbolic link etc ..)

Filename : 3b.c

#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<unistd.h>int main(int argc, char *argv[]) { int i; struct stat buf; for(i=1; i< argc; i++) { printf("%s: ", argv[i]); lstat(argv[i],&buf); if(S_ISREG(buf.st_mode)) printf("file is a regular file\n"); if(S_ISDIR(buf.st_mode)) printf("file is a directory file\n"); if(S_ISCHR(buf.st_mode)) printf("file is a character file\n"); if(S_ISBLK(buf.st_mode)) printf("file is a block file\n"); if(S_ISLNK(buf.st_mode)) printf("file is a symbolic link file\n"); } exit(0);}

Page 34: Lab

34 System Software and Compiler Design

Output :

$cc 3b.c$./a.out /root/6ise/3b.c/root/6ise/3b.c: file is a regular file$./a.out /root/6ise/3b.c /root/6ise/root/6ise/3b.c: file is a regular file/root/6ise: file is a directory file$./a.out /dev/tty/dev/tty: file is a character file

Explanation :lstat Function

#include <sys/stat.h>int lstat(const char *pathname, struct stat *buf);

Return : 0 if OK, 1 on error

Given a pathname, the stat function returns a structure of information about thenamed file. The fstat function obtains information about the file that is already open onthe descriptor filedes. The lstat function is similar to stat, but when the named file is asymbolic link, lstat returns information about the symbolic link, not the file referencedby the symbolic link.

The second argument is a pointer to a structure that we must supply. The functionfills in the structure pointed to by buf. The definition of the structure can differ amongimplementations, but it could look like

struct stat {mode_t st_mode; /* file type & mode (permissions) */ino_t st_ino; /* i-node number (serial number) */dev_t st_dev; /* device number (file system) */dev_t st_rdev; /* device number for special files */nlink_t st_nlink; /* number of links */uid_t st_uid; /* user ID of owner */gid_t st_gid; /* group ID of owner */off_t st_size; /* size in bytes, for regular files */time_t st_atime; /* time of last access */time_t st_mtime; /* time of last modification */time_t st_ctime; /* time of last file status change */blksize_t st_blksize; /* best I/O block size */blkcnt_t st_blocks; /* number of disk blocks allocated */};

Page 35: Lab

35System Software and Compiler Design

File TypesMost files on a UNIX system are either regular files or directories, but there are

additional types of files. The types are :

1. Regular file. The most common type of file, which contains data of some form.There is no distinction to the UNIX kernel whether this data is text or binary. Anyinterpretation of the contents of a regular file is left to the application processing thefile.

2. Directory file. A file that contains the names of other files and pointers to informationon these files. Any process that has read permission for a directory file can read thecontents of the directory, but only the kernel can write directly to a directory file

3. Block special file. A type of file providing buffered I/O access in fixed-size units todevices such as disk drives.

4. Character special file. A type of file providing unbuffered I/O access in variablesizedunits to devices. All devices on a system are either block special files or characterspecial files.

5. FIFO. A type of file used for communication between processes. It’s sometimescalled a named pipe.

6. Socket. A type of file used for network communication between processes. A socketcan also be used for non-network communication between processes on a singlehost.

7. Symbolic link. A type of file that points to another file.

The type of a file is encoded in the st_mode member of the stat structure. We candetermine the file type with the macros shown in below .The argument to each of thesemacros is the st_mode member from the stat structure.

File type macros in <sys/stat.h>

4. a) Shell script that accepts file names specified as arguments and creates ashell script that contains this file as well as the code to recreate these files.Thus if the script generated by your script is executed,it would recreatethe original files.

Macro Type of file

S_ISDIR()

S_ISCHR()

S_ISBLK()

S_ISFIFO()

S_ISLNK()

S_ISSOCK()

directory file

character special file

block special file

pipe or FIFO

symbolic link

socket

Page 36: Lab

36 System Software and Compiler Design

Filename : 4a.sh

echo “#to bundle,sh this file”for i in $*do

echo "echo $i 1>&2"echo "cat >$i <<'End of $i'"cat $iecho "End of $i"

done

Output :

$ls10b.c 1b.c 4a.sh 5a.sh 5b.c 6a.sh 6b.c 7a.sh 8a.sh 9a.sh a$cat > file1this is first file$cat > file2this is second file$ls10b.c 4a.sh 5b.c 6b.c 8a.sh a file21b.c 5a.sh 6a.sh 7a.sh 9a.sh file1$sh 4a.sh file1 file2 > new.sh$ls10b.c 4a.sh 5b.c 6b.c 8a.sh a file21b.c 5a.sh 6a.sh 7a.sh 9a.sh file1 new.sh$rm file1rm: remove regular file `file1'? y$rm file2rm: remove regular file `file2'? y$ls10b.c 1b.c 4a.sh 5a.sh 5b.c 6a.sh 6b.c 7a.sh 8a.sh 9a.sha new.sh$sh new.shfile1file2$ls10b.c 4a.sh 5b.c 6b.c 8a.sh a file21b.c 5a.sh 6a.sh 7a.sh 9a.sh file1 new.sh$cat file1this is first file$cat file2this is second file

Page 37: Lab

37System Software and Compiler Design

4. b) C program to do the following. Using fork( ) create a child process. Thechild process prints its own process-id and id of its parent and thenexits.The parent process waits for its child to finish(by executing wait( ))and prints its own process-id and the id of its child process and then exits.

Filename : 4b.c

#include <sys/types.h>#include <stdio.h>int main() { pid_t pid; if((pid=fork())<0) printf("fork error"); if(pid==0) { printf("\n This is child process "); printf("\n Child PID :%d",getpid()); printf("\n Parent PID :%d\n",getppid()); exit(0); } else { wait(); printf("\n This is parent process"); printf("\n Parent PID :%d",getpid()); printf("\n Child PID :%d",pid); exit(0); } }

Output :

$cc 4b.c$./a.out This is child process Child PID :3122 Parent PID :3121

This is parent process Parent PID :3121 Child PID :3122

Explanation :Every process has a unique process ID, a non-negative integer. Because the process

ID is the only well-known identifier of a process that is always unique, it is often used asa piece of other identifiers, to guarantee uniqueness. Process ID 0 is usually the

Page 38: Lab

38 System Software and Compiler Design

scheduler process and is often known as the swapper. No program on disk correspondsto this process, which is part of the kernel and is known as a system process. Process ID1 is usually the init process and is invoked by the kernel at the end of the bootstrapprocedure. In addition to the process ID, there are other identifiers for every process. Thefollowing functions return these identifiers.

#include <unistd.h>pid_t getpid(void);

Returns : process ID of calling process

pid_t getppid(void);Returns: parent process ID of calling process

5. Write a C program to implement the syntax directed definition of “if E then S1”and “if E then S1 else S2”.

/* Input to the program is assumed to be syntactically correct. The expression of ‘if’statement, statement for true condition and statement for false condition are enclosedin parenthesis */

#include <stdio.h>#include <stdlib.h>#include <conio.h>#include <string.h>int parsecondition(char[],int,char*,int);void gen(char [],char [],char[],int);

int main(){int counter = 0,stlen =0,elseflag=0;char stmt[60]; // contains the input statementchar strB[54]; // holds the expression for 'if' conditionchar strS1[50]; // holds the statement for true conditionchar strS2[45]; // holds the statement for false condition

clrscr();

printf("Format of ‘if’ statement \n Example ...\n");printf("if (a<b) then (s=a);\n");printf("if (a<b) then (s=a) else (s=b);\n\n");printf("Enter the statement \n");

gets(stmt);stlen = strlen(stmt);counter = counter + 2; // increment over 'if'

Page 39: Lab

39System Software and Compiler Design

counter = parsecondition(stmt,counter,strB,stlen);

if(stmt[counter]==')') counter++;

counter = counter + 3; // increment over 'then'

counter = parsecondition(stmt,counter,strS1,stlen);

if(stmt[counter+1]==';'){ // reached end of statement, generate the output printf("\n Parsing the input statement...."); gen(strB,strS1,strS2,elseflag); getch(); return 0;}

if(stmt[counter]==')')counter++; // increment over ')'

counter = counter + 3; // increment over 'else'

counter = parsecondition(stmt,counter,strS2,stlen);

counter = counter + 2; // move to the end of statement

if(counter == stlen){ //generate the outputelseflag = 1;printf("\n Parsing the input statement....");gen(strB,strS1,strS2,elseflag);getch();return 0;}

return 0;

}

/* Function : parseconditionDescription : This function parses the statement from the given index to get the statementenclosed in () Input : Statement, index to begin search, string to store the condition, totalstring length Output : Returns 0 on failure, Non zero counter value on success */

int parsecondition(char input[],int cntr,char *dest,int totallen){

Page 40: Lab

40 System Software and Compiler Design

int index = 0,pos = 0;while(input[cntr]!= '(' && cntr <= totallen)cntr++;if(cntr >= totallen)return 0;index = cntr;while (input[cntr]!=')')cntr++;if(cntr >= totallen)return 0;while(index<=cntr)dest[pos++] = input[index++];dest[pos]='\0'; //null terminate the stringreturn cntr; //non zero value}

/* Function : gen ()Description : This function generates three address code Input : Expression, statementfor true condition, statement for false condition, flag to denote if the 'else' part is presentin the statement output :Three address code */

void gen(char B[],char S1[],char S2[],int elsepart){int Bt =101,Bf = 102,Sn =103;

printf("\n\tIf %s goto %d",B,Bt);printf("\n\tgoto %d",Bf);printf("\n%d: ",Bt);printf("%s",S1);

if(!elsepart)printf("\n%d: ",Bf);else{printf("\n\tgoto %d",Sn);printf("\n%d: %s",Bf,S2);printf("\n%d:",Sn);}}

Output :Format of ‘if’ statementExample ...

if (a<b) then (s=a);if (a<b) then (s=a) else (s=b);

Page 41: Lab

41System Software and Compiler Design

Enter the statementif (a<b) then (s=a);Parsing the input statement....

If (a<b) goto 101goto 102101: (s=a)

102:

Output :Format of ‘if’ statementExample ...

if (a<b) then (s=a);if (a<b) then (s=a) else (s=b);

Enter the statement

if (a<b) then (x=a) else (x=b);

Parsing the input statement....

If (a<b) goto 101

goto 102

101: (x=a)goto 103

102: (x=b)

103:

/* ALTERNATE PROGRAMTo implement syntax directed translation of if-else statement */

#include <iostream>#include <string>#include <cstring>

class SyntaxDirectedTranslator {public: // Input the ifelse statement... void input(); // Parse and extract the different parts...

Page 42: Lab

42 System Software and Compiler Design

void parse(); // Generate the intermediate code... void generate();

private: std :: string ifelse; // The if-else statement char expression[51] , // Expression part statement1[51] , // 'True' part statement2[51]; // 'False' part};

int main ( int argc , char **argv ) {

// Create a Translator... SyntaxDirectedTranslator SDT;

// Input the statement... SDT.input();

// Parse... SDT.parse();

// Generate code... SDT.generate();

return 0;}void SyntaxDirectedTranslator :: input() {

// Enter the statement... std :: cout << "Enter the if-else statement --\n" << "Example : if (expr) then (s1) else (s2)\n"; std :: getline ( std :: cin , ifelse , '\n' );}

void SyntaxDirectedTranslator :: parse() {

// Skip the 'if' part... std :: size_t i = 0;

while(ifelse[i] == ' ') ++i;

i += 2; while(ifelse[i] == ' ') ++i;

Page 43: Lab

43System Software and Compiler Design

// Find the expression part... std :: size_t j = 0; while ( ifelse[i] != ')' ) expression[j++] = ifelse[i++];

expression[j++] = ifelse[i++]; expression[j] = '\0';

// Skip the 'then' part... while(ifelse[i] == ' ') ++i;

i += 4;

while(ifelse[i] == ' ') ++i;

// Next, get the 'true' statement... j = 0; while ( ifelse[i] != ')' ) statement1[j++] = ifelse[i++];

statement1[j++] = ifelse[i++]; statement1[j] = '\0';

// Check if else part is there... while(ifelse[i] == ' ') ++i;

if ( ifelse[i] == '\0' ) { statement2[0] = '\0'; return; }

// Skip the else part... i += 4; while(ifelse[i] == ' ') ++i; // Get the 'false' part... j = 0; while ( ifelse[i] != ')' ) statement2[j++] = ifelse[i++];

statement2[j++] = ifelse[i++]; statement2[j] = '\0';}

Page 44: Lab

44 System Software and Compiler Design

void SyntaxDirectedTranslator :: generate() {

// Output the generated code... std :: cout << " if " << expression << " goto 101\n" << " goto 102\n" << "101: " << statement1 << std :: endl;

if ( strlen ( statement2 ) == 0 ) { std :: cout << "102: \n"; return; } std :: cout << " goto 103\n" << "102: " << statement2 << std :: endl << "103: ";}

6. Write a yacc program that accepts a regular expression as input and produceits parse tree as output

%{#include<ctype.h>char str[20];int i=0;%}

%token id%left '+''/''*''-'%%E:S {infix_postfix(str);}S:S'+'T |S'-'T|TT:T'*'F| T'/'F|FF:id |'('S')';%%

#include<stdio.h>main(){ printf("\nEnter an identifier:"); yyparse();}

yyerror()

Page 45: Lab

45System Software and Compiler Design

{ printf("invalid");}

yylex(){char ch=' ';while(ch!='\n'){ ch=getchar(); str[i++]=ch;

if(isalpha(ch)) return id;

if(ch=='+'||ch=='*'|| ch=='-'||ch=='/') return ch;}str[--i]='\0';return(0);exit(0);}

void push(char stack[],int *top,char ch){stack[++(*top)]=ch;}

char pop(char stack[],int *top){return(stack[(*top)--]);}

int prec(char ch){switch(ch) {case '/':case '*': return 2;case '+':case '-': return 1;case '(': return 0;default: return -1; }}

Page 46: Lab

46 System Software and Compiler Design

void infix_postfix(char infix[]){int top=-1,iptr=-1,pptr=-1;char postfix[20],stack[20],stksymb,cursymb;push(stack,&top,'\0');

while((cursymb=infix[++iptr])!='\0'){switch(cursymb){case '(' : push(stack,&top,cursymb);break;case ')' :stksymb=pop(stack,&top); while(stksymb!='(') { postfix[++pptr]=stksymb; stksymb=pop(stack,&top); } break;case '*' :case '/' :case '+' :case '-' : while(prec(stack[top])>=prec(cursymb)) postfix[++pptr]=pop(stack,&top); push(stack,&top,cursymb); break;default : if(isalnum(cursymb)==0) { printf("Error in input!"); exit(0);} postfix[++pptr]=cursymb; }}

while(top!=-1)postfix[++pptr]=pop(stack,&top);

printf("%s\n",postfix);}

Output :

Enter the identifier :a+b*cabc*+

Page 47: Lab

47System Software and Compiler Design

/* ALTERNATE PROGRAM Yacc program to recognise a regular expression and produce aparse tree as output */

%{ #include <stdio.h> #include <ctype.h> #include <stdlib.h> #include <string.h>

/* To store the productions */ #define MAX 100

int getREindex ( const char* );

signed char productions[MAX][MAX]; int count = 0 , i , j; char temp[MAX + MAX] , temp2[MAX + MAX];%}

%token ALPHABET

%left '|'%left '.'%nonassoc '*' '+'

%%S : re '\n' { printf ( "This is the rightmost derivation--\n" ); for ( i = count - 1 ; i >= 0 ; --i ) { if ( i == count - 1 ) { printf ( "\nre => " ); strcpy ( temp , productions[i] ); printf ( "%s" , productions[i] ); } else { printf ( "\n => " ); j = getREindex ( temp ); temp[j] = '\0';sprintf ( temp2 , "%s%s%s" , temp , productions[i] , (temp + j+ 2) ); printf ( "%s" , temp2 ); strcpy ( temp , temp2 ); } } printf ( "\n" );

Page 48: Lab

48 System Software and Compiler Design

exit ( 0 ); }

re : ALPHABET { temp[0] = yylval; temp[1] = '\0'; strcpy ( productions[count++] , temp ); }

| '(' re ')'{ strcpy ( productions[count++] , "(re)" ); } | re '*' { strcpy ( productions[count++] , "re*" ); } | re '+' { strcpy ( productions[count++] , "re+" ); } | re '|' re { strcpy ( productions[count++] , "re | re" ); } | re '.' re { strcpy ( productions[count++] , "re . re" ); } ;%%

int main ( int argc , char **argv ) {

/* Parse and output the rightmost derivation, from which we canget the parse tree */

yyparse();

return 0;}

yylex() { signed char ch = getchar(); yylval = ch; if ( isalpha ( ch ) ) return ALPHABET; return ch;}

yyerror() { fprintf ( stderr , "Invalid Regular Expression!!\n" ); exit ( 1 );}

int getREindex ( const char *str ) { int i = strlen ( str ) - 1; for ( ; i >= 0 ; --i ) { if ( str[i] == 'e' && str[i-1] == 'r' ) return i-1;

Page 49: Lab

49System Software and Compiler Design

}}

Operators used -| is for ORing. is for concatenating* is Kleene closurea+ is equivalent to a.a*

C:\Prog6>a.outa+|b*|(b.c*)This is the rightmost derivation--

re => re | re=> re | (re)=> re | (re . re)=> re | (re . re*)=> re | (re . c*)=> re | (b . c*)=> re | re | (b . c*)=> re | re* | (b . c*)=> re | b* | (b . c*)=> re+ | b* | (b . c*)=> a+ | b* | (b . c*)

C:\Prog6>a.outa.(b|(a+))This is the rightmost derivation--

re => re . re=> re . (re)=> re . (re | re)=> re . (re | (re))=> re . (re | (re+))=> re . (re | (a+))=> re . (b | (a+))=> a . (b | (a+))

/* Some explanation of the code –Yacc generates an LR parser. Because it is LR, it matchesproductions for the rightmost derivation in REVERSE order. Theseproductions are stored in an array of strings. Once the wholeregex expression is matched then the derivation is output in thecorrect order. While outputting we need to store the currentsentential form in the string 'temp'. At each step the rightmost're' is replaced with the next production. getREindex() returnsthe position of the rightmost 're'.*/

Page 50: Lab

50 System Programming

SYSTEM PROGAMMING LABORATORY

PART – A

Execution of the following programs using LEX :1) a. Program to count the number of characters, words, spaces and lines in a given

input file.

b. Program to count the numbers of comment lines in a given program. Alsoeliminate them and copy that program into separate file.

2) a. Program to recognize a valid arithmetic expression and identify the identifiersand operators present. Print them separately.

b. Program to recognize whether a given sentence is simple or compound.

3) Program to recognize and count the number of identifiers in a given input file.Execution of the following programs using YACC. :

4) a. Program to recognize a valid arithmetic expression that uses operators +,- ,*and /.

b. Program to recognize a valid variable, which starts with a letter, followed byany number of letters or digits.

5) a. Program to evaluate an arithmetic expression involving operators +, -, * and .

b. Program to recognize strings ‘aaab’, ‘abbb’, ‘ab’ and ‘a’ using the grammar(ambn, m>0, n>=0).

6) Program to recognize the grammar (anb, n>=10).

PART – B

1) a. Non-recursive shell script that accepts any number of arguments and printsthem in a Reverse order, (For example, if the script is named rargs, then rargsA B C should produce C B A on the standard output).

b. C program that creates a child process to read commands from the standardinput and execute them (a minimal implementation of a shell – like program).You can assume that no arguments will be passed to the commands to beexecuted.

2) a. Shell script that accepts two file names as arguments, checks if the permissionsfor these files are identical and if the permissions are identical, outputs thecommon permissions, otherwise outputs each file name followed by itspermissions.

Page 51: Lab

51System Programming

b. C program to create a file with 16 bytes of arbitrary data from the beginning andanother 16 bytes of arbitrary data from an offset of 48. Display the file contentsto demonstrate how the hole in file is handled.

3) a. Shell function that takes a valid directory names as an argument and recursivelydescends all the subdirectories, finds the maximum length of any file in thathierarchy and writes this maximum value to the standard output.

b. Write a C program which accepts valid file names as command line argumentsand for each of the arguments, prints the type of the file (regular file, directoryfile, character special file, block file, symbolic link etc.).

4) a. Shell script that accepts path names and creates all the components in that pathnames as directories. For example, if the script name is mpe, then thecommand mpe a/b/c/d should create directories a, a/b, a/b/c and a/b/c/d.

b. C program that accepts one command-line argument, executes the argumentsas a shell command, determines the time taken by it and prints the time values,Use the “times”, function and the “tms” structure. The code need not includeerror checking.

5) a. Shell script that accepts valid log-in names as arguments and prints theircorresponding home directories. If no arguments are specified, print a suitableerror message.

b. C program that accepts valid directory names as a command line argument andlists all the files in the given directory as well as all the subsequent subdirectories.(The solution can be recursive or non-recursive).

6) a. Shell script to implement terminal locking. It should prompt the user for apassword. After accepting the password entered by the user, it must promptagain for password confirmation (to retype the password). If a match occurs,it must lock the terminal and prompt for a password. If the proper password isentered, the terminal must be unlocked. Note the script must be written todisregard BREAK, Control-D etc. No time limit need be implemented for thelock duration.

b. Write a C program to prompt user for the name of an environment variable andprint its value if it is defined and a suitable message otherwise; and to repeatthe process if user wants it.

7) a. Shell script that accepts file names specified as arguments and creates a shellscript that contains this file as well as the code to recreate these files. Thus ifthe script generated by your script is executed, it would recreate the originalfiles (This is same as the “bundle” script described by Brain W. Kernighan andRob Pike in “The Unix Programming Environment”, Prentice – Hall India).

b. Awk script to delete duplicate lines in a file. The order of original lines must notchange.

Page 52: Lab

52 System Programming

8) a. Shell script to find and display all the links of a file specified as the firstargument to the script. The second argument, which is optional, can be usedto specify the directory in which the search is to begin. If this second argumentis not present, the search is to begin in current working directory. In either case,the starting directory as well as its subdirectories at all levels must be searched.The script need not include any error checking.

b. PERL script that echoes its command line arguments, one per line aftertranslating all lower case letters to upper case.

9) a. Shell script to display the calendar for current month with current date replacedby * or ** depending on whether date has one digit or two digits.

b. PERL program to convert unsigned binary number (supplied as argument) todecimal (for example if the argument is 10110 the output should be 22). If anargument is present, it can be a valid binary number and if no argument ispresent, the program should display an error message.

10) a. Awk script that folds long line into 40 columns. Thus any line that exceeds 40Characters must be broken after 40th and is to be continued with the residue.The inputs to be supplied through a text file created by the user.

b. C program to do the following using fork () create a child process. The childprocess prints its own process id and id of its parent and then exits. The parentprocess waits for its child to finish (by executing the wait ()) and prints its ownprocess id and the id of its child process and then exits.

Note – Part A,LEX and YACC Programs are same as given and explained inSYSTEM SOFTWARE AND COMPILER DESIGN LABORATORY

PART – B

UNIX PROGRAMMING

1. a) Non-recursive shell script that accepts any number of arguments andprints them in the reverse order.

Filename : 1a.sh

echo "number of arguments are : $#"len=$#while [ $len -ne 0 ] do eval echo \$$len len=`expr $len - 1` done

Page 53: Lab

53System Programming

Output :

$ sh 1a.sh 1 2 3number of arguments are : 3321$ ./1a.sh rahul raj raninumber of arguments are : 3ranirajrahul

1. b) C program that creates a child process to read commands from thestandard input and execute them ( a minimal implementation pf a shell –like a program). You can assume that no arguments will be passed to thecommands to be executed.

Filename : 1b.c

#include<stdio.h>#include<sys/types.h>int main(){ char cmd[20]; pid_t pid; int ch; pid=fork(); if(pid == 0) { do { printf("\n Enter the command to be executed : "); scanf("%s",cmd); system(cmd); printf("\n Enter 1 to continue and 0 to exit : "); scanf("%d",&ch); } while(ch!=0); } wait();}

Output :

$ cc 1b.c

Page 54: Lab

54 System Programming

$ ./a.out

Enter the command to be executed : datewed Dec 16 11:05:52 IST 2009

Enter 1 to continue and 0 to exit : 1Enter the command to be executed : cal December 2009Su Mo Tu We Th Fr Sa 1 2 3 4 56 7 8 9 10 11 1213 14 15 16 17 18 1920 21 22 23 24 25 2627 28 29 30 31

2. a) Shell script that accepts two file names as arguments, checks if thepermissions of these files are identical and if the permissions are identical,outputs the common permission, otherwise outputs each file name followedby its permission.

Filename : 2a.sh

ls -l $1 | cut –c 1-10 > file1perls -l $2 | cut -c 1-10 > file2perif cmp file1per file2perthenecho "Both the files have same permission"cat file1perelseecho "Both the files have different permission"echo "The permission of first file $1 is "cat file1perecho "The permission of second file $2 is "cat file2perfi

Output :

$cat > file1this is first file content$cat > file2this is second file content$sh 2a.sh file1 file2Both the files have same permission-rw-r--r--$chmod 777 file2

Page 55: Lab

55System Programming

$sh 2a.sh file1 file2file1per file2per differ: byte 4, line 1Both the files have different permissionThe permission of first file file1 is-rw-r--r--The permission of second file file2 is-rwxrwxrwx

2. b) C program to create a file with 16 bytes of arbitary data from the beginningand another 16 bytes of arbitary data from an offset of 48. Display the filecontents to demonstrate how the hole in file is handled

Filename : 2b.c

#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<unistd.h>int main() { int fd; char buf1[]="Department of IS"; char buf2[]="Department of CS"; fd=creat("ise",0622); if(fd < 0) { printf("\n Error in creating file"); exit(0); } write(fd,buf1,16); lseek(fd,48,SEEK_SET); write(fd,buf2,16); exit(0); }

Output :

$cc 2b.c$./a.out$od -c ise0000000 D e p a r t m e n t o f I S0000020 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0\0 \0*0000060 D e p a r t m e n t o f C S0000100

Page 56: Lab

56 System Programming

3. a) Shell script that takes a valid directory names as as argument andrecursively descends all the subdirectories, finds the maximum length ofany file in that hierarchy and writes this maximum valut to the standardoutput.

Filename : 3a.sh

maxsize=`ls -lR $1 | grep '^-' | cut -c 38-43 | sort -n | tail-1`echo "The max size of the file in directort $1 is $maxsize bytes"

Output :

$ls -ltotal 12-rwxr-xr-x 1 root root 148 Mar 1 22:17 1a.sh-rwxr-xr-x 1 root root 366 Mar 1 22:17 2a.sh-rwxrwxrwx 1 root root 192 Mar 1 22:17 3a.sh$ sh 3a.sh /root/6ise/unixThe max size of the file in directort /root/6ise/unix is 366bytes

3. b) C program that accepts valid file names as coomand line arguments andfor each of the arguments, prints the type of the file ( Regular file,directory file, character special file, block special file, symbolic link etc ..)

Filename : 3b.c

#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<unistd.h>int main(int argc, char *argv[]) { int i; struct stat buf; for(i=1; i< argc; i++) { printf("%s: ", argv[i]); lstat(argv[i],&buf); if(S_ISREG(buf.st_mode)) printf("file is a regular file\n"); if(S_ISDIR(buf.st_mode)) printf("file is a directory file\n"); if(S_ISCHR(buf.st_mode)) printf("file is a character file\n");

Page 57: Lab

57System Programming

if(S_ISBLK(buf.st_mode)) printf("file is a block file\n"); if(S_ISLNK(buf.st_mode)) printf("file is a symbolic link file\n"); } exit(0);}

Output :

$cc 3b.c$./a.out /root/6ise/3b.c/root/6ise/3b.c: file is a regular file$./a.out /root/6ise/3b.c /root/6ise/root/6ise/3b.c: file is a regular file/root/6ise: file is a directory file$./a.out /dev/tty/dev/tty: file is a character file

4. a) Write a shell script that accepts path names and creates all the componentsin that path names as directories. For example, if the script is mpe, thenthe command mpe a/b/c/d should create directories a, a/b, a/b/c anda/b/c/d.

Filename : 4a.sh

if [ $# -le 0 –o $# -gt 1 ]then

echo “Improper Usage : pathname required”elsemkdir -p $1fi

Output :

$ sh 4a.sh a/b/c/d$ cd a$ lsb$ cd b$ lsC$ cd c$ lsd

Page 58: Lab

58 System Programming

4. b) Write a C program that accepts one command-line argument, executes thearguments as shell command, determines the time taken by it and printsthe time values, Use the “times”, function and the “tms” structure. Thecode need not include error checking.

Filename : 4b.c

#include<stdio.h>#include<sys/times.h>#include<unistd.h>#include<time.h>

int main(int argc, char *argv[]) {struct tms tms1,tms2;clock_t begin,end;long clktick = sysconf(_SC_CLK_TCK);begin=times(&tms1);system(argv[1]);end=times(&tms2);printf("\n\t Time taken is %f ",(end-begin)/(double)CLK_TCK);printf("\n\t Time taken is %f ",(tms2.tms_utimetms1.tms_utime)/(double)clktick); }

Output :

$ cc 4b.c$./a.out ls1a.l 1b.l 2a.l 2b.l 3.l 4a.l 4a.y 4b.l 4b.y 5a.l 5b.y 6 1a.sh 2a.sh3a.sh 4a.sh 1b.c 2b.c 3b.c 4b.c ./a.out

Time taken is 0.010000Time taken is 0.000000

$ ./a.out calDecember 2009Su Mo Tu We Th Fr Sa 1 2 3 4 56 7 8 9 10 11 1213 14 15 16 17 18 1920 21 22 23 24 25 2627 28 29 30 31

Time taken is 0.020000Time taken is 0.000000

Page 59: Lab

59System Programming

5. a) Shell script that accepts valid log-in names as arguments and prints theircorresponding home directories. If no arguments are specified, print asuitable error message.

Filename : 5a.shif [ $# -lt 1 ] then echo " Invalid Arguments....... " exitfifor x in "$@" do if grep "$x" /etc/passwd > file1 then echo" The login name is : $x" echo " The Home directory is : `cut -d ":" -f 6 file1`" elseecho " $x is not a valid login name " fi done

Output :

$ sh 5a.sh cseThe login name is : cseThe Home directory is : /home/cse$ sh 5a.shInvalid Arguments.......

5. b) C program that accepts valid directory names as a command line argumentand lists all the files in the given directory as well as all the subsequentsubdirectories. (The solution can be recursive or non-recursive).

Filename : 5b.c

#include<stdio.h.#include<string.h>int main(int argc, char *argv[]) {

int i;char str[50];for(i=1;i<argc;i++){

strcpy(str,” ls –R “); /* leave space after –R */strcat(str,argv[i]);system(str);

} }

Page 60: Lab

60 System Programming

Output :

$ cc 5b.c$ ./a.out /home/ise

1a.l 1b.l 2a.l 2b.l 3.l 4a.l 4a.y 4b.l 4b.y 5a.l 5b.y 6 1a.sh 2a.sh3a.sh 4a.sh 1b.c 2b.c 3b.c 4b.c ./a.out a

/home/ise/a:b/home/ise/a/b:c/home/ise/a/b/c:d/home/ise/a/b/c/d:

6. a) Shell script to implement terminal locking. It should prompt the user fora password. After accepting the password entered by the user, it mustprompt again for password confirmation (to retype the password). If amatch occurs, it must lock the terminal and prompt for a password. If theproper password is entered, the terminal must be unlocked. Note thescript must be written to disregard BREAK, Control-D etc. No time limitneed be implemented for the lock duration.

Filename : 6a.sh

trap "" 1 2 3 5 20clearecho -e "Enter password to lock terminal:"stty -echoread keynewstty echoecho -e "Confirm password:"stty -echoread keyoldstty echoif [ $keyold = $keynew ] then echo "Terminal locked!" while [ 1 ] do echo "Retype the password to unlock:" stty -echo read key if [ $key = $keynew ] then

Page 61: Lab

61System Programming

stty echo echo "Terminal unlocked!" stty sane exit fi echo "Invalid password!" doneelse echo " Passwords do not match!"fistty sane

Output :

$ sh 6a.shEnter password to lock terminal:Confirm password:Terminal locked!Retype the password to unlock:Invalid password!Retype the password to unlock:Invalid password!Retype the password to unlock:Terminal unlocked!$ sh 6a.shEnter password to lock terminal:Confirm password:Passwords do not match!

6. b) Write a C program to prompt user for the name of an environment variableand print its value if it is defined and a suitable message otherwise; andto repeat the process if user wants it.

Filename : 6b.c

#include<stdio.h>#include<sys/types.h>#include<sys/stat.h>#include<stdlib.h>

int main( ) {

char name[25];int i;char *p;do

Page 62: Lab

62 System Programming

{printf(“\n Enter any environment variable :”);scanf(%s”,name);p=getenv(name);if(p) printf(“%s”,p);else printf(“\n Environment variable not defined”); printf(“\n Want to continue 1-yes 0-no :\n”);

scanf(“%d”,&i); } while(i!=0); }

Output :

$ cc 6b.c$ ./a.outEnter any environment variable :HOMERootWant to continue 1-yes 0-no :0

7. a) Shell script that accepts file names specified as arguments and creates ashell script that contains this file as well as the code to recreate these files.Thus if the script generated by your script is executed, it would recreatethe original files (This is same as the “bundle” script described by BrainW. Kernighan and Rob Pike in “The Unix Programming Environment”,Prentice – Hall India).

Filename : 7a.sh

echo “#to bundle,sh this file”for i in $*do

echo "echo $i 1>&2"echo "cat >$i <<'End of $i'"cat $iecho "End of $i"

done

Output :

$ls10b.c 1b.c 4a.sh 5a.sh 5b.c 6a.sh 6b.c 7a.sh 8a.sh 9a.sha$cat > file1this is first file

Page 63: Lab

63System Programming

$cat > file2this is second file$ls10b.c 4a.sh 5b.c 6b.c 8a.sh a file21b.c 5a.sh 6a.sh 7a.sh 9a.sh file1$sh 7a.sh file1 file2 > new.sh$ls10b.c 4a.sh 5b.c 6b.c 8a.sh a file21b.c 5a.sh 6a.sh 7a.sh 9a.sh file1 new.sh$rm file1rm: remove regular file `file1'? y$rm file2rm: remove regular file `file2'? y$ls10b.c 1b.c 4a.sh 5a.sh 5b.c 6a.sh 6b.c 7a.sh 8a.sh 9a.sha new.sh$sh new.shfile1file2$ls10b.c 4a.sh 5b.c 6b.c 8a.sh a file21b.c 5a.sh 6a.sh 7a.sh 9a.sh file1 new.sh$cat file1this is first file$cat file2this is second file

7. b) Awk script to delete duplicate lines in a file. The order of original linesmust not change.

Filename : 7b.awk

{ found=0 for(i=0;i<nlines;i++) if(lines[i] == $0)

{ found=1

break } if(!found)

{ lines[nlines++]=$0 print $0

} }

Page 64: Lab

64 System Programming

Output :

$ vi sample.txtisecseiseectccse$ awk –f 7b.awk sample.txtisecseectc

8. a) Shell script to find and display all the links of a file specified as the firstargument to the script. The second argument, which is optional, can beused to specify the directory in which the search is to begin. If this secondargument is not present, he search is to begin in current working directory.In either case, the starting directory as well as its subdirectories at alllevels must be searched. The script need not include any error checking.

Filename : 8a.sh

if [ $# -eq 0 ] then echo "Usage:sh 8a.sh[file1] [dir1(optional)]" exitfiif [ -f $1 ] then dir="." if [ $# -eq 2 ] then dir=$2 fi str=`ls -i $1|cut -d " " -f 1` echo "Hard links of $1 are" find $dir -inum $str -print echo "Soft links of $1 are" find $dir -lname $1 -printelse echo "The file $1 does not exist"fi

Page 65: Lab

65System Programming

Output :

$ vi file1$ ln –s file1 file2$ ln file1 file3$ ln file1 file4$ sh 8a.sh file1Hard links of file1 arefile3file4Soft links of file1 arefile2

8. b) PERL script that echoes its command line arguments, one per line aftertranslating all lower case letters to upper case.

Filename : 8b.pl

foreach $string (@ARGV) {

$string=~tr/a-z/A-Z/; print(“$string\n”); }

Output :

$perl 8b.pl unix system programmingUNIXSYSTEMPROGRAMMING

9. a) Shell script to display the calendar for current month with current datereplaced by * or ** depending on whether date has one digit or two digits.

Filename : 9a.sh

cal > daynoset `date`x=$3if [ $x –le 9 ]then sed “s/ $3 / */” daynoelse sed “s/ $3/ **/” daynofirm dayno

Page 66: Lab

66 System Programming

Output :$ sh 9a.shDecember 2009Su Mo Tu We Th Fr Sa 1 2 3 4 56 7 8 9 10 11 1213 14 15 ** 17 18 1920 21 22 23 24 25 2627 28 29 30 31

9. b) PERL program to convert unsigned binary number (supplied as argument)to decimal (for example if the argument is 10110 the output should be 22).If an argument is present, it can be a valid binary number and if noargument is present, the program should display an error message.

Filename : 9b.pl

if(@ARGV==0) {

print(“Invalid arguments”); }else {

$num=0;$mul=1;while($ARGV[0] != “ “) {

$num = $num + chop($ARGV[0]) * $mul;$mul = $mul * 2;

}print(“$num\n”);

}

Output :

$ perl 9b.pl 1015$ perl 9b.pl 1117$ perl 9b.plInvalid arguments

10) a. Awk script that folds long line into 40 columns. Thus any line that exceeds40 Characters must be broken after 40th and is to be continued with theresidue. The inputs to be supplied through a text file created by the user.

Page 67: Lab

67System Programming

Filename : 10a.awk

{ x=$0 while(length(x) > 40) {

printf(“%sX\n”,substr(x,1,40))x=substr(x,41,length(x)-40)

} print(“%s\n”,x);}

Output :

$vi abc.txt

Signals are software interrupts. UNIX uses signals to inform aprocess of asynchronous events and to handle exception. Signalsprovide a mechanism for notifying process of systems events. Forexample, when a user types control C at the terminal.

$awk -f 10a.awk abc.tzt

Signals are software interrupts. UNIX usXes signals to inform a process of asynchXronous events and to handle exception. SX ignals provide a mechanism for notifyingX process of systems events. For example,Xwhen a user types control C at the termXinal.

10. b) C program to do the following using fork () create a child process. Thechild process prints its own process id and id of its parent and then exits.The parent process waits for its child to finish (by executing the wait ())and prints its own process id and the id of its child process and then exits.

Filename : 10b.c

#include <sys/types.h>#include <stdio.h>int main() { pid_t pid; if((pid=fork())<0) printf("fork error"); if(pid==0)

Page 68: Lab

68 System Programming

{ printf("\n This is child process "); printf("\n Child PID :%d",getpid()); printf("\n Parent PID :%d\n",getppid()); exit(0); } else { wait(); printf("\n This is parent process"); printf("\n Parent PID :%d",getpid()); printf("\n Child PID :%d",pid); exit(0); } }

Output :

$cc 10b.c$./a.outThis is child processChild PID :3122Parent PID :3121

This is parent processParent PID :3121Child PID :3122

Page 69: Lab

69File Structures

FILE STRUCTURES LABORATORY

1. Write a C++ program to read series of names, one per line, from standardinput and write these names spelled in reverse order to the standardoutput using I/O redirection and pipes. Repeat the exercise using aninput file specified by the user instead of the standard input and usingan output file specified by the user instead of the standard output.

2. Write a C++ program to read and write and student objects with fixedlength records and the fields delimited by “|”.implementpack(),unpack(),modify() and search() methods.

3. Write a C++ program to read and write and student objects with variablelength records using any suitable record structure. Implementpack(),unpack(),modify() and search() methods

4. Write a c++ program to write student objects with variable-lengthrecords using any suitable record structure and to read from this file astudent record using RRN.

5. Write a C++ program to implement simple index on primary key for a fileof student objects. Implement add(),search(),delete() using the index.

6. Write a C++ program to implement index on secondary key, the name,for a file of student objects. Implement add(),search(),delete() using thesecondary index.

7. Write a C++ program to read two lists of names and then match thenames in the two lists using Consequential Match based on a single loop.Output the names common to both the lists.

8. Write a C++ program to read k Lists of names and merge them usingkway merge algorithm with k = 8.

9. Write a C++ program to implement B-Tree for a given set of integers andits operations insert ( ) and search ( ). Display the tree.

10. Write a C++ program to implement B+ tree for a given set of integers andits operations insert ( ), and search ( ). Display the tree.

11. Write a C++ program to store and retrieve student data from file usinghashing. Use any collision resolution technique

12. Write a C++ program to reclaim the free space resulting from thedeletion of records using linked lists.

Page 70: Lab

70 File Structures

1. Write a C++ program to read series of names, one per line, from standardinput and write these names spelled in reverse order to the standard outputusing I/O redirection and pipes. Repeat the exercise using an input filespecified by the user instead of the standard input and using an output filespecified by the user instead of the standard output.

Filename : fs1.cpp

#include<iostream.h>#include<fstream.h>#include<conio.h>#include<string.h>

void swap(char &x,char &y) {char temp=x;x=y;y=temp; }

void reverse(char *name) {int count=strlen(name);for(int i=0,j=count-1;i<count/2;++i,--j)swap(name[i],name[j]); }

void main(int argc,char *argv[]) {if(argc==1){ char name[10]; do {cin>>name;reverse(name);cout<<name<<endl;if(cin.eof())break; }while(1); }else if(argc>2){char name[20];fstream fd1,fd2;fd1.open(argv[1],ios::in);

Page 71: Lab

71File Structures

fd2.open(argv[2],ios::out|ios::app|ios::trunc);do {fd1>>name;reverse(name);cout<<name;fd2<<name<<endl;if(fd1.eof())break;}while(1);fd1.close();fd2.close();}cout<<"usage:"<<argv[0]<<"filename1 filename2"; }

Output:

C:\TC\BIN>FS1.exenetworksskrowtenfileelifsystemmetsys

C:\TC\BIN>edit inputnetworksfilessystemcompilergraphics

C:\TC\BIN>FS1.exe input outputskrowtenselifmetsysrelipmocscihparg

C:\TC\BIN>type outputskrowtenselifmetsysrelipmocscihparg

C:\TC\BIN>FS1.EXE INPUTusage:FS1.EXE filename1 filename2

Page 72: Lab

72 File Structures

2. Write a C++ program to read and write and student objects with fixed-lengthrecords and the fields delimited by “|”.implement pack(),unpack(),modify()and search() methods.

#include<stdio.h>#include<stdlib.h>#include<iostream.h>#include<fstream.h>#include<conio.h>#include<string.h>#include<iomanip.h>

class student{ public: charname[15],usn[15],age[5],sem[5],branch[15],buffer[45];};

student s2[100];

void writeRecord() //Function to add record to file{ fstream app; student s; app.open("student.txt",ios::app); //Open file in append mode

if(!app) { cout<<"cannot open the file in output mode"; getch(); exit(0); } cout<<"\n Enter the student name = "; cin>>s.name; cout<<"\n Enter the usn = "; cin>>s.usn; cout<<"\n Enter the age = "; cin>>s.age; cout<<"\n Enter the sem = "; cin>>s.sem; cout<<"\n Enter the branch = "; cin>>s.branch;

//packing the information strcpy(s.buffer, s.name); strcat(s.buffer,"|"); strcat(s.buffer, s.usn); strcat(s.buffer,"|"); strcat(s.buffer, s.age); strcat(s.buffer,"|"); strcat(s.buffer, s.sem); strcat(s.buffer,"|"); strcat(s.buffer, s.branch);

int count=strlen(s.buffer);

Page 73: Lab

73File Structures

for(int k=0;k<45-count;k++) strcat(s.buffer,"!"); strcat(s.buffer,"\n"); app<<s.buffer; //writing the packed information to buffer app.close();}

void search(){ fstream in; char usn[15], extra[45]; in.open("student.txt",ios::in); if(!in) { cout<<"\nUnable to open the file in input mode"; getch(); exit(0); } cout<<"\nEnter the record's usn you want to search = ";cin>>usn; student s;

//Unpacking the record while(!in.eof()) { in.getline(s.name,15,'|'); in.getline(s.usn,15,'|'); in.getline(s.age,5,'|'); in.getline(s.sem,5,'|'); in.getline(s.branch,15,'|'); in.getline(extra,45,'\n');

if(strcmp(s.usn,usn)==0) {

cout<<"\nRecord found";

cout<<"\n"<<s.name<<"\t"<<s.usn<<"\t"<<s.age<<"\t"<<s.sem<<"\t"<<s.branch;getch();return;

} } cout<<"\n Record not found"; getch(); return;}

Page 74: Lab

74 File Structures

void displayFile(){ student s; int c,i; char extra[45]; fstream in; in.open("student.txt",ios::in);

if(!in) { cout<<"\nCannot open the file in output mode"; getch(); exit(0); } i=0; printf("Name\t\tUsn\t\tAge\t\tSem\t\tBranch\n"); while(!in.eof()) { in.getline(s.name,15,'|'); in.getline(s.usn,15,'|'); in.getline(s.age,5,'|'); in.getline(s.sem,5,'|'); in.getline(s.branch,15,'!'); in.getline(extra,45,'\n'); printf("\n%s\t\t%s\t\t%s\t\t%s\t\t%s",s.name,s.usn,s.age,s.sem,s.branch);

i++; } in.close(); getch();}

void modify(){ fstream in; char usn[15],buffer[45],extra[45]; int i,j; student s1[100]; in.open("student.txt",ios::in); if(!in) { cout<<"\nUnable to open the file in input mode"; getch(); exit(0); } cout<<"\nEnter the usn"; cin>>usn;

Page 75: Lab

75File Structures

i=0;//Loading the file to Main memory

while(!in.eof()) { in.getline(s1[i].name,15,'|'); in.getline(s1[i].usn,15,'|'); in.getline(s1[i].age,5,'|'); in.getline(s1[i].sem,5,'|'); in.getline(s1[i]. branch, 15,'\n'); in.getline(extra,45,'\n'); i++; } i--; for(j=0;j<i;j++) { if(strcmp(usn,s1[j].usn)==0) {

cout<<"\nThe old values of the record with usn "<<usn<<" are";

cout<<"\nname = "<< s1[j].name;cout<<"\nusn = "<< s1[j].usn;cout<<"\nage = "<< s1[j].age;cout<<"\nsem = "<< s1[j].sem;cout<<"\nbranch = "<< s1[j].branch;

cout<<"\nEnter the new values \n";cout<<"\nname = "; cin>>s1[j].name;cout<<"\nusn = "; cin>>s1[j].usn;cout<<"\nage = "; cin>>s1[j].age;cout<<"\nsem = "; cin>>s1[j].sem;cout<<"\nbranch= "; cin>>s1[j].branch;break;

} } if(j==i) { cout<<"\n Record with usn "<<usn<<" is not present"; getch(); return; } in.close(); fstream out1; out1.open("student.txt",ios::out); if(!out1) { cout<<"\nUnable to open file in output mode";

Page 76: Lab

76 File Structures

getch(); return; } for(j=0;j<i;j++) { strcpy(buffer,s1[j].name); strcat(buffer,"|"); strcat(buffer,s1[j].usn); strcat(buffer,"|"); strcat(buffer,s1[j].age); strcat(buffer,"|"); strcat(buffer,s1[j].sem); strcat(buffer,"|"); strcat(buffer,s1[j].branch);

int count=strlen(buffer); for(int k=0;k<45-count;k++) strcat(buffer,"!");

strcat(buffer,"\n"); out1<<buffer; } out1.close();}

void main(){ fstream in; fstream out; int ch; out.open("student.txt",ios::out); if(!in) { cout<<"\n\nCannot open the file in output mode"; getch(); exit(0); } out.close();

for(;;) { clrscr(); cout<<"\n 1: write to file\n 2:display the file"

<<"\n 3:modify the file\n 4:search\n 5.exit"; cout<<"\n\n Enter the choice: "; cin>>ch; switch(ch) { case 1: writeRecord();break; case 2: displayFile();break; case 3: modify();break;

Page 77: Lab

77File Structures

case 4: search (); break; case 5: exit(0); default: cout<<"\nInvalid input....";break; } }}

Output :

1:write to file2:display the file3:modify the file4:search5.exit

Enter the choice:1

Enter the student name = ajayEnter the usn = 1vk07is002Enter the age = 20Enter the sem = 6Enter the branch = ise

1:write to file2:display the file3:modify the file4:search5.exit

Enter the choice:1

Enter the student name = rahulEnter the usn = 1vk07cs045Enter the age = 20Enter the sem = 6Enter the branch = cse

1:write to file2:display the file3:modify the file4:search5.exit

Enter the choice:2Name Usn Age Sem Branch

Page 78: Lab

78 File Structures

ajay 1vk07is002 20 6 ise!!!!!!!!!!!rahul 1vk07cs045 20 6 cse!!!!!!!!!!!

1:write to file2:display the file3:modify the file4:search5.exit

Enter the choice:4

Enter the record's usn you want to search = 1vk07cs045Record foundrahul 1vk07cs045 20 6 cse!!!!!!!!!!!

1:write to file2:display the file3:modify the file4:search5.exit

Enter the choice:5

C:\TC|BIN>type student.txtajay|1vk07is002|20|6|ise!!!!!!!!!!!rahul|1vk07cs045|20|6|cse!!!!!!!!!!!

3. Write a C++ program to read and write and student objects with variablelength records using any suitable record structure. Implementpack(),unpack(),modify() and search() methods

#include<stdio.h>#include<stdlib.h>#include<iostream.h>#include<fstream.h>#include<conio.h>#include<string.h>#include<iomanip.h>

class student{public: char name[15], usn[15], age[5], sem[5], branch[15],buffer[100];};

student s2[100];

Page 79: Lab

79File Structures

void writeRecord(){ fstream app; student s; app.open("student.txt",ios::app); //Open file in append mode if(!app) { cout<<"cannot open the file in output mode"; getch(); exit(0); } cout<<"\n Enter the student name = "; cin>>s.name; cout<<"\n Enter the usn = "; cin>>s.usn; cout<<"\n Enter the age = "; cin>>s.age; cout<<"\n Enter the sem = "; cin>>s.sem; cout<<"\n Enter the branch = "; cin>>s.branch;

//packing the information strcpy(s.buffer, s.name); strcat(s.buffer,"|"); strcat(s.buffer, s.usn); strcat(s.buffer,"|"); strcat(s.buffer, s.age); strcat(s.buffer,"|"); strcat(s.buffer, s.sem); strcat(s.buffer,"|"); strcat(s.buffer, s.branch);strcat(s.buffer,"\n");

app<<s.buffer; //writing the packed information to buffer app.close();}

void search(){ fstream in; char usn[15], extra[45]; in.open("student.txt",ios::in); if(!in) { cout<<"\nUnable to open the file in input mode"; getch(); exit(0); } cout<<"\nEnter the record's usn you want to search = ";cin>>usn; student s;

//Unpacking the record while(!in.eof()) {

Page 80: Lab

80 File Structures

in.getline(s.name,15,'|'); in.getline(s.usn,15,'|'); in.getline(s.age,5,'|'); in.getline(s.sem,5,'|'); in.getline(s.branch,15,'\n'); if(strcmp(s.usn,usn)==0) {

cout<<"\nRecord found";cout<<"\n"<<s.name<<"\t"<<s.usn<<"\t"<<s.age<<"\t"

<<s.sem<<"\t"<<s.branch;getch();return;

} } cout<<"\n Record not found"; getch(); return;}

void displayFile(){ student s; int c,i; fstream in; in.open("student.txt",ios::in); if(!in) { cout<<"\nCannot open the file in output mode"; getch(); exit(0); } i=0; printf("Name\t\tUsn\t\tAge\t\tSem\t\tBranch\n"); while(!in.eof()) { in.getline(s.name,15,'|'); in.getline(s.usn,15,'|'); in.getline(s.age,5,'|'); in.getline(s.sem,5,'|'); in.getline(s.branch,15,'\n');

printf("\n%s\t\t%s\t\t%s\t\t%s\t\t%s",s.name,s.usn,s.age,s.sem,s.branch);

i++; } in.close(); getch();}

Page 81: Lab

81File Structures

void modify(){ fstream in; char usn[15],buffer[45],extra[45]; int i,j; student s1[100]; in.open("student.txt",ios::in); if(!in) { cout<<"\nUnable to open the file in input mode"; getch(); exit(0); } cout<<"\nEnter the usn"; cin>>usn; i=0;

//Loading the file to Main memory while(!in.eof()) { in.getline(s1[i].name,15,'|'); in.getline(s1[i].usn,15,'|'); in.getline(s1[i].age,5,'|'); in.getline(s1[i].sem,5,'|'); in.getline(s1[i]. branch, 15,'\n'); i++; }

i--;

for(j=0;j<i;j++) { if(strcmp(usn,s1[j].usn)==0) {cout<<"\nThe old values of the record with usn "<<usn<<" are ";

cout<<"\nname = "<< s1[j].name;cout<<"\nusn = "<< s1[j].usn;cout<<"\nage = "<< s1[j].age;cout<<"\nsem = "<< s1[j].sem;cout<<"\nbranch = "<< s1[j].branch;cout<<"\nEnter the new values \n";cout<<"\nname = "; cin>>s1[j].name;cout<<"\nusn = "; cin>>s1[j].usn;cout<<"\nage = "; cin>>s1[j].age;cout<<"\nsem = "; cin>>s1[j].sem;cout<<"\nbranch= "; cin>>s1[j].branch;break;

}

Page 82: Lab

82 File Structures

} if(j==i) { cout<<"\n Record with usn "<<usn<<" is not present"; getch(); return; } in.close();

fstream out1; out1.open("student.txt",ios::out);

if(!out1) { cout<<"\nUnable to open file in output mode"; getch(); return; }

for(j=0;j<i;j++) { out1<<s1[j].name<<'|'<<s1[j].usn<<'|'<<s1[j].age<<'|'

<<s1[j].sem<<'|'<<s1[j].sem<<'|'<<s1[j].branch<<'\n'; } out1.close();}

void main(){ fstream in; fstream out; int ch; out.open("student.txt",ios::out); if(!in) { cout<<"\n\nCannot open the file in output mode"; getch(); exit(0); } out.close();

for(;;) { clrscr(); cout<<"\n 1: write to file\n 2:display the file"

<<"\n 3:modify the file\n 4:search\n 5:exit";

Page 83: Lab

83File Structures

cout<<"\n\n Enter the choice: "; cin>>ch; switch(ch) { case 1: writeRecord();break; case 2: displayFile();break; case 3: modify();break; case 4: search (); break; case 5: exit(0); default: cout<<"\nInvalid input....";break; } }}

Output :

1:write to file2:display the file3:modify the file4:search5.exit

Enter the choice:1

Enter the student name = ajayEnter the usn = 1vk07is002Enter the age = 20Enter the sem = 6Enter the branch = ise

1:write to file2:display the file3:modify the file4:search5.exit

Enter the choice:1

Enter the student name = rahulEnter the usn = 1vk07cs045Enter the age = 20Enter the sem = 6Enter the branch = cse

1:write to file2:display the file3:modify the file

Page 84: Lab

84 File Structures

4:search5.exit

Enter the choice:2Name Usn Age Sem Branchajay 1vk07is002 20 6 iserahul 1vk07cs045 20 6 cse

1:write to file2:display the file3:modify the file4:search5.exit

Enter the choice:4

Enter the record's usn you want to search = 1vk07cs045Record foundrahul 1vk07cs045 20 6 cse

1:write to file2:display the file3:modify the file4:search5.exit

Enter the choice:5

C:\TC|BIN>type student.txtajay|1vk07is002|20|6|iserahul|1vk07cs045|20|6|cse

4. Write a c++ program to write student objects with variable-length recordsusing any suitable record structure and to read from this file a student recordusing RRN.

#include<stdio.h>#include<stdlib.h>#include<iostream.h>#include<fstream.h>#include<conio.h>#include<string.h>#include<iomanip.h>

class student{

Page 85: Lab

85File Structures

public: char name[15],usn[15],age[5],sem[5],branch[15],buffer[100];

};

void search(){ char usn[15]; int i=0; student s1[100]; cout<<"\nEnter the usn to be searched: "; cin>>usn; fstream in; in.open("student.txt",ios::in); if(!in) { cout<<"\ncannot open the file in output mode"; getch(); exit(0); } i=0; printf("Name\tUsn\tAge\tSem\tBranch\n"); while(!in.eof()) { in.getline(s1[i].name,15,'|'); in.getline(s1[i].usn,15,'|'); in.getline(s1[i].age,5,'|'); in.getline(s1[i].sem,5,'|'); in.getline(s1[i].branch,15,'\n'); i++; } for(int j=0; j<i-1; j++) { if(strcmp(usn,s1[j].usn)==0) { printf("\n Record found"); printf("\n%s\t%s\t%s\t%s\t%s",s1[j].name,s1[j].usn,

s1[j].age,s1[j].sem,s1[j].branch); return; } } cout<<"\nRecord not found"; return;}

void writeRecord(){ fstream app;

Page 86: Lab

86 File Structures

student s; app.open("student.txt",ios::app); if(!app) { cout<<"cannot open the file in output mode"; getch(); exit(0); } cout<<"\nEnter the student name: "; cin>>s.name; cout<<"\nEnter the usn: "; cin>>s.usn; cout<<"\nEnter the age: "; cin>>s.age; cout<<"\nEnter the sem: "; cin>>s.sem; cout<<"\nEnter the branch: "; cin>>s.branch; strcpy(s.buffer,s.name); strcat(s.buffer,"|"); strcat(s.buffer,s.usn); strcat(s.buffer,"|"); strcat(s.buffer,s.age); strcat(s.buffer,"|"); strcat(s.buffer,s.sem); strcat(s.buffer,"|"); strcat(s.buffer,s.branch); strcat(s.buffer,"\n"); app<<s.buffer; app.close();}

void main(){ clrscr(); int ch; fstream out; out.open("student.txt",ios::out); if(!out) { cout<<"\nCannot open the file in output mode"; getch(); exit(0); } out.close(); for(;;) { cout<<"\n1:Insert\n2:Search\n3:exit"

<<"\nEnter the choice = "; cin>>ch; switch(ch) {

case 1: writeRecord();break;case 2: search();break;case 3: exit(0);default: cout<<"\nInvalid option";

}

Page 87: Lab

87File Structures

}}

Output :

1:Insert2.Search3.exit

Enter the choice:1

Enter the student name = ajayEnter the usn = 1vk07is002Enter the age = 20Enter the sem = 6Enter the branch = ise

1:Insert2.Search3.exit

Enter the choice:1

Enter the student name = rahulEnter the usn = 1vk07cs045Enter the age = 20Enter the sem = 6Enter the branch = cse

1:Insert2.Search3.exit

Enter the choice:2Enter the usn to be searched:1vk07is007Record not found

1:Insert2.Search3.exit

Enter the choice:2Enter the usn to be searched:1vk07cs045Record found

Page 88: Lab

88 File Structures

5. Write a C++ program to implement simple index on primary key for a file ofstudent objects. Implement add(),search(),delete() using the index.

#include<iostream.h>#include<string.h>#include<fstream.h>#include<stdlib.h>

//Record specificationclass record{ public: char age[5];

char usn[20],name[20],branch[5]; char sem[2];

}rec[20];

char st_no[5];int no;

void retrieve_details(){ fstream file2; char name[20],usn[20],branch[5]; char ind[5],age[5],sem[5]; file2.open("record.txt",ios::in); for(int i=0;i<no;i++) //Unpacking record data { file2.getline(ind,5,'|'); file2.getline(usn,20,'|'); file2.getline(name,20,'|'); file2.getline(age,5,'|'); file2.getline(sem,5,'|'); file2.getline(branch,5,'\n'); if(strcmp(ind,st_no)==0) //Required record found - printdetails {

cout<<"\n\n"<<"Student details are: "; cout<<"\n\nUSN: "<<usn<<"\nName: "<<name<<"\nAge:

"<<age<<"\nSem: "<<sem<<"\nBranch: "<<branch<<"\n"; } } file2.close();}

void delete_record(char usno[]){

Page 89: Lab

89File Structures

int i; fstream file1, file2; char age[5],sem[5],branch[5],usn[20],name[20],ind[5]; file2.open("record.txt",ios::in); for(i=0;i<no;i++) //Unpack records { file2.getline(ind,5,'|'); file2.getline(usn,20,'|'); file2.getline(name,20,'|'); file2.getline(age,5,'|'); file2.getline(sem,5,'|'); file2.getline(branch,5,'\n');

strcpy(rec[i].usn,usn); strcpy(rec[i].name,name); strcpy(rec[i].age,age); strcpy(rec[i].sem,sem); strcpy(rec[i].branch,branch); } int flag=-1; for(i=0;i<no;i++) //Check for the record's existence { if(strcmp(rec[i].usn,usno)==0) flag=i; } if(flag==-1) //Record not found { cout<<"Error !\n"; return; } if(flag==(no-1)) //Delete found record { no--; cout<<"Deleted !\n"; return; } for(i=flag;i<no;i++) { rec[i]=rec[i+1]; } no--; cout<<"\nDeleted !\n"; file2.close(); file1.open("index.txt",ios::out); //Open index and record

files file2.open("record.txt",ios::out); //After deletion

Page 90: Lab

90 File Structures

for(i=0;i<no;i++) //Pack index n record data onto files { file1<<rec[i].usn<<"|"<<i<<"\n"; file2<<i<<"|"<<rec[i].usn<<"|"<<rec[i].name<<"|"

<<rec[i].age<<"|"<<rec[i].sem<<"|"<<rec[i].branch<<"\n"; } file1.close(); file2.close(); return;}

int main(){ fstream file1,file2; int ch; char rt_usn[20],st_usn[20]; char ind[2],name[20],age[2],sem[5],branch[5]; int i,flag,flag1; file1.open("index.txt",ios::out); file2.open("record.txt",ios::out); if(!file1 || !file2) { cout<<"File creation Error! \n"; exit(0); } for(;;) { cout<<"\n1: Add Record"

<<"\n2: Search Record" <<"\n3: Delete Record" <<"\n4: Display Record" <<"\n5: Exit" <<"\n\n Enter u'r choice :"; cin>>ch; switch(ch) { case 1: cout<<"Enter the no. of students : "; cin>>no;

cout<<"Enter the details:\n"; for(i=0;i<no;i++) //Pack data onto the index and record files

{ //USN is the indexed data cout<<"\nName: "; cin>>rec[i].name; cout<<"Age: "; cin>>rec[i].age; cout<<"USN: "; cin>>rec[i].usn; cout<<"Sem: "; cin>>rec[i].sem; cout<<"Branch: "; cin>>rec[i].branch;

Page 91: Lab

91File Structures

file1<<rec[i].usn<<"|"<<i<<"\n"; file2<<i<<"|"<<rec[i].usn<<"|"<<rec[i].name<<"|"

<<rec[i].age<<"|"<<rec[i].sem<<"|"<<rec[i].branch<<"\n"; } file1.close(); file2.close(); break;

case 2: cout<<"Enter USN whose record is to be displayed: "; cin>>st_usn; file1.open("index.txt",ios::in); if(!file1) { cout<<"\nError !\n"; exit(0); } flag1=0; for(i=0;i<no;i++) {

file1.getline(rt_usn,20,'|'); //Unpack index file and file1.getline(st_no,4,'\n'); //look for a match in the USN if(strcmp(st_usn,rt_usn)==0)

{ retrieve_details(); //Retrieve details if index found flag1=1; } } if(!flag1) cout<<"Record search failed!\n"; file1.close(); break;

case 3: cout<<"Enter USN whose record is to be deleted: "; cin>>st_usn; file1.open("index.txt", ios::in); if(!file1) { cout<<"Error! \n"; exit(0); } flag=0; for(i=0;i<no;i++) {file1.getline(rt_usn,20,'|'); //Search index file and

file1.getline(st_no,4,'\n'); //call del if index found if(strcmp(st_usn, rt_usn)==0) {

delete_record(rt_usn);

Page 92: Lab

92 File Structures

flag=1; } } if(!flag) cout<<"Deletion Failed\n"; file1.close(); break;

case 4: for(i=0;i<no;i++) { cout<<"\n\n USN: "<<rec[i].usn

<<"\n Name: "<<rec[i].name <<"\n Age: "<<rec[i].age <<"\n Sem: "<<rec[i].sem <<"\n Branch: "<<rec[i].branch;

} break;

case 5:exit(0); default: cout<<"Invalid choice";

exit(0); break;

} }}

Output :

1: Add Record2: Search Record3: Delete Record4: Display Record5: Exit

Enter u'r choice : 1

Enter the no. of students :2Enter the details:

Name: ajayAge: 20USN: 1vk07is002Sem: 6Branch: ise

Name: rahulAge: 20USN: 1vk07cs045

Page 93: Lab

93File Structures

Sem: 6Branch: cse

1: Add Record2: Search Record3: Delete Record4: Display Record5: Exit

Enter u'r choice : 4

Name: ajayAge: 20USN: 1vk07is002Sem: 6Branch: ise

Name: rahulAge: 20USN: 1vk07cs045Sem: 6Branch: cse

1: Add Record2: Search Record3: Delete Record4: Display Record5: Exit

Enter u'r choice :3

Enter USN whose record is to be deleted:1vk07cs045Deleted !1: Add Record2: Search Record3: Delete Record4: Display Record5: Exit

Enter u'r choice :4

Name: ajayAge: 20USN: 1vk07is002Sem: 6Branch: ise

Page 94: Lab

94 File Structures

6. Write a C++ program to implement index on secondary key, the name, for a fileof student objects. Implement add(),search(),delete() using the secondaryindex.

#include<iostream.h>#include<string.h>#include<fstream.h>#include<stdlib.h>

//using namespace std;

class record{ public: char age[5];

char usn[20],name[20],branch[5]; char sem[2];}rec[20],found[20];

char st_no[5],rt_name[20];int no;

void sort_records(){ int i,j; record temp; for(i=0;i<no-1;i++) for(j=0;j<no-i-1;j++)

if(strcmp(rec[j].name, rec[j+1].name) > 0) { temp=rec[j]; rec[j]=rec[j+1]; rec[j+1]=temp; }

}

void create_indexfile(){ fstream index,index2; int i; index.open("secindex.txt",ios::out); index2.open("record.txt",ios::out); for(i=0;i<no;i++) { index<<rec[i].name<<"|"

<<rec[i].usn<<"|"<<i<<"\n"; index2<<i<<"|"<<rec[i].usn<<"|"<<rec[i].name<<"|"<<rec[i].age<<"|"

<<rec[i].sem<<"|"<<rec[i].branch<<"\n";

Page 95: Lab

95File Structures

}}

void retrieve_record(char* index){ fstream file; int i; char ind[2],usn[20],name[20],age[3],sem[3],branch[10]; file.open("record.txt",ios::in); for(i=0;i<no;i++) { file.getline(ind,4,'|'); file.getline(usn,20,'|'); file.getline(name,20,'|'); file.getline(age,4,'|'); file.getline(sem,4,'|'); file.getline(branch,5,'\n'); if(strcmp(index,ind) == 0)

cout<<"\nUSN: "<<usn <<"\nName: "<<name <<"\nAge: "<<age <<"\nSem: "<<sem <<"\nBranch: "<<branch;

} file.close(); return;}

void retrieve_details(){ int k=0,i; char name[20],usn[20],ind[2]; char chusn[20]; char index[20][20]; fstream file; file.open("secindex.txt",ios::in); for(i=0;i<no;i++) { file.getline(name,20,'|'); file.getline(usn,20,'|'); file.getline(ind,4,'\n'); if(strcmp(name,rt_name) == 0) {

strcpy(found[k].name,name); strcpy(found[k].usn,usn); strcpy(index[k],ind);

Page 96: Lab

96 File Structures

k++; } } file.close(); if(k==1) { retrieve_record(index[0]); return; } else { cout<<"Please choose the candidate's USN: \n"; for(i=0;i<k;i++) cout<<"Name: "<<found[i].name<<" USN: "<<found[i].usn<<endl; } cin>>chusn; for(i=0;i<k;i++) { if(strcmp(chusn,found[i].usn) == 0) {

retrieve_record(index[i]); return;

} } cout<<"Invalid Entry! \n"; return;}

void delete_record(char indx[]){ int i; fstream file1,file2; char age[5],sem[5],branch[5],usn[20],name[20],ind[5]; char index[20][20]; file2.open("record.txt",ios::in); for(i=0;i<no;i++) { file2.getline(ind,4,'|'); file2.getline(usn,20,'|'); file2.getline(name,20,'|'); file2.getline(age,5,'|'); file2.getline(sem,5,'|'); file2.getline(branch,8,'\n'); strcpy(index[i],ind); strcpy(rec[i].usn,usn); strcpy(rec[i].name,name);

Page 97: Lab

97File Structures

strcpy(rec[i].age,age); strcpy(rec[i].sem,sem); strcpy(rec[i].branch,branch); } int flag=-1; for(i=0;i<no;i++) { if(strcmp(index[i],indx) == 0) flag=i; } if(flag==-1) { cout<<"Error!\n"; return; } if(flag==(no-1)) { no--; cout<<"Deleted!\n"; return; } for(i=flag;i<no;i++) { rec[i]=rec[i+1]; } no--; cout<<"Deleted!\n"; file2.close(); file1.open("secindex.txt",ios::out); file2.open("record.txt",ios::out); for(i=0;i<no;i++) { file1<<rec[i].name<<"|"<<rec[i].usn<<"|"<<i<<"\n";

file2<<i<<"|"<<rec[i].usn<<"|"<<rec[i].name<<"|"

<<rec[i].age<<"|"<<rec[i].sem<<"|"<<rec[i].branch<<"\n"; } file1.close(); file2.close(); return;}

void delete_index(char* nam){ fstream file;

Page 98: Lab

98 File Structures

int i; int k=0; char name[20],usn[20],ind[5],index[20][20],chusn[20]; file.open("secindex.txt",ios::in); for(i=0;i<no;i++) { file.getline(name,20,'|'); file.getline(usn,20,'|'); file.getline(ind,4,'\n'); if(strcmp(nam,name)==0) {

strcpy(found[k].name,name); strcpy(found[k].usn,usn); strcpy(index[k],ind); k++;

} } file.close(); if(k==1) { delete_record(index[0]); return; } else { cout<<"Please choose the candidate's USN: \n"; for(i=0;i<k;i++) {

cout<<"Name: "<<found[i].name<<" USN: "<<found[i].usn<<endl; } } cin>>chusn; for(i=0;i<k;i++) { if(strcmp(chusn,found[i].usn)==0) {

delete_record(index[i]); return;

} } cout<<"Invalid Entry!\n"; return;}

int main(){

Page 99: Lab

99File Structures

fstream file1,file2; int ch; char rt_usn[20],st_name[20],st_usn[20]; char ind[2],name[20],age[2],sem[5],branch[5]; int i,flag,flag1; file1.open("index.txt",ios::out); file2.open("record.txt",ios::out); if(!file1 || !file2) {

cout<<"File creation Error!\n"; exit(0);

} for(;;) {

cout<<"\nl:Add Record\n2:Search Record" <<"\n3:Delete Record\n4:Display Record\n5:Exit" <<"\n\nEnter u'r choice :"; cin>>ch; switch(ch) { case 1: cout<<"Enter the no. of students : "; cin>>no;

cout<<"Enter the details :\n"; for(i=0;i<no;i++) { cout<<"\nName : "; cin>>rec[i].name; cout<<"Age : "; cin>>rec[i].age; cout<<"USN : "; cin>>rec[i].usn; cout<<"Sem : "; cin>>rec[i].sem; cout<<"Branch : "; cin>>rec[i].branch; } sort_records(); create_indexfile(); file1.close (); file2.close(); break;

case 2: cout<<"Enter name of the student whose record is tobe displayed\n";

cin>>st_name; file1.open("secindex.txt",ios::in); if(!file1) { cout<<"Error !\n"; exit(0); } flag1=0;

Page 100: Lab

100 File Structures

for(i=0;i<no;i++) { file1.getline(rt_name,20,'|'); file1.getline(rt_usn,20,'|'); file1.getline(st_no,4,'\n');

if(strcmp(st_name,rt_name)==0) {

retrieve_details();flag1=1;goto one;

} } one: if(!flag1)

cout<<"Record search failed !\n"; file1.close(); break;

case 3: cout<<"Enter name of student whose record is to bedeleted\n";

cin>>st_name; file1.open("secindex.txt",ios::in); if(!file1) { cout<<"Error !\n"; exit(0); } flag=0; for(i=0;i<no;i++) { file1.getline(rt_name,20,'|'); file1.getline(rt_usn,20,'|'); file1.getline(ind,4,'\n');

if(strcmp(st_name,rt_name) == 0) {

delete_index(rt_name); flag=1;

} } if(!flag) cout<<"Deletion failed !\n"; file1.close(); break;

case 4: for(i=0;i<no;i++)

Page 101: Lab

101File Structures

{ cout<<"\n\nUSN : "<<rec[i].usn

<<"\nName: "<<rec[i].name <<"\nAge : "<<rec[i].age <<"\nSem : "<<rec[i].sem <<"\nBranch : "<<rec[i].branch<<"\n";

} break;

case 5:exit(0); default: cout<<"Invalid option !\n";

exit(0); break;

} }}

Output :

1: Add Record2: Search Record3: Delete Record4: Display Record5: Exit

Enter u'r choice : 1

Enter the no. of students :2Enter the details:

Name: ajayAge: 20USN: 1vk07is002Sem: 6Branch: ise

Name: rahulAge: 20USN: 1vk07cs045Sem: 6Branch: cse

1: Add Record2: Search Record3: Delete Record4: Display Record5: Exit

Page 102: Lab

102 File Structures

Enter u'r choice : 4

Name: ajayAge: 20USN: 1vk07is002Sem: 6Branch: ise

Name: rahulAge: 20USN: 1vk07cs045Sem: 6Branch: cse

1: Add Record2: Search Record3: Delete Record4: Display Record5: Exit

Enter u'r choice :3

Enter USN whose record is to be deleted:1vk07cs045Deleted !

1: Add Record2: Search Record3: Delete Record4: Display Record5: Exit

Enter u'r choice :4

Name: ajayAge: 20USN: 1vk07is002Sem: 6Branch: ise

7. Write a C++ program to read two lists of names and then match the names inthe two lists using Consequential Match based on a single loop. Output thenames common to both the lists.

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

Page 103: Lab

103File Structures

#include<conio.h>#include<fstream.h>#include<iostream.h>

void writeLists(){ fstream out1,out2; int i,m,n; char name[20]; out1.open("file1.txt",ios::out); out2.open("file2.txt",ios::out); if( (!out1) || (!out2) ) {

cout<<"Unable to open one of the list files"; getch(); exit(0);

} cout<<"Enter no. of names you want to enter in file1 :"; cin>>m; cout<<"\nEnter the names in ascending order\n"; for(i=0;i<m;i++) {

cin>>name; out1<<name; out1<<'\n';

} cout<<"Enter no. of names you want to enter in file2 :"; cin>>n; cout<<"\nEnter the names in ascending order \n"; for(i=0;i<n;i++) {

cin>>name; out2<<name; out2<<'\n';

} out1.close(); out2.close();}

void main(){ char list1[100][20], list2[100][20]; int i,j,m,n; clrscr(); fstream out1,out2,out3; writeLists();

Page 104: Lab

104 File Structures

out1.open("file1.txt",ios::in); out2.open("file2.txt",ios::in); out3.open("file3.txt",ios::out); if( (!out3) || (!out1) || (!out2) ) { printf("Unable to open one of the file"); getch(); exit(0); } clrscr(); m=0; n=0; while(!out1.eof()) { out1.getline(list1[m],20,'\n'); cout<<list1[m]; m++; } while(!out2.eof()) { out2.getline(list2[n],20,'\n'); cout<<list2[n]; n++; } m--; n--; i=0; j=0;

cout<<"\nElements common to both files are: \n "; while(i<m && j<n)

{ if( strcmp(list1[i],list2[j]) == 0 ) {

out3<<list1[i]; cout<<list1[i]<<"\n"; out3<<'\n'; i++; j++;

} else if( strcmp(list1[i],list2[j]) < 0 )

i++; else

j++; }

Page 105: Lab

105File Structures

getch();}

Output :

Enter no. of names you want to enter in file1 : 3Enter the names in ascending ordercseisetc

Enter no. of names you want to enter in file1 : 2Enter the names in ascending orderecise

cseisetcecise

Elements common to both files are: ise

8. Write a C++ program to read k Lists of names and merge them using kwaymerge algorithm with k = 8.

#include<iostream.h>#include<fstream.h>#include<string.h>#include<conio.h>

// Record specification

class record{

public: char name[20];char usn[20];

}rec[20];

int no;

fstream file[8];

//The first 8 fileschar fname[8][8] = {"l.txt","2.txt","3.txt","4.txt","5.txt",

"6.txt","7.txt","8.txt"};

Page 106: Lab

106 File Structures

void merge_file(char* file1, char* file2, char* filename){

record recrd[20];int k; k=0;fstream f1,f2;f1.open(file1,ios::in); //open the first filef2.open(file2,ios::in); //open the second filewhile(!f1.eof()) //Unpack and retrieve first file{

f1.getline(recrd[k].name,20,'|'); f1.getline(recrd[k++].usn,20,'\n');

}while(!f2.eof()) //Unpack and retrieve second file{

f2.getline(recrd[k].name,20,'|');f2.getline(recrd [k++].usn, 20,'\n');

}record temp;int t,y;for(t=0;t<k-2;t++) //Sort the retrieved recordsfor(y=0;y<k-t-2;y++)if(strcmp(recrd[y].name,recrd[y+1].name)>0){

temp=recrd[y];recrd[y]=recrd[y+1];recrd[y+1]=temp;

}fstream temp1;temp1.open(filename,ios::out); //Open the file to be packed intofor(t=1;t<k-1;t++) //Pack the sorted records onto the file

temp1<<recrd[t].name<<"|"<<recrd[t].usn<<"\n";f1.close();f2.close();temp1.close();return;

}void kwaymerge(){char filename[7][20]={"ll.txt","22.txt","33.txt","44.txt","

lll.txtw","222.txt","llll.txr"};int i;int k;k=0;for(i=0;i<8;i+=2) //Merge and sort the 8 original files onto{ //the four files indicated {ll.txt,22.txt....}

merge_file(fname[i],fname[i+1],filename[k++]);

Page 107: Lab

107File Structures

}k=4;for(i=0;i<4;i+=2) //Merge and sort the four files onto lll.txt

and 222.txt{

merge_file(filename[i],filename[i+1],filename[k++]);}//Merge and sort the two files onto the llll.txt filemerge_file(filename[4],filename[5],filename[6]);return;

}

void main(){

int i;clrscr();cout<<"Enter the no. of records : ";cin>>no;cout<<"\nEnter the details : \n";for(i=0;i<8;i++) //Create 8 files to store the split data

file[i].open(fname[i],ios::out);for(i=0;i<no;i++) //Split and pack data onto the files{

cout<<"Name :"; cin>>rec[i].name;cout<<"USN : ";cin>>rec[i].usn;file[i%8]<<rec[i].name<<'|'<<rec[i].usn<<"\n";

}for(i=0;i<8;i++)file[i].close();kwaymerge(); //Mergefstream result;result.open("lll.txt",ios::in);cout<<"\nSorted Records : \n";char name[20],usn[20];for(i=0;i<no;i++) //Unpack the sorted records and dispL{

result.getline(name,20,'|');result.getline(usn,20,'\n');cout<<"\nName : "<<name<<"\nUSN : "<<usn<<"\n";

} getch();}

Output :

Enter the no. of records :4

Page 108: Lab

108 File Structures

Enter the details :

Name :rahulUSN :25

Name :laxmiUSN :16

Name :ajayUSN :2

Name :deepakUSN :8

Sorted Records :

Name :ajayUSN :2

Name :deepakUSN :8

Name :laxmiUSN :16

Name :rahulUSN :25

9. Write a C++ program to implement B-Tree for a given set of integers and itsoperations insert ( ) and search ( ). Display the tree.

#include<iostream.h>#include<stdio.h>#include<fstream.h>#include<stdlib.h>#include<string.h>class node{public:int a[4];node * next[4];node * parent;int size;node();};node :: node()

Page 109: Lab

109File Structures

{for(int i = 0; i < 4; i++)next[i] = NULL;parent = NULL;size = 0;}class btree{node * root;public:node* findLeaf(int key,int &level);void updateKey(node *p,node *c,int newKey);void search(int key);void insert(int key);void insertIntoNode(node *n,int key,node *address);void promote(node *n,int key,node *address);node* split(node *n);void traverse(node *ptr);btree();};void btree :: traverse(node *ptr){if(ptr == NULL)return;for(int i = 0; i < ptr->size; i++)cout<<ptr->a[i]<<" ";cout<<endl;for(i = 0; i < ptr->size;i++)traverse(ptr->next[i]);}btree :: btree(){root = NULL;}node* btree :: findLeaf(int key,int &level) {node *ptr = root;node *prevptr = NULL;level = 0;int i;while(ptr){i = 0;level++;while(i < ptr -> size-1 && key > ptr -> a[i])i++;

Page 110: Lab

110 File Structures

prevptr = ptr;ptr = ptr -> next[i]; } return prevptr;}node* btree :: split(node *n){int midpoint = (n -> size+1)/2;int newsize = n->size - midpoint;node *newptr = new node;node *child;newptr->parent = n -> parent;int i;for(i = 0; i < midpoint; i++){newptr->a[i] = n->a[i];newptr ->next[i] = n->next[i];n->a[i] = n->a[i+midpoint];n->next[i] = n->next[i+midpoint];}n->size = midpoint;newptr -> size = newsize;for( i = 0; i < n->size; i++){child = n->next[i];if(child!= NULL)child -> parent = n;}for( i = 0; i < newptr -> size; i++){child = newptr -> next[i];if(child!= NULL)child -> parent = newptr;}return newptr;}void btree :: updateKey(node *parent,node *child,int newkey){if( parent == NULL)return;if(parent->size == 0)return;int oldkey = child->a[child->size-2];for(int i = 0; i < parent->size;i++)if(parent->a[i] == oldkey){

Page 111: Lab

111File Structures

parent->a[i] = newkey; parent->next[i] = child;}}void btree :: insertIntoNode(node *n,int key,node *address){int i;if( n == NULL)return;for(i = 0; i < n->size; i++)if(n->a[i] == key)return;i = n->size-1;while(i >= 0 && n -> a[i] > key){n->a[i+1] = n->a[i];n->next[i+1] = n->next[i];i--;}i++;n->a[i] = key;n->next[i] = address;n->size++;if( i == n->size-1)updateKey(n->parent,n,key);}void btree :: promote(node *n,int key,node *address){if( n == NULL)return;if(n -> size < 4){

insertIntoNode(n,key,address);return;

}if( n == root){

root = new node;n->parent = root;

}node *newptr = split(n);node *t;if(key < n->a[0])t = newptr;elset = n;

Page 112: Lab

112 File Structures

insertIntoNode(t,key,address);promote(n->parent,n->a[n->size-1],n);promote(newptr->parent,newptr->a[newptr->size-1],newptr);}

void btree :: insert(int key){if( root == NULL){root = new node;root->a[root->size] = key;root->size++;return;}

int level;node *leaf = findLeaf(key,level);int i;for(i = 0; i < leaf->size; i++)if(leaf -> a[i] == key){cout<<"The Key to be inserted already exists"<<endl;return;}promote(leaf,key,NULL);cout<<"---------------\n";traverse(root);cout<<"----------------\n";}void btree :: search(int key){if(root == NULL){cout<<"The tree Does not exist"<<endl;return;}int level;node *leaf = findLeaf(key,level);int flag = 0;for(int i = 0; i < leaf ->size; i++)if(leaf->a[i] == key){flag = 1;cout<<"The Key "<<key<<" Exists in the B-Tree at the

level"<<level<<endl;}

Page 113: Lab

113File Structures

if(!flag)cout<<"The Key Searched for was not found"<<endl;}int main(){btree b;int choice = 1,key;while(choice <=2){cout<<"1.Insert a Key\n";cout<<"2.Search a key\n";cout<<"3.Exit\n";cout<<”\n\n Enter u’r choice :”;cin>>choice;switch(choice){case 1: cout<<"Enter The Key to be inserted in B-Tree\n";cin>>key;b.insert(key);break;case 2: cout<<"Enter The key to be searched\n";cin>>key;b.search(key);break;}}return 0;}

Output :

1.Insert a Key2.Search a key3.Exit

Enter u’r choice :1

Enter The Key to be inserted in B-Tree100

1.Insert a Key2.Search a key3.Exit

Enter u’r choice :1

Page 114: Lab

114 File Structures

Enter The Key to be inserted in B-Tree50-----------50 100-----------1.Insert a Key2.Search a key3.Exit

Enter u’r choice :1

Enter The Key to be inserted in B-Tree75

-------------50 75 100-------------1.Insert a Key2.Search a key3.Exit

Enter u’r choice :1

Enter The Key to be inserted in B-Tree200

---------------50 75 100 200---------------

1.Insert a Key2.Search a key3.Exit

Enter u’r choice :2

Enter The key to be searched100Key 100 exists in B-tree at level 1

10. Write a C++ program to implement B+ tree for a given set of integers and itsoperations insert ( ), and search ( ). Display the tree.

#include<iostream.h>#include<stdio.h>#include<fstream.h>

Page 115: Lab

115File Structures

#include<stdlib.h>#include<string.h>

class node{public:int a[4];node * next[4];node * parent;int size;node();};

class linkleaf{public:node * data;linkleaf *next;linkleaf();};

linkleaf :: linkleaf(){next = NULL;}node :: node(){for(int i = 0; i < 4; i++)next[i] = NULL;parent = NULL;size = 0;}class btree{node * root;linkleaf *head;int flag;public:node* findLeaf(int key,int &level);void updateKey(node *p,node *c,int newKey);void search(int key);void insert(int key);void insertIntoNode(node *n,int key,node *address);void promote(node *n,int key,node *address);node* split(node *n);void traverse(node *ptr);

Page 116: Lab

116 File Structures

void connectLeaf(node *n,node *newptr);void traverseleaf();btree();};void btree :: traverseleaf(){linkleaf * ptr = head;int i;while(ptr){for(i = 0; i < ptr -> data -> size; i++)cout<<ptr -> data -> a[i]<<" ";cout<<endl;ptr = ptr ->next;}}void btree :: connectLeaf(node *n,node *newptr){linkleaf *ptr = head,*prevptr = NULL,*p;while(ptr){if(ptr-> data == n)break;prevptr = ptr;ptr = ptr ->next;}if( ptr == NULL){cout<<"Unexpected Error!!";exit(0);}if( ptr == head){p = new linkleaf;p -> next = head;head = p;p->data = newptr;}else{p = new linkleaf;p-> next = ptr;prevptr -> next = p;p->data = newptr;}}

Page 117: Lab

117File Structures

void btree :: traverse(node *ptr){if(ptr == NULL)return;for(int i = 0; i < ptr->size; i++)cout<<ptr->a[i]<<" ";cout<<endl;for(int j = 0; j < ptr->size; j++)traverse(ptr->next[j]);}

btree :: btree(){root = NULL;head = NULL;}node* btree :: findLeaf(int key,int &level){node *ptr = root;node *prevptr = NULL;level = 0;int i;while(ptr){i = 0;level++;while(i < ptr -> size-1 && key > ptr -> a[i])i++;prevptr = ptr;ptr = ptr -> next[i];}return prevptr;}node* btree :: split(node *n){int midpoint = (n -> size+1)/2;int newsize = n->size - midpoint;node *newptr = new node;node *child;newptr->parent = n -> parent;int i;for(i = 0; i < midpoint; i++){newptr->a[i] = n->a[i];newptr ->next[i] = n->next[i];n->a[i] = n->a[i+midpoint];

Page 118: Lab

118 File Structures

n->next[i] = n->next[i+midpoint];}n->size = midpoint;newptr -> size = newsize;for( i = 0; i < n->size; i++){child = n->next[i];if(child!= NULL)child -> parent = n;}for( i = 0; i < newptr -> size; i++){child = newptr -> next[i];if(child!= NULL)child -> parent = newptr;}return newptr;}void btree :: updateKey(node *parent,node *child,int newkey){if( parent == NULL)return;if(parent->size == 0)return;int oldkey = child->a[child->size-2];for(int i = 0; i < parent->size;i++)if(parent->a[i] == oldkey){parent->a[i] = newkey;parent->next[i] = child;}}

void btree :: insertIntoNode(node *n,int key,node *address){int i;if( n == NULL)return;for(i = 0; i < n->size; i++)if(n->a[i] == key)return;i = n->size-1;while(i >= 0 && n -> a[i] > key){n->a[i+1] = n->a[i];n->next[i+1] = n->next[i];

Page 119: Lab

119File Structures

i--;}i++;n->a[i] = key;n->next[i] = address;n->size++;if( i == n->size-1)updateKey(n->parent,n,key);}

void btree :: promote(node *n,int key,node *address){if( n == NULL)return;if(n -> size < 4){insertIntoNode(n,key,address);return;}if( n == root){root = new node;n->parent = root;}node *newptr = split(n);node *t;if(key < n->a[0])t = newptr;elset = n;insertIntoNode(t,key,address);if(!flag){connectLeaf(n,newptr);flag = 1;}promote(n->parent,n->a[n->size-1],n);promote(newptr->parent,newptr->a[newptr->size-1],newptr);}void btree :: insert(int key){flag = 0;if( root == NULL){root = new node;root->a[root->size] = key;root->size++;head = new linkleaf;

Page 120: Lab

120 File Structures

head -> data = root;return;}int level;node *leaf = findLeaf(key,level);int i;for(i = 0; i < leaf->size; i++)if(leaf -> a[i] == key){cout<<"The Key to be inserted already exists"<<endl;return;}promote(leaf,key,NULL);cout<<"---------------\n";traverse(root);cout<<"----------------\n"; }void btree :: search(int key){if(root == NULL){cout<<"The tree Does not exist"<<endl;return;}int level;node *leaf = findLeaf(key,level);int flag = 0;for(int i = 0; i < leaf ->size; i++)if(leaf->a[i] == key){flag = 1;cout<<"The Key "<<key<<" Exists in the B-Tree at thelevel"<<level<<endl;}if(!flag)cout<<"The Key Searched for was not found"<<endl;}

int main(){btree b;int choice = 1,key;while(choice <=3){cout<<"1.Insert a Key\n";cout<<"2.Search a key\n";

Page 121: Lab

121File Structures

cout<<"3.Traverse Leaf\n";cout<<"4.Exit\n";cout<<”\n enter u’r choice :”;cin>>choice;switch(choice){case 1: cout<<"Enter The Key to be inserted in B-Tree\n";cin>>key;b.insert(key);break;case 2: cout<<"Enter The key to be searched\n";cin>>key;b.search(key);break;case 3: b.traverseleaf();break;}}return 0;}

Output :

1.Insert a Key2.Search a key3.Traverse Leaf4.Exit

enter u’r choice : 1

Enter The Key to be inserted in B-Tree100

1.Insert a Key2.Search a key3.Traverse Leaf4.Exit

enter u’r choice : 1

Enter The Key to be inserted in B-Tree50--------50 100--------

Page 122: Lab

122 File Structures

1.Insert a Key2.Search a key3.Traverse Leaf4.Exit

enter u’r choice : 1

Enter The Key to be inserted in B-Tree200

----------50 100 200----------1.Insert a Key2.Search a key3.Traverse Leaf4.Exit

enter u’r choice : 1

Enter The Key to be inserted in B-Tree75---------------50 75 100 200---------------

1.Insert a Key2.Search a key3.Traverse Leaf4.Exit

enter u’r choice : 2

Enter The key to be searched300

The Key Searched for was not found

11. Write a C++ program to store and retrieve student data from file usinghashing. Use any collision resolution technique

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<conio.h>#include<fstream.h>

Page 123: Lab

123File Structures

#include<iostream.h>

//Record specification

class node{ public: char name[15],usn[15];

node *link;};

node *h[29]; //Array of record pointers equal to size of hashkeys - 29

void insert(){ char name[15], usn[15], buffer[50]; fstream out; out.open("student.txt",ios::app); //opening student.txt inappend mode if(!out) { cout<<"\nUnable to open the file in append mode"; getch(); return; }

cout<<"\nEnter the name = "; cin>>name; cout<<"\nEnter the usn = "; cin>>usn;

strcpy(buffer,name); //Packing the record onto the file using'|' as a delimiter

strcat(buffer,"|"); strcat(buffer,usn); strcat(buffer,"\n"); // \n delimiter for the record out<<buffer; // appending the packed record onto the file out.close();}

//Insert record into the hash tablevoid hash_insert(char name1[], char usn1[], int hash_key){ node *p,*prev,*curr; p = new node; //dynamically allocate space using 'new' strcpy(p->name,name1); strcpy(p->usn,usn1); p->link=NULL;

Page 124: Lab

124 File Structures

prev=NULL; curr=h[hash_key]; if(curr==NULL) //getting hash pointer location Case: No

collision { h[hash_key]=p; return; } while(curr!=NULL) // Case : On collision - Insert at rear end { prev=curr; curr=curr->link; } prev->link=p;}

void retrive(){ fstream in; char name[15],usn[15]; int j,count; node *curr; in.open("student.txt",ios::in); // open record file in input

mode if(!in) { cout<<"\n Unable to open the file in input mode"; getch(); exit(0); } while(!in.eof()) { in.getline(name,15,'|'); //unpacking the record in.getline(usn,15,'\n'); count=0; for(j=0; j<strlen(usn); j++) {

count=count+usn[j]; } count=count%29; //Hash Key = ASCII count% 29 hash_insert(name,usn,count); } cout<<"\n Enter the usn = "; cin>>usn; count=0; for(j=0; j<strlen(usn); j++) // Calculating Hash Key count=count+usn[j];

Page 125: Lab

125File Structures

count=count%29; curr=h[count]; if(curr == NULL) { cout<<"\nRecord not found"; getch(); return; } do {

if(strcmp(curr->usn,usn)==0) //When the record is found,retrieve

{ cout<<"\nRecord found : "<<curr->usn<<" "<<curr->name; getch(); return;}else{ curr=curr->link;}

}while(curr!=NULL); //Search till end of list

if(curr==NULL) //End of list reached with no record found { cout<<"\nRecord not found"; getch(); return; }}

void main(){ int choice; clrscr(); fstream out; out.open("student.txt",ios::out); if(!out) {

cout<<"\nUnable to open the file in out mode";getch();exit(0);

} for(;;) {

cout<<"\n1:insert\n2: retrive\n3:exit\nEnter the choice - ";

Page 126: Lab

126 File Structures

cin>>choice;switch(choice){ case 1: insert();

break; case 2: retrive();

break; case 3: exit(0); default: cout<<"\nInvalid option";}

}}

Output :

1:insert2:retrive3:exit

Enter the choice – 1

Enter the name – ajayEnter the usn - 10

1:insert2:retrive3:exit

Enter the choice – 1

Enter the name – rahulEnter the usn - 20

1:insert2:retrive3:exit

Enter the choice – 1

Enter the name – deepakEnter the usn - 30

1:insert2:retrive3:exit

Enter the choice – 2

Page 127: Lab

127File Structures

Enter the usn = 20

Record found : rahul 20

12. Write a C++ program to reclaim the free space resulting from the deletion ofrecords using linked lists.

#include<stdio.h>#include<conio.h>#include<stdlib.h>#include<string.h>#include<iostream.h>#include<fstream.h>#include<new.h>

class node{ public: char name[20];

char usn[20]; node *link;

};node *first=NULL;

void writeFile(){ node *p; char buffer[100]; fstream out; out.open("student.txt", ios::out); if(!out) { cout<<"\n Unable to open the file student.txt in out mode"; getch(); exit(0); } p=first; while(p!=NULL) { strcpy(buffer,p->name); strcat(buffer,"|"); strcat(buffer,p->usn); strcat(buffer,"\n"); out<<buffer; p=p->link; }}

Page 128: Lab

128 File Structures

void display(){ node *p; if(first==NULL) { cout<<"\nList is empty"; return; } p=first; while(p!=NULL) { cout<<"|"<<p->name<<" "<<p->usn<<"|"<<"->"; p=p->link; }}

void Insert() //Insert the record at the rear end{ char name[20],usn[15]; node *p,*q; cout<<"\n Enter name = "; cin>>name; cout<<"\nEnter usn = "; cin>>usn; p=new node; strcpy(p->name,name); strcpy(p->usn,usn); p->link=NULL; if(first==NULL) {

first=p;writeFile();display(); //display the record on the screenreturn;

} for(q=first; q->link!=NULL; q=q->link) {

; } q->link=p; writeFile(); //writing the record to the file display(); //display the records to the screen.}

void Delete(){ char usn[15]; node *curr,*prev,*del; if(first==NULL)

Page 129: Lab

129File Structures

{ printf("\nThe list is empty. Deletion is not possible"); return; } cout<<"\nEnter the usn to be deleted = "; cin>>usn; if(strcmp(first->usn,usn)==0) {

cout<<"\n Record deleted";del = first;delete del;first=first->link;writeFile();return;

} prev=NULL; curr=first; while( ( strcmp(curr->usn,usn) != 0 ) && curr!=NULL) { prev=curr; curr=curr->link; } if(curr == NULL) { cout<<"\nThe student with usn "<<usn<<" is not present"; return; } prev->link = curr->link; writeFile(); display(); //display the records to the screen}

void main(){ int ch; clrscr(); for(;;) { cout<<"\n 1-Insert_rear \n 2-Delete_id \n 3-Exit \n Enter choice :"; cin>>ch; switch(ch) {

case 1: Insert(); break;

case 2: Delete(); break;

case 3: exit(0);

Page 130: Lab

130 File Structures

default: cout<<"\n Invalid option"; break;

} }}

Output :

1-Insert_rear2-Delete_id3-ExitEnter choice : 1

Enter name : ajayEnter USN : 10

|ajay 10|->1-Insert_rear2-Delete_id3-ExitEnter choice : 1

Enter name : rahulEnter USN : 20

|ajay 10|rahul 20|->

1-Insert_rear2-Delete_id3-ExitEnter choice : 1

Enter name : deepakEnter USN : 30

|ajay 10|rahul 20|Deepak 30|->

1-Insert_rear2-Delete_id3-ExitEnter choice :2

Enter the usn to be deleted = 20|ajay 10|Deepak 30|->

Page 131: Lab

131Computer Graphics and Visualization

COMPUTER GRAPHICS AND VISUALIZATIONLABORATORY

PART – A

IMPLEMENT THE FOLLOWING PROGRAMS IN C / C++

1. Program to recursively subdivides a tetrahedron to from 3D Sierpinskigasket. The number of recursive steps is to be specified by the user.

2. Program to implement Liang-Barsky line clipping algorithm.

3. Program to draw a color cube and spin it using OpenGL transformationmatrices.

4. Program to create a house like figure and rotate it about a given fixedpoint using OpenGL functions.

5. Program to implement the Cohen-Sutherland line-clipping algorithm.Make provision to specify the input line, window for clipping and view portfor displaying the clipped image.

6. Program to create a cylinder and a parallelepiped by extruding a circleand quadrilateral respectively. Allow the user to specify the circle and thequadrilateral.

7. Program, using OpenGL functions, to draw a simple shaded sceneconsisting of a tea pot on a table. Define suitably the position andproperties of the light source along with the properties of the propertiesof the surfaces of the solid object used in the scene.

8. Program to draw a color cube and allow the user to move the camerasuitably to experiment with perspective viewing. Use OpenGL functions.

9. Program to fill any given polygon using scan-line area filling algorithm.(Use appropriate data structures.)

10. Program to display a set of values { fij } as a rectangular mesh.

Procedure to run programs

Install GLUT 3.7 on your PC

1. Find where the OpenGL32.dll is installed on your computer. It is generally at:C:\WINNT\SYSTEM32 or C:\WINDOWS\SYSTEM32

2. Copy glut32.dll to the above directory, you may need to have administrator'sprivilege

Page 132: Lab

132 Computer Graphics and Visualization

3. Find the Visual Studio lib path: generally at: C:\Program Files\Microsoft VisualStudio\VC\lib or C:\Program Files\Microsoft Visual Studio .NET 2003\VC7\lib, orC:\Program Files\Microsoft Visual Studio 2005\VC8\lib, depending on your VisualStudio version.

4. Copy glut32.lib to the above directory

5. Find the Visual Studio include path: should be similar to 3 while \lib changes to\include

6. Copy glut.h to the above directory.

Introduction to opengl :GLUT stands for OpenGL Utility Toolkit. Mark J. Kilgard, to enable the construction

of OpenGL applications that are truly window system independent, conceived the GLUTlibrary. Thanks to GLUT, we can write applications without having to learn about Xwindows or Microsoft's own window system. Kilgard implemented the version for Xwindows, and later Nate Robins ported it to Microsoft Windows.

The main function will perform the required initializations and start the eventprocessing loop. All the functions in GLUT have the prefix glut, and those which performsome kind of initialization have the prefix glutInit. The first thing you must do is call thefunction glutInit.

void glutInit(int *argc, char **argv);

Parameters :argc - A pointer to the unmodified argc variable from the main function.argv - A pointer to the unmodified argv variable from the main function.

After initializing GLUT itself, we're going to define our window. First we establish thewindow's position, i.e. its top left corner. In order to do this we use the functionglutInitWindowPosition.

glutInitWindowPosition(int x, int y);

Parameters :x - the number of pixels from the left of the screen. -1 is the default value, meaning it isup to the window manager to decide where the window will appear. If not using thedefault values then you should pick a positive value, preferably one that will fit in yourscreen.

y - the number of pixels from the top of the screen.

Note that these parameters are only a suggestion to the window manager. Thewindow returned may be in a different position, although if you choose them wisely you'llusually get what you want. Next we'll choose the window size. In order to do this we usethe function glutInitWindowSize.

void glutInitWindowSize(int width, int height);

Parameters :width - The width of the windowheight - the height of the window

Page 133: Lab

133Computer Graphics and Visualization

Again the values for width and height are only a suggestion, so avoid choosingnegative values. Then you should define the display mode using the functionglutInitDisplayMode.

void glutInitDisplayMode(unsigned int mode)

Parameters :mode - specifies the display mode

The mode parameter is a Boolean combination (OR bit wise) of the possiblepredefined values in the GLUT library. You use mode to specify the color mode, and thenumber and type of buffers. The predefined constants to specify the color model are :

GLUT_RGBA or GLUT_RGB - selects a RGBA window. This is the default color mode.

GLUT_INDEX - selects a color index mode. The display mode also allows you toselect either a single or double buffer window. The predefined constants for this are:

GLUT_SINGLE - single buffer window

GLUT_DOUBLE - double buffer window, required to have smooth animation. Thereis more, you can specify if you want a window with a particular set of buffers. Themost common are :

1. GLUT_ACCUM - The accumulation buffer

2. GLUT_STENCIL - The stencil buffer

3. GLUT_DEPTH - The depth buffer

So, suppose you want a RGB window, with single buffering, and a depth buffer. Allyou have to do is to OR all the respective constants in order to create the required displaymode.

...glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE | GLUT DEPTH);...

After all the above steps, the window can be created with glutCreateWindow.

int glutCreateWindow(char *title);

Parameters :title - sets the window title

The return value of glutCreateWindow is the window identifier.

So now here is a little bit of code to perform all the initializations :

#include <GL/glut.h>

void main(int argc, char **argv) {

glutInit(&argc, argv);glutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE | GLUT_RGBA);glutInitWindowPosition(100,100);glutInitWindowSize(320,320);glutCreateWindow("3D Tech- GLUT Tutorial");

}

Page 134: Lab

134 Computer Graphics and Visualization

Note the include statement at the beginning of the code. The required include file comeswith the GLUT distribution. If you run this code, you'll obtain an empty black consolewindow but no OpenGL window. Furthermore after a few seconds the window disappears.There are two things left to do before we are ready to render something.

The first is to tell GLUT what is the function responsible for the rendering. Lets createan example function for the rendering. The function presented bellow will clear the colorbuffer and draw a triangle.

void renderScene(void) {

glClear(GL_COLOR_BUFFER_BIT);glBegin(GL_TRIANGLES);glVertex3f(-0.5,-0.5,0.0);glVertex3f(0.5,0.0,0.0);glVertex3f(0.0,0.5,0.0);glEnd();glFlush();

}

The name of this function is up to you. However, now you must tell GLUT that itshould use that function we just wrote for the rendering. This is called registering acallback. GLUT will call the function you supply whenever rendering is in order. For nowlets tell GLUT that the function renderScene should be used whenever the window isreported by the window system to be damaged. GLUT has a function that takes as aparameter the name of the function to use when redrawing is needed. Note: the functionyou supply as a parameter is also called the first time the window is created. The syntaxis as follows :

void glutDisplayFunc(void (*func)(void));

Parameters :func - the name of the function to be called when the window needs to be redrawn. Note:it is illegal to pass NULL as the argument to this function.

One last thing missing, that is telling GLUT that we're ready to get in the applicationevent processing loop. GLUT provides a function that gets the application in a neverending loop, always waiting for the next event to process. The GLUT function isglutMainLoop, and the syntax is as follows:

void glutMainLoop(void)

The code so far is presented bellow. Note that we've added an include statement inorder to start using standard OpenGL functions, like glClear, glBegin, glVertex3f, andglEnd. .If you try to run this code you'll get a console window, and a few instants after theOpenGL window with a white triangle, hopefully at the desired position and with thedesired size.

Page 135: Lab

135Computer Graphics and Visualization

#include <GL/glut.h>

void renderScene(void) {

glClear(GL_COLOR_BUFFER_BIT);glBegin(GL_TRIANGLES);glVertex3f(-0.5,-0.5,0.0);glVertex3f(0.5,0.0,0.0);glVertex3f(0.0,0.5,0.0);glEnd();glFlush();

}

void main(int argc, char **argv) {

glutInit(&argc, argv);glutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE | GLUT_RGBA);glutInitWindowPosition(100,100);glutInitWindowSize(320,320);glutCreateWindow("3D Tech- GLUT Tutorial");glutDisplayFunc(renderScene);glutMainLoop();

}

GLUT provides a way to define which function should be called when the windowis resized, i.e. to register a callback for recomputing the perspective. Furthermore, thisfunction will also be called when the window is initially created so that even if you'reinitial window is not square things will look OK.

GLUT achieves this using the function glutReshapeFunc.

void glutReshapeFunc(void (*func)(int width, int height));

Parameters :func - The name of the function that will be responsible for setting the correct perspectivewhen the window changes size.

So the first thing that we must do is to go back to the main function we defined inthe previous section and add a call to glutReshapeFunc. Lets call our own function to takecare of window resizes changeSize. The code for the main function with the call toglutReshapeFunc added in is:

void main(int argc, char **argv){

glutInit(&argc, argv);glutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE | GLUT_RGBA);glutInitWindowPosition(100,100);glutInitWindowSize(320,320);

Page 136: Lab

136 Computer Graphics and Visualization

glutCreateWindow("3D Tech- GLUT Tutorial");glutDisplayFunc(renderScene);

// Here is our new entry in the main functionglutReshapeFunc(changeSize);glutMainLoop();

}

The next thing we need to do is to define the function that we'll take care of theperspective. As seen by the syntax of glutReshapeFunc, the changeSize function has twoarguments, these are the new width and height, respectively, of the client area of thewindow, i.e. without the window decorations.

void changeSize(int w, int h){

// Prevent a divide by zero, when window is too short// (you cant make a window of zero width).if(h == 0)

h = 1;

float ratio = 1.0* w / h;

// Reset the coordinate system before modifyingglMatrixMode(GL_PROJECTION);glLoadIdentity();

// Set the viewport to be the entire windowglViewport(0, 0, w, h);

// Set the correct perspective.gluPerspective(45,ratio,1,1000);glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt(0.0,0.0,5.0,

0.0,0.0,-1.0, 0.0f,1.0f,0.0f);

}

A few functions we're introduced in this piece of code so let's go into a bit of detailin here before we all get lost. The first step was to compute the ratio between the widthand the height. Note that in order for this to be done correctly we must take care of thecase when the height of a window is actually zero to prevent a division by zero.

We then set the current matrix to be the projection matrix. This is the matrix thatdefines the viewing volume. We then load the identity matrix to initialize it. Afterwardswe set the viewport to be the whole window with the function glViewport. You can try

Page 137: Lab

137Computer Graphics and Visualization

with different values to see what you come up with, the first two parameters are the topright corner, and the last two are the bottom left. Note that these coordinates are relativeto the client area of the window, not the screen. If you do try with different values thendon't forget that the ratio computed above should also use the new width and heightvalues. The gluPerspective function is part of another library for OpenGL, the OpenGLUtility Library, or GLU. GLU is a standard component of the implementation of OpenGL.The gluPerspective function establishes the perspective parameters. The first onedefines the field of view angle in the yz plane, the ratio defines the relation between thewidth and height of the viewport. The last two parameters define the near and far clippingplanes. Anything closer than the near value, or further away than the far value will beclipped away from the scene. Beware with these settings or you may end up not seeinganything at all.

Finally, setting the camera. First we set the GL_MODELVIEW as our current matrix.the modelview matrix is where we'll define both the camera settings and the modelingtransformations. Before setting the camera it is always healthy to load the identity matrix.this avoids previous transformations to affect the camera settings. The gluLookAtfunction provides an easy and intuitive way to set the camera position and orientation.Basically it has three groups of parameters, each one is composed of 3 floating pointvalues. The first three values indicate the camera position. The second set of valuesdefines the point we're looking at. Actually it can be any point in our line of sight.The lastgroup indicates the up vector, this is usually set to (0.0, 1.0, 0.0), meaning that thecamera's is not tilted. If you want to tilt the camera just play with these values. Forexample, to see everything upside down try (0.0, -1.0, 0.0).

OK, so far so good. We have an OpenGL window with a white triangle. Nothing veryexciting, but hey, its a start. Now to complete this part of the GLUT tutorial lets have thattriangle spinning.

Lets go back to the main function and add some extra stuff. First lets tell GLUT thatwe want a double buffer. Double buffering allows for smooth animation by keeping thedrawing in a back buffer and swapping the back with the front buffer (the visible one)when the rendering is complete. Using double buffering prevents flickering.

...glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);...

The second thing we must do is to tell GLUT that when the application is idle therender function should be called. This causes GLUT to keep calling our renderingfunction therefore enabling animation. GLUT provides a function, glutIdleFunc, that letsyou register a callback function to be called when the application is idle.

void glutIdleFunc(void (*func)(void));

Parameters :func - The name of the function that will be called whenever the application is idle.

In our case, when the application is idle we want to call the previously defined

Page 138: Lab

138 Computer Graphics and Visualization

function that does the actual rendering: renderScene. We also need to enable depthtesting. By default OpenGL doesn't do this, so it doesn't know what objects are in the frontand which are on the back. Unless we did draw everything in back to front order, theobjects would be incorrectly drawn. Fortunately all that is required is to enable depthtesting as shown in the main function below. OK, so the main function now looks likethis :

void main(int argc, char **argv) {

glutInit(&argc, argv);

// This is where we say that we want a double bufferglutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);

glutInitWindowPosition(100,100);glutInitWindowSize(320,320);glutCreateWindow("3D Tech- GLUT Tutorial");glutDisplayFunc(renderScene);

// here is the setting of the idle functionglutIdleFunc(renderScene);

glutReshapeFunc(changeSize);

// enable depth testingglEnable(GL_DEPTH_TEST);glutMainLoop();

}

Afterwards, we go and change the rendering itself. First lets declare a floating pointvariable angle, and initialize it to 0.0 . Then lets add the necessary stuff to the renderScenefunction.

float angle=0.0;

void renderScene(void) {

// notice that we're now clearing the depth buffer// as well this is required, otherwise the depth buffer// gets filled and nothing gets rendered.// Try it out, remove the depth buffer part.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// save the previous settings, in this case save// we're refering to the camera settings.glPushMatrix();

Page 139: Lab

139Computer Graphics and Visualization

// Perform a rotation around the y axis (0,1,0)// by the amount of degrees defined in the variable angleglRotatef(angle,0.0,1.0,0.0);glBegin(GL_TRIANGLES);

glVertex3f(-0.5,-0.5,0.0);glVertex3f(0.5,0.0,0.0);glVertex3f(0.0,0.5,0.0);

glEnd();

// discard the modelling transformations// after this the matrix will have only the camera settings.glPopMatrix();

// swapping the buffers causes the rendering above to be// shownglutSwapBuffers();

// finally increase the angle for the next frameangle++;

}

The glutSwapBuffers function cause the front and back buffers to switch therebyshowing what was previously drawn in the back buffer. The syntax is as follows:

void glutSwapBuffers();

1. Program to recursively subdivides a tetrahedron to from 3D Sierpinski gasket.The number of recursive steps is to be specified by the user.

#include <stdlib.h>#include <stdio.h>#include <GL/glut.h>

typedef float point[3];

/* initial tetrahedron */

point v[]={{0.0, 0.0, 1.0}, {0.0, 0.942809, -0.33333},{-0.816497,-0.471405, -0.333333}, {0.816497, -0.471405, -0.333333}};

static GLfloat theta[] = {0.0,0.0,0.0};

int n;

void triangle( point a, point b, point c)

Page 140: Lab

140 Computer Graphics and Visualization

/* display one triangle using a line loop for wire frame, a singlenormal for constant shading, or three normals for interpolativeshading */{ glBegin(GL_POLYGON); glNormal3fv(a); glVertex3fv(a); glVertex3fv(b); glVertex3fv(c); glEnd();}

void divide_triangle(point a, point b, point c, int m){

/* triangle subdivision using vertex numbers righthand ruleapplied to create outward pointing faces */

point v1, v2, v3; int j; if(m>0) { for(j=0; j<3; j++) v1[j]=(a[j]+b[j])/2; for(j=0; j<3; j++) v2[j]=(a[j]+c[j])/2; for(j=0; j<3; j++) v3[j]=(b[j]+c[j])/2; divide_triangle(a, v1, v2, m-1); divide_triangle(c, v2, v3, m-1); divide_triangle(b, v3, v1, m-1); } else(triangle(a,b,c)); /* draw triangle at end of recursion*/}

void tetrahedron( int m){

/* Apply triangle subdivision to faces of tetrahedron */

glColor3f(1.0,1.0,1.0); divide_triangle(v[0], v[1], v[2], m);

glColor3f(1.0,0.0,0.0); divide_triangle(v[3], v[2], v[1], m);

glColor3f(0.0,1.0,0.0); divide_triangle(v[0], v[3], v[1], m);

glColor3f(0.0,0.0,1.0); divide_triangle(v[0], v[2], v[3], m);}

Page 141: Lab

141Computer Graphics and Visualization

void display(void){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); tetrahedron(n); glFlush();}

void myReshape(int w, int h){ glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w <= h) glOrtho(-2.0, 2.0, -2.0 * (GLfloat) h / (GLfloat) w, 2.0 * (GLfloat) h / (GLfloat) w, -10.0, 10.0); else glOrtho(-2.0 * (GLfloat) w / (GLfloat) h, 2.0 * (GLfloat) w / (GLfloat) h, -2.0, 2.0, -10.0,10.0); glMatrixMode(GL_MODELVIEW); glutPostRedisplay();}

void main(int argc, char **argv){ printf(" No. of Divisions ? "); scanf("%d",&n); glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(500, 500); glutCreateWindow("3D Gasket"); glutReshapeFunc(myReshape); glutDisplayFunc(display); glEnable(GL_DEPTH_TEST); glClearColor (0.0, 0.0, 0.0, 0.0); glutMainLoop();}

Page 142: Lab

142 Computer Graphics and Visualization

Output :

Page 143: Lab

143Computer Graphics and Visualization

2. Program to implement Liang-Barsky line clipping algorithm.

#include<stdio.h>#include<GL/glut.h>

double xmin=50,ymin=50,xmax=100,ymax=100;double xvmin=200,yvmin=200,xvmax=300,yvmax=300;float X0,Y0,X1,Y1;

int cliptest(double p,double q,double *t1,double *t2){

double t=q/p;if(p<0.0){

if(t>*t1) *t1=t;if(t>*t2) return(false);

}else

if(p>0.0){

if(t<*t2) *t2=t;if(t<*t2) return(false);

}else

if(p==0.0){

if(q<0.0) return(false);}return(true);

}

void LiangBarskyLineClipAndDraw(double x0,double y0,doublex1,double y1){

double dx=x1-x0,dy=y1-y0,te=0.0,t1=1.0;glColor3f(1.0,0.0,0.0);

glBegin(GL_LINE_LOOP);glVertex2f(xvmin,yvmin);glVertex2f(xvmax,yvmin);glVertex2f(xvmax,yvmax);glVertex2f(xvmin,yvmax);glEnd();

if(cliptest(-dx,x0-xmin,&te,&t1))if(cliptest(dx,xmax-x0,&te,&t1))

if(cliptest(-dy,y0-ymin,&te,&t1))if(cliptest(dy,ymax-y0,&te,&t1))

Page 144: Lab

144 Computer Graphics and Visualization

{if(t1<1.0){

x1=x0+t1*dx;y1=y0+t1*dy;

}if(te>0.0){

x0=x0+te*dx;y0=y0+te*dy;

} printf("\n%f %f : %f %f",x0,y0,x1,y1); double sx=(xvmax-xvmin)/(xmax-xmin); double sy=(yvmax-yvmin)/(ymax-ymin); double vx0=xvmin+(x0-xmin)*sx; double vy0=yvmin+(y0-ymin)*sy; double vx1=xvmin+(x1-xmin)*sx; double vy1=yvmin+(y1-ymin)*sy; glColor3f(0.0,0.0,1.0); glBegin(GL_LINES); glVertex2d(vx0,vy0); glVertex2d(vx1,vy1); glEnd();}

}

void display(){

//double x0=60,y0=20,x1=80,y1=120;glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0,0.0,0.0);glBegin(GL_LINES);glVertex2d(X0,Y0);glVertex2d(X1,Y1);glEnd();glColor3f(0.0,0.0,1.0);glBegin(GL_LINE_LOOP);glVertex2f(xmin,ymin);glVertex2f(xmax,ymin);glVertex2f(xmax,ymax);glVertex2f(xmin,ymax);glEnd();LiangBarskyLineClipAndDraw(X0,Y0,X1,Y1);glFlush();

}

Page 145: Lab

145Computer Graphics and Visualization

void myinit(){

glClearColor(1.0,1.0,1.0,1.0);glColor3f(1.0,0.0,0.);glPointSize(1.0);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0.0,499.0,0.0,499.0);

}

void main(int argc,char **argv){

printf("Enter end points : ");scanf("%f%f%f%f",&X0,&Y0,&X1,&Y1);glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);glutInitWindowSize(500,500);glutInitWindowPosition(0,0);glutCreateWindow("Liang Barsky Line Clipping Algorithm");glutDisplayFunc(display);myinit();glutMainLoop();

}

Output :

Page 146: Lab

146 Computer Graphics and Visualization

3. Program to draw a color cube and spin it using OpenGL transformationmatrices.

#include<stdlib.h>#include<GL/glut.h>

GLfloat vertices[]={-1.0,-1.0,-1.0, 1.0,-1.0,-1.0, 1.0,1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,1.0, 1.0,-1.0,1.0, 1.0,1.0,1.0,-1.0,1.0,1.0};

GLfloatnormals[]={-1.0,-1.0,-1.0,1.0,-1.0,-1.0,1.0,1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,1.0,1.0,-1.0,1.0,1.0,1.0,1.0,-1.0,1.0,1.0};GLfloatcolors[]={0.0,0.0,0.0,1.0,0.0,0.0,1.0,1.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0,1.0,0.0,1.0,1.0,1.0,1.0,0.0,1.0,1.0};GLubyteCubeIndices[]={0,3,2,1,2,3,7,6,0,4,7,3,1,2,6,5,4,5,6,7,0,1,5,4};static GLfloat theta[]={0.0,0.0,0.0};static GLint axis=2;void display(void){

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);glLoadIdentity();glRotatef(theta[0],1.0,0.0,0.0);glRotatef(theta[1],0.0,1.0,0.0);glRotatef(theta[2],0.0,0.0,1.0);glDrawElements(GL_QUADS,24,GL_UNSIGNED_BYTE,CubeIndices);glBegin(GL_LINES);glVertex3f(0.0,0.0,0.0);glVertex3f(1.0,1.0,1.0);glEnd();glFlush();glutSwapBuffers();

}

void spincube(){

theta[axis]-=1.0;if(theta[axis]>360.0)theta[axis]-=360.0;glutPostRedisplay();

}

Page 147: Lab

147Computer Graphics and Visualization

void mouse(int btn,int state,int x,int y){

if(btn==GLUT_LEFT_BUTTON && state==GLUT_DOWN) axis=0;if(btn==GLUT_MIDDLE_BUTTON && state==GLUT_DOWN) axis=1;if(btn==GLUT_RIGHT_BUTTON && state==GLUT_DOWN) axis=2;

}

void myReshape(int w,int h){

glViewport(0,0,w,h);glMatrixMode(GL_PROJECTION);glLoadIdentity();if(w<=h){

g l O r t h o ( - 2 . 0 , 2 . 0 , - 2 . 0 * ( G L f l o a t ) h /(GLfloat)w,2.0*(GLfloat)h/(GLfloat)w,-10.0,10.0);

}else{

glOrtho(-2.0*(GLfloat)w/(GLfloat)h,2.0*(GLfloat)w/(GLfloat)h,-2.0,2.0,-10.0,10.0);

}glMatrixMode(GL_MODELVIEW);

}

void main(int argc,char **argv){

glutInit(&argc,argv);glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);glutInitWindowSize(500,500);glutCreateWindow("Rotating Cube");glutReshapeFunc(myReshape);glutDisplayFunc(display);glutIdleFunc(spincube);glutMouseFunc(mouse);glEnable(GL_DEPTH_TEST);glEnableClientState(GL_COLOR_ARRAY);glEnableClientState(GL_NORMAL_ARRAY);glEnableClientState(GL_VERTEX_ARRAY);glVertexPointer(3,GL_FLOAT,0,vertices);glColorPointer(3,GL_FLOAT,0,colors);glNormalPointer(GL_FLOAT,0,normals);glClearColor(0.0,0.0,0.0,0.0);glColor3f(1.0,1.0,1.0);glutMainLoop();

}

Page 148: Lab

148 Computer Graphics and Visualization

Output :

4. Program to create a house like figure and rotate it about a given fixed pointusing OpenGL functions.

#include<stdio.h>#include<math.H>#include<GL/glut.h>

Glfloat house[3][9]={{150.0,150.0,225.0,300.0,300.0,200.0,200.0,250.0,250.0},{150.0,250.0,300.0,250.0,150.0,150.0,200.0,200.0,150.0},{1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0}};GLfloat rot_mat[3][3]={{0},{0},{0}};GLfloat result[3][9]={{0},{0},{0}};GLfloat h=150.0;GLfloat k=150.0;GLfloat theta;

void multiply(){

int i,j,l;for(i=0;i<3;i++)

Page 149: Lab

149Computer Graphics and Visualization

for(j=0;j<9;j++){

result[i][j]=0;for(l=0;l<3;l++)

result[i][j]=result[i][j]+rot_mat[i][l]*house[l][j];}

}

void rotate(){

GLfloat m,n;m=-h*(cos(theta)-1)+k*(sin(theta));n=-k*(cos(theta)-1)-h*(sin(theta));rot_mat[0][0]=cos(theta);rot_mat[0][1]=-sin(theta);rot_mat[0][2]=m;rot_mat[1][0]=sin(theta);rot_mat[1][1]=cos(theta);rot_mat[1][2]=n;rot_mat[2][0]=0;rot_mat[2][1]=0;rot_mat[2][2]=1;multiply();

}

void drawhouse(){

glColor3f(0.0,0.0,1.0);glBegin(GL_LINE_LOOP);glVertex2f(house[0][0],house[1][0]);glVertex2f(house[0][1],house[1][1]);glVertex2f(house[0][3],house[1][3]);glVertex2f(house[0][4],house[1][4]);glEnd();glColor3f(1.0,0.0,0.0);glBegin(GL_LINE_LOOP);glVertex2f(house[0][5],house[1][5]);glVertex2f(house[0][6],house[1][6]);glVertex2f(house[0][7],house[1][7]);glVertex2f(house[0][8],house[1][8]);glEnd();glColor3f(0.0,0.0,1.0);glBegin(GL_LINE_LOOP);glVertex2f(house[0][1],house[1][1]);

Page 150: Lab

150 Computer Graphics and Visualization

glVertex2f(house[0][2],house[1][2]);glVertex2f(house[0][3],house[1][3]);glEnd();

}

void drawrotatedhouse(){

glColor3f(0.0,0.0,1.0); glBegin(GL_LINE_LOOP);

glVertex2f(result[0][0],result[1][0]);glVertex2f(result[0][1],result[1][1]);glVertex2f(result[0][3],result[1][3]);glVertex2f(result[0][4],result[1][4]);glEnd();glColor3f(1.0,0.0,0.0);glBegin(GL_LINE_LOOP);glVertex2f(result[0][5],result[1][5]);glVertex2f(result[0][6],result[1][6]);glVertex2f(result[0][7],result[1][7]);glVertex2f(result[0][8],result[1][8]);glEnd();glColor3f(0.0,0.0,1.0);glBegin(GL_LINE_LOOP);glVertex2f(result[0][1],result[1][1]);glVertex2f(result[0][2],result[1][2]);glVertex2f(result[0][3],result[1][3]);glEnd();

}

void display(){

glClear(GL_COLOR_BUFFER_BIT);drawhouse();rotate();drawrotatedhouse();glFlush();

}

void myinit(){

glClearColor(1.0,1.0,1.0,1.0);glColor3f(1.0,0.0,0.0);glPointSize(1.0);

Page 151: Lab

151Computer Graphics and Visualization

glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0.0,499.0,0.0,499.0);

}

void main(int argc,char **argv){

printf("Enter the rotation angle\n");scanf("%f",&theta);theta=theta*(3.14/180);glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);glutInitWindowSize(500,500);glutInitWindowPosition(0,0);glutCreateWindow("house rotation");glutDisplayFunc(display);myinit();glutMainLoop();

}

Output :

Page 152: Lab

152 Computer Graphics and Visualization

5. Program to implement the Cohen-Sutherland line-clipping algorithm. Makeprovision to specify the input line, window for clipping and view port fordisplaying the clipped image.

#include<stdio.h>#include<GL/glut.h>

#define outcode intdouble xmin=50,ymin=50,xmax=100,ymax=100;double xvmin=200,yvmin=200,xvmax=300,yvmax=300;float X0,Y0,X1,Y1;const int RIGHT=2;const int LEFT=1;const int TOP=8;const int BOTTOM=4;

outcode ComputeOutCode(double x,double y);

void CohenSutherlandLineClipAndDraw(double x0,double y0,doublex1,double y1){

outcode outcode0,outcode1,outcodeOut;bool accept=false,done=false;outcode0=ComputeOutCode(x0,y0);outcode1=ComputeOutCode(x1,y1);

do{

if(!(outcode0 | outcode1)){

accept=true;done=true;

}else if(outcode0 & outcode1)

done=true;else{

double x,y,m;m=(y1-y0)/(x1-x0);outcodeOut=outcode0?outcode0:outcode1;if(outcodeOut & TOP){

x=x0+(ymax-y0)/m;y=ymax;

}else if(outcodeOut & BOTTOM)

Page 153: Lab

153Computer Graphics and Visualization

{x=x0+(ymin-y0)/m;y=ymin;

}else if(outcodeOut & RIGHT){

y=y0+(xmax-x0)*m;x=xmax;

}else{

y=y0+(xmin-x0)*m;x=xmin;

}if(outcodeOut == outcode0){

x0=x;y0=y;outcode0=ComputeOutCode(x0,y0);

}else{

x1=x;y1=y;outcode1=ComputeOutCode(x1,y1);

}}

}while(!done);glColor3f(1.0,0.0,0.0);glBegin(GL_LINE_LOOP);glVertex2f(xvmin,yvmin);glVertex2f(xvmax,yvmin);glVertex2f(xvmax,yvmax);glVertex2f(xvmin,yvmax);glEnd();printf("\n%f %f : %f %f",x0,y0,x1,y1);if(accept){

double sx=(xvmax-xvmin)/(xmax-xmin);double sy=(yvmax-yvmin)/(ymax-ymin);double vx0=xvmin+(x0-xmin)*sx;double vy0=yvmin+(y0-ymin)*sy;double vx1=xvmin+(x1-xmin)*sx;double vy1=yvmin+(y1-ymin)*sy;glColor3f(0.0,0.0,1.0);glBegin(GL_LINES);

Page 154: Lab

154 Computer Graphics and Visualization

glVertex2d(vx0,vy0);glVertex2d(vx1,vy1);glEnd();

}}outcode ComputeOutCode(double x,double y){

outcode code=0;if(y>ymax)

code|=TOP;else if(y<ymin)

code|=BOTTOM;if(x>xmax)

code|=RIGHT;else if(x<xmin)

code|=LEFT;return code;

}void display(){

glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0,0.0,0.0);glBegin(GL_LINES);glVertex2d(X0,Y0);glVertex2d(X1,Y1);glEnd();glColor3f(0.0,0.0,1.0);glBegin(GL_LINE_LOOP);glVertex2f(xmin,ymin);glVertex2f(xmax,ymin);glVertex2f(xmax,ymax);glVertex2f(xmin,ymax);glEnd();CohenSutherlandLineClipAndDraw(X0,Y0,X1,Y1);glFlush();

}

void myinit(){

glClearColor(1.0,1.0,1.0,1.0);glColor3f(1.0,0.0,0.0);glPointSize(1.0);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0.0,499.0,0.0,499.0);

}

Page 155: Lab

155Computer Graphics and Visualization

void main(int argc,char** argv){

printf("Enter end points : ");scanf("%f%f%f%f",&X0,&Y0,&X1,&Y1);glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);glutInitWindowSize(500,500);glutInitWindowPosition(0,0);glutCreateWindow("Cohen Sutherland Line Clipping Algorithm");glutDisplayFunc(display);myinit();glutMainLoop();

}

Output :

6. Program to create a cylinder and a parallelepiped by extruding a circle andquadrilateral respectively. Allow the user to specify the circle and thequadrilateral.

#include<stdio.h>#include<GL/glut.h>#include<math.h>

Page 156: Lab

156 Computer Graphics and Visualization

void d_pixel(GLint cx,GLint cy){

glColor3f(1.0,0.0,0.0);glBegin(GL_POINTS);glVertex2f(cx,cy);glEnd();

}

void plotpixels(GLint h,GLint k,GLint x,GLint y){ d_pixel(x+h,y+k); d_pixel(-x+h,-y+k); d_pixel(x+h,-y+k); d_pixel(-x+h,y+k); d_pixel(y+h,x+k); d_pixel(-y+h,x+k); d_pixel(y+h,-x+k); d_pixel(-y+h,-x+k);}

void circle_draw(GLint h,GLint k,GLint r){

GLint d=1-r,x=0,y=r;while(y>x){

plotpixels(h,k,x,y);if(d<0)

d+=2*x+3;else{

d+=2*(x-y)+5; --y;

}++x;

}plotpixels(h,k,x,y);

}

void cylinder_draw(){

GLint xc=100,yc=100,r=50;GLint i,n=50;for(i=0;i<n;i+=3){

circle_draw(xc,yc+i,r);}

}

Page 157: Lab

157Computer Graphics and Visualization

void parallelopiped(int x1,int x2,int y1,int y2){

glColor3f(0.0,0.0,1.0);glPointSize(2.0);glBegin(GL_LINE_LOOP);glVertex2i(x1,y1);

glVertex2i(x1,y2);glVertex2i(x2,y2);glVertex2i(x2,y1);

glEnd();}

void parallelopiped_draw(){

int x1=200,x2=300,y1=100,y2=175;GLint i,n=40;for(i=0;i<n;i+=2){

parallelopiped(x1+i,x2+i,y1+i,y2+i);}

}

void myinit(void){

glMatrixMode(GL_PROJECTION);gluOrtho2D(0.0,499.0,0.0,499.0);

}

void display(void){

glColor3f(1.0,0.0,0.0);glClear(GL_COLOR_BUFFER_BIT);glClearColor(1.0,1.0,1.0,1.0);glPointSize(2.0);cylinder_draw();parallelopiped_draw();glFlush();

}

void main(int argc,char** argv){

glutInit(&argc,argv); glutInitWindowPosition(0,0);

glutInitWindowSize(500,500);glutCreateWindow("cylinder and parallelopiped display byxtruding circle and quadrilateral");

Page 158: Lab

158 Computer Graphics and Visualization

myinit();glutDisplayFunc(display);glutMainLoop();

}

Output :

7. Program, using OpenGL functions, to draw a simple shaded scene consistingof a tea pot on a table. Define suitably the position and properties of the lightsource along with the properties of the properties of the surfaces of the solidobject used in the scene.

#include<stdio.h>#include<GL/glut.h>

void wall(double thickness){

//draw thin wall with top=xz-plan,corner at orginglPushMatrix();glTranslated(0.5,0.5*thickness,0.5);glScaled(1.0,thickness,1.0);glutSolidCube(1.0);glPopMatrix();

}

Page 159: Lab

159Computer Graphics and Visualization

//draw one table legvoid tableLeg(double thick,double len){

glPushMatrix();glTranslated(0,len/2,0);glScaled(thick,len,thick);glutSolidCube(1.0);glPopMatrix();

}

void table(double topWid,double topThick,double legThick,doublelegLen){

//draw the table -a top and four legs//draw the top firstglPushMatrix();glTranslated(0,legLen,0);glScaled(topWid,topThick,topWid);glutSolidCube(1.0);glPopMatrix();double dist=0.95*topWid/2.0 - legThick/2.0;glPushMatrix();glTranslated(dist,0,dist);tableLeg(legThick,legLen);glTranslated(0.0,0.0,-2*dist);tableLeg(legThick,legLen);glTranslated(-2*dist,0,2*dist);tableLeg(legThick,legLen);glTranslated(0,0,-2*dist);tableLeg(legThick,legLen);glPopMatrix();

}

void displaySolid(void){

//set properties of the surface materialGLfloat mat_ambient[]={1.0f,0.0f,0.0f,0.0f};//grayGLfloat mat_diffuse[]={0.5f,0.5f,0.5f,1.0f};GLfloat mat_specular[]={1.0f,1.0f,1.0f,1.0f};GLfloat mat_shininess[]={50.0f};glMaterialfv(GL_FRONT,GL_AMBIENT,mat_ambient);glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess);//set the light source propertiesGLfloat lightIntensity[]={0.9f,0.9f,0.9f,1.0f};

Page 160: Lab

160 Computer Graphics and Visualization

GLfloat light_position[]={2.0f,6.0f,3.0f,0.0f};glLightfv(GL_LIGHT0,GL_POSITION,light_position);glLightfv(GL_LIGHT0,GL_DIFFUSE,lightIntensity);

//set the cameraglMatrixMode(GL_PROJECTION);glLoadIdentity();double winHt=1.0;//half-height of windowglOrtho(-winHt*64/48.0,winHt*64/48.0,-winHt,winHt,0.1,100.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt(2.3,1.3,2.0,0.0,0.25,0.0,0.0,1.0,0.0);

//start drawingglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);glPushMatrix();glTranslated(0.4,0.4,0.6);glRotated(45,0,0,1);glScaled(0.08,0.08,0.08);glPopMatrix();

glPushMatrix();glTranslated(0.4,0.38,0.4);glRotated(30,0,1,0);glutSolidTeapot(0.08);glPopMatrix();

/*glPushMatrix();glTranslated(0.25,0.42,0.35);glutSolidSphere(0.1,15,15);glPopMatrix();*/

glPushMatrix();glTranslated(0.4,0,0.4);table(0.6,0.02,0.02,0.3);glPopMatrix();wall(0.02);

glPushMatrix();glRotated(90.0,0.0,0.0,1.0);wall(0.02);glPopMatrix();

glPushMatrix();glRotated(-90.0,1.0,0.0,0.0);wall(0.02);

Page 161: Lab

161Computer Graphics and Visualization

glPopMatrix();glFlush();

}

void main(int argc,char **argv){

glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);glutInitWindowSize(640,480);glutInitWindowPosition(100,100);glutCreateWindow("SIMPLE SHADED SCENE CONSISTING OF A TEA POT

ON A TABLE");glutDisplayFunc(displaySolid);glEnable(GL_LIGHTING);glEnable(GL_LIGHT0);glShadeModel(GL_SMOOTH);glEnable(GL_DEPTH_TEST);glEnable(GL_NORMALIZE);glClearColor(0.1,0.1,0.1,0.0);glViewport(0,0,640,480);glutMainLoop();

}

Output :

Page 162: Lab

162 Computer Graphics and Visualization

8. Program to draw a color cube and allow the user to move the camera suitablyto experiment with perspective viewing. Use OpenGL functions.

#include<stdio.h>#include<stdlib.h>#include<GL/glut.h>GLfloat vertices[][3]={{-1.0,-1.0,-1.0},{1.0,-1.0,-1.0},

{1.0,1.0,-1.0},{-1.0,1.0,-1.0},{-1.0,-1.0,1.0},{1.0,-1.0,1.0},{1.0,1.0,1.0},{-1.0,1.0,1.0}};

GLfloat normals[][3]={{-1.0,-1.0,-1.0},{1.0,-1.0,-1.0},{1.0,1.0,-1.0},{-1.0,1.0,-1.0},{-1.0,-1.0,1.0},{1.0,-1.0,1.0},{1.0,1.0,1.0},{-1.0,1.0,1.0}};

GLfloat colors[][3]={{0.0,0.0,0.0},{1.0,0.0,0.0},{1.0,1.0,0.0},{0.0,1.0,0.0},{0.0,0.0,1.0},{1.0,0.0,1.0},{1.0,1.0,1.0},{0.0,1.0,1.0}};

void polygon(int a,int b,int c,int d){

glBegin(GL_POLYGON);glColor3fv(colors[a]);glNormal3fv(normals[a]);glVertex3fv(vertices[a]);glColor3fv(colors[b]);glNormal3fv(normals[b]);glVertex3fv(vertices[b]);glColor3fv(colors[c]);glNormal3fv(normals[c]);glVertex3fv(vertices[c]);glColor3fv(colors[d]);glNormal3fv(normals[d]);glVertex3fv(vertices[d]);glEnd();

}

void colorcube(){

polygon(0,3,2,1);polygon(2,3,7,6);polygon(0,4,7,3);polygon(1,2,6,5);polygon(4,5,6,7);polygon(0,1,5,4);

}

Page 163: Lab

163Computer Graphics and Visualization

static GLfloat theta[]={0.0,0.0,0.0};static GLint axis=2;static GLdouble viewer[]={0.0,0.0,5.0};

void display(){

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);glLoadIdentity();

gluLookAt(viewer[0],viewer[1],viewer[2],0.0,0.0,0.0,0.0,1.0,0.0);glRotatef(theta[0],1.0,0.0,0.0);glRotatef(theta[1],0.0,1.0,0.0);glRotatef(theta[2],0.0,0.0,1.0);colorcube();glFlush();glutSwapBuffers();

}

void mouse(int btn,int state,int x,int y){

if(btn==GLUT_LEFT_BUTTON && state==GLUT_DOWN) axis=0;if(btn==GLUT_MIDDLE_BUTTON && state==GLUT_DOWN) axis=1;if(btn==GLUT_RIGHT_BUTTON && state==GLUT_DOWN) axis=2;theta[axis]+=2.0;if(theta[axis]>360.0)theta[axis]-=360.0;display();

}

void keys(unsigned char key,int x,int y){

if(key=='x') viewer[0]-=1.0;if(key=='X') viewer[0]+=1.0;if(key=='y') viewer[1]-=1.0;if(key=='Y') viewer[1]+=1.0;if(key=='z') viewer[2]-=1.0;if(key=='Z') viewer[2]+=1.0;display();

}

void myReshape(int w,int h){

glViewport(0,0,w,h);glMatrixMode(GL_PROJECTION);glLoadIdentity();if(w<=h){

glFrustum(-2.0,2.0,-2.0*(GLfloat)h/(GLfloat)w,2.0*

Page 164: Lab

164 Computer Graphics and Visualization

(GLfloat)h/(GLfloat)w,2.0,20.0);}else{

glFrustum(-2.0,2.0,-2.0*(GLfloat)w/(GLfloat)h,2.0*(GLfloat)w/(GLfloat)h,2.0,20.0);

}glMatrixMode(GL_MODELVIEW);

}

void main(int argc,char **argv){

glutInit(&argc,argv);glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);glutInitWindowSize(500,500);glutCreateWindow("Color Cube Viewer");glutReshapeFunc(myReshape);glutDisplayFunc(display);glutMouseFunc(mouse);glutKeyboardFunc(keys);glEnable(GL_DEPTH_TEST);glutMainLoop();

}

Output :

Page 165: Lab

165Computer Graphics and Visualization

9. Program to fill any given polygon using scan-line area filling algorithm. (Useappropriate data structures.)

#include <stdlib.h>#include <stdio.h>#include <GL/glut.h>

float x1,x2,x3,x4,y1,y2,y3,y4;void edgedetect(float x1,float y1,float x2,float y2,int *le,int*re){

float mx,x,temp;int i;

if((y2-y1)<0) { temp=y1;y1=y2;y2=temp; temp=x1;x1=x2;x2=temp; }

if((y2-y1)!=0) mx=(x2-x1)/(y2-y1); else mx=x2-x1;

x=x1; for(i=y1;i<=y2;i++) { if(x<(float)le[i]) le[i]=(int)x; if(x>(float)re[i]) re[i]=(int)x; x+=mx; }}

void draw_pixel(int x,int y,int value){ glColor3f(0.7,0.5,0.8); glBegin(GL_POINTS); glVertex2i(x,y); glEnd();}

void scanfill(float x1,float y1,float x2,float y2,float x3,floaty3,float x4,float y4){ int le[500],re[500];

Page 166: Lab

166 Computer Graphics and Visualization

int i,y; for(i=0;i<500;i++) { le[i]=500; re[i]=0; } edgedetect(x1,y1,x2,y2,le,re); edgedetect(x2,y2,x3,y3,le,re); edgedetect(x3,y3,x4,y4,le,re); edgedetect(x4,y4,x1,y1,le,re); for(y=0;y<500;y++) { if(le[y]<=re[y]) for(i=(int)le[y];i<(int)re[y];i++) draw_pixel(i,y,BLACK); }}

void display(){

x1=200.0;y1=200.0;x2=100.0;y2=300.0;x3=200.0;y3=400.0;x4=300.0;y4=300.0;

glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0, 0.0, 0.0);glBegin(GL_LINE_LOOP);glVertex2f(x1,y1);glVertex2f(x2,y2);glVertex2f(x3,y3);glVertex2f(x4,y4);glEnd();scanfill(x1,y1,x2,y2,x3,y3,x4,y4);glColor3f(1.0,0.0,0.0);glBegin(GL_LINES);glVertex2f(x1,y1);glVertex2f(x2,y2);glEnd();glColor3f(1.0,0.0,0.0);glBegin(GL_LINES);glVertex2f(x2,y2);glVertex2f(x3,y3);glEnd();glFlush();

}

void myinit(){

Page 167: Lab

167Computer Graphics and Visualization

glClearColor(1.0,1.0,1.0,1.0); glColor3f(1.0,0.0,0.0); glPointSize(1.0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0,499.0,0.0,499.0);}

void main(int argc, char** argv){ glutInit(&argc,argv); glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutInitWindowSize(500,500); glutInitWindowPosition(0,0); glutCreateWindow("Filling a Polygon using Scan-lineAlgorithm"); glutDisplayFunc(display); myinit(); glutMainLoop();}

Output :

Page 168: Lab

168 Computer Graphics and Visualization

10. Program to display a set of values { fij } as a rectangular mesh.

#include<stdlib.h>#include<GL/glut.h>

#define maxx 25#define maxy 25#define dx 15#define dy 10

GLfloat x[maxx]={0.0},y[maxy]={0.0};GLfloat x0=50,y0=50;int i,j;

void init(){

glClearColor(1.0,1.0,1.0,1.0);glColor3f(1.0,0.0,0.0);glPointSize(5.0);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0.0,499.0,0.0,499.0);glutPostRedisplay();

}

void display(void){

glClear(GL_COLOR_BUFFER_BIT);glColor3f(0.0,0.0,1.0);for(i=0;i<maxx;i++)

x[i]=x0+i*dx;for(j=0;j<maxy;j++)

y[j]=y0+j*dy;glColor3f(0.0,1.0,0.0);for(i=0;i<maxx-1;i++)

for(j=0;j<maxy-1;j++){

glColor3f(0.0,0.0,1.0);glBegin(GL_LINE_LOOP);glVertex2f(x[i],y[j]);glVertex2f(x[i],y[j+1]);glVertex2f(x[i+1],y[j+1]);glVertex2f(x[i+1],y[j]);glEnd();glFlush();

}

Page 169: Lab

169Computer Graphics and Visualization

glFlush();}

void main(int argc,char **argv){

glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);glutInitWindowSize(500,400);glutCreateWindow("rectangular mesh");glutDisplayFunc(display);init();glutMainLoop();

}

Output :


Recommended