⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cfar.c

📁 OXCC is a multipass, interpreting C compiler with several language extensions. It generates an Archi
💻 C
📖 第 1 页 / 共 3 页
字号:
    N         If File mode, give input file a new name (last part of cfpath)\n\
");
}
static int
get_nameparts(char *name)
{
int namlen = strlen(name);
int i,j;

	basefile[0] = 0;
	midpath[0] = 0;
	innerpath[0] = 0;
	midpart = 0;
	if((lastpart = strrchr(name, '/')) != NULL)
		++lastpart;
	if(newname && !lastpart)
	{
		cfprintf("cfar: new filename enabled but not supplied\n");
		Usage();
		return 1;
	}
	for(i = namlen-1; i >= 0; --i)
	{
		if(		name[i] == 'f'
			&&	name[i-1] == 'f'
			&&	name[i-2] == 'c'
			&&	name[i-3] == '.')
		{
			_strncpy(basefile, name, i+1);

			if(&name[i] > lastpart)
			{/* basefile is all there is */
				lastpart = NULL;
			}
			else if(&name[i] != lastpart-2)
			{/* there is more than just a root directory mentioned */
				midpart = &name[i]+2;
				_strncpy(midpath, midpart, (int)(lastpart-midpart-1));
			}
			j = 0;
			if(midpart)
			{
				innerpath[0] = '/';
				j = _strcpy(&innerpath[1], midpath);
				++j;
			}
			if(lastpart && !newname)
			{
				innerpath[j++] = '/';
				strcpy(&innerpath[j], lastpart);
			}
		}
	}
	return 0;
}
static void
shrink_archive(char *name)
{
void *x;
void *y;

	cfprintf("cfar: shrink_archive %s\n", name);
	if(verbose)
		cfprintf("cfar: copy in\n");
	x = cfcopy("MEMORY/shrink", name);
	if(verbose)
		cfprintf("cfar: copy out\n");
	y = cfcopy(name, x);
	if(verbose)
		cfprintf("cfar: clean up\n");
	cfunlink(x, NULL);
	cfclose(y);
}
static void
stat_file(OrgItem *op, char *name, long namlen, long typ, long num, 
		char *arch, void *scratch)
{
Item orgtag;
char orgpath[1024];
char *in;
long orglen;
long sn = op->sn;

	cfget(qorigins, &sn, 4, &orgpath, 1023);
	orglen = strlen(orgpath);

	if(typ >= 0 && orgpath[orglen-1] == 'a' && orgpath[orglen-2] == '.')
	{/* This origin is a library */
		/* Mark this origin or return if it has been marked */
		orgtag.a2.size = op->sn;
		orgtag.a0 = typ<<4 + num;
		orgtag.a2.type = STO_VALUE;
		/* libraries are handled differently */
		if(cfinsert(scratch, &orgtag, 8, &orgtag) != OK)
			return;
	}
	else if(typ == -3 || typ >= 0)
	{/* This origin is a directory, with an embedded file */
		orgpath[orglen] = '/';
		++orglen;
		orglen += _strcpy(&orgpath[orglen], name);
	}
	else if(typ == -1)
	{/* this origin is for a filemode entry */
		in = strrchr(name, '/');
		if(name[namlen-1] == '?')
			typ = -2;		/* the entry was made with newname */
		else
		{
			orglen += _strcpy(&orgpath[orglen], in);
			orgpath[orglen-1] = 0;	/* strip tag */
		}
	}
	/* The origin has not been examined, do it */
	if(freshen)
	{
	CFSTAT s;
		if(cfstat(orgpath, &s) == OK)
		{
			if(s.st_mtime > op->filetime)
			{ /* REFRESH THIS ITEM */
				++orglen;
				if(typ < 0 && typ != -3)
				{
					--namlen;	/* clip tag */
					cfpush_data(scratch, name, namlen);
					cfpush_value(scratch, &namlen);
					++namlen;
				}
				cfpush_data(scratch, orgpath, orglen);
				cfpush_value(scratch, &orglen);
				cfpush_value(scratch, &typ);
				cfpush_value(scratch, &num);
			}
		}
		else
			cfprintf("cannot stat %s, CONTINUING\n", orgpath);
	}
	if(batfile)
	{
		if(typ == -3)
		{/* dllmode entry */
			cfprintf("cfar -Dr %s %s\n", arch, orgpath);
		}
		else if(typ < 0)
		{/* filemode entry */
		int c = (num == 1) ? 'C' : ' ';	/* chunk flag */
			if(typ == -2)
			{/* rename needed */
				name[namlen-1] = 0;	/* clip off the tag */
				cfprintf("cfar -FNr%c %s%s %s\n", c, arch, name, orgpath);
			}
			else
			{/* no rename, clip off the last part of name */
				*in = 0;
				cfprintf("cfar -Fr%c %s%s %s\n", c, arch, name, orgpath);
				*in = '/';
			}
		}
		else
		{/* object file entry */
			cfprintf("cfar -rt%dl%d %s %s\n", typ, num, arch, orgpath);
		}
	}
}
static void
scan_archive(char *archname, void *scratch)
{
int i;
OrgItem oi;
void *clib;

	/* Check stored object files */
	get_libtypes(archname);
	for(i = 0; i < MAXLIBTYPE; ++i)
	{
	char path[256];
	int j;
		if(!ltypes[i])
			continue;
		cfsprintf(path, "%s/ltype%d", archname, i);
		get_libnums(path);
		if(i == 3)
		{/* dllmode libtype */
			if((clib = cfopen(path, F_RDONLY, NULL)))
			{
			  if(cfhead(clib, &oi) == OK)
			  {
				do {
				char key[256];
				int keylen;
				char *cp;
					memclr(key,256);
					cfkey(clib, key, 255);
					keylen = strlen(key);

					if((cp = strstr(key, ".org")))
					{
					  *cp = 0;
					  stat_file(&oi, key, keylen-4, -3, 0, archname, scratch);
					}
				} while (cfnext(clib, &oi) == OK);
			  }
			  cfclose(clib);
			}
		}
		else
		{ /* objmode libtype */
		  for(j = 0; j < 4096; ++j)
		  {
			if(!lnums[j])
				continue;
			cfsprintf(path, "%s/ltype%d/lib%d", archname, i, j);
			if((clib = cfopen(path, F_RDONLY, NULL)))
			{
			  if(cfhead(clib, &oi) == OK)
			  {
				do {
				char key[256];
				int keylen;
					memclr(key,256);
					cfkey(clib, key, 255);
					keylen = strlen(key);
					if(key[keylen-1] == 't') {
						key[keylen-1] = 'o';
						stat_file(&oi, key, keylen, i, j, archname, scratch);
					}
				} while (cfnext(clib, &oi) == OK);
			  }
			  cfclose(clib);
			}
		  }
		}
	}
	/* Check stored FILEMODE files */
	if(cfhead(fipaths, &oi) == OK)
	{
	  do {
	  char key[1024];
	  int keylen;
	  char tag;
	  int ischunk;
	  CFSTAT sbuf;
		memclr(key,1024);
		cfkey(fipaths, key, 1023);
		keylen = strlen(key);
		tag = key[keylen-1];
		key[keylen-1] = 0;
		if(cfsubstat(archive, &key[1], &sbuf) != OK)
		{
			cfprintf("cfar: can't stat internal file %s\n", key);
			continue;
		}
		if(sbuf.st_mode & M_CHUNK)
			ischunk = 1;
		else
			ischunk = 0;
		key[keylen-1] = tag;
		stat_file(&oi, key, keylen, -1, ischunk, archname, scratch);
	  } while (cfnext(fipaths, &oi) == OK);
	}
}
static void
setup_version(int flag, char *archname)
{
KeyItem snval = 0;
	cfinsert(archive, "ArVer", 5, &prgversion);
	cfinsert(archive, "SN0", 3, &snval);
	cfinsert(archive, "SN1", 3, &snval);
	cfinsert(archive, "SN2", 3, &snval);
	if(flag)
		 cfprintf("cfar: add archive property to %s\n", archname);
	else cfprintf("cfar: create archive %s\n", archname);
}
static void
lose_backslashes(char *cp)
{
	while(*cp) {
		if(*cp == '\\')
			*cp = '/';
		++cp;
	}
}
#ifdef SKELETON
int cfar(int argc, char **argv)
#else
int main(int argc, char **argv)
#endif
{
int err = 0;
int i, j;
long curbufs, newbufs;

#ifndef SKELETON
	cfinit("cfar", 400, NULL);
	if((err = oxlink_init(cf_find_file(argv[0], 0))) == 0)
	{
#endif
	  /* Get the switches */
	  for(i = 1; i < argc; ++i)
	  {
	  int trimsize = 1;
		lose_backslashes(argv[i]);
		if(argv[i][0] == '-')
		{
		  for(j=1; argv[i][j]; ++j)
		  {
			switch(argv[i][j])
			{
			  case 'f':
				freshen = 1;
				break;
			  case 'r':
				act = arREPLACE;
				replace = 1;
				break;
			  case 'a':
				act = arADD;
				add = 1;
				replace = 0;
				break;
			  case 'x':
				act |= arEXTRACT;
				break;
			  case 'd':
				act |= arDELETE;
				delete = 1;
				break;
			  case 'v':
				verbose = 1;
				break;
			  case 'c':
				act = arCHECK;
				add = 0;
				replace = 0;
				break;
			  case 'S':
				shrink = 1;
				break;
			  case 'l':
				libnum = atol(&argv[i][j+1]);
				if(libnum < 0 || libnum > 4095)
					err = 1;
				break;
			  case 't':
				libtype = atol(&argv[i][j+1]);
				if(libtype < 0 || libtype >= MAXLIBTYPE)
					err = 1;
				break;
			  case 'm':
				map = 1;
				break;
			  case 's':
				issymbol = 1;
				break;
			  case 'B':
				map_bitmaps = 1;
				break;
			  case 'C':
				chunk = 1;
				break;
			  case 'F':
				filemode = 1;
				dllmode = 0;
				break;
			  case 'D':
			  	dllmode = 1;
			  	filemode = 0;
			  	break;
			  case 'N':
				newname = 1;
				break;
			  case 'E':
				map_entries = 1;
				break;
			  case 'M':
				batfile = 1;
				break;
			  case '?':
				err = 1;
				break;
			  default:
				break;
			}
		  }/* END: switch */
trim:
		  /* Trim switch */
		  for(j = i; j < argc-trimsize; ++j)
			argv[j] = argv[j+trimsize];
		  argc -= trimsize;
		  --i;
		}/* END: if('-') */
	  }/* END: for(argc) (get switches) */
	  if(verbose) {
		cfprintf("cff archiver Version:%u Copyright 1993, 1995 Norman D. Culver\n",
				prgversion.a0);
	  }
	  if(err) Usage();

	  if(argc > 1)
		  err = get_nameparts(argv[1]);

	  /* Get the archive */
	  if(!err && (     (map|shrink|freshen|batfile)
					|| (act && argc > 2)
					|| (filemode && (act & (arDELETE|arEXTRACT)))
				 )
		)
	  {
	  int mode = F_RDWR;
	  int new = 0;

		if(act & (arADD|arREPLACE))
			mode |= F_CREAT;

		curbufs = cfcurbufs(); /* current size of localizer space */

#ifdef SKELETON
		oxlink_close_libs();
#endif
		if((archive = cfopen(basefile, mode, NULL)) != NULL)
		{
		  if(!(cfobtype(archive) & OB_XFILE))
		  {
#if 0
		    cfsetverylazy(archive);
#endif
			if(cfisnew(archive))
			{/* new file, set up version and serial numbers */
				setup_version(0, basefile);
				new = 1;
			}
			else
			{
				if(cffind(archive, "ArVer", 5, &arversion) < FOUND) 
				{/* old .cff file without archive property, enable it */
					setup_version(1, basefile);
					new = 1;
				}
			}
			if(cffind(archive, "ArVer", 5, &arversion) >= FOUND)
			{
			  if(arversion.a0 <= prgversion.a0)
			  {
				ipaths = cfsubopen(archive,"ipaths",F_RDWR|F_CREAT|F_SORTED,NULL);
				qipaths = cfsubopen(archive,"qipaths",F_RDWR|F_CREAT, NULL);
				origins = cfsubopen(archive,"origins",F_RDWR|F_CREAT|F_SORTED|F_BIGDIR, NULL);
				qorigins = cfsubopen(archive,"qorigins",F_RDWR|F_CREAT, NULL);
				msyms = cfsubopen(archive,"msyms",F_RDWR|F_CREAT|F_SORTED|F_HUGEDIR,NULL);
				fipaths = cfsubopen(archive,"fipaths",F_RDWR|F_CREAT|F_SORTED,NULL); 

				if(!ipaths) {
					cfprintf("cfar: can't open subdir `ipaths'\n");
					goto xt;
				}
				if(!qipaths) {
					cfprintf("cfar: can't open subdir `ipaths'\n");
					goto xt;
				}
				if(!origins) {
					cfprintf("cfar: can't open subdir `origins'\n");
					goto xt;
				}
				if(!qorigins) {
					cfprintf("cfar: can't open subdir `qorigins'\n");
					goto xt;
				}
				if(!msyms) {
					cfprintf("cfar: can't open subdir `msyms'\n");
					goto xt;
				}
				if(!fipaths) {
					cfprintf("cfar: can't open subdir `fipaths'\n");
					goto xt;
				}
#if 0
				cfsetverylazy(msyms);
				cfsetverylazy(ipaths);
				cfsetverylazy(qipaths);
				cfsetverylazy(origins);
				cfsetverylazy(qorigins);
				cfsetverylazy(fipaths);
#endif
				if(dllmode && argc >= 3 && (add || replace || delete))
				{
					libtype = 3;
					libnum = 0;
					for(i = 2; i < argc; ++i)
					{
						lose_backslashes(argv[i]);
						strlwr(argv[i]);
						cur_orgtype = cfpathtrn(argv[i], &cur_orgpath);
						proc_dllmode(argv[i]);
						free(cur_orgpath);
					}
				}
				else if(filemode)
				{/* PROCESS FILES STORED IN FILEMODE */

					if(act & (arEXTRACT|arDELETE))
					{
						if(act & arEXTRACT)
							out_entry();
						else
							del_entry();
					}
					else if(add || chunk || newname || replace)
					{
						subdir = open_middle(archive);
						for(i = 2; i < argc; ++i)
						{
							lose_backslashes(argv[i]);
							strlwr(argv[i]);
							cur_orgtype = cfpathtrn(argv[i], &cur_orgpath);
							proc_filemode(argv[i]);
							free(cur_orgpath);
						}
						if(subdir)
							cfclose(subdir);
					}
					else
					{
						cfprintf("cfar: incorrect filemode spec\n");
					}
				}
				else if((argc < 3) && (freshen|batfile) && (!new))
				{/* FRESHEN FILES IN ARCHIVE, OR PRINT BATCHFILE */
				void *scratch = make_scratch();

				  /* check for files to freshen, print batfile if requested */
				  scan_archive(basefile, scratch);			
				  act = arUPDATE;
				  replace = 1;

				  /* files to freshen will be on the stack */
				  while(cfstackdepth(scratch) > 0)
				  {
				  long filelen;
					cfpop_value(scratch, &libnum);
					cfpop_value(scratch, &libtype);
					cfpop_value(scratch, &filelen);
					cur_orgpath = malloc(filelen);
					cfpop_data(scratch, cur_orgpath, filelen);

					if(libtype == -3)
					{/* freshen a dllmode file */
						libtype = 3;
						libnum = 0;
						proc_dllmode(cur_orgpath);
					}
					else if(libtype < 0)
					{/* Freshen a filemode file */
					long namlen, x;
					char *cur_name;
						cfpop_value(scratch, &namlen);
						cur_name = calloc(1, namlen+strlen(basefile)+2);
						x = _strcpy(cur_name, basefile);
						cfpop_data(scratch, &cur_name[x], namlen);
						chunk = (libnum == 1) ? 1 : 0;
						newname = (libtype == -2) ? 1 : 0;
						if(!newname) cur_name[x] = 0;

						get_nameparts(cur_name);
						subdir = open_middle(archive);

						proc_filemode(cur_orgpath);
						if(subdir)
							cfclose(subdir);
						free(cur_name);
					}
					else if(open_curlib())
					{/* Freshen an object file */
						proc_objfile(cur_orgpath);
					}
					free(cur_orgpath);
				  }/* END: freshen files on stack */
				  cfclose(scratch);
				}
				else if(argc > 2)
				{/* PROCESS OBJECT FILES STORED WITH SYMBOL TABLES */
				  if(open_curlib())
				  {/* Process the input files */
					  for(i = 2; i < argc; ++i)
					  {
						if(!issymbol)
						{
						  lose_backslashes(argv[i]);
						  strlwr(argv[i]);
						}
						cur_orgtype = cfpathtrn(argv[i], &cur_orgpath);
						proc_objfile(argv[i]);
						free(cur_orgpath);
					  }		
					}
				}
				cfclose(lib);
				cfclose(plib);
				cfclose(msyms);
				cfclose(ipaths);
				cfclose(qipaths);
				cfclose(origins);
				cfclose(qorigins);
				cfclose(fipaths);
				cfclose(archive);

				if(shrink) shrink_archive(basefile);
				if(map) print_map(basefile);

				cfmodbufs(curbufs-cfcurbufs()); /* reset localizer space */

			  } else cfprintf("cfar: a version %u archive cannot be processed by a version %u program\n", arversion.a0, prgversion.a0);
			} else cfprintf("cfar: %s is not an archive\n", basefile);
		  } else cfprintf("cfar: %s is not a cff database\n", basefile);
		} else cfprintf("cfar: can't open archive %s\n", basefile);
	  } else {cfprintf("cfar: insufficient args\n"); Usage();}
#ifndef SKELETON
	} else cfprintf("cfar: cannot find executable %s\n", argv[0]);
xt:
	cfexit();
	return 0;
#else
xt:
	return 0;
#endif
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -