Теоретические исследования

ОТЧЕТ

По лабораторной работе № 4

«Система контроля версий»

по дисциплине «Методы программирования»

Выполнили

студент гр. xxxxx/x И.И. Иванов

<подпись>

студент гр. xxxxx/x А.А. Александров

<подпись>

Проверил

В.Б. Вагисаров

<подпись>

Санкт-Петербург

Формулировка задания

Необходимо реализовать простой вариант системы контроля версий для текстовых файлов.

Программа с помощью меню реализует следующие команды:

Базовые:

- open <fname> <version> - открываем файл в версии <version>. Если версия не задана - открываем корневую версию (ее номер по умолчанию равен 0)

- print - отображает на экран текущую версию файла, с которым работаем.

Ф-ии редактирования:

- edit <i> <j> <data> - замена в текущей версии файла данных с индексом i (включительно) по индекс j (не включительно) на символы data

- add <i> <data> - добавление к текущей версии файла данных, начиная с позиции с индексом i

- remove <i> <j> - удаляем данные

Ф-ии работы с версиями:

- push - сохраняем текущую версию в виде разностного образа с предыдущей версией (не с корневой!). Функция возвращает номер версии, по которому можно впоследствии откатиться к этой версии.

- pull <№ версии> - делает текущей версию с переданным номером (т.е. перемещается по дереву версий, получая текущую версию из разностной информации на пути). Дальнейшее редактирование запоминается как изменения(разность) относительно этой (текущей) версией.

- delete_version <<№ версии> - удаляет версию из дерева. При этом корректируются наследники этой версии в дереве - разность теперь высчитывается относительно нового корня(предка удаленной вершины)

- rebase - перебалансирует дерево, помещая текущую версию в корень дерева путем перерассчета разностей версий относительно нового корня. Все номера версий остаются прежними, кроме 2х версий - текущей и бывшей корневой. Их номера меняются местами (т.е. текущая версия становится корнем дерева с номером 0, прежний корень забирает себе бывший номер этой версии)

теоретические исследования

Система управления версиями— программное обеспечение для облегчения работы с изменяющейся информацией. Система управления версиями позволяет хранить несколько версий одного и того же документа, при необходимости возвращаться к более ранним версиям, определять, кто и когда сделал то или иное изменение.

Система управления версиями обеспечивает хранение всех существовавших вариантов файлов и, как следствие, всех вариантов проекта в целом, имевших место с момента начала его разработки. Но само понятие «версии» в разных системах может трактоваться двумя различными способами.

Одни системы поддерживают версионность файлов. Это означает, что любой файл, появляющийся в проекте, получает собственный номер версии (обычно — номер 1, условной «нулевой» версией файла считается пустой файл с тем же именем). При каждой фиксации разработчиком изменений, затрагивающих файл, соответствующая часть фиксируемых изменений применяется к файлу и файл получает новый, обычно следующий по порядку, номер версии.

Для других систем понятие «версия» относится не к отдельному файлу, а к репозиторию целиком. Вновь созданный пустой репозиторий имеет версию 1 или 0, любая фиксация изменений приводит к увеличению этого номера (то есть даже при изменении одного файла на один байт весь репозиторий считается изменённым и получает новый номер версии).

Rebase — перенос точки ветвления (версии, от которой начинается ветвь) на более позднюю версию основной ветви. Например, после выпуска версии 1.0 проекта в стволе продолжается доработка (исправление ошибок, доработка имеющегося функционала), одновременно начинается работа над новой функциональностью в новой ветви. Через какое-то время в основной ветви происходит выпуск версии 1.1 (с исправлениями); теперь желательно, чтобы ветвь разработки новой функциональности включала изменения, произошедшие в стволе. Система самостоятельно определяет нужные наборы изменений и производит их слияние, после чего для ветви базовой версией становится версия 1.1; при последующем слиянии ветви со стволом система не рассматривает повторно изменения, внесённые между версиями 1.0 и 1.1, так как ветвь логически считается выделенной после версии 1.1.

Дельта-кодирование— способ представления данных в виде разницы (дельты) между последовательными данными вместо самих данных.Пожалуй, наиболее простой пример заключается в сохранении значений байтов как различия (дельты) между последовательными значениями, в отличие от самих значений. Поэтому вместо 2, 4, 6, 9, 7, мы будем сохранять 2, 2, 2, 3, −2.

Вариация дельта-кодирования, которая кодирует различия между префиксами или суффиксами строк, называется инкрементным кодированием. Оно в частности эффективно для отсортированных списков с малыми различиями между строками, такими, например, как список слов из словаря.

Результаты работы

Рис.1. – Главное меню и приветствие.

Рис.2. – команды открытия файлов и перехода к нужной версии.

Рис.3. – Открытие различных версий.

Рис.4. – Функция rebase, которая меняет текущую версию с корневой местами и пересчитывает дельта-файлы для всех версий на своём пути.

Рис.5. – Команды add и remove, которые добавляют и удаляют информацию.

Рис.6. – Команда push, которая сохраняет текущие изменения в новой версии путём подсчёта дельт, с предком.

