⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.c

📁 这是一个Linux下的集成开发环境
💻 C
字号:
/*Copyright (c) 2000, Red Hat, Inc.This file is part of Source-Navigator.Source-Navigator is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public License as publishedby the Free Software Foundation; either version 2, or (at your option)any later version.Source-Navigator is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNUGeneral Public License for more details.You should have received a copy of the GNU General Public License alongwith Source-Navigator; see the file COPYING.  If not, write tothe Free Software Foundation, 59 Temple Place - Suite 330, Boston,MA 02111-1307, USA.*//* * parser.c * * This file contains support routines used by SN parsers. These * routines typically output data in a format that is then read * by dbimp. */#include "parser.h"#include <tcl.h>#include <sn.h>/* This seems to conflict with a define in longstr.h so include first! */#include "mxdefine.h"#include "mxfuncs.h"#include "longstr.h"#include "fileutils.h" /* for SN_PATH_UNIX */#include <config.h>#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#include <errno.h>static  char    *acc_strings[] = {	"r","w","p","u"};#ifndef WIN32typedef FILE*   HANDLE;#define INVALID_HANDLE_VALUE    (FILE *)0#endif /* WIN32 */static  HANDLE  pipe_handle = INVALID_HANDLE_VALUE;/* These global vars are accessed directly from the parsers */int  comment_database = FALSE;FILE *cross_ref_fp;int	 report_local_vars = FALSE;static int Paf_Pipe_Write MX_VARARGS(char *,str);static int Paf_Pipe_Flush ();#ifndef MY_DEBUG2#define MY_DEBUG(x)#define MY_DEBUG2(x)#define MY_DEBUG(x)#endifvoidPaf_Pipe_Create(char *incl_to_pipe){#ifdef WIN32	pipe_handle = GetStdHandle(STD_OUTPUT_HANDLE);#else	pipe_handle = stdout;#endif /* WIN32 */	if (incl_to_pipe)	{		FILE    *ifp;		char    tmp[1024];		if ((ifp = fopen(incl_to_pipe,"r")) == NULL)		{			fprintf(stderr,"Error: couldn't load \"%s\", error: \"%s\"\n",				incl_to_pipe, strerror(errno));			fflush(stderr);			exit(1);		}		while (fgets(tmp,sizeof(tmp)-1,ifp))		{			Paf_Pipe_Write(tmp);		}		Paf_Pipe_Flush();		fclose(ifp);		unlink(incl_to_pipe);   /* Nobody needs it. */	}}intPaf_Pipe_Close(){	if (pipe_handle == INVALID_HANDLE_VALUE)		panic("pipe was not opened before Paf_Pipe_Close call");	pipe_handle = INVALID_HANDLE_VALUE;	return 0;}static intPaf_Pipe_Write MX_VARARGS_DEF(char *, arg1){	va_list args;	char    *fmt;	char    tmp[10000];	int     len;#ifdef WIN32	DWORD     cou;#else	int     cou;#endif	Tcl_DString utfBuffer;	if (pipe_handle == INVALID_HANDLE_VALUE)		return -1;	fmt = (char *)MX_VARARGS_START(char *,arg1,args);	len = vsprintf(tmp,fmt, args);	for (fmt = tmp; len > 0;)	{		cou = 0;		Tcl_ExternalToUtfDString(NULL, tmp, len, &utfBuffer);#ifdef _WINDOWS		if (WriteFile(pipe_handle,Tcl_DStringValue(&utfBuffer),		    Tcl_DStringLength(&utfBuffer),&cou,NULL) == FALSE)		{			Tcl_DStringFree(&utfBuffer);			return FALSE;		}#else		cou = fprintf(pipe_handle,"%s",Tcl_DStringValue(&utfBuffer));		if (cou == -1) {			Tcl_DStringFree(&utfBuffer);			return FALSE;		}#endif		if (cou > 0)		{			fmt += cou;			len -= cou;		}		Tcl_DStringFree(&utfBuffer);	}	return TRUE;}static intPaf_Pipe_Flush(){	if (pipe_handle == INVALID_HANDLE_VALUE)		return -1;#ifdef  WIN32	return (int)FlushFileBuffers(pipe_handle);#else	return fflush(pipe_handle);#endif /* __MSVC__ */}/* This functions writes out a file parsing status line. * It is invoked by the various parser routines to write * out a line of input that is parsed by the * Source-Navigator procudure event_LoadPipeInput. */voidput_status_parsing_file(char *fname) {    Paf_Pipe_Write("Status: Parsing: %s\n", fname);    Paf_Pipe_Flush();}/* * This functions prints data for a file to the output pipe. * This function is only called by the parsers. */intput_file(char *file_name,char *group,char *highlight_file){	if (!file_name)	{		fprintf(stderr,"put_file: empty file name\n");		return -1;	}	if (pipe_handle == INVALID_HANDLE_VALUE)	{		panic("put_file called when pipe is not open");	}	Paf_Pipe_Write("%d%c%s%c%s%c%s\n",		PAF_FILE,      KEY_DATA_SEP_CHR,		file_name,     KEY_DATA_SEP_CHR,		group,         DB_FLDSEP_CHR,		highlight_file ? highlight_file : "");	return Paf_Pipe_Flush();       /* 'dbimp' can start deleting. */}/* * This functions prints symbol data to the output pipe. * This function is only called by the parsers. */intput_symbol(int     sym_type,char    *scope_name,char    *symbol_name,char    *file_name,int     start_lineno,int     start_colpos,int     end_lineno,int     end_colpos,unsigned long   attr,char    *ret,char    *arg_types,char    *args,char    *comment,int     high_start_lineno,int     high_start_colpos,int     high_end_lineno,int     high_end_colpos){	char	*sym_str_type = SN_GetSymbolType(sym_type);	if (!file_name)	{		fprintf(stderr,"Error: put_symbol argument file_name must not be NULL\n");		fflush(stderr);		return -1;	}	for (; isspace(*file_name); file_name++);	if (!sym_str_type)	{		fprintf(stderr,"Error: put_symbol unknown type: %d file: %s\n",			sym_type,file_name);		fflush(stderr);		return -1;	}	if (!symbol_name || !*symbol_name)	{		fprintf(stderr,			"Error: put_symbol argument #3 must not be empty, type: (%s), line: %d file: %s\n",			sym_str_type,start_lineno,file_name);		fflush(stderr);		return -1;	}	for (; isspace(*symbol_name); symbol_name++);	/* If args is just a string we take a special name. */	if (args && *args == '"')	{		args = "%STRING%";	}	if (comment_database && comment && *comment)	{		register char *p;		for (p = comment; *p; p++)		{			switch (*p)			{			case    '\n':				*p = (char )0xff;				break;			case    '{':			case    '}':				*p = DB_FLDSEP_CHR;				break;			}		}	}	else		comment = "";	/* Make sure no '\n' appears in the symbol name */	{		register char *p;		for (p = symbol_name; *p; p++)		{			if (*p == '\n') {			    *p = (char )0xff;			}		}	}	switch (sym_type)	{	case	PAF_TYPE_DEF:	case	PAF_CLASS_DEF:	case	PAF_ENUM_DEF:	case	PAF_CONS_DEF:	case	PAF_MACRO_DEF:	case	PAF_FUNC_DEF:	case	PAF_GLOB_VAR_DEF:	case	PAF_FUNC_DCL:	case	PAF_UNION_DEF:	case	PAF_ENUM_CONST_DEF:		scope_name = NULL;		break;	}	/* Skip leading blanks */	for (;scope_name && isspace(*scope_name); scope_name++);	if (!scope_name || *scope_name == '\0')	{		scope_name = NULL;		switch (sym_type)		{		case PAF_MBR_FUNC_DEF:		case PAF_MBR_VAR_DEF:		case PAF_COMMON_MBR_VAR_DEF:		case PAF_CLASS_INHERIT:		case PAF_MBR_FUNC_DCL:/*		case PAF_ENUM_CONST_DEF: */			fprintf(stderr,				"Error: put_symbol argument #2 must not be empty, type: (%s), line: %d file: %s\n",				sym_str_type,start_lineno,file_name);			fflush(stderr);			return -1;			break;		}	}	if (high_start_lineno == 0)	/* Take the symbol definition. */	{		high_start_lineno = start_lineno;		high_start_colpos = start_colpos;		high_end_lineno = start_lineno;		high_end_colpos = start_colpos + strlen(symbol_name);	}	if (pipe_handle == INVALID_HANDLE_VALUE)	{		panic("put_symbol called when pipe is not open");	}	Paf_Pipe_Write("%d%c%s%s%s%c%06d.%03d%c%s%c%d.%d%c0x%x%c{%s}%c{%s}%c{%s}%c{%s}\n",		sym_type,                        KEY_DATA_SEP_CHR,		scope_name ? scope_name : "",		scope_name ? DB_FLDSEP_STR : "",		symbol_name,                     DB_FLDSEP_CHR,		high_start_lineno,                    high_start_colpos,           DB_FLDSEP_CHR,		file_name,                       KEY_DATA_SEP_CHR,		high_end_lineno, high_end_colpos,DB_FLDSEP_CHR,		attr,                            DB_FLDSEP_CHR,		ret ? ret : "",                  DB_FLDSEP_CHR,		arg_types ? arg_types : "",      DB_FLDSEP_CHR,		args ? args : "",                DB_FLDSEP_CHR,		comment		);	Paf_Pipe_Write("%d%c%s%c%06d.%03d%c%s%c%s%c%s%c%d.%d%c%d.%d%c%d.%d%c{%s}\n",		PAF_FILE_SYMBOLS,                     KEY_DATA_SEP_CHR,		file_name,                            DB_FLDSEP_CHR,		start_lineno, start_colpos,           DB_FLDSEP_CHR,		scope_name ? scope_name : "#",        DB_FLDSEP_CHR,		symbol_name,                          DB_FLDSEP_CHR,		sym_str_type,                         KEY_DATA_SEP_CHR,		end_lineno,        end_colpos,        DB_FLDSEP_CHR,		high_start_lineno, high_start_colpos, DB_FLDSEP_CHR,		high_end_lineno,   high_end_colpos,   DB_FLDSEP_CHR,		arg_types ? arg_types : ""		);	return 0;}/* * This functions prints comment info to the xref file. * This function is only called by the parsers. */intput_comment(char *classn,char *func,char *filename,char *comment,int beg_line,int beg_char){	register unsigned char  *p;	if (!comment_database || !comment || !cross_ref_fp)	{		return 0;	}	/* We use cross_ref_fp because the comments should be inserted	 * only during the second phase with the cross reference together.	 */	for (p = (unsigned char *)comment; *p; p++)	{		if (*p == '\n')		{			*p = 0xff;		}	}	MY_DEBUG((Output, "put comment into file <%s>\n", filename));	fprintf(cross_ref_fp,		"%d%c%s%c%06d.%03d%c%s%c%s%c%s\n",		PAF_COMMENT_DEF,                  KEY_DATA_SEP_CHR,		filename,                         DB_FLDSEP_CHR,		beg_line, beg_char,               DB_FLDSEP_CHR,		classn && *classn ? classn : "#", DB_FLDSEP_CHR,		func && *func ? func : "#",       KEY_DATA_SEP_CHR,		comment);	return 0;}intput_cross_ref(int     type,int     scope_type,int     scope_lev,char    *fnc_cls,              /* caller class */char    *fnc,                   /* caller function/method */char	*fnc_arg_types,         /* caller function/method argument types */char    *scope,                 /* referenced class */char	*what,                  /* referenced member */char	*arg_types,		/* referenced function/method argument types */char	*file,int	lineno,int	acc){	LongString	key_value;	LongString	data_value;	char	lineno_buf[10];	if (!cross_ref_fp || !fnc || *fnc == '\0' ||		(scope_lev == PAF_REF_SCOPE_LOCAL && !report_local_vars))	{		return -1;	}	MY_DEBUG2 ((Output, "put_cross_ref (%i, %i, %i, %s, %s, %s, %s, %s, %s, %s, %i, %i)\n",					type, scope_type, scope_lev,					fnc_cls?fnc_cls:"?",					fnc?fnc:"?",					fnc_arg_types?fnc_arg_types:"?", scope?scope:"?", what?what:"?",					arg_types?arg_types:"?",	file?file:"?", lineno, acc));	if (scope && *scope == '\0')		scope = NULL;	else if (scope)	{		char *_p;		for (; isspace(*scope); scope++);				/*		 * It can happen, that the scope contains "class fld ",		 * so then terminate the rest after "class" */		if ((_p=strchr (scope, DB_FLDSEP_CHR)))		{			*_p = 0;		}		/**/		if (*scope == '\0')			scope = NULL;	}	if (fnc_cls && *fnc_cls == '\0')		fnc_cls = NULL;	else if (fnc_cls)	{		for (; isspace(*fnc_cls); fnc_cls++);	}	if (!file)	{		fprintf(stderr,"Filename must not be NULL\n");		return -1;	}	if (!what || !*what)	{		fprintf(stderr,"Input parameter (#8) must not be NULL file: %s line: %d\n",				file,lineno);		return -1;	}	for (; isspace(*what); what++);	for (; isspace(*file); file++);	if (type <= 0 || type > PAF_REF_UNDEFINED)	{		fprintf(stderr,"Input parameter (#1) %d is not allowed\n",			type);		return -1;	}	if (scope_type <= 0 || scope_type >= PAF_VAR_DCL)	{		fprintf(stderr,"Input parameter (#2) %d is not allowed\n",			scope_type);		return -1;	}	LongStringInit(&key_value,0);	LongStringInit(&data_value,0);	if (type == PAF_MBR_FUNC_DCL)		type = PAF_MBR_FUNC_DEF;	sprintf(lineno_buf,"%06d",lineno);	key_value.copystrings(&key_value,		fnc_cls ? fnc_cls : "#",            DB_FLDSEP_STR,		fnc,                                DB_FLDSEP_STR,		SN_GetSymbolType(scope_type),       DB_FLDSEP_STR,		scope ? scope : "#",                DB_FLDSEP_STR,		what,                               DB_FLDSEP_STR,		SN_GetSymbolType(type),             DB_FLDSEP_STR,		acc_strings[acc],                   DB_FLDSEP_STR,		lineno_buf,                         DB_FLDSEP_STR,		file,		NULL);	data_value.copystrings(&data_value,		fnc_arg_types ? fnc_arg_types : "", DB_FLDSEP_STR,		arg_types ? arg_types : "",		NULL);	if(!scope || *scope != '?')	{		fprintf(cross_ref_fp, "%d%c%s%c%s\n",			PAF_CROSS_REF, KEY_DATA_SEP_CHR,			key_value.buf, KEY_DATA_SEP_CHR,			data_value.buf);	}	key_value.free(&key_value);	data_value.free(&data_value);	return 0;}/* *      We have to conver '\\' to '/'. That's all. */char *Paf_tempnam(char *dir,char *pref){	static	char	tmpnm[MAXPATHLEN + 1];	char    *nm;	nm = tempnam(dir,pref);	if (!nm)		return nm;	unlink(nm);     /* Just to be very sure !!! */	strcpy (tmpnm, nm);	sn_internal_convert_path (tmpnm, SN_PATH_UNIX);		/* DON'T USE ckfree */	free(nm);	return tmpnm;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -