1 /*****************************************************************************
2 ** This is part of the SpaceZero program
3 ** Copyright(C) 2006-2013 MRevenga
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License (version 3), or
7 ** (at your option) any later version, as published by the Free Software
8 ** Foundation.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 ******************************************************************************/
19
20 /************* SpaceZero M.R.H. 2006-2013 ******************
21 Author: MRevenga
22 E-mail: mrevenga at users.sourceforge.net
23 version 0.86 December 2013
24 **************************************************************/
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include "data.h"
29 #include "general.h"
30 #include "objects.h"
31 #include "functions.h"
32
33
34 /*
35 * data structures and functions
36 *
37 */
38
39
40
41 /*
42 Unordered list
43 */
44
Add2IntList(struct IntList * list,int id)45 struct IntList* Add2IntList(struct IntList *list,int id){
46 /*
47 version 01
48 add the integer id to the end of the list
49 if is not already added.
50 returns:
51 a pointer to the beginning of the list.
52 */
53
54 struct IntList *kps;
55
56 if(list==NULL){ /* first item */
57 list=malloc(sizeof(struct IntList));
58 MemUsed(MADD,+sizeof(struct IntList));
59 if(list==NULL){
60 fprintf(stderr,"ERROR in malloc (Add2IntList)\n");
61 exit(-1);
62 }
63 list->id=id;
64 list->next=NULL;
65 return(list);
66 }
67
68 /* look if it its already added */
69 kps=list;
70
71 if(kps->id==id)
72 return(list); /* first item is known */
73
74 while(kps->next!=NULL){
75 if(kps->next->id==id)
76 return(list); /* item was known */
77 kps=kps->next;
78 }
79 /*
80 item is not in the list
81 adding to the end
82 */
83
84 kps->next=malloc(sizeof(struct IntList));
85 if(kps->next==NULL){
86 fprintf(stderr,"ERROR in malloc (Add2IntList)\n");
87 exit(-1);
88 }
89 MemUsed(MADD,+sizeof(struct IntList));
90 kps->next->id=id;
91 kps->next->next=NULL;
92 return(list);
93 }
94
95
IsInIntList(struct IntList * list,int id)96 int IsInIntList(struct IntList *list,int id){
97 /*
98 Secuential search (must be improve)
99 return:
100 TRUE if id is in the list
101 FALSE if not.
102 */
103
104 /* look if it its already added */
105
106 while(list!=NULL){
107 if(list->id==id){
108 return(TRUE); /* item is known */
109 }
110 list=list->next;
111 }
112
113 /* item is not in the list */
114 return(FALSE);
115 }
116
CountIntList(struct IntList * list)117 int CountIntList(struct IntList *list){
118 /* return the number of item of the list */
119
120 int n=0;
121
122 while(list!=NULL){
123 n++;
124 list=list->next;
125 }
126 return(n);
127 }
128
DelFirstIntList(struct IntList * list)129 int DelFirstIntList(struct IntList *list){
130 /* Delete the first item of the list */
131 struct IntList *item0;
132
133 if(list!=NULL){
134 item0=list;
135 list=list->next;
136 free(item0);
137 MemUsed(MADD,-sizeof(struct IntList));
138 item0=NULL;
139 return(1);
140 }
141 return(0);
142 }
143
144
DelIntList(struct IntList * list)145 int DelIntList(struct IntList *list){
146 /*
147 version 01
148 Delete all the list
149 returns the number of items deleted
150 */
151
152 struct IntList *item0;
153 int n=0;
154
155 if(list==NULL)return(0);
156
157 while(list->next!=NULL){
158 item0=list->next;
159 list->next=list->next->next;
160 free(item0);
161 MemUsed(MADD,-sizeof(struct IntList));
162 item0=NULL;
163 n++;
164 }
165
166 free(list);
167 MemUsed(MADD,-sizeof(struct IntList));
168 list=NULL;
169 n++;
170 return (n);
171 }
172
173
FPrintIntList(FILE * fp,struct IntList * list)174 int FPrintIntList(FILE *fp,struct IntList *list){
175 /* return the number of item of the list */
176
177 int n=0;
178
179 while(list!=NULL){
180 fprintf(fp,"%d ",list->id);
181 n++;
182 list=list->next;
183 }
184 return(n);
185 }
186
187
188 /*
189 Ordered list
190 */
191
IsInIntOList(struct IntList * list,int id)192 int IsInIntOList(struct IntList *list,int id){
193 /* return:
194 TRUE if id is in the list
195 FALSE if not.
196 */
197
198 while(list!=NULL){
199 if(list->id==id)
200 return(TRUE); /* item is known */
201 if(list->id>id)
202 return(FALSE);
203 list=list->next;
204 }
205
206 /* item is not in the list */
207 return(FALSE);
208 }
209
210
211 /*
212 Indexed list
213 */
214
Add2IntIList(struct HeadIntIList * head,int id)215 int Add2IntIList(struct HeadIntIList *head,int id){
216 /* add the integer id to the list head
217 if is not already added.
218 returns:
219 0 if item is added
220 1 if is not added, the item exists
221 */
222 struct IntList *item;
223 struct IntList *last=NULL;
224 int i;
225
226 /* is the first */
227 if(head->list==NULL){
228 head->list=malloc(sizeof(struct IntList));
229 MemUsed(MADD,+sizeof(struct IntList));
230 if(head->list==NULL){
231 fprintf(stderr,"ERROR in malloc (Add2IntIList)\n");
232 exit(-1);
233 }
234 head->n++;
235 head->n0++;
236 head->list->id=id;
237 head->list->next=NULL;
238 for(i=0;i<NINDEXILIST;i++){
239 head->index[i]=head->list;
240 }
241 return(0);
242 }
243
244 if(head->n0 > NINDEXCALC){
245 int i=0;
246 int n=0;
247 int m;
248
249 item=head->list;
250 head->n0=0;
251 m=head->n/NINDEXILIST;
252 head->index[i++]=head->list;
253 while(item!=NULL){
254 n++;
255 if(n>m){
256 head->index[i++]=item;
257 n=0;
258 }
259 item=item->next;
260 }
261 }
262
263 item=head->list;
264 for(i=0;i<NINDEXILIST-1;i++){
265 if( head->index[i]->id > id)break;
266 item=head->index[i];
267 }
268
269 /* look if it its already added */
270 while(item!=NULL){
271
272 if(item->id==id){
273 return(1); /* item is in the list */
274 }
275 if(item->id>id){ /*item is not in the list, adding in the middle */
276 struct IntList *itemn;
277 itemn=malloc(sizeof(struct IntList));
278 MemUsed(MADD,+sizeof(struct IntList));
279 if(itemn==NULL){
280 fprintf(stderr,"ERROR in malloc (Add2IntIList)\n");
281 exit(-1);
282 }
283 head->n++;
284 head->n0++;
285
286 if(last==NULL){ /* first item */
287 itemn->id=id;
288 itemn->next=head->list;
289 head->list=itemn;
290 head->index[0]=head->list;
291
292 }
293 else{
294 itemn->id=id;
295 last->next=itemn;
296 itemn->next=item;
297 }
298 return(0);
299 }
300 last=item;
301 item=item->next;
302 }
303
304 /* item is not in the list, adding to the end */
305 head->n++;
306 head->n0++;
307
308 item=malloc(sizeof(struct IntList));
309 MemUsed(MADD,+sizeof(struct IntList));
310 if(item==NULL){
311 fprintf(stderr,"ERROR in malloc (Add2IntIList)\n");
312 exit(-1);
313 }
314
315 last->next=item;
316 item->next=NULL;
317 item->id=id;
318
319 return(0);
320 }
321
IsInIntIList(struct HeadIntIList * head,int id)322 int IsInIntIList(struct HeadIntIList *head,int id){
323 /* return:
324 TRUE if id is in the list
325 FALSE if not.
326 */
327
328 /* look if it its already added */
329
330 int i;
331 struct IntList *list;
332
333
334 list=head->index[0];
335
336 if(list==NULL){
337 return(FALSE);
338 }
339 for(i=0;i<NINDEXILIST-1;i++){
340 if( head->index[i]->id > id)break;
341 list=head->index[i];
342 }
343
344 while(list!=NULL){
345 if(list->id==id)
346 return(TRUE); /* item is known */
347 if(list->id>id)
348 return(FALSE);
349 list=list->next;
350 }
351
352 /* item is not in the list */
353 return(FALSE);
354 }
355
DelIntIList(struct HeadIntIList * head)356 int DelIntIList(struct HeadIntIList *head){
357 /* Delete all the list */
358
359 int n=0;
360 int i;
361
362 DelIntList(head->list);
363
364 head->n=head->n0=0;
365
366 head->list=NULL;
367 for(i=0;i<NINDEXILIST;i++){
368 head->index[i]=NULL;
369 }
370 return (n);
371 }
372
PrintIntIList(struct HeadIntIList head)373 int PrintIntIList(struct HeadIntIList head){
374 /* print the list */
375 int n=0;
376 int i;
377 struct IntList *list;
378
379 list=head.list;
380
381 while(list!=NULL){
382 printf("%d ",list->id);
383 n++;
384 list=list->next;
385 }
386 printf("\n");
387 for(i=0;i<NINDEXILIST;i++){
388 if(head.index[i]!=NULL)
389 printf("%p %d\n",(void *)head.index[i],head.index[i]->id);
390 else
391 printf("%p\n",(void *)head.index[i]);
392 }
393 return(n);
394 }
395
396
397 /* char list with scroll */
398
Add2CharList(struct CharListHead * hlist,char * cad,int mode)399 int Add2CharList(struct CharListHead *hlist,char *cad,int mode){
400 /*
401 version 00
402 add the char cad to the end of the list
403 returns:
404 0 if success, item added.
405 1 success,list full, item added and first item deleted.
406 2 if there are some error.
407 3 if is already added.
408 */
409
410 struct CharList *list;
411 int swfull=0;
412 int m=0;
413 int n;
414
415
416 if(hlist==NULL){
417 fprintf(stderr,"ERROR in Add2CharList(): NULL\n");
418 exit(-1);
419 }
420 if(cad==NULL){
421 fprintf(stderr,"ERROR in Add2CharList(): cad NULL\n");
422 return(2);
423 }
424 n=strlen(cad);
425 if(n>MAXTEXTLEN)n=MAXTEXTLEN; /* max of log messages */
426
427 if(mode==1){ /* check if is recently added => don't add*/
428 m=0;
429 list=hlist->next;
430 while(list!=NULL){
431 if(strncmp(cad,list->cad,MAXTEXTLEN)==0){
432 if(m > hlist->n-20){
433 return(2);
434 }
435 }
436 m++;
437 list=list->next;
438 }
439 }
440
441 list=hlist->next;
442
443 if(list==NULL){ /* first item */
444 list=malloc(sizeof(struct CharList));
445 MemUsed(MADD,+sizeof(struct CharList));
446 if(list==NULL){
447 fprintf(stderr,"ERROR in malloc (Add2Charlist)\n");
448 exit(-1);
449 }
450
451 list->cad=malloc((n+1)*sizeof(char));
452 MemUsed(MADD,+sizeof((n+1)*sizeof(char)));
453 if(list->cad==NULL){
454 fprintf(stderr,"ERROR in malloc (Add2Charlist)\n");
455 exit(-1);
456 }
457
458 snprintf(list->cad,n+1,"%s",cad);
459 /* strncpy(list->cad,cad,n+1); */
460 list->next=NULL;
461 hlist->next=list;
462 hlist->n++;
463 return(0);
464 }
465
466 /* checking max number of elements */
467 /* if reach its limit delete the first item */
468
469 if(hlist->n==hlist->max){
470 struct CharList *freeitem;
471 int n;
472 freeitem=hlist->next;
473 if(freeitem!=NULL){
474 hlist->next=hlist->next->next;
475 n=strlen(freeitem->cad);
476 free(freeitem->cad);
477 free(freeitem);
478 MemUsed(MADD,-(sizeof((n+1)*sizeof(char))+sizeof(struct CharList)));
479 hlist->n--;
480 swfull++;
481 }
482 else{
483 fprintf(stderr,"ERROR in List (Add2Charlist) not added.\n");
484 return(2);
485 }
486 }
487
488
489 /* adding to the end of the list if there are room */
490
491 while(list->next!=NULL)list=list->next;
492
493 list->next=malloc(sizeof(struct CharList));
494 MemUsed(MADD,+sizeof(struct CharList));
495 if(list->next==NULL){
496 fprintf(stderr,"ERROR in malloc (Add2Charlist)\n");
497 exit(-1);
498 }
499
500 list->next->cad=malloc((n+1)*sizeof(char));
501 MemUsed(MADD,+sizeof((n+1)*sizeof(char)));
502 if(list->next->cad==NULL){
503 fprintf(stderr,"ERROR in malloc (Add2Charlist)\n");
504 exit(-1);
505 }
506 snprintf(list->next->cad,n+1,"%s",cad);
507 /* strncpy(list->next->cad,cad,n+1); */
508 list->next->next=NULL;
509 hlist->n++;
510
511 if(swfull)return(1);
512 return(0);
513 }
514
Add2CharListWindow(struct CharListHead * hlist,char * cad,int mode,struct Window * w)515 int Add2CharListWindow(struct CharListHead *hlist,char *cad,int mode,struct Window *w){
516 /*
517 version 00
518 change the scroll bar if a new item is added to hlist.
519 returns:
520 0 if success
521 1 if there are some error
522 2 if is already added
523 */
524
525 int status;
526
527 if(hlist==NULL){
528 fprintf(stderr,"ERROR in Add2CharListWindow(): NULL\n");
529 exit(-1);
530 }
531 if(cad==NULL){
532 fprintf(stderr,"ERROR in Add2CharListwindow(): cad NULL\n");
533 return(1);
534 }
535
536 if(w==NULL)return(1);
537
538 status= Add2CharList(hlist,cad,mode);
539
540 switch(status){
541 case 0:
542 case 1:
543 if(w->scrollbar.n!=0){
544 w->scrollbar.n++;
545 }
546 break;
547 case 2:
548 break;
549 default:
550 break;
551 }
552
553 return(status);
554 }
555
556
557
PrintCharList(struct CharListHead * hlist)558 int PrintCharList(struct CharListHead *hlist){
559 /*
560 version 00
561 print the list
562 returns:
563 the number of item printed.
564 */
565
566 struct CharList *list;
567 int n=0;
568
569
570 if(hlist==NULL){
571 fprintf(stderr,"ERROR in Add2CharList(): NULL\n");
572 exit(-1);
573 }
574
575 list=hlist->next;
576
577 while(list!=NULL){
578 printf("%d: %s\n",n,list->cad);
579 list=list->next;
580 n++;
581 }
582 if(n!=hlist->n){
583 printf("ERROR in list n: %d hlist.n:%d\n",n,hlist->n);
584 }
585 return(n);
586 }
587
588
DestroyCharList(struct CharListHead * hlist)589 int DestroyCharList(struct CharListHead *hlist){
590 /*
591 version 00
592 delete all the list
593 returns:
594 the number of item deleted.
595 */
596
597 struct CharList *freeitem;
598 int n=0;
599 int cont=0;
600
601 if(hlist==NULL){
602 fprintf(stderr,"ERROR in Add2CharList(): NULL\n");
603 exit(-1);
604 }
605
606 while(hlist->next!=NULL){
607 freeitem=hlist->next;
608 hlist->next=hlist->next->next;
609 n=strlen(freeitem->cad);
610 free(freeitem->cad);
611 free(freeitem);
612 MemUsed(MADD,-(sizeof(n*sizeof(char))+sizeof(struct CharList)));
613 hlist->n--;
614 cont++;
615 }
616 return(cont);
617 }
618
619
620
621 /********
622 Tree
623 ********/
624
Add2IntTree(struct IntTree * head,int id)625 struct IntTree *Add2IntTree(struct IntTree *head,int id){
626 /* add the integer id to the tree head
627 if is not already added.
628 returns:
629 a pointer to the head of the list.
630 */
631
632 if(!head){
633 head=malloc(sizeof(struct IntTree));
634 MemUsed(MADD,+sizeof(struct IntTree));
635 if(head==NULL){
636 fprintf(stderr,"ERROR in malloc (Add2IntTree)\n");
637 exit(-1);
638 }
639 head->id=id;
640 head->l=NULL;
641 head->r=NULL;
642 printf("added: %d\n",head->id);
643 return(head);
644 }
645
646 if(id<head->id){
647 head->l=Add2IntTree(head->l,id);
648 }
649 else{
650 if(id>head->id){
651 head->r=Add2IntTree(head->r,id);
652 }
653 }
654 return(head);
655 }
656
PrintTree(struct IntTree * head)657 void PrintTree (struct IntTree *head){
658 static int level=0;
659 level++;
660 if(head!=NULL){
661 PrintTree(head->l);
662 printf("l %d: %d\n",level,head->id);
663 PrintTree(head->r);
664 }
665 level--;
666 }
667
SizeIntTree(struct IntTree * head,int reset)668 int SizeIntTree (struct IntTree *head,int reset){
669 /*
670 Return:
671 the size of the tree.
672 */
673
674
675 static int level=0;
676 static int max=0;
677 if(reset){
678 max=0;
679 return(0);
680 }
681 if(level>max)max=level;
682 level++;
683
684 if(head!=NULL){
685 SizeIntTree(head->l,0);
686 SizeIntTree(head->r,0);
687 }
688 level--;
689 return(max);
690 }
691
692
IsInIntTree(struct IntTree * head,int id)693 int IsInIntTree(struct IntTree *head,int id){
694 /*
695 returns:
696 1 if the element id is in the tree
697 0 if not.
698 */
699 if(head!=NULL){
700 if(id==head->id){
701 return(1);
702 }
703 if(id < head->id){
704 return(IsInIntTree(head->l,id));
705 }
706 else{
707 return(IsInIntTree(head->r,id));
708 }
709 }
710 return(0);
711 }
712
DelIntTree(struct IntTree * head)713 void DelIntTree(struct IntTree *head){
714 /*
715 Delete the tree freeing the memory.
716 */
717
718 if(head!=NULL){
719 DelIntTree(head->l);
720 DelIntTree(head->r);
721 head->l=NULL;
722 head->r=NULL;
723 free(head);
724 MemUsed(MADD,-sizeof(struct IntTree));
725 head=NULL;
726 }
727 }
728
729
CountIntTree(struct IntTree * head)730 int CountIntTree (struct IntTree *head){
731 /*
732 Returns:
733 the number of elemnets of the tree.
734 */
735 int cont=0;
736
737 if(head!=NULL){
738 cont+=CountIntTree(head->l);
739 cont++;
740 cont+=CountIntTree(head->r);
741 }
742 return(cont);
743 }
744
745 /************
746 Text Lists
747 ***********/
748
Add2TextList(struct HeadTextList * listhead,char * cad,int color)749 int Add2TextList(struct HeadTextList *listhead,char *cad,int color){
750 /*
751 add the cad to the list
752 */
753 struct TextList *lh,*new;
754
755 new=malloc(sizeof(struct TextList));
756 if(new==NULL){
757 fprintf(stderr,"ERROR in malloc Add2TextList()\n");
758 exit(-1);
759 }
760 MemUsed(MADD,+sizeof(struct TextList));
761
762 strncpy(new->text,cad,MAXTEXTLEN);
763 new->color=color;
764 new->next=NULL;
765
766 /* first item*/
767 if(listhead->next==NULL){
768 listhead->next=new;
769 }
770 else{
771 /* Add text at the end of the list */
772 lh=listhead->next;
773 while(lh->next!=NULL){
774 lh=lh->next;
775 }
776 lh->next=new;
777 }
778 listhead->n++;
779 return (0);
780 }
781
DestroyTextList(struct HeadTextList * head)782 int DestroyTextList(struct HeadTextList *head){
783 /*
784 delete all the list
785 return:
786 the number of items deleted
787 */
788 struct TextList *lh0;
789 struct TextList *lh;
790 int n=0;
791 long memused=0;
792
793 lh=head->next;
794 while(lh!=NULL){
795 lh0=lh;
796 lh=lh->next;
797 free(lh0);
798 lh0=NULL;
799 memused-=sizeof(struct TextList);
800 n++;
801 }
802 head->next=NULL;
803 head->n=0;
804 MemUsed(MADD,memused);
805 return (n);
806 }
807
PrintTextList(struct HeadTextList * head)808 int PrintTextList(struct HeadTextList *head){
809 struct TextList *lh;
810
811 lh=head->next;
812 while(lh!=NULL){
813 printf("%s\n",lh->text);
814 lh=lh->next;
815 }
816 return(0);
817 }
CountTextList(struct HeadTextList * head)818 int CountTextList(struct HeadTextList *head){
819 /*
820 returns:
821 the number of items of the the list head.
822 */
823 struct TextList *lh;
824 int n=0;
825 lh=head->next;
826 while(lh!=NULL){
827 n++;
828 lh=lh->next;
829 }
830 return(n);
831 }
PosFirstTextList(struct HeadTextList * head,int m)832 int PosFirstTextList(struct HeadTextList *head,int m){
833 /*
834 returns:
835 the position of the first text with color m
836 */
837
838 struct TextList *lh;
839 int n=0;
840 lh=head->next;
841 while(lh!=NULL){
842 if(lh->color==m)return(n);
843 n++;
844 lh=lh->next;
845 }
846 return(-1);
847 }
848
849
PosLastTextList(struct HeadTextList * head,int m)850 int PosLastTextList(struct HeadTextList *head,int m){
851 /*
852 returns:
853 the position of the last text item with color m
854 */
855
856 struct TextList *lh;
857 int n=0;
858 int ret=0;
859
860 lh=head->next;
861 while(lh!=NULL){
862 if(lh->color==m)ret=n;
863 n++;
864 lh=lh->next;
865 }
866 return(ret);
867 }
868
CountColorTextList(struct HeadTextList * head,int m)869 int CountColorTextList(struct HeadTextList *head,int m){
870 /*
871 returns:
872 the number of texts of color m
873 */
874
875 struct TextList *lh;
876 int n=0;
877 lh=head->next;
878 while(lh!=NULL){
879 if(lh->color==m)n++;
880 lh=lh->next;
881 }
882 return(n);
883 }
884