-
Notifications
You must be signed in to change notification settings - Fork 0
/
instruct_dllist.c
310 lines (286 loc) · 14.5 KB
/
instruct_dllist.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
/**
* Projekt: IFJ2021
*
* @brief Implementace DLListu pro instrukce.
*
* @author Vít Janeček xjanec30@stud.fit.vutbr.cz
*
* @property Kostra je založena na základě IAL DU1
*/
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include "instruct_dllist.h"
void DLL_Instruct_Init( DLList_Instruct * listInstruct){
listInstruct->firstElement = NULL; //inicalizuje prvni, aktivni a posledni prvek na NULL
listInstruct->lastElement = NULL;
listInstruct->activeElement = NULL;
listInstruct->count = 0;
}
void DLL_Instruct_Dispose( DLList_Instruct * listInstruct){
while (listInstruct->firstElement != NULL){ //dokud prvni element neni NULL
DLLElementPtr_Instruct elemPtr;
elemPtr = listInstruct->firstElement; //pomocny ukazatel ukazuje na 1. prvek
free(elemPtr->instruction);
listInstruct->firstElement = listInstruct->firstElement->nextElement; //prvni se posune na dalsi
free(elemPtr); //smaze prvni prvek
}
DLL_Instruct_Init(listInstruct);
}
int DLL_Instruct_InsertFirst( DLList_Instruct *listInstruct, Dynamic_string *string){
DLLElementPtr_Instruct nElemPtr = (DLLElementPtr_Instruct)malloc(sizeof(struct DLLElement_Instruct)); //naalokuje prostor pro pridavany prvek
Dynamic_string *string2 = (Dynamic_string *)malloc(sizeof(Dynamic_string));
if (nElemPtr == NULL || string2 == NULL){
return ERROR_COMPILER; //kdyby nenaalokoval
}
nElemPtr->instruction = string2; //nahraje data
nElemPtr->instruction->str = string->str;
nElemPtr->nextElement = listInstruct->firstElement; //prenastavi ukazatele
nElemPtr->previousElement = NULL;
if(listInstruct->firstElement != NULL){
listInstruct->firstElement->previousElement = nElemPtr; //kdyz neni prvni prvek, prida novy prvek pred prvni prvek
}else{
listInstruct->lastElement = nElemPtr; //jinak ho prida jako posledni prvek
}
listInstruct->firstElement = nElemPtr; //nastavi novy prvek na prvni
(listInstruct->count)++;
return ERROR_PASSED;
}
int DLL_Instruct_InsertLast( DLList_Instruct *listInstruct, Dynamic_string *string){
DLLElementPtr_Instruct nElemPtr = (DLLElementPtr_Instruct)malloc(sizeof(struct DLLElement_Instruct)); //naalokuje prostor pro pridavany prvek
Dynamic_string *string2 = (Dynamic_string *)malloc(sizeof(Dynamic_string));
if (nElemPtr == NULL || string == NULL){
return ERROR_COMPILER; //kdyby nenaalokoval
}
nElemPtr->instruction = string2;
nElemPtr->instruction->str = string->str;
nElemPtr->previousElement = listInstruct->lastElement; //prenastavi ukazatele
nElemPtr->nextElement = NULL;
if(listInstruct->lastElement != NULL){
listInstruct->lastElement->nextElement = nElemPtr; //kdyz neni posledni prvek, prida novy prvek za posledni
}else{
listInstruct->firstElement = nElemPtr; //jinak ho prida jako prvni prvek
}
listInstruct->lastElement = nElemPtr; //nastavi novy prvek na posledni
(listInstruct->count)++; //inkrementuje counter
return ERROR_PASSED;
}
void DLL_Instruct_First( DLList_Instruct *listInstruct){
listInstruct->activeElement = listInstruct->firstElement; //zmeni aktivitu na prvni prvek
}
void DLL_Instruct_Last( DLList_Instruct *listInstruct){
listInstruct->activeElement = listInstruct->lastElement; //zmeni aktivitu na posledni prvek
}
void DLL_Instruct_GetFirst( DLList_Instruct *listInstruct, Dynamic_string *string){
if (listInstruct->firstElement == NULL){
return;
} else{
*string = *(listInstruct->firstElement->instruction); //ziska data od prvniho prvku
}
}
void DLL_Instruct_GetLast( DLList_Instruct *listInstruct, Dynamic_string *string){
if (listInstruct->lastElement == NULL){
return;
} else{
*string = *(listInstruct->lastElement->instruction); //ziska data od posledniho prvku
}
}
void DLL_Instruct_DeleteFirst( DLList_Instruct *listInstruct){
DLLElementPtr_Instruct elemPtr;
if (listInstruct->firstElement != NULL){ //jestli existuje 1. prvek
elemPtr = listInstruct->firstElement; //pomocny ukazatel ukazuje na 1. prvek
if (listInstruct->activeElement == listInstruct->firstElement){
listInstruct->activeElement = listInstruct->firstElement->nextElement; //ztraci aktivitu
}
if (listInstruct->firstElement == listInstruct->lastElement){ //zdali ma seznam jen jeden prvek
listInstruct->firstElement = NULL; //vyprazdni celi seznam
listInstruct->lastElement = NULL;
}else{
listInstruct->firstElement = listInstruct->firstElement->nextElement; //posune 1.prvek na nasledujici
listInstruct->firstElement->previousElement = NULL; //nastavy ukazatel na predesli 1. prvku na NULL
}
free(elemPtr->instruction);
free(elemPtr); //uvolni 1. prvek
(listInstruct->count)--;
}
}
void DLL_Instruct_DeleteLast( DLList_Instruct *listInstruct){
if (listInstruct->lastElement != NULL){ //jestli existuje posledni prvek
DLLElementPtr_Instruct elemPtr;
elemPtr = listInstruct->lastElement; //pomocny ukazatel ukazuje na posledni prvek
if (listInstruct->activeElement == listInstruct->lastElement){
listInstruct->activeElement = listInstruct->lastElement->previousElement; //ztraci aktivitu
}
if (listInstruct->firstElement == listInstruct->lastElement){ //zdali ma seznam jen jeden prvek
listInstruct->firstElement = NULL; //vyprazdni celi seznam
listInstruct->lastElement = NULL;
}else{
listInstruct->lastElement = listInstruct->lastElement->previousElement; //posune posledni prvek na predchozi
listInstruct->lastElement->nextElement = NULL; //nastavy ukazatel na nasledujici posledni prvku na NULL
}
free(elemPtr->instruction);
free(elemPtr); //uvolni predesli posledni prvek
(listInstruct->count)--;
}
}
void DLL_Instruct_DeleteAfter( DLList_Instruct *listInstruct){
if (listInstruct->activeElement != NULL){
if (listInstruct->activeElement->nextElement != NULL){ //jestlize existuje nasledujici prvek
DLLElementPtr_Instruct elemPtr;
elemPtr = listInstruct->activeElement->nextElement; //pomocny ukazatel ukazuje na nasledujici prvek za aktivnim
listInstruct->activeElement->nextElement = elemPtr->nextElement; //nastavi ukazatel na nasledujici az na dalsi za nasledujicim prvkem
if (elemPtr == listInstruct->lastElement){
listInstruct->lastElement = listInstruct->activeElement; //jestli je mazany posledni, stane se posledni aktivnim
} else{
elemPtr->nextElement->previousElement = listInstruct->activeElement; // jinak nastavi ukazatel na predesli prvku za smazanym na aktivni prvek
}
free(elemPtr->instruction);
free(elemPtr); //uvolni mazany prvek
(listInstruct->count)--;
}
}
}
void DLL_Instruct_DeleteBefore( DLList_Instruct *listInstruct){
if (listInstruct->activeElement != NULL){
if (listInstruct->activeElement->previousElement != NULL){ //jestlize existuje predesli prvek
DLLElementPtr_Instruct elemPtr;
elemPtr = listInstruct->activeElement->previousElement; //pomocny ukazatel ukazuje na predesli prvek pred aktivnim
listInstruct->activeElement->previousElement = elemPtr->previousElement; //nastavi ukazatel na predchozi na prepredesli prvek
if (elemPtr == listInstruct->firstElement){
listInstruct->firstElement = listInstruct->activeElement; //jestli je mazany prvni, stane se prvni aktivnim
} else{
elemPtr->previousElement->nextElement = listInstruct->activeElement; // jinak nastavi ukazatel na nasledujici prvku pred smazanym na aktivni prvek
}
free(elemPtr->instruction);
free(elemPtr); //uvolni mazany prvek
(listInstruct->count)--;
}
}
}
int DLL_Instruct_InsertAfter( DLList_Instruct *listInstruct, Dynamic_string *string){
if(listInstruct->activeElement != NULL){
DLLElementPtr_Instruct nElemPtr = (DLLElementPtr_Instruct)malloc(sizeof(struct DLLElement_Instruct)); //naalokuje prostor pro pridavany prvek
Dynamic_string *string2 = (Dynamic_string *)malloc(sizeof(Dynamic_string));
if (nElemPtr == NULL || string2 == NULL){ //kdyby nenaalokoval
return ERROR_COMPILER;
}
nElemPtr->instruction = string2; //nahraje data
nElemPtr->instruction->str = string->str;
nElemPtr->nextElement = listInstruct->activeElement->nextElement; //prenastavi ukazatele
nElemPtr->previousElement = listInstruct->activeElement;
listInstruct->activeElement->nextElement = nElemPtr; //prida novy prvek
if (listInstruct->activeElement == listInstruct->lastElement){
listInstruct->lastElement = nElemPtr; //jestlize je nasledujici prvek posledni, novy prvek nastavi na posledni prvek
} else{
nElemPtr->nextElement->previousElement = nElemPtr; //jinak nastavi ukazatel na prdechozi prvku za nevym prvkem na novy prvek
}
(listInstruct->count)++;
}
return ERROR_PASSED;
}
int DLL_Instruct_InsertBefore( DLList_Instruct *listInstruct, Dynamic_string *string){
if(listInstruct->activeElement != NULL){
DLLElementPtr_Instruct nElemPtr = (DLLElementPtr_Instruct)malloc(sizeof(struct DLLElement_Instruct)); //naalokuje prostor pro pridavany prvek
Dynamic_string *string2 = (Dynamic_string *)malloc(sizeof(Dynamic_string));
if (nElemPtr == NULL || string2 == NULL){ //kdyby nenaalokoval
return ERROR_COMPILER;
}
nElemPtr->instruction = string2; //nahraje data
nElemPtr->instruction->str = string->str;
nElemPtr->previousElement = listInstruct->activeElement->previousElement; //prenastavi ukazatele
nElemPtr->nextElement = listInstruct->activeElement;
listInstruct->activeElement->previousElement = nElemPtr; //prida novy prvek
if (listInstruct->activeElement == listInstruct->firstElement){
listInstruct->firstElement = nElemPtr; //jestlize je predchozi prvek prvni, novy prvek nastavi na prvni prvek
} else{
nElemPtr->previousElement->nextElement = nElemPtr; //jinak nastavi ukazatel na nasledujici prvku pred nevym prvkem na novy prvek
}
(listInstruct->count)++;
}
return ERROR_PASSED;
}
void DLL_Instruct_GetValue( DLList_Instruct *listInstruct, Dynamic_string *string){
if(listInstruct->activeElement != NULL) {
*string = *(listInstruct->activeElement->instruction); //ziska data od aktivniho prvku, kdyz je aktivni
} else{
return;
}
}
void DLL_Instruct_SetValue( DLList_Instruct *listInstruct, Dynamic_string *string){
if(listInstruct->activeElement != NULL) {
listInstruct->activeElement->instruction->str = string->str; //nastavi data do aktivniho prvku, kdyz je aktivni
}
}
void DLL_Instruct_Next( DLList_Instruct *listInstruct){
if (listInstruct->activeElement == listInstruct->lastElement) {
listInstruct->activeElement = NULL; //nastavi na neaktivitu
}
if(listInstruct->activeElement != NULL) {
listInstruct->activeElement = listInstruct->activeElement->nextElement; //presune aktivitu
}
}
void DLL_Instruct_Previous( DLList_Instruct *listInstruct){
if (listInstruct->activeElement == listInstruct->firstElement) {
listInstruct->activeElement = NULL; //nastavi na neaktivitu
}
if(listInstruct->activeElement != NULL) {
listInstruct->activeElement = listInstruct->activeElement->previousElement; //presune aktivitu
}
}
void DLL_Instruct_setSource(DLList_Instruct *listInstruct, int position){
if (position <= listInstruct->count){
listInstruct->sourceElement = listInstruct->firstElement;
if (position == 1){
return;
}
for (int i = 0; i < position-1; i++) {
listInstruct->sourceElement = listInstruct->sourceElement->nextElement;
}
}
}
void DLL_Instruct_setDestination(DLList_Instruct *listInstruct, int position){
if (position <= listInstruct->count){
listInstruct->destinationElement = listInstruct->firstElement;
if (position == 1){
return;
}
for (int i = 0; i < position-2; i++) {
listInstruct->destinationElement = listInstruct->destinationElement->nextElement;
}
}
}
int DLL_Instruct_Move(DLList_Instruct *listInstruct, int countOfElem, int positionOfDestination, int positionOfSource){
int isRdyToCpy = positionOfSource + countOfElem;
int countOfElemForDes = countOfElem;
if ((listInstruct->count+1) >= isRdyToCpy){
DLLElementPtr_Instruct elemPtr = listInstruct->sourceElement;
if (positionOfDestination == 1){
DLL_Instruct_InsertFirst(listInstruct, listInstruct->sourceElement->instruction);
countOfElemForDes--;
listInstruct->activeElement = listInstruct->destinationElement->previousElement;
elemPtr = elemPtr->nextElement;
} else{
listInstruct->activeElement = listInstruct->destinationElement;
}
for (int i = 0; i < countOfElemForDes; i++) {
DLL_Instruct_InsertAfter(listInstruct,elemPtr->instruction);
listInstruct->activeElement = listInstruct->activeElement->nextElement;
elemPtr = elemPtr->nextElement;
}
listInstruct->activeElement = listInstruct->sourceElement->previousElement;
if (positionOfSource == 1){
countOfElem--;
listInstruct->activeElement = listInstruct->sourceElement;
}
for (int i = 0; i < countOfElem; i++) {
DLL_Instruct_DeleteAfter(listInstruct);
}
if (positionOfSource == 1){
DLL_Instruct_DeleteFirst(listInstruct);
}
} else{
return ERROR_COMPILER;
}
return ERROR_PASSED;
}
/** @endcode */