📄 make.c
字号:
/*
* Do the actual making for make
*/
#include "h.h"
/*
* Support functions for Windows 95
*/
time_t CnvSystemTime(LPSYSTEMTIME pSysTime)
{
time_t result = 0;
int MonthDays[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
int wYear,wMonth;
for (wYear = 1970;wYear < pSysTime->wYear;wYear++)
result += (((wYear % 4)==0) ? 366 : 365);
for (wMonth = 1;wMonth < pSysTime->wMonth;wMonth++)
result += MonthDays[wMonth-1];
if ( (wMonth == 2) && ((wYear % 4) == 0) )
result ++;
result += pSysTime->wDay - 1;
result *= 24;
result += pSysTime->wHour;
result *= 60;
result += pSysTime->wMinute;
result *= 60;
result += pSysTime->wSecond;
#ifndef NDEBUG
printf("%2d %2d %4d , %2d:%02d:%02d = %d\n",
pSysTime->wDay,pSysTime->wMonth,pSysTime->wYear,
pSysTime->wHour,pSysTime->wMinute,pSysTime->wSecond,
result);
#endif
return result;
}
time_t time(time_t *buf)
{
SYSTEMTIME stNow;
time_t result;
GetSystemTime(&stNow);
result = CnvSystemTime(&stNow);
if (buf)
*buf = result;
return result;
}
char *strdup(const char *orig)
{
char *result;
result = (char *)malloc(strlen(orig)+1);
if (result != NULL)
strcpy(result,orig);
return result;
}
/*
* This way, child programs will execute and return the
* right exit code values.
*/
int _system(const char *cmd)
{
BOOL bResult;
STARTUPINFO si;
PROCESS_INFORMATION pi;
DWORD exitcode;
memset(&si,0,sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
bResult = CreateProcess(NULL,
cmd,
NULL,NULL, /* No security */
TRUE, /* Inherits handles */
0, /* Runs normally */
NULL,NULL, /* Inherits env & cwd */
&si,&pi);
if (bResult == FALSE)
return system(cmd);
/* Modification proposed by Sune Falck, Sune.Falck@swipnet.se */
WaitForSingleObject(pi.hProcess,INFINITE);
if (GetExitCodeProcess(pi.hProcess,&exitcode)==FALSE) {
fprintf(stderr,"Impossible to get the exit status for %s\n",cmd);
return -1;
}
return (int)exitcode;
}
/*
* Do commands to make a target
*/
void docmds1(NAME *np,LINE *lp)
{
bool ssilent;
bool signore;
int estat;
register char *q;
register CMD *cp;
for (cp = lp->l_cmd; cp; cp = cp->c_next)
{
strcpy(str1, cp->c_cmd);
expand(str1);
q = str1;
ssilent = silent;
signore = ignore;
while ((*q == '@') || (*q == '-'))
{
if (*q == '@') /* Specific silent */
ssilent = TRUE;
else /* Specific ignore */
signore = TRUE;
q++; /* Not part of the command */
}
if (!domake)
ssilent = 0;
if (!ssilent)
printf(" %s\n",q);
if (domake)
{ /* Get the shell to execute it */
estat = _system(q);
if (estat != 0)
{
printf("%s: Error code %d", myname, estat);
if (signore)
fputs(" (Ignored)\n", stdout);
else
{
putchar('\n');
if (!(np->n_flag & N_PREC))
if (unlink(np->n_name) == 0)
printf("%s: '%s' removed.\n", myname, np->n_name);
exit(estat);
}
}
}
}
}
void docmds(NAME *np)
{
register LINE *lp;
for (lp = np->n_line; lp; lp = lp->l_next)
docmds1(np, lp);
}
/*
* Get the modification time of a file. If the first
* doesn't exist, it's modtime is set to 0.
*/
void modtime(struct name *np)
{
FILETIME LastModifyTime;
SYSTEMTIME LastModSysTime;
HANDLE hFile;
BOOL bResult;
np->n_time = 0L;
hFile = CreateFileA(np->n_name,GENERIC_READ,
FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,NULL);
if (hFile == INVALID_HANDLE_VALUE) {
DWORD LastError = GetLastError();
if (LastError != ERROR_FILE_NOT_FOUND)
fatal ("Couldn't open %s GetLastError() = %d",np->n_name,LastError);
return;
}
bResult = GetFileTime(hFile,NULL,NULL,&LastModifyTime);
CloseHandle(hFile);
if (bResult == FALSE)
fatal ("Couldn't get file time for %s\n",np->n_name);
FileTimeToSystemTime(&LastModifyTime,&LastModSysTime);
np->n_time = CnvSystemTime(&LastModSysTime);
}
/*
* Update the mod time of a file to now.
*/
void touch(struct name *np)
{
SYSTEMTIME stNow;
FILETIME ftNow;
HANDLE hFile;
if (!domake || !silent)
printf(" touch(%s)\n", np->n_name);
if (domake)
{
hFile = CreateFileA(np->n_name,GENERIC_WRITE,
0,NULL,OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,NULL);
if (hFile == INVALID_HANDLE_VALUE) {
fatal("Couldn't touch %s",np->n_name);
}
GetSystemTime(&stNow);
SystemTimeToFileTime(&stNow,&ftNow);
SetFileTime(hFile,&ftNow,&ftNow,&ftNow);
CloseHandle(hFile);
}
}
/*
* Recursive routine to make a target.
*/
int make(NAME *np,int level)
{
register DEPEND *dp;
register LINE *lp;
register struct depend *qdp;
time_t dtime = 1;
bool didsomething = 0;
if (np->n_flag & N_DONE)
return 0;
if (!np->n_time)
modtime(np); /* Gets modtime of this file */
if (rules)
{
for (lp = np->n_line; lp; lp = lp->l_next)
if (lp->l_cmd)
break;
if (!lp)
dyndep(np);
}
if ( ((np->n_flag & N_TARG) == 0) && (np->n_time == 0L) )
fatal("Don't know how to make %s", np->n_name);
for (qdp = (DEPEND *)0, lp = np->n_line; lp; lp = lp->l_next)
{
for (dp = lp->l_dep; dp; dp = dp->d_next)
{
make(dp->d_name, level+1);
if (np->n_time < dp->d_name->n_time)
qdp = newdep(dp->d_name, qdp);
dtime = max(dtime, dp->d_name->n_time);
}
if (!quest && (np->n_flag & N_DOUBLE) && (np->n_time < dtime))
{
make1(np, lp, qdp); /* free()'s qdp */
dtime = 1;
qdp = (DEPEND *)0;
didsomething++;
}
}
np->n_flag |= N_DONE;
if (quest)
{
long t;
t = np->n_time;
time(&np->n_time);
return t < dtime;
}
else if (np->n_time < dtime && !(np->n_flag & N_DOUBLE))
{
make1(np, (LINE *)0, qdp); /* free()'s qdp */
time(&np->n_time);
}
else if (level == 0 && !didsomething)
printf("%s: '%s' is up to date\n", myname, np->n_name);
return 0;
}
make1(np, lp, qdp)
register DEPEND * qdp;
LINE * lp;
NAME * np;
{
register DEPEND * dp;
if (dotouch)
touch(np);
else
{
strcpy(str1, "");
for (dp = qdp; dp; dp = qdp)
{
if (strlen(str1))
strcat(str1, " ");
strcat(str1, dp->d_name->n_name);
qdp = dp->d_next;
free(dp);
}
setmacro("?", str1);
setmacro("@", np->n_name);
/* R.D. 1987/02/01 add "$*" macro to stand for target minus suffix */
/* I'm assuming that np->n_name is the full name of the target. */
{
#if 1
#define MAXNAMSIZ 32 /* allow 32-char names */
char tmpnam[MAXNAMSIZ];
char *p;
strcpy(tmpnam, np->n_name);
p = tmpnam + strlen(tmpnam);
while (*p != '.' && p != tmpnam)
--p;
/* now p points to dot, or tmpnam, or both */
if (*p == '.')
*p = '\0'; /* null out extension */
/* now tmpnam holds target minus suffix */
setmacro("*", tmpnam);
#else
char *ntarget = strdup(np->n_name);
char *p = strrchr(ntarget,'.');
if (*p)
p = '\0';
setmacro("*",ntarget);
#endif
}
if (lp) /* lp set if doing a :: rule */
docmds1(np, lp);
else
docmds(np);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -