chiark / gitweb /
Import upstream version 5.3.
[mup] / mup / mup / mainlist.c
1
2 /* Copyright (c) 1995, 2001, 2003 by Arkkra Enterprises */
3 /* All rights reserved */
4
5 /* functions for manipulating the main list of structs, allocating,
6  * inserting and deleting. */
7
8 #include "defines.h"
9 #include "structs.h"
10 #include "globals.h"
11
12
13
14
15 /* allocate a new MAINLL struct and return a pointer to it */
16
17 struct MAINLL *
18 newMAINLLstruct(structtype, lineno)
19
20 int structtype;         /* what kind to allocate: S_SSV, S_BAR, etc */
21 int lineno;             /* input line number that caused this call */
22
23 {
24         struct MAINLL *new_p;   /* the newly allocated struct */
25
26
27         debug(4, "newMAINLLstruct lineno=%d structtype=%d", lineno, structtype);
28
29         /* allocate the struct */
30         CALLOC(MAINLL, new_p, 1);
31
32         /* fill in the type to say which union member will be used */
33         new_p->str = (short) structtype;
34
35         /* initialize link pointers to point nowhere */
36         new_p->next = new_p->prev = (struct MAINLL *) 0;
37
38
39         /* now allocate and initialize the proper S_* struct */
40         switch (structtype) {
41
42         case S_SSV:
43                 CALLOC(SSV, new_p->u.ssv_p, 1);
44                 break;
45
46         case S_STAFF:
47                 CALLOC(STAFF, new_p->u.staff_p, 1);
48                 break;
49
50         case S_BAR:
51                 CALLOC(BAR, new_p->u.bar_p, 1);
52                 break;
53
54         case S_LINE:
55                 CALLOC(LINE, new_p->u.line_p, 1);
56                 break;
57
58         case S_CURVE:
59                 CALLOC(CURVE, new_p->u.curve_p, 1);
60                 break;
61
62         case S_PRHEAD:
63                 CALLOC(PRHEAD, new_p->u.prhead_p, 1);
64                 break;
65
66         case S_CHHEAD:
67                 CALLOC(CHHEAD, new_p->u.chhead_p, 1);
68                 break;
69
70         case S_FEED:
71                 CALLOC(FEED, new_p->u.feed_p, 1);
72                 /* negative value for margin means use score parameter */
73                 new_p->u.feed_p->rightmargin = -1.0;
74                 new_p->u.feed_p->leftmargin = -1.0;
75                 break;
76
77         case S_BLOCKHEAD:
78                 CALLOC(BLOCKHEAD, new_p->u.blockhead_p, 1);
79                 break;
80
81         case S_CLEFSIG:
82                 CALLOC(CLEFSIG, new_p->u.clefsig_p, 1);
83                 break;
84
85         default:
86                 pfatal("unknown structure type %d requested", structtype);
87                 break;
88         }
89
90         /* remember the user's input file and line number,
91          * so in case we have to print an error message later,
92          * we know which line number to print */
93         new_p->inputlineno = (short) lineno;
94         new_p->inputfile = Curr_filename;
95
96         /* return the newly allocated struct */
97         return(new_p);
98 }
99 \f
100
101 /* insert MAINLL struct into main list, after an arbitrary existing struct. */
102 /* If where to insert is NULL, put at beginning of list */
103
104 void
105 insertMAINLL(info_p, where)
106
107 struct MAINLL *info_p;  /* what to insert */
108 struct MAINLL *where;   /* put it right after this one in the list */
109
110 {
111         if (info_p == where) {
112                 /* Any bug that gets us here would cause an infinite loop */
113                 pfatal("attempt to insert a MAINLL after itself");
114         }
115
116         /* if where is NULL, this means to insert at beginning of list */
117         if (where == (struct MAINLL *) 0) {
118                 if (Mainllhc_p != (struct MAINLL *) 0) {
119                         Mainllhc_p->prev = info_p;
120                 }
121                 info_p->prev = (struct MAINLL *) 0;
122                 info_p->next = Mainllhc_p;      
123                 Mainllhc_p = info_p;
124         }
125
126         else {
127                 /* standard linked list stuff --
128                  * fix up the next and prev pointers */
129                 info_p->next = where->next;
130                 info_p->prev = where;
131                 if (where->next != (struct MAINLL *) 0) {
132                         where->next->prev = info_p;
133                 }
134                 where->next = info_p;
135         }
136
137         /* if we just added to the very end of the list, need to adjust the
138          * tail pointer */
139         if ( (Mainlltc_p == (struct MAINLL *) 0) || (where == Mainlltc_p) ) {
140                 Mainlltc_p = info_p;
141         }
142 }
143 \f
144
145 /* unlink a MAINLL struct from the main list
146  * (probably for re-inserting elsewhere). The struct is not freed. */
147
148 void
149 unlinkMAINLL(which_p)
150
151 struct MAINLL *which_p; /* the one to unlink */
152
153 {
154         if (which_p->prev != (struct MAINLL *) 0) {
155                 which_p->prev->next = which_p->next;
156         }
157         if (which_p->next != (struct MAINLL *) 0) {
158                 which_p->next->prev = which_p->prev;
159         }
160
161         /* if this happened to be the tail cell, need to fix up */
162         if (Mainlltc_p == which_p) {
163                 Mainlltc_p = which_p->prev;
164         }
165
166         /* likewise for head cell */
167         if (Mainllhc_p == which_p) {
168                 Mainllhc_p = which_p->next;
169         }
170 }