Created
February 7, 2018 19:46
-
-
Save Leandros/af7e1e75a7b9e1c46287c5df3a8283ec to your computer and use it in GitHub Desktop.
Compile any file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*% cc -o # % | |
* com [-n] [file ...] | |
* looks for the sequence /*% in each file, and sends the rest of the | |
* line off to the shell, after replacing any instances of a `%' character | |
* with the filename, and any instances of `#' with the filename with its | |
* suffix removed. Used to allow information about how to compile a program | |
* to be stored with the program. The -n flag causes com not to | |
* act, but to print out the action it would have taken. | |
*/ | |
#include <string.h> | |
#include <stdio.h> | |
int nflag=0; | |
int maxstat=0; | |
void make(char []); | |
main(int argc, char *argv[]){ | |
int i; | |
FILE *fd; | |
char str[8192], *nl; | |
while(argc>1 && argv[1][0]=='-'){ | |
for(i=1;argv[1][i];i++) switch(argv[1][i]){ | |
case 'n': nflag++; break; | |
default: | |
Usage: | |
fprintf(stderr, "Usage: %s [-n] [file ...]\n", argv[0]); | |
exit(1); | |
} | |
argv++; | |
--argc; | |
} | |
if(argc==1){ | |
if((fd=fopen(".comfile", "r"))==NULL) goto Usage; | |
while(fgets(str, sizeof(str), fd)!=NULL){ | |
nl=strchr(str, '\n'); | |
if(nl) *nl='\0'; | |
make(str); | |
} | |
} | |
else{ | |
if(!nflag && (fd=fopen(".comfile", "w"))!=NULL){ | |
for(i=1;i!=argc;i++) fprintf(fd, "%s\n", argv[i]); | |
fclose(fd); | |
} | |
for(i=1;i!=argc;i++) make(argv[i]); | |
} | |
exit(maxstat); | |
} | |
void make(char file[]){ | |
char command[8192]; | |
char *s, *t, *suffix; | |
int c; | |
FILE *f; | |
int stat; | |
if((f=fopen(file, "r"))==NULL){ | |
fprintf(stderr, "com: "); | |
perror(file); | |
if(maxstat<1) maxstat=1; | |
return; | |
} | |
/* | |
* Look for /*% | |
*/ | |
for(;;){ | |
c=getc(f); | |
if(c==EOF){ | |
fprintf(stderr, "%s: no command\n", file); | |
fclose(f); | |
if(maxstat<1) maxstat=1; | |
return; | |
} | |
if(c=='/'){ | |
if((c=getc(f))=='*' && (c=getc(f))=='%') break; | |
ungetc(c, f); /* might be another slash! */ | |
} | |
} | |
s=command; | |
do;while((c=getc(f))==' ' || c=='\t'); | |
suffix=strrchr(file, '.'); | |
if(suffix==NULL) suffix=file+strlen(file); | |
while(c>=0 && c!='\n'){ | |
switch(c){ | |
default: | |
*s++=c; | |
break; | |
case '%': | |
c=getc(f); | |
if(c=='%') *s++='%'; | |
else{ | |
ungetc(c, f); | |
t=file; | |
while(*t) *s++ = *t++; | |
} | |
break; | |
case '#': | |
c=getc(f); | |
if(c=='#') *s++='#'; | |
else{ | |
ungetc(c, f); | |
t=file; | |
while(t!=suffix) *s++ = *t++; | |
} | |
} | |
c=getc(f); | |
} | |
t=s; | |
while(*t==' '||*t=='\0') t--; | |
if(*t == '/' && *(t - 1) == '*') { | |
t -= 2; | |
s=t; | |
} | |
*s='\0'; | |
if(nflag){ | |
printf("%s\n", command); | |
return; | |
} | |
fprintf(stderr, "%s\n", command); | |
switch(fork()){ | |
case -1: | |
fprintf(stderr, "com: can't fork\n"); | |
exit(1); | |
case 0: | |
execl("/bin/sh", "sh", "-c", command, 0); | |
fprintf(stderr, "com: No shell!\n"); | |
exit(1); | |
default: | |
wait(&stat); | |
if(stat>maxstat) maxstat=stat; | |
fclose(f); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment