Prova Pratica 2012.05.30

From Sistemi Operativi
Jump to navigation Jump to search

Soluzione di Dado e Pierg

Scrivere un minimake, cioe' una versione minimale del programma make.
Questo programma legge il file minimakefile nella directory corrente che ha il seguente formato:
target: comando
Il minimakefile e' scritto in modo che se le dipendenze sono generate da regole del minimakefile queste vengano definite
prima. Ad esempio il minimakefile per compilare ed eseguire il programma hw.c (hello world) sara':
hw.o: gcc -c hw.c
hw: gcc -o hw hw.o
run: ./hw
minimake deve scorrere il minimakefile, se il file indicato come target non esiste esegue il comando (e' vietato l'uso di popen,
system e simili!)
#include <stdio.h>
#include <stdlib.h>
#include "s2argv/s2argv.h"
#define MAKEFILE "minimakefile"
#define RUN "run"

int main(int argc, char * argv[]){
	FILE *mf;
	char *line=NULL;
	char *target,*command;
	int dim=0;
	mf=fopen(MAKEFILE,"r");
	if(mf==NULL){
		fprintf(stderr,"minimakefile not found!\n");
		exit(1);
	}
	while(getline(&line,&dim,mf)>0){
		target=strtok(line,":");
		command=strtok(NULL,"\n");
		if(strcmp(target,RUN)==0){
			system_noshell(command);
		}
		else if(fopen(target,"r")==NULL){
			system_noshell(command);
		}
        else{
			fprintf(stderr,"target %s già esistente: non eseguo\n",target);
		}
	}
	free(line);
	fclose(mf);
	return 0;
}
la sintassi del minimakefile per l'esercizio2 deve prevedere le dipendenze come il vero makefile.
target: dependence1 dependence2
comando
comando
(come per il makefile il target viene scritto a inizio linea, i comandi hanno un tab come primo carattere)
es per compilare hw.c.
hw.o: hw.c
gcc -c hw.c
hw: hw.o
gcc -o hw hw.o
run: hw
hw
in questo caso occorre eseguire i comandi che seguono la regola di dipendenza solo se il file target non esiste o
se un file indicato come dipendenza e' stato modificato piu' recentemente del target.
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include "s2argv/s2argv.h"
#define MAKEFILE "minimakefile"
#define RUN "run"

int main(int argc, char * argv[]){
	FILE *mf;
	char *line=NULL;
	char *target, *tmp;
	int dim = 0;
    int a = b = 0;
    struct stat st_target, st_tmp;
    
	mf=fopen(MAKEFILE,"r");
	if(fd==NULL){
		fprintf(stderr,"minimakefile not found!\n");
		exit(1);
	}
	while(getline(&line,&dim,mf)>0){
        if (line[0] == "\t") {
            if(a || b){
                system_noshell(line + 1);
            }
        }
		else{
			a = b = 0;
            target = strtok(line, ":")
            if(fopen(target,"r")==NULL){
                a = 1;
		    }
            else if(strcmp(target,RUN)==0){
                char *command = strtok(NULL, "\n");
                system_noshell(command);
		    }
            else {
                stat(target, &st_target);
                while ((tmp = (strtok(NULL, " "))!=NULL){
                    stat(tmp, &st_tmp);
                    if (st_tmp.st_mtime > st_target.st_mtime ) {
                        b = 1;
                        break;
                    }
                }
		    }
		}
	}
	free(line);
	fclose(fd);
	return 0;
}