QLPatch

Authors

Publication

Pub Details

Date

Pages

See all articles from QL Hacker's Journal 7

One of the problems I’ve encountered in publishing souce code in the QHJ, is the dilemma of publishing a newer version of a program (or bug fixes). I could publish the whole program but this would waste bandwidth if only a small portion of the code has been changed.

Another way is to publish the changes to the program and figure a way to have the user edit his version, add the changes and create a newer (second) version.

In my dealings with the Unix world, I have heard of a program that does something like this, called Patch. In using Patch, the originator of the program runs the two version of the code through a file comparison utility (like Unix’s diff) and creates a diff (or delta) file. The end user takes the diff file, version 1 of the program, and runs it through Patch to create the second version. Patch uses the diff file as a guide to edit the source code.

To make this work on the QL, I first needed a file comparison program. A few issues ago, I published FCOMP_C from the C Users Group. With only a few changes to FCOMP_C I was able to get a program that would work for me. I now have FCOMP2_C.

Now that I could generate a diff file, I needed a version of Patch. Not having the source code to Patch, I decided to write my own version from scratch, based on the output of FCOMP2_C.

Below is the result of that effort, QLPatch. This version is only written in SuperBasic. I plan to port it to C, but I prefer to develop in SuperBasic because it’s easier than C.

After the source code, I have included an example of two versions of a file and the diff file for them. Take version 1 of the file, the diff file, and run them through QLPatch and see that you indeed get the second version.

After this is the diff file for FCOMP_C to create FCOMP2_C. Running this and FCOMP_C though QLPatch will give you a version of FCOMP_C to use with QLPatch.

If you encounter any bugs, please let me know. I do plan to use this program for the QHJ and I want it to work as advertised.

** QLPatch
** By Timothy Swenson
**
** This program takes version 1 of a file, a diff file
** created by fcomp_c, and creates version 2 of the
** file. This program can be used to distribute
** changes to a program with out having to redistribute
** all of the source code. You need only distribute those
** lines needed.
**
** This program can be used for any text file, be it a C
** program, Achive program, or a text document.
**

TRUE = 1
FALSE = 0
IN_FILE = 4
DIFF_FILE = 5
OUT_FILE = 6

last_insert = FALSE

INPUT "Enter Souce File : ";in_file$
INPUT "Enter Diff File : ";diff_file$
INPUT "Enter Output File : ";out_file$

DELETE out_file$

OPEN #IN_FILE,in_file$
OPEN #DIFF_FILE,diff_file$
OPEN_NEW #OUT_FILE,out_file$

in_file_count = 1

REPEAT big_loop

