📄 util.c
字号:
/************************************************************************** util.c Copyright (C) 1998, 1999 Andrew T. Veliath This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: util.c,v 1.113 1999/10/01 21:58:10 sopwith Exp $***************************************************************************/#include <assert.h>#include <stdarg.h>#include <stdio.h>#include <stdlib.h>#include <ctype.h>#include <string.h>#include <errno.h>#ifndef _WIN32# include <unistd.h>#endif#include "rename.h"#include "util.h"IDL_EXPORT const char *IDL_tree_type_names[] = { "IDLN_NONE", "IDLN_ANY", "IDLN_LIST", "IDLN_GENTREE", "IDLN_INTEGER", "IDLN_STRING", "IDLN_WIDE_STRING", "IDLN_CHAR", "IDLN_WIDE_CHAR", "IDLN_FIXED", "IDLN_FLOAT", "IDLN_BOOLEAN", "IDLN_IDENT", "IDLN_TYPE_DCL", "IDLN_CONST_DCL", "IDLN_EXCEPT_DCL", "IDLN_ATTR_DCL", "IDLN_OP_DCL", "IDLN_PARAM_DCL", "IDLN_FORWARD_DCL", "IDLN_TYPE_INTEGER", "IDLN_TYPE_FLOAT", "IDLN_TYPE_FIXED", "IDLN_TYPE_CHAR", "IDLN_TYPE_WIDE_CHAR", "IDLN_TYPE_STRING", "IDLN_TYPE_WIDE_STRING", "IDLN_TYPE_BOOLEAN", "IDLN_TYPE_OCTET", "IDLN_TYPE_ANY", "IDLN_TYPE_OBJECT", "IDLN_TYPE_TYPECODE", "IDLN_TYPE_ENUM", "IDLN_TYPE_SEQUENCE", "IDLN_TYPE_ARRAY", "IDLN_TYPE_STRUCT", "IDLN_TYPE_UNION", "IDLN_MEMBER", "IDLN_NATIVE", "IDLN_CASE_STMT", "IDLN_INTERFACE", "IDLN_MODULE", "IDLN_BINOP", "IDLN_UNARYOP", "IDLN_CODEFRAG", /* IDLN_LAST */};IDL_EXPORT int __IDL_check_type_casts = FALSE;#ifndef HAVE_CPP_PIPE_STDINchar * __IDL_tmp_filename = NULL;#endifconst char * __IDL_real_filename = NULL;char * __IDL_cur_filename = NULL;int __IDL_cur_line;GHashTable * __IDL_filename_hash;IDL_fileinfo * __IDL_cur_fileinfo;GHashTable * __IDL_structunion_ht;int __IDL_inhibits;IDL_tree __IDL_root;IDL_ns __IDL_root_ns;int __IDL_is_okay;int __IDL_is_parsing;unsigned long __IDL_flags;unsigned long __IDL_flagsi;gpointer __IDL_inputcb_user_data;IDL_input_callback __IDL_inputcb;GSList * __IDL_new_ident_comments;static int __IDL_max_msg_level;static int __IDL_nerrors, __IDL_nwarnings;static IDL_msg_callback __IDL_msgcb;/* Case-insensitive version of g_str_hash */guint IDL_strcase_hash (gconstpointer v){ const char *p; guint h = 0, g; for (p = (char *) v; *p != '\0'; ++p) { h = (h << 4) + isupper (*p) ? tolower (*p) : *p; if ((g = h & 0xf0000000)) { h = h ^ (g >> 24); h = h ^ g; } } return h /* % M */;}gint IDL_strcase_equal (gconstpointer a, gconstpointer b){ return g_strcasecmp (a, b) == 0;}gint IDL_strcase_cmp (gconstpointer a, gconstpointer b){ return g_strcasecmp (a, b);}static int my_strcmp (IDL_tree p, IDL_tree q){ const char *a = IDL_IDENT (p).str; const char *b = IDL_IDENT (q).str; int cmp = IDL_strcase_cmp (a, b); if (__IDL_is_parsing && cmp == 0 && strcmp (a, b) != 0 && !(IDL_IDENT (p)._flags & IDLF_IDENT_CASE_MISMATCH_HIT || IDL_IDENT (q)._flags & IDLF_IDENT_CASE_MISMATCH_HIT)) { IDL_tree_warning (p, IDL_WARNING1, "Case mismatch between `%s'", a); IDL_tree_warning (q, IDL_WARNING1, "and `%s'", b); yywarning (IDL_WARNING1, "(Identifiers should be case-consistent after initial declaration)"); IDL_IDENT (p)._flags |= IDLF_IDENT_CASE_MISMATCH_HIT; IDL_IDENT (q)._flags |= IDLF_IDENT_CASE_MISMATCH_HIT; } return cmp;}guint IDL_ident_hash (gconstpointer v){ return IDL_strcase_hash (IDL_IDENT ((IDL_tree) v).str);}gint IDL_ident_equal (gconstpointer a, gconstpointer b){ return my_strcmp ((IDL_tree) a, (IDL_tree) b) == 0;}gint IDL_ident_cmp (gconstpointer a, gconstpointer b){ return my_strcmp ((IDL_tree) a, (IDL_tree) b);}const char *IDL_get_libver_string (void){ return LIBIDL_LIBRARY_VERSION;}const char *IDL_get_IDLver_string (void){ return "2.2";}static void IDL_tree_optimize (IDL_tree *p, IDL_ns ns){ if (!(__IDL_flags & IDLF_IGNORE_FORWARDS)) IDL_tree_process_forward_dcls (p, ns); if (!(__IDL_flags & IDLF_INHIBIT_TAG_ONLY)) IDL_tree_remove_inhibits (p, ns); IDL_tree_remove_empty_modules (p, ns);}int IDL_parse_filename (const char *filename, const char *cpp_args, IDL_msg_callback msg_cb, IDL_tree *tree, IDL_ns *ns, unsigned long parse_flags, int max_msg_level){ extern void __IDL_lex_init (void); extern void __IDL_lex_cleanup (void); extern int yyparse (void); extern FILE *__IDL_in; FILE *input; char *cmd; size_t cmd_len;#ifdef HAVE_CPP_PIPE_STDIN char *fmt = CPP_PROGRAM " " CPP_NOSTDINC " - %s%s %s < \"%s\" 2>/dev/null"; char *wd = "", *dirend;#else char *fmt = CPP_PROGRAM " " CPP_NOSTDINC " -I- -I%s %s \"%s\" 2>/dev/null"; char *s, *tmpfilename; char cwd[2048]; gchar *linkto;#endif GSList *slist; int rv; if (!filename || !tree || (tree == NULL && ns != NULL)) { errno = EINVAL; return -1; }#ifndef NO_ACCESS if (access (filename, R_OK)) return -1;#endif#ifdef HAVE_CPP_PIPE_STDIN if ((dirend = strrchr (filename, '/'))) { int len = dirend - filename + 1; wd = g_malloc (len); strncpy (wd, filename, len - 1); wd[len - 1] = 0; } cmd_len = (strlen (filename) + (*wd ? 2 : 0) + strlen (wd) + (cpp_args ? strlen (cpp_args) : 0) + strlen (fmt) - 8 + 1); cmd = g_malloc (cmd_len); if (!cmd) { errno = ENOMEM; return -1; } g_snprintf (cmd, cmd_len, fmt, *wd ? "-I" : "", wd, cpp_args ? cpp_args : "", filename); if (dirend) g_free (wd);#else s = tmpnam (NULL); if (s == NULL) return -1; if (!getcwd (cwd, sizeof (cwd))) return -1; if (*filename == '/') { linkto = g_strdup (filename); } else { linkto = g_malloc (strlen (cwd) + strlen (filename) + 2); if (!linkto) { errno = ENOMEM; return -1; } strcpy (linkto, cwd); strcat (linkto, "/"); strcat (linkto, filename); } tmpfilename = g_malloc (strlen (s) + 3); if (!tmpfilename) { g_free (linkto); errno = ENOMEM; return -1; } strcpy (tmpfilename, s); strcat (tmpfilename, ".c");#ifndef NO_SYMLINK if (symlink (linkto, tmpfilename) < 0) { g_free (linkto); g_free (tmpfilename); return -1; }#endif g_free (linkto); cmd_len = (strlen (tmpfilename) + strlen (cwd) + (cpp_args ? strlen (cpp_args) : 0) + strlen (fmt) - 6 + 1); cmd = g_malloc (cmd_len); if (!cmd) { g_free (tmpfilename); errno = ENOMEM; return -1; } g_snprintf (cmd, cmd_len, fmt, cwd, cpp_args ? cpp_args : "", tmpfilename);#endif#ifndef NO_POPEN input = popen (cmd, "r");#else input = fopen (cmd, "r");#endif g_free (cmd); if (input == NULL || ferror (input)) {#ifndef HAVE_CPP_PIPE_STDIN g_free (tmpfilename);#endif return IDL_ERROR; } if (parse_flags & IDLF_XPIDL) parse_flags |= IDLF_PROPERTIES; __IDL_max_msg_level = max_msg_level; __IDL_nerrors = __IDL_nwarnings = 0; __IDL_in = input; __IDL_msgcb = msg_cb; __IDL_inhibits = 0; __IDL_flags = parse_flags; __IDL_flagsi = 0; __IDL_root_ns = IDL_ns_new (); __IDL_is_parsing = TRUE; __IDL_is_okay = TRUE; __IDL_lex_init (); __IDL_new_ident_comments = NULL; __IDL_real_filename = filename;#ifndef HAVE_CPP_PIPE_STDIN __IDL_tmp_filename = tmpfilename;#endif __IDL_filename_hash = IDL_NS (__IDL_root_ns).filename_hash; __IDL_structunion_ht = g_hash_table_new (g_direct_hash, g_direct_equal); rv = yyparse (); g_hash_table_destroy (__IDL_structunion_ht); __IDL_is_parsing = FALSE; __IDL_lex_cleanup (); __IDL_parser_reset (); __IDL_real_filename = NULL;#ifndef HAVE_CPP_PIPE_STDIN __IDL_tmp_filename = NULL;#endif#ifndef NO_POPEN pclose (input);#else fclose (input);#endif#ifndef HAVE_CPP_PIPE_STDIN unlink (tmpfilename); g_free (tmpfilename);#endif for (slist = __IDL_new_ident_comments; slist; slist = slist->next) g_free (slist->data); g_slist_free (__IDL_new_ident_comments); if (__IDL_root != NULL) { IDL_tree_optimize (&__IDL_root, __IDL_root_ns); if (__IDL_root == NULL) yyerror ("File empty after optimization"); } __IDL_msgcb = NULL; if (rv != 0 || !__IDL_is_okay) { if (tree) *tree = NULL; if (ns) *ns = NULL; return IDL_ERROR; } if (__IDL_flags & IDLF_PREFIX_FILENAME) IDL_ns_prefix (__IDL_root_ns, filename); if (tree) *tree = __IDL_root; else IDL_tree_free (__IDL_root); if (ns) *ns = __IDL_root_ns; else IDL_ns_free (__IDL_root_ns); return IDL_SUCCESS;}int IDL_parse_filename_with_input (const char *filename, IDL_input_callback input_cb, gpointer input_cb_user_data, IDL_msg_callback msg_cb, IDL_tree *tree, IDL_ns *ns, unsigned long parse_flags, int max_msg_level){ extern void __IDL_lex_init (void); extern void __IDL_lex_cleanup (void); extern int yyparse (void); union IDL_input_data data; GSList *slist; int rv; if (!filename || !input_cb || !tree || (tree == NULL && ns != NULL)) { errno = EINVAL; return -1; } if (parse_flags & IDLF_XPIDL) parse_flags |= IDLF_PROPERTIES; __IDL_max_msg_level = max_msg_level; __IDL_nerrors = __IDL_nwarnings = 0; __IDL_msgcb = msg_cb; __IDL_inhibits = 0; __IDL_flags = parse_flags; __IDL_flagsi = 0; __IDL_root_ns = IDL_ns_new (); __IDL_is_parsing = TRUE; __IDL_is_okay = TRUE; __IDL_lex_init (); __IDL_inputcb = input_cb; __IDL_inputcb_user_data = input_cb_user_data; __IDL_new_ident_comments = NULL; __IDL_real_filename = filename;#ifndef HAVE_CPP_PIPE_STDIN __IDL_tmp_filename = NULL;#endif __IDL_filename_hash = IDL_NS (__IDL_root_ns).filename_hash; data.init.filename = filename; if ((*__IDL_inputcb) ( IDL_INPUT_REASON_INIT, &data, __IDL_inputcb_user_data)) { IDL_ns_free (__IDL_root_ns); __IDL_lex_cleanup (); __IDL_real_filename = NULL; return -1; } __IDL_structunion_ht = g_hash_table_new (g_direct_hash, g_direct_equal); rv = yyparse (); g_hash_table_destroy (__IDL_structunion_ht); __IDL_is_parsing = FALSE; __IDL_lex_cleanup (); __IDL_parser_reset (); __IDL_real_filename = NULL; for (slist = __IDL_new_ident_comments; slist; slist = slist->next) g_free (slist->data); g_slist_free (__IDL_new_ident_comments); if (__IDL_root != NULL) { IDL_tree_optimize (&__IDL_root, __IDL_root_ns); if (__IDL_root == NULL) yyerror ("File empty after optimization"); } __IDL_msgcb = NULL; if (rv != 0 || !__IDL_is_okay) { if (tree) *tree = NULL; if (ns) *ns = NULL; (*__IDL_inputcb) ( IDL_INPUT_REASON_ABORT, NULL, __IDL_inputcb_user_data); return IDL_ERROR; } (*__IDL_inputcb) (IDL_INPUT_REASON_FINISH, NULL, __IDL_inputcb_user_data); if (__IDL_flags & IDLF_PREFIX_FILENAME) IDL_ns_prefix (__IDL_root_ns, filename); if (tree) *tree = __IDL_root; else IDL_tree_free (__IDL_root); if (ns) *ns = __IDL_root_ns; else IDL_ns_free (__IDL_root_ns); return IDL_SUCCESS;}void yyerrorl (const char *s, int ofs){ int line = __IDL_cur_line - 1 + ofs; gchar *filename = NULL; if (__IDL_cur_filename) {#ifdef HAVE_CPP_PIPE_STDIN filename = __IDL_cur_filename;#else filename = g_basename (__IDL_cur_filename);#endif } else line = -1; ++__IDL_nerrors; __IDL_is_okay = FALSE; /* Errors are counted, even if not printed */ if (__IDL_max_msg_level < IDL_ERROR) return; if (__IDL_msgcb) (*__IDL_msgcb)(IDL_ERROR, __IDL_nerrors, line, filename, s); else { if (line > 0) fprintf (stderr, "%s:%d: Error: %s\n", filename, line, s); else fprintf (stderr, "Error: %s\n", s); }}void yywarningl (int level, const char *s, int ofs){ int line = __IDL_cur_line - 1 + ofs; gchar *filename = NULL; /* Unprinted warnings are not counted */ if (__IDL_max_msg_level < level) return; if (__IDL_cur_filename) {#ifdef HAVE_CPP_PIPE_STDIN filename = __IDL_cur_filename;#else filename = g_basename (__IDL_cur_filename);#endif } else line = -1; ++__IDL_nwarnings; if (__IDL_msgcb) (*__IDL_msgcb)(level, __IDL_nwarnings, line, filename, s); else { if (line > 0) fprintf (stderr, "%s:%d: Warning: %s\n", filename, line, s); else fprintf (stderr, "Warning: %s\n", s); }}void yyerror (const char *s){ yyerrorl (s, 0);}void yywarning (int level, const char *s){ yywarningl (level, s, 0);}void yyerrorlv (const char *fmt, int ofs, ...){ gchar *msg; va_list args; va_start (args, ofs);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -