Пример #1
0
/*
 * sz is size of 'line' buffer in bytes.  Must be reasonably
 * long enough to hold one physical real-world e-mail line.
 */
static int read_one_header_line(char *line, int sz, FILE *in)
{
	int len;

	/*
	 * We will read at most (sz-1) bytes and then potentially
	 * re-add NUL after it.  Accessing line[sz] after this is safe
	 * and we can allow len to grow up to and including sz.
	 */
	sz--;

	/* Get the first part of the line. */
	if (!fgets(line, sz, in))
		return 0;

	/*
	 * Is it an empty line or not a valid rfc2822 header?
	 * If so, stop here, and return false ("not a header")
	 */
	len = eatspace(line);
	if (!len || !is_rfc2822_header(line)) {
		/* Re-add the newline */
		line[len] = '\n';
		line[len + 1] = '\0';
		return 0;
	}

	/*
	 * Now we need to eat all the continuation lines..
	 * Yuck, 2822 header "folding"
	 */
	for (;;) {
		int peek, addlen;
		static char continuation[1000];

		peek = fgetc(in); ungetc(peek, in);
		if (peek != ' ' && peek != '\t')
			break;
		if (!fgets(continuation, sizeof(continuation), in))
			break;
		addlen = eatspace(continuation);
		if (len < sz - 1) {
			if (addlen >= sz - len)
				addlen = sz - len - 1;
			memcpy(line + len, continuation, addlen);
			line[len] = '\n';
			len += addlen;
		}
	}
	line[len] = 0;

	return 1;
}
Пример #2
0
/* extract a (-prefixed url from the input stream.
 * the label is either of the format `<link>`, where I
 * extract until I find a >, or it is of the format
 * `text`, where I extract until I reach a ')' or
 * whitespace.
 */
static char*
linkyurl(MMIOT *f, int *sizep)
{
    int size = 0;
    char *ptr;
    int c;

    if ( (c = eatspace(f)) == EOF )
	return 0;

    ptr = cursor(f);

    if ( c == '<' ) {
	pull(f);
	ptr++;
	if ( (size = parenthetical('<', '>', f)) == EOF )
	    return 0;
    }
    else {
	for ( ; ((c=pull(f)) != ')') && !isspace(c); size++)
	    if ( c == EOF ) return 0;
	if ( c == ')' )
	    shift(f, -1);
    }
    *sizep = size;
    return ptr;
}
Пример #3
0
/* extract a )-terminated title from the input stream.
 */
static char*
linkytitle(MMIOT *f, int *sizep)
{
    int countq=0, qc, c, size;
    char *ret, *lastqc = 0;

    eatspace(f);
    if ( (qc=pull(f)) != '"' && qc != '\'' && qc != '(' )
	return 0;

    if ( qc == '(' ) qc = ')';

    for ( ret = cursor(f); (c = pull(f)) != EOF;  ) {
	if ( (c == ')') && countq ) {
	    size = (lastqc ? lastqc : cursor(f)) - ret;
	    *sizep = size-1;
	    return ret;
	}
	else if ( c == qc ) {
	    lastqc = cursor(f);
	    countq++;
	}
    }
    return 0;
}
Пример #4
0
Файл: tok.c Проект: 8l/myrddin
static Tok *toknext()
{
    Tok *t;
    int c;

    eatspace();
    c = peek();
    if (c == End) {
        t =  mktok(0);
    } else if (c == '\n') {
        curloc.line++;
        next();
        t =  mktok(Tendln);
    } else if (isalpha(c) || c == '_' || c == '$') {
        t =  kwident();
    } else if (c == '"') {
        t =  strlit();
    } else if (c == '\'') {
        t = charlit();
    } else if (isdigit(c)) {
        t =  numlit();
    } else if (c == '@') {
        t = typaram();
    } else {
        t = oper();
    }

    if (!t || t->type == Terror)
        lfatal(curloc, "Unable to parse token starting with %c", c);
    return t;
}
Пример #5
0
static char *cleanup_subject(char *subject)
{
	for (;;) {
		char *p;
		int len, remove;
		switch (*subject) {
		case 'r': case 'R':
			if (!memcmp("e:", subject+1, 2)) {
				subject += 3;
				continue;
			}
			break;
		case ' ': case '\t': case ':':
			subject++;
			continue;

		case '[':
			p = strchr(subject, ']');
			if (!p) {
				subject++;
				continue;
			}
			len = strlen(p);
			remove = p - subject;
			if (remove <= len *2) {
				subject = p+1;
				continue;
			}
			break;
		}
		eatspace(subject);
		return subject;
	}
}
Пример #6
0
/* extract a =HHHxWWW size from the input stream
 */
