Remove tests/inc/test-eom-align
[mmh] / sbr / seq_add.c
1 /*
2 ** seq_add.c -- add message(s) to a sequence
3 **
4 ** This code is Copyright (c) 2002, by the authors of nmh.  See the
5 ** COPYRIGHT file in the root directory of the nmh distribution for
6 ** complete copyright information.
7 */
8
9 #include <h/mh.h>
10
11
12 /*
13 ** Add all the SELECTED messages to a (possibly new) sequence.
14 **
15 ** If public ==  1, make sequence public.
16 ** If public ==  0, make sequence private.
17 ** If public == -1, leave the public/private bit alone for existing
18 **                  sequences.  For new sequences, set this bit based
19 **                  on its readonly status.
20 **
21 ** If error, return 0, else return 1.
22 */
23
24 int
25 seq_addsel(struct msgs *mp, char *cp, int public, int zero)
26 {
27         unsigned int i;
28         int msgnum, new_seq = 1;
29
30         if (!seq_nameok(cp))
31                 return 0;
32
33         /*
34         ** We keep mp->curmsg and cur sequence in sync.
35         ** See seq_list() and seq_init().
36         */
37         if (strcmp(seq_cur, cp)==0)
38                 mp->curmsg = mp->hghsel;
39
40         /*
41         ** Get the number for this sequence
42         */
43         for (i = 0; mp->msgattrs[i]; i++) {
44                 if (strcmp(mp->msgattrs[i], cp)==0) {
45                         new_seq = 0;
46                         break;
47                 }
48         }
49
50         /*
51         ** If this is a new sequence, add a slot for it
52         */
53         if (new_seq) {
54                 if (i >= NUMATTRS) {
55                         advise(NULL, "only %d sequences allowed (no room for %s)!", NUMATTRS, cp);
56                         return 0;
57                 }
58                 if (!(mp->msgattrs[i] = strdup(cp))) {
59                         advise(NULL, "strdup failed");
60                         return 0;
61                 }
62                 mp->msgattrs[i + 1] = NULL;
63         }
64
65         /*
66         ** If sequence is new, or zero flag is set, then first
67         ** clear the bit for this sequence from all messages.
68         */
69         if (mp->nummsg>0 && (new_seq || zero)) {
70                 for (msgnum = mp->lowmsg; msgnum <= mp->hghmsg; msgnum++)
71                         clear_sequence(mp, i, msgnum);
72         }
73
74         /*
75         ** Now flip on the bit for this sequence
76         ** for all selected messages.
77         */
78         for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++)
79                 if (is_selected(mp, msgnum))
80                         add_sequence(mp, i, msgnum);
81
82         /*
83         ** Set the public/private bit for this sequence.
84         */
85         if (public == 1)
86                 make_seq_public(mp, i);
87         else if (public == 0)
88                 make_seq_private(mp, i);
89         else if (new_seq) {
90                 /*
91                 ** If public == -1, then only set the
92                 ** public/private bit for new sequences.
93                 */
94                 if (is_readonly(mp))
95                         make_seq_private(mp, i);
96                 else
97                         make_seq_public(mp, i);
98         }
99
100         mp->msgflags |= SEQMOD;
101         return 1;
102 }
103
104
105 /*
106 ** Add a message to a (possibly new) sequence.
107 **
108 ** If public ==  1, make sequence public.
109 ** If public ==  0, make sequence private.
110 ** If public == -1, leave the public/private bit alone for existing
111 **                  sequences.  For new sequences, set this bit based
112 **                  on its readonly status.
113 **
114 ** If error, return 0, else return 1.
115 */
116
117 int
118 seq_addmsg(struct msgs *mp, char *cp, int msgnum, int public, int zero)
119 {
120         unsigned int i;
121         int j, new_seq = 1;
122
123         if (!seq_nameok(cp))
124                 return 0;
125
126         /*
127         ** keep mp->curmsg and msgattrs[] of seq_cur in sync - see seq_list()
128         */
129         if (strcmp(seq_cur, cp)==0)
130                 mp->curmsg = msgnum;
131
132         /*
133         ** Get the number for this sequence
134         */
135         for (i = 0; mp->msgattrs[i]; i++) {
136                 if (strcmp(mp->msgattrs[i], cp)==0) {
137                         new_seq = 0;
138                         break;
139                 }
140         }
141
142         if (new_seq) {
143                 /* If this is a new sequence, add a slot for it */
144                 if (i >= NUMATTRS) {
145                         advise(NULL, "only %d sequences allowed (no room for %s)!", NUMATTRS, cp);
146                         return 0;
147                 }
148                 if (!(mp->msgattrs[i] = strdup(cp))) {
149                         advise(NULL, "strdup failed");
150                         return 0;
151                 }
152                 mp->msgattrs[i + 1] = NULL;
153         }
154
155         if (mp->nummsg>0 && (new_seq || zero)) {
156                 /* Clear the bit for this sequence from all messages. */
157                 for (j = mp->lowmsg; j <= mp->hghmsg; j++)
158                         clear_sequence(mp, i, j);
159         }
160
161         /* Set the bit for this sequence for this particular message. */
162         add_sequence(mp, i, msgnum);
163
164         /* Set the public/private bit for this sequence. */
165         if (public == 1)
166                 make_seq_public(mp, i);
167         else if (public == 0)
168                 make_seq_private(mp, i);
169         else if (new_seq) {
170                 /*
171                 ** If public == -1, then only set the
172                 ** public/private bit for new sequences.
173                 */
174                 if (is_readonly(mp))
175                         make_seq_private(mp, i);
176                 else
177                         make_seq_public(mp, i);
178         }
179
180         mp->msgflags |= SEQMOD;
181         return 1;
182 }