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