static int
linkysize(MMIOT *f, Footnote *ref)
{
    int height=0, width=0;
    int whence = mmiottell(f);
    int c;

    if ( isspace(peek(f,0)) ) {
	pull(f);	/* eat '=' */

	for ( c = pull(f); isdigit(c); c = pull(f))
	    width = (width * 10) + (c - '0');

	if ( c == 'x' ) {
	    for ( c = pull(f); isdigit(c); c = pull(f))
		height = (height*10) + (c - '0');

	    if ( isspace(c) )
		c = eatspace(f);

	    if ( (c == ')') || ((c == '\'' || c == '"') && linkytitle(f, c, ref)) ) {
		ref->height = height;
		ref->width  = width;
		return 1;
	    }
	}
    }
    mmiotseek(f, whence);
    return 0;
}
Пример #7
0
void
link(char *e)
{
	char *s, *o;

	s = o = pos;
	while(s < epos){
		if(e != nil && s >= e)
			break;
		if(*s == 0 || strchr("<>[] \t\r\n", *s) != nil)
			break;
		s++;
	}
	if(s-4 >= o)
	if(cistrncmp(s-4, ".png", 4)
	&& cistrncmp(s-4, ".jpg", 4)
	&& cistrncmp(s-4, ".gif", 4)){
		string("<a href=\"");
		escape(s);
		string("\">");
		eatspace();
		if(e != nil && pos < e)
			ebody(e);
		else {
			pos = o;
			escape(s);
		}
		string("</a>");
	} else {
		string("<img src=\"");
		escape(s);
		string("\">");
	}
}
Пример #8
0
/* extract a =HHHxWWW size from the input stream
 */
static int
linkysize(MMIOT *f, int *heightp, int *widthp)
{
    int height=0, width=0;
    int c;

    *heightp = 0;
    *widthp = 0;

    if ( (c = eatspace(f)) != '=' ) 
	return (c != EOF);
    pull(f);	/* eat '=' */

    for ( c = pull(f); isdigit(c); c = pull(f))
	width = (width * 10) + (c - '0');

    if ( c == 'x' ) {
	for ( c = pull(f); isdigit(c); c = pull(f))
	    height = (height*10) + (c - '0');

	if ( c != EOF ) {
	    if ( !isspace(c) ) shift(f, -1);
	    *heightp = height;
	    *widthp = width;
	    return 1;
	}
    }
    return 0;
}
Пример #9
0
/*
 * process embedded links and images
 */
static int
linkylinky(int image, MMIOT *f)
{
    int start = mmiottell(f);
    Cstring name;
    Footnote key, *ref;
		
    int status = 0;

    CREATE(name);
    bzero(&key, sizeof key);

    if ( linkylabel(f, &name) ) {
	if ( peek(f,1) == '(' ) {
	    pull(f);
	    if ( linkyurl(f, image, &key) )
		status = linkyformat(f, name, image, &key);
	}
	else {
	    int goodlink, implicit_mark = mmiottell(f);

	    if ( eatspace(f) == '[' ) {
		pull(f);	/* consume leading '[' */
		goodlink = linkylabel(f, &key.tag);
	    }
	    else {
		/* new markdown implicit name syntax doesn't
		 * require a second []
		 */
		mmiotseek(f, implicit_mark);
		goodlink = !(f->flags & MKD_1_COMPAT);
	    }
	    
	    if ( goodlink ) {
		if ( !S(key.tag) ) {
		    DELETE(key.tag);
		    T(key.tag) = T(name);
		    S(key.tag) = S(name);
		}

		if ( ref = bsearch(&key, T(*f->footnotes), S(*f->footnotes),
					  sizeof key, (stfu)__mkd_footsort) )
		    status = linkyformat(f, name, image, ref);
	    }
	}
    }

    DELETE(name);
    ___mkd_freefootnote(&key);

    if ( status == 0 )
	mmiotseek(f, start);

    return status;
}
Пример #10
0
int
heading(void)
{
	char *o, *s, *e;
	int n;

	for(s = "======"; *s; s++)
		if(got(s))
			break;
	if(*s == 0)
		return 0;
	n = strlen(s);
	e = look("=", look("\n", nil));
	if(e == nil)
		e = look("\n", nil);
	if(e == nil)
		e = epos;
	eatspace();
	string("<h");
	output("0123456"+n, 1);
	string("><a name=\"");
	o = pos;
	s = trimback(e);
	while(pos < s){
		if((*pos >= 'a' && *pos <= 'z')
		|| (*pos >= 'A' && *pos <= 'Z')
		|| (*pos >= '0' && *pos <= '9')
		|| (strchr("!#$%()_+,-./{|}~:;=?@[\\]^_`", *pos) != 0))
			output(pos, 1);
		else if(*pos == ' ' || *pos == '\t')
			output("_", 1);
		else if(*pos == '<')
			string("&lt;");
		else if(*pos == '>')
			string("&gt;");
		else if(*pos == '&')
			string("&amp;");
		else if(*pos == '"')
			string("&quot;");
		else if(*pos == '\'')
			string("&#39;");
		pos++;
	}
	string("\"></a>");
	pos = o;
	ebody(e);
	while(got("="))
		;
	string("</h");
	output("0123456"+n, 1);
	string(">");
	return 1;
}
Пример #11
0
/* look up (or construct) a footnote from the [xxx] link
 * at the head of the stream.
 */
static int
linkykey(int image, Footnote *val, MMIOT *f)
{
    Footnote *ret;
    Cstring mylabel;

    memset(val, 0, sizeof *val);

    if ( (T(val->tag) = linkylabel(f, &S(val->tag))) == 0 )
	return 0;

    eatspace(f);
    switch ( pull(f) ) {
    case '(':
	/* embedded link */
	if ( (T(val->link) = linkyurl(f,&S(val->link))) == 0 )
	    return 0;

	if ( image && !linkysize(f, &val->height, &val->width) )
	    return 0;

	T(val->title) = linkytitle(f, &S(val->title));

	return peek(f,0) == ')';

    case '[':
	/* footnote link */
	mylabel = val->tag;
	if ( (T(val->tag) = linkylabel(f, &S(val->tag))) == 0 )
	    return 0;

	if ( !S(val->tag) )
	    val->tag = mylabel;

	ret = bsearch(val, T(*f->footnotes), S(*f->footnotes),
	               sizeof *val, (stfu)__mkd_footsort);

	if ( ret ) {
	    val->tag = mylabel;
	    val->link = ret->link;
	    val->title = ret->title;
	    val->height = ret->height;
	    val->width = ret->width;
	    return 1;
	}
    }
    return 0;
}
Пример #12
0
int
tag(char *term, char *tag)
{
	char *e;

	if(!got(term))
		return 0;
	if(e = look(term, nil)){
		eatspace();
		string("<"); string(tag); string(">");
		ebody(e);
		string("</"); string(tag); string(">");
		pos += strlen(term);
	} else
		string(term);
	return 1;
}
Пример #13
0
/* see if the quote-prefixed linky segment is actually a title.
 */
static int
linkytitle(MMIOT *f, char quote, Footnote *ref)
{
    int whence = mmiottell(f);
    char *title = cursor(f);
    char *e;
    register int c;

    while ( (c = pull(f)) != EOF ) {
	e = cursor(f);
	if ( c == quote ) {
	    if ( (c = eatspace(f)) == ')' ) {
		T(ref->title) = 1+title;
		S(ref->title) = (e-title)-2;
		return 1;
	    }
	}
    }
    mmiotseek(f, whence);
    return 0;
}
Пример #14
0
/* extract a (-prefixed url from the input stream.
 * the label is either of the format `<link>`, where I
 * extract until I find a >, or it is of the format
 * `text`, where I extract until I reach a ')', a quote,
 * or (if image) a '='
 */
static int
linkyurl(MMIOT *f, int image, Footnote *p)
{
    int c;
    int mayneedtotrim=0;

    if ( (c = eatspace(f)) == EOF )
	return 0;

    if ( c == '<' ) {
	pull(f);
	if ( !(f->flags & MKD_1_COMPAT) )
	    return linkybroket(f,image,p);
	mayneedtotrim=1;
    }

    T(p->link) = cursor(f);
    for ( S(p->link)=0; (c = peek(f,1)) != ')'; ++S(p->link) ) {
	if ( c == EOF )
	    return 0;
	else if ( (c == '"' || c == '\'') && linkytitle(f, c, p) )
	    break;
	else if ( image && (c == '=') && linkysize(f, p) )
	    break;
	else if ( (c == '\\') && ispunct(peek(f,2)) ) {
	    ++S(p->link);
	    pull(f);
	}
	pull(f);
    }
    if ( peek(f, 1) == ')' )
	pull(f);
	
    ___mkd_tidy(&p->link);
    
    if ( mayneedtotrim && (T(p->link)[S(p->link)-1] == '>') )
	--S(p->link);
    
    return 1;
}
Пример #15
0
/* extract a <...>-encased url from the input stream.
 * (markdown 1.0.2b8 compatibility; older versions
 * of markdown treated the < and > as syntactic
 * sugar that didn't have to be there.  1.0.2b8 
 * requires a closing >, and then falls into the
 * title or closing )
 */
static int
linkybroket(MMIOT *f, int image, Footnote *p)
{
    int c;
    int good = 0;

    T(p->link) = cursor(f);
    for ( S(p->link)=0; (c = pull(f)) != '>'; ++S(p->link) ) {
	/* pull in all input until a '>' is found, or die trying.
	 */
	if ( c == EOF )
	    return 0;
	else if ( (c == '\\') && ispunct(peek(f,2)) ) {
	    ++S(p->link);
	    pull(f);
	}
    }

    c = eatspace(f);

    /* next nonspace needs to be a title, a size, or )
     */
    if ( ( c == '\'' || c == '"' ) && linkytitle(f,c,p) )
	good=1;
    else if ( image && (c == '=') && linkysize(f,p) )
	good=1;
    else 
	good=( c == ')' );

    if ( good ) {
	if ( peek(f, 1) == ')' )
	    pull(f);
	    
	___mkd_tidy(&p->link);
    }

    return good;
} /* linkybroket */
Пример #16
0
void
body(void)
{
	char *s;
	int t;

Next:
	if(pos >= epos)
		return;

	if(got("\n") || got("\r\n"))
		indent = -1;
	if(got("\n") || got("\r\n")){
		string("<br>");
		while(got("\n") || got("\r\n"))
			;
	}

	if(indent == -1){
		indent = 0;
		for(;;){
			if(got(" "))
				indent++;
			else if(got("\t")){
				indent += 8;
				indent %= 8;
			}
			else break;
		}

		if(intable && look("||", look("\n", nil)) == nil){
			string("</table>");
			intable = 0;
		}

		string("\n");
		if((indent < inlist) || (indent < inquote))
			return;

		while(indent > 0){
			if(pos >= epos)
				return;
			if(got("*") || got("#")){
				s = pos-1;
				eatspace();
				if(indent > inlist){
					if(*s == '*')
						string("<ul><li>");
					else
						string("<ol><li>");
					t = inlist;
					inlist = indent;
					body();
					inlist = t;
					if(*s == '*')
						string("</li></ul>");
					else
						string("</li></ol>");
				} else {
					string("</li><li>");
					break;
				}
			} else if(indent > inquote){
				string("<blockquote>");
				t = inquote;
				inquote = indent;
				body();
				inquote = t;
				string("</blockquote>");
			} else
				break;
		}

		if(indent == 0){
			if(got("#")){
				if((pos = look("\n", nil)) == nil)
					pos = epos;
				goto Next;
			}
			if(heading())
				goto Next;
			if(got("----")){
				while(got("-"))
					;
				string("<hr>");
				goto Next;
			}
		}
	}

	if(got("`")){
		if(s = look("`", nil)){
			escape(s);
			pos = s+1;
		} else
			string("`");
	}
	else if(got("<")){
		string("<");
		if(s = look(">", nil)){
			s++;
			output(pos, s - pos);
			pos = s;
		}
	}
	else if(got("[")){
		if(s = look("]", nil)){
			link(s);
			pos = s+1;
		} else
			string("[");
	}
	else if(tag("*", "b") ||
		tag("_", "i") ||
		tag("^", "sup") ||
		tag(",,", "sub") ||
		tag("~~", "strike")){
	}
	else if(got("{{{")){
		if(s = look("}}}", nil)){
			if(look("\n", s)){
				string("<pre>");
				escape(s);
				string("</pre>");
			} else {
				string("<tt>");
				escape(s);
				string("</tt>");
			}
			pos = s+3;
		} else
			string("{{{");
	}
	else if(got("||")){
		if(s = look("||", look("\n", nil))){
			eatspace();
			switch(intable){
			case 0:	string("<table>");
				intable++;
			case 1:	string("<tr>");
				intable++;
			}
			string("<td>");
			ebody(s);
			string("</td>");
		} else if(intable){
			string("</tr>");
			intable = 1;
		}
	}
	else if(match("http://"))
		link(nil);
	else if(match("https://"))
		link(nil);
	else if(match("ftp://"))
		link(nil);
	else{
		output(pos, 1);
		pos++;
	}
	goto Next;
}
Пример #17
0
struct compile_error expr_parse(struct input ci, struct expr_environ *env,
			     struct parse_options opts, struct objcode **ocode)
{
	struct compile_error ret;
	struct chain locals = new_chain();
	struct proto_obj outp;
	char *end_ptr;
	int error = -E_OK, prev_stat=NADA, input_counter = 0;
	
