10 /* eqn input stream */
12 struct ein
*prev
; /* previous buffer */
13 char *buf
; /* input buffer; NULL for stdin */
14 int pos
; /* current position in buf */
15 int unbuf
[LNLEN
]; /* push-back buffer */
17 char *args
[NARGS
]; /* macro arguments */
18 int call
; /* is a macro call */
21 static struct ein ein_stdin
; /* the default input stream */
22 static struct ein
*ein
= &ein_stdin
;
24 static char *in_strdup(char *s
)
26 char *d
= malloc(strlen(s
) + 1);
31 /* push buf in the input stream; this is a macro call if args is not NULL */
32 static void in_push(char *buf
, char **args
)
34 struct ein
*next
= malloc(sizeof(*next
));
36 memset(next
, 0, sizeof(*next
));
38 next
->buf
= in_strdup(buf
);
39 next
->call
= args
!= NULL
;
41 for (i
= 0; i
< NARGS
; i
++)
42 next
->args
[i
] = args
[i
] ? in_strdup(args
[i
]) : NULL
;
46 /* back to the previous ein buffer */
47 static void in_pop(void)
49 struct ein
*prev
= ein
->prev
;
52 for (i
= 0; i
< NARGS
; i
++)
60 /* read the next character */
65 return ein
->unbuf
[--ein
->uncnt
];
68 if (ein
->buf
[ein
->pos
])
69 return ein
->buf
[ein
->pos
++];
79 ein
->unbuf
[ein
->uncnt
++] = c
;
87 static struct macro macros
[NMACROS
];
90 static int in_findmacro(char *name
)
93 for (i
= 0; i
< nmacros
; i
++)
94 if (!strcmp(macros
[i
].name
, name
))
100 void in_define(char *name
, char *def
)
102 int idx
= in_findmacro(name
);
103 if (idx
< 0 && nmacros
< NMACROS
)
106 strcpy(macros
[idx
].name
, name
);
107 free(macros
[idx
].def
);
108 macros
[idx
].def
= in_strdup(def
);
112 /* see if name starts with a macro name followed by a '(' */
113 int in_macrocall(char *name
)
116 for (i
= 0; i
< nmacros
; i
++) {
117 mlen
= strlen(macros
[i
].name
);
118 if (!strncmp(macros
[i
].name
, name
, mlen
) && name
[mlen
] == '(')
125 int in_expand(char *name
, char **args
)
127 int i
= in_findmacro(name
);
129 in_push(macros
[i
].def
, args
);
133 /* expand argument */
136 int call
= ein
->call
;
137 if (call
&& ein
->args
[i
- 1])
138 in_push(ein
->args
[i
- 1], NULL
);