ВЫВОды

Таким образом, в ходе выполнения лабораторной работы была разработана программа, представляющая собой простой вариант системы контроля версий для текстовых файлов. Реализованы базовые функции открытия и отображения текущей версии файла, функции редактирования (edit, add и remove), а также функции работы с версиями (push, pull, delete и rebase).

ПРИЛОЖЕНИЕ

#include <stdio.h>

#include <conio.h>

#include <string.h>

#include <locale>

#include <Windows.h>

#define M 100//Максимальная длина вводимой команды

void greeting(bool c)

{

if (c)

{

printf("Добро пожаловать в приложение, для работы с текстовыми файлами различных версий (расширение .txt) \n\n");

printf("Список доступных команд : \n");

printf("open \"<fname>\" <version> - открывает файл <fname> (без расширения) в версии <version>, если версия не указана, открывает файл с версией \"0\";\n");

printf("print - отображает на экран текущую версию файла, с которым работаем;\n");

printf("edit <i> <j> <data> - замена в текущей версии файла данных с индексом i (включительно) по индекс j (не включительно) на символы data;\n");

printf("add <i> <data> - добавление к текущей версии файла данных, начиная с позиции с индексом i;\n");

printf("push - сохраняет текущую версию в виде разностного образа с предыдущей версией;\n");

printf("pull <№ версии> - делает текущей версию с переданным номером;\n");

printf("delete_version <№ версии> - удаляет версию из дерева;\n");

printf("rebase - перебалансирует дерево, помещая текущую версию в корень дерева;\n");

printf("save \"<out-name>\" - сохраняет текущий вариант в указанный файл (без расширения);\n");

printf("remove <start_index> <end_index> - удаляет байты из текущей версии, начиная с индекса <start_index> включительно и заканчивая <end_index> не включительно.\n");

}

}

void delta_read(char(&buf)[100], char(&delta_str)[20])

{

char temp_str[100] = { '\0' };

strcpy_s(temp_str, buf);

if (delta_str[0] == '+')

{

int add_ind = 0, f = 2;

char ind[4] = { '\0' }, add_data[50] = { '\0' };

while ((int)delta_str[f] > 47 && (int)delta_str[f] < 58)

{

ind[strlen(ind)] = delta_str[f];

f++;

}

ind[strlen(ind)] = '\0';

add_ind = atoi(ind);

for (int ct = f + 1; ct < strlen(delta_str); ct++)

{

if (delta_str[ct] != '\n') add_data[strlen(add_data)] = delta_str[ct];

}

strncpy_s(temp_str, buf, add_ind);

temp_str[add_ind] = '\0';

strcat_s(temp_str, add_data);

int k = add_ind + strlen(add_data);

for (int ct = add_ind; ct < strlen(buf); ct++)

{

temp_str[k] = buf[ct];

k++;

}

temp_str[k] = '\0';

}

else if (delta_str[0] == '-')

{

int first_ind = 0, second_ind = 0, f = 2;

char ind_1[4] = { '\0' }, ind_2[4] = { '\0' };

while ((int)delta_str[f] > 47 && (int)delta_str[f] < 58)

{

ind_1[strlen(ind_1)] = delta_str[f];

f++;

}

ind_1[strlen(ind_1)] = '\0';

first_ind = atoi(ind_1);

f++;

while (f<strlen(delta_str) && delta_str[f] != '\n')

{

ind_2[strlen(ind_2)] = delta_str[f];

f++;

}

ind_2[strlen(ind_2)] = '\0';

second_ind = atoi(ind_2);

strncpy_s(temp_str, buf, first_ind);

int k = strlen(temp_str);

for (int ct = second_ind; ct < strlen(buf); ct++)

{

temp_str[k] = buf[ct];

k++;

}

temp_str[k] = '\0';

}

strcpy_s(buf, temp_str);

}

void numb_str(char(&numb)[4], int number)

{

int d = number / 10, e = number % 10;

if (d == 0)

{

char ce = e + 48;

numb[0] = ce;

numb[1] = '\0';

}

else

{

char ce = e + 48, cd = d + 48;

numb[0] = cd;

numb[1] = ce;

numb[2] = '\0';

}

}

bool correct_name(char(&str)[M], int &first_of_name, int &last_of_name)

{

int ct = 0, corr_symb = 0, ind_find = 0, have_name = 0;

char bad_symb[9] = { '/', '*', ':', '?', '"', '<', '>', '|', '\\' };

while (str[ind_find] != ' ') ind_find++;

for (int i = ind_find; i < strlen(str); i++)

if (str[i] == '"')

{

first_of_name = i + 1;

break;

}

for (int i = first_of_name; i < strlen(str); i++)

if (str[i] == '"')

{

last_of_name = i - 1;

break;

}

if (last_of_name != 0 && first_of_name != 0 && first_of_name <= last_of_name)

{

for (int i = 0; i < 9; i++)

for (int ii = first_of_name; ii < last_of_name + 1; ii++)

if (str[ii] == bad_symb[i])

{

corr_symb++;

break;

}

have_name++;

}

if (have_name == 0) printf("Отсутствует имя файла\n");

else if (corr_symb != 0) printf("Присутствуют некорректные символы /,*,\\,:,?,\",<,>,|\n");

else return(1);

return(0);

}

void new_vers(char(&newname)[M + 7], int ver_numb, char(&name)[M], bool mod)//создание имени версии

{

strcpy_s(newname, name);

if (ver_numb > 0)

{

char numb[4];

strcat_s(newname, "_");

numb_str(numb, ver_numb);

strcat_s(newname, numb);

}

if (mod == 0) strcat_s(newname, ".txt");

else strcat_s(newname, ".temp");

}

void get_vers(char(&buf_v)[100], int ver_numb, char(&name)[M])

{

FILE *forget = NULL;

char newname[M + 7] = { '\0' };

new_vers(newname, ver_numb, name, 0);

fopen_s(&forget, newname, "r");

char numb[4];

fgets(numb, 4, forget);

int old_numb = atoi(numb);

if (old_numb > 0)

{

get_vers(buf_v, old_numb, name);

}

char delta_str[20] = { '\0' };

while (fgets(delta_str, 20, forget) != NULL)

{

delta_read(buf_v, delta_str);

if (delta_str[0] != '-' && delta_str[0] != '+')

{

fclose(forget);

return;

}

}

fclose(forget);

}

bool open_f(char(&name)[M], char(&tempname)[M + 7], FILE **inf, int &n_vers, int &amount_of_vers, int last_of_name, char(&buf)[100], char(&str)[M])

{

FILE *foropen = NULL, *fvers = NULL, *ftemp = NULL;

char fversname[M + 7] = { '\0' };

char c;

int ct = 0;

int f = last_of_name + 2;

char version[5] = { '\0' };

while (str[f] == ' ') f++;

while ((int)str[f] > 47 && (int)str[f] < 58 && strlen(version)<4)

{

version[strlen(version)] = str[f];

f++;

}

n_vers = atoi(version);

if (n_vers == -1) n_vers = 0;

char newname[M + 7] = { '\0' };

new_vers(newname, n_vers, name, 0);

fopen_s(&foropen, newname, "r");

if (foropen == NULL)

{

n_vers = -1;

printf("Файл с этой версией не существует.\n");

return(0);

}

else

{

FILE *core = NULL;

fclose(foropen);

char corename[M + 7] = { '\0' };

strcpy_s(fversname, name);

strcat_s(fversname, "_vers.txt");

fopen_s(&fvers, fversname, "r");

if (fvers == NULL)

{

fopen_s(&fvers, fversname, "a");

amount_of_vers = 0;

}

else

{

char vers_numb[4] = { '\0' };

fgets(vers_numb, 4, fvers);

amount_of_vers = atoi(vers_numb);

}

fclose(fvers);

fvers = NULL;

amount_of_vers++;

new_vers(tempname, amount_of_vers, name, 1);

fopen_s(&ftemp, tempname, "w");

char numb[4];

numb_str(numb, n_vers);

fprintf(ftemp, numb);

fprintf(ftemp, "\n");

fclose(ftemp);

new_vers(corename, 0, name, 0);

fopen_s(&core, corename, "r");

while ((c = fgetc(core)) != EOF)

{

buf[ct] = c;

ct++;

}

buf[ct] = '\0';

if (n_vers > 0)

get_vers(buf, n_vers, name);

*inf = foropen;

fclose(core);

return(1);

}

fclose(foropen);

return(0);

}

bool pull_f(char(&core_name)[M], char(&tempname)[M + 7], FILE **inf, int &n_vers, int &amount_of_vers, char(&buf)[100], char(&str)[M])

{

remove(tempname);

char for_open[M] = "open \"";

n_vers = -1;

amount_of_vers = -1;

strcat_s(for_open, core_name);

for_open[6 + strlen(core_name)] = '\"';

for_open[7 + strlen(core_name)] = ' ';

int f = 4;

while (str[f] == ' ') f++;

int ct = 8 + strlen(core_name);

for (int i = f; i < strlen(str) + 1; i++)

{

for_open[ct] = str[i];

ct++;

}

*inf = NULL;

int last_of_name = 5 + strlen(core_name);

if (open_f(core_name, tempname, inf, n_vers, amount_of_vers, last_of_name, buf, for_open)) return(1);

else return(0);

}

bool remove_f(char(&core_name)[M], char(&tempname)[M + 7], int &n_vers, char(&buf)[100], char(&str)[M], int amount_of_vers)

{

FILE *ftemp = NULL;

int first_ind = 0, second_ind = 0, f = 6;

while (str[f] == ' ') f++;

char ind_1[4] = { '\0' }, ind_2[4] = { '\0' };

char temp_str[100] = { '\0' }, delta_str[100] = { '\0' };

while ((int)str[f] > 47 && (int)str[f] < 58)

{

ind_1[strlen(ind_1)] = str[f];

f++;

}

ind_1[strlen(ind_1)] = '\0';

first_ind = atoi(ind_1);

f++;

while ((int)str[f] > 47 && (int)str[f] < 58)

{

ind_2[strlen(ind_2)] = str[f];

f++;

}

ind_2[strlen(ind_2)] = '\0';

second_ind = atoi(ind_2);

if (strlen(ind_1) == 0 || strlen(ind_2) == 0)

{

printf("Неверные индексы.\n");

return(0);

}

if (second_ind <= strlen(buf) && first_ind > -1 && first_ind <= second_ind)

{

strncpy_s(temp_str, buf, first_ind);

int k = strlen(temp_str);

for (int ct = second_ind; ct < strlen(buf); ct++)

{

temp_str[k] = buf[ct];

k++;

}

temp_str[k] = '\0';

strcpy_s(buf, temp_str);

delta_str[0] = '-'; delta_str[1] = ' ';

strcat_s(delta_str, ind_1);

delta_str[2 + strlen(ind_1)] = ' ';

delta_str[3 + strlen(ind_1)] = '\0';

strcat_s(delta_str, ind_2);

fopen_s(&ftemp, tempname, "a");

fprintf(ftemp, delta_str);

fprintf(ftemp, "\n");

fclose(ftemp);

return(1);

}

else printf("Неверные индексы.\n");

return(0);

}

bool add_f(char(&core_name)[M], char(&tempname)[M + 7], int &n_vers, char(&buf)[100], char(&str)[M], int amount_of_vers)

{

FILE *ftemp = NULL;

int add_ind = 0, f = 3;

char temp_str[100] = { '\0' }, delta_str[100] = { '\0' };

char ind[4] = { '\0' }, add_data[50] = { '\0' };

while (str[f] == ' ') f++;

while ((int)str[f] > 47 && (int)str[f] < 58 && strlen(ind)<3)

{

ind[strlen(ind)] = str[f];

f++;

}

ind[strlen(ind)] = '\0';

add_ind = atoi(ind);

if (strlen(ind) == 0)

{

printf("Неверный индекс.\n");

return(0);

}

if (add_ind < strlen(buf) && add_ind>-1)

{

while (str[f] == ' ') f++;

for (int ct = f; ct < strlen(str); ct++)

{

if (str[ct] != '\n') add_data[strlen(add_data)] = str[ct];

}

strncpy_s(temp_str, buf, add_ind);

temp_str[add_ind] = '\0';

strcat_s(temp_str, add_data);

int k = add_ind + strlen(add_data);

for (int ct = add_ind; ct < strlen(buf); ct++)

{

temp_str[k] = buf[ct];

k++;

}

temp_str[k] = '\0';

strcpy_s(buf, temp_str);

delta_str[0] = '+'; delta_str[1] = ' ';

strcat_s(delta_str, ind);

delta_str[2 + strlen(ind)] = ' ';

delta_str[3 + strlen(ind)] = '\0';

strcat_s(delta_str, add_data);

fopen_s(&ftemp, tempname, "a");

fprintf(ftemp, delta_str);

fprintf(ftemp, "\n");

fclose(ftemp);

return(1);

}

else printf("Неверный индекс.\n");

return(0);

}

bool edit_f(char(&core_name)[M], char(&tempname)[M + 7], int &n_vers, char(&buf)[100], char(&str)[M], int amount_of_vers)

{

int f = 4;

while (str[f] == ' ') f++;

int first_ind = f;

while ((int)str[f] > 47 && (int)str[f] < 58) f++;

while (str[f] == ' ') f++;

int second_ind = f;

while ((int)str[f] > 47 && (int)str[f] < 58) f++;

while (str[f] == ' ') f++;

int data_ind = f;

int ct = 7;

char for_rem[100] = "remove ";

for (int i = first_ind; i < data_ind; i++)

{

for_rem[ct] = str[i];

ct++;

}

if (!remove_f(core_name, tempname, n_vers, buf, for_rem, amount_of_vers)) return(0);

ct = 4;

char for_add[100] = "add ";

for (int i = first_ind; i < second_ind; i++)

{

for_add[ct] = str[i];

ct++;

}

for (int i = data_ind; i < strlen(str); i++)

{

for_add[ct] = str[i];

ct++;

}

if (!add_f(core_name, tempname, n_vers, buf, for_add, amount_of_vers)) return(0);

return(1);

}

void push_f(char(&core_name)[M], char(&tempname)[M + 7], FILE **inf, int &n_vers, int &amount_of_vers, char(&buf)[100], char(&str)[M])

{

char new_version[M + 7] = { '\0' };

new_vers(new_version, amount_of_vers, core_name, 0);

CopyFile(tempname, new_version, false);

remove(tempname);

FILE *fvers = NULL;

char fversname[M + 7] = { '\0' };

strcpy_s(fversname, core_name);

strcat_s(fversname, "_vers.txt");

fopen_s(&fvers, fversname, "w");

char numb[4];

numb_str(numb, amount_of_vers);

fprintf(fvers, numb);

fclose(fvers);

*inf = NULL;

n_vers = -1;

printf("Номер версии: %i.\n", amount_of_vers);

amount_of_vers = -1;

}