	ret = init_ce();
	*ocode = NULL;
	
	end_ptr = ""; /*force an input read ("" != NULL) */
	
	//error = load_expr(&outp, expr);
	error = po_init(&outp, opts.n_args, opts.n_rets);
	
	while (error == -E_OK && end_ptr != NULL) {
		char *startptr = end_ptr;
		data_t tmp_data;
		int tmp_int;
		char *ident = NULL;
		
		if (eatspace(startptr, &end_ptr)) {
			/* do nothing */
		} else if (*startptr == TERM) {
			startptr = end_ptr = get_input(ci);
		} else if (prev_stat == NADA && 
				atodata_load(startptr, &end_ptr, &tmp_data)){
			error = inject_data(&outp, tmp_data);
			prev_stat = NADA;
		} else if (prev_stat == ARG || prev_stat == NCLEAR) {
			if (atoint_load(startptr, &end_ptr, &tmp_int)) {
				if (prev_stat == ARG)
					error = inject_arg(&outp, tmp_int);
				else
					error = inject_nclear(&outp, tmp_int);	
			} else {
				error = -EXPR_EXPECTING_INT;
			}
			prev_stat = NADA;
		} else if (loadtok(&ident, startptr, &end_ptr)) {
			int l_index;
			struct expr_var *tmp_var;
			
			if (prev_stat == NADA) {
				int kwn = strtoKW(ident);
				
				switch (kwn) {
				case KW_VARSET: prev_stat = VARSET; break;
				case KW_ARG: prev_stat = ARG; break;
				case KW_FULLCLEAR:
					error = inject_clear(&outp);
					prev_stat = NADA;
					break;
				case KW_NCLEAR: prev_stat = NCLEAR; break;
				default: /* not a kw */
 				{
				    struct expr_func *tmp_fn;
				    struct expr_const *tmp_const;
				    
				    int l_index;
				    if ((l_index = strtoLocal(&locals, ident )) 
							!= _NO_SUCH_LOCAL) {
					    error = inject_localvar_get(&outp, 
								      l_index);
				    } else if ((tmp_var = strtoVar(&env->vars, 
							    ident)) != NULL) {
					    error = inject_globalvar_get(&outp,
								      tmp_var);
				    } else if ((tmp_fn = strtoFun(env, ident)) 
								   != NULL) {
					    error = inject_fn(&outp, tmp_fn);
				    } else if ((tmp_const = strtoConst(env, 
							     ident)) != NULL) {
					    error = inject_const(&outp, 
								  tmp_const);
				    } else {
					    error = -EXPR_NOSYM;
				    }
				}
				}
			} else {
				if (strtoKW(ident) != NOT_A_KW) {
					if (prev_stat == VARSET)
						error = -EXPR_EXPECTING_VAR;
					else
						error = -EXPR_EXPECTING_VALUE;
				} else if (prev_stat == VARSET) {
				    if ((l_index = strtoLocal(&locals, ident )) 
							!= _NO_SUCH_LOCAL) {
					    error = inject_localvar_set(&outp, 
								      l_index);
				    } else if ((tmp_var = strtoVar(&env->vars, 
							    ident)) != NULL) {
					    error = inject_globalvar_set(&outp,
								      tmp_var);
				    } else {
					    l_index =inject_localvar_setdeclare(
									&outp);
					    if (l_index < 0) {
						    error = l_index;
					    } else {
						    error = ins_local(&locals, 
								ident, l_index);
					    }
				    }
				} else {
					error = -EXPR_NOSYM;
				}
				prev_stat = NADA;
			}
		} else {
			error = -EXPR_NOSYM;
		}
		input_counter += end_ptr - startptr;
		if (error != -E_OK) {
			ret.pos = input_counter;
			ret.lineno = get_lineno(ci);
			ret.type = error;
			if (ident != NULL) {
				ret.fname = ident;
				ident = NULL; /* prevent free() */
			} else {
				ret.fname = strndup(startptr, 
							    end_ptr - startptr);
			}
		}
		free(ident);
	}
	
