📄 snptools.c
字号:
/* * snptools.c * * Copyright (C) 1997 Cygnus Solutions, Inc. * * Description: * Implementation of the Source-Navigator parser toolbox library. */#include <assert.h>#include <ctype.h>#include <stdarg.h>#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <config.h>#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#ifdef HAVE_SYS_PARAM_H#include <sys/param.h>#endif#include <sys/stat.h>#ifdef WIN32#define OPEN_MODE "rb"#ifndef MAXPATHLEN#define MAXPATHLEN _MAX_PATH#endif /* MAXPATHLEN */#else /* UNIX */#define OPEN_MODE "r"#endif /* WIN32 */#include <tcl.h> #include "snptools.h"#include "parser.h"/* For platforms that do not have getopt globals in their headers. */extern char *optarg;extern int optind;Tcl_Encoding encoding = NULL;extern FILE * cross_ref_fp;static FILE * includelist = NULL;static long line = 1;static long column = 0;static long savedLine;static long savedColumn;static char * group = NULL;static char * incl_to_pipe = NULL;static char * includename = NULL;static char * xref_filename = NULL;static char * dump_tokens_file = NULL;static char includebuf[512];static char currentFilename[MAXPATHLEN];/* * boolean values (with their defaults) for command line switches */static int case_sensitive = 1;extern int comment_database;static int dialect = 0;extern int report_local_vars;static int drop_usr_headers = 0;static int treat_as_cplusplus = 0;static FILE * listfp = NULL;static FILE * outfp = NULL;static int highlight = 0;static int highlight_number = 0;static FILE * highlightfp = NULL;/* * Return the first include path from the list (or NULL if the list is empty). */char *sn_includepath_first(){ if (includelist != NULL) { fclose(includelist); } includelist = fopen(includename, "r"); if (includelist == NULL) { return(NULL); } return sn_includepath_next();}/* * Returns the next include path from the list (or NULL if there are no more). */char *sn_includepath_next(){ char *p; if (includelist == NULL) { return sn_includepath_first(); } p = fgets(includebuf, sizeof(includebuf), includelist); if (p == NULL) { return(p); } else { p = strchr(includebuf, '\n'); if (p != NULL) { *p = '\0'; /* strip off newline */ } if (strlen(includebuf) > 0 && includebuf[strlen(includebuf) - 1] != '/') { strcat(includebuf, "/"); /* ensure path ends in a slash */ } } return(includebuf);}/* * Make the executable panic and return an errorcode of 2. */voidsn_panic(){ exit(2);}/* * A pseudo-main function that handles command line processing, opening of * source files and invoking the parser on those files. */intsn_main(int argc, char *argv[], char * group, FILE ** lexstream, int (*lexer)(), void (*reset)()){ sn_set_group(group); sn_process_options(argc, argv); if (optind < argc || sn_getopt(SN_OPT_LISTFILE)) { sn_init(); if ((char *) sn_getopt(SN_OPT_LISTFILE) != NULL) { /* This part is called when the project is being created. */ sn_parse_all(lexstream, lexer, reset); } else { /* * This part is called when a file has been saved, thus we parse the * file. */ if (sn_register_filename(lexstream, argv[optind]) == 0) { reset(); lexer(); } } } else { sn_error("-y or file name required\n"); return(1); } sn_close(); return(0);}/* * Get the value of any options set on the command line (e.g. -c 300 sets * cachesize to "300". */void *sn_getopt(enum sn_options opt){ switch (opt) { case SN_OPT_CASE_SENSITIVE: return (void *) case_sensitive; case SN_OPT_COMMENTS: return (void *) comment_database; case SN_OPT_DIALECT: return (void *) dialect; case SN_OPT_DUMP_TOKENS: return (void *) dump_tokens_file; case SN_OPT_DROP_USR_HEADERS: return (void *) drop_usr_headers; case SN_OPT_GROUP: return group; case SN_OPT_HIGHLIGHT: return (void *) highlight; case SN_OPT_INCL_TO_PIPE: return incl_to_pipe; case SN_OPT_INCLUDE_LIST: return (void *) includename; case SN_OPT_LOCAL_VARS: return (void *) report_local_vars; case SN_OPT_LISTFILE: return listfp; case SN_OPT_TREAT_AS_CPLUSPLUS: return (void *) treat_as_cplusplus; case SN_OPT_XREF_FILENAME: return xref_filename; default: assert(0); break; } return 0;}/* * Process the command line options and set the relevant static variables * for later reference using sn_getopt(). */voidsn_process_options(int argc, char *argv[]){ int opt; /* Character set encoding (as defined by Tcl). */ Tcl_FindExecutable(argv[0]); while ((opt = getopt(argc, argv, "I:n:s:hy:g:x:i:luB:e:tCrDS:O:T:")) != EOF) { switch (opt) { case 'B': /* silently ignore according to zkoppany */ break; case 'C': treat_as_cplusplus = 1; break; case 'D': /* silently ignore according to zkoppany */ break; case 'e': if ((encoding = Tcl_GetEncoding(NULL, optarg)) == NULL) { sn_error("Unable to locate `%s' encoding\n", optarg); sn_exit(); } break; case 'g': group = optarg; break; case 'h': highlight = 1; break; case 'i': incl_to_pipe = optarg; break; case 'I': includename = optarg; break; case 'l': report_local_vars = 1; break; case 'n': /* FIXME: Remove db prefix option later */ break; case 'r': comment_database = 1; break; case 's': if ((outfp = fopen(optarg, "a")) == NULL) { sn_error("could not create %s\n", optarg); sn_exit(); } break; case 'S': /* silently ignore according to zkoppany */ break; case 'T': /* Dump tokens to a file and exit */ dump_tokens_file = optarg; break; case 't': drop_usr_headers = 1; break; case 'u': case_sensitive = 0; break; case 'x': xref_filename = optarg; break; case 'y': listfp = fopen(optarg, "r"); if (listfp == NULL) { sn_error("Could not open \"%s\", %s\n", optarg, strerror(errno)); sn_panic(); } break; default: assert(0); break; } }}/* * Print an error message. */intsn_error(char * format, ...){ int i; va_list ap; va_start(ap, format); i = vfprintf(stderr, format, ap); va_end(ap); fflush(stderr); return(i);}/* * Print a diagnostic message on the S-N processing dialog. */intsn_message(char * format, ...){ int i; va_list ap; va_start(ap, format); i = vfprintf(stdout, format, ap); va_end(ap); fflush(stdout); return(i);}/* * Write highlight info to a file that will be read by * the IDE and used to add highlight tags to the editor. * This function should only be called when the -h * option has been passed to the browser. */void sn_highlight(enum sn_highlights type, long start_line, int start_column, long end_line, int end_column){ char * tag; if (!highlight) return; switch (type) { case SN_HIGH_COMMENT: tag = "rem"; break; case SN_HIGH_KEYWORD: tag = "key"; break; case SN_HIGH_STRING: tag = "str"; break; case SN_HIGH_VAR_GLOBAL: tag = "gv"; break; case SN_HIGH_VAR_LOCAL: tag = "lv"; break; case SN_HIGH_FUNCTION: tag = "fu"; break; default: sn_error("Unknown highlight type %d\n", type); sn_panic(); } fprintf(highlightfp, "%d %s %d.%d %d.%d\n", highlight_number++, /* Ignored by Sn_Highlight_Text */ tag, start_line, start_column, end_line, end_column);}/* * Make the executable exit due to some error with the error code expected by * S-N. */voidsn_exit(){ if (encoding) { Tcl_FreeEncoding(encoding); Tcl_Finalize(); } exit(1);}/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -