📄 make.c
字号:
/*
Copyright 2001-2003 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
You may contact the author at:
mailto::camille@bluegrass.net
or by snail mail at:
David Lindauer
850 Washburn Ave Apt 99
Louisville, KY 40222
**********************************************************************
MAKE.C holds the code for the compile and build operations.
**********************************************************************
*/
#include <windows.h>
#include <commctrl.h>
#include <commdlg.h>
#include <richedit.h>
#include <stdio.h>
#include "header.h"
#define TEMPFILE "$$$CC386.TMP"
extern int browsing;
extern HWND hwndToolDebug;
extern PROJLIST *projectList;
extern char szInstallPath[];
extern HWND hwndError;
extern int changedProject;
extern int browseInfo;
extern char szProjectName[256];
extern enum DebugState uState;
extern HANDLE hInstance, hwndClient, hwndFrame;
int making, stopBuild;
int errcount, warncount;
static char tempfile[260];
void IsMaking(int makeRunning)
{
making = makeRunning;
SendMessage(hwndFrame, WM_REDRAWTOOLBAR, 0, 0);
} static void CreateTempFileName(void)
{
GetTempPath(240, tempfile);
if (tempfile[strlen(tempfile) - 1] != '\\')
;
strcat(tempfile, "\\");
strcat(tempfile, TEMPFILE);
}
//-------------------------------------------------------------------------
void newDepends(HWND tree, char *name, DEPENDSLIST *din, HTREEITEM item,
DEPENDSLIST **d, DEPENDSLIST *root)
{
DEPENDSLIST *temp = root;
char buf2[280];
FILE *in = fopen(name, "r");
if (!in)
return ;
// if (din)
// din->treeHandle = TVInitInsert(tree,item,TVI_LAST,din->title,TRUE) ;
while (!feof(in))
{
char buf[1024], *p = buf;
buf[0] = 0;
fgets(buf, 1024, in);
while (*p && (*p == ' ' || *p == '\t'))
p++;
if (*p == '#')
{
p++;
while (*p && (*p == ' ' || *p == '\t'))
p++;
if (!strncmp(p, "include", 7))
{
p += 7;
while (*p && (*p == ' ' || *p == '\t'))
p++;
if (*p == '"' || *p == '<')
{
int i = 0;
char *q, path[256];
FILE *fil;
p++;
strcpy(path, szProjectName);
q = strrchr(path, '\\');
if (q && *(q - 1) != ':')
{
*q = ';';
q++;
}
else
q = path;
strcpy(q, ProjectFindSelectedEXE()->includePath);
while (*p && *p != '"' && *p != '>')
buf[i++] = *p++;
buf[i] = 0;
if (fil = searchPathI(buf, path, "r"))
{
fclose(fil);
if ((q = strchr(buf, '\\')) && q[ - 1] != '.')
strcpy(buf, relpath(buf));
strcpy(buf2, buf);
abspath(buf2); // in case it is in local dir
temp = root;
while (temp)
{
if (!stricmp(temp->name, buf2))
break;
temp = temp->next;
}
if (!temp)
{
(*d) = malloc(sizeof(DEPENDSLIST));
if (*d)
{
memset(*d, 0, sizeof(DEPENDSLIST));
strcpy((*d)->name, buf2);
strcpy((*d)->title, buf);
newDepends(tree, (*d)->name, (*d), item, &(*d)
->next, root);
while ((*d))
d = (*d);
}
}
}
}
}
}
}
fclose(in);
}
//-------------------------------------------------------------------------
void CalcDepends(HWND tree, PROJLIST *proj)
{
PROJLIST *l = proj;
int count = 0, prog = 0;
FILELIST *m = proj->files;
while (m)
{
count++;
m = m->next;
}
m = proj->files;
if (count == 0)
{
ExtendedMessageBox("Dependency Calculations", MB_SETFOREGROUND |
MB_SYSTEMMODAL, "No files in project");
return ;
}
SetBusy(1);
MakeProgress(0, hInstance, "Dependency Calculation Progress", count);
while (m)
{
SetProgress(prog++, "File %d of %d", prog, count);
DeleteDepends(m->depends);
m->depends = 0;
newDepends(tree, m->name, 0, m->treeHandle, &m->depends, &m->depends);
m = m->next;
}
SetProgress(prog++, "File %d of %d", count, count);
RefreshDepends(tree, l);
TreeView_Expand(tree, l->includeTreeHandle, TVE_EXPAND);
TreeView_Expand(tree, l->treeHandle, TVE_EXPAND);
DeleteProgress();
SetBusy(0);
}
//-------------------------------------------------------------------------
void markProjects(int val)
{
PROJLIST *l = projectList;
while (l)
{
FILELIST *m = l->files;
l->rebuild = val;
while (m)
{
DEPENDSLIST *n = m->depends;
while (n)
{
n->rebuild = val;
n = n->next;
}
m->rebuild = val;
m = m->next;
}
l = l->next;
}
}
//-------------------------------------------------------------------------
int FileTime(FILETIME *timex, char *name)
{
HANDLE fd;
fd = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
if (fd == INVALID_HANDLE_VALUE)
return 0;
if (!GetFileTime(fd, 0, 0, timex))
{
CloseHandle(fd);
return 0;
}
CloseHandle(fd);
return 1;
}
//-------------------------------------------------------------------------
int CompareTimes(FILETIME *target, FILETIME *source)
{
// gotta have a two second delay because windows writes the files
// in different orders... this is the max delay based on FAT
DWORD high = source->dwHighDateTime - target->dwHighDateTime;
int carry = source->dwLowDateTime < target->dwLowDateTime;
DWORD low = source->dwLowDateTime - target->dwLowDateTime;
high -= carry;
carry = (low - 20000001) > low;
low -= 20000001;
high -= carry;
if ((int)high >= 0)
return 1;
return 0;
}
//-------------------------------------------------------------------------
int exists(char *name)
{
FILE *in;
if (!name[0])
return TRUE;
in = fopen(name, "r");
if (in)
fclose(in);
return !!(int)in;
}
//-------------------------------------------------------------------------
void OutputFile(PROJLIST *p, FILELIST *f, FILETIME *timex)
{
char drive[10], dir[256], name[256], ext[100];
if (p->outputPath[0])
{
int l = strlen(p->outputPath);
strcpy(f->output, p->outputPath);
if (f->output[l - 1] != '\\')
strcat(f->output, "\\");
}
else
{
_splitpath(p->name, drive, dir, name, ext);
strcpy(f->output, drive);
strcat(f->output, dir);
}
_splitpath(f->name, drive, dir, name, ext);
strcat(f->output, name);
if (!xstricmpz(ext, ".c") || !xstricmpz(ext, ".cpp") || !xstricmpz(ext,
".asm"))
strcat(f->output, ".obj");
else if (!xstricmpz(ext, ".rc"))
strcat(f->output, ".res");
else
strcat(f->output, ext);
if (exists(f->output) && timex)
FileTime(timex, f->output);
}
//-------------------------------------------------------------------------
void repDependsTime(char *name, FILETIME *time)
{
PROJLIST *l = projectList;
while (l)
{
FILELIST *m = l->files;
while (m)
{
DEPENDSLIST *n = m->depends;
while (n)
{
if (!stricmp(name, n->name))
{
n->timex = *time;
n->gottime = TRUE;
}
n = n->next;
}
m = m->next;
}
l = l->next;
}
}
//-------------------------------------------------------------------------
int CalcRebuilds(void)
{
PROJLIST *l = projectList;
int rv = FALSE;
SetBusy(1);
while (l)
{
FILELIST *m = l->files;
FileTime(&l->timex, l->name);
while (m)
{
DEPENDSLIST *n = m->depends;
while (n)
{
n->gottime = FALSE;
n = n->next;
}
m = m->next;
}
l = l->next;
}
l = projectList;
while (l)
{
FILELIST *m = l->files;
FileTime(&l->timex, l->name);
while (m)
{
DEPENDSLIST *n = m->depends;
FileTime(&m->timex, m->name);
OutputFile(l, m, &m->outputTimex);
while (n)
{
if (!n->gottime)
{
FileTime(&n->timex, n->name);
repDependsTime(n->name, &n->timex);
}
n = n->next;
}
m = m->next;
}
l = l->next;
}
l = projectList;
while (l)
{
FILELIST *m = l->files;
while (m)
{
DEPENDSLIST *n = m->depends;
while (n)
{
l->rebuild |= CompareTimes(&l->timex, &n->timex);
n->rebuild = CompareTimes(&m->outputTimex, &n->timex);
if (n->rebuild)
{
// ExtendedMessageBox("hi",MB_SETFOREGROUND | MB_SYSTEMMODAL,"%s %s %s",l->title,m->output,n->title) ;
}
m->rebuild |= n->rebuild;
n = n->next;
}
if (xstricmpz(m->output, m->name) && !exists(m->output) ||
CompareTimes(&m->outputTimex, &m->timex))
{
m->rebuild = TRUE;
// ExtendedMessageBox("hi",MB_SETFOREGROUND | MB_SYSTEMMODAL,"%s %s",m->title,m->output) ;
rv = TRUE;
}
if (m->rebuild || CompareTimes(&l->timex, &m->timex))
{
l->rebuild = TRUE;
// ExtendedMessageBox("hi",MB_SETFOREGROUND | MB_SYSTEMMODAL,"%s %s",l->title,m->title) ;
rv = TRUE;
}
m = m->next;
}
l = l->next;
}
SetBusy(0);
return rv;
}
//-------------------------------------------------------------------------
void countErrors(char *buf)
{
char *p = buf;
if (!xstricmp(p, "ERROR") || stristr(p, "ERROR:"))
errcount++;
if (!xstricmp(p, "WARNING") || stristr(p, "WARNING:"))
warncount++;
if (!xstricmp(p, "LINKER ERROR"))
errcount++;
if (!xstricmp(p, "FATAL ERROR"))
errcount++;
while (p = stristr(p, "\nERROR"))
{
errcount++;
p += 6;
}
p = buf;
while (p = stristr(p, "\nLINKER ERROR"))
{
errcount++;
p += 13;
}
p = buf;
while (p = stristr(p, "\nFATAL ERROR"))
{
errcount++;
p += 13;
}
p = buf;
while (p = stristr(p, "\nWARNING"))
{
warncount++;
p += 8;
}
}
//-------------------------------------------------------------------------
int ParsePipeData(HANDLE handle, int window, HANDLE hProcess)
{
static char buf[513];
static int pos = 0;
char *p;
int rv = TRUE;
while (TRUE)
{
int read = 0;
if (pos < 512)
{
int avail = 0;
while (TRUE)
{
DWORD xx;
avail = 0;
rv = PeekNamedPipe(handle, 0, 0, 0, &avail, 0);
if (!rv)
{
Sleep(100);
rv = PeekNamedPipe(handle, 0, 0, 0, &avail, 0);
}
if (rv && avail)
break;
// if (WaitForSingleObject(hProcess, 0) != WAIT_TIMEOUT) {
GetExitCodeProcess(hProcess, &xx);
if (xx != STILL_ACTIVE)
{
rv = FALSE;
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -