1 /* $Id: wr.c,v 1.13 1994/06/24 11:19:14 ceriel Exp $ */
3 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
4 * See the copyright notice in the ACK home directory, in the file "Copyright".
7 * You can choose between two strategies:
8 * - Open the output file several times, once for each logical part, and
9 * write to it in multiple places.
10 * - Open the output file once and seek back and forth to each logical
11 * part. In this case #define OUTSEEK.
19 * Parts of the output file.
21 static long offset[MAXSECT];
22 struct fil __parts[NPARTS];
29 #define sectionnr __sectionnr
34 register struct fil *ptr;
37 /* seek to correct position even if we aren't going to write now */
38 if (currpos != ptr->currpos) {
39 currpos = lseek(ptr->fd, ptr->currpos, 0);
42 if (ptr->pnow > ptr->pbegin) {
43 wr_bytes(ptr->fd, ptr->pbegin, (long)(ptr->pnow - ptr->pbegin));
44 ptr->currpos += ptr->pnow - ptr->pbegin;
46 currpos = ptr->currpos;
48 if (ptr < &__parts[PARTEMIT+SECTCNT]) {
49 offset[sectionnr] = ptr->currpos;
53 ptr->pnow = ptr->pbuf;
54 ptr->pbegin = ptr->pbuf;
59 int p; /* part number */
60 register char *b; /* buffer pointer */
61 long n; /* write count */
63 register struct fil *ptr = &__parts[p];
64 register char *pn = ptr->pnow;
72 wr_bytes(ptr->fd, b, (long) i);
77 currpos = ptr->currpos;
79 if (ptr < &__parts[PARTEMIT+SECTCNT]) {
80 offset[sectionnr] = ptr->currpos;
94 if (ptr->cnt == 0 || ptr->cnt == WBUFSIZ) {
96 m = n & ~(WBUFSIZ - 1);
98 wr_bytes(ptr->fd, b, m);
103 currpos = ptr->currpos;
105 if (ptr < &__parts[PARTEMIT+SECTCNT]) {
106 offset[sectionnr] = ptr->currpos;
125 int p; /* part number */
126 long o; /* offset in file */
128 register struct fil *ptr = &__parts[p];
134 ptr->currpos = lseek(ptr->fd, o, 0);
136 if (p >= PARTRELO) o = 0; /* no attempt to align writes
137 for the time being */
138 ptr->cnt = WBUFSIZ - ((int)o & (WBUFSIZ-1));
139 ptr->pbegin = ptr->pbuf + (WBUFSIZ - ptr->cnt);
140 ptr->pnow = ptr->pbegin;
145 * Open the output file according to the chosen strategy.
151 register struct fil *fdp;
153 close(creat(f, 0666));
155 if ((outfile = open(f, 1)) < 0)
158 #else /* not OUTSEEK */
159 for (fdp = &__parts[PARTEMIT]; fdp < &__parts[NPARTS]; fdp++)
160 if ((fdp->fd = open(f, 1)) < 0)
162 #endif /* not OUTSEEK */
170 register struct fil *ptr;
172 for (ptr = &__parts[PARTEMIT]; ptr < &__parts[NPARTS]; ptr++) {
176 #endif /* not OUTSEEK */
187 register struct outhead *head;
190 register long off = OFF_RELO(*head);
192 BEGINSEEK(PARTEMIT, 0L);
193 BEGINSEEK(PARTRELO, off);
194 off += (long) head->oh_nrelo * SZ_RELO;
195 BEGINSEEK(PARTNAME, off);
196 off += (long) head->oh_nname * SZ_NAME;
197 BEGINSEEK(PARTCHAR, off);
199 off += head->oh_nchar;
200 BEGINSEEK(PARTDBUG, off);
203 if (BYTE_ORDER != 0x0123 || sizeof(struct outhead) != SZ_HEAD)
207 register char *c = &buf[0];
209 put2(head->oh_magic, c); c += 2;
210 put2(head->oh_stamp, c); c += 2;
211 put2(head->oh_flags, c); c += 2;
212 put2(head->oh_nsect, c); c += 2;
213 put2(head->oh_nrelo, c); c += 2;
214 put2(head->oh_nname, c); c += 2;
215 put4(head->oh_nemit, c); c += 4;
216 put4(head->oh_nchar, c);
217 OUTWRITE(PARTEMIT, buf, (long)SZ_HEAD);
219 else OUTWRITE(PARTEMIT, (char *)head, (long)SZ_HEAD);
224 register struct outsect *sect;
225 register unsigned int cnt;
227 { register unsigned int i = cnt;
230 if (offcnt >= 1 && offcnt < SECTCNT) {
231 BEGINSEEK(PARTEMIT+offcnt, sect->os_foff);
233 offset[offcnt++] = sect->os_foff;
238 #if BYTE_ORDER == 0x0123
239 if (sizeof(struct outsect) != SZ_SECT)
244 register unsigned int i;
246 i = __parts[PARTEMIT].cnt/SZ_SECT;
247 c = __parts[PARTEMIT].pnow;
248 if (i > cnt) i = cnt;
250 __parts[PARTEMIT].cnt -= (i*SZ_SECT);
252 put4(sect->os_base, c); c += 4;
253 put4(sect->os_size, c); c += 4;
254 put4(sect->os_foff, c); c += 4;
255 put4(sect->os_flen, c); c += 4;
256 put4(sect->os_lign, c); c += 4;
259 __parts[PARTEMIT].pnow = c;
261 __wr_flush(&__parts[PARTEMIT]);
264 #if BYTE_ORDER == 0x0123
266 OUTWRITE(PARTEMIT, (char *) sect, (long) cnt * SZ_SECT);
273 int s; /* section number */
275 register struct fil *ptr = &__parts[PARTEMIT + getsect(sectionnr)];
277 if (s != sectionnr && s >= (SECTCNT-1) && sectionnr >= (SECTCNT-1)) {
279 if (currpos != ptr->currpos)
280 currpos = lseek(ptr->fd, ptr->currpos, 0);
282 wr_bytes(ptr->fd, ptr->pbegin, (long)(ptr->pnow - ptr->pbegin));
283 ptr->currpos += ptr->pnow - ptr->pbegin;
285 currpos = ptr->currpos;
287 offset[sectionnr] = ptr->currpos;
288 if (offset[s] != ptr->currpos) {
289 ptr->currpos = lseek(ptr->fd, offset[s], 0);
291 currpos = ptr->currpos;
294 ptr->cnt = WBUFSIZ - ((int)offset[s] & (WBUFSIZ-1));
295 ptr->pbegin = ptr->pbuf + (WBUFSIZ - ptr->cnt);
296 ptr->pnow = ptr->pbegin;
302 * We don't have to worry about byte order here.
309 OUTWRITE(PARTEMIT + getsect(sectionnr) , emit, cnt);
314 register struct outrelo *relo;
318 #if BYTE_ORDER == 0x0123
319 if (sizeof(struct outrelo) != SZ_RELO)
324 register unsigned int i;
326 i = __parts[PARTRELO].cnt/SZ_RELO;
327 c = __parts[PARTRELO].pnow;
328 if (i > cnt) i = cnt;
330 __parts[PARTRELO].cnt -= (i*SZ_RELO);
332 *c++ = relo->or_type;
333 *c++ = relo->or_sect;
334 put2(relo->or_nami, c); c += 2;
335 put4(relo->or_addr, c); c += 4;
338 __parts[PARTRELO].pnow = c;
340 __wr_flush(&__parts[PARTRELO]);
343 #if BYTE_ORDER == 0x0123
345 OUTWRITE(PARTRELO, (char *) relo, (long) cnt * SZ_RELO);
352 register struct outname *name;
355 #if BYTE_ORDER == 0x0123
356 if (sizeof(struct outname) != SZ_NAME)
361 register unsigned int i;
363 i = __parts[PARTNAME].cnt/SZ_NAME;
364 c = __parts[PARTNAME].pnow;
365 if (i > cnt) i = cnt;
367 __parts[PARTNAME].cnt -= (i*SZ_NAME);
369 put4(name->on_foff, c); c += 4;
370 put2(name->on_type, c); c += 2;
371 put2(name->on_desc, c); c += 2;
372 put4(name->on_valu, c); c += 4;
375 __parts[PARTNAME].pnow = c;
376 if (cnt) __wr_flush(&__parts[PARTNAME]);
378 #if BYTE_ORDER == 0x0123
380 OUTWRITE(PARTNAME, (char *) name, (long)cnt * SZ_NAME);
392 OUTWRITE(PARTCHAR, addr, len);
402 OUTWRITE(PARTDBUG, buf, size);