Author Topic: Creating Parts of Source Code via Spreadsheets  (Read 571 times)

Offline Ishad Nha

  • Hero Member
  • *****
  • Posts: 945
Creating Parts of Source Code via Spreadsheets
« on: October 18, 2015, 04:12:35 AM »
Under certain circumstances, writing part of a program can be automated to a degree. The piece of code must follow a pattern, have a fair amount of repetition inside itself. For example, a Switch function with a large number of terms. Here we see elements that are common from one for clause to another and we also see elements that are not:

Code: [Select]
printf("\n,");
for (i = 912; i < 2152; i++) {
if (i % 16 == 0)
printf("%d,",i);
printf("%d,",buffer[i]);
if (i % 16 == 15)
printf("\n,");
if (i == 2151)
printf("\n,");
}

printf("\n,");
for (i = 2152; i < 4000; i++) {
if (i % 16 == 8)
printf("%d,",i);
printf("%d,",buffer[i]);
if (i % 16 == 7)
printf("\n,");
if (i == 3999)
printf("\n,");
}

(A whole lot of lines have been omitted for brevity's sake.)

printf("\n,");
for (i = 32466; i < 32983; i++) {
if (i % 16 == 2)
printf("%d,",i);
printf("%d,",buffer[i]);
if (i % 16 == 1)
printf("\n,");
if (i == 32982)
printf("\n,");
}

printf("\n,");
for (i = 32983; i < 33100; i++) {
if (i % 16 == 7)
printf("%d,",i);
printf("%d,",buffer[i]);
if (i % 16 == 6)
printf("\n,");
if (i == 33099)
printf("\n,");
}
   
The for function is a common element, ditto i % 16, but the absolute numbers contained in each clause are not, they are variable from one clause to another. 

Step 1: First, we create a specimen line of code.
If a variable number is surrounded on both sides by tab stops, when it is pasted into a spreadsheet it will be in a cell by itself. Hence all numbers of its class, that occur in the same place in the clause, will occur in the same column.
Numbers that vary must be created by a formula or must come from a known list of values. If numbers that vary are created by a formula, the Fill Down function can copy that formula into all the relevant cells. If numbers that vary come from a known list of values, this can be pasted right into the column concerned.
That is why all numbers of the same class must occur in the same column.

Tab stops are placed before and after every variable number. Below, "\t" represents an otherwise invisible tab stop.
All paragraph marks are replaced by at symbols, "@". This means the clause now occupies only one line of code, thus we have our specimen line of code:
Code: [Select]
printf("\n,");@for (i = \t912\t; i < \t2152\t; i++) {@if (i % 16 == \t0\t)@printf("%d,";i);@printf("%d,";buffer[i]);@if (i % 16 == \t15\t)@printf("\n,");@if (i == \t2151\t)@printf("\n,");@}@
Specimen line has eleven parts:
Code: [Select]
(1) printf("\n,");@for (i =
(2) 912
(3) ; i <
(4) 2152
(5) ; i++) {@if (i % 16 ==
(6) 0
(7) )@printf("%d,";i);@printf("%d,";buffer[i]);@if (i % 16 ==
(8) 15
(9) )@printf("\n,");@if (i ==
(10) 2151
(11) )@printf("\n,");@}@

It consists of text strings:
(1) printf("\n,");@for (i =
(3) ; i <
(5) ; i++) {@if (i % 16 ==
(7) )@printf("%d,";i);@printf("%d,";buffer[i]);@if (i % 16 ==
(9) )@printf("\n,");@if (i ==
(11) )@printf("\n,");@}@

and results of formulas:
(2) 912
(6) 0
(8) 15
(10) 2151

and a record from a data table:
(4) 2152.
Note: deleting of line returns/paragraph marks can be done by a hex editor if the clause is large. The specimen line of code is copied to a text file, which is saved. File is then opened in a hex editor. Use Replace All to replace all of the paragraph mark and tab pairs with an at sign, @.
In Windows hex terms 0D0A09h needs to be replaced by 40h.

Step 2: The specimen line of code is now copied into a spreadsheet.
This is shown in the graphic below:

Step 3: Now the the Fill Down function is used.
We have the required number of lines of code, all lines are identical.
Now all the variable parts are in columns by themselves.

Step 4: Use Fill Down to add in those variable numbers that are created by a formula.
If using a formula, once it is discovered, it will have to be written in to the top cell in the column then applied to other cells by Fill Down:
This involves parts (2), (6), (8) and (10).

Step 5: If using lists of values, copy them into the relevant columns.
Here this only involves part (4).

Step 6: Final Processing.
The code is then copied to a text file, which is saved. File is then opened in a hex editor.
All tab stops are deleted, in Windows they are all equal to 09h. Use Replace All to replace all of them with nothing, this has the effect of deleting all of them.
Now at symbols, @, need to be replaced by a paragraph mark and a tab. In Windows hex terms 40h needs to be replaced by 0D0A09h. This assumes that the paragraph mark equals 0D0Ah.

Notes:
This method is valid for any brand of source code.
It is only useful if you have large numbers of clauses or you might be altering the number of Bytes covered by each clause.
« Last Edit: October 18, 2015, 04:21:45 AM by Ishad Nha »

Offline Ishad Nha

  • Hero Member
  • *****
  • Posts: 945
Re: Creating Parts of Source Code via Spreadsheets
« Reply #1 on: October 22, 2015, 02:26:33 AM »
Using a program to print out the source code rather than a spreadsheet

I had trouble getting this approach to work. I wanted clauses like:
Code: [Select]
for (i = 912; i < 2152; i++) {
if (i % 16 == 0)
printf("\n%d,",i);
printf("%d,",buffer[i]);
if (i == 2151)
printf("\n\n,");
}
instead I got the likes of:
Code: [Select]
for (i = 912; i < 2152; i++) {
if (i  == 0)
printf("
4206821,",i);
printf("4206821,",buffer[i]);
if (i == 2151)
printf("
,");
}
So I decided to remove the troublesome bits from the code, presumably % and \n,the program generates clauses like:
Code: [Select]
for (i = 912; i < 2152; i++) {
if (i @ 16 == 0)
printf("/n@d,",i);
printf("@d,",buffer[i]);
if (i == 2151)
printf("/n/n,");
}
Then the code is copied into a text editor and I
(1) Use Replace All to change @ to %
(2) Use Replace All to change /n to \n

This generates the correct code when the program is run. Source code is shown below:
Code: [Select]
#include <stdio.h>
#include <stdlib.h>

int main(void) {

    unsigned int i;

char *var1[10] = {
"912","2152","4000","7768","12000","15600","17200","21354","28556","32983",
};
char *var2[10] = {
"2152","4000","7768","12000","15600","17200","21354","28556","32983","33100",
};
char *var3[10] = {
"0","8","0","8","0","0","0","10","12","7",
};
char *var4[10] = {
"2151","3999","7767","11999","15599","17199","21353","28555","32982","33099",
};

for (i = 0; i < 10; i++) {
printf("\nfor (i = %s; i < %s; i++) {",var1[i],var2[i]);
printf("\nif (i @ 16 == %s)",var3[i]);
printf("\nprintf(\"/n@d,\",i);");
printf("\nprintf(\"@d,\",buffer[i]);");
printf("\nif (i == %s)",var4[i]);
printf("\nprintf(\"/n/n,\");");
printf("\n}\n");
}

    return EXIT_SUCCESS;
}


char *var#[10] = {}, these terms if large could be generated by a program themselves.
« Last Edit: February 18, 2017, 12:58:55 AM by Ishad Nha »

Offline Ishad Nha

  • Hero Member
  • *****
  • Posts: 945
Re: Creating Parts of Source Code via Spreadsheets
« Reply #2 on: February 18, 2017, 01:00:34 AM »
This approach can be adapted to a program that reads from multiple files at once.
Worked example, I was trying to decrypt the save games for Dark Sun 1: Shattered Lands, with the intent of creating a Universal Game Editor module. I found this tough going as the format was different to anything I had seen before.
My best guess is to track the ability scores of PC#1, a Half Giant Ranger.
24,15,22,14,17,15

Attached file, main.cpp, is the source file for a program ("ProjectDS2.exe") that checks for this sequence.