bool delete_f(char(&core_name)[M], int amount_of_vers, char(&str)[M], int n_vers)

{

FILE *fdel = NULL;

int f = 15, del_vers = 0;

char ind[4] = { '\0' };

char del_name[M + 7] = { '\0' };

while (str[f] == ' ') f++;

while ((int)str[f] > 47 && (int)str[f] < 58)

{

ind[strlen(ind)] = str[f];

f++;

}

ind[strlen(ind)] = '\0';

del_vers = atoi(ind);

if (del_vers == n_vers)

{

printf("Невозможно удалить версию, когда она открыта.\n");

return(0);

}

if (strlen(ind) == 0)

{

printf("Неверный индекс.\n");

return(0);

}

new_vers(del_name, del_vers, core_name, 0);

fopen_s(&fdel, del_name, "r");

if (fdel == NULL)

{

printf("Файла с такой версией не существует.\n");

return(0);

}

int ct = 0;

for (int i = 1; i < amount_of_vers; i++)

{

char check_name[M + 7] = { '\0' };

char parent[4] = { '\0' };

int par = 0;

new_vers(check_name, i, core_name, 0);

FILE *fcheck = NULL, *ftemp = NULL;

fopen_s(&fcheck, check_name, "r");

if (fcheck != NULL)

{

fgets(parent, 4, fcheck);

par = atoi(parent);

if (par == del_vers)

{

char temp_name[M + 7] = { '\0' };

new_vers(temp_name, i, core_name, 1);

CopyFile(del_name, temp_name, false);

fopen_s(&ftemp, temp_name, "a");

char delta_str[20] = { '\0' };

while (fgets(delta_str, 20, fcheck) != NULL)

{

fprintf(ftemp, delta_str);

}

fclose(ftemp);

fclose(fcheck);

CopyFile(temp_name, check_name, false);

remove(temp_name);

continue;

}

}

fclose(fcheck);

fcheck = NULL;

}

fclose(fdel);

remove(del_name);

return(1);

}

void rebase_f(char(&core_name)[M], char(&tempname)[M + 7], int amount_of_vers, char(&str)[M], int &n_vers)

