da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* Copyright (c) 1986-2009 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Glenn Fowler
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Research
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * convert C prototypes to ANSI, K&R and C++ styles or K&R to ANSI
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * slips into the pp block read
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * define PROTOMAIN for standalone proto
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * PROTOMAIN is coded for minimal library support
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic const char id[] = "\n@(#)$Id: proto (AT&T Research) 2008-05-11 $\0\n";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define MAGICARG "prototyped" /* proto magic directive arg */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define MAGICOFF "noticed" /* no notice if found in pragma */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define NOTICED "Copyright" /* no notice if found in magic */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define PUBLICDOMAIN "Public Domain" /* no notice if found in magic */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* output buffer */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* slide buffer */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* input buffer */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * proto is separate from pp so these undef's are ok
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define RESERVED(b,e,n) ((((long)(b))<<16)|(((long)(e))<<8)|((long)(n)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * generate integer
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * pointer to end returned
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register long d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * namespace pollution forces us to claim parts of libc
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * environmentally safe strlen()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char* b;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (b = s; *s; s++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return s - b;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * environmentally safe strncmp()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsstrncmp(register const char* s, register char* t, register int n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char* e = s + n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (s < e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*s != *t || !*s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return *s - *t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * strcpy() except pointer to end returned
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*s++ = *t++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return s - 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct proto* proto = (struct proto*)(iob - sizeof(struct proto));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = '"';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = '"';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = ',';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = ':';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = '\n';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * memcpy() but pointer to end returned
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* e = t + n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (t < e) *s++ = *t++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * generate line sync
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * pointer to end returned
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinlinesync(register struct proto* proto, register char* p, register long n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = '\n';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * output init header
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * pointer to end returned
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if !defined(__PROTO__)\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# if defined(__STDC__) || defined(__cplusplus) || defined(_proto) || defined(c_plusplus)\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# if defined(__cplusplus)\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define __LINKAGE__ \"C\"\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define __LINKAGE__\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define __STDARG__\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define __PROTO__(x) x\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define __OTORP__(x)\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define __PARAM__(n,o) n\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# if !defined(__STDC__) && !defined(__cplusplus)\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# if !defined(c_plusplus)\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define const\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define signed\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define void int\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define volatile\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define __V_ char\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define __V_ void\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define __PROTO__(x) ()\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define __OTORP__(x) x\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define __PARAM__(n,o) o\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define __LINKAGE__\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define __V_ char\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define const\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define signed\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define void int\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define volatile\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define __MANGLE__ __LINKAGE__\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# if defined(__cplusplus) || defined(c_plusplus)\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define __VARARG__ ...\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define __VARARG__\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# if defined(__STDARG__)\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define __VA_START__(p,a) va_start(p,a)\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define __VA_START__(p,a) va_start(p)\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# if !defined(__INLINE__)\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# if defined(__cplusplus)\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define __INLINE__ extern __MANGLE__ inline\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# if defined(_WIN32) && !defined(__GNUC__)\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define __INLINE__ __inline\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if !defined(__LINKAGE__)\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define __LINKAGE__ /* 2004-08-11 transition */\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if !defined(__PROTO__)\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <prototyped.h>\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if !defined(__LINKAGE__)\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define __LINKAGE__ /* 2004-08-11 transition */\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef __MANGLE_%_DATA__\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifdef _BLD_%\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifdef __EXPORT__\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define __MANGLE_%_DATA__ __MANGLE__ __EXPORT__\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define __MANGLE_%_DATA__ __MANGLE__\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define __MANGLE_%_FUNC__ __MANGLE__\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifdef __IMPORT__\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define __MANGLE_%_DATA__ __MANGLE__ __IMPORT__\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define __MANGLE_%_DATA__ __MANGLE__\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define __MANGLE_%_FUNC__ __MANGLE__\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (*op++ = *s++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define CACHE() do{CACHEIN();CACHEOUT();call=proto->call;}while(0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define SYNC() do{SYNCIN();SYNCOUT();proto->flags&=~(EXTERN|INIT|OTHER|VARIADIC|VARIADIC2);proto->flags|=flags&(EXTERN|INIT|OTHER|VARIADIC|VARIADIC2);proto->call=call;}while(0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * advance to the next non-space character
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * update directive mask
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (*(s = nns(s)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (*++s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the tokenizer
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * top level calls loop until EOB
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * recursive calls just return the next token
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (state > 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (op > proto->ob && *(op - 1) == '=' && (op == proto->ob + 1 || *(op - 2) != '=')) switch (c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\n':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((flags & (DECLARE|GLOBAL|RECURSIVE)) == GLOBAL && (proto->flags & MORE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *(ip + n) = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* NOTE: RECURSIVE lex() should really SLIDE too */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (n = 0, t = qe + 1; t < op && (*t == ' ' || *t == '\t' || *t == '\n' && ++n || *t >= 'A' && *t <= 'Z' || *t == '_'); t++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (qn > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (qn > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((flags & EXTERN) && *proto->tp == 's' && !strncmp(proto->tp, "static", 6))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*proto->tp == '_' && !strncmp(proto->tp, "__STDPP__directive", 6)) c = '#';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (op != proto->ob && LASTOUT() != ' ' && LASTOUT() != '\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags &= ~(DEFINE|DIRECTIVE|IDID|INDIRECT|JUNK|MATCH|SHARP|TYPEDEF);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin op = strcopy(om, "#if defined(__STDC__) || defined(__STDPP__)\n");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while ((c = *ip) >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z' || c >= '0' && c <= '9' || c == '_') *op++ = *ip++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags &= ~(DEFINE|DIRECTIVE|IDID|INDIRECT|MATCH|OTHER|SHARP|SKIP|TOKENS|TYPEDEF);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (paren == 0 && (flags & (MATCH|RECURSIVE|SKIP|SLIDE)) == SLIDE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(flags & DECLARE)) switch (RESERVED(*proto->tp, *(ip - 1), ip - proto->tp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(flags & RECURSIVE) && (flags & (DIRECTIVE|TOKENS)) != DIRECTIVE && !strncmp(proto->tp, "else", 4))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(flags & RECURSIVE) && !strncmp(proto->tp, "for", 3))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!strncmp(proto->tp, "inline", 6) && !(flags & (MATCH|SKIP|TOKENS|TYPEDEF)) && proto->brace == 0 && paren == 0 && group == 0 && (last == ';' || last == '}' || last == '\n' || last == 0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(flags & RECURSIVE) && !strncmp(proto->tp, "return", 6))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((proto->options & EXTERNALIZE) && !strncmp(proto->tp, "static", 6))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(flags & RECURSIVE) && !strncmp(proto->tp, "typedef", 7))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*ip == '(' && !strncmp(proto->tp, "va_start", 8)) c = T_VA_START;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (flags & (CLASSIC|PLUSONLY|INIT_DEFINE|INIT_INCLUDE)) c = T_VOID;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(flags & RECURSIVE) && !strncmp(proto->tp, "while", 5))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (op > proto->ob && (*(op - 1) == ' ' || *(op - 1) == '\t'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == '\\')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(n = GETCHR()))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n == '\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (paren++ == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (m = ip - 2; m > im && (*m == ' ' || *m == '\t'); m--);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if ((flags & MATCH) && sub == 1 && *nns(ip) != '*')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (--paren == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (proto->brace == 0 && paren == 0 && last != '=' && (flags & (CLASSIC|DECLARE|DIRECTIVE|MATCH|PLUSONLY|SKIP|TOKENS)) == (MATCH|TOKENS) && ((dir & DIR) != DIR_en || ((dir>>2) & DIR) != DIR_if))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*ip == 'l' && *++ip == 'i' && *++ip == 'n' && *++ip == 'e')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*ip == 'i' && *++ip == 'n' && *++ip == 'c' && *++ip == 'l' && *++ip == 'u' && *++ip == 'd' && *++ip == 'e')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*ip++ == '<' && *ip++ == 's' && *ip++ == 't' && *ip++ == 'd' && *ip++ == 'a' && *ip++ == 'r' && *ip++ == 'g' && *ip++ == '.' && *ip++ == 'h' && *ip++ == '>')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinif !defined(va_start)\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if defined(__STDARG__)\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <stdarg.h>\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <varargs.h>\n\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (*ip == 'd' && *++ip == 'e' && *++ ip == 'f' && *++ip == 'i' && *++ip == 'n' && *++ip == 'e' && (*++ip == ' ' || *ip == '\t'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*ip == 'e' && *++ip == 'x' && *++ ip == 't' && *++ip == 'e' && *++ip == 'r' && *++ip == 'n' && (*++ip == ' ' || *ip == '\t'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*t == 'e' && *++t == 'x' && *++ t == 't' && *++t == 'e' && *++t == 'r' && *++t == 'n' && (*++t == ' ' || *t == '\t' || *t == '\n' || *t == '\r'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (*ip == 'u' && *++ip == 'n' && *++ ip == 'd' && *++ip == 'e' && *++ip == 'f' && (*++ip == ' ' || *ip == '\t'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*ip == 'e' && *++ip == 'x' && *++ ip == 't' && *++ip == 'e' && *++ip == 'r' && *++ip == 'n' && (*++ip == ' ' || *ip == '\t' || *ip == '\n' || *ip == '\r'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *v++ = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin proto_error((char*)proto + sizeof(struct proto), 2, op, NiL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*UNDENT...*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (e > v && (*(e - 1) == ' ' || *(e - 1) == '\t')) e--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (--e >= v)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *--t = *e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*...INDENT*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*v != ' ')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *v = *(v - 4);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*v == ' ')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *v++ = '*';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *v = '\t';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (e > v)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *e = *(e - 1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *v = *(v - 7);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*UNDENT...*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (op > om && ((c = *(op - 1)) == '(' || c == ')' || c == '[' || c == ']'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (v < m)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (m < e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*--e != ' ');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin proto_error((char*)proto + sizeof(struct proto), 1, "function pointer argument prototype omitted", NiL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if ((flags & EXTERN) && (op == om || *(op - 1) == ' ') && *ie == 'r' && !strncmp(ie, "register", 8) && (*(ie + 8) == ' ' || *(ie + 8) == '\t' || *(ie + 8) == '\n'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*...INDENT*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if ((flags & (MATCH|PLUSONLY|SKIP|TOKENS)) == (MATCH|TOKENS))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((vc = ie - im + 1) > sizeof(proto->variadic)) vc = sizeof(proto->variadic);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (--paren == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (flags & EXTERNALIZE) memcpy(proto->ox, "extern", 6);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if (paren == 0 && (flags & (INIT|MATCH|SKIP)) == MATCH)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (last == ')' && proto->brace && (group != 2 || call != 2)) flags |= SKIP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (paren == 0 && (flags & DECLARE)) *(op - 1) = c = ';';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (paren == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((flags & (DECLARE|INDIRECT)) == INDIRECT && aim && aie < im)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (aie < ip && (*aie == ' ' || *aie == '\t' || *aie == '\n')) aie++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (v < aie)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*v++ == ')') break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (v < aie && (*v == ' ' || *v == '\t' || *v == '\n')) v++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else n = 11;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (v >= ko + n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *v = *(v - n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while ((x = *(op - 14)) >= 'A' && x <= 'Z' || x >= 'a' && x <= 'z' || x >= '0' && x <= '9' || x == '_')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!(flags & TOKENS)) op = strcopy(om, "(__VARARG__)");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (flags & EXTERNALIZE) memcpy(proto->ox, "extern", 6);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == ';')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (paren == 1 && group == 1 && !(flags & (IDID|MANGLE))) flags |= TOKENS|OTHER;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (paren == 0 && (flags & (DECLARE|VARIADIC)) == DECLARE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = e - m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*bp == 'r' && !strncmp(bp, "register", 8) && (*(bp + 8) == ' ' || *(bp + 8) == '\t')) bp += 9;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (--paren == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*bp == 'r' && !strncmp(bp, "register", 8) && (*(bp + 8) == ' ' || *(bp + 8) == '\t')) bp += 9;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (proto->brace == 0 && !(flags & DECLARE)) flags |= SKIP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if ((flags & SKIP) || c == T_ID || c == T_VOID) call++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;; op--)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while ((c = *--t) >= '0' && c <= '9' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*t == '.')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(n & 01))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while ((c = *--t) >= '0' && c <= '9' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*t == '.')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n & 01)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n & 02)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while ((c = *--m) >= '0' && c <= '9' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((flags & CLASSIC) && paren == 0 && group <= 2) flags |= SKIP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((flags & (EXTERN|MATCH)) == (EXTERN|MATCH) && ((flags & (DIRECTIVE|SKIP)) || proto->brace || c != '(' && c != ')' && c != '*' && c != T_ID))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == '#') for (t = ip; *t == ' ' || *t == '\t'; t++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else t = "";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*t++ == 'i' && *t++ == 'f' && *t++ == 'n' && *t++ == 'd' && *t++ == 'e' && *t++ == 'f')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*t != '_')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * close a proto buffer stream
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct proto* proto = (struct proto*)(iob - sizeof(struct proto));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((char*)proto); /* some ANSI cc's botch the free() prototype */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * open a new proto buffer stream
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * read buffer pointer returned
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * 0 returned on error or if no magic
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * file !=0 file path to open, otherwise use fd
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * fd open file fd if file==0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * notice !=0 copyright notice info commented at the top
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * options !=0 additional notice name=value pairs, space or ; separated
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * package !=0 generate header for this package
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinpppopen(char* file, int fd, char* notice, char* options, char* package, char* comment, int flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register long n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int pragma;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int m = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * initialize proto
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * file read in one chunk
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * file read in BLOCK chunks
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * read the first chunk
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * check for proto pragma in first block of lines
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * pragma blanked out if found
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * -1 no pragma
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * 0 #pragma noprototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * 1 #pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * NOTE: matches may occur inside comments and quotes
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!notice && !options || (comlen = astlicense(com, sizeof(com), NiL, "type=check", proto->cc[0], proto->cc[1], proto->cc[2])) <= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pragma = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (m-- > 0 && *s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*s == '#')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!strncmp(s, MAGICDIR, sizeof(MAGICDIR) - 1) && (*(s += sizeof(MAGICDIR) - 1) == ' ' || *s == '\t'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pragma = -2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!strncmp(s, MAGICARG, sizeof(MAGICARG) - 1) && (*(s += sizeof(MAGICARG) - 1) == ' ' || *s == '\t' || *s == '\n' || *s == '\r'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((*(s - 1) == ' ' || *(s - 1) == '\t') && *s == *MAGICOFF && !strncmp(s, MAGICOFF, sizeof(MAGICOFF) - 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*s++ == '\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pragma += 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(flags & PROTO_DISABLE) || (flags & PROTO_NOPRAGMA))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (s--; b < s; *b++ = ' ');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pragma = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (*s == '/' && !strncmp(s, MAGICGEN, sizeof(MAGICGEN) - 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pragma = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*s == *NOTICED && !strncmp(s, NOTICED, sizeof(NOTICED) - 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*s == '(' && (*(s + 1) == 'c' || *(s + 1) == 'C') && *(s + 2) == ')' || *s >= '0' && *s <= '9' && *(s + 1) >= '0' && *(s + 1) <= '9')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (*s == *PUBLICDOMAIN && !strncmp(s, PUBLICDOMAIN, sizeof(PUBLICDOMAIN) - 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (*s++ == '\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*s && *s++ != '\n');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (flags & PROTO_EXTERNALIZE) proto->options |= EXTERNALIZE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(proto->flags & YACC) && file && (m = strlen(file)) > 2 && file[--m] == 'y' && file[--m] == '.')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pragma <= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if ((flags & (PROTO_FORCE|PROTO_PASS)) == PROTO_PASS || !pragma)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (proto->cc[0] == '#' && proto->ip[0] == '#' && proto->ip[1] == '!')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*s && *s++ != '\n');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((comlen = astlicense(proto->op, proto->oz, notice, options, proto->cc[0], proto->cc[1], proto->cc[2])) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin proto_error((char*)proto + sizeof(struct proto), 1, proto->op, NiL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(flags & PROTO_CLASSIC) && !(proto->flags & YACC))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (notice || options || (flags & (PROTO_HEADER|PROTO_INCLUDE)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((comlen = astlicense(proto->op, proto->oz, notice, options, proto->cc[0], proto->cc[1], proto->cc[2])) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin proto_error((char*)proto + sizeof(struct proto), 1, proto->op, NiL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * read next proto'd chunk into iob
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the chunk is 0 terminated and its size is returned
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct proto* proto = (struct proto*)(iob - sizeof(struct proto));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if ((n = read(proto->fd, proto->ob, proto->oz)) <= 0 || (proto->options & REGULAR) && n < proto->oz)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if ((n = read(proto->fd, ip, proto->iz)) <= 0 || (proto->options & REGULAR) && n < proto->iz)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n < 0) n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n == '%')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*ip == '%' && (ip == proto->ip + 1 || *(ip - 2) == '\n'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin proto->op = memcopy(proto->ob, proto->ip, ip - proto->ip);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin proto->op = strcopy(proto->op, "/* NOTE: some constructs may not have been converted */\n");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * drop control of iob after first pppread()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return value is input fd
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if fd<0 then all data in iob
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct proto* proto = (struct proto*)(iob - sizeof(struct proto));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;