	{
		char *bad_string;
		switch (ret.type) {
			case -EXPR_ARG_OORANGE:
				ret.n = query_bad_argument(&outp);
				break;
			case -EXPR_FEWARGS:
				ret.n = query_bf_in(&outp);
				ret.m = query_bf_real(&outp);
				break;
			default: /* <-- includes EXPECTING_STH */
				break;
			case -E_OK:
			    {
				int nr = query_excess_rets(&outp);
				
				if (!opts.auto_clear && nr > 0)
					ret.type = -EXPR_MANYVALUES;
				
				if (ret.type != -E_OK)
					ret.n = query_n_rets(&outp);
				else if ((*ocode = po_compile(&outp))==NULL)
					ret.type = query_status(&outp);
			    }
			    break;
		}
			
		if (ret.fname == NULL
		    && (bad_string = query_bad_fname(&outp)) != NULL) {
			ret.fname = strdup(bad_string);
		}
	}
	
	destroy_locals(&locals);
	
	if (*ocode == NULL) {
		po_abort(&outp);
	}
	
	return ret;
}
Пример #18
0
void
work(void){
	int c;
	struct keyw *lptr;
	char *pt;
	int cc;
	int ct;

	while ((c = getch()) != Beof){
		switch (c){
		case '{':
			if ((lptr = lookup(lastlook,p)) != 0){
				if (lptr->type == ELSE)gotelse();
				else if(lptr->type == DO)gotdo();
				else if(lptr->type == STRUCT)structlev++;
			}
			if(++clev >= &ind[CLEVEL-1]){
				fprint(2,"too many levels of curly brackets\n");
				clev = &ind[CLEVEL-1];
			}
			clev->pdepth = 0;
			clev->tabs = (clev-1)->tabs;
			clearif(clev);
			if(strict && clev->tabs > 0)
				putspace(' ',NO);
			putch(c,NO);
			getnl();
			if(keyflag == DATADEF){
				OUT;
			}
			else {
				OUTK;
			}
			clev->tabs++;
			pt = getnext(0);		/* to handle initialized structures */
			if(*pt == '{'){		/* hide one level of {} */
				while((c=getch()) != '{')
					if(c == Beof)error("{");
				putch(c,NO);
				if(strict){
					putch(' ',NO);
					eatspace();
				}
				keyflag = SINIT;
			}
			continue;
		case '}':
			pt = getnext(0);		/* to handle initialized structures */
			if(*pt == ','){
				if(strict){
					putspace(' ',NO);
					eatspace();
				}
				putch(c,NO);
				putch(*pt,NO);
				*pt = '\0';
				ct = getnl();
				pt = getnext(0);
				if(*pt == '{'){
					OUT;
					while((cc = getch()) != '{')
						if(cc == Beof)error("}");
					putch(cc,NO);
					if(strict){
						putch(' ',NO);
						eatspace();
					}
					getnext(0);
					continue;
				}
				else if(strict || ct){
					OUT;
				}
				continue;
			}
			else if(keyflag == SINIT && *pt == '}'){
				if(strict)
					putspace(' ',NO);
				putch(c,NO);
				getnl();
				OUT;
				keyflag = DATADEF;
				*pt = '\0';
				pt = getnext(0);
			}
			outs(clev->tabs);
			if(--clev < ind)clev = ind;
			ptabs(clev->tabs);
			putch(c,NO);
			lbegin = 0;
			lptr=lookup(pt,lastplace+1);
			c = *pt;
			if(*pt == ';' || *pt == ','){
				putch(*pt,NO);
				*pt = '\0';
				lastplace=pt;
			}
			ct = getnl();
			if((dolevel && clev->tabs <= dotabs[dolevel]) || (structlev )
			    || (lptr != 0 &&lptr->type == ELSE&& clev->pdepth == 0)){
				if(c == ';'){
					OUTK;
				}
				else if(strict || (lptr != 0 && lptr->type == ELSE && ct == 0)){
					putspace(' ',NO);
					eatspace();
				}
				else if(lptr != 0 && lptr->type == ELSE){
					OUTK;
				}
				if(structlev){
					structlev--;
					keyflag = DATADEF;
				}
			}
			else {
				OUTK;
				if(strict && clev->tabs == 0){
					if((c=getch()) != '\n'){
						Bputc(output, '\n');
						Bputc(output, '\n');
						unget(c);
					}
					else {
						lineno++;
						Bputc(output, '\n');
						if((c=getch()) != '\n')unget(c);
						else lineno++;
						Bputc(output, '\n');
					}
				}
			}
			if(lptr != 0 && lptr->type == ELSE && clev->pdepth != 0){
				UNBUMP;
			}
			if(lptr == 0 || lptr->type != ELSE){
				clev->iflev = 0;
				if(dolevel && docurly[dolevel] == NO && clev->tabs == dotabs[dolevel]+1)
					clev->tabs--;
				else if(clev->pdepth != 0){
					UNBUMP;
				}
			}
			continue;
		case '(':
			paren++;
			if ((lptr = lookup(lastlook,p)) != 0){
				if(!(lptr->type == TYPE || lptr->type == STRUCT))keyflag=KEYWORD;
				if (strict){
					putspace(lptr->punc,NO);
					opflag = 1;
				}
				putch(c,NO);
				if (lptr->type == IF)gotif();
			}
			else {
				putch(c,NO);
				lastlook = p;
				opflag = 1;
			}
			continue;
		case ')':
			if(--paren < 0)paren = 0;
			putch(c,NO);
			if((lptr = lookup(lastlook,p)) != 0){
				if(lptr->type == TYPE || lptr->type == STRUCT)
					opflag = 1;
			}
			else if(keyflag == DATADEF)opflag = 1;
			else opflag = 0;
			outs(clev->tabs);
			pt = getnext(1);
			if ((ct = getnl()) == 1 && !strict){
				if(dolevel && clev->tabs <= dotabs[dolevel])
					resetdo();
				if(clev->tabs > 0 && (paren != 0 || keyflag == 0)){
					if(join){
						eatspace();
						putch(' ',YES);
						continue;
					} else {
						OUT;
						split = 1;
						continue;
					}
				}
				else if(clev->tabs > 0 && *pt != '{'){
					BUMP;
				}
				OUTK;
			}
			else if(strict){
				if(clev->tabs == 0){
					if(*pt != ';' && *pt != ',' && *pt != '(' && *pt != '['){
						OUTK;
					}
				}
				else {
					if(keyflag == KEYWORD && paren == 0){
						if(dolevel && clev->tabs <= dotabs[dolevel]){
							resetdo();
							eatspace();
							continue;
						}
						if(*pt != '{'){
							BUMP;
							OUTK;
						}
						else {
							*pt='\0';
							eatspace();
							unget('{');
						}
					}
					else if(ct){
						if(paren){
							if(join){
								eatspace();
							} else {
								split = 1;
								OUT;
							}
						}
						else {
							OUTK;
						}
					}
				}
			}
			else if(dolevel && clev->tabs <= dotabs[dolevel])
				resetdo();
			continue;
		case ' ':
		case '\t':
			if ((lptr = lookup(lastlook,p)) != 0){
				if(!(lptr->type==TYPE||lptr->type==STRUCT))
					keyflag = KEYWORD;
				else if(paren == 0)keyflag = DATADEF;
				if(strict){
					if(lptr->type != ELSE){
						if(lptr->type == TYPE){
							if(paren != 0)putch(' ',YES);
						}
						else
							putch(lptr->punc,NO);
						eatspace();
					}
				}
				else putch(c,YES);
				switch(lptr->type){
				case CASE:
					outs(clev->tabs-1);
					continue;
				case ELSE:
					pt = getnext(1);
					eatspace();
					if((cc = getch()) == '\n' && !strict){
						unget(cc);
					}
					else {
						unget(cc);
						if(checkif(pt))continue;
					}
					gotelse();
					if(strict) unget(c);
					if(getnl() == 1 && !strict){
						OUTK;
						if(*pt != '{'){
							BUMP;
						}
					}
					else if(strict){
						if(*pt != '{'){
							OUTK;
							BUMP;
						}
					}
					continue;
				case IF:
					gotif();
					continue;
				case DO:
					gotdo();
					pt = getnext(1);
					if(*pt != '{'){
						eatallsp();
						OUTK;
						docurly[dolevel] = NO;
						dopdepth[dolevel] = clev->pdepth;
						clev->pdepth = 0;
						clev->tabs++;
					}
					continue;
				case TYPE:
					if(paren)continue;
					if(!strict)continue;
					gottype(lptr);
					continue;
				case STRUCT:
					gotstruct();
					continue;
				}
			}
			else if (lbegin == 0 || p > string) 
				if(strict)
					putch(c,NO);
				else putch(c,YES);
			continue;
		case ';':
			putch(c,NO);
			if(paren != 0){
				if(strict){
					putch(' ',YES);
					eatspace();
				}
				opflag = 1;
				continue;
			}
			outs(clev->tabs);
			pt = getnext(0);
			lptr=lookup(pt,lastplace+1);
			if(lptr == 0 || lptr->type != ELSE){
				clev->iflev = 0;
				if(clev->pdepth != 0){
					UNBUMP;
				}
				if(dolevel && docurly[dolevel] == NO && clev->tabs <= dotabs[dolevel]+1)
					clev->tabs--;
/*
				else if(clev->pdepth != 0){
					UNBUMP;
				}
*/
			}
			getnl();
			OUTK;
			continue;
		case '\n':
			if ((lptr = lookup(lastlook,p)) != 0){
				pt = getnext(1);
				if (lptr->type == ELSE){
					if(strict)
						if(checkif(pt))continue;
					gotelse();
					OUTK;
					if(*pt != '{'){
						BUMP;
					}
				}
				else if(lptr->type == DO){
					OUTK;
					gotdo();
					if(*pt != '{'){
						docurly[dolevel] = NO;
						dopdepth[dolevel] = clev->pdepth;
						clev->pdepth = 0;
						clev->tabs++;
					}
				}
				else {
					OUTK;
					if(lptr->type == STRUCT)gotstruct();
				}
			}
			else if(p == string)Bputc(output, '\n');
			else {
				if(clev->tabs > 0 &&(paren != 0 || keyflag == 0)){
					if(join){
						putch(' ',YES);
						eatspace();
						continue;
					} else {
						OUT;
						split = 1;
						continue;
					}
				}
				else if(keyflag == KEYWORD){
					OUTK;
					continue;
				}
				OUT;
			}
			continue;
		case '"':
		case '\'':
			putch(c,NO);
			while ((cc = getch()) != c){
				if(cc == Beof)
					error("\" or '");
				putch(cc,NO);
				if (cc == '\\'){
					putch(getch(),NO);
				}
				if (cc == '\n'){
					outs(clev->tabs);
					lbegin = 1;
					count = 0;
				}
			}
			putch(cc,NO);
			opflag=0;
			if (getnl() == 1){
				unget('\n');
			}
			continue;
		case '\\':
			putch(c,NO);
			putch(getch(),NO);
			continue;
		case '?':
			question = 1;
			gotop(c);
			continue;
		case ':':
			if (question == 1){
				question = 0;
				gotop(c);
				continue;
			}
			putch(c,NO);
			if(structlev)continue;
			if ((lptr = lookup(lastlook,p)) != 0){
				if (lptr->type == CASE)outs(clev->tabs - 1);
			}
			else {
				lbegin = 0;
				outs(clev->tabs);
			}
			getnl();
			OUTK;
			continue;
		case '/':
			if ((cc = getch()) == '/') {
				putch(c,NO);
				putch(cc,NO);
				cpp_comment(YES);
				OUT;
				lastlook = 0;
				continue;
			}
			else if (cc != '*') {
				unget(cc);
				gotop(c);
				continue;
			}
			putch(c,NO);
			putch(cc,NO);
			cc = comment(YES);
			if(getnl() == 1){
				if(cc == 0){
					OUT;
				}
				else {
					outs(0);
					Bputc(output, '\n');
					lbegin = 1;
					count = 0;
				}
				lastlook = 0;
			}
			continue;
		case '[':
			putch(c,NO);
			ct = 0;
			while((c = getch()) != ']' || ct > 0){
				if(c == Beof)error("]");
				putch(c,NO);
				if(c == '[')ct++;
				if(c == ']')ct--;
			}
			putch(c,NO);
			continue;
		case '#':
			putch(c,NO);
			while ((cc = getch()) != '\n'){
				if(cc == Beof)error("newline");
				if (cc == '\\'){
					putch(cc,NO);
					cc = getch();
				}
				putch(cc,NO);
			}
			putch(cc,NO);
			lbegin = 0;
			outs(clev->tabs);
			lbegin = 1;
			count = 0;
			continue;
		default:
			if (c == ','){
				opflag = 1;
				putch(c,YES);
				if (strict){
					if ((cc = getch()) != ' ')unget(cc);
					if(cc != '\n')putch(' ',YES);
				}
			}
			else if(isop(c))gotop(c);
			else {
				if(isalnum(c) && lastlook == 0)lastlook = p;
				if(isdigit(c)){
					putch(c,NO);
					while(isdigit(c=Bgetc(input))||c == '.')putch(c,NO);
					if(c == 'e'){
						putch(c,NO);
						c = Bgetc(input);
						putch(c, NO);
						while(isdigit(c=Bgetc(input)))putch(c,NO);
					}
					Bungetc(input);
				}
				else putch(c,NO);
				if(keyflag != DATADEF)opflag = 0;
			}
		}
	}
}