{

char buf[100];

char vers_line[20] = { '\0' };

int ct = 0;

while (n_vers >= 0)

{

FILE *ftemp = NULL, *fdelta = NULL;

char temp_name[M + 7] = { '\0' };

char delta_name[M + 7] = { '\0' };

new_vers(temp_name, n_vers, core_name, 1);

new_vers(delta_name, n_vers, core_name, 0);

fopen_s(&ftemp, temp_name, "w");

fopen_s(&fdelta, delta_name, "r");

if (ct == 0)

{

FILE *fakeinf = NULL;

char numb[4], fakestr[M] = "pull ";

char fake_tempname[M + 7];

numb_str(numb, n_vers);

strcat_s(fakestr, numb);

int fake1 = 0, fake2 = 0;

vers_line[ct] = n_vers;

ct++;

pull_f(core_name, fake_tempname, &fakeinf, fake1, fake2, buf, fakestr);

}

if (n_vers > 0)

{

char numb[4] = { '\0' };

fgets(numb, 4, fdelta);

int number = atoi(numb);

vers_line[ct] = (char)number;

ct++;

n_vers = number;

}

else

{

fprintf(ftemp, buf);

fgets(buf, M, fdelta);

n_vers = -1;

}

fclose(ftemp);

fclose(fdelta);

}

int i = 0;

while (ct - 2 * i - 2 > 0)

{

int first_delta = (int)vers_line[i];

int second_delta = (int)vers_line[ct - i - 2];

FILE *ftemp = NULL, *fdelta = NULL;

char temp_name[M + 7] = { '\0' };

char delta_name[M + 7] = { '\0' };

new_vers(temp_name, first_delta, core_name, 1);

new_vers(delta_name, second_delta, core_name, 0);

fopen_s(&ftemp, temp_name, "w");

fopen_s(&fdelta, delta_name, "r");

char delta[20] = { '\0' };

int first_parent = (int)vers_line[i + 1];

int second_parent = (int)vers_line[ct - i - 1];

fgets(delta, 20, fdelta);

char numb[4];

numb_str(numb, first_parent);

fprintf(ftemp, numb);

fprintf(ftemp, "\n");

int amount_of_str = 0;

rewind(fdelta);

while (fgets(delta, 20, fdelta) != NULL) amount_of_str++;

while (amount_of_str > 1)

{

rewind(fdelta);

FILE *fakeinf = NULL;

char fakestr[M] = "pull ";

char fake_tempname3[M + 7];

numb_str(numb, second_parent);

strcat_s(fakestr, numb);

int fake1 = 0, fake2 = 0;

pull_f(core_name, fake_tempname3, &fakeinf, fake1, fake2, buf, fakestr);

for (int str_i = 0; str_i < amount_of_str-1; str_i++)

{

fgets(delta, 20, fdelta);

delta_read(buf, delta);

}

fgets(delta, 20, fdelta);

char reversed_delta[20] = { '\0' };

if (delta[0] == '+')

{

reversed_delta[0] = '-';

reversed_delta[1] = ' ';

int add_ind = 0, f = 2;

char ind[4] = { '\0' }, add_data[50] = { '\0' };

while ((int)delta[f] > 47 && (int)delta[f] < 58)

{

ind[strlen(ind)] = delta[f];

reversed_delta[f] = delta[f];

f++;

}

ind[strlen(ind)] = '\0';

reversed_delta[f] = ' ';

add_ind = atoi(ind);

for (int count = f + 1; count < strlen(delta); count++)

{

if (delta[count] != '\n') add_data[strlen(add_data)] = delta[count];

}

add_ind += strlen(add_data);

numb_str(numb, add_ind);

strcat_s(reversed_delta, numb);

fprintf(ftemp, reversed_delta);

fprintf(ftemp, "\n");

}

else if (delta[0] == '-')

{

reversed_delta[0] = '+';

reversed_delta[1] = ' ';

int first_ind = 0, second_ind = 0, f = 2;

char ind_1[4] = { '\0' }, ind_2[4] = { '\0' };

while ((int)delta[f] > 47 && (int)delta[f] < 58)

{

ind_1[strlen(ind_1)] = delta[f];

f++;

}

ind_1[strlen(ind_1)] = '\0';

first_ind = atoi(ind_1);

f++;

while (f < strlen(delta) && delta[f] != '\n')

{

ind_2[strlen(ind_2)] = delta[f];

f++;

}

ind_2[strlen(ind_2)] = '\0';

second_ind = atoi(ind_2);

numb_str(numb, first_ind);

strcat_s(reversed_delta, numb);

reversed_delta[2 + strlen(numb)] = ' ';

int scht = 3 + strlen(numb);

for (int w = first_ind; w < second_ind; w++)

{

reversed_delta[scht] = buf[w];

scht++;

}

reversed_delta[scht] = '\0';

fprintf(ftemp, reversed_delta);

fprintf(ftemp, "\n");

}

amount_of_str--;

}

fclose(ftemp);

fclose(fdelta);

new_vers(temp_name, second_delta, core_name, 1);

new_vers(delta_name, first_delta, core_name, 0);

fopen_s(&ftemp, temp_name, "w");

fopen_s(&fdelta, delta_name, "r");

fgets(delta, 20, fdelta);

numb_str(numb, second_parent);

fprintf(ftemp, numb);

fprintf(ftemp, "\n");

amount_of_str = 0;

rewind(fdelta);

while (fgets(delta, 20, fdelta) != NULL) amount_of_str++;

while (amount_of_str > 1)

{

rewind(fdelta);

FILE *fakeinf = NULL;

char fakestr[M] = "pull ";

char fake_tempname3[M + 7];

numb_str(numb, second_parent);

strcat_s(fakestr, numb);

int fake1 = 0, fake2 = 0;

pull_f(core_name, fake_tempname3, &fakeinf, fake1, fake2, buf, fakestr);

for (int str_i = 0; str_i < amount_of_str - 1; str_i++)

{

fgets(delta, 20, fdelta);

delta_read(buf, delta);

}

fgets(delta, 20, fdelta);

char reversed_delta[20] = { '\0' };

if (delta[0] == '+')

{

reversed_delta[0] = '-';

reversed_delta[1] = ' ';

int add_ind = 0, f = 2;

char ind[4] = { '\0' }, add_data[50] = { '\0' };

while ((int)delta[f] > 47 && (int)delta[f] < 58)

{

ind[strlen(ind)] = delta[f];

reversed_delta[f] = delta[f];

f++;

}

ind[strlen(ind)] = '\0';

reversed_delta[f] = ' ';

add_ind = atoi(ind);

for (int count = f + 1; count < strlen(delta); count++)

{

if (delta[count] != '\n') add_data[strlen(add_data)] = delta[count];

}

add_ind += strlen(add_data);

numb_str(numb, add_ind);

strcat_s(reversed_delta, numb);

fprintf(ftemp, reversed_delta);

fprintf(ftemp, "\n");

}

else if (delta[0] == '-')

{

FILE *fakeinf = NULL;

char fakestr[M] = "pull ";

char fake_tempname2[M + 7];

numb_str(numb, first_parent);

strcat_s(fakestr, numb);

int fake1 = 0, fake2 = 0;

pull_f(core_name, fake_tempname2, &fakeinf, fake1, fake2, buf, fakestr);

memset(fake_tempname2, 0, sizeof(fake_tempname2));

reversed_delta[0] = '+';

reversed_delta[1] = ' ';

int first_ind = 0, second_ind = 0, f = 2;

char ind_1[4] = { '\0' }, ind_2[4] = { '\0' };

while ((int)delta[f] > 47 && (int)delta[f] < 58)

{

ind_1[strlen(ind_1)] = delta[f];

f++;

}

ind_1[strlen(ind_1)] = '\0';

first_ind = atoi(ind_1);

f++;

while (f < strlen(delta) && delta[f] != '\n')

{

ind_2[strlen(ind_2)] = delta[f];

f++;

}

ind_2[strlen(ind_2)] = '\0';

second_ind = atoi(ind_2);

numb_str(numb, first_ind);

strcat_s(reversed_delta, numb);

reversed_delta[2 + strlen(numb)] = ' ';

int scht = 3 + strlen(numb);

for (int w = first_ind; w < second_ind; w++)

{

reversed_delta[scht] = buf[w];

scht++;

}

reversed_delta[scht] = '\0';

fprintf(ftemp, reversed_delta);

fprintf(ftemp, "\n");

}

amount_of_str--;

}

fclose(ftemp);

fclose(fdelta);

i++;

}

if ((ct - i * 2 - 2) == 0)

{

FILE *ftemp = NULL, *fdelta = NULL;

char temp_name[M + 7] = { '\0' };

char delta_name[M + 7] = { '\0' };

int first_parent = (int)vers_line[i + 1];

int first_delta = (int)vers_line[i];

new_vers(temp_name, first_delta, core_name, 1);

new_vers(delta_name, first_delta, core_name, 0);

fopen_s(&ftemp, temp_name, "w");

fopen_s(&fdelta, delta_name, "r");

char delta[20] = { '\0' }, numb[4];

numb_str(numb, first_parent);

fprintf(ftemp, numb);

fprintf(ftemp, "\n");

int amount_of_str = 0;

rewind(fdelta);

while (fgets(delta, 20, fdelta) != NULL) amount_of_str++;

while (amount_of_str > 1)

{

rewind(fdelta);

FILE *fakeinf = NULL;

char fakestr[M] = "pull ";

char fake_tempname3[M + 7];

numb_str(numb, first_parent);

strcat_s(fakestr, numb);

int fake1 = 0, fake2 = 0;

pull_f(core_name, fake_tempname3, &fakeinf, fake1, fake2, buf, fakestr);

for (int str_i = 0; str_i < amount_of_str - 1; str_i++)

{

fgets(delta, 20, fdelta);

delta_read(buf, delta);

}

fgets(delta, 20, fdelta);

char reversed_delta[20] = { '\0' };

if (delta[0] == '+')

{

reversed_delta[0] = '-';

reversed_delta[1] = ' ';

int add_ind = 0, f = 2;

char ind[4] = { '\0' }, add_data[50] = { '\0' };

while ((int)delta[f] > 47 && (int)delta[f] < 58)

{

ind[strlen(ind)] = delta[f];

reversed_delta[f] = delta[f];

f++;

}

ind[strlen(ind)] = '\0';

reversed_delta[f] = ' ';

add_ind = atoi(ind);

for (int count = f + 1; count < strlen(delta); count++)

{

if (delta[count] != '\n') add_data[strlen(add_data)] = delta[count];

}

add_ind += strlen(add_data);

numb_str(numb, add_ind);

strcat_s(reversed_delta, numb);

fprintf(ftemp, reversed_delta);

fprintf(ftemp, "\n");

}

else if (delta[0] == '-')

{

FILE *fakeinf = NULL;

char fakestr[M] = "pull ";

char fake_tempname1[M + 7];

numb_str(numb, first_parent);

strcat_s(fakestr, numb);

int fake1 = 0, fake2 = 0;

pull_f(core_name, fake_tempname1, &fakeinf, fake1, fake2, buf, fakestr);

memset(fake_tempname1, 0, sizeof(fake_tempname1));

reversed_delta[0] = '+';

reversed_delta[1] = ' ';

int first_ind = 0, second_ind = 0, f = 2;

char ind_1[4] = { '\0' }, ind_2[4] = { '\0' };

while ((int)delta[f] > 47 && (int)delta[f] < 58)

{

ind_1[strlen(ind_1)] = delta[f];

f++;

}

ind_1[strlen(ind_1)] = '\0';

first_ind = atoi(ind_1);

f++;

while (f < strlen(delta) && delta[f] != '\n')

{

ind_2[strlen(ind_2)] = delta[f];

f++;

}

ind_2[strlen(ind_2)] = '\0';

second_ind = atoi(ind_2);

numb_str(numb, first_ind);

strcat_s(reversed_delta, numb);

reversed_delta[2 + strlen(numb)] = ' ';

int scht = 3 + strlen(numb);

for (int w = first_ind; w < second_ind; w++)

{

reversed_delta[scht] = buf[w];

scht++;

}

reversed_delta[scht] = '\0';

fprintf(ftemp, reversed_delta);

fprintf(ftemp, "\n");

}

amount_of_str--;

}

fclose(ftemp);

fclose(fdelta);

}

char temp_exch[M + 7], data_exch[M + 7];

new_vers(data_exch, 0, core_name, 0);

new_vers(temp_exch, 0, core_name, 1);

remove(data_exch);

CopyFile(temp_exch, data_exch, false);

remove(temp_exch);

int len = strlen(vers_line);

int j=0;

while (len - 2 * j > 1)

{

int for_temp_exch = (int)vers_line[j];

int for_data_exch = (int)vers_line[j];

char name_temp_exch[M + 7], name_data_exch[M + 7];

new_vers(name_data_exch, for_data_exch, core_name, 0);

new_vers(name_temp_exch, for_temp_exch, core_name, 1);

remove(name_data_exch);

CopyFile(name_temp_exch, name_data_exch, false);

remove(name_temp_exch);

for_temp_exch = (int)vers_line[len - j - 1];

for_data_exch = (int)vers_line[len - j - 1];

new_vers(name_data_exch, for_data_exch, core_name, 0);

new_vers(name_temp_exch, for_temp_exch, core_name, 1);

remove(name_data_exch);

CopyFile(name_temp_exch, name_data_exch, false);

remove(name_temp_exch);

j++;

}

if (len - 2 * j == 1)

{

int for_temp_exch = (int)vers_line[j];

int for_data_exch = (int)vers_line[len - j];

char name_temp_exch[M + 7], name_data_exch[M + 7];

new_vers(name_data_exch, for_data_exch, core_name, 0);

new_vers(name_temp_exch, for_temp_exch, core_name, 1);

remove(name_data_exch);

CopyFile(name_temp_exch, name_data_exch, false);

remove(name_temp_exch);

}

}

