1/* 2 * Copyright (c) 1985 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that this notice is preserved and that due credit is given 7 * to the University of California at Berkeley. The name of the University 8 * may not be used to endorse or promote products derived from this 9 * software without specific written prior permission. This software 10 * is provided ``as is'' without express or implied warranty. 11 */ 12 13#ifdef LIBC_SCCS 14_sccsid:.asciz "@(#)fputs.s 5.5 (Berkeley) 05/23/88" 15#endif /* LIBC_SCCS */ 16 17/* 18 * fputs(s, iop); 19 * char *s; 20 * FILE *iop; 21 * 22 * arguments: a source string and a file pointer. 23 * side effects: writes to the file indicated by iop using the data in 24 * the null-terminated source string. 25 * result: technically void; for compatibility we return 0 for the null 26 * string, non-zero otherwise. We return zero for errors too. 27 */ 28 29#include "DEFS.h" 30 31#define NBF 04 32#define LBF 0200 33 34#define NL 012 35 36ENTRY(fputs, R11|R10|R9) 37 38#define S r11 39 movl 4(ap),S 40#define IOP r10 41#define _CNT 42#define _PTR 4 43#define _BASE 8 44#define _BUFSIZ 12 45#define _FLAG 16 46 movl 8(ap),IOP 47 48#define UNBUF -4(fp) 49 50#define COUNT r9 51 52 /* 53 * For compatibility (sigh). 54 */ 55 tstb (S) 56 jeql Lerror 57 58 /* 59 * For unbuffered I/O, line buffer the output line. 60 * Ugly but fast -- and doesn't CURRENTLY break anything (sigh). 61 */ 62 movab -1028(sp),sp 63 bicw3 $~NBF,_FLAG(IOP),UNBUF 64 jeql 1f 65 66 bicw2 $NBF,_FLAG(IOP) /* Clear no-buffering flag */ 67 movl sp,_BASE(IOP) /* Create a buffer */ 68 movl sp,_PTR(IOP) 69 cvtwl $1024,_BUFSIZ(IOP) 70 jbr 2f 71 721: 73 tstl _CNT(IOP) /* Has a buffer been allocated? */ 74 jgtr 2f 75 pushl IOP /* Get _flsbuf() to do the work */ 76 pushl $0 77 calls $2,__flsbuf 78 tstl r0 79 jlss Lerror 80 incl _CNT(IOP) /* Unput the char we sent */ 81 decl _PTR(IOP) 822: 83 84 /* 85 * Search for the terminating null. 86 * We only need to look at _BUFSIZ bytes or less on each pass. 87 */ 88Lloop: 89 addl3 _BASE(IOP),_BUFSIZ(IOP),COUNT /* How many bytes? */ 90 subl2 _PTR(IOP),COUNT 91 locc $0,COUNT,(S) /* Look for a null */ 92 jeql Lagain 93 94 subl2 r0,COUNT /* Copy the data */ 95 movc3 COUNT,(S),*_PTR(IOP) 96 movl r3,_PTR(IOP) /* Fix up IOP */ 97 subl2 COUNT,_CNT(IOP) 98 bitw $LBF,_FLAG(IOP) /* If line buffered... */ 99 jneq 1f 100 tstw UNBUF /* or unbuffered... */ 101 jneq 1f 102 tstl _CNT(IOP) /* or a full buffer... */ 103 jgtr 2f 1041: 105 pushl IOP /* ... flush the buffer */ 106 calls $1,_fflush 107 tstl r0 108 jlss Lerror 1092: 110 111 /* 112 * Fix up buffering again. 113 */ 114Lfixup: 115 tstw UNBUF 116 jeql 1f 117 bisw2 $NBF,_FLAG(IOP) /* Reset flag */ 118 clrl _BASE(IOP) /* Clear data structure */ 119 clrl _BUFSIZ(IOP) 120 clrl _CNT(IOP) 1211: 122 cvtbl $NL,r0 /* Compatibility hack */ 123 ret 124 125 /* 126 * We didn't find the null -- loop. 127 */ 128Lagain: 129 movc3 COUNT,(S),*_PTR(IOP) /* Copy the data */ 130 movl r1,S 131 movl r3,_PTR(IOP) /* Fix up IOP */ 132 subl2 COUNT,_CNT(IOP) 133 pushl IOP /* The buffer is full -- flush it */ 134 calls $1,_fflush 135 tstl r0 136 jlss Lerror 137 tstb (S) /* More data? */ 138 jneq Lloop 139 jbr Lfixup 140 141 /* 142 * Bomb out. Return 0 (why not? that's what the old one did). 143 */ 144Lerror: 145 clrl r0 146 ret 147