#include <stdio.h>

#define	IN_CODE		0	/* Not in any comment or string */
#define	IN_PS_COMMENT	1	/* Inside a comment beginning with "(*" */
#define	IN_CB_COMMENT	2	/* Inside a comment beginning with "{" */
#define	IN_QUOTE	3	/* Inside a quoted string */

main(argc, argv)
int	argc;
char	*argv[];
{
if (argc < 2 || 3 < argc) {
	fprintf(stderr, "Usage: %s modula_file [output_file]\n", argv[0]);
	exit(-1);
	}
if (freopen(argv[1], "r", stdin) == NULL) {
	perror(argv[1]);
	exit(-2);
	}
if (argc == 3 && freopen(argv[2], "w", stdout) == NULL) {
	perror(argv[2]);
	exit(-3);
	}
return(scan(0, IN_CODE));
}

scan(depth, state)
int		depth;
register int	state;
{
register int	c1, c2;

for (;;) {
	if ((c1 = getchar()) == EOF) {
		if (depth != 0)
			fputs("Unexpected EOF\n", stderr);
		return(depth);
		}
	if (state == IN_QUOTE) {
		putchar(c1);
		if (c1 == '\'')
			state = IN_CODE;
		}
	else switch (c1) {
		case '\'':
			if (state != IN_CODE)
				goto DEFAULT;
			state = IN_QUOTE;
			putchar(c1);
			break;

		case '(':
			if ((c2 = getchar()) == EOF) {
				if (depth != 0)
					fputs("Unexpected EOF\n", stderr);
				return(depth);
				}
			if (c2 == '*')
				scan(depth + 1, IN_PS_COMMENT);
			else {
				ungetc(c2, stdin);
				goto DEFAULT;
				}
			break;

		case '{':
			scan(depth + 1, IN_CB_COMMENT);
			break;

		case '*':
			if (state != IN_PS_COMMENT)
				goto DEFAULT;
			if ((c2 = getchar()) == EOF) {
				if (depth != 0)
					fputs("Unexpected EOF\n", stderr);
				return(depth);
				}
			if (c2 != ')') {
				ungetc(c2, stdin);
				goto DEFAULT;
				}
			return(0);

		case '}':
			if (state != IN_CB_COMMENT)
				goto DEFAULT;
			return(0);

		default:
		DEFAULT:
			if (state == IN_CODE || c1 == '\n')
				putchar(c1);
			break;
		}
	}
}
