home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume26 / cforms / part02 < prev    next >
Encoding:
Text File  |  1992-05-18  |  37.8 KB  |  1,401 lines

  1. Newsgroups: comp.sources.unix
  2. From: lab@techno.sth.cgl.se (Lars Berntzon)
  3. Subject: v26i057: cforms - forms management front end for curses(3), Part02/03
  4. Sender: unix-sources-moderator@pa.dec.com
  5. Approved: vixie@pa.dec.com
  6.  
  7. Submitted-By: lab@techno.sth.cgl.se (Lars Berntzon)
  8. Posting-Number: Volume 26, Issue 57
  9. Archive-Name: cforms/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:  doc/cforms.tex src/get_field.c src/output.c src/token.c
  19. # Wrapped by vixie@cognition.pa.dec.com on Tue May 19 19:14:29 1992
  20. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  21. if test -f 'doc/cforms.tex' -a "${1}" != "-c" ; then 
  22.   echo shar: Will not clobber existing file \"'doc/cforms.tex'\"
  23. else
  24. echo shar: Extracting \"'doc/cforms.tex'\" \(13964 characters\)
  25. sed "s/^X//" >'doc/cforms.tex' <<'END_OF_FILE'
  26. X% LATEX Documentation for CForms
  27. X% By Lars Berntzon
  28. X% $Log:    cforms.tex,v $
  29. X% Revision 1.2  92/01/25  18:08:54  lasse
  30. X% Adde how to compile
  31. X% 
  32. X% Revision 1.1  92/01/19  12:41:08  lasse
  33. X% Initial revision
  34. X% 
  35. X%
  36. X\newcommand{\synopsys}[1]{\verb!\newline
  37. XSynopsys: {#1}!
  38. X}
  39. X
  40. X\documentstyle{article}
  41. X\title{CForms v 1.0}
  42. X\author{Lars Berntzon, E-Mail: lab@cgl.se}
  43. X\begin{document}
  44. X\maketitle
  45. X
  46. X\section{Introduction}
  47. X
  48. X    CForms is a formular manager for building applications to be used for
  49. X    many types of terminals though it uses the {\em curses} library.
  50. X    CForms is built up by a language that consists of the objects: modules,
  51. X    pictures, fields, literals and events.
  52. X
  53. X    An application is built by one or more modules that contains one or more
  54. X    pictures that handles the various functions in the application.
  55. X    Each picture may contain any number of fields and text literal
  56. X    that describes the appearance of the picture.
  57. X
  58. X    Fields are defined by their name and may be specified with any type,
  59. X    size, special attributes and event handling functions.
  60. X
  61. X    CForms may be intermixed with C-code modules in any way.
  62. X
  63. X
  64. X\section{Language description}
  65. X
  66. X     Currently you can only have one module (file) with CForms language,
  67. X    but i plan to make a CForms 'linker' and thus make it possible to
  68. X    have multiple files.
  69. X
  70. X    The language is not case sensitive exept thoose parts
  71. X    that are pure C-code (in events- and ccode statements).
  72. X
  73. X    
  74. X\subsection{Viewports}
  75. X
  76. X    To create a picture you first need to create a viewport, wich 
  77. X    describes the size and position on the real screen where the picture
  78. X    should appear. A viewport is defined by its name, wich later should
  79. X    be referenced in the picture. Several pictures may share the same
  80. X    viewport.
  81. X
  82. X    Syntax for a viewport is:
  83. X    \begin{verbatim}
  84. X        VIEWPORT <name> {
  85. X            POS <column>, <row>;
  86. X            SIZE <width>, <height>;
  87. X        }
  88. X    \end{verbatim}
  89. X
  90. X    Example:
  91. X    \begin{verbatim}
  92. X        Viewport stdscreen {
  93. X            Pos 1,1;
  94. X            Size 80, 24;
  95. X        }
  96. X    \end{verbatim}
  97. X
  98. X
  99. X\subsection{CCode}
  100. X    The CCode statement introduces a C-code block that may contain any
  101. X    code such as global variables, functions, preprocessor statements.
  102. X    This means that there is no need to have separated form-files and
  103. X    C-files with support functions. Ccodes may only be used in outer
  104. X    scopes, i.e. not inside pictures, literals or fields.
  105. X
  106. X    Syntax for Ccode is:
  107. X        \begin{verbatim}
  108. X        CCODE {
  109. X            <Any C code>
  110. X        }
  111. X        \end{verbatim}
  112. X
  113. X    Example:
  114. X        \begin{verbatim}
  115. X        CCode {
  116. X            cleanup()
  117. X            {
  118. X                free_all_mem();
  119. X                cforms_end();
  120. X                exit();
  121. X            }
  122. X        }
  123. X        \end{verbatim}
  124. X
  125. X
  126. X\subsection{Pictures}
  127. X
  128. X    A picture is what shows up on the terminal when the application is
  129. X    running. Pictures contains fields - which are places for input or
  130. X    output, literals - which are static texts and events -
  131. X    events doesn't show but defines C-code functions to be called when
  132. X    certain things happens. Events specified in pictures are actually
  133. X    used by fields, but they are automatically specified for all fields
  134. X    in that pictures (unless specifically turned off), in other worlds a
  135. X    default event for all fields.
  136. X
  137. X    A pictures is defined by its name, and the first picture to be started
  138. X    in the application is determined in the main routine (or a descendant)
  139. X    through the function {\em pic\_call}.
  140. X    
  141. X
  142. X    Syntax for a picture is:
  143. X    \begin{verbatim}
  144. X        PICTURE <picture-name> VIEWPORT <viewport-name> {
  145. X            <literals>   \
  146. X            <fields>      > in any order
  147. X            <events>     /
  148. X        }
  149. X    \end{verbatim}
  150. X
  151. X    Example:
  152. X    \begin{verbatim}
  153. X        Picture main Viewport stdscreen {
  154. X            Literal 10, 10, "Welcome, enter your name: ";
  155. X            Field Name {
  156. X                Pos +0, +1;
  157. X                Type Char(10);
  158. X            }
  159. X        }
  160. X    \end{verbatim}
  161. X
  162. X
  163. X\subsection{Fields}
  164. X
  165. X    Fields are placesholders in pictures that may be used to input from
  166. X    operator and/or as output from the application. A field may be of
  167. X    many kind of types and sizes. Fields can also contain events that
  168. X    will be called when the specified event occurs. It is also possible
  169. X    to specify literal text to appear immediately before and immediately
  170. X    after the actual field, this makes it possible to have text belonging
  171. X    to fields that are not depending of the fields position.
  172. X
  173. X    The position of a field may be specified in absolute- or relative 
  174. X    coordinates. For relative coordinates the column- and row number is
  175. X    prepended by a minus or a plus sign to indikate positive or negative
  176. X    relative position.
  177. X    Finally it is possible to specify a couple of modifiers for the field that
  178. X    modifies adjustment, visibility, protection e.t.c.
  179. X    Valid types for a field is:
  180. X    \begin{itemize}
  181. X       \item{INT} Field may only contain digits.
  182. X       \item{STR} Field may only contain alphanumeric characters.
  183. X       \item{CHAR} Field may contain any printable character.
  184. X    \end{itemize}
  185. X    The size of a field is by default 1, but may be altered as a number
  186. X    within brackets after the type.
  187. X
  188. X    Valid modifiers are:
  189. X    \begin{itemize}
  190. X        \item{PROTECTED}    - Field may not be altered.
  191. X        \item{UPPERCASE}    - All alpha characters are in uppercase.
  192. X    \end{itemize}
  193. X
  194. X    Syntax for a field is:
  195. X    \begin{verbatim}
  196. X        FIELD <name> {
  197. X            <type> [(<size>)];
  198. X            POS [+-]<column>, [+-]<row>;
  199. X            LVALUE "<left value>";
  200. X            RVALUE "<right value>";
  201. X            [UPPERCASE;]
  202. X            [PROTECTED;]
  203. X        }
  204. X    \end{verbatim}
  205. X    Example:
  206. X    \begin{verbatim}
  207. X        Field adress {
  208. X            Pos 20, +1;
  209. X            Type Char(20);
  210. X            LValue "Adress: ";
  211. X            Uppercase;
  212. X        }
  213. X    \end{verbatim}
  214. X
  215. X\subsection{Literals}
  216. X    Literals is static text to be visualized in the picture, literals
  217. X    is below fields if a collission should occur. Syntax of a literal
  218. X    is:
  219. X    \begin{verbatim}
  220. X        Literal [+-]<column>, [+-]<row>, "<text>";
  221. X    \end{verbatim}
  222. X    Example:
  223. X    \begin{verbatim}
  224. X        Literal +0, +1, "List of persons";
  225. X    \end{verbatim}
  226. X\subsection{Events}
  227. X
  228. X    Events are used to define functions keys and other special cases for eg.
  229. X    refresh display and so on. An event is specified by its event type
  230. X    and either a block of C-code to execute when the event occurres, or the
  231. X    word 'forget' wich means that the specified event should be disabled for
  232. X    this field.
  233. X
  234. X    Type of events is:
  235. X    \begin{itemize}
  236. X       \item[KEY] A key has been pressed. An event of the type KEY must 
  237. X              have one of the following modifiers:
  238. X       \begin{itemize}
  239. X           \item[F0 - F20 -] Function keys
  240. X           \item[UP -] Up arrow
  241. X           \item[DOWN -] Down arrow
  242. X           \item[LEFT -] Left arrow
  243. X           \item[RIGHT -] Right arrow
  244. X           \item[CR -] Carriage return
  245. X           \item[BS -] Backspace
  246. X           \item[TAB -] Horizontal tab
  247. X           \item[FIND -] Search
  248. X           \item[INSERT -] Insert
  249. X       \end{itemize}
  250. X       \item[REFRESH] Refresh the picture
  251. X       \item[DRAW] Only available from pictures, is called
  252. X                   when a pictures is first drawn.
  253. X       \item[LEFT] When trying to move to the left of the field
  254. X       \item[RIGHT] When trying to move to the left of the field
  255. X       \item[ENTRY] When field is entered
  256. X       \item[EXIT] When field is left
  257. X    \end{itemize}
  258. X        
  259. X
  260. X    Syntax for an event is:
  261. X    \begin{verbatim}
  262. X        EVENT <type> [<type modifier>] {
  263. X            <C-code statements>
  264. X        }
  265. X    \end{verbatim}
  266. X    or
  267. X    \begin{verbatim}
  268. X        EVENT <type> [<type modifier>] FORGET;
  269. X    \end{verbatim}
  270. X    Example:
  271. X    \begin{verbatim}
  272. X        Event Entry {
  273. X            fld_set(current.field, "X");
  274. X        }
  275. X
  276. X        Event Key DOWN  {
  277. X            fld_move(fld_down(current.field));
  278. X        }
  279. X    \end{verbatim}
  280. X    
  281. X\section{EVENT and CCODE programing}
  282. X
  283. X
  284. X    For all event- and ccode blocks the developer can use a set
  285. X    library functions that comes with cforms. Most functions returning
  286. X    integers returns ether OK or FAIL exept for those like fld\_len that
  287. X    returns the value expected. Those returning pointers return NULL
  288. X    uppon failure.
  289. X    This is a list and a description of all functions:        
  290. X    \subsection{Start/stop functions}
  291. X         \subsubsection{cforms\_init} Initiate CForms, this must be done
  292. X        before any cforms functions can be called.
  293. X            \synopsys{int cforms\_init(void)}
  294. X
  295. X        \subsubsection{cforms\_end} Stop CForms.
  296. X        \synopsys{int cforms\_end(void)}
  297. X
  298. X     \subsection{Picture functions}
  299. X         \subsubsection{pic\_call} Call picture.
  300. X           \synopsys{int pic\_call(struct picture *, field *)}\\
  301. X        Where picture is a pointer to the picture to call and field
  302. X        is where the cursor lands on, NULL means the first field in
  303. X        picture.
  304. X
  305. X        \subsubsection{pic\_clear} Clear all fields for picture.
  306. X        \synopsys{int pic\_clear(struct picture *)}\\
  307. X        If picture is NULL current.picture is cleared.
  308. X
  309. X        \subsubsection{pic\_leave} Leave current picture after current
  310. X        event has finished.
  311. X        \synopsys{int pic\_leave(void)}
  312. X
  313. X        \subsubsection{picture} Get picture with name.
  314. X        \synopsys{struct picture *picture(char *fmt, ...)}\\
  315. X        Returns a pointer to a picture with the name generated
  316. X        with 'fmt' and its arguments the same way that printf works.
  317. X
  318. X    \subsection{Field functions}
  319. X        \subsubsection{field} Get field with name
  320. X        \synopsys{struct field *field(char *fmt, ...)}\\
  321. X        Returns a pointer to a field with the name generated
  322. X        with 'fmt' and its arguments the same way that printf works.
  323. X
  324. X        If the field name is prepended by the picture name and a
  325. X        colon, i.e.  "picture:field", a field can be found in another
  326. X        picture than current.picture.
  327. X        
  328. X        \subsubsection{fld\_isempty} Check if field is empty, i.e.
  329. X        full of spaces, tabs or null.
  330. X        \synopsys{int fld\_isempty(struct field *)}\\
  331. X        Returns TRUE or FALSE condition.
  332. X
  333. X        \subsubsection{fld\_first} Find first field of picture.
  334. X        \synopsys{struct field *fld\_first(void)}
  335. X
  336. X        \subsubsection{fld\_last} Find last field of picture.
  337. X        \synopsys{struct field *fld\_last(void)}
  338. X
  339. X        \subsubsection{fld\_next} Find next field for picture.
  340. X        \synopsys{struct field *fld\_next(struct field *)}\\
  341. X        Returns the field after field given by argument (or
  342. X        current.field if NULL).
  343. X        
  344. X        \subsubsection{fld\_previous} Find previous field for picture.
  345. X        \synopsys{struct field *fld\_previous(struct field *)}\\
  346. X        Returns the field berfore field given by argument (or
  347. X        current.field if NULL).
  348. X
  349. X        \subsubsection{fld\_left} Find left field.
  350. X        \synopsys{struct field *fld\_left(struct field *)}\\
  351. X        Returns the field to the left of the field given by argument
  352. X        (or current.field if NULL).
  353. X
  354. X        \subsubsection{fld\_right} Find right field.
  355. X        \synopsys{struct field *fld\_right(struct field *)}\\
  356. X        Returns the field to the right of the field given by argument
  357. X        (or current.field if NULL).
  358. X
  359. X        \subsubsection{fld\_up} Find field above current.
  360. X        \synopsys{struct field *fld\_up(struct field *)}\\
  361. X        Returns the field above the field given by argument
  362. X        (or cur\-rent.\-field if\- NULL).
  363. X
  364. X        \subsubsection{fld\_down} Find field below current.
  365. X        \synopsys{struct field *fld\_down(struct field *)}\\
  366. X        Returns the field below the field given by argument
  367. X        (or current.\-field if\- NULL).
  368. X
  369. X        \subsubsection{fld\_set} Set value for field.
  370. X        \synopsys{int fld\_set(struct field *, char *)}\\
  371. X        If field is NULL set value for current.field.
  372. X
  373. X        \subsubsection{fld\_nset} Set value for field but max n chars.
  374. X        \synopsys{int fld\_nset(struct field *, char *)}\\
  375. X        If field is NULL set value for current.field.
  376. X
  377. X        \subsubsection{fld\_get} Get value of field.
  378. X        \synopsys{char *fld\_get(struct field *)}\\
  379. X        If field is NULL get value for current.field.
  380. X
  381. X        \subsubsection{fld\_len} Return length of field.
  382. X        \synopsys{int fld\_len(struct field *)}\\
  383. X        If field is NULL return length for current.field.
  384. X        
  385. X        \subsubsection{fld\_ismodified} Return true if field has been
  386. X        modified since last fld\_set or fld\_nset.
  387. X        \synopsys{int fld\_ismodified(struct field *)}\\
  388. X        If field is NULL return modified for current.field.
  389. X        
  390. X        \subsubsection{fld\_touch} Make field not modified.
  391. X        \synopsys{int fld\_touch(struct field *)}\\
  392. X        If field is NULL touch current.field.
  393. X
  394. X     \subsection{General functions}
  395. X         \subsubsection{message} Give message (line 24).
  396. X        \synopsys{int message(char *fmt, ...)}
  397. X
  398. X        \subsubsection{strequ} Compare two strings, but case insensitive.
  399. X        \synopsys{int strequ(char *s1, char *s2)}
  400. X
  401. X    \subsection{Global variables}
  402. X        \subsubsection{current.picture} Allways points to current picture
  403. X        (can be NULL).
  404. X        \synopsys{struct picture *current.picture}
  405. X
  406. X        \subsubsection{current.field} Allways points to current field
  407. X        (can be NULL).
  408. X        \synopsys{struct field *current.field}
  409. X
  410. X\section{How to compile and install CForms}
  411. X
  412. XWhen you have unpacked the CForms archive you just do cd to the directory
  413. Xwhere you unpacked it and change the DEST-variable in the Makefile to
  414. Xwhere you want CForms installed.
  415. XAfter that you should do a 'make' followed by an 'make install'.
  416. X
  417. XYou can also compile the example application in the example subdirectory
  418. Xby doing 'make example', look it up to see what an application might look
  419. Xlike.
  420. X
  421. X\section{How to compile CForms applications}
  422. X
  423. XLets say you just installed CForms with DEST set to {\em /usr/local},
  424. Xthat means that the CForms compiler resides in /usr/local/bin, the
  425. Xcforms include file resides in /usr/local/include and the library
  426. Xlibcforms.a in /usr/local/lib, then this is how to compile a CForms
  427. Xapplication:
  428. X
  429. XFirst you run the CForms compiler, {\em cfc}, on your inputfile:
  430. X    \begin{verbatim}
  431. X    cfc <yourfile>
  432. X    \end{verbatim}
  433. XThis will generate the compiler output file, {\em cforms.c}. That file
  434. Xshould be compiled with you ordinary c-compiler by doing something like:
  435. X    \begin{verbatim}
  436. X    cc -o <yourapp> -I/usr/local/include -L/usr/local/lib \
  437. X         cforms.c -lcforms -lcurses
  438. X    \end{verbatim}
  439. XObserve that the -L flag must be there beccause the cforms library is in
  440. X/usr/\-local/\-lib.
  441. X
  442. XNow you should be able to run you application.
  443. X
  444. X\newpage
  445. X\tableofcontents
  446. X
  447. X\end{document}
  448. END_OF_FILE
  449. if test 13964 -ne `wc -c <'doc/cforms.tex'`; then
  450.     echo shar: \"'doc/cforms.tex'\" unpacked with wrong size!
  451. fi
  452. # end of 'doc/cforms.tex'
  453. fi
  454. if test -f 'src/get_field.c' -a "${1}" != "-c" ; then 
  455.   echo shar: Will not clobber existing file \"'src/get_field.c'\"
  456. else
  457. echo shar: Extracting \"'src/get_field.c'\" \(6000 characters\)
  458. sed "s/^X//" >'src/get_field.c' <<'END_OF_FILE'
  459. X/*******************************************************************************
  460. X *
  461. X *        G E T _ F I E L D . C
  462. X *        ---------------------
  463. X *
  464. X * Description:
  465. X *    Compiles a field statement.
  466. X *
  467. X * Included functions:
  468. X *    get_field    - Does the job.
  469. X *
  470. X * Revision:
  471. X *    Ver    Date    By        Reason
  472. X *    ---    ----    --        ------
  473. X *    1.00    900625    Lars Berntzon    Created
  474. X *
  475. X ******************************************************************************/
  476. X
  477. X#include <stdio.h>
  478. X#include <ctype.h>
  479. X#include <string.h>
  480. X
  481. X#include "token.h"
  482. X#include "comp.h"
  483. X
  484. X#define isnormal(ch) (isalnum(ch) || (ch) == '_')
  485. Xstatic int found_pos();
  486. Xstatic int found_event();
  487. Xstatic int found_lvalue();
  488. Xstatic int found_rvalue();
  489. Xstatic int found_type();
  490. Xstatic int found_protected();
  491. Xstatic int found_uppercase();
  492. X
  493. Xstatic struct lookup_s lookup[] = {
  494. X    "LVALUE",     found_lvalue,
  495. X    "RVALUE",     found_rvalue,
  496. X    "POS",     found_pos,
  497. X    "EVENT",     found_event,
  498. X    "TYPE",     found_type,
  499. X    "PROTECTED", found_protected,
  500. X    "UPPERCASE", found_uppercase
  501. X};
  502. X
  503. Xstruct field *get_field()
  504. X{
  505. X    char token[TOKENSIZE];
  506. X    struct field *fp = NULL;
  507. X    int i;
  508. X    
  509. X    if (GetTokNC(token) == NULL || !isnormal(token[0])) {
  510. X        error("expected name of field");
  511. X        return NULL;
  512. X    }
  513. X    
  514. X    fp = memalloc(sizeof *fp);
  515. X    link_name(&fp->link, token);
  516. X    
  517. X    if (GetTokNC(token) == NULL || strcmp(token, "{")) {
  518. X        error("expected '{'");
  519. X        unget_field(fp);
  520. X        return NULL;
  521. X    }
  522. X    
  523. X    while(GetTokNC(token) != NULL) {
  524. X    if(strcmp(token, "}") == 0) break;
  525. X    else if (strcmp(token, "{") == 0) {
  526. X        UnGetTok("{");
  527. X        skip_stmt();
  528. X        continue;
  529. X    }
  530. X    
  531. X    for(i = 0; i < N_CMDS; i++) {
  532. X        if (strequ(token, lookup[i].cmd) == 0) break;
  533. X    }
  534. X    if (i < N_CMDS) {
  535. X        if ((*lookup[i].func)(fp) != OK) {
  536. X            unget_field(fp);
  537. X            return NULL;
  538. X        }
  539. X    }
  540. X    else {
  541. X        error("unknown token for field");
  542. X    }
  543. X    }
  544. X    if (fp->lvalue && fp->pos.x - (int) strlen(fp->lvalue) < 1) {
  545. X        error("field has position to far left");
  546. X    }
  547. X    if (fp->rvalue && fp->pos.x + fp->len +  (int) strlen(fp->rvalue) >= 80) {
  548. X        error("field has position to far left");
  549. X    }
  550. X    if (fp->type == NULL) {
  551. X        error("undefined type for field");
  552. X        unget_field(fp);
  553. X        return NULL;
  554. X    }
  555. X    return fp;
  556. X}
  557. X
  558. Xstruct field *unget_field(struct field *fp)
  559. X{
  560. X    struct field *next;
  561. X    struct event *ep;
  562. X
  563. X    if (fp == NULL) return NULL;
  564. X    next = (struct field *)fp->link.next;
  565. X    
  566. X    for(ep = fp->event; ep != NULL; ep = unget_event(ep))
  567. X    ;
  568. X    if (fp->link.name) free(fp->link.name);
  569. X    if (fp->lvalue) free(fp->lvalue);
  570. X    if (fp->rvalue) free(fp->rvalue);
  571. X    free(fp);
  572. X
  573. X    return next;
  574. X}
  575. X
  576. Xstatic int found_lvalue(fp)
  577. X    struct field *fp;
  578. X{
  579. X    char token[TOKENSIZE];
  580. X    
  581. X    if (GetTokNC(token) == NULL || token[0] != '"') {
  582. X        error("expected lvalue");
  583. X        return FAIL;
  584. X    }
  585. X    token[strlen(token) - 1] = 0;
  586. X    
  587. X    fp->lvalue = memalloc(strlen(token));
  588. X    strcpy(fp->lvalue, token + 1);
  589. X    if (GetTokNC(token) == NULL || strcmp(token, ";")) {
  590. X        error("expected ';'");
  591. X        return FAIL;
  592. X    }
  593. X
  594. X    return OK;
  595. X}
  596. X
  597. Xstatic int found_rvalue(fp)
  598. X    struct field *fp;
  599. X{
  600. X    char token[TOKENSIZE];
  601. X    
  602. X    if (GetTokNC(token) == NULL || token[0] != '"') {
  603. X        error("expected rvalue");
  604. X        return FAIL;
  605. X    }
  606. X    token[strlen(token) - 1] = 0;
  607. X    
  608. X    fp->rvalue = memalloc(strlen(token));
  609. X    strcpy(fp->rvalue, token + 1);
  610. X    if (GetTokNC(token) == NULL || strcmp(token, ";")) {
  611. X        error("expected ';'");
  612. X        return FAIL;
  613. X    }
  614. X
  615. X    return OK;
  616. X}
  617. X
  618. Xstatic int found_pos(fp)
  619. X    struct field *fp;
  620. X{
  621. X    char token[TOKENSIZE];
  622. X    
  623. X    if (GetPos(&fp->pos.x, & fp->pos.y) != OK) return FAIL;
  624. X    
  625. X    if (GetTokNC(token) == NULL || strcmp(token, ";")) {
  626. X        error("expected ';'");
  627. X        return FAIL;
  628. X    }
  629. X    return OK;
  630. X}
  631. X
  632. Xstatic int found_event(fp)
  633. X    struct field *fp;
  634. X{
  635. X    struct event *ep;
  636. X    
  637. X    if ((ep = get_event()) == NULL) return FAIL;
  638. X    
  639. X    link((struct link **)&fp->event, &ep->link, TYPE_EVENT);
  640. X    
  641. X    return OK;
  642. X}
  643. X
  644. Xstatic int found_type(fp)
  645. X    struct field *fp;
  646. X{
  647. X    char token[TOKENSIZE];
  648. X    int i;
  649. X    
  650. X    static struct {
  651. X        char *name;
  652. X        char *code;
  653. X    } type[] = {
  654. X        "INT",     "FLD_INT",
  655. X        "CHAR",  "FLD_STR",
  656. X        "ALNUM", "FLD_ALNUM",
  657. X        NULL, NULL
  658. X    };
  659. X    
  660. X    if (GetTokNC(token) == NULL) {
  661. X        error("unexpected end of file for field");
  662. X        return FAIL;
  663. X    }
  664. X    
  665. X    for(i = 0; type[i].name != NULL; i++) {
  666. X        if (strequ(token, type[i].name) == 0) break;
  667. X    }
  668. X
  669. X    if (type[i].name == NULL) {
  670. X        error("unknown type for field");
  671. X        return FAIL;
  672. X    }
  673. X    
  674. X    fp->type = type[i].code;
  675. X    fp->len = 1;
  676. X    
  677. X    if (GetTokNC(token) == NULL) {
  678. X        error("unexpected end of file for field");
  679. X        return FAIL;
  680. X    }
  681. X    
  682. X    if (strcmp(token, ";") == 0) return OK;
  683. X    
  684. X    if (strcmp(token, "(") != 0) {
  685. X        error("expected '(' or ';' after field type");
  686. X        return FAIL;
  687. X    }
  688. X    
  689. X    if (GetTokNC(token) == NULL || !isdigit(token[0])) {
  690. X        error("field size must be integer");
  691. X        return FAIL;
  692. X    }
  693. X    
  694. X    fp->len = atoi(token);
  695. X    
  696. X    if (GetTokNC(token) == NULL || strcmp(token, ")")) {
  697. X        error("expected ')' after field");
  698. X        return FAIL;
  699. X    } 
  700. X
  701. X    if (GetTokNC(token) == NULL || strcmp(token, ";")) {
  702. X        error("expected ';' after field");
  703. X        return FAIL;
  704. X    }
  705. X
  706. X    return OK;
  707. X}
  708. X
  709. Xstatic int found_protected(fp)
  710. X    struct field *fp;
  711. X{
  712. X    char token[TOKENSIZE];
  713. X    
  714. X    fp->flags |= FLD_PROTECTED;
  715. X    
  716. X    if (GetTokNC(token) == NULL) {
  717. X        error("unexpected end of file for field");
  718. X        return FAIL;
  719. X    }
  720. X    if (strcmp(token, ";") != 0) {
  721. X        error("expetced ';'");
  722. X        return FAIL;
  723. X    }
  724. X    
  725. X    return OK;
  726. X}
  727. X
  728. Xstatic int found_uppercase(fp)
  729. X    struct field *fp;
  730. X{
  731. X    char token[TOKENSIZE];
  732. X    
  733. X    fp->flags |= FLD_UPPERCASE;
  734. X    
  735. X    if (GetTokNC(token) == NULL) {
  736. X        error("unexpected end of file for field");
  737. X        return FAIL;
  738. X    }
  739. X    if (strcmp(token, ";") != 0) {
  740. X        error("expetced ';'");
  741. X        return FAIL;
  742. X    }
  743. X    
  744. X    return OK;
  745. X}
  746. X
  747. END_OF_FILE
  748. if test 6000 -ne `wc -c <'src/get_field.c'`; then
  749.     echo shar: \"'src/get_field.c'\" unpacked with wrong size!
  750. fi
  751. # end of 'src/get_field.c'
  752. fi
  753. if test -f 'src/output.c' -a "${1}" != "-c" ; then 
  754.   echo shar: Will not clobber existing file \"'src/output.c'\"
  755. else
  756. echo shar: Extracting \"'src/output.c'\" \(8094 characters\)
  757. sed "s/^X//" >'src/output.c' <<'END_OF_FILE'
  758. X/*******************************************************************************
  759. X *
  760. X *        O U T P U T . C
  761. X *        ---------------
  762. X *
  763. X * Description:
  764. X *    Generates the C-code for CForms.
  765. X *
  766. X * Included functions:
  767. X *    output        - Does the job
  768. X *
  769. X * Revision:
  770. X *    Ver    Date    By        Reason
  771. X *    ---    ----    --        ------
  772. X *    1.00    900627    Lars Berntzon    Created
  773. X *
  774. X ******************************************************************************/
  775. X
  776. X#include "config.h"
  777. X
  778. X#include <stdio.h>
  779. X#include <ctype.h>
  780. X#include <string.h>
  781. X#include <assert.h>
  782. X
  783. X#include "token.h"
  784. X#include "comp.h"
  785. X
  786. Xvoid output()
  787. X{
  788. X    struct viewport *vp;
  789. X    struct picture *pp;
  790. X    struct field *fp;
  791. X    struct event *ep;
  792. X    struct stmt *sp;
  793. X    struct literal *lp;
  794. X    struct ccode *cp;
  795. X    int n_fields, n_events, n_literals, n_pictures;
  796. X    FILE *out;
  797. X    
  798. X    if ((out = fopen("cforms.c", "w")) == NULL) {
  799. X        fprintf(stderr, "failed to open output file.\n");
  800. X        cleanup(1);
  801. X    }
  802. X    
  803. X    /*
  804. X     * G e n e r a t e   H e a d e r.
  805. X     */
  806. X     
  807. X     fprintf(out, "/* Generated by C-Forms version %s */\n\n", version);
  808. X     fprintf(out, "#include <stdio.h>\n\n");
  809. X     fprintf(out, "#include <curses.h>\n");
  810. X     fprintf(out, "#include \"cforms.h\"\n\n");
  811. X
  812. X#if 0     
  813. X     /*
  814. X      * C r e a t e   v i e w p o r t s.
  815. X      */
  816. X     if (list.viewport) {
  817. X         fprintf(out, "    /* V i e w p o r t s */\n\n");
  818. X         for(vp = list.viewport; vp != NULL; vp = NEXT_VIEWPORT(vp))
  819. X         {
  820. X             fprintf(out, "WINDOW *win_%s;\n", vp->link.name);
  821. X         }
  822. X         fprintf(out, "\n");
  823. X    }
  824. X#endif
  825. X    
  826. X    /*
  827. X     * C r e a t e   C - c o d e s.
  828. X     */
  829. X    if (list.ccode) fprintf(out, "    /* C - c o d e s */\n\n");
  830. X    for(cp = list.ccode; cp != NULL; cp = NEXT_CCODE(cp)) 
  831. X    {
  832. X        for(sp = cp->stmt; sp != NULL; sp = sp->next) {
  833. X            fprintf(out, "%s\n", sp->txt);
  834. X        }
  835. X        fprintf(out, "\n");
  836. X    }
  837. X    
  838. X    /*
  839. X     * C r e a t e   p i c t u r e s.
  840. X     */
  841. X    if (list.picture) fprintf(out, "    /* P i c t u r e s */\n\n");
  842. X    for(pp = list.picture; pp != NULL; pp = NEXT_PICTURE(pp))
  843. X    {
  844. X        /*
  845. X         * E v e n t s   f o r   a l l   f i e l d s.
  846. X         */
  847. X        n_fields = 0;
  848. X        n_literals = 0;
  849. X        
  850. X    for(fp = pp->field; fp != NULL; fp = NEXT_FIELD(fp))
  851. X    {
  852. X        /* Event routines for field */
  853. X        
  854. X    for(ep = fp->event; ep != NULL; ep = NEXT_EVENT(ep))
  855. X    {
  856. X        if (ep->stmt) {
  857. X            fprintf(out, "static void event_%s_%s_%s()\n{\n",
  858. X            pp->link.name, fp->link.name, ep->link.name);
  859. X        for(sp = ep->stmt; sp != NULL; sp = sp->next)
  860. X        {
  861. X            fprintf(out, "    %s\n", sp->txt);
  862. X        }
  863. X        fprintf(out, "}\n");
  864. X        }
  865. X    }
  866. X    
  867. X        /* Event table for field */
  868. X
  869. X    if (fp->event) {
  870. X        fprintf(out, "static struct event etab_%s_%s[] = {\n",
  871. X            pp->link.name, fp->link.name);
  872. X        for(ep = fp->event; ep != NULL; ep = NEXT_EVENT(ep))
  873. X        {
  874. X            fprintf(out, "    %s, %s, ", ep->type, ep->code);
  875. X            
  876. X            if (ep->stmt) {
  877. X                fprintf(out, "event_%s_%s_%s",
  878. X                    pp->link.name, fp->link.name, ep->link.name);
  879. X            }
  880. X            else {
  881. X                fprintf(out, "NULL");
  882. X            }
  883. X            fprintf(out, "%s\n", NEXT_EVENT(ep) ? "," : "");
  884. X        }
  885. X        fprintf(out, "};\n\n");
  886. X    }
  887. X    
  888. X    /* 
  889. X     * F i e l d   d a t a   a r r a y.
  890. X     */
  891. X    fprintf(out, "static char field_%s_%s[%d];\n\n",
  892. X          pp->link.name, fp->link.name, fp->len + 1);
  893. X    fprintf(out, "/***************************************************/\n");
  894. X    }
  895. X    
  896. X    /*
  897. X     * T a b l e   o f   a l l   f i e l d s.
  898. X     */
  899. X    if (pp->field) {
  900. X        fprintf(out, "static struct field ftab_%s[] = {\n", pp->link.name);
  901. X        
  902. X    for(fp = pp->field; fp != NULL; n_fields++, fp = NEXT_FIELD(fp))
  903. X    {
  904. X        fprintf(out, "   {\"%s\", ", fp->link.name);
  905. X        fprintf(out, "%s, %d, ", fp->type, fp->len);
  906. X        fprintf(out, "field_%s_%s, ", pp->link.name, fp->link.name);
  907. X        fprintf(out, "%d, %d, \"%s\", \"%s\", ", fp->pos.x, fp->pos.y,
  908. X            fp->lvalue ? fp->lvalue : "", fp->rvalue ? fp->rvalue : "");
  909. X        if (fp->event) {
  910. X            fprintf(out, "etab_%s_%s", pp->link.name, fp->link.name);
  911. X        }
  912. X        else {
  913. X            fprintf(out, "NULL");
  914. X        }
  915. X        for(n_events = 0, ep = fp->event; ep != NULL;
  916. X            n_events++, ep = NEXT_EVENT(ep))
  917. X            ;
  918. X        fprintf(out, ", %d, %d", n_events, fp->flags);
  919. X        fprintf(out, ", 0"); /* Modified flag */
  920. X        fprintf(out, ", NULL"); /* Modified flag */
  921. X        fprintf(out, "}%s", NEXT_FIELD(fp) ? ",\n" : "\n");
  922. X    }
  923. X    fprintf(out, "};\n\n");
  924. X    }
  925. X    
  926. X    /*
  927. X     * T a b l e   o f   l i t e r a l s.
  928. X     */
  929. X    if (pp->literal) {
  930. X        fprintf(out, "static struct literal ltab_%s[] = {\n", pp->link.name);
  931. X        for(lp = pp->literal; lp != NULL; n_literals++, lp = NEXT_LITERAL(lp))
  932. X        {
  933. X            fprintf(out, "    %d, %d, \"%s\", %d%s\n",
  934. X                lp->pos.x, lp->pos.y,
  935. X                lp->link.name, lp->display_flags,
  936. X                NEXT_LITERAL(lp) ? "," : "");
  937. X        }
  938. X        fprintf(out, "};\n\n");
  939. X    }
  940. X    
  941. X    /*
  942. X     * E v e n t s   f o r   p i c t u r e.
  943. X     */
  944. X     
  945. X    for(ep = pp->event; ep != NULL; ep = NEXT_EVENT(ep))
  946. X    {
  947. X        if (ep->stmt) {
  948. X        fprintf(out, "static void event_%s_%s()\n{\n",
  949. X            pp->link.name, ep->link.name);
  950. X        for(sp = ep->stmt; sp != NULL; sp = sp->next)
  951. X        {
  952. X            fprintf(out, "    %s\n", sp->txt);
  953. X        }
  954. X        fprintf(out, "}\n\n");
  955. X    }
  956. X    }
  957. X    
  958. X    n_events = 0;
  959. X    if(pp->event) {
  960. X        fprintf(out, "static struct event etab_%s[] = {\n", 
  961. X            pp->link.name);
  962. X        for(ep = pp->event; ep != NULL; n_events++, ep = NEXT_EVENT(ep))
  963. X        {
  964. X            fprintf(out, "    %s, %s, ", ep->type, ep->code);
  965. X            
  966. X            if (ep->stmt) {
  967. X                fprintf(out, "event_%s_%s", pp->link.name, ep->link.name);
  968. X            }
  969. X            else {
  970. X                fprintf(out, "NULL");
  971. X            }
  972. X            fprintf(out, "%s\n", NEXT_EVENT(ep) ? "," : "");
  973. X        }
  974. X        fprintf(out, "};\n\n");
  975. X    }
  976. X    }
  977. X    
  978. X    /*
  979. X     * T a b l e   o f   p i c t u r e s.
  980. X     */
  981. X    if(list.picture) {
  982. X        fprintf(out, "static struct picture ptab[] = {\n");
  983. X    }
  984. X    n_pictures = 0;
  985. X    for(pp = list.picture; pp != NULL; n_pictures++, pp = NEXT_PICTURE(pp))
  986. X    {
  987. X        fprintf(out, "    {\"%s\", ", pp->link.name);
  988. X            /* Fields */
  989. X    for(n_fields = 0, fp = pp->field; fp; fp = NEXT_FIELD(fp)) {
  990. X        n_fields++;
  991. X    }
  992. X    
  993. X    if (pp->field) {
  994. X        fprintf(out, "ftab_%s, %d, ", pp->link.name, n_fields);
  995. X    }
  996. X    else fprintf(out, "NULL, 0, ");
  997. X    
  998. X        /* Literals */
  999. X    for(n_literals = 0, lp = pp->literal; lp; lp = NEXT_LITERAL(lp)) {
  1000. X        n_literals++;
  1001. X    }
  1002. X    if (pp->literal) {
  1003. X        fprintf(out, "ltab_%s, %d, ", pp->link.name, n_literals);
  1004. X    }
  1005. X    else fprintf(out, "NULL, 0, ");
  1006. X    
  1007. X        /* Events */
  1008. X    for(n_events = 0, ep = pp->event; ep; ep = NEXT_EVENT(ep)) {
  1009. X        n_events++;
  1010. X    }
  1011. X    if (pp->event) {
  1012. X        fprintf(out, "etab_%s, %d", pp->link.name, n_events);
  1013. X    }
  1014. X    else fprintf(out, "NULL, 0");
  1015. X
  1016. X    fprintf(out, ", %d,%d, %d,%d}", pp->viewport->pos.x, pp->viewport->pos.y,
  1017. X        pp->viewport->size.x, pp->viewport->size.y);
  1018. X    if (NEXT_PICTURE(pp)) {
  1019. X        fprintf(out, ",");
  1020. X    }
  1021. X    fprintf(out, "\n");
  1022. X    }
  1023. X    if(list.picture) {
  1024. X        fprintf(out, "};\n\n");
  1025. X    }
  1026. X
  1027. X    /*
  1028. X     * Event functions for module.
  1029. X     */
  1030. X    for(ep = list.event; ep != NULL; ep = NEXT_EVENT(ep))
  1031. X    {
  1032. X        if (ep->stmt) {
  1033. X        fprintf(out, "static void event_%s()\n{\n", ep->link.name);
  1034. X        for(sp = ep->stmt; sp != NULL; sp = sp->next)
  1035. X        {
  1036. X            fprintf(out, "    %s\n", sp->txt);
  1037. X        }
  1038. X        fprintf(out, "}\n\n");
  1039. X    }
  1040. X    }
  1041. X    n_events = 0;
  1042. X    if(list.event) {
  1043. X        fprintf(out, "static struct event etab[] = {\n");
  1044. X        for(ep = list.event; ep != NULL; n_events++, ep = NEXT_EVENT(ep))
  1045. X        {
  1046. X            fprintf(out, "    %s, %s, ", ep->type, ep->code);
  1047. X            
  1048. X            if (ep->stmt) {
  1049. X                fprintf(out, "event_%s", ep->link.name);
  1050. X            }
  1051. X            else {
  1052. X                fprintf(out, "NULL");
  1053. X            }
  1054. X            fprintf(out, "%s\n", NEXT_EVENT(ep) ? "," : "");
  1055. X        }
  1056. X        fprintf(out, "};\n\n");
  1057. X    }
  1058. X
  1059. X    fprintf(out, "struct module _module = { ");
  1060. X    if (list.picture) fprintf(out, "ptab, %d, ", n_pictures);
  1061. X    else fprintf(out, "NULL, 0, ");
  1062. X    if (list.event)  fprintf(out, "etab, %d", n_events);
  1063. X    else fprintf(out, "NULL, 0");
  1064. X    fprintf(out, "};\n");
  1065. X}
  1066. END_OF_FILE
  1067. if test 8094 -ne `wc -c <'src/output.c'`; then
  1068.     echo shar: \"'src/output.c'\" unpacked with wrong size!
  1069. fi
  1070. # end of 'src/output.c'
  1071. fi
  1072. if test -f 'src/token.c' -a "${1}" != "-c" ; then 
  1073.   echo shar: Will not clobber existing file \"'src/token.c'\"
  1074. else
  1075. echo shar: Extracting \"'src/token.c'\" \(6503 characters\)
  1076. sed "s/^X//" >'src/token.c' <<'END_OF_FILE'
  1077. X/*******************************************************************************
  1078. X*
  1079. X*        T O K E N . C
  1080. X*        -------------
  1081. X*
  1082. X* Description:
  1083. X*    Reads tokens from input file. Tokens are the C-stype tokens. It is
  1084. X*    allso possible to unget tokens for later recall by GetTok().
  1085. X*
  1086. X* Included functions:
  1087. X*    GetTok()    - Get token
  1088. X*    GetTokNC()    - Get token but skip comment
  1089. X*    UnGetTok()    - Unget token
  1090. X*    OpenTok()    - Open file to read tokens from
  1091. X*
  1092. X*
  1093. X* Revision:
  1094. X*    Ver    Date   By        Reason
  1095. X*    ---    ----   --        ------
  1096. X*    1.00   900619 Lars Berntzon    Created
  1097. X*
  1098. X******************************************************************************/
  1099. X
  1100. X#include "config.h"
  1101. X
  1102. X#include <stdio.h>
  1103. X#include <ctype.h>
  1104. X#include <string.h>
  1105. X#ifdef STDLIB_H
  1106. X#include <stdlib.h>
  1107. X#endif
  1108. X#ifdef MALLOC_H
  1109. X#include <malloc.h>
  1110. X#endif
  1111. X
  1112. X#include "token.h"
  1113. X
  1114. X#define isnormal(c) (isalnum(c) || (c) == '_')
  1115. X
  1116. X
  1117. X    /* G l o b a l   v a r i a b l e s */
  1118. X    
  1119. Xint newline = 1;       /* Number of newlines before this token    */
  1120. Xint line = 1;           /* Current line number            */
  1121. XFILE *in;           /* The input file pointer            */
  1122. X
  1123. X    /* L o c a l   v a r i a b l e */
  1124. X
  1125. Xstatic struct saved {       /* Queue of ungotten tokens            */
  1126. X    struct saved *next;
  1127. X    char token[TOKENSIZE];
  1128. X} *saved = NULL;
  1129. Xtypedef void *(*state_t)(char *);
  1130. X
  1131. X/*******************************************************************************
  1132. X *
  1133. X *        G E T O K 
  1134. X *        ---------
  1135. X *
  1136. X * Description:
  1137. X *    Reads one token from input file (or from ungotten token).
  1138. X *
  1139. X * Output:
  1140. X *    str    - String where data wil be put (if not NULL).
  1141. X *
  1142. X * Return:
  1143. X *    String containing token, NULL if end of file.
  1144. X *
  1145. X ******************************************************************************/
  1146. Xchar *GetTok(char *str)
  1147. X{
  1148. X    static char token[TOKENSIZE];
  1149. X    static int ch = ' ';
  1150. X    struct saved *p;
  1151. X    int pos;
  1152. X    enum { gt_init, gt_got_delim, gt_normal,
  1153. X           gt_searching_quote, gt_got_backslash } state = gt_init;
  1154. X
  1155. X    if (p = saved) {
  1156. X    strncpy(token, saved->token, TOKENSIZE);
  1157. X    saved = p->next;
  1158. X    free(p);
  1159. X    pos = 1;
  1160. X    goto found;
  1161. X    }
  1162. X    
  1163. X    token[0] = 0;
  1164. X    
  1165. X    newline = 0;
  1166. X    
  1167. X    if (ch == EOF) return NULL;
  1168. X    
  1169. X    for(pos = 0; ch != EOF; ch = getc(in)) {
  1170. X    if (ch == '\n') {
  1171. X        line++;
  1172. X        newline++;
  1173. X    }
  1174. X    switch(state) 
  1175. X    {
  1176. X    case gt_init:
  1177. X        if (isspace(ch)) {
  1178. X            break;
  1179. X        }
  1180. X        else if (ch == '"') {
  1181. X        token[pos++] = ch;
  1182. X        state = gt_searching_quote;
  1183. X        }
  1184. X        else if (!isnormal(ch)) {
  1185. X        token[pos++] = ch;
  1186. X        token[pos++] = 0;
  1187. X        ch = ' ';
  1188. X        goto found;
  1189. X        }
  1190. X        else if (isnormal(ch)) {
  1191. X            token[pos++] = ch;
  1192. X            state = gt_normal;
  1193. X        }
  1194. X        break;
  1195. X
  1196. X    case gt_normal:
  1197. X        if (isnormal(ch)) {
  1198. X            token[pos++] = ch;
  1199. X        }
  1200. X        else {
  1201. X        token[pos++] = 0;
  1202. X        goto found;
  1203. X        }
  1204. X        break;
  1205. X
  1206. X    case gt_searching_quote:
  1207. X        token[pos++] = ch;
  1208. X        if (ch == '\\') {
  1209. X            state = gt_got_backslash;
  1210. X        }
  1211. X        else {
  1212. X            if (ch == '"') {
  1213. X                token[pos++] = 0;
  1214. X                ch = ' ';
  1215. X                goto found;
  1216. X            }
  1217. X        }
  1218. X        break;
  1219. X
  1220. X    case gt_got_backslash:
  1221. X        token[pos++] = ch;
  1222. X        state = gt_searching_quote;
  1223. X        break;
  1224. X    }
  1225. X    }
  1226. X
  1227. Xfound:
  1228. X    if (pos == 0) return NULL;
  1229. X
  1230. X    if (str) return strcpy(str, token);
  1231. X
  1232. X    return token;
  1233. X}
  1234. X
  1235. X/*******************************************************************************
  1236. X *
  1237. X *        G E T T O K N C
  1238. X *        ---------------
  1239. X *
  1240. X * Description:
  1241. X *    Reads one token from input file (or from ungotten token) and skips
  1242. X *    C-style comments.
  1243. X *
  1244. X * Output:
  1245. X *    str    - String where data will be put (if not NULL).
  1246. X *
  1247. X * Return:
  1248. X *    String containing token, NULL if EOF.
  1249. X *
  1250. X ******************************************************************************/
  1251. Xstatic void *nc_init(char *);
  1252. Xstatic void *nc_found_leading_slash(char *);
  1253. Xstatic void *nc_searching_star(char *);
  1254. Xstatic void *nc_expect_slash(char *);
  1255. X
  1256. Xchar *GetTokNC(char *token)
  1257. X{
  1258. X    char *ret;
  1259. X    state_t state = nc_init;
  1260. X
  1261. X    while((ret = GetTok(token)) != NULL &&
  1262. X          (state = (state_t) (*state)(ret)) != NULL) {
  1263. X    }
  1264. X    return ret;
  1265. X}
  1266. Xstatic void *nc_init(char *token)
  1267. X{
  1268. X    if(strcmp(token, "/") != 0) return NULL;
  1269. X    return (void *)nc_found_leading_slash;
  1270. X}
  1271. Xstatic void *nc_found_leading_slash(char *token)
  1272. X{
  1273. X    if(strcmp(token, "*") == 0) return (void *)nc_searching_star;
  1274. X    UnGetTok(token);
  1275. X    strcpy(token, "/");
  1276. X    return NULL;
  1277. X}
  1278. Xstatic void *nc_searching_star(char *token)
  1279. X{
  1280. X    if(strcmp(token, "*") == 0) return (void *)nc_expect_slash;
  1281. X    return (void *)nc_searching_star;
  1282. X}
  1283. Xstatic void *nc_expect_slash(char *token)
  1284. X{
  1285. X    if (strcmp(token, "/") == 0) return (void *)nc_init;
  1286. X    UnGetTok(token);
  1287. X    return (void *)nc_searching_star;
  1288. X}
  1289. X
  1290. X/*******************************************************************************
  1291. X *
  1292. X *        U N G E T T O K
  1293. X *        ---------------
  1294. X *
  1295. X * Description:
  1296. X *    Returns a token to be read later by GetTok().
  1297. X *
  1298. X * Input:
  1299. X *    str    - String to be put back.
  1300. X *
  1301. X ******************************************************************************/
  1302. Xvoid
  1303. XUnGetTok(char *str)
  1304. X{
  1305. X    struct saved *p = NULL;
  1306. X    
  1307. X    if ((p = (struct saved *)malloc(sizeof *p)) == NULL) {
  1308. X    fprintf(stderr, "Out of memory");
  1309. X    return;
  1310. X    }
  1311. X
  1312. X    p->next = saved;
  1313. X    saved = p;
  1314. X    strncpy(saved->token, str, TOKENSIZE);
  1315. X}
  1316. X
  1317. X/*******************************************************************************
  1318. X *
  1319. X *        O P E N T O K
  1320. X *        -------------
  1321. X *
  1322. X * Description:
  1323. X *    Open a file to read tokens from.
  1324. X *
  1325. X * Input:
  1326. X *    name    - Name of file.
  1327. X *
  1328. X * Return:
  1329. X *    Opened files pointer, of NULL if failure.
  1330. X *
  1331. X ******************************************************************************/
  1332. XFILE *OpenTok(char *name)
  1333. X{
  1334. X    if (in != NULL) {
  1335. X    fclose(in);
  1336. X    }
  1337. X    return in = fopen(name, "r");
  1338. X}
  1339. X
  1340. X#ifdef STANDALONE
  1341. X/*******************************************************************************
  1342. X *
  1343. X *        M A I N
  1344. X *        -------
  1345. X *
  1346. X * Description:
  1347. X *    Main routine when compiled as standalone.
  1348. X *    This is only used for test.
  1349. X *
  1350. X ******************************************************************************/
  1351. X
  1352. Xmain()
  1353. X{
  1354. X    char filename[100];
  1355. X    char *p;
  1356. X    
  1357. X    printf("Enter filename of 'stdin': ");
  1358. X    scanf("%s", filename);
  1359. X    if (strcmp(filename, "stdin") == 0) {
  1360. X    printf("Using stdin\n");
  1361. X    in = stdin;
  1362. X    }
  1363. X    else if (OpenTok(filename) == NULL) {
  1364. X    fprintf(stderr, "Can't open file '%s'\n", filename);
  1365. X    exit(1);
  1366. X    }
  1367. X
  1368. X    while(p = GetTokNC(NULL)) printf("'%s'\n", p);
  1369. X    UnGetTok("ungotten 1");
  1370. X    while(p = GetTokNC(NULL)) printf("'%s'\n", p);
  1371. X    UnGetTok("ungotten 2");
  1372. X    UnGetTok("ungotten 3");
  1373. X    while(p = GetTokNC(NULL)) printf("'%s'\n", p);
  1374. X    printf("END\n");    
  1375. X}
  1376. X#endif /* STANDALONE */
  1377. END_OF_FILE
  1378. if test 6503 -ne `wc -c <'src/token.c'`; then
  1379.     echo shar: \"'src/token.c'\" unpacked with wrong size!
  1380. fi
  1381. # end of 'src/token.c'
  1382. fi
  1383. echo shar: End of archive 2 \(of 3\).
  1384. cp /dev/null ark2isdone
  1385. MISSING=""
  1386. for I in 1 2 3 ; do
  1387.     if test ! -f ark${I}isdone ; then
  1388.     MISSING="${MISSING} ${I}"
  1389.     fi
  1390. done
  1391. if test "${MISSING}" = "" ; then
  1392.     echo You have unpacked all 3 archives.
  1393.     rm -f ark[1-9]isdone
  1394. else
  1395.     echo You still need to unpack the following archives:
  1396.     echo "        " ${MISSING}
  1397. fi
  1398. ##  End of shell archive.
  1399. exit 0
  1400.