IF last_insert = FALSE THEN
INPUT #DIFF_FILE,in$
IF EOF(#DIFF_FILE) THEN EXIT big_loop
ELSE
last_insert = FALSE
ENDIF

IF LEN(in$) < 13 THEN END REPEAT big_loop
IF in$(1 TO 13) = "Deleted line " THEN del_line
IF in$(1 to 13) = "Deleted lines" THEN del_lines
IF in$(1 to 13) = "Changed line " THEN chang_line
IF in$(1 to 13) = "Changed lines" THEN chang_lines
IF LEN(in$) < 19 THEN END REPEAT big_loop
IF in$(1 to 19) = "Inserted after line" THEN insert

END REPEAT big_loop

** add rest of original file to new file
REPEAT loop
INPUT #IN_FILE,in_file$
IF EOF(#IN_FILE) THEN EXIT loop
PRINT #OUT_FILE,in_file$
END REPEAT loop

@END
PRINT #OUT_FILE
CLOSE #IN_FILE
CLOSE #DIFF_FILE
CLOSE #OUT_FILE

** Start of Functions

DEFine FuNction EOS(x$)
IF LEN(x$) < 3 THEN RETURN FALSE
IF x$(1 to 3) = "To:" THEN RETURN TRUE
IF LEN(x$) < 12 THEN RETURN FALSE
IF x$(1 to 12) = "Deleted line" THEN RETURN TRUE
IF x$(1 to 12) = "Changed line" THEN RETURN TRUE
IF LEN(x$) < 19 THEN RETURN FALSE
IF x$(1 to 19) = "Inserted after line" THEN RETURN TRUE
RETURN FALSE
END DEFine EOS

DEFine PROCedure del_line
LOCal z,x
x = in$(14 to)
FOR z = in_file_count TO x-1
INPUT #IN_FILE,in_file$
PRINT #OUT_FILE,in_file$
NEXT z
INPUT #IN_FILE,in_file$
in_file_count = x+1
END DEFine del_line

DEFine PROCedure del_lines
LOCal x,y,z,temp
temp = "-" INSTR in$
x = in$( 15 TO temp-1)
y = in$( temp+1 TO LEN(in$)-1)
FOR z = in_file_count TO x-1
INPUT #IN_FILE,in_file$
PRINT #OUT_FILE,in_file$
NEXT z
FOR z = x TO y
INPUT #IN_FILE,in_file$
NEXT z
in_file_count = y+1
END DEFine del_lines

DEFine PROCedure insert
LOCal x,y,loop
x = in$(21 TO)
FOR y = in_file_count to x
INPUT #IN_FILE,infile$
PRINT #OUT_FILE,infile$
NEXT y
in_file_count = x+1
REPEAT loop
INPUT #DIFF_FILE,in$
IF EOF(#DIFF_FILE) THEN GOTO @END
IF EOS(in$) THEN EXIT loop
IF LEN(in$) < 2 THEN
PRINT #OUT_FILE,in$
ELSE
PRINT #OUT_FILE,in$(2 TO)
ENDIF
END REPEAT loop
last_insert = TRUE
END DEFine insert

DEFine PROCedure chang_line
LOCal x,y
x = in$(14 TO)
FOR y = in_file_count TO x-1
INPUT #IN_FILE,infile$
PRINT #OUT_FILE,infile$
NEXT y
in_file_count = x+1
INPUT #IN_FILE,infile$
INPUT #DIFF_FILE,in$
INPUT #DIFF_FILE,in$
INPUT #DIFF_FILE,in$
PRINT #OUT_FILE,in$(2 TO)
END DEFine chang_line

DEFine PROCedure chang_lines
LOCal x,y,z,temp
temp = "-" INSTR in$
x = in$( 15 TO temp-1)
y = in$( temp+1 TO LEN(in$)-1)
FOR z = in_file_count TO x-1
INPUT #IN_FILE,infile$
PRINT #OUT_FILE,infile$
NEXT z
FOR z = x to y
INPUT #IN_FILE,in$
INPUT #DIFF_FILE,in$
NEXT z
INPUT #DIFF_FILE,in$
REPEAT loop
INPUT #DIFF_FILE,in$
IF EOF(#DIFF_FILE) THEN GOTO @END
IF EOS(IN$) THEN EXIT loop
IF LEN(in$) < 2 THEN
PRINT #OUT_FILE,in$
ELSE
PRINT #OUT_FILE,in$(2 TO)
END IF
END REPEAT loop
last_insert = TRUE
in_file_count = y+1
END DEFine chang_lines

Example files:

Version 1 File:
This is line 1
This is line 2
This is line 3
This is line 4
This is line 5
This is line 6
This is line 7
This is line 8
This is line 9
This is line 10
This is line 11
This is line 12
This is line 13
This is line 14
This is line 15
This is line 16
This is line 17
This is line 18

Version 2 File:
This is line 1
This is line 3
This is line 4
add a line here
This is line 5
This is line 6
add a line here
add a line here
This is line 7
This is a line 8
This is line 9
This is line 13
This is line 14
This is a line 15
This is a line 16
This is line 17
This is line 18
add a line here: 1
add a line here: 2
add a line here: 3

Diff File:
Deleted line 2
This is line 2
Inserted after line 4:
add a line here
Inserted after line 6:
add a line here
add a line here
Changed line 8
This is line 8
To:
This is a line 8
Deleted lines 10-12:
This is line 10
This is line 11
This is line 12
Changed lines 15-16:
This is line 15
This is line 16
To:
This is a line 15
This is a line 16
Inserted after line 18:
add a line here: 1
add a line here: 2
add a line here: 3

Diff File for FCOMP2_C:

  (some lines wrapped for printing,so be carefull when
re-typing.)

Inserted after line 0:

Inserted after line 13:
UPDATED: 11 Nov 91 by Timothy Swenson
Added changes so that output will be sent to a file.
Output file will be third file arguement.

Usage: CRUN "flp1_fcomp2 flp1_file_ver_1
flp1_file_ver_2 flp1_diff"
Deleted line 25

Deleted line 28

Changed line 54
#include <string.h>
To:
#include <string_h>
Inserted after line 69:
FILE *fd;
Changed lines 93-94:
if(argc != 3)
fatal("fcomp requires two file names.");
To:
if(argc != 4)
fatal("fcomp requires three file names.");
Inserted after line 95:
if (( fd = fopen(argv[3],"w")) == NULL ) {
fprintf(stderr,"Cannot open file %s.\n",argv[3]);
}

Changed line 107
puts("The files are identical.");
To:
fputs(fd,"The files are identical.");
fclose(fd);
Inserted after line 144:
fclose(fd);
Inserted after line 169:
fclose(fd);
Changed line 207
printf("Inserted after line %d:\n",ep->line1);
To:
fprintf(fd,"Inserted after line %d:\n",ep->line1);
Changed line 218
printf("\nChanged ");
To:
fprintf(fd,"Changed ");
Changed line 220
printf("\nDeleted ");
To:
fprintf(fd,"Deleted ");
Changed line 222
printf("line %d\n",ep->line1);
To:
fprintf(fd,"line %d\n",ep->line1);
Changed line 224
printf("lines %d-%d:\n",ep->line1,a->line1);
To:
fprintf(fd,"lines %d-%d:\n",ep->line1,a->line1);
Changed line 228
printf(" %s",A[ep->line1-1]);
To:
fprintf(fd," %s",A[ep->line1-1]);
Changed line 234
printf("To:\n");
To:
fprintf(fd,"To:\n");
Changed line 238
printf(" %s",B[ep->line2-1]);
To:
fprintf(fd," %s",B[ep->line2-1]);
Inserted after line 241:
fprintf(fd,"\n");
Inserted after line 247:
fclose(fd);
Inserted after line 254:
fclose(fd);

Products

 

Downloadable Media

 
Scroll to Top