void main(void)

{

char tempname[M + 7] = { '\0' };

char core_name[M] = { '\0' };//Имя файла

char buf[100] = { '\0' };

FILE *inf = NULL;

int n_vers = -1, amount_of_vers = -1;

setlocale(LC_ALL, "Russian");

greeting(1);

char add[] = "add ",

ed[] = "edit ",

del[] = "delete_version ",

op[] = "open ",

ph[] = "push",

pl[] = "pull ",

rb[] = "rebase",

pr[] = "print",

sv[] = "save ",

rem[] = "remove ",

txt[] = ".txt";

while (1)

{

printf("\nВведите команду... \n");

char str[M];

gets_s(str);

if (strncmp(str, add, 4) != 0

&& strncmp(str, ed, 5) != 0

&& strncmp(str, del, 15) != 0

&& strncmp(str, pl, 5) != 0

&& strncmp(str, op, 5) != 0

&& strcmp(str, rb) != 0

&& strcmp(str, ph) != 0

&& strcmp(str, pr) != 0

&& strncmp(str, sv, 5) != 0

&& strncmp(str, rem, 7) != 0) printf("Недопустимая команда. Повторите ввод.\n");

else

{

if ((strncmp(str, op, 5) != 0) && inf == NULL) printf("Необходимо открыть файл для работы команды.\n");

else

{

if (strncmp(str, sv, 5) == 0 || strncmp(str, op, 5) == 0)

{

int first_of_name = 0, last_of_name = 0;

if (correct_name(str, first_of_name, last_of_name))

{

char name[M] = { '\0' };//Имя файла

for (int i = first_of_name; i < last_of_name + 1; i++)

name[strlen(name)] = str[i];

name[strlen(name)] = '\0';

if (strncmp(str, op, 5) == 0)

{

if (open_f(name, tempname, &inf, n_vers, amount_of_vers, last_of_name, buf, str))

{

printf("Файл ");

printf(name);

printf(" версии ");

printf("%i", n_vers);

printf(" открыт.\n");

strcpy_s(core_name, name);

}

}

else if (strncmp(str, sv, 5) == 0)

{

strcat_s(name, ".txt");

FILE *forsave = NULL;

fopen_s(&forsave, name, "w");

fprintf(forsave, buf);

fclose(forsave);

printf("Текущая версия сохранена в файл ");

printf(name);

printf(".\n");

}

}

}

else

{

if (strcmp(str, pr) == 0)

{

printf("Содержимое текущей версии: \n");

printf(buf);

printf("\n");

}

else if (strncmp(str, add, 4) == 0)

{

if (add_f(core_name, tempname, n_vers, buf, str, amount_of_vers)) printf("Информация добавлена.\n");

}

else if (strncmp(str, rem, 7) == 0)

{

if (remove_f(core_name, tempname, n_vers, buf, str, amount_of_vers)) printf("Информация удалена.\n");

}

else if (strncmp(str, ed, 5) == 0)

{

if (edit_f(core_name, tempname, n_vers, buf, str, amount_of_vers)) printf("Информация изменена.\n");

}

else if (strncmp(str, pl, 5) == 0)

{

if (pull_f(core_name, tempname, &inf, n_vers, amount_of_vers, buf, str)) printf("Версия открыта.\n");

}

else if (strcmp(str, ph) == 0)

{

push_f(core_name, tempname, &inf, n_vers, amount_of_vers, buf, str);

printf("Файл версии сохранён.\n");

}

else if (strncmp(str, del, 15) == 0)

{

if (delete_f(core_name, amount_of_vers, str, n_vers)) printf("Файл успешно удалён.\n");

}

else if (strcmp(str, rb) == 0)

{

rebase_f(core_name, tempname, amount_of_vers, str, n_vers);

printf("Перебалансировано.\n");

}

}

}

}

}

}

Наши рекомендации