home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / unix / volume26 / celllr20 / part02 < prev    next >
Encoding:
Text File  |  1993-04-02  |  94.8 KB  |  2,871 lines

  1. Newsgroups: comp.sources.unix
  2. From: dana@rucs.faculty.cs.runet.edu (J Dana Eckart)
  3. Subject: v26i089: cellular-2.0 - a cellular automata language, Part02/03
  4. Sender: unix-sources-moderator@vix.com
  5. Approved: paul@vix.com
  6.  
  7. Submitted-By: dana@rucs.faculty.cs.runet.edu (J Dana Eckart)
  8. Posting-Number: Volume 26, Issue 89
  9. Archive-Name: cellular-2.0/part02
  10.  
  11. #! /bin/sh
  12. # This is a shell archive.  Remove anything before this line, then unpack
  13. # it by saving it into a file and typing "sh file".  To overwrite existing
  14. # files, type "sh file -c".  You can also feed this as standard input via
  15. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  16. # will see the following message at the end:
  17. #        "End of archive 2 (of 3)."
  18. # Contents:  COPYING compiler/Cellang.tex compiler/scanner.c
  19. #   driver/pe-scam.man viewer/cellview.man viewer/view.c viewer/x11.c
  20. # Wrapped by vixie@gw.home.vix.com on Sat Apr  3 01:27:39 1993
  21. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  22. if test -f 'COPYING' -a "${1}" != "-c" ; then 
  23.   echo shar: Will not clobber existing file \"'COPYING'\"
  24. else
  25. echo shar: Extracting \"'COPYING'\" \(12488 characters\)
  26. sed "s/^X//" >'COPYING' <<'END_OF_FILE'
  27. X
  28. X            GNU GENERAL PUBLIC LICENSE
  29. X             Version 1, February 1989
  30. X
  31. X Copyright (C) 1989 Free Software Foundation, Inc.
  32. X                    675 Mass Ave, Cambridge, MA 02139, USA
  33. X Everyone is permitted to copy and distribute verbatim copies
  34. X of this license document, but changing it is not allowed.
  35. X
  36. X                Preamble
  37. X
  38. X  The license agreements of most software companies try to keep users
  39. at the mercy of those companies.  By contrast, our General Public
  40. License is intended to guarantee your freedom to share and change free
  41. software--to make sure the software is free for all its users.  The
  42. General Public License applies to the Free Software Foundation's
  43. software and to any other program whose authors commit to using it.
  44. You can use it for your programs, too.
  45. X
  46. X  When we speak of free software, we are referring to freedom, not
  47. price.  Specifically, the General Public License is designed to make
  48. sure that you have the freedom to give away or sell copies of free
  49. software, that you receive source code or can get it if you want it,
  50. that you can change the software or use pieces of it in new free
  51. programs; and that you know you can do these things.
  52. X
  53. X  To protect your rights, we need to make restrictions that forbid
  54. anyone to deny you these rights or to ask you to surrender the rights.
  55. These restrictions translate to certain responsibilities for you if you
  56. distribute copies of the software, or if you modify it.
  57. X
  58. X  For example, if you distribute copies of a such a program, whether
  59. gratis or for a fee, you must give the recipients all the rights that
  60. you have.  You must make sure that they, too, receive or can get the
  61. source code.  And you must tell them their rights.
  62. X
  63. X  We protect your rights with two steps: (1) copyright the software, and
  64. X(2) offer you this license which gives you legal permission to copy,
  65. distribute and/or modify the software.
  66. X
  67. X  Also, for each author's protection and ours, we want to make certain
  68. that everyone understands that there is no warranty for this free
  69. software.  If the software is modified by someone else and passed on, we
  70. want its recipients to know that what they have is not the original, so
  71. that any problems introduced by others will not reflect on the original
  72. authors' reputations.
  73. X
  74. X  The precise terms and conditions for copying, distribution and
  75. modification follow.
  76. X
  77. X            GNU GENERAL PUBLIC LICENSE
  78. X   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
  79. X
  80. X  0. This License Agreement applies to any program or other work which
  81. contains a notice placed by the copyright holder saying it may be
  82. distributed under the terms of this General Public License.  The
  83. X"Program", below, refers to any such program or work, and a "work based
  84. on the Program" means either the Program or any work containing the
  85. Program or a portion of it, either verbatim or with modifications.  Each
  86. licensee is addressed as "you".
  87. X
  88. X  1. You may copy and distribute verbatim copies of the Program's source
  89. code as you receive it, in any medium, provided that you conspicuously and
  90. appropriately publish on each copy an appropriate copyright notice and
  91. disclaimer of warranty; keep intact all the notices that refer to this
  92. General Public License and to the absence of any warranty; and give any
  93. other recipients of the Program a copy of this General Public License
  94. along with the Program.  You may charge a fee for the physical act of
  95. transferring a copy.
  96. X
  97. X  2. You may modify your copy or copies of the Program or any portion of
  98. it, and copy and distribute such modifications under the terms of Paragraph
  99. X1 above, provided that you also do the following:
  100. X
  101. X    a) cause the modified files to carry prominent notices stating that
  102. X    you changed the files and the date of any change; and
  103. X
  104. X    b) cause the whole of any work that you distribute or publish, that
  105. X    in whole or in part contains the Program or any part thereof, either
  106. X    with or without modifications, to be licensed at no charge to all
  107. X    third parties under the terms of this General Public License (except
  108. X    that you may choose to grant warranty protection to some or all
  109. X    third parties, at your option).
  110. X
  111. X    c) If the modified program normally reads commands interactively when
  112. X    run, you must cause it, when started running for such interactive use
  113. X    in the simplest and most usual way, to print or display an
  114. X    announcement including an appropriate copyright notice and a notice
  115. X    that there is no warranty (or else, saying that you provide a
  116. X    warranty) and that users may redistribute the program under these
  117. X    conditions, and telling the user how to view a copy of this General
  118. X    Public License.
  119. X
  120. X    d) You may charge a fee for the physical act of transferring a
  121. X    copy, and you may at your option offer warranty protection in
  122. X    exchange for a fee.
  123. X
  124. Mere aggregation of another independent work with the Program (or its
  125. derivative) on a volume of a storage or distribution medium does not bring
  126. the other work under the scope of these terms.
  127. X
  128. X  3. You may copy and distribute the Program (or a portion or derivative of
  129. it, under Paragraph 2) in object code or executable form under the terms of
  130. Paragraphs 1 and 2 above provided that you also do one of the following:
  131. X
  132. X    a) accompany it with the complete corresponding machine-readable
  133. X    source code, which must be distributed under the terms of
  134. X    Paragraphs 1 and 2 above; or,
  135. X
  136. X    b) accompany it with a written offer, valid for at least three
  137. X    years, to give any third party free (except for a nominal charge
  138. X    for the cost of distribution) a complete machine-readable copy of the
  139. X    corresponding source code, to be distributed under the terms of
  140. X    Paragraphs 1 and 2 above; or,
  141. X
  142. X    c) accompany it with the information you received as to where the
  143. X    corresponding source code may be obtained.  (This alternative is
  144. X    allowed only for noncommercial distribution and only if you
  145. X    received the program in object code or executable form alone.)
  146. X
  147. Source code for a work means the preferred form of the work for making
  148. modifications to it.  For an executable file, complete source code means
  149. all the source code for all modules it contains; but, as a special
  150. exception, it need not include source code for modules which are standard
  151. libraries that accompany the operating system on which the executable
  152. file runs, or for standard header files or definitions files that
  153. accompany that operating system.
  154. X
  155. X  4. You may not copy, modify, sublicense, distribute or transfer the
  156. Program except as expressly provided under this General Public License.
  157. Any attempt otherwise to copy, modify, sublicense, distribute or transfer
  158. the Program is void, and will automatically terminate your rights to use
  159. the Program under this License.  However, parties who have received
  160. copies, or rights to use copies, from you under this General Public
  161. License will not have their licenses terminated so long as such parties
  162. remain in full compliance.
  163. X
  164. X  5. By copying, distributing or modifying the Program (or any work based
  165. on the Program) you indicate your acceptance of this license to do so,
  166. and all its terms and conditions.
  167. X
  168. X  6. Each time you redistribute the Program (or any work based on the
  169. Program), the recipient automatically receives a license from the original
  170. licensor to copy, distribute or modify the Program subject to these
  171. terms and conditions.  You may not impose any further restrictions on the
  172. recipients' exercise of the rights granted herein.
  173. X
  174. X  7. The Free Software Foundation may publish revised and/or new versions
  175. of the General Public License from time to time.  Such new versions will
  176. be similar in spirit to the present version, but may differ in detail to
  177. address new problems or concerns.
  178. X
  179. XEach version is given a distinguishing version number.  If the Program
  180. specifies a version number of the license which applies to it and "any
  181. later version", you have the option of following the terms and conditions
  182. either of that version or of any later version published by the Free
  183. Software Foundation.  If the Program does not specify a version number of
  184. the license, you may choose any version ever published by the Free Software
  185. XFoundation.
  186. X
  187. X  8. If you wish to incorporate parts of the Program into other free
  188. programs whose distribution conditions are different, write to the author
  189. to ask for permission.  For software which is copyrighted by the Free
  190. Software Foundation, write to the Free Software Foundation; we sometimes
  191. make exceptions for this.  Our decision will be guided by the two goals
  192. of preserving the free status of all derivatives of our free software and
  193. of promoting the sharing and reuse of software generally.
  194. X
  195. X                NO WARRANTY
  196. X
  197. X  9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
  198. XFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
  199. OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
  200. PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
  201. OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  202. MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
  203. TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
  204. PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
  205. REPAIR OR CORRECTION.
  206. X
  207. X  10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
  208. WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
  209. REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
  210. INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
  211. OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
  212. TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
  213. YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
  214. PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
  215. POSSIBILITY OF SUCH DAMAGES.
  216. X
  217. X             END OF TERMS AND CONDITIONS
  218. X
  219. X    Appendix: How to Apply These Terms to Your New Programs
  220. X
  221. X  If you develop a new program, and you want it to be of the greatest
  222. possible use to humanity, the best way to achieve this is to make it
  223. free software which everyone can redistribute and change under these
  224. terms.
  225. X
  226. X  To do so, attach the following notices to the program.  It is safest to
  227. attach them to the start of each source file to most effectively convey
  228. the exclusion of warranty; and each file should have at least the
  229. X"copyright" line and a pointer to where the full notice is found.
  230. X
  231. X    <one line to give the program's name and a brief idea of what it does.>
  232. X    Copyright (C) 19yy  <name of author>
  233. X
  234. X    This program is free software; you can redistribute it and/or modify
  235. X    it under the terms of the GNU General Public License as published by
  236. X    the Free Software Foundation; either version 1, or (at your option)
  237. X    any later version.
  238. X
  239. X    This program is distributed in the hope that it will be useful,
  240. X    but WITHOUT ANY WARRANTY; without even the implied warranty of
  241. X    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  242. X    GNU General Public License for more details.
  243. X
  244. X    You should have received a copy of the GNU General Public License
  245. X    along with this program; if not, write to the Free Software
  246. X    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  247. X
  248. Also add information on how to contact you by electronic and paper mail.
  249. X
  250. If the program is interactive, make it output a short notice like this
  251. when it starts in an interactive mode:
  252. X
  253. X    Gnomovision version 69, Copyright (C) 19xx name of author
  254. X    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
  255. X    This is free software, and you are welcome to redistribute it
  256. X    under certain conditions; type `show c' for details.
  257. X
  258. The hypothetical commands `show w' and `show c' should show the
  259. appropriate parts of the General Public License.  Of course, the
  260. commands you use may be called something other than `show w' and `show
  261. c'; they could even be mouse-clicks or menu items--whatever suits your
  262. program.
  263. X
  264. You should also get your employer (if you work as a programmer) or your
  265. school, if any, to sign a "copyright disclaimer" for the program, if
  266. necessary.  Here a sample; alter the names:
  267. X
  268. X  Yoyodyne, Inc., hereby disclaims all copyright interest in the
  269. X  program `Gnomovision' (a program to direct compilers to make passes
  270. X  at assemblers) written by James Hacker.
  271. X
  272. X  <signature of Ty Coon>, 1 April 1989
  273. X  Ty Coon, President of Vice
  274. X
  275. That's all there is to it!
  276. END_OF_FILE
  277. if test 12488 -ne `wc -c <'COPYING'`; then
  278.     echo shar: \"'COPYING'\" unpacked with wrong size!
  279. fi
  280. # end of 'COPYING'
  281. fi
  282. if test -f 'compiler/Cellang.tex' -a "${1}" != "-c" ; then 
  283.   echo shar: Will not clobber existing file \"'compiler/Cellang.tex'\"
  284. else
  285. echo shar: Extracting \"'compiler/Cellang.tex'\" \(21705 characters\)
  286. sed "s/^X//" >'compiler/Cellang.tex' <<'END_OF_FILE'
  287. X%  Cellang.tex
  288. X%  Copyright (C) 1992  J Dana Eckart
  289. X%
  290. X%  This program is free software; you can redistribute it and/or modify
  291. X%  it under the terms of the GNU General Public License as published by
  292. X%  the Free Software Foundation; either version 1, or (at your option)
  293. X%  any later version.
  294. X%
  295. X%  This program is distributed in the hope that it will be useful,
  296. X%  but WITHOUT ANY WARRANTY; without even the implied warranty of
  297. X%  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  298. X%  GNU General Public License for more details.
  299. X%
  300. X%  You should have received a copy of the GNU General Public License
  301. X%  along with CELLULAR-2.0; see the file COPYING.  If not, write to the 
  302. X%  Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  303. X
  304. X\documentstyle[twocolumn]{article}
  305. X
  306. X% Setup the desired page style.
  307. X\pagestyle{plain}
  308. X\setlength{\textwidth}{6.5in}
  309. X\setlength{\textheight}{8.75in}
  310. X\setlength{\oddsidemargin}{0mm}
  311. X\setlength{\evensidemargin}{0mm}
  312. X\setlength{\topmargin}{0mm}
  313. X\setlength{\headheight}{0mm}
  314. X\setlength{\headsep}{0mm}
  315. X
  316. X\setlength{\columnsep}{5mm}
  317. X
  318. X% Setup the desired paragraph style.
  319. X\setlength{\parindent}{0mm}
  320. X\setlength{\parskip}{3mm}
  321. X\begin{document}
  322. X
  323. X% A new command to define a constant tabbing distance for code examples.
  324. X\newcommand{\tab}{\hspace{5mm}}
  325. X
  326. X\title{Cellang 2.0: Language Reference Manual}
  327. X\author{J Dana Eckart\\
  328. X     Radford University}
  329. X\date{13 April 1992}
  330. X\maketitle
  331. X
  332. X
  333. X\section{Introduction}
  334. The Cellang programming language is a special purpose
  335. programming language for the programming of a wide variety of cellular
  336. automata.  The language is quite small and simple.  During
  337. its design, care was taken to create a language that would be expressive
  338. enough to allow a wide variety of cellular automata to be written
  339. while restricting the possible programs to those considered truly cellular
  340. in nature.
  341. Cellang is intended both as an aid in introducing university students to
  342. the wonderful world of cellular automata as well as a common language in
  343. which to describe such systems for both teaching and research purposes.
  344. X
  345. This reference manual specifies the form and meaning of Cellang programs.  
  346. Its purpose is to ensure the portability of Cellang programs.  Thus
  347. the set of accepted programs and the set of rejected programs should
  348. be identical for all Cellang compilers.
  349. XFurthermore, the proper execution of an accepted program should produce 
  350. the same result regardless of the compiler used.
  351. X
  352. X\subsection{Language Summary}
  353. Cellang programs are composed of comments, statements and a
  354. cell declaration.  The cell declaration indicates the number of dimensions
  355. of the automata, the number of field values
  356. contained within each cell of the automata, and the range of values
  357. associated with each field.  The cell declaration
  358. must appear before any statements are given.
  359. Statements are either selections
  360. or assignments and provide the only mechanism whereby cells can change
  361. state.
  362. Variables are implicitly declared at the point of first assignment and
  363. correspond to either a complete set of field values associated with a cell
  364. or to the only builtin data type, integer.  
  365. X
  366. X\subsection{Syntax Notation}
  367. A variant of Backus--Naur--Form is used to describe the form of Cellang 
  368. programs.  Narrative rules describe both the effects of each 
  369. construct and the composition rules for constructs.
  370. The particular variations of Backus--Naur--Form used are:
  371. X\begin{enumerate}
  372. X\item
  373. Lower case words, possibly containing underscores, are used to denote
  374. syntactic categories.
  375. Whenever the name of a syntactic category is used apart from the syntax rules
  376. themselves, spaces take the place of the underscores.
  377. X
  378. X\item
  379. Boldface is used to denote reserved keywords.
  380. X
  381. X\item
  382. Alternatives are separated by right arrows ($\rightarrow$).
  383. X
  384. X\item
  385. Curly braces enclose items that may appear zero or more times.
  386. X
  387. X\end{enumerate}
  388. X
  389. X\section{Lexical Elements}
  390. Programs are represented by collections of lexical elements.  Lexical
  391. elements are one of: comments, reserved keywords, identifiers, 
  392. operators, separators or numeric literals.  Lexical elements, in turn, are
  393. collections of ASCII (American Standard Code for Information Interchange)
  394. characters.
  395. X
  396. X\subsection{Comments}
  397. A comment starts with a sharp (\#) and extends to the end of the line.
  398. A comment can appear anywhere within a program.  The presence or absence
  399. of comments has no influence on whether a program is legal or illegal.
  400. XFurthermore, comments do not influence the effect of a program.
  401. Any character
  402. may appear within a comment, except of course any character denoting the
  403. end of a line.
  404. X
  405. X\subsection{Reserved Keywords}
  406. XFor readability of this manual, the reserved keywords appear in lower 
  407. case boldface.  The reserved keywords are:
  408. X\begin{center}
  409. X\begin{tabular}{lll}
  410. X{\bf dimensions}& {\bf elsif}    & {\bf otherwise } \\
  411. X{\bf end}     & {\bf if}    & {\bf then} \\
  412. X{\bf else}    & {\bf of}    & {\bf when} \\
  413. X\end{tabular}
  414. X\end{center}
  415. The case of the alphabetic characters that form a reserved keyword is
  416. ignored, thus {\tt ELsE} and {\tt eLSe} both represent the keyword {\bf else}.
  417. X
  418. X\subsection{Identifiers}
  419. Identifiers are used as names.  Identifiers must consist of at least
  420. one character, but are otherwise unlimited in length.  
  421. X\begin{center}
  422. X\begin{tabbing}
  423. underscore\_option \=$\rightarrow$ \kill
  424. X
  425. identifier         \>$\rightarrow$ letter \{ \= underscore\_option \\
  426. X            \>\>letter\_or\_digit \}\\
  427. X \\
  428. underscore\_option     \>$\rightarrow$ underscore \\
  429. X            \>$\rightarrow$ $\lambda$\\
  430. X\end{tabbing}
  431. X\end{center}
  432. Any identifier constructed from the above rules are legal except when it 
  433. also names
  434. a reserved keyword.  In this case the lexical element is a reserved
  435. keyword.  All characters of an identifier are significant, including 
  436. any underscore characters; however, as with reserved keywords,
  437. the case of the alphabetic characters that form an identifier are ignored.
  438. All non-reserved identifiers represent variables.  There are two predefined
  439. identifiers: {\tt cell} and {\tt time}.
  440. While {\tt time} can only be used within expressions (i.e. not assigned),
  441. X{\tt cell} can be used within expressions as well as assigned new values
  442. and refers to the cell with relative
  443. index {\tt [0, ..., 0]}.  The first lexical appearance of an 
  444. identifier, on the left hand side of an assignment statement,
  445. implicitly declares it as a variable.
  446. X
  447. X\subsection{Operators and Separators}
  448. The simple (one character) operators are:
  449. X\begin{center}
  450. X* \ / \ + \  -- \ \% \ = \ $<$ \ $>$ \ \& \ $|$ \ !\\
  451. X\end{center}
  452. and the compound (two character) operators are:
  453. X\begin{center}
  454. X$<=$ \ \ $>=$ \ \ $!=$ \\
  455. X\end{center}
  456. X
  457. In some cases an explicit separator is required to separate adjacent
  458. lexical elements (namely, when without separation, interpretation as a single
  459. lexical element is possible).  A separator is any of:
  460. X\begin{center}
  461. X[ \ ] \ , \ . \ := \ ..\\
  462. X\end{center}
  463. Space characters, format effectors, and the end of a line are also
  464. separators.  A space character is a separator
  465. except within a comment.
  466. XFormat effectors other than horizontal tabulation are always separators.
  467. Horizontal tabulation is a separator except within a comment.
  468. One or more separators are allowed before, after or between lexical elements.
  469. X
  470. The end of a line is always a separator.  The language does not define
  471. what causes the end of a line.  However if, for a given implementation,
  472. the end of a line is signified by one or more characters, then these
  473. characters must be format effectors.
  474. X
  475. X\subsection{Numeric Literals}
  476. A numeric literal is expressed in the conventional integer decimal notation.
  477. Underlines are ignored in determining the value of the numeric literal, thus
  478. they can be used to increase readability.
  479. X\begin{center}
  480. numeric\_literal $\rightarrow$ digit \{ underscore\_option digit \}\\
  481. X\end{center}
  482. X
  483. X\section{Syntax and Semantics}
  484. The lexical elements of the previous section are combined in accordance
  485. with the rules given in this section to form correct programs.  The
  486. semantics of these programs are also described.  Examples are used to
  487. clarify rules that might otherwise be confusing.
  488. X
  489. X\subsection{Cell Declaration}
  490. The cell declaration
  491. X describes the entire set of cells that make up the cellular automata.
  492. The declaration must appear only once in the program, and must precede
  493. any statements.
  494. X\begin{center}
  495. X\begin{tabbing}
  496. cell\_declaration \=$\rightarrow$ \= \tab \=\kill
  497. X
  498. cell\_declaration \>$\rightarrow$ numeric\_literal {\bf dimensions } {\bf of} \\
  499. X        \>\>\>field\_list\\
  500. X \\
  501. field\_list     \>$\rightarrow$ range\\
  502. X            \>$\rightarrow$ field \{ field \} {\bf end}\\
  503. X \\
  504. field        \>$\rightarrow$ ident\_list {\bf of} range\\
  505. X \\
  506. range         \>$\rightarrow$ integer .. integer\\
  507. X \\
  508. ident\_list     \>$\rightarrow$ identifier \{ , identifier \} \\
  509. X \\
  510. integer        \>$\rightarrow$ sign numeric\_literal\\
  511. X \\
  512. sign        \>$\rightarrow$ +\\
  513. X            \>$\rightarrow$ --\\
  514. X            \>$\rightarrow$ $\lambda$\\
  515. X
  516. X\end{tabbing}
  517. X\end{center}
  518. The numeric literal appearing before {\bf dimensions} specifies the
  519. number of dimensions, in a discrete cartesian space, to be used in 
  520. computations.  The maximum number of dimensions allowed, and the size of
  521. each, is determined by the implementation.  The field list gives a
  522. description of the information associated with each cell of the automata.
  523. If only a single field is given, then no field name (identifier) is needed.
  524. When more than one field is used, then each field is represented by an
  525. identifier and associated range.  An ident list allows a number of
  526. identifers to be associated with a single range.
  527. X
  528. A range defines an inclusive set of integer values.  The
  529. first is the lower bound and must be less than or equal to the second 
  530. which is the upper bound of the range.  A range indicates the permissible
  531. values that a field can be assigned.  It is an error to assign 
  532. a field a value outside of its associated range.  The maximal size and allowed
  533. bounds of a range are determined by the implementation.
  534. X
  535. XExamples:
  536. X\begin{center}
  537. X\begin{tabbing}
  538. X\tab \= \tab \= \tab \= \tab \= \tab \=\kill
  539. X\>2 {\bf dimensions} {\bf of} 0..255\\
  540. X \\
  541. X\>3 {\bf dimensions} {\bf of}\\
  542. X\>\>x, y {\bf of} --9..9\\
  543. X\>\>distance {\bf of} 0..999\\
  544. X\>{\bf end}\\
  545. X\end{tabbing}
  546. X\end{center}
  547. X
  548. X\subsection{Expressions}
  549. An expression is a formula that defines a computation.
  550. X\begin{center}
  551. X\begin{tabbing}
  552. field\_reference \=$\rightarrow$ \tab \= \kill
  553. X
  554. expression \>$\rightarrow$ expression\\
  555. X                \>\>\{ binary\_op expression \}\\
  556. X           \>$\rightarrow$ unary\_op expression\\
  557. X           \>$\rightarrow$ ( expression )\\
  558. X           \>$\rightarrow$ primary\\
  559. X \\
  560. unary\_op  \>$\rightarrow$ +\\
  561. X           \>$\rightarrow$ --\\
  562. X \\
  563. binary\_op \>$\rightarrow$ +\\
  564. X           \>$\rightarrow$ --\\
  565. X           \>$\rightarrow$ * \\
  566. X           \>$\rightarrow$ / \\
  567. X           \>$\rightarrow$ \% \\
  568. X           \>$\rightarrow$ \& \\
  569. X           \>$\rightarrow$ $|$ \\
  570. X           \>$\rightarrow$ ! \\
  571. X           \>$\rightarrow$ = \\
  572. X           \>$\rightarrow$ $<$ \\
  573. X           \>$\rightarrow$ $>$ \\
  574. X           \>$\rightarrow$ $<=$ \\
  575. X           \>$\rightarrow$ $>=$ \\
  576. X           \>$\rightarrow$ != \\
  577. X \\
  578. primary    \>$\rightarrow$ numeric\_literal\\
  579. X           \>$\rightarrow$ identifier field\_reference\\
  580. X           \>$\rightarrow$ [ index \{ , index \} ] field\_reference\\
  581. X \\
  582. field\_reference \>$\rightarrow$ . identifier \\
  583. X           \>$\rightarrow$ $\lambda$\\
  584. X \\
  585. index      \>$\rightarrow$ integer\\
  586. X\end{tabbing}
  587. X\end{center}
  588. The predefined identifier {\tt time} evaluates to
  589. the current step of the execution.  The initial value of {\tt time} is
  590. zero (0), and is increased by one (1) each time all of the cells in the
  591. automata have been updated.
  592. The predefined identifier {\tt cell} yields the value of the current
  593. cell, which is also the value of {\tt [0, ..., 0]}
  594. X
  595. There are 6 levels of precedence for the unary and binary operators.
  596. Operators belonging to the same level are evaluated from
  597. left to right.  The precedence levels, from highest to lowest are:
  598. X\begin{center}
  599. X\begin{enumerate}
  600. X\item
  601. X(unary) + \ --
  602. X\item
  603. X* \ / \ \% (remainder)
  604. X\item
  605. X(binary) + \ --
  606. X\item
  607. X= \ $<$ \ $>$ \ $!=$ \ $<=$ \ $>=$
  608. X\item
  609. X\& (logical and) \ $|$ (logical or)
  610. X\item
  611. X! (logical negation)
  612. X\end{enumerate}
  613. X\end{center}
  614. The relational and logical operations return integer values, with a zero value
  615. being returned when the condition is false and a non--zero value when the
  616. condition is true.  Note, however, that no assumption can be made about the
  617. non--zero value returned.  In particular, the non--zero values
  618. can be different for each evaluation of the same condition.  If no fields,
  619. of a multi--field value,
  620. are specified then only the equal (=) and not equal (!=) operations are
  621. applicable.  In this case, all the fields are used in the comparison.
  622. X
  623. When referencing a neighboring cell (using an index list contained within
  624. X[ \ ]), the number of indices given must match exactly the number of dimensions
  625. indicated by the cell declaration.  
  626. Such a reference is taken relative to
  627. the current cell of computation.  Since it is possible that adding the index 
  628. to the current cell location might give an index value outside the range of
  629. that dimension, ``wrap around'' is used to insure that the reference is
  630. a legal one.  Thus neighboring cell references can ``wrap around'' the edge
  631. of the cells of the automata.  
  632. XFurthermore, each relative indice must
  633. have an absolute value no larger than the size of the corresponding dimension
  634. X(as determined by the implemenatation). 
  635. The optional field reference should only be
  636. used if a named field was declared in the cell declaration.  The field
  637. reference indicates which field value to use.
  638. X
  639. X\subsection{Statements}
  640. A statement defines an action to be performed; the process by which
  641. a statement achieves its action is called execution of the statement.
  642. Cellang programs may contain any number of statements.
  643. X\begin{center}
  644. X\begin{tabbing}
  645. statement                \=$\rightarrow$ \kill
  646. X
  647. statement                \>$\rightarrow$ assignment\_statement \\
  648. X                         \>$\rightarrow$ if\_statement \\
  649. X\end{tabbing}
  650. X\end{center}
  651. All of the statements in a Cellang program are performed for each cell,
  652. once during each {\bf time} value.  Programs whose behavior depends on
  653. the relative order of statement execution between cells of the automata
  654. are erroneous.
  655. X
  656. X\subsubsection{Assignment Statement}
  657. An assignment statement permits the value of the variable on the
  658. left hand side of the first := to be set or changed.
  659. X\begin{center}
  660. X\begin{tabbing}
  661. assignment\_statement \=$\rightarrow$ \= \tab \= \tab \=\kill
  662. X
  663. assignment\_statement     \>$\rightarrow$ identifier field\_reference \\
  664. X            \>\>\>:= expression \\
  665. X            \>\>\>\>rest\_expression \\
  666. X \\
  667. rest\_expression     \>$\rightarrow$ rest\_when \\
  668. X                     \>$\rightarrow$ $\lambda$\\
  669. X \\
  670. rest\_when              \>$\rightarrow$ {\bf when} expression \\
  671. X            \>\>\>:= expression \\
  672. X            \>\>\>\>rest\_when \\
  673. X                        \>$\rightarrow$ {\bf when} expression \\
  674. X             \>$\rightarrow$ {\bf otherwise} \\
  675. X\end{tabbing}
  676. X\end{center}
  677. If no field reference is given and if the identifier has
  678. not previously appeared on the left hand side of an assignment statement,
  679. then the identifier is implicitly declared as a variable.  The variable
  680. is (statically) declared as either a single or multiple field variable 
  681. depending upon the value of the provided expression(s).  This implies that
  682. the expressions of the assignment statement must be either all single field
  683. or all multi--field expressions.  The range of values that can be assigned
  684. to the field(s) of a variable is determined by the implementation, but must
  685. be at least as large as the union of all field ranges given in the 
  686. cell declaration.  Programs which assign the field(s) of variable values 
  687. outside of its associated range are erroneous, though compilers are not
  688. required to generate run--time checks to detect such occurrences.
  689. X
  690. If a single expression (or a single expression followed by {\bf otherwise} )
  691. appears to the right of the := then that expression
  692. is assigned to the entity on the left hand side of the :=.  In the case that
  693. one or more {\bf when} clauses appear then the expression to the right
  694. of {\bf when} is evaluated first, if it is non--zero the value of the expression
  695. to the left of {\bf when} is assigned and execution of the assignment statement
  696. is complete.  In the case that the expression to the right of {\bf when}
  697. evaluates to zero, then successive {\bf when} clauses are tried in order.  
  698. If all
  699. expressions to the right of {\bf when} in all such clauses yield a zero value
  700. and if an expression to the left of {\bf otherwise} appears, its value
  701. is assigned.  If none of the {\bf when} conditions yield a non--zero value
  702. and if no {\bf otherwise} appears, then the value is unchanged.
  703. X
  704. Assigning a value to {\tt cell} causes the value of the current cell to
  705. become that value.  This is the only way that the value of cells
  706. of the automata can be altered.  Note, however, that that assignment(s) to
  707. X{\tt cell} determine the value that the current cell will have beginning with
  708. the next {\bf time} value.  Thus an assignment to {\tt cell} will NOT alter the
  709. value that {\tt cell} yields in an expression, for computations performed
  710. during the same {\bf time} value.  The variable {\tt cell} is the only variable
  711. that expresses this dual nature of present versus future value.
  712. X
  713. If fields were declared for the cells of the automata, and if no field
  714. reference was specified for a multi--field value, then all of the fields 
  715. are assigned.
  716. X
  717. XExamples:
  718. X\begin{center}
  719. X\begin{tabbing}
  720. X\tab\=maybe \=:= \kill
  721. X\>value \>:= max\_value -- 1\\
  722. X \\
  723. X\>shade \>:= blue {\bf otherwise}\\
  724. X \\
  725. X\>cell     \>:= blue {\bf when} time = 0\\
  726. X    \>\>:= orange {\bf otherwise}\\
  727. X \\
  728. X\>maybe \>:= 1 {\bf when} random = x\\
  729. X    \>\>:= 2 {\bf when} random = y\\
  730. X \\
  731. X\>max    \>:= north\\
  732. X\>max    \>:= south when south $>$ max\\
  733. X\>max    \>:= east when east $>$ max\\
  734. X\end{tabbing}
  735. X\end{center}
  736. X
  737. X\subsubsection{If Statements}
  738. An if statement selects for execution one or none of the enclosed
  739. statement lists, depending on the value of one or more conditions.
  740. X\begin{center}
  741. X\begin{tabbing}
  742. if\_statement \=$\rightarrow$ \= \tab \=\kill
  743. X
  744. if\_statement     \>$\rightarrow$ {\bf if} expression {\bf then}\\
  745. X              \>\>\>statement\_list\\
  746. X              \>\>\{ {\bf elsif} expression {\bf then}\\
  747. X              \>\>\>statement\_list \}\\
  748. X              \>\>else\_option\\
  749. X              \>\>{\bf end} \\
  750. X \\
  751. else\_option      \>$\rightarrow$ {\bf else} statement\_list \\
  752. X        \>$\rightarrow$ $\lambda$\\
  753. X\end{tabbing}
  754. X\end{center}
  755. XFor the execution of an if statement, the condition specified after {\bf if},
  756. and any conditions specified after {\bf elsif}, are evaluated in succession
  757. X(treating a final ``{\bf else}'' as ``{\bf elsif} non--zero {\bf then}''), 
  758. until one
  759. evaluates to a non--zero value or all conditions are evaluated and yield 
  760. zero values.  If
  761. a condition evaluates to non--zero, then the corresponding statement
  762. list is executed; otherwise none of the statement lists are executed.
  763. X
  764. XExample:
  765. X\begin{center}
  766. X\begin{tabbing}
  767. X\tab \= \tab \= \tab \= \tab \= \tab \=\kill
  768. X
  769. X\>{\bf if} neigbor\_count = 4 {\bf then}\\
  770. X\>\>cell := 0\\
  771. X\>{\bf elsif} neigbor\_count = 3 {\bf then}\\
  772. X\>\>cell := 1\\
  773. X\>\>count := count + 1\\
  774. X\>{\bf else}\\
  775. X\>\>cell := 0\\
  776. X\>{\bf end}\\
  777. X\end{tabbing}
  778. X\end{center}
  779. X
  780. X\section{Input and Output}
  781. The form of the input and output for Cellang programs is identical.
  782. X\begin{center}
  783. X\begin{tabbing}
  784. time\_block    \=$\rightarrow$ \= \tab \=\kill
  785. X
  786. i/o\_form     \>$\rightarrow$ \{ time\_block \}\\
  787. X \\
  788. time\_block    \> $\rightarrow$ time \{ cell\_value \}\\
  789. X \\
  790. cell\_value      \>$\rightarrow$ [ integer \{ , integer \} ] = value\_list\\
  791. X \\
  792. value\_list    \>$\rightarrow$ field\_value \{ , field\_value \}\\
  793. X \\
  794. field\_value     \>$\rightarrow$ integer \\
  795. X        \>$\rightarrow$ $\lambda$\\
  796. X \\
  797. time          \>$\rightarrow$ numeric\_literal \\
  798. X\end{tabbing}
  799. X\end{center}
  800. The time must be a non--negative number, which should be strictly larger
  801. than any previous time that has appeared in the input (for input) or
  802. output (for output).  The cell value is an absolute reference to a cell
  803. within the cells of the automata\footnote{
  804. X        The absolute index values for a dimension always
  805. X        begin at zero (0) and extend in the positive direction.
  806. X    }
  807. with the field values of the indicated cell taken as the respective numeric
  808. literal values given by the value list.  These are associated with the fields in
  809. the same order as the field identifiers were given in the cell declaration.
  810. The number of numeric literals in the value list must be no greater than the 
  811. number of fields given in the cell declaration.
  812. X
  813. As input, the cell values appearing after a time (and before the next time)
  814. give the new field values
  815. for all of the indicated cells; beginning at the specified time.
  816. The field values of
  817. all cells at time zero (0) is zero (0) unless otherwise specified.  No
  818. cells other than those specified by a cell value
  819. have their values altered and only those fields specified (indicated by
  820. supplying an integer value) are assigned new values.
  821. X
  822. In the output, cell values appearing after a specific time indicate the 
  823. field value of cells at the beginning of that time.  The field value(s)
  824. given are the field value(s) of the cell at that time.  As with the 
  825. input, the initial
  826. value of all cells of the automata zero (0) unless otherwise indicated.
  827. X
  828. Unlike the syntax for programs, the syntax of the input
  829. X(output) must also be given (appear) in a line oriented fashion.  In
  830. particular the time and cell value information must each reside on a
  831. single line of input (output) with no intervening blank lines.\footnote{
  832. X        This syntactic restriction makes the 
  833. X        construction of filter programs easier.
  834. X    }
  835. X
  836. X\end{document}
  837. END_OF_FILE
  838. if test 21705 -ne `wc -c <'compiler/Cellang.tex'`; then
  839.     echo shar: \"'compiler/Cellang.tex'\" unpacked with wrong size!
  840. fi
  841. # end of 'compiler/Cellang.tex'
  842. fi
  843. if test -f 'compiler/scanner.c' -a "${1}" != "-c" ; then 
  844.   echo shar: Will not clobber existing file \"'compiler/scanner.c'\"
  845. else
  846. echo shar: Extracting \"'compiler/scanner.c'\" \(6838 characters\)
  847. sed "s/^X//" >'compiler/scanner.c' <<'END_OF_FILE'
  848. X/* scanner.c
  849. X   Copyright (C) 1992  J Dana Eckart
  850. X  
  851. X   This program is free software; you can redistribute it and/or modify
  852. X   it under the terms of the GNU General Public License as published by
  853. X   the Free Software Foundation; either version 1, or (at your option)
  854. X   any later version.
  855. X  
  856. X   This program is distributed in the hope that it will be useful,
  857. X   but WITHOUT ANY WARRANTY; without even the implied warranty of
  858. X   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  859. X   GNU General Public License for more details.
  860. X  
  861. X   You should have received a copy of the GNU General Public License
  862. X   along with CELLULAR-2.0; see the file COPYING.  If not, write to the 
  863. X   Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  864. X*/
  865. X
  866. X/* This is a hand coded scanner for cellang. */
  867. X
  868. X#include <stdio.h>
  869. X#include "scanner.h"
  870. X#include "error.h"
  871. X#include "io.h"
  872. X
  873. X#define MAX_TOKEN_LENGTH     256     /* Maximum size of any token. */
  874. X
  875. char yytext[MAX_TOKEN_LENGTH];        /* Saved text of a token. */
  876. int yyleng;                /* Length of the saved text. */
  877. X
  878. int c;
  879. X
  880. boolean save_c = false;    /* True iff a character should be reused. */
  881. X
  882. int linenumber;     /* Current line number in the input stream. */
  883. X
  884. boolean scan_error;    /* True iff a scanning error was encountered. */
  885. X
  886. boolean one_error;    /* Used to limit one scanner error notice per token. */
  887. X
  888. X/* Performs the initialization to begin scanning a new file. */
  889. void startscan() {
  890. X    linenumber = 1;
  891. X    c = ' ';
  892. X    fprintf(file_c, "\n#line %d\n", linenumber);
  893. X}
  894. X
  895. X/* Gets the next character.  Responsible for updating "linenumber". */
  896. int get_char() {
  897. X    if (!save_c) {
  898. X        if (c == '\n') {
  899. X            linenumber++;
  900. X            fprintf(file_c, "\n#line %d\n", linenumber);
  901. X        }
  902. X        c = getc(stdin);
  903. X    }
  904. X    else save_c = false;
  905. X    return (c);
  906. X}
  907. X
  908. X/* Prints out the prefix that appears before all compiler generated
  909. X   error messages.  The form of the prefix is:
  910. X        "line line_number: "
  911. X   where line_number is replaced with the appropriate information.
  912. X*/
  913. void error_prefix() {
  914. X    fprintf(stderr, "line %d: ", linenumber);
  915. X}
  916. X
  917. X/* Takes a string format and a string with which to build an
  918. X   error message.  The message is automatically prepended with
  919. X   the current linenumber.
  920. X*/
  921. void lex_error(format, string) char *format, *string; {
  922. X    if (one_error) return;
  923. X    one_error = true;
  924. X    scan_error = true;
  925. X    error_prefix();
  926. X    fprintf(stderr, format, string);
  927. X    fprintf(stderr, "\n");
  928. X}
  929. X
  930. X/* Saves the character c in yytext.  Checks to insure that the maximum
  931. X   token length has not been exceeded.
  932. X*/
  933. void save(c) char c; {
  934. X    if (yyleng == 256 && !one_error) {
  935. X        one_error = true;
  936. X        yytext[yyleng] = '\0';
  937. X        lex_error("Token '%s' is too long", yytext);
  938. X    }
  939. X    else yytext[yyleng++] = c;
  940. X}
  941. X
  942. X/* Recognizes comments: #[^#"\n"]"\n"
  943. X   No text is saved.
  944. X*/
  945. void comment() {
  946. X    c = get_char();
  947. X    while (c != '\n') c = get_char();
  948. X}
  949. X
  950. X/* Skips comments, blanks, tabs and new lines. */
  951. void skip_white_space() {
  952. X    while (c >= 0) {
  953. X        if (c == '#') comment();
  954. X        else if (c <= 32 || c == 127) c = get_char();
  955. X        else break;
  956. X    }
  957. X}
  958. X
  959. X/* Recognizes numeric literals: [0-9]+(_[0-9]+)* 
  960. X   Underscores are stripped out.
  961. X*/
  962. void integer() {
  963. X    boolean error;
  964. X    error = false;
  965. X    while ('0' <= c && c <= '9') {
  966. X        save(c);
  967. X        c = get_char();
  968. X        if (c == '_') {
  969. X            c = get_char();
  970. X            if (c < '0' || '9' > c) error = true;
  971. X        }
  972. X    }
  973. X    save_c = true;
  974. X    yytext[yyleng] = '\0';
  975. X    if (error) lex_error("Illegal underscore in '%s'", yytext);
  976. X}
  977. X
  978. X
  979. X/* Recognizes identifiers (and keywords): [A-Za-z][A-Za-z0-9]*(_[A-Za-z0-9]+)*
  980. X   Identifiers (and keywords) are converted to lower case.
  981. X*/
  982. void identifier() {
  983. X    boolean error;
  984. X    error = false;
  985. X    while (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') ||
  986. X           ('0' <= c && c <= '9')) {
  987. X        if ('A' <= c && c <= 'Z') c = 'a' + (c - 'A');
  988. X        save(c);
  989. X        c = get_char();
  990. X        if (c == '_') {
  991. X            save(c);
  992. X            c = get_char();
  993. X            if (c == '_') error = true;
  994. X        }
  995. X    }
  996. X    save_c = true;
  997. X    yytext[yyleng] = '\0';
  998. X    if (error) lex_error("Illegal underscore in '%s'", yytext);
  999. X}
  1000. X
  1001. X/* The record "string_number" associates a reserved word with its token
  1002. X   number.  The "table" is a collection of these associations.  The 
  1003. X   function "lookup" uses the table to determine whether or not yytext
  1004. X   contains a reserved word.  If it does it's token number is returned,
  1005. X   else the token number of an identifier is returned.
  1006. X*/
  1007. X
  1008. typedef struct {
  1009. X    char *string;
  1010. X    int number;
  1011. X} string_number;
  1012. X
  1013. X#define MAX_TABLE 9
  1014. X
  1015. static string_number table[MAX_TABLE] = {
  1016. X    {"dimensions", DIMENSIONS},
  1017. X    {"else", ELSE},
  1018. X    {"elsif", ELSIF},
  1019. X    {"end", END},
  1020. X    {"if", IF},
  1021. X    {"of", OF},
  1022. X    {"otherwise", OTHERWISE},
  1023. X    {"then", THEN},
  1024. X    {"when", WHEN}
  1025. X};
  1026. X
  1027. X#include <strings.h>
  1028. X
  1029. X/* Performs a binary search to determine if the identifier is a
  1030. X   reserved word.
  1031. X*/
  1032. int lookup() {
  1033. X    int upper, middle, lower;
  1034. X    upper = MAX_TABLE - 1;
  1035. X    lower = 0;
  1036. X    while (lower <= upper) {
  1037. X        int cmp;
  1038. X        middle = (upper + lower) / 2;
  1039. X        cmp = strcmp(yytext, table[middle].string);
  1040. X        if (cmp < 0) upper = middle - 1;
  1041. X        else if (cmp > 0) lower = middle + 1;
  1042. X        else return table[middle].number;
  1043. X    }
  1044. X    return IDENTIFIER;
  1045. X}
  1046. X
  1047. X/* This is the procedure called by the parser generated by bison.  It
  1048. X   returns integer token numbers that depend upon the token read.  
  1049. X   White space that occurs between tokens is always skipped.  A legal
  1050. X   token is always returned, even if several errors occur while scan-
  1051. X   ning such a token. 
  1052. X*/
  1053. int yylex() {
  1054. X    while (1) {    /* Search until you find something. */
  1055. X        yyleng = 0;
  1056. X        one_error = false;
  1057. X        c = get_char();
  1058. X        skip_white_space();
  1059. X        if (c < 0) return(c);
  1060. X        else if ('0' <= c && c <= '9') {
  1061. X            integer();
  1062. X            return(NUMERICLITERAL);
  1063. X        }
  1064. X        else if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')) {
  1065. X            identifier();
  1066. X            return(lookup());
  1067. X        }
  1068. X        else switch(c) {
  1069. X        case '+':    return(PLUS);
  1070. X        case '-':    return(MINUS);
  1071. X        case '*':    return(TIMES);
  1072. X        case '/':    return(DIVIDE);
  1073. X        case '%':    return(MOD);
  1074. X        case '&':    return(AND);
  1075. X        case '|':    return(OR);
  1076. X        case '!':    c = get_char();
  1077. X                if (c == '=') return(NOTEQ);
  1078. X                else {
  1079. X                    save_c = true;
  1080. X                    return(NOT);
  1081. X                }
  1082. X        case '=':    return(EQUAL);
  1083. X        case '<':    c = get_char();
  1084. X                if (c == '=') return(LESSEQ);
  1085. X                else {
  1086. X                    save_c = true;
  1087. X                    return(LESSER);
  1088. X                }
  1089. X        case '>':    c = get_char();
  1090. X                if (c == '=') return(GREATEQ);
  1091. X                else {
  1092. X                    save_c = true;
  1093. X                    return(GREATER);
  1094. X                }
  1095. X        case '(':    return(LEFTPAREN);
  1096. X        case ')':    return(RIGHTPAREN);
  1097. X        case '[':    return(LEFTBRACKET);
  1098. X        case ']':    return(RIGHTBRACKET);
  1099. X        case ':':    save(c);
  1100. X                c = get_char();
  1101. X                if (c == '=') return(ASSIGN);
  1102. X                else {
  1103. X                    save_c = true;
  1104. X                    yytext[yyleng] = '\0';
  1105. X                    lex_error("Illegal use of '%s'", 
  1106. X                          yytext);
  1107. X                }
  1108. X        case ',':    return(COMMA);
  1109. X        case '.':    c = get_char();
  1110. X                if (c == '.') return(DOTS);
  1111. X                else {
  1112. X                    save_c = true;
  1113. X                    return(DOT);
  1114. X                }
  1115. X        default:    save(c);
  1116. X                yytext[yyleng] = '\0';
  1117. X                lex_error("Illegal use of '%s'", yytext);
  1118. X        }
  1119. X    }
  1120. X}
  1121. END_OF_FILE
  1122. if test 6838 -ne `wc -c <'compiler/scanner.c'`; then
  1123.     echo shar: \"'compiler/scanner.c'\" unpacked with wrong size!
  1124. fi
  1125. # end of 'compiler/scanner.c'
  1126. fi
  1127. if test -f 'driver/pe-scam.man' -a "${1}" != "-c" ; then 
  1128.   echo shar: Will not clobber existing file \"'driver/pe-scam.man'\"
  1129. else
  1130. echo shar: Extracting \"'driver/pe-scam.man'\" \(7186 characters\)
  1131. sed "s/^X//" >'driver/pe-scam.man' <<'END_OF_FILE'
  1132. X.TH pe-scam 1
  1133. X.SH NAME
  1134. pe-scam \- 
  1135. X.I "Cellang 2.0"
  1136. X(cellular automata) machine driver
  1137. X.SH SYNOPSIS
  1138. X.B pe-scam
  1139. X[
  1140. X.B \-r " timefile"
  1141. X] 
  1142. X[
  1143. X.B \-c " codefile"
  1144. X]
  1145. X(
  1146. X.B \-o
  1147. X|
  1148. X[
  1149. X.B \-curses
  1150. X|
  1151. X.B \-x11
  1152. X[
  1153. X.BI \-display " connection"
  1154. X]
  1155. X]
  1156. X[
  1157. X.BI \-p " n"
  1158. X]
  1159. X[
  1160. X.BI \-s " (n|n,n)"
  1161. X]
  1162. X[
  1163. X.BI \-map " file"
  1164. X]
  1165. X[
  1166. X.BI \-f " n"
  1167. X]
  1168. X[
  1169. X.BI \-dim " (n|n..n){,n|,n..n}"
  1170. X]
  1171. X)
  1172. X.SH DESCRIPTION
  1173. X.I pe-scam
  1174. is the driver which controls the pe-scam architecture for running cellular
  1175. automata programs.  It can either display the results of the run in the
  1176. same fashion as
  1177. X.I cellview
  1178. or it can place the cell values on the standard output (
  1179. X.B \-o
  1180. X).  In either case, the input to the automata is taken from standard input.
  1181. X.TP
  1182. X.B \-c " codefile"
  1183. Specifies the program to run, where
  1184. X.B codefile
  1185. contains the pe-scam object code for some Cellang 2.0 program.  The default
  1186. file to use is 
  1187. X.I a.pe-scam.
  1188. X.TP
  1189. X.B \-r " timefile"
  1190. Indicates when cell values should be reported/sampled.
  1191. X.B timefile 
  1192. is a list of time indications given one per line.  A number indicates a
  1193. time when the values should be
  1194. reported.  If a ``+'' appears before the number, this causes values to be 
  1195. produced at the indicated time intervals.  If a ``!'' appearing after
  1196. the number, this indicates the time at which the last set of values should 
  1197. be produced and the simulation stops.
  1198. Note that a 
  1199. X.B timefile 
  1200. need not contain a ``!'' entry.
  1201. X.TP
  1202. X.B \-o
  1203. Place the cell values on the standard output rather than viewing them.  The
  1204. default is to view them in the manner of
  1205. X.I cellview
  1206. X.
  1207. X.TP
  1208. X.B \-curses
  1209. View the output in character mode.  This makes it possible to view the
  1210. output of Cellang programs on most ordinary terminals.  The
  1211. X.B \-x11
  1212. option is more desirable, however, when working on a graphics terminal
  1213. or workstation.  This option is the default.  To quit, you must kill the
  1214. process (probably ^C).
  1215. X.TP
  1216. X.B \-x11
  1217. View the output in the X-Windows windowing environment.  A window is opened
  1218. and the output shown using colors rather than characters (see the
  1219. X.B \-curses
  1220. option).  This is the preferred way to examine the output of Cellang programs.
  1221. The following key stroke commands are available:
  1222. X.bf
  1223. X.nf
  1224. X
  1225. X       q or Q to quit
  1226. X       s or S to stop (temporarily)
  1227. X       c or C to continue (from a stop)
  1228. X       n or N to toggle neighborhood window display
  1229. X
  1230. X.fi
  1231. Within the focus of the neighborhood window, typing a single digit will
  1232. change the size of the displayed neighborhood.  The values shown in the
  1233. neighborhood window are those centered about the chosen cursor location
  1234. inside the main viewing window.  Cursor locations are chosen by clicking
  1235. any of the mouse points when the cursor is positioned at the desired point.
  1236. The initial cursor location is taken to be the center of the viewing area.
  1237. Note that whenever a value is too large to be shown, hyphens
  1238. are displayed instead of the value.
  1239. X.TP
  1240. X.BI \-display " connection"
  1241. Connect to the X server display,
  1242. X.IR connection.
  1243. X.TP
  1244. X.BI \-p " n"
  1245. If 
  1246. X.I n 
  1247. is positive, then this will cause an 
  1248. X.I n 
  1249. second delay between displaying
  1250. the cells of the universe of each time step.  Negative values of 
  1251. X.I n 
  1252. are ignored.  The default pause time is 0.
  1253. X.TP
  1254. X.BI \-s " (n|n,n)"
  1255. XFor the first option, if
  1256. X.I n
  1257. is positive, it is taken as the size of each cell (i.e. the number of pixels
  1258. used for each side of a displayed cell) when
  1259. the results are first displayed; provided that using this value will
  1260. allow all of the cells to be displayed.  The second option allows both
  1261. the width and height of displayed cells to be specified.  If neither the
  1262. width nor the height are, a default value of 1 is used.
  1263. X.TP
  1264. X.BI \-map " file"
  1265. Uses the map contained in 
  1266. X.I file 
  1267. when displaying cell values.  Entries in the 
  1268. X.I file 
  1269. appear one per line, with the first entry being either an
  1270. integer value or an increasing range of integer values (e.g. -12..100).
  1271. The second entry is either a character (for use with the
  1272. X.B \-curses
  1273. option) or a color indication
  1274. X(for use with the
  1275. X.B \-x11
  1276. option).  
  1277. The color indication is either a triplet of unsigned (positive) 
  1278. integers (0..65535) associated with 
  1279. the amount of red, green and blue "pigment" to use to represent the color 
  1280. or it is a 0 or 1 (representing white and black respectively) when using
  1281. monochrome displays.
  1282. When giving the character values for use by the
  1283. X.B \-curses
  1284. option, the character may appear either within single quotes or given
  1285. as the decimal ascii code.
  1286. Comments about a particular value mapping may appear on the
  1287. remainder of the line.
  1288. X.TP
  1289. X.BI \-f " n"
  1290. Indicates which field of the cell values should be used for display.  The
  1291. default is to use the first field (
  1292. X.BI \-f " 1"
  1293. X).
  1294. X.TP
  1295. X.BI \-dim " (n|n..n){,n|,n..n}"
  1296. Indicates which of the dimensions are to be used for viewing as well as
  1297. which parts of that dimension to display.  The dimensions must be given
  1298. in the order they appear in the input.  A single number indicates a
  1299. projection on that dimension, while ranges of the form
  1300. X.I n..n
  1301. indicate which cells of the specified dimension to display.  The range must be
  1302. increasing.
  1303. No spaces should appear anywhere within the dimension indicator.
  1304. The number of ranges given for display can be zero (0), one (1) or
  1305. two (2); but the number of dimensions specified must be the same as those
  1306. given in the input.  The default for curses is
  1307. X.BI \-dim 0..20,0..20
  1308. while the default for x11 is
  1309. X.BI \-dim 0..MAX_DIM_SIZE,0..MAX_DIM_SIZE
  1310. X.br
  1311. X.ne 5
  1312. X.SH FILES
  1313. file                            file of color/character maps
  1314. LIB_DIR/curses-map       default map for curses option
  1315. LIB_DIR/color-map        default color map for x11 option
  1316. LIB_DIR/bw-map           default black/white map for x11 option
  1317. X.SH "SEE ALSO"
  1318. cellc(MAN_EXT), cellview(MAN_EXT)
  1319. X.br
  1320. J Dana Eckart,
  1321. X.I "A Cellular Automata Simulation System: Version 2.0"
  1322. X(1992)
  1323. X.br
  1324. J Dana Eckart,
  1325. X.I "Cellang 2.0: Language Reference Manual"
  1326. X(1992)
  1327. X.SH DIAGNOSTICS
  1328. The diagnostics produced by cellview are intended to be
  1329. self-explanatory.
  1330. X.SH BUGS
  1331. X.PP
  1332. All values, including intermediate values, of the cellular automata
  1333. computation are limited to the range 0..255 inclusive.
  1334. X.PP
  1335. The maximum size of a color/character map is 256 entries.  
  1336. X.PP
  1337. Key stroke commands (i.e. quitting) should be permitted with the curses 
  1338. viewing option.  Unfortunately
  1339. this cannot be done since the standard input is already being used for
  1340. reading in the cell values.
  1341. X.PP
  1342. When the
  1343. X.B \-curses
  1344. option is chosen, the maximum number of cells which can be displayed
  1345. is determined by the size of the screen.  The choice of the
  1346. X.B \-x11
  1347. option however permits the size to be scaled to fit the display, with
  1348. the largest cell size limited to 256 pixels square.  Ultimately, both
  1349. options should allow the window to be moved over the cells of the
  1350. universe so that no such limitations would be present.
  1351. X.PP
  1352. When using the
  1353. X.B \-x11
  1354. option, the two first dimensions are displayed by default.  If a different
  1355. view is desired, the
  1356. X.B \-o
  1357. option should be chosen, and its output sent to cellview(MAN_EXT).
  1358. X.PP
  1359. The maximum size of a neighborhood which can be examined using the neighborhood
  1360. sub-window is 9, which encompasses a 19 x 19 region centered about the selected
  1361. cell.  In addition, only neighbor values between -999 and 999 can be displayed.
  1362. END_OF_FILE
  1363. if test 7186 -ne `wc -c <'driver/pe-scam.man'`; then
  1364.     echo shar: \"'driver/pe-scam.man'\" unpacked with wrong size!
  1365. fi
  1366. # end of 'driver/pe-scam.man'
  1367. fi
  1368. if test -f 'viewer/cellview.man' -a "${1}" != "-c" ; then 
  1369.   echo shar: Will not clobber existing file \"'viewer/cellview.man'\"
  1370. else
  1371. echo shar: Extracting \"'viewer/cellview.man'\" \(6243 characters\)
  1372. sed "s/^X//" >'viewer/cellview.man' <<'END_OF_FILE'
  1373. X.TH cellview 1
  1374. X.SH NAME
  1375. cellview \- cellular automata viewer
  1376. X.SH SYNOPSIS
  1377. X.B cellview
  1378. X[
  1379. X.B \-curses
  1380. X|
  1381. X.B \-x11
  1382. X[
  1383. X.BI \-display " connection"
  1384. X]
  1385. X]
  1386. X[
  1387. X.BI \-p " n"
  1388. X]
  1389. X[
  1390. X.BI \-s " (n|n,n)"
  1391. X]
  1392. X[
  1393. X.BI \-map " file"
  1394. X]
  1395. X[
  1396. X.BI \-f " n"
  1397. X]
  1398. X.BI \-dim " (n|n..n){,n|,n..n}"
  1399. X.SH DESCRIPTION
  1400. X.I cellview
  1401. is the viewer for looking at the output of Cellang programs.
  1402. X.I cellview
  1403. uses a map of values to colors (characters when the -curses option is
  1404. used) to display one (1) or two (2) dimensions of the output of a Cellang 
  1405. program;
  1406. even though the output of the Cellang program may contain far more than 
  1407. two (2) dimensions.  The input to
  1408. X.I cellview
  1409. is always taken from standard input.
  1410. Upon display, the lower left hand corner of the view corresponds to the
  1411. first index in each (if more than one) range of the dimension(s) being 
  1412. displayed.
  1413. At time zero (0) all cells default to the color/character mapped from the
  1414. zero (0) value, except when specified otherwise by the input.  The current
  1415. time is displayed in the lower left hand corner.
  1416. X.TP
  1417. X.B \-curses
  1418. View the output in character mode.  This makes it possible to view the
  1419. output of Cellang programs on most ordinary terminals.  The
  1420. X.B \-x11
  1421. option is more desirable, however, when working on a graphics terminal
  1422. or workstation.  This option is the default.  To quit, you must kill the
  1423. process (probably ^C).
  1424. X.TP
  1425. X.B \-x11
  1426. View the output in the X-Windows windowing environment.  A window is opened
  1427. and the output shown using colors rather than characters (see the
  1428. X.B \-curses
  1429. option).  This is the preferred way to examine the output of Cellang programs.
  1430. The following key stroke commands are available:
  1431. X.bf
  1432. X.nf
  1433. X
  1434. X       q or Q to quit
  1435. X       s or S to stop (temporarily)
  1436. X       c or C to continue (from a stop)
  1437. X       n or N to toggle neighborhood window display
  1438. X
  1439. X.fi
  1440. Within the focus of the neighborhood window, typing a single digit will
  1441. change the size of the displayed neighborhood.  The values shown in the
  1442. neighborhood window are those centered about the chosen cursor location
  1443. inside the main viewing window.  Cursor locations are chosen by clicking
  1444. any of the mouse points when the cursor is positioned at the desired point.
  1445. The initial cursor location is taken to be the center of the viewing area.
  1446. Note that whenever a value is too large to be shown, hyphens
  1447. are displayed instead of the value.
  1448. X.TP
  1449. X.BI \-display " connection"
  1450. Connect to the X server display,
  1451. X.IR connection.
  1452. X.TP
  1453. X.BI \-p " n"
  1454. If 
  1455. X.I n 
  1456. is positive, then this will cause an 
  1457. X.I n 
  1458. second delay between displaying
  1459. the cells of the universe of each time step.  Negative values of 
  1460. X.I n 
  1461. are ignored.  The default pause time is 0.
  1462. X.TP
  1463. X.BI \-s " (n|n,n)"
  1464. XFor the first option, if
  1465. X.I n
  1466. is positive, it is taken as the size of each cell (i.e. the number of pixels 
  1467. used for each side of a displayed cell) when
  1468. the results are first displayed; provided that using this value will
  1469. allow all of the cells to be displayed.  The second option allows both 
  1470. the width and height of displayed cells to be specified.  If neither the 
  1471. width nor the height are, a default value of 1 is used.
  1472. X.TP
  1473. X.BI \-map " file"
  1474. Uses the map contained in 
  1475. X.I file 
  1476. when displaying cell values.  Entries in the 
  1477. X.I file 
  1478. appear one per line, with the first entry being either an
  1479. integer value or an increasing range of integer values (e.g. -12..100).
  1480. The second entry is either a character (for use with the
  1481. X.B \-curses
  1482. option) or a color indication
  1483. X(for use with the
  1484. X.B \-x11
  1485. option).  
  1486. The color indication is either a triplet of unsigned (positive) 
  1487. integers (0..65535) associated with 
  1488. the amount of red, green and blue "pigment" to use to represent the color 
  1489. or it is a 0 or 1 (representing white and black respectively) when using
  1490. monochrome displays.
  1491. When giving the character values for use by the
  1492. X.B \-curses
  1493. option, the character may appear either within single quotes or given
  1494. as the decimal ascii code.
  1495. Comments about a particular value mapping may appear on the
  1496. remainder of the line.
  1497. X.TP
  1498. X.BI \-f " n"
  1499. Indicates which field of the cell values should be used for display.  The
  1500. default is to use the first field (
  1501. X.BI -f " 1"
  1502. X).
  1503. X.TP
  1504. X.BI \-dim " [n|n..n]{,n|,n..n}"
  1505. Indicates which of the dimensions are to be used for viewing as well as
  1506. which parts of that dimension to display.  The dimensions must be given
  1507. in the order they appear in the input.  A single number indicates a
  1508. projection on that dimension, while ranges of the form
  1509. X.I n..n
  1510. indicate which cells of the specified dimension to display.  The range must be
  1511. increasing.
  1512. No spaces should appear anywhere within the dimension indicator.
  1513. The number of ranges given for display can be zero (0), one (1) or 
  1514. two (2); but the number of dimensions specified must be the same as those
  1515. given in the input.
  1516. X.br
  1517. X.ne 5
  1518. X.SH FILES
  1519. file                            file of color/character maps
  1520. LIB_DIR/curses-map       default map for curses option
  1521. LIB_DIR/color-map        default color map for x11 option
  1522. LIB_DIR/bw-map           default black/white map for x11 option
  1523. X.SH "SEE ALSO"
  1524. cellc(MAN_EXT), pe-scam(MAN_EXT)
  1525. X.br
  1526. J Dana Eckart,
  1527. X.I "A Cellular Automata Simulation System: Version 2.0"
  1528. X(1992)
  1529. X.br
  1530. J Dana Eckart,
  1531. X.I "Cellang 2.0: Language Reference Manual"
  1532. X(1992)
  1533. X.SH DIAGNOSTICS
  1534. The diagnostics produced by cellview are intended to be
  1535. self-explanatory.
  1536. X.SH BUGS
  1537. X.PP
  1538. The maximum size of a color/character map is 256 entries.  
  1539. X.PP
  1540. Key stroke commands (i.e. quitting) should be permitted with the curses 
  1541. viewing option.  Unfortunately
  1542. this cannot be done since the standard input is already being used for
  1543. reading in the cell values.
  1544. X.PP
  1545. When the
  1546. X.B \-curses
  1547. option is chosen, the maximum number of cells which can be displayed
  1548. is determined by the size of the screen.  The choice of the
  1549. X.B \-x11
  1550. option however permits the size to be scaled to fit the display, with
  1551. the largest cell size limited to 256 pixels square.  Ultimately, both
  1552. options should allow the window to be moved over the cells of the
  1553. universe so that no such limitations would be present.
  1554. X.PP
  1555. The maximum size of a neighborhood which can be examined using the neighborhood
  1556. sub-window is 9, which encompasses a 19 x 19 region centered about the selected
  1557. cell.  In addition, only neighbor values between -999 and 999 can be displayed.
  1558. END_OF_FILE
  1559. if test 6243 -ne `wc -c <'viewer/cellview.man'`; then
  1560.     echo shar: \"'viewer/cellview.man'\" unpacked with wrong size!
  1561. fi
  1562. # end of 'viewer/cellview.man'
  1563. fi
  1564. if test -f 'viewer/view.c' -a "${1}" != "-c" ; then 
  1565.   echo shar: Will not clobber existing file \"'viewer/view.c'\"
  1566. else
  1567. echo shar: Extracting \"'viewer/view.c'\" \(15058 characters\)
  1568. sed "s/^X//" >'viewer/view.c' <<'END_OF_FILE'
  1569. X/* view.c
  1570. X   Copyright (C) 1992  J Dana Eckart
  1571. X  
  1572. X   This program is free software; you can redistribute it and/or modify
  1573. X   it under the terms of the GNU General Public License as published by
  1574. X   the Free Software Foundation; either version 1, or (at your option)
  1575. X   any later version.
  1576. X  
  1577. X   This program is distributed in the hope that it will be useful,
  1578. X   but WITHOUT ANY WARRANTY; without even the implied warranty of
  1579. X   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1580. X   GNU General Public License for more details.
  1581. X  
  1582. X   You should have received a copy of the GNU General Public License
  1583. X   along with CELLULAR-2.0; see the file COPYING.  If not, write to the 
  1584. X   Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1585. X*/
  1586. X
  1587. X/* This is the default display type. */
  1588. X#define DEFAULT_DISPLAY        curses_option
  1589. X
  1590. X#include <stdio.h>
  1591. X#include <signal.h>
  1592. X#include <stdlib.h>
  1593. X#include <malloc.h>
  1594. X#include <string.h>
  1595. X#include "view.h"
  1596. X#include "curses.h"
  1597. X#include "boolean.h"
  1598. X
  1599. X/* The cellular universe which contains the colors/characters that
  1600. X   correspond to the cell values which are read.
  1601. X*/
  1602. celltype *cell_vals;
  1603. X
  1604. X/* The number of dimensions specified to display. */
  1605. int dim_given = 0;
  1606. X
  1607. X#if !COMBINED
  1608. X/* Contains the current time. */
  1609. unsigned long int _time = 0;
  1610. X
  1611. X/* Contains the time of the next block of cell value entries. */
  1612. long int next_time = 0;
  1613. X#endif
  1614. X
  1615. X/* The default amount of time to pause between displaying time steps. */
  1616. long int pause_time = 0;
  1617. X
  1618. X/* Contains the current entry number within a particular block of
  1619. X   cell value entries.  It's only purpose is in error messages to
  1620. X   better indicate their location within the input.
  1621. X*/
  1622. long int entry = 0;
  1623. X
  1624. X/* The values of the following variables determine which method of
  1625. X   display has been chosen.
  1626. X*/
  1627. short curses_option = false, x11_option = false;
  1628. X
  1629. X/* Global variable set in "main", which is the name of this program. */
  1630. char *command = NULL;
  1631. X
  1632. X/* Decides which cleanup actions to perform. */
  1633. void finish_up() {
  1634. X    /* Do whichever cleanup is necessary. */
  1635. X    if (curses_option) finish_curses();
  1636. X    else if (x11_option) finish_x11();
  1637. X}
  1638. X
  1639. X/* Performs the actions desired when a kill signal is received. */
  1640. void exit_signaled() {
  1641. X    finish_up();
  1642. X    exit(0);
  1643. X}
  1644. X
  1645. X/* Prints out the error message in a standard format and exits.  This
  1646. X   format is intended for use when the problem is with other than the
  1647. X   input.
  1648. X*/
  1649. void error(format, string) char *format, *string; {
  1650. X    char error_msg[MAX_STRING_SIZE];
  1651. X    sprintf(error_msg, format, string);
  1652. X    fprintf(stderr, "%s: %s.\n", command, error_msg);
  1653. X    exit(1);
  1654. X}
  1655. X
  1656. X/* Prints out the error message in a standard format and exits.  This
  1657. X   format is intended for use when there is a problem with the input.
  1658. X*/
  1659. void input_error(format, string) char *format, *string; {
  1660. X    char error_msg[MAX_STRING_SIZE];
  1661. X    sprintf(error_msg, format, string);
  1662. X    fprintf(stderr, "%s: time %d, entry %d: %s.\n",
  1663. X        command, _time, entry, error_msg);
  1664. X    finish_up();
  1665. X    exit(1);
  1666. X}
  1667. X
  1668. X/* Array of ranges and associated colors (i.e. the map). */
  1669. struct {
  1670. X    int lower, upper;
  1671. X    celltype color;
  1672. X        
  1673. X} map[MAX_MAP_SIZE];
  1674. X
  1675. X/* Number of map entries given. */
  1676. int max_map_entry = 0;
  1677. X
  1678. X/* Read in the color map from the map_name file. */
  1679. void read_map(map_name, black_and_white) char *map_name; int black_and_white; {
  1680. X    FILE *map_file = fopen(map_name, "r");
  1681. X
  1682. X    if (NULL == map_file)
  1683. X        error("Unable to open map file '%s'", map_name);
  1684. X
  1685. X    /* Read in all the map entries from the file. */
  1686. X    while (1) {
  1687. X        int c;
  1688. X        int lower, upper;
  1689. X        int count;
  1690. X        int red, blue, green;
  1691. X
  1692. X        /* Read the next entry, but if there are no more, quit. */
  1693. X        count = fscanf(map_file, " %d", &lower);
  1694. X        if (0 == count || EOF == count)
  1695. X            break;
  1696. X        count = fscanf(map_file, "..%d", &upper);
  1697. X        if (0 == count)
  1698. X            upper = lower;
  1699. X        else if (EOF == count)
  1700. X            error("Map entry %d is incomplete",
  1701. X                  (char*) max_map_entry+1); 
  1702. X
  1703. X        /* Make sure not too many entries are used. */
  1704. X        if (max_map_entry >= MAX_MAP_SIZE)
  1705. X            error("More than %d color map entries used",
  1706. X                  (char*) MAX_MAP_SIZE); 
  1707. X
  1708. X        /* Set the new map entry value range. */
  1709. X        map[max_map_entry].lower = lower;
  1710. X        map[max_map_entry].upper = upper;
  1711. X
  1712. X        /* Read and set the color/character. */
  1713. X        if (curses_option) {
  1714. X            char c;
  1715. X            count = fscanf(map_file, " '%c'", &c);
  1716. X            map[max_map_entry].color = (celltype) c;
  1717. X            if (0 == count) {
  1718. X                /* Numeric ASCII value was given. */
  1719. X                int tmp_int;
  1720. X                count = fscanf(map_file, " %d", &tmp_int);
  1721. X                map[max_map_entry].color = 
  1722. X                        (celltype) tmp_int;
  1723. X            }
  1724. X            /* Check for legality of map entry. */
  1725. X            if (1 != count)
  1726. X                error("Entry %d of curses map file is illegal",
  1727. X                      (char*) max_map_entry);
  1728. X        }
  1729. X        else if (black_and_white) {
  1730. X            /* A black/white display. */
  1731. X            int tmp_int;
  1732. X            count = fscanf(map_file, " %d", &tmp_int);
  1733. X
  1734. X            /* Check for legality of map entry. */
  1735. X            if (1 != count)
  1736. X                error("Entry %d of b&w map file is illegal",
  1737. X                      (char*) max_map_entry);
  1738. X
  1739. X            map[max_map_entry].color = 
  1740. X                        (celltype) tmp_int;
  1741. X        }
  1742. X        else {
  1743. X            /* A color display. */
  1744. X            count = fscanf(map_file, " %d %d %d",
  1745. X                    &red, &green, &blue);
  1746. X
  1747. X            /* Check for legality of map entry. */
  1748. X            if (3 != count)
  1749. X                error("Entry %d of b&w map file is illegal",
  1750. X                      (char*) max_map_entry);
  1751. X
  1752. X            map[max_map_entry].color = 
  1753. X                    setcolor(red, green, blue, 
  1754. X                         max_map_entry);
  1755. X        }
  1756. X
  1757. X        max_map_entry++;
  1758. X
  1759. X        /* Skip to the end of the line. */
  1760. X        while ((c = getc(map_file)) != '\n' && c != EOF);
  1761. X        if (EOF == c) break;
  1762. X    }
  1763. X    fclose(map_file);
  1764. X}
  1765. X
  1766. X/* Maps the given (cell) value to the desired color/character display value. */
  1767. celltype map_value(value) long int value; {
  1768. X    int i;
  1769. X    for (i = 0; i < max_map_entry; i++)
  1770. X        if (map[i].lower <= value && value <= map[i].upper)
  1771. X            return map[i].color;
  1772. X    
  1773. X    /* If an appropriate map value wasn't found, then complain
  1774. X       and die.
  1775. X    */
  1776. X    input_error("No color/character for cell value %d", (char*) value);
  1777. X}
  1778. X
  1779. X/* The following variables are the lower and upper bounds of the dimensions
  1780. X   given on the command line.  The range of each dimension is then calculated.
  1781. X*/
  1782. long int lower[MAX_DIMS], upper[MAX_DIMS], range[MAX_DIMS];
  1783. X
  1784. X/* The indices of the above arrays which correspond to the dimensions
  1785. X   which contain a non-zero range (i.e. lower and upper bounds differ).
  1786. X*/
  1787. int range_dim_1_index = -1;
  1788. int range_dim_2_index = -1;
  1789. X
  1790. X/* Total number of dimensions with non-trivial ranges. */
  1791. int range_dim_given = 0;
  1792. X
  1793. X/* Indicates the cell field value to use. */
  1794. int field;
  1795. X
  1796. X/* Set the cell value and have it displayed. */
  1797. void set_cell_entry(dim_index_1, dim_index_2, cell_value)
  1798. long int dim_index_1, dim_index_2, cell_value; {
  1799. X    /* Set cell value. */
  1800. X    cell_vals[(dim_index_1 - lower[range_dim_1_index])
  1801. X                    * range[range_dim_2_index] +
  1802. X          dim_index_2 - lower[range_dim_2_index]] 
  1803. X                            = cell_value;
  1804. X
  1805. X    /* Update the appropriate display. */
  1806. X    if (curses_option) 
  1807. X        update_curses(dim_index_1, dim_index_2, map_value(cell_value));
  1808. X    else 
  1809. X        update_x11(dim_index_1, dim_index_2, map_value(cell_value));
  1810. X}
  1811. X
  1812. X#if !COMBINED
  1813. X/* Reads in a single cell and value entry from standard input.  If
  1814. X   the dimensional indices fall outside of the desired display range
  1815. X   the entry is ignored.
  1816. X*/
  1817. void read_cell_entry() {
  1818. X    int i;
  1819. X    celltype cell_color;
  1820. X    long int cell_value;
  1821. X     long int dim_index_1 = 0, dim_index_2 = 0;
  1822. X
  1823. X    /* Read in the (up to 2) indices for the dimensional ranges. */
  1824. X    scanf(" [ ");
  1825. X    for (i = 0; i < dim_given; i++) {
  1826. X        long int index;
  1827. X
  1828. X        /* Read the index value. */
  1829. X        if (scanf(" %ld ", &index) != 1)
  1830. X            input_error("Too few dimensions in input", 
  1831. X                    (char*) NULL);
  1832. X
  1833. X        /* Only consider the desired dimensional projections. 
  1834. X           If either the index is out of range or is not the
  1835. X           desired value, then skip to the next line of input
  1836. X           and return.
  1837. X        */
  1838. X        if (range[i] == 1 && index != lower[i]) {
  1839. X            while (getchar() != '\n');
  1840. X            return;
  1841. X        }
  1842. X        else if (range[i] > 1 && 
  1843. X                (index < lower[i] || index > upper[i])) {
  1844. X            while (getchar() != '\n');
  1845. X            return;
  1846. X        }
  1847. X
  1848. X        /* Remember the indices of range projected dimensions. */
  1849. X        if (i == range_dim_1_index) dim_index_1 = index;
  1850. X        else if (i == range_dim_2_index) dim_index_2 = index;
  1851. X
  1852. X        if (i < dim_given - 1) scanf(" , ");
  1853. X    }
  1854. X    scanf(" ] ");
  1855. X
  1856. X    /* Read in the cell field value. */
  1857. X    if (1 != scanf(" = %ld ", &cell_value))
  1858. X        input_error("read error", (char*) NULL);
  1859. X    for (i = 1; i < field; i++)
  1860. X        if (1 != scanf(", %ld", &cell_value))
  1861. X            input_error("read error", (char*) NULL);
  1862. X
  1863. X    set_cell_entry(dim_index_1, dim_index_2, cell_value);
  1864. X
  1865. X    /* Ignore the remaining values, if any. */
  1866. X    while (1 == scanf(", %ld", &cell_value));
  1867. X}
  1868. X
  1869. X/* Read an entire block of cell entries.  When complete, the value
  1870. X   of next_time will either be strictly greater than the current
  1871. X   _time (old value of next_time) or it will equal -1 (indicating
  1872. X   that the input is exhausted).
  1873. X*/
  1874. void read_cell_block() {
  1875. X    entry = 0;
  1876. X    while (next_time == _time) {
  1877. X        int count;
  1878. X
  1879. X        /* Assume that a time specification is next on the input.
  1880. X           If it isn't (and the input is non-empty), then read a 
  1881. X           cell entry instead.  If a new time specification is
  1882. X           present, make sure it is legal.
  1883. X        */
  1884. X        count = scanf(" %ld ", &next_time);
  1885. X        if (0 == count) {
  1886. X            entry++;
  1887. X            read_cell_entry();
  1888. X        }
  1889. X        else if (EOF == count) {
  1890. X            /* End of input. */
  1891. X            next_time = -1;
  1892. X            break;
  1893. X        }
  1894. X        else if (next_time < _time)
  1895. X            /* Check legality of new _time. */
  1896. X            input_error("Time went backwards at %d", (char*) _time);
  1897. X    }
  1898. X}
  1899. X#endif
  1900. X
  1901. X/* Print out the correct usage. */
  1902. void usage() {
  1903. X    fprintf(stderr, 
  1904. X#if COMBINED
  1905. X        "usage: [ ... | ] %s ( [-curses | -x11 [-display connection]]\n\t[-r file] [-p n] [-s (n|n,n)] [-map file] [-f n] -dim [n|n..n]{,n|,n..n} ]\n\t\t|\n\t[-r file] -o )\n",
  1906. X#else
  1907. X        "usage: [ ... | ] %s [-curses | -x11 [-display connection]]\n\t[-p n] [-s (n|n,n)] [-map file] [-f n] -dim [n|n..n]{,n|,n..n}\n",
  1908. X#endif
  1909. X        command); 
  1910. X    exit(1);
  1911. X}
  1912. X
  1913. X/* The main driver for everything. */
  1914. void main(argc, argv) int argc; char *argv[]; {
  1915. X#if COMBINED
  1916. X    boolean output = false;
  1917. X    extern FILE *time_file;
  1918. X#endif
  1919. X    int i, cell_size_x = 1, cell_size_y = 1;
  1920. X    celltype value_for_0;
  1921. X    char *map_name = NULL, *x11_display = NULL;
  1922. X
  1923. X    field = 1;    /* Look at the first cell field value by default. */
  1924. X
  1925. X    command = argv[0];
  1926. X
  1927. X    /* Check for proper usage and options. */
  1928. X    i = 0;
  1929. X    while (++i <= argc-1)
  1930. X        if (strcmp(argv[i], "-curses") == 0)
  1931. X            curses_option = true;
  1932. X        else if (strcmp(argv[i], "-x11") == 0)
  1933. X            x11_option = true;
  1934. X        else if (strcmp(argv[i], "-display") == 0)
  1935. X            x11_display = argv[++i];
  1936. X        else if (strcmp(argv[i], "-f") == 0) {
  1937. X            field = atoi(argv[++i]);
  1938. X            if (field < 1)
  1939. X                error("Field must be integer > 0",
  1940. X                    (char*) NULL);
  1941. X        }
  1942. X#if COMBINED
  1943. X        else if (strcmp(argv[i], "-o") == 0)
  1944. X            output = true;
  1945. X#endif
  1946. X        else if (strcmp(argv[i], "-p") == 0) {
  1947. X            if (sscanf(argv[++i], "%ld", &pause_time) != 1)
  1948. X                error("Pause time must be an integer",
  1949. X                    (char*) NULL);
  1950. X        }
  1951. X#if COMBINED
  1952. X        else if (strcmp(argv[i], "-r") == 0)
  1953. X            time_file = fopen(argv[++i], "r");
  1954. X#endif
  1955. X        else if (strcmp(argv[i], "-s") == 0) {
  1956. X            int sides = sscanf(argv[++i], 
  1957. X                    "%ld,%ld", &cell_size_x, &cell_size_y);
  1958. X            if (sides < 1)
  1959. X                error("Cell size(s) must be integer",
  1960. X                    (char*) NULL);
  1961. X            if (sides == 1) cell_size_y = cell_size_x;
  1962. X            if (cell_size_x < 1) cell_size_x = 1;
  1963. X            if (cell_size_y < 1) cell_size_y = 1;
  1964. X        }
  1965. X        else if (strcmp(argv[i], "-map") == 0)
  1966. X            if (i == argc-1)
  1967. X                usage();
  1968. X            else
  1969. X                map_name = argv[++i];
  1970. X        else if (strcmp(argv[i], "-dim") == 0) {
  1971. X            int count;
  1972. X            char *dim_token;
  1973. X            if (i == argc-1)
  1974. X                usage();
  1975. X
  1976. X            /* Give dim, lower and upper reasonable defaults. */
  1977. X            for (count = 0; count < MAX_DIMS; count++)
  1978. X                lower[count] = upper[count] = 0;
  1979. X
  1980. X            /* Read/parse the dimensions. */
  1981. X            dim_token = strtok(argv[++i], ",");
  1982. X            while (dim_token != NULL) {
  1983. X                if (strchr(dim_token, '.') == NULL)
  1984. X                    lower[dim_given] = upper[dim_given]
  1985. X                            = atoi(dim_token);
  1986. X                else {
  1987. X                    if (2 != sscanf(dim_token, 
  1988. X                            " %ld .. %ld ", 
  1989. X                            &lower[dim_given],
  1990. X                            &upper[dim_given]))
  1991. X                        usage();
  1992. X
  1993. X                    /* A "true" range was given. */
  1994. X                    if (lower[dim_given] != 
  1995. X                            upper[dim_given])
  1996. X                        if (range_dim_1_index < 0)
  1997. X                            range_dim_1_index = 
  1998. X                                dim_given;
  1999. X                        else
  2000. X                            range_dim_2_index = 
  2001. X                                dim_given;
  2002. X                
  2003. X                }
  2004. X                dim_given++;
  2005. X                dim_token = strtok((char*) NULL, ",");
  2006. X            }
  2007. X
  2008. X            /* Establish default ranges if necessary. */
  2009. X            if (range_dim_1_index < 0) 
  2010. X                range_dim_1_index = 0;
  2011. X            if (range_dim_2_index < 0) 
  2012. X                range_dim_2_index = MAX_DIMS - 1;
  2013. X        }
  2014. X        else
  2015. X            fprintf(stderr, "%s: Unknown option '%s' ignored.\n",
  2016. X                command, argv[i]);
  2017. X
  2018. X    /* Can't give both of these options. */
  2019. X    if (curses_option && x11_option)
  2020. X        usage();
  2021. X
  2022. X    /* If neither option was explicitly given, then default to curses. */
  2023. X    if (!(curses_option || x11_option))
  2024. X        DEFAULT_DISPLAY = true;
  2025. X
  2026. X    /* Can only request a paritcular display for x11. */
  2027. X    if (x11_display != NULL && !x11_option)
  2028. X        error("Must use the -display option with the -x11 option",
  2029. X            (char*) NULL);
  2030. X
  2031. X    /* Check that dimensions were described. */
  2032. X#if COMBINED
  2033. X    if (0 == dim_given && !output)
  2034. X#else
  2035. X    if (0 == dim_given)
  2036. X#endif
  2037. X        usage();
  2038. X
  2039. X    /* Determine and check ranges. */
  2040. X    for (i = 0; i < MAX_DIMS; i++) {
  2041. X        range[i] = upper[i] - lower[i] + 1;
  2042. X        if (range[i] <= 0) {
  2043. X            char msg[MAX_STRING_SIZE];
  2044. X            sprintf(msg, 
  2045. X                "Dimension %d has decreasing range of indices",
  2046. X                i+1);
  2047. X            error(msg, (char*) NULL);
  2048. X        }
  2049. X        else if (range[i] > 1)
  2050. X            range_dim_given++;
  2051. X    }
  2052. X
  2053. X    /* Determine if too many or too few ranges were given. */
  2054. X    if (range_dim_given > 2)
  2055. X        error("A maximum of 2 dimension ranges can be given", (char*) NULL);
  2056. X
  2057. X#if COMBINED
  2058. X    /* If output is requested, then don't display in either curses
  2059. X       of X11 modes.
  2060. X    */
  2061. X    if (output) {
  2062. X        curses_option = false;
  2063. X        x11_option = false;
  2064. X    }
  2065. X#endif
  2066. X
  2067. X    /* Set the signal so things can be cleaned up when the program
  2068. X       is terminated.
  2069. X    */
  2070. X    signal(SIGINT, exit_signaled);
  2071. X
  2072. X    /* Do setup for the necessary display mode. */
  2073. X    if (curses_option)
  2074. X        setup_curses(map_name);
  2075. X    else if (x11_option)
  2076. X        setup_x11(map_name, x11_display, cell_size_x, cell_size_y);
  2077. X
  2078. X#if !COMBINED
  2079. X    /* Read the first time from the input. */
  2080. X    i = scanf("%ld", &next_time);
  2081. X    if (0 == i)
  2082. X        input_error("Missing time specification", (char*) NULL);
  2083. X    else if (EOF == i)
  2084. X        /* End of input. */
  2085. X        next_time = -1;
  2086. X    else if (next_time < 0)
  2087. X        /* Check legality of new _time. */
  2088. X        input_error("Time must be >= 0", (char*) NULL);
  2089. X#endif
  2090. X
  2091. X    /* Allocate the space for the cell_vals. */
  2092. X    cell_vals = (celltype*) calloc((unsigned int) 
  2093. X                    (range[range_dim_1_index] * 
  2094. X                        range[range_dim_2_index]), 
  2095. X                   (unsigned int) sizeof(celltype));
  2096. X    if (cell_vals == NULL) {
  2097. X        finish_up();
  2098. X        error("Insufficient memory", (char*) NULL);
  2099. X    }
  2100. X
  2101. X    /* Initialize cell_vals to be 0. */
  2102. X    for(i = range[range_dim_1_index] * range[range_dim_2_index];i > 0; i--)
  2103. X             cell_vals[i-1] = 0;
  2104. X
  2105. X#if COMBINED
  2106. X    /* Initialize the cell universe. */
  2107. X    init_cells();
  2108. X#endif
  2109. X
  2110. X    /* Start displaying stuff! */
  2111. X    if (curses_option) display_curses(field-1);
  2112. X    else if (x11_option) display_x11(field-1);
  2113. X#if COMBINED
  2114. X    else cellang_main(output, field-1);
  2115. X#endif
  2116. X}
  2117. END_OF_FILE
  2118. if test 15058 -ne `wc -c <'viewer/view.c'`; then
  2119.     echo shar: \"'viewer/view.c'\" unpacked with wrong size!
  2120. fi
  2121. # end of 'viewer/view.c'
  2122. fi
  2123. if test -f 'viewer/x11.c' -a "${1}" != "-c" ; then 
  2124.   echo shar: Will not clobber existing file \"'viewer/x11.c'\"
  2125. else
  2126. echo shar: Extracting \"'viewer/x11.c'\" \(21295 characters\)
  2127. sed "s/^X//" >'viewer/x11.c' <<'END_OF_FILE'
  2128. X/* x11.c
  2129. X   Copyright (C) 1992  J Dana Eckart
  2130. X  
  2131. X   This program is free software; you can redistribute it and/or modify
  2132. X   it under the terms of the GNU General Public License as published by
  2133. X   the Free Software Foundation; either version 1, or (at your option)
  2134. X   any later version.
  2135. X  
  2136. X   This program is distributed in the hope that it will be useful,
  2137. X   but WITHOUT ANY WARRANTY; without even the implied warranty of
  2138. X   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  2139. X   GNU General Public License for more details.
  2140. X  
  2141. X   You should have received a copy of the GNU General Public License
  2142. X   along with CELLULAR-2.0; see the file COPYING.  If not, write to the 
  2143. X   Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  2144. X*/
  2145. X
  2146. X#include <stdio.h>
  2147. X#include <stdlib.h>
  2148. X#include <string.h>
  2149. X#include <malloc.h>
  2150. X#include <math.h>
  2151. X#include <X11/Xos.h>
  2152. X#include <X11/Xlib.h>
  2153. X#include <X11/Xutil.h>
  2154. X#include <X11/cursorfont.h>
  2155. X#include "view.h"
  2156. X
  2157. X/* Font for displaying the time in the time window. */
  2158. X#define FONT  "10x20"
  2159. X
  2160. X/* Maximum setttings for x11. */
  2161. X#define MAX_CELL_SIDE    256
  2162. X
  2163. X/* Maximum width of the largest cell value. */
  2164. X#define MAX_VALUE_WIDTH    4
  2165. X
  2166. X/* Variables used by all the windows. */
  2167. static XFontStruct     *font_info;
  2168. static Display         *dpy;
  2169. static int        screen;
  2170. static GC        gc;
  2171. X
  2172. static Colormap cmap;
  2173. static unsigned long int pixels[MAX_MAP_SIZE];
  2174. static unsigned long int Black_Pixel, White_Pixel;
  2175. X
  2176. static Pixmap cell_pixmap;
  2177. X
  2178. X/* Variables for controlling the main viewing window. */
  2179. static Window  mainWindow;
  2180. static XSetWindowAttributes     xswa;
  2181. static int            cell_side_x = MAX_CELL_SIDE;
  2182. static int            cell_side_y = MAX_CELL_SIDE;
  2183. static float            cell_side_ratio = 1.0;
  2184. static int             time_window_height = 0;
  2185. static int            mainWidth = 0, mainHeight = 0;
  2186. X
  2187. X/* Variables for controlling the neighborhood sub-window. */
  2188. static Window   neighborWindow = NULL;
  2189. static int     neighborhood = 1;        /* size of the neighborhood. */
  2190. static         int neighbor_x, neighbor_y;    /* x, y neighborhood viewing 
  2191. X                                co-ordinates. */
  2192. static         int neighborWidth, neighborHeight;
  2193. X
  2194. X
  2195. X/* Create the sub-window dedicated to showing the numeric values of a
  2196. X   neighborhood.
  2197. X*/
  2198. void CreateNeighborWindow() {
  2199. X    int charheight = font_info->ascent + font_info->descent;
  2200. X    XSizeHints sizehints;
  2201. X
  2202. X    neighborWidth = (2*neighborhood+1) * charheight * MAX_VALUE_WIDTH;
  2203. X    neighborHeight = (range_dim_given > 1 ? neighborWidth :
  2204. X                            charheight*MAX_VALUE_WIDTH);
  2205. X
  2206. X    /* Configure the window size hints. */
  2207. X    sizehints.flags = PMinSize | PMaxSize | PPosition | PSize;
  2208. X    sizehints.x = 0;
  2209. X    sizehints.y = 0;
  2210. X    sizehints.width = neighborWidth;
  2211. X    sizehints.height = neighborHeight;
  2212. X    sizehints.min_width = sizehints.width;
  2213. X    sizehints.min_height = sizehints.height;
  2214. X    sizehints.max_width = sizehints.width;
  2215. X    sizehints.max_height = sizehints.height;
  2216. X
  2217. X    neighborWindow = 
  2218. X        XCreateWindow(
  2219. X            dpy, 
  2220. X            RootWindow(dpy, screen),
  2221. X            0, 0,
  2222. X            sizehints.width, sizehints.height,
  2223. X            1,
  2224. X            DefaultDepth(dpy, screen),
  2225. X            InputOutput,
  2226. X            DefaultVisual(dpy, screen),
  2227. X            CWEventMask | CWBackPixel | CWBorderPixel | CWColormap,
  2228. X            &xswa);
  2229. X
  2230. X    if (!neighborWindow) {
  2231. X        error("Unable to open a neighborhood window", (char*) NULL);
  2232. X        return;
  2233. X    }
  2234. X
  2235. X    /* Define the window's name. */
  2236. X    XSetStandardProperties(dpy, neighborWindow, 
  2237. X                   "neighborhood", "neighborhood",
  2238. X                   None, NULL, 0, &sizehints);
  2239. X
  2240. X    XMapRaised(dpy, neighborWindow);
  2241. X     XSelectInput(dpy, neighborWindow, ExposureMask | StructureNotifyMask |
  2242. X                     KeyPressMask | VisibilityChangeMask);
  2243. X}
  2244. X
  2245. X/* Display the values of the appropriate neighborhood. */
  2246. void display_neighbor_values() {
  2247. X    int charheight = font_info->ascent + font_info->descent;
  2248. X    int i, j;
  2249. X
  2250. X    /* Clear the contents of the window. */
  2251. X    XSetForeground(dpy, gc, Black_Pixel);
  2252. X    XFillRectangle(dpy, neighborWindow, gc, 
  2253. X               0, 0, neighborWidth, neighborHeight);
  2254. X
  2255. X    XSetForeground(dpy, gc, White_Pixel);
  2256. X
  2257. X    /* Draw the horizontal lines (if need be). */
  2258. X    if (range_dim_given > 1) for (i = 2*neighborhood; i > 0; i--)
  2259. X        XDrawLine(dpy, neighborWindow, gc,
  2260. X              0, i*charheight*MAX_VALUE_WIDTH,
  2261. X              neighborWidth, i*charheight*MAX_VALUE_WIDTH);
  2262. X
  2263. X    /* Draw the vertical lines. */
  2264. X    for (i = 2*neighborhood; i > 0; i--)
  2265. X        XDrawLine(dpy, neighborWindow, gc,
  2266. X              i*charheight*MAX_VALUE_WIDTH, 0,
  2267. X              i*charheight*MAX_VALUE_WIDTH, neighborHeight);
  2268. X
  2269. X    /* Display the neighbor values. */
  2270. X    for (i = -neighborhood; i <= neighborhood; i++)
  2271. X        for (j = -neighborhood; j <= neighborhood; j++) {
  2272. X            int x = (neighbor_x + i + range[range_dim_1_index]) %
  2273. X                        range[range_dim_1_index];
  2274. X            int y = (neighbor_y + j + range[range_dim_2_index]) %
  2275. X                        range[range_dim_2_index];
  2276. X            char string[MAX_VALUE_WIDTH];
  2277. X            celltype value = cell_vals[x*range[range_dim_2_index]+y];
  2278. X
  2279. X            /* If a range of indices was only given for 1
  2280. X               dimension, then don't print the extra values
  2281. X               above and below.
  2282. X            */
  2283. X            if (range_dim_given <= 1 && j != 0) continue;
  2284. X
  2285. X            /* Make sure the value will fit.  If it won't then
  2286. X               display hyphens in place of the value.
  2287. X            */
  2288. X            if (value == 0 ||
  2289. X                (value < 0 ? log10(-value):log10(value)) 
  2290. X                            <= MAX_VALUE_WIDTH)
  2291. X                sprintf(string, "%ld", value);
  2292. X            else {
  2293. X                int i;
  2294. X                string[0] = '\0';
  2295. X                for (i = 0; i < MAX_VALUE_WIDTH; i++)
  2296. X                    strcat(string, "-");
  2297. X            }
  2298. X            XDrawString(dpy, neighborWindow, gc, 
  2299. X                    (neighborhood+i)*charheight*MAX_VALUE_WIDTH +
  2300. X                    charheight,
  2301. X                    (neighborhood-j)*charheight*MAX_VALUE_WIDTH +
  2302. X                    (MAX_VALUE_WIDTH/2)*charheight +
  2303. X                    charheight/2,
  2304. X                        string, strlen(string));
  2305. X        }
  2306. X
  2307. X    XFlush(dpy);
  2308. X}
  2309. X
  2310. X/* Resize the neighborhood sub-window. */
  2311. void resize_neighborhood() {
  2312. X    int charheight = font_info->ascent + font_info->descent;
  2313. X
  2314. X    neighborWidth = (2*neighborhood+1) * charheight * MAX_VALUE_WIDTH;
  2315. X    neighborHeight = (range_dim_given > 1 ? neighborWidth :
  2316. X                            charheight*MAX_VALUE_WIDTH);
  2317. X
  2318. X    XResizeWindow(dpy, neighborWindow, neighborWidth, neighborHeight);
  2319. X}
  2320. X
  2321. X/* Do any cleanup for x11 windows and quit. */
  2322. void finish_x11() {
  2323. X    XFreeColormap(dpy, cmap);
  2324. X    XCloseDisplay(dpy);
  2325. X}
  2326. X
  2327. X/* Display the current time step at the bottom of the window. */
  2328. void display_time() {
  2329. X    char time_string[MAX_STRING_SIZE];
  2330. X
  2331. X    /* Clear the time display part of the window. */
  2332. X    XSetForeground(dpy, gc, White_Pixel);
  2333. X    XFillRectangle(dpy, mainWindow, gc, 
  2334. X               0, cell_side_y*range[range_dim_2_index] + 1,
  2335. X               cell_side_x*range[range_dim_1_index], time_window_height);
  2336. X
  2337. X    /* Display the new current time step. */
  2338. X    XSetForeground(dpy, gc, Black_Pixel);
  2339. X    sprintf(time_string, "time = %d", _time);
  2340. X    XDrawString(dpy, mainWindow, gc, 
  2341. X            time_window_height/2,
  2342. X            cell_side_y * range[range_dim_2_index] + 
  2343. X                (int) (0.75 * time_window_height), 
  2344. X                time_string, strlen(time_string));
  2345. X    XFlush(dpy);
  2346. X}
  2347. X
  2348. X/* Display all the cell_vals in the universe. */
  2349. void display_x11_cells() {
  2350. X    XCopyArea(dpy, cell_pixmap, mainWindow, gc, 0, 0,
  2351. X          range[range_dim_1_index]*cell_side_x, 
  2352. X          range[range_dim_2_index]*cell_side_y, 0, 0);
  2353. X    XFlush(dpy);
  2354. X
  2355. X    /* May need to update the neighbor values too. */
  2356. X    if (neighborWindow) display_neighbor_values();
  2357. X}
  2358. X
  2359. X/* Reset the pixel map with cell "colors". */
  2360. void redisplay_cells() {
  2361. X    int i, j;
  2362. X
  2363. X    /* Draw the cells onto the pixmap. */
  2364. X    for (i = 0; i < range[range_dim_1_index]; i++)
  2365. X        for (j = 0; j < range[range_dim_2_index]; j++) {
  2366. X            XSetForeground(dpy, gc, 
  2367. X                    (unsigned long) 
  2368. X                    map_value(cell_vals[i*range[range_dim_2_index]+j]));
  2369. X            XFillRectangle(dpy, cell_pixmap, gc, 
  2370. X                    i*cell_side_x, 
  2371. X                    (range[range_dim_2_index]-1-j)*cell_side_y, 
  2372. X                    cell_side_x, cell_side_y);
  2373. X        }
  2374. X    display_x11_cells();
  2375. X}
  2376. X
  2377. X/* Handle the events for the neighborhood sub-window. */
  2378. void sub_window_event(event) XEvent *event; {
  2379. X    XExposeEvent *ee = (XExposeEvent*) event;
  2380. X    XKeyPressedEvent *ke = (XKeyPressedEvent *) event;
  2381. X    char keybuff[10];
  2382. X        int nchar;
  2383. X
  2384. X    switch(event->type) {
  2385. X           case ConfigureNotify:
  2386. X        /* Don't resize this window. */
  2387. X        break;
  2388. X
  2389. X    case Expose:
  2390. X        if (ee->count) break;
  2391. X
  2392. X    case VisibilityNotify:
  2393. X        display_neighbor_values();
  2394. X               break;
  2395. X
  2396. X    case ButtonPress:
  2397. X               break;
  2398. X
  2399. X    case KeyPress:
  2400. X        nchar = XLookupString(ke, keybuff, 1, NULL, NULL);
  2401. X                   if (nchar > 0) {
  2402. X                       switch (keybuff[0]) {
  2403. X                           case '0':
  2404. X                           case '1':
  2405. X                           case '2':
  2406. X                           case '3':
  2407. X                           case '4':
  2408. X                           case '5':
  2409. X                           case '6':
  2410. X                           case '7':
  2411. X                           case '8':
  2412. X                           case '9':
  2413. X                neighborhood = keybuff[0]-'0';
  2414. X                resize_neighborhood();
  2415. X                display_neighbor_values();
  2416. X                break;
  2417. X
  2418. X            default:
  2419. X                break;
  2420. X                           }
  2421. X                      }
  2422. X                      break;
  2423. X
  2424. X    default:
  2425. X        break;
  2426. X    }
  2427. X}
  2428. X
  2429. X/* Handle the events for the main window. */
  2430. void main_window_event(stopped, event) int *stopped; XEvent *event; {
  2431. X    XExposeEvent *ee = (XExposeEvent*) event;
  2432. X        XConfigureEvent *ce = (XConfigureEvent*) event;
  2433. X    XButtonPressedEvent *be = (XButtonPressedEvent *) event;
  2434. X    XKeyPressedEvent *ke = (XKeyPressedEvent *) event;
  2435. X    char keybuff[10];
  2436. X        int nchar;
  2437. X
  2438. X    switch(event->type) {
  2439. X           case ConfigureNotify:
  2440. X        /* Don't resize the window if both the width and
  2441. X           the height are the same.
  2442. X        */
  2443. X        if (ce->width == mainWidth && ce->height == mainHeight)
  2444. X            break;
  2445. X
  2446. X        /* The window needs to be resized. */
  2447. X        ce->height -= (time_window_height + 1);
  2448. X        cell_side_x = (ce->width / range[range_dim_1_index] > 
  2449. X                ce->height / range[range_dim_2_index] ?
  2450. X                ce->height / range[range_dim_2_index] : 
  2451. X                ce->width / range[range_dim_1_index]);
  2452. X
  2453. X        if (cell_side_ratio < 1) {
  2454. X            if (cell_side_x > MAX_CELL_SIDE) 
  2455. X                cell_side_x = MAX_CELL_SIDE;
  2456. X
  2457. X            /* Make sure cell_vals are "visible". */
  2458. X            if (cell_side_x <= 0) cell_side_x = 1;
  2459. X
  2460. X            cell_side_y = cell_side_x * cell_side_ratio;
  2461. X        }
  2462. X        else {
  2463. X            cell_side_y = cell_side_x * cell_side_ratio;
  2464. X
  2465. X            if (cell_side_y > MAX_CELL_SIDE) 
  2466. X                cell_side_y = MAX_CELL_SIDE;
  2467. X
  2468. X            /* Make sure cell_vals are "visible". */
  2469. X            if (cell_side_y <= 0) cell_side_y = 1;
  2470. X
  2471. X            cell_side_x = cell_side_y / cell_side_ratio;
  2472. X        }
  2473. X
  2474. X        /* Since the size just chosen for the window may
  2475. X           not yield an integer number of pixels for the
  2476. X           sides of cells, reset the window size to just
  2477. X           fit the new cell_side_x and cell_side_y values.
  2478. X        */
  2479. X        mainWidth = range[range_dim_1_index]*cell_side_x;
  2480. X        mainHeight = range[range_dim_2_index]*cell_side_y + 
  2481. X                      time_window_height + 1;
  2482. X        XResizeWindow(dpy, mainWindow, 
  2483. X                  mainWidth, mainHeight);
  2484. X
  2485. X        /* Free and create a new pixel map. */
  2486. X        XFreePixmap(dpy, cell_pixmap);
  2487. X        cell_pixmap = 
  2488. X            XCreatePixmap(dpy, mainWindow,
  2489. X                    range[range_dim_1_index]*cell_side_x,
  2490. X                    range[range_dim_2_index]*cell_side_y,
  2491. X                    DefaultDepth(dpy, screen));
  2492. X
  2493. X        redisplay_cells();
  2494. X        display_time();
  2495. X               break;
  2496. X
  2497. X    case Expose:
  2498. X        if (ee->count) break;
  2499. X
  2500. X    case VisibilityNotify:
  2501. X        display_x11_cells();
  2502. X        display_time();
  2503. X               break;
  2504. X
  2505. X    case ButtonPress:
  2506. X        if (neighborWindow != NULL) {
  2507. X            neighbor_x = (be->x/cell_side_x + 
  2508. X                    range[range_dim_1_index]) %
  2509. X                        range[range_dim_1_index];
  2510. X            neighbor_y = (-be->y/cell_side_y - 1 + 
  2511. X                    range[range_dim_2_index]) %
  2512. X                        range[range_dim_2_index];
  2513. X            display_neighbor_values();
  2514. X        }
  2515. X        break;
  2516. X
  2517. X    case KeyPress:
  2518. X        nchar = XLookupString(ke, keybuff, 1, NULL, NULL);
  2519. X                   if (nchar > 0) {
  2520. X                       switch (keybuff[0]) {
  2521. X                           case 'n':
  2522. X                           case 'N':
  2523. X                /* Neighborhood window */
  2524. X                if (!neighborWindow)
  2525. X                    CreateNeighborWindow();
  2526. X                else {
  2527. X                    XDestroyWindow(
  2528. X                        dpy, neighborWindow);
  2529. X                    neighborWindow = NULL;
  2530. X                }
  2531. X                break;
  2532. X                       case 'q':
  2533. X                       case 'Q':
  2534. X                /* Quit */
  2535. X                finish_x11();
  2536. X                               exit(0);
  2537. X                       case 's':
  2538. X                       case 'S':
  2539. X                /* Stop */
  2540. X                               *stopped = true;
  2541. X                break;
  2542. X                       case 'c':
  2543. X                       case 'C':
  2544. X                /* Continue */
  2545. X                               *stopped = false;
  2546. X                break;
  2547. X            default:
  2548. X                break;
  2549. X                           }
  2550. X                      }
  2551. X                      break;
  2552. X
  2553. X    default:
  2554. X        break;
  2555. X    }
  2556. X}
  2557. X
  2558. X/* Check for, and perform events as they arise. */
  2559. void do_event() {
  2560. X    XEvent event;
  2561. X    boolean stopped = false;
  2562. X
  2563. X    /* If there are events, handled them. */
  2564. X    while (XPending(dpy) || stopped) {
  2565. X        XNextEvent(dpy, &event);
  2566. X        if (event.xany.window == neighborWindow)
  2567. X            sub_window_event(&event);
  2568. X        else if (event.xany.window == mainWindow)
  2569. X            main_window_event(&stopped, &event);
  2570. X    }
  2571. X}
  2572. X
  2573. X/* Update (display) the color of a single cell. */
  2574. void update_x11(x, y, color_index) long int x, y; celltype color_index; {
  2575. X    long int i = x - lower[range_dim_1_index];
  2576. X    long int j = y - lower[range_dim_2_index];
  2577. X    XSetForeground(dpy, gc, (unsigned long) color_index);
  2578. X    XFillRectangle(dpy, cell_pixmap, gc, 
  2579. X               i*cell_side_x, (range[range_dim_2_index]-1-j)*cell_side_y, 
  2580. X               cell_side_x, cell_side_y);
  2581. X}
  2582. X
  2583. X/* Stores the red, green and blue portions that make up a color. */
  2584. celltype setcolor(red, green, blue, index) int red, green, blue, index; {
  2585. X    XColor color;
  2586. X    color.pixel = pixels[index];
  2587. X    color.red = red;
  2588. X    color.green = green;
  2589. X    color.blue = blue;
  2590. X    color.flags = DoRed | DoGreen | DoBlue;
  2591. X    XStoreColor(dpy, cmap, &color);
  2592. X    return color.pixel;
  2593. X}
  2594. X
  2595. X/* Set the values for Black_Pixel and White_Pixel. */
  2596. void Black_and_White_Pixels(max_colors) int max_colors; {
  2597. X    if (max_colors <= 2) {
  2598. X        Black_Pixel = BlackPixel(dpy, screen);
  2599. X        White_Pixel = WhitePixel(dpy, screen);
  2600. X    }
  2601. X    else {
  2602. X        /* Assume that the darkest pixels are given first and
  2603. X           the lightest in color are given last.  In either
  2604. X           case, both should be sufficiently different in color
  2605. X           to be readable.
  2606. X        */
  2607. X        White_Pixel = pixels[max_colors-1];
  2608. X        Black_Pixel = pixels[0];
  2609. X    }
  2610. X}
  2611. X
  2612. X/* Returns the number of lines in the file denoted by file_name. */
  2613. int file_size(file_name) char *file_name; {
  2614. X    int c, lines = 0;
  2615. X    FILE *file = fopen(file_name, "r");
  2616. X
  2617. X    if (NULL == file)
  2618. X        error("Unable to open map file '%s'", file_name);
  2619. X
  2620. X    /* Count the lines in the file. */
  2621. X    while ((c = getc(file)) != EOF) if ('\n' == c) lines++;
  2622. X
  2623. X    fclose(file);
  2624. X    return lines;
  2625. X}
  2626. X
  2627. X/* Do all the setup and housekeeping for starting an x11 window. */
  2628. void setup_x11(map_name, display, first_cell_side_x, first_cell_side_y) 
  2629. char *map_name, *display; int first_cell_side_x, first_cell_side_y; {
  2630. X    Visual *visual;
  2631. X    XSizeHints sizehints;
  2632. X    int max_x_pixels, max_y_pixels, ncolors, depth;
  2633. X    char *default_file;
  2634. X
  2635. X    if ((dpy = XOpenDisplay(display)) == NULL)
  2636. X            error("Can't open display '%s'", display);
  2637. X
  2638. X    screen = XDefaultScreen(dpy);
  2639. X
  2640. X    /* Do setup for displaying the time in the time window. */
  2641. X    font_info = XLoadQueryFont(dpy, FONT);
  2642. X    if (NULL == font_info)
  2643. X        error("Unable to load font '%s'", FONT);
  2644. X    time_window_height = 1.5*(font_info->ascent + font_info->descent);
  2645. X
  2646. X    /* Get the height and width of the screen in pixels. */
  2647. X    max_x_pixels = XDisplayWidth(dpy, screen);
  2648. X    max_y_pixels = XDisplayHeight(dpy, screen) - time_window_height - 1;
  2649. X
  2650. X    cell_side_ratio = (float) first_cell_side_y / (float) first_cell_side_x;
  2651. X
  2652. X    /* Determine the size of the sides of each displayed cell. */
  2653. X    cell_side_x = (max_x_pixels / range[range_dim_1_index] > 
  2654. X                max_y_pixels / range[range_dim_2_index] ?
  2655. X            max_y_pixels / range[range_dim_2_index] : 
  2656. X            max_x_pixels / range[range_dim_1_index]);
  2657. X
  2658. X    if (cell_side_ratio < 1) {
  2659. X        if (cell_side_x > MAX_CELL_SIDE) 
  2660. X            cell_side_x = MAX_CELL_SIDE;
  2661. X
  2662. X        /* Make sure cell_vals are "visible". */
  2663. X        if (cell_side_x <= 0)
  2664. X            error("Too many cells to display on screen", 
  2665. X                (char*) NULL);
  2666. X
  2667. X        cell_side_y = cell_side_x * cell_side_ratio;
  2668. X    }
  2669. X    else {
  2670. X        cell_side_y = cell_side_x * cell_side_ratio;
  2671. X
  2672. X        if (cell_side_y > MAX_CELL_SIDE) 
  2673. X            cell_side_y = MAX_CELL_SIDE;
  2674. X
  2675. X        /* Make sure cell_vals are "visible". */
  2676. X        if (cell_side_y <= 0)
  2677. X            error("Too many cells to display on screen", 
  2678. X                (char*) NULL);
  2679. X
  2680. X        cell_side_x = cell_side_y / cell_side_ratio;
  2681. X    }
  2682. X
  2683. X    /* Go with the prefered size if possible. */
  2684. X    if (cell_side_x > first_cell_side_x) cell_side_x = first_cell_side_x;
  2685. X    if (cell_side_y > first_cell_side_y) cell_side_y = first_cell_side_y;
  2686. X
  2687. X    mainWidth = range[range_dim_1_index]*cell_side_x;
  2688. X    mainHeight = range[range_dim_2_index]*cell_side_y + 
  2689. X                  time_window_height + 1;
  2690. X
  2691. X    /* Get the default display inforamtion. */
  2692. X    visual = DefaultVisual(dpy, screen);
  2693. X    depth =    DefaultDepth(dpy,screen);
  2694. X        cmap = DefaultColormap(dpy, screen);
  2695. X
  2696. X    /* If a map file was given, read it; otherwise use the default. */
  2697. X    if (NULL == map_name) {
  2698. X        if (DisplayCells(dpy, screen) > 2) default_file = "color-map";
  2699. X        else default_file = "bw-map";
  2700. X
  2701. X        map_name = (char*) malloc((unsigned int) (strlen(LIB_DIR) + 
  2702. X                        strlen(default_file) + 2));
  2703. X        if (NULL == map_name)
  2704. X            error("Out of memory", (char*) NULL);
  2705. X        sprintf(map_name, "%s/%s", LIB_DIR, default_file);
  2706. X    }
  2707. X    ncolors = file_size(map_name);
  2708. X
  2709. X    /* Set up a color map. */
  2710. X    if (DisplayCells(dpy, screen) > 2) {
  2711. X        /* Create a new colormap if not a black/white display. */
  2712. X        XVisualInfo     vinfo;
  2713. X        int planes = DisplayPlanes(dpy,screen);
  2714. X         if (!(XMatchVisualInfo(dpy, screen, planes, PseudoColor, &vinfo)
  2715. X                  || 
  2716. X              XMatchVisualInfo(dpy, screen, planes, GrayScale, &vinfo)
  2717. X                      || 
  2718. X              XMatchVisualInfo(dpy, screen, planes, DirectColor, &vinfo)))
  2719. X            error("Unable to set up the color mapping",
  2720. X                 (char*) NULL);
  2721. X
  2722. X        visual = vinfo.visual;
  2723. X        depth = vinfo.depth;
  2724. X
  2725. X        /* Only create a new colormap, if the current one doesn't
  2726. X           have enough room in it for the map read in.
  2727. X        */
  2728. X        if (! XAllocColorCells(dpy, cmap, False, NULL, 0, 
  2729. X                       pixels, ncolors)) {
  2730. X            cmap = XCreateColormap(dpy, RootWindow(dpy, screen),
  2731. X                        visual, AllocNone);
  2732. X
  2733. X            /* Get the color cells. */
  2734. X            if (! XAllocColorCells(dpy, cmap, False, NULL, 0, 
  2735. X                           pixels, ncolors))
  2736. X                error("Unable to allocate %d colors", 
  2737. X                    (char*) ncolors);
  2738. X        }
  2739. X    }
  2740. X    else if (ncolors > 2)
  2741. X        error("This display can only show %d colors", 
  2742. X            (char*) DisplayCells(dpy, screen));
  2743. X
  2744. X    printf("Using %d colors...\n", ncolors);
  2745. X    read_map(map_name, (ncolors <= 2 ? 1 : 0));
  2746. X    Black_and_White_Pixels(ncolors);
  2747. X
  2748. X    /* Create the palette main window and set its standard properties. */
  2749. X    xswa.event_mask = KeyPressMask | StructureNotifyMask | ExposureMask
  2750. X                | ButtonPressMask;
  2751. X    xswa.border_pixel = Black_Pixel;
  2752. X    xswa.background_pixel = Black_Pixel;
  2753. X    xswa.colormap = cmap;
  2754. X
  2755. X    /* Configure the window size hints. */
  2756. X    sizehints.flags = PMinSize | PPosition | PSize;
  2757. X    sizehints.x = 0;
  2758. X    sizehints.y = 0;
  2759. X    sizehints.min_width = range[range_dim_1_index];
  2760. X    sizehints.min_height = range[range_dim_2_index] + 
  2761. X                        time_window_height + 1;
  2762. X    sizehints.width = range[range_dim_1_index] * cell_side_x;
  2763. X    sizehints.height = range[range_dim_2_index] * cell_side_y + 
  2764. X                            time_window_height + 1;
  2765. X
  2766. X    /* Create the window. */
  2767. X    mainWindow = XCreateWindow(dpy, RootWindow(dpy, screen),
  2768. X                       sizehints.x, sizehints.y,
  2769. X                       sizehints.width, sizehints.height,
  2770. X                       1 /* Border Width */,
  2771. X                   depth,
  2772. X                       InputOutput,
  2773. X                       visual,
  2774. X                       CWEventMask | CWBackPixel | CWBorderPixel
  2775. X                    | CWColormap,
  2776. X                       &xswa);
  2777. X
  2778. X    /* Define the window's name. */
  2779. X    XSetStandardProperties(dpy, mainWindow, "cellview", "cellview",
  2780. X                   None, NULL, 0, &sizehints);
  2781. X
  2782. X    XMapRaised(dpy, mainWindow);
  2783. X     XSelectInput(dpy, mainWindow, ExposureMask | StructureNotifyMask |
  2784. X                     KeyPressMask | VisibilityChangeMask | ButtonPressMask);
  2785. X        gc = XCreateGC(dpy, mainWindow, 0, NULL);
  2786. X    XSetFont(dpy, gc, font_info->fid);
  2787. X    XFreeFontInfo(NULL, font_info, 1);
  2788. X    cell_pixmap = XCreatePixmap(dpy, mainWindow,
  2789. X                    range[range_dim_1_index]*cell_side_x,
  2790. X                    range[range_dim_2_index]*cell_side_y,
  2791. X                    depth);
  2792. X
  2793. X    /* Get a more accurate looking cursor. */
  2794. X    XDefineCursor(dpy, mainWindow,  XCreateFontCursor(dpy, XC_crosshair));
  2795. X
  2796. X    /* Assign intial values for the cursor location to be used for
  2797. X       neighborhood value viewing within a sub-window.
  2798. X    */
  2799. X    neighbor_x = range[range_dim_1_index]/2;
  2800. X    if (range_dim_given > 1)
  2801. X        neighbor_y = range[range_dim_2_index]/2;
  2802. X}
  2803. X
  2804. X/* Start displaying the cell_vals. */
  2805. void display_x11(field) int field; {
  2806. X    int i, j;
  2807. X
  2808. X    /* Initialize the cell_vals to the color values. */
  2809. X        for (i = lower[range_dim_1_index]; i <= upper[range_dim_1_index]; i++)
  2810. X                for (j = lower[range_dim_2_index]; j <= upper[range_dim_2_index] ; j++)
  2811. X                        update_x11(i, j,
  2812. X                                      map_value(cell_vals[(i -
  2813. X                                                lower[range_dim_1_index]) *
  2814. X                                                range[range_dim_2_index] +
  2815. X                                            j - lower[range_dim_2_index]]));
  2816. X
  2817. X    /* Initializes pixel map. */
  2818. X    redisplay_cells();
  2819. X
  2820. X    /* Wait for the first event. */
  2821. X    while (!XPending(dpy));
  2822. X
  2823. X    /* Display cell_vals for the rest of time. */
  2824. X    while (1) {
  2825. X        do_event();
  2826. X#if !COMBINED
  2827. X        if (next_time >= 0) 
  2828. X#endif
  2829. X        {
  2830. X            display_time();
  2831. X#if COMBINED
  2832. X            cellang_main(false, field);
  2833. X#else
  2834. X            read_cell_block();
  2835. X#endif
  2836. X            display_x11_cells();
  2837. X
  2838. X#if !COMBINED
  2839. X            if (next_time >= 0) _time++;
  2840. X#endif
  2841. X    
  2842. X            /* Pause times of 0 or less are ignored. */
  2843. X            if (pause_time > 0) sleep((unsigned int) pause_time);
  2844. X        }
  2845. X    }
  2846. X}
  2847. END_OF_FILE
  2848. if test 21295 -ne `wc -c <'viewer/x11.c'`; then
  2849.     echo shar: \"'viewer/x11.c'\" unpacked with wrong size!
  2850. fi
  2851. # end of 'viewer/x11.c'
  2852. fi
  2853. echo shar: End of archive 2 \(of 3\).
  2854. cp /dev/null ark2isdone
  2855. MISSING=""
  2856. for I in 1 2 3 ; do
  2857.     if test ! -f ark${I}isdone ; then
  2858.     MISSING="${MISSING} ${I}"
  2859.     fi
  2860. done
  2861. if test "${MISSING}" = "" ; then
  2862.     echo You have unpacked all 3 archives.
  2863.     rm -f ark[1-9]isdone
  2864. else
  2865.     echo You still need to unpack the following archives:
  2866.     echo "        " ${MISSING}
  2867. fi
  2868. ##  End of shell archive.
  2869. exit 0
  2870.