Exemple #1
0
/**
 * @brief Applies a diff to the universe.
 *
 *    @param name Diff to apply.
 *    @return 0 on success.
 */
int diff_apply( const char *name )
{
   xmlNodePtr node;
   xmlDocPtr doc;
   size_t bufsize;
   char *buf;
   char *diffname;

   /* Check if already applied. */
   if (diff_isApplied(name))
      return 0;

   buf = ndata_read( DIFF_DATA_PATH, &bufsize );
   doc = xmlParseMemory( buf, bufsize );

   node = doc->xmlChildrenNode;
   if (strcmp((char*)node->name,"unidiffs")) {
      ERR(_("Malformed unidiff file: missing root element 'unidiffs'"));
      return 0;
   }

   node = node->xmlChildrenNode; /* first system node */
   if (node == NULL) {
      ERR(_("Malformed unidiff file: does not contain elements"));
      return 0;
   }

   do {
      if (xml_isNode(node,"unidiff")) {
         /* Check to see if it's the diff we're looking for. */
         xmlr_attr(node,"name",diffname);
         if (strcmp(diffname,name)==0) {
            /* Apply it. */
            diff_patch( node );

            /* Clean up. */
            free(diffname);
            xmlFreeDoc(doc);
            free(buf);

            economy_execQueued();

            return 0;
         }
         free(diffname);
      }
   } while (xml_nextNode(node));

   /* More clean up. */
   xmlFreeDoc(doc);
   free(buf);

   WARN(_("UniDiff '%s' not found in %s."), name, DIFF_DATA_PATH);
   return -1;
}
Exemple #2
0
static int do_merge(int argc, char *argv[], int obj,
		    int reverse, int replace, int ignore, int show_wiggles,
		    int quiet)
{
	/* merge three files, A B C, so changed between B and C get made to A
	 */
	struct stream f, flist[3];
	struct file fl[3];
	int i;
	int chunks1 = 0, chunks2 = 0, chunks3 = 0;
	char *replacename = NULL, *orignew = NULL;
	struct csl *csl1, *csl2;
	struct ci ci;
	FILE *outfile = stdout;

	switch (argc) {
	case 0:
		fprintf(stderr, "%s: no files given for --merge\n", Cmd);
		return 2;
	case 3:
	case 2:
	case 1:
		for (i = 0; i < argc; i++) {
			flist[i] = load_file(argv[i]);
			if (flist[i].body == NULL) {
				fprintf(stderr, "%s: cannot load file '%s' - %s\n",
					Cmd,
					argv[i], strerror(errno));
				return 2;
			}
		}
		break;
	default:
		fprintf(stderr, "%s: too many files given for --merge\n",
			Cmd);
		return 2;
	}
	switch (argc) {
	case 1: /* a merge file */
		f = flist[0];
		if (!split_merge(f, &flist[0], &flist[1], &flist[2])) {
			fprintf(stderr, "%s: merge file %s looks bad.\n",
				Cmd,
				argv[0]);
			return 2;
		}
		break;
	case 2: /* a file and a patch */
		f = flist[1];
		chunks2 = chunks3 = split_patch(f, &flist[1], &flist[2]);
		break;
	case 3: /* three separate files */
		break;
	}
	if (reverse) {
		f = flist[1];
		flist[1] = flist[2];
		flist[2] = f;
	}

	for (i = 0; i < 3; i++) {
		if (flist[i].body == NULL) {
			fprintf(stderr, "%s: file %d missing\n", Cmd, i);
			return 2;
		}
	}
	if (replace) {
		int fd;
		replacename = xmalloc(strlen(argv[0]) + 20);
		orignew = xmalloc(strlen(argv[0]) + 20);
		strcpy(replacename, argv[0]);
		strcpy(orignew, argv[0]);
		strcat(orignew, ".porig");
		if (open(orignew, O_RDONLY) >= 0 ||
		    errno != ENOENT) {
			fprintf(stderr, "%s: %s already exists\n",
				Cmd,
				orignew);
			return 2;
		}
		strcat(replacename, "XXXXXX");
		fd = mkstemp(replacename);
		if (fd == -1) {
			fprintf(stderr,
				"%s: could not create temporary file for %s\n",
				Cmd,
				replacename);
			return 2;
		}
		outfile = fdopen(fd, "w");
	}

	if (obj == 'l') {
		fl[0] = split_stream(flist[0], ByLine);
		fl[1] = split_stream(flist[1], ByLine);
		fl[2] = split_stream(flist[2], ByLine);
	} else {
		fl[0] = split_stream(flist[0], ByWord);
		fl[1] = split_stream(flist[1], ByWord);
		fl[2] = split_stream(flist[2], ByWord);
	}
	if (chunks2 && !chunks1)
		csl1 = pdiff(fl[0], fl[1], chunks2);
	else
		csl1 = diff(fl[0], fl[1]);
	csl2 = diff_patch(fl[1], fl[2]);

	ci = make_merger(fl[0], fl[1], fl[2], csl1, csl2,
			 obj == 'w', ignore, show_wiggles);
	print_merge(outfile, &fl[0], &fl[1], &fl[2],
		    obj == 'w', ci.merger);
	if (!quiet && ci.conflicts)
		fprintf(stderr,
			"%d unresolved conflict%s found\n",
			ci.conflicts,
			ci.conflicts == 1 ? "" : "s");
	if (!quiet && ci.ignored)
		fprintf(stderr,
			"%d already-applied change%s ignored\n",
			ci.ignored,
			ci.ignored == 1 ? "" : "s");

	if (replace) {
		fclose(outfile);
		if (rename(argv[0], orignew) == 0 &&
		    rename(replacename, argv[0]) == 0)
			/* all ok */;
		else {
			fprintf(stderr,
				"%s: failed to move new file into place.\n",
				Cmd);
			return 2;
		}
	}
	return (ci.conflicts > 0);
}
Exemple #3
0
static int do_diff(int argc, char *argv[], int obj, int ispatch,
		   int which, int reverse)
{
	/* create a diff (line or char) of two streams */
	struct stream f, flist[3];
	int chunks1 = 0, chunks2 = 0, chunks3 = 0;
	int exit_status = 0;
	struct file fl[2];
	struct csl *csl;

	switch (argc) {
	case 0:
		fprintf(stderr, "%s: no file given for --diff\n", Cmd);
		return 2;
	case 1:
		f = load_file(argv[0]);
		if (f.body == NULL) {
			fprintf(stderr,
				"%s: cannot load file '%s' - %s\n", Cmd,
				argv[0], strerror(errno));
			return 2;
		}
		chunks1 = chunks2 =
			split_patch(f, &flist[0], &flist[1]);
		if (!flist[0].body || !flist[1].body) {
			fprintf(stderr,
				"%s: couldn't parse patch %s\n", Cmd,
				argv[0]);
			return 2;
		}
		break;
	case 2:
		flist[0] = load_file(argv[0]);
		if (flist[0].body == NULL) {
			fprintf(stderr,
				"%s: cannot load file '%s' - %s\n", Cmd,
				argv[0], strerror(errno));
			return 2;
		}
		if (ispatch) {
			f = load_file(argv[1]);
			if (f.body == NULL) {
				fprintf(stderr,
					"%s: cannot load patch"
					" '%s' - %s\n", Cmd,
					argv[1], strerror(errno));
				return 2;
			}
			if (which == '2')
				chunks2 = chunks3 =
					split_patch(f, &flist[2],
						    &flist[1]);
			else
				chunks2 = chunks3 =
					split_patch(f, &flist[1],
						    &flist[2]);

		} else
			flist[1] = load_file(argv[1]);
		if (flist[1].body == NULL) {
			fprintf(stderr,
				"%s: cannot load file"
				" '%s' - %s\n", Cmd,
				argv[1], strerror(errno));
			return 2;
		}
		break;
	default:
		fprintf(stderr,
			"%s: too many files given for --diff\n", Cmd);
		return 2;
	}
	if (reverse) {
		f = flist[1];
		flist[1] = flist[2];
		flist[2] = f;
	}
	fl[0] = split_stream(flist[0], obj == 'l' ? ByLine : ByWord);
	fl[1] = split_stream(flist[1], obj == 'l' ? ByLine : ByWord);
	if (chunks2 && !chunks1)
		csl = pdiff(fl[0], fl[1], chunks2);
	else
		csl = diff_patch(fl[0], fl[1]);
	if (obj == 'l') {
		if (!chunks1)
			printf("@@ -1,%d +1,%d @@\n",
			       fl[0].elcnt, fl[1].elcnt);
		exit_status = do_diff_lines(fl, csl);
	} else {
		if (!chunks1) {
			/* count lines in each file */
			int l1, l2, i;
			l1 = l2 = 0;
			for (i = 0 ; i < fl[0].elcnt ; i++)
				if (ends_line(fl[0].list[i]))
					l1++;
			for (i = 0 ; i < fl[1].elcnt ; i++)
				if (ends_line(fl[1].list[i]))
					l2++;
			printf("@@ -1,%d +1,%d @@\n", l1, l2);
		}
		exit_status = do_diff_words(fl, csl);
	}
	return exit_status;
}