1 /*********************************************************************************************
2 * ibm1130_fmt.c : interpret tabs in 1130 Assembler or Fortran source
4 * -------------------------------------------------------------------------------------------
6 * These routines are used by ibm1130_cr.c when the user has indicated
7 * that the input text is formatted with tabs. Input lines are edited
8 * into the appropriate column format. Three edit modes are recognized:
11 * Input lines of the form
13 * [label]<whitespace>[opcode]<tab>[tag][L]<tab>[argument]
15 * are rearranged so that the input fields are placed in the appropriate columns
17 * The label must start on the first character of the line. If there is no label,
18 * the first character(s) before the opcode must be whitespace. Following the opcode, there
19 * MUST be a tab character, followed by the format and tag. Following the format and tag
20 * may be exactly one whitespace character, and then starts the argument.
22 * Input lines with * in column 1 and blank lines are turned into Assembler comments,
23 * with the * in the Opcode field.
25 * Assembler directive lines at the beginning of the deck must be preceded by
26 * ! to indicate that they are not comments. For example,
32 * Input lines of the form
34 * [label]<tab>statement
38 * [label]<tab>Xcontinuation
40 * where X is a non alphabetic contination character are rearranged in the
44 * 12345678901234567890...
45 * ------------------------
49 * However, you must take care that you don't end up with statement text after column 72.
51 * Input lines with * or C in column 1 are left alone (comments and directives)
53 * (The ! escape is not used before Fortran directives as before Assembler directives)
56 * Tabs are replaced with spaces. Tab settings are assumed to be eight characters wide,
57 * as is standard for vi, notepad, etc.
58 *********************************************************************************************/
65 #include "ibm1130_fmt.h"
67 #define MAXLINE 81 /* maximum output line size */
68 #define WORKSZ 256 /* size for tab work area */
69 #define TAGOFFSET 12 /* offset for tag field */
70 #define FMTOFFSET 11 /* offset for format field */
72 #define MIN(a,b) ((a < b) ? a : b)
73 #define AMSG " with Assembler Reformat"
74 #define FMSG " with FORTRAN Reformat"
75 #define AFORMAT "%20.20s%-60.60s"," "
76 #define ACOMMENTFMT "%20.20s%-60.60s"," "
77 #define ABLANKLINE "%20.20s*"," "
78 #define FFORMAT "%-5.5s %-74.74s"
79 #define FCONTFMT "%-5.5s%-75.75s"
81 char gszLabel
[6]; /* work area for label */
82 char gszArg
[MAXLINE
]; /* .. argument */
83 char gszOutput
[MAXLINE
]; /* .. output */
84 short gaiAsmTabs
[] = {7,12,15,20,25,30,35,40,45,52,0};/* tab stops for assembler */
86 short gaiPlainTabs
[] = {9, 17, 25, 33, 41, 49, 57, 65, 73, 0};/* tab stops for just plain tabs */
92 /*************************************************
93 * ExpandTabs: Expand tabs to spaces
96 char* ExpandTabs(char* p_szInbuf
, /* expand tabs .. input buffer */
97 char* p_szOutbuf
, /* .. output buffer */
98 short* p_aiTabs
) /* .. array of tab stops (1 based) -- 0 end of array */
100 short iI
, /* input position */
101 iO
, /* output position */
102 iT
; /* next tab stop */
104 char cX
; /* character to test */
106 iI
= 0; /* init input position */
107 iO
= 0; /* init output position */
108 iT
= 0; /* init tab stop */
110 while ((cX
= *(p_szInbuf
+ iI
)) != 0) /* while there are characters */
112 if (cX
== '\t') /* q. tab character? */
114 while ((p_aiTabs
[iT
] <= iO
+ 1) /* search for next valid stop .. */
115 && (p_aiTabs
[iT
] != 0)) /* .. or end of table */
116 iT
++; /* .. go to next tab */
118 if (p_aiTabs
[iT
] != 0) /* q. end of tab array? */
120 while (iO
< (p_aiTabs
[iT
] - 1)) /* fill to tab with blanks */
121 *(p_szOutbuf
+ iO
++) = ' '; /* .. put in a blank */
124 else /* Otherwise ... */
125 *(p_szOutbuf
+ iO
++) = ' '; /* .. Translate to blank */
127 else /* Otherwise .. not tab */
128 *(p_szOutbuf
+ iO
++) = cX
; /* .. save the input char */
130 iI
++; /* next input character */
133 *(p_szOutbuf
+ iO
) = 0; /* end the string.. */
134 return p_szOutbuf
; /* .. return output area addr */
137 /*************************************************
138 * extract next token, modify pointer
141 char* GetToken(char* p_szOut
, /* output location */
142 int p_iLen
, /* max output length */
143 char**p_pszToken
) /* pointer to input token */
145 int iI
; /* work integer */
146 char* pszX
; /* work pointer */
148 pszX
= *p_pszToken
; /* get pointer to token */
150 for (iI
= 0; *(pszX
+ iI
) && (!isspace(*(pszX
+ iI
)));) /* while not whitespace & not end */
151 iI
++; /* .. count token length */
153 memset(p_szOut
, 0, p_iLen
); /* zero out output area */
155 if (iI
> 0) /* q. any chars? */
156 strncpy(p_szOut
, *p_pszToken
, MIN(iI
, p_iLen
-1)); /* a. yes.. copy max of p_iLen-1 */
158 *p_pszToken
+= iI
; /* point beyond token */
159 return p_szOut
; /* .. return token pointer */
162 /*************************************************
163 * EditToAsm - convert tab-formatted text line to 1130 Assembler format
166 char *EditToAsm (char* p_pszEdit
) /* convert line to 1130 assembler */
168 char pszLine
[MAXLINE
]; /* source line */
169 char pszWork
[WORKSZ
]; /* work buffer */
170 char acTFWrk
[2]; /* tag/format work area */
171 size_t iI
; /* work integer */
173 if (p_pszEdit
== NULL
) /* q. null request? */
174 return AMSG
; /* a. yes .. return display message */
176 if (*p_pszEdit
== '!') /* leave lines starting with ! alone */
177 return EditToWhitespace(p_pszEdit
+1);
179 if (*p_pszEdit
== '*') /* q. comment line? */
181 strncpy(pszWork
, EditToWhitespace(p_pszEdit
), MAXLINE
); /* .. convert any tabs */
182 sprintf(gszOutput
, ACOMMENTFMT
, pszWork
); /* .. put the comment out there in the opcode column */
183 return gszOutput
; /* .. and return it */
186 strncpy(pszLine
, p_pszEdit
, MAXLINE
-1); /* copy the line local */
188 ExpandTabs(pszLine
, pszWork
, gaiAsmTabs
); /* expand the tabs */
189 strncpy(pszLine
, pszWork
, MAXLINE
-1); /* copy the line back */
191 for (iI
= strlen(pszLine
); iI
--;) /* trim trailing whitespace */
193 if (*(pszLine
+ iI
) <= ' ') /* q. space or less? */
194 *(pszLine
+ iI
) = 0; /* a. yes .. remove it */
196 break; /* .. done. Leave loop. */
199 if (strlen(pszLine
) == 0) /* q. blank line? */
200 { /* a. yes .. Assembler abhors these so */
201 sprintf(gszOutput
, ABLANKLINE
); /* format as comment statement */
202 return gszOutput
; /* .. and return it */
206 /* TODO: Add code to process a strip switch
210 if (strlen(pszLine
) > (TAGOFFSET
+ 1)) /* q. line long enough? */
211 { /* a. yes.. reorder tag/format */
212 memcpy(acTFWrk
, pszLine
+ FMTOFFSET
, 2); /* get tag/format */
213 memset((pszLine
+ FMTOFFSET
), ' ', 2); /* .. blank 'em out */
215 for (iI
= 0; iI
< 2; iI
++)
216 if (isalpha(acTFWrk
[iI
])) /* q. alpha char? */
217 *(pszLine
+ FMTOFFSET
) = acTFWrk
[iI
]; /* a. yes .. make it format */
218 else if (isdigit(acTFWrk
[iI
])) /* q. digit? */
219 *(pszLine
+ TAGOFFSET
) = acTFWrk
[iI
]; /* a. yes .. make it the tag */
222 sprintf(gszOutput
, AFORMAT
, pszLine
); /* format the line */
224 return gszOutput
; /* return formatted line */
227 /*************************************************
228 * EditToFortran - convert tab-formatted input text line to FORTRAN format
232 char *EditToFortran(char* p_pszEdit
) /* convert line to 1130 assembler */
234 char pszLine
[MAXLINE
]; /* source line */
235 char* pszWork
; /* work pointer */
236 size_t iI
; /* work integer */
237 int bContinue
; /* true if continue */
239 if (p_pszEdit
== NULL
) /* q. null request? */
240 return FMSG
; /* a. yes .. return display message */
242 if (strchr(p_pszEdit
, '\t') == NULL
) /* q. no tab in the line? */
243 return p_pszEdit
; /* a. nope, return line as is, assume it's formatted correctly */
245 if (*p_pszEdit
== 'C' || *p_pszEdit
== '*' || *p_pszEdit
== '\0') /* q. comment or directive or blank line? */
246 { /* a. yes.. don't restructure */
247 return EditToWhitespace(p_pszEdit
);
250 strncpy(pszLine
, p_pszEdit
, MAXLINE
-1); /* copy the line local */
252 for (iI
= strlen(pszLine
); iI
--;) /* trim trailing whitespace */
254 if (*(pszLine
+ iI
) <= ' ') /* q. space or less? */
255 *(pszLine
+ iI
) = 0; /* a. yes .. remove it */
257 break; /* .. done. Leave loop. */
261 * TODO: Add code to process a strip switch
265 pszWork
= (char*) pszLine
; /* set pointer to line */
266 GetToken(gszLabel
, 6, &pszWork
); /* get the line, if any. */
268 pszWork
++; /* skip tab/whitespace */
270 /* continuation... */
271 bContinue
= ((isdigit(*pszWork
) && (*pszWork
!= '0')) /* if first char non-zero digit */
272 || (!isspace(*pszWork
) && !isalpha(*pszWork
))); /* .. or non-alpha non-blank */
274 memset(gszArg
, 0, MAXLINE
); /* .. and arguments */
276 strncpy(gszArg
, pszWork
, 75); /* copy rest to argument */
278 sprintf(gszOutput
, (bContinue
) ? FCONTFMT
: FFORMAT
, /* format the line */
279 gszLabel
, /* .. statement # */
280 gszArg
); /* .. code */
282 return gszOutput
; /* return formatted line */
285 /*************************************************
286 * EditToWhitespace - expand tabs at 8 space intervals.
289 char* EditToWhitespace(char *p_pszEdit
)
291 int iI
; /* work integer */
292 char pszLine
[MAXLINE
]; /* source line */
293 char pszWork
[WORKSZ
]; /* work buffer */
295 if (p_pszEdit
== NULL
) /* q. null request? */
296 return AMSG
; /* a. yes .. return display message */
298 strncpy(pszLine
, p_pszEdit
, MAXLINE
-1); /* copy the line local */
300 ExpandTabs(pszLine
, pszWork
, gaiPlainTabs
); /* expand the tabs */
301 strncpy(gszOutput
, pszWork
, MAXLINE
-1); /* copy the line back */
303 for (iI
= strlen(gszOutput
); iI
--;) /* look at each character */
305 if (*(gszOutput
+ iI
) <= ' ') /* q. space or less? */
306 *(gszOutput
+ iI
) = 0; /* a. yes .. remove it */
308 break; /* .. done. Leave loop. */
312 return gszOutput
; /* ... return buffer */