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 }