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