1 /*****************************************************************************
2 
3 	ExeA()
4 
5 	This function executes an A command.
6 
7 	A	Appends the next page of the input file to the contents
8 		of the text buffer, thus combining the two pages of
9 		text on a single page with no intervening form feed
10 		character.  This command takes no argument.  To perform
11 		n Appends, use the n<A> construct.  Note that nA is a
12 		completely different command.
13 
14 	:A	Equivalent to the A command except that a value is
15 		returned.  -1 is returned if the append succeeded, and
16 		0 is returned if the append failed because the
17 		end-of-the-input-file had previously been reached (^N
18 		flag is -1 at start of this command).
19 
20 	n:A	Appends n lines of text from the input file to the
21 		contents of the text buffer.  The value of n must not
22 		be negative.  A value is returned indicating whether or
23 		not there were in fact n lines remaining in the input
24 		file.  -1 is returned if the command succeeded.  0 is
25 		returned if end-of-file on the input file was
26 		encountered before all n lines were read in.  Note that
27 		the command can succeed and yet read in fewer than n
28 		lines in the case that the text buffer fills up.
29 
30 	nA	Equivalent to the ASCII code for the .+n+1th character
31 		in the buffer (that is, the character to the right of
32 		buffer pointer position .+n). The expression -1A is
33 		equivalent to the ASCII code of the character
34 		immediately preceding the pointer and 0A is equivalent
35 		to the ASCII code of the character immediately
36 		following the pointer (the current character). If the
37 		character position referenced lies outside the bounds
38 		of the text buffer, this command returns a -1.
39 
40 *****************************************************************************/
41 
42 #include "zport.h"		/* define portability identifiers */
43 #include "tecoc.h"		/* define general identifiers */
44 #include "defext.h"		/* define external global variables */
45 #include "deferr.h"		/* define identifiers for error messages */
46 
ExeA()47 DEFAULT ExeA()			/* execute an A command */
48 {
49     BOOLEAN		EBfFul;
50     unsigned char	TmpChr;
51     BOOLEAN		ColonMod;
52 
53     DBGFEN(1,"ExeA",NULL);
54 
55     ColonMod = (CmdMod & COLON);		/* is it :A or n:A */
56     CmdMod &= ~COLON;				/* clear : flag */
57 
58 /*
59  * if we have a numeric argument, it's nA or n:A
60  */
61 
62     if (EStTop > EStBot) {			/* if numeric argument */
63         UMinus();				/* if it's -A, make it -1A */
64 	if (GetNmA() == FAILURE) {		/* get numeric argument */
65 	    DBGFEX(1,DbgFNm,"FAILURE, GetNmA() failed");
66 	    return FAILURE;
67 	}
68 
69 	if (ColonMod) {				/* if it's n:A */
70 	    if (NArgmt < 1) {
71 	        ErrMsg(ERR_IPA);
72 		DBGFEX(1,DbgFNm,"FAILURE, n:A, n < 1");
73 		return FAILURE;
74 	    }
75 	    while (NArgmt-- > 0) {
76 	        EBfFul = FALSE;
77 		if (RdLine(&EBfFul) == FAILURE) {
78 		    DBGFEX(1,DbgFNm,"FAILURE, RdLine() failed");
79 		    return FAILURE;
80 		}
81 		if (EBfFul) {
82 		    break;
83 		}
84 		if (IsEofI[CurInp]) {		/* if end-of-file */
85 		    DBGFEX(1,DbgFNm,"PushEx(0)");
86 		    return PushEx(0L, OPERAND);
87 		}
88 	    }
89 	    DBGFEX(1,DbgFNm,"PushEx(-1)");
90 	    return PushEx(-1L, OPERAND);
91 	}
92 
93 /*
94  * it's nA
95  */
96 	if (NArgmt < 0) {
97 	    if ((GapBeg+NArgmt) < EBfBeg) {
98 	        DBGFEX(1,DbgFNm,"PushEx(-1)");
99 		return PushEx(-1L, OPERAND);
100 	    }
101 	    TmpChr = *(GapBeg+NArgmt);
102 	} else {
103 	    if ((GapEnd+NArgmt+1) > EBfEnd) {
104 	        DBGFEX(1,DbgFNm,"PushEx(-1)");
105 		return PushEx(-1L, OPERAND);
106 	    }
107 	    TmpChr = *(GapEnd+NArgmt+1);
108 	}
109 #if DEBUGGING
110 	sprintf(DbgSBf,"PushEx(%d)", TmpChr);
111 	DbgFEx(1,DbgFNm,DbgSBf);
112 #endif
113 	return PushEx((LONG)TmpChr, OPERAND);
114     }
115 
116 /*
117  * if there is no numeric argument, must be A or :A
118  */
119 
120     if (IsEofI[CurInp]) {			/* if already at end-of-file */
121         DBGFEX(1,DbgFNm,(ColonMod) ? "PushEx(0)" : "SUCCESS");
122 	return ((ColonMod) ? PushEx(0L,OPERAND) : SUCCESS);
123     }
124 
125     if (RdPage() == FAILURE) {			/* read a page */
126         DBGFEX(1,DbgFNm,"FAILURE, RdPage() failed");
127 	return FAILURE;
128     }
129 
130     DBGFEX(1,DbgFNm,(ColonMod) ? "PushEx(-1)" : "SUCCESS");
131     return (ColonMod) ? PushEx(-1L, OPERAND) : SUCCESS;
132 }
133