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

📄 common.w

📁 模拟器提供了一个简单易用的平台
💻 W
📖 第 1 页 / 共 4 页
字号:
% This file is part of CWEB.% This program by Silvio Levy and Donald E. Knuth% is based on a program by Knuth.% It is distributed WITHOUT ANY WARRANTY, express or implied.% Version 3.61 --- July 2000 (works with later versions too)% Copyright (C) 1987,1990,1993,2000 Silvio Levy and Donald E. Knuth% Permission is granted to make and distribute verbatim copies of this% document provided that the copyright notice and this permission notice% are preserved on all copies.% Permission is granted to copy and distribute modified versions of this% document under the conditions for verbatim copying, provided that the% entire resulting derived work is given a different name and distributed% under the terms of a permission notice identical to this one.\def\v{\char'174} % vertical (|) in typewriter font\def\title{Common code for CTANGLE and CWEAVE (Version 3.61)}\def\topofcontents{\null\vfill  \centerline{\titlefont Common code for {\ttitlefont CTANGLE} and    {\ttitlefont CWEAVE}}  \vskip 15pt  \centerline{(Version 3.61)}  \vfill}\def\botofcontents{\vfill\noindentCopyright \copyright\ 1987, 1990, 1993, 2000 Silvio Levy and Donald E. Knuth\bigskip\noindentPermission is granted to make and distribute verbatim copies of thisdocument provided that the copyright notice and this permission noticeare preserved on all copies.\smallskip\noindentPermission is granted to copy and distribute modified versions of thisdocument under the conditions for verbatim copying, provided that theentire resulting derived work is given a different name and distributedunder the terms of a permission notice identical to this one.}\pageno=\contentspagenumber \advance\pageno by 1\let\maybe=\iftrue@s not_eq normal @q unreserve a C++ keyword @>@** Introduction.  This file contains code commonto both \.{CTANGLE} and \.{CWEAVE}, which roughly concerns the followingproblems: character uniformity, input routines, error handling andparsing of command line.  We have tried to concentrate in this fileall the system dependencies, so as to maximize portability.In the texts below we willsometimes use \.{CWEB} to refer to either of the two componentprograms, if no confusion can arise.The file begins with a few basic definitions.@c@<Include files@>@/@h@<Definitions that should agree with \.{CTANGLE} and \.{CWEAVE}@>@/@<Other definitions@>@/@<Predeclaration of procedures@>@/@ In certain cases \.{CTANGLE} and \.{CWEAVE} should do almost, but notquite, the same thing.  In these cases we've written common code forboth, differentiating between the two by means of the global variable|program|.@d ctangle 0@d cweave 1@<Definitions...@>=typedef short boolean;boolean program; /* \.{CWEAVE} or \.{CTANGLE}? */@ \.{CWEAVE} operates in three phases: First it inputs the sourcefile and stores cross-reference data, then it inputs the source once again andproduces the \TEX/ output file, and finally it sorts and outputs the index.Similarly, \.{CTANGLE} operates in two phases.The global variable |phase| tells which phase we are in.@<Other...@>= int phase; /* which phase are we in? */@ There's an initialization procedure that gets both \.{CTANGLE} and\.{CWEAVE} off to a good start. We will fill in the details of thisprocedure later.@cvoidcommon_init(){  @<Initialize pointers@>;  @<Set the default options common to \.{CTANGLE} and \.{CWEAVE}@>;  @<Scan arguments and open output files@>;}@* The character set.\.{CWEB} uses the conventions of \CEE/ programs found in the standard\.{ctype.h} header file.@<Include files@>=#include <ctype.h>@ A few character pairs are encoded internally as single characters,using the definitions below. These definitions are consistent withan extension of ASCII code originally developed at MIT and explained inAppendix~C of {\sl The \TEX/book\/}; thus, users who have such acharacter set can type things like \.{\char'32} and \.{\char'4} insteadof \.{!=} and \.{\&\&}. (However, their files will not be too portableuntil more people adopt the extended code.)If the character set is not ASCII, the definitions given here may conflictwith existing characters; in such cases, other arbitrary codes should besubstituted. The indexes to \.{CTANGLE} and \.{CWEAVE} mention everycase where similar codes may have to be changed in order toavoid character conflicts. Look for the entry ``ASCII code dependencies''in those indexes.@^ASCII code dependencies@>@^system dependencies@>@d and_and 04 /* `\.{\&\&}'\,; corresponds to MIT's {\tentex\char'4} */@d lt_lt 020 /* `\.{<<}'\,;  corresponds to MIT's {\tentex\char'20} */@d gt_gt 021 /* `\.{>>}'\,;  corresponds to MIT's {\tentex\char'21} */@d plus_plus 013 /* `\.{++}'\,;  corresponds to MIT's {\tentex\char'13} */@d minus_minus 01 /* `\.{--}'\,;  corresponds to MIT's {\tentex\char'1} */@d minus_gt 031 /* `\.{->}'\,;  corresponds to MIT's {\tentex\char'31} */@d not_eq 032 /* `\.{!=}'\,;  corresponds to MIT's {\tentex\char'32} */@d lt_eq 034 /* `\.{<=}'\,;  corresponds to MIT's {\tentex\char'34} */@d gt_eq 035 /* `\.{>=}'\,;  corresponds to MIT's {\tentex\char'35} */@d eq_eq 036 /* `\.{==}'\,;  corresponds to MIT's {\tentex\char'36} */@d or_or 037 /* `\.{\v\v}'\,;  corresponds to MIT's {\tentex\char'37} */@d dot_dot_dot 016 /* `\.{...}'\,;  corresponds to MIT's {\tentex\char'16} */@d colon_colon 06 /* `\.{::}'\,;  corresponds to MIT's {\tentex\char'6} */@d period_ast 026 /* `\.{.*}'\,;  corresponds to MIT's {\tentex\char'26} */@d minus_gt_ast 027 /* `\.{->*}'\,;  corresponds to MIT's {\tentex\char'27} */@** Input routines.  The lowest level of input to the \.{CWEB} programsis performed by |input_ln|, which must be told which file to read from.The return value of |input_ln| is 1 if the read is successful and 0 ifnot (generally this means the file has ended). The conventionsof \TEX/ are followed; i.e., the characters of the next line of the fileare copied into the |buffer| array,and the global variable |limit| is set to the first unoccupied position.Trailing blanks are ignored. The value of |limit| must be strictly lessthan |buf_size|, so that |buffer[buf_size-1]| is never filled.Since |buf_size| is strictly less than |long_buf_size|,some of \.{CWEB}'s routines use the fact that it is safe to refer to|*(limit+2)| without overstepping the bounds of the array.@d buf_size 100 /* for \.{CWEAVE} and \.{CTANGLE} */@d longest_name 1000@d long_buf_size (buf_size+longest_name) /* for \.{CWEAVE} */@d xisspace(c) (isspace(c)&&((unsigned char)c<0200))@d xisupper(c) (isupper(c)&&((unsigned char)c<0200))@<Definitions...@>=char buffer[long_buf_size]; /* where each line of input goes */char *buffer_end=buffer+buf_size-2; /* end of |buffer| */char *limit=buffer; /* points to the last character in the buffer */char *loc=buffer; /* points to the next character to be read from the buffer */@ @<Include files@>=#include <stdio.h>@ In the unlikely event that your standard I/O library does notsupport |feof|, |getc|, and |ungetc| you may have to change things here.@^system dependencies@>@cint input_ln(fp) /* copies a line into |buffer| or returns 0 */FILE *fp; /* what file to read from */{  register int  c=EOF; /* character read; initialized so some compilers won't complain */  register char *k;  /* where next character goes */  if (feof(fp)) return(0);  /* we have hit end-of-file */  limit = k = buffer;  /* beginning of buffer */  while (k<=buffer_end && (c=getc(fp)) != EOF && c!='\n')    if ((*(k++) = c) != ' ') limit = k;  if (k>buffer_end)    if ((c=getc(fp))!=EOF && c!='\n') {      ungetc(c,fp); loc=buffer; err_print("! Input line too long");@.Input line too long@>  }  if (c==EOF && limit==buffer) return(0);  /* there was nothing after    the last newline */  return(1);}@ Now comes the problem of deciding which file to read from next.Recall that the actual text that \.{CWEB} should process comes from twostreams: a |web_file|, which can contain possibly nested includecommands \.{@@i}, and a |change_file|, which might also containincludes.  The |web_file| together with the currently open includefiles form a stack |file|, whose names are stored in a parallel stack|file_name|.  The boolean |changing| tells whether or not we're readingfrom the |change_file|.The line number of each open file is also kept for error reporting andfor the benefit of \.{CTANGLE}.@f line x /* make |line| an unreserved word */@d max_include_depth 10 /* maximum number of source files open  simultaneously, not counting the change file */@d max_file_name_length 60@d cur_file file[include_depth] /* current file */@d cur_file_name file_name[include_depth] /* current file name */@d cur_line line[include_depth] /* number of current line in current file */@d web_file file[0] /* main source file */@d web_file_name file_name[0] /* main source file name */@<Definitions...@>=int include_depth; /* current level of nesting */FILE *file[max_include_depth]; /* stack of non-change files */FILE *change_file; /* change file */char file_name[max_include_depth][max_file_name_length];  /* stack of non-change file names */char change_file_name[max_file_name_length]; /* name of change file */char alt_web_file_name[max_file_name_length]; /* alternate name to try */int line[max_include_depth]; /* number of current line in the stacked files */int change_line; /* number of current line in change file */int change_depth; /* where \.{@@y} originated during a change */boolean input_has_ended; /* if there is no more input */boolean changing; /* if the current line is from |change_file| */boolean web_file_open=0; /* if the web file is being read */@ When |changing==0|, the next line of |change_file| is kept in|change_buffer|, for purposes of comparison with the nextline of |cur_file|. After the change file has been completely input, weset |change_limit=change_buffer|,so that no further matches will be made.Here's a shorthand expression for inequality between the two lines:@d lines_dont_match (change_limit-change_buffer != limit-buffer ||  strncmp(buffer, change_buffer, limit-buffer))@<Other...@>=char change_buffer[buf_size]; /* next line of |change_file| */char *change_limit; /* points to the last character in |change_buffer| */@ Procedure |prime_the_change_buffer|sets |change_buffer| in preparation for the next matching operation.Since blank lines in the change file are not used for matching, we have|(change_limit==change_buffer && !changing)| if and only ifthe change file is exhausted. This procedure is called only when|changing| is 1; hence error messages will be reported correctly.@cvoidprime_the_change_buffer(){  change_limit=change_buffer; /* this value is used if the change file ends */  @<Skip over comment lines in the change file; |return| if end of file@>;  @<Skip to the next nonblank line; |return| if end of file@>;  @<Move |buffer| and |limit| to |change_buffer| and |change_limit|@>;}@ While looking for a line that begins with \.{@@x} in the change file, weallow lines that begin with \.{@@}, as long as they don't begin with \.{@@y},\.{@@z}, or \.{@@i} (which would probably mean that the change file is fouled up).@<Skip over comment lines in the change file...@>=while(1) {  change_line++;  if (!input_ln(change_file)) return;  if (limit<buffer+2) continue;  if (buffer[0]!='@@') continue;  if (xisupper(buffer[1])) buffer[1]=tolower(buffer[1]);  if (buffer[1]=='x') break;  if (buffer[1]=='y' || buffer[1]=='z' || buffer[1]=='i') {    loc=buffer+2;    err_print("! Missing @@x in change file");@.Missing @@x...@>  }}@ Here we are looking at lines following the \.{@@x}.@<Skip to the next nonblank line...@>=do {  change_line++;  if (!input_ln(change_file)) {    err_print("! Change file ended after @@x");@.Change file ended...@>    return;  }} while (limit==buffer);@ @<Move |buffer| and |limit| to |change_buffer| and |change_limit|@>={  change_limit=change_buffer-buffer+limit;  strncpy(change_buffer,buffer,limit-buffer+1);}@ The following procedure is used to see if the next change entry shouldgo into effect; it is called only when |changing| is 0.The idea is to test whether or not the currentcontents of |buffer| matches the current contents of |change_buffer|.If not, there's nothing more to do; but if so, a change is called for:All of the text down to the \.{@@y} is supposed to match. An errormessage is issued if any discrepancy is found. Then the procedureprepares to read the next line from |change_file|.When a match is found, the current section is marked as changed unlessthe first line after the \.{@@x} and after the \.{@@y} both start witheither |'@@*'| or |'@@ '| (possibly preceded by whitespace).This procedure is called only when |buffer<limit|, i.e., when thecurrent line is nonempty.@d if_section_start_make_pending(b) {@+*limit='!';  for (loc=buffer;xisspace(*loc);loc++) ;  *limit=' ';  if (*loc=='@@' && (xisspace(*(loc+1)) || *(loc+1)=='*')) change_pending=b;}@cvoidcheck_change() /* switches to |change_file| if the buffers match */{  int n=0; /* the number of discrepancies found */  if (lines_dont_match) return;  change_pending=0;  if (!changed_section[section_count]) {    if_section_start_make_pending(1);    if (!change_pending) changed_section[section_count]=1;  }  while (1) {    changing=1; print_where=1; change_line++;    if (!input_ln(change_file)) {      err_print("! Change file ended before @@y");@.Change file ended...@>      change_limit=change_buffer; changing=0;      return;    }    if (limit>buffer+1 && buffer[0]=='@@') {      if (xisupper(buffer[1])) buffer[1]=tolower(buffer[1]);      @<If the current line starts with \.{@@y},        report any discrepancies and |return|@>;    }    @<Move |buffer| and |limit|...@>;    changing=0; cur_line++;    while (!input_ln(cur_file)) { /* pop the stack or quit */      if (include_depth==0) {        err_print("! CWEB file ended during a change");@.CWEB file ended...@>        input_has_ended=1; return;      }      include_depth--; cur_line++;    }    if (lines_dont_match) n++;

⌨️ 快